]> arthur.barton.de Git - netatalk.git/blob - etc/afpd/afs.c
implemented config.h
[netatalk.git] / etc / afpd / afs.c
1 /*
2  * Copyright (c) 1990,1993 Regents of The University of Michigan.
3  * All Rights Reserved.  See COPYRIGHT.
4  */
5
6 #ifdef HAVE_CONFIG_H
7 #include "config.h"
8 #endif
9
10 #ifdef AFS
11
12 #include <string.h>
13 #include <sys/types.h>
14 #include <sys/syslog.h>
15 #include <netatalk/endian.h>
16 #include <netinet/in.h>
17 #include <afs/venus.h>
18 #include <afs/afsint.h>
19 #include <atalk/afp.h>
20 #include <unistd.h>
21
22 #include "globals.h"
23 #include "directory.h"
24 #include "volume.h"
25 #include "misc.h"
26
27 afs_getvolspace( vol, bfree, btotal, bsize )
28     struct vol  *vol;
29     VolSpace    *bfree, *btotal;
30     u_int32_t   *bsize;
31 {
32     struct ViceIoctl    vi;
33     struct VolumeStatus *vs;
34     char                venuspace[ sizeof( struct VolumeStatus ) + 3 ];
35     int                 total, free;
36
37     vi.in_size = 0;
38     vi.out_size = sizeof( venuspace );
39     vi.out = venuspace;
40     if ( pioctl( vol->v_path, VIOCGETVOLSTAT, &vi, 1 ) < 0 ) {
41         return( AFPERR_PARAM );
42     }
43
44     vs = (struct VolumeStatus *)venuspace;
45
46     if ( vs->PartBlocksAvail > 0 ) {
47         if ( vs->MaxQuota != 0 ) {
48 #define min(x,y)        (((x)<(y))?(x):(y))
49             free = min( vs->MaxQuota - vs->BlocksInUse, vs->PartBlocksAvail );
50         } else {
51             free = vs->PartBlocksAvail;
52         }
53     } else {
54         free = 0;
55     }
56
57     if ( vs->MaxQuota != 0 ) {
58         total = free + vs->BlocksInUse;
59     } else {
60         total = vs->PartMaxBlocks;
61     }
62
63     *bsize = 1024;
64     *bfree = (VolSpace) free * 1024;
65     *btotal = (VolSpace) total * 1024;
66
67     return( AFP_OK );
68 }
69
70 afp_getdiracl(obj, ibuf, ibuflen, rbuf, rbuflen )
71     AFPObj      *obj;
72     char        *ibuf, *rbuf;
73     int         ibuflen, *rbuflen;
74 {
75     struct ViceIoctl    vi;
76     struct vol          *vol;
77     struct dir          *dir;
78     char                *path;
79     u_int32_t           did;
80     u_int16_t           vid;
81
82     ibuf += 2;
83     memcpy( &vid, ibuf, sizeof( vid ));
84     ibuf += sizeof( short );
85     if (( vol = getvolbyvid( vid )) == NULL ) {
86         *rbuflen = 0;
87         return( AFPERR_PARAM );
88     }
89
90     memcpy( &did, ibuf, sizeof( did ));
91     ibuf += sizeof( int );
92     if (( dir = dirsearch( vol, did )) == NULL ) {
93         *rbuflen = 0;
94         return( AFPERR_NOOBJ );
95     }
96
97     if (( path = cname( vol, dir, &ibuf )) == NULL ) {
98         *rbuflen = 0;
99         return( AFPERR_NOOBJ );
100     }
101     if ( *path != '\0' ) {
102         *rbuflen = 0;
103         return( AFPERR_BITMAP );
104     }
105
106     vi.in_size = 0;
107     vi.out_size = *rbuflen;
108     vi.out = rbuf;
109     if ( pioctl( ".", VIOCGETAL, &vi, 1 ) < 0 ) {
110         *rbuflen = 0;
111         return( AFPERR_PARAM );
112     }
113     *rbuflen = strlen( vi.out ) + 1;
114     return( AFP_OK );
115 }
116
117 /*
118  * Calculate the mode for a directory in AFS.  First, make sure the
119  * directory is in AFS.  Could probably use something less heavy than
120  * VIOCGETAL.  If the directory is on AFS, use access() calls to
121  * estimate permission, a la mdw.
122  */
123 afsmode( path, ma, dir )
124     char                *path;
125     struct maccess      *ma;
126     struct dir          *dir;
127 {
128     struct ViceIoctl    vi;
129     char                buf[ 1024 ];
130
131     if (( dir->d_flags & DIRF_FSMASK ) == DIRF_NOFS ) {
132         vi.in_size = 0;
133         vi.out_size = sizeof( buf );
134         vi.out = buf;
135         if ( pioctl( path, VIOCGETAL, &vi, 1 ) < 0 ) {
136             dir->d_flags |= DIRF_UFS;
137         } else {
138             dir->d_flags |= DIRF_AFS;
139         }
140     }
141
142     if (( dir->d_flags & DIRF_FSMASK ) != DIRF_AFS ) {
143         return;
144     }
145
146     if ( access( path, R_OK|W_OK|X_OK ) == 0 ) {
147         ma->ma_user = AR_UREAD|AR_UWRITE|AR_USEARCH|AR_UOWN;
148         ma->ma_owner = AR_UREAD|AR_UWRITE|AR_USEARCH;
149     } else if ( access( path, R_OK|X_OK ) == 0 ) {
150         ma->ma_user = AR_UREAD|AR_USEARCH;
151         ma->ma_owner = AR_UREAD|AR_USEARCH;
152     } else {
153         ma->ma_user = ma->ma_owner = 0;
154         if ( access( path, R_OK ) == 0 ) {
155             ma->ma_user |= AR_UREAD;
156             ma->ma_owner |= AR_UREAD;
157         }
158         if ( access( path, X_OK ) == 0 ) {
159             ma->ma_user |= AR_USEARCH;
160             ma->ma_owner |= AR_USEARCH;
161         }
162         if ( access( path, W_OK ) == 0 ) {
163             ma->ma_user |= AR_UWRITE|AR_UOWN;
164             ma->ma_owner |= AR_UWRITE;
165         }
166     }
167
168     return;
169 }
170
171 extern struct dir       *curdir;
172 /*
173  * cmd | 0 | vid | did | pathtype | pathname | 0 | acl
174  */
175 afp_setdiracl(obj, ibuf, ibuflen, rbuf, rbuflen )
176     AFPObj      *obj;
177     char        *ibuf, *rbuf;
178     int         ibuflen, *rbuflen;
179 {
180     struct ViceIoctl    vi;
181     struct vol          *vol;
182     struct dir          *dir;
183     char                *path, *iend;
184     u_int32_t           did;
185     u_int16_t           vid;
186
187     *rbuflen = 0;
188     iend = ibuf + ibuflen;
189     ibuf += 2;
190     memcpy( &vid, ibuf, sizeof( vid ));
191     ibuf += sizeof( short );
192     if (( vol = getvolbyvid( vid )) == NULL ) {
193         *rbuflen = 0;
194         return( AFPERR_PARAM );
195     }
196
197     memcpy( &did, ibuf, sizeof( did ));
198     ibuf += sizeof( int );
199     if (( dir = dirsearch( vol, did )) == NULL ) {
200         *rbuflen = 0;
201         return( AFPERR_NOOBJ );
202     }
203
204     if (( path = cname( vol, dir, &ibuf )) == NULL ) {
205         *rbuflen = 0;
206         return( AFPERR_NOOBJ );
207     }
208     if ( *path != '\0' ) {
209         *rbuflen = 0;
210         return( AFPERR_BITMAP );
211     }
212
213     if ((int)ibuf & 1 ) {
214         ibuf++;
215     }
216
217     vi.in_size = iend - ibuf;
218     vi.in = ibuf;
219     vi.out_size = 0;
220
221     if ( pioctl( ".", VIOCSETAL, &vi, 1 ) < 0 ) {
222         *rbuflen = 0;
223         return( AFPERR_PARAM );
224     }
225     pioctl( ".AppleDouble", VIOCSETAL, &vi, 1 );
226     if ( curdir->d_did  == DIRDID_ROOT ) {
227         pioctl( ".AppleDesktop", VIOCSETAL, &vi, 1 );
228     }
229
230     return( AFP_OK );
231 }
232
233
234 #ifdef UAM_AFSKRB
235
236 #include <krb.h>
237 #include <des.h>
238 #include <afs/kauth.h>
239 #include <afs/kautils.h>
240
241 extern C_Block          seskey;
242 extern Key_schedule     seskeysched;
243
244 afp_afschangepw(obj, ibuf, ibuflen, rbuf, rbuflen )
245     AFPObj      *obj;
246     char        *ibuf, *rbuf;
247     int         ibuflen, *rbuflen;
248 {
249     char        name[ MAXKTCNAMELEN ], instance[ MAXKTCNAMELEN ];
250     char        realm[ MAXKTCREALMLEN ];
251     char        oldpw[ 9 ], newpw[ 9 ];
252     int         len, rc;
253     u_int16_t   clen;
254     struct ktc_encryptionKey    oldkey, newkey;
255     struct ktc_token            adtok;
256     struct ubik_client          *conn;
257
258     *rbuflen = 0;
259     ++ibuf;
260     len = (unsigned char) *ibuf++;
261     ibuf[ len ] = '\0';
262     *name = *instance = *realm = '\0';
263     ka_ParseLoginName( ibuf, name, instance, realm );
264     ucase( realm );
265     if ( *realm == '\0' ) {
266         if ( krb_get_lrealm( realm, 1 ) != KSUCCESS ) {
267             syslog( LOG_ERR, "krb_get_lrealm failed" );
268             return( AFPERR_BADUAM );
269         }
270     }
271
272     if ( strlen( name ) < 2 || strlen( name ) > 18 ) {
273         return( AFPERR_PARAM );
274     }
275     ibuf += len;
276
277     memcpy( &clen, ibuf, sizeof( clen ));
278     clen = ntohs( clen );
279     if ( clen % 8 != 0 ) {
280         return( AFPERR_PARAM );
281     }
282
283     ibuf += sizeof( short );
284     pcbc_encrypt((C_Block *)ibuf, (C_Block *)ibuf,
285             clen, seskeysched, seskey, DES_DECRYPT );
286
287     len = (unsigned char) *ibuf++;
288     if ( len > 8 ) {
289         return( AFPERR_PARAM );
290     }
291     memset( oldpw, 0, sizeof( oldpw ));
292     memcpy( oldpw, ibuf, len );
293     ibuf += len;
294     oldpw[ len ] = '\0';
295
296     len = (unsigned char) *ibuf++;
297     if ( len > 8 ) {
298         return( AFPERR_PARAM );
299     }
300     memset( newpw, 0, sizeof( newpw ));
301     memcpy( newpw, ibuf, len );
302     ibuf += len;
303     newpw[ len ] = '\0';
304
305     syslog( LOG_INFO,
306         "changing password for <%s>.<%s>@<%s>", name, instance, realm );
307
308     ka_StringToKey( oldpw, realm, &oldkey );
309     memset( oldpw, 0, sizeof( oldpw ));
310     ka_StringToKey( newpw, realm, &newkey );
311     memset( newpw, 0, sizeof( newpw ));
312
313     rc = ka_GetAdminToken( name, instance, realm, &oldkey, 60, &adtok, 0 );
314     memset( &oldkey, 0, sizeof( oldkey ));
315     switch ( rc ) {
316         case 0:
317             break;
318         case KABADREQUEST:
319             memset( &newkey, 0, sizeof( newkey ));
320             return( AFPERR_NOTAUTH );
321         default:
322             memset( &newkey, 0, sizeof( newkey ));
323             return( AFPERR_BADUAM );
324     }
325     if ( ka_AuthServerConn( realm, KA_MAINTENANCE_SERVICE, &adtok, &conn )
326                 != 0 ) {
327         memset( &newkey, 0, sizeof( newkey ));
328         return( AFPERR_BADUAM );
329     }
330
331     rc = ka_ChangePassword( name, instance, conn, 0, &newkey );
332     memset( &newkey, 0, sizeof( newkey ));
333     if ( rc != 0 ) {
334         return( AFPERR_BADUAM );
335     }
336
337     syslog( LOG_DEBUG, "password changed succeeded" );
338     return( AFP_OK );
339 }
340
341 #endif UAM_AFSKRB
342 #endif AFS