]> arthur.barton.de Git - netatalk.git/blob - etc/uams/uams_krb4/uams_krb4.c
Cleanup header checks in configure.in
[netatalk.git] / etc / uams / uams_krb4 / uams_krb4.c
1 /*
2  * $Id: uams_krb4.c,v 1.10 2009-10-15 11:39:48 didg Exp $
3  *
4  * Copyright (c) 1990,1993 Regents of The University of Michigan.
5  * All Rights Reserved.  See COPYRIGHT.
6  */
7
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif /* HAVE_CONFIG_H */
11
12 #if defined( KRB ) || defined( UAM_AFSKRB )
13 #include <unistd.h>
14 #include <fcntl.h>
15 #include <sys/types.h>
16 #include <sys/time.h>
17 #include <sys/stat.h>
18 #include <sys/socket.h>
19 #include <limits.h>
20 #include <string.h>
21 #include <ctype.h>
22 #include <pwd.h>
23 #include <atalk/logger.h>
24 #include <netinet/in.h>
25 #include <des.h>
26 #include <krb.h>
27 #if 0
28 #include <prot.h>
29 #endif /* 0 */
30
31 #include <netatalk/endian.h>
32 #include <atalk/afp.h>
33 #include <atalk/compat.h>
34 #include <atalk/util.h>
35 #include <atalk/uam.h>
36
37 static C_Block                  seskey;
38 static Key_schedule             seskeysched;
39
40 static char             realm[ REALM_SZ ];
41
42 #ifdef UAM_AFSKRB
43 static int              validseskey = 0;
44 static int              logged = 0;
45 static char             *tktfile;
46 static char             instance[ INST_SZ ], name[ ANAME_SZ ];
47 #endif /* UAM_AFSKRB */
48
49 #ifdef AFS
50 #include <afs/stds.h>
51 #include <rx/rxkad.h>
52 #include <afs/afs.h>
53 #include <afs/venus.h>
54 #include <afs/afsint.h>
55
56 char *ka_LocalCell();
57
58 struct ClearToken {
59     int32_t AuthHandle;
60     char HandShakeKey[8];
61     int32_t ViceId;
62     int32_t BeginTimestamp;
63     int32_t EndTimestamp;
64 };
65 #endif /* AFS */
66
67
68 #ifdef KRB
69
70 static void lcase( p )
71     char        *p;
72 {
73     for (; *p; p++ ) {
74         if ( isupper( *p )) {
75             *p = tolower( *p );
76         }
77     }
78     return;
79 }
80
81 static void ucase( p )
82     char        *p;
83 {
84     for (; *p; p++ ) {
85         if ( islower( *p )) {
86             *p = toupper( *p );
87         }
88     }
89     return;
90 }
91
92 #define KRB4CMD_HELO    1
93 #define KRB4RPL_REALM   2
94 #define KRB4WRT_SESS    3
95 #define KRB4RPL_DONE    4
96 #define KRB4RPL_PRINC   5
97 #define KRB4WRT_TOKEN   6
98 #define KRB4WRT_SKIP    7
99 #define KRB4RPL_DONEMUT 8
100 #define KRB4CMD_SESS    9
101 #define KRB4CMD_TOKEN   10
102 #define KRB4CMD_SKIP    11
103
104 static int krb4_login(void *obj, struct passwd **uam_pwd,
105                       char *ibuf, size_t ibuflen,
106                       char *rbuf, size_t *rbuflen )
107 {
108     char                *p;
109     char                *username;
110     struct passwd       *pwd;
111     u_int16_t           len;
112     KTEXT_ST            tkt;
113     static AUTH_DAT     ad;
114     int                 rc, proto;
115     size_t              ulen;
116     char                inst[ 40 ], princ[ 40 ];
117
118     if (uam_afpserver_option(obj, UAM_OPTION_USERNAME, &username, &ulen) < 0)
119       return AFPERR_MISC;
120
121     if (uam_afpserver_option(obj, UAM_OPTION_PROTOCOL, &proto, NULL) < 0)
122       return AFPERR_MISC;
123
124     switch( *ibuf ) {
125         case KRB4CMD_SESS:
126             LOG(log_info, logtype_default, "krb4_login: KRB4CMD_SESS" );
127             ++ibuf;
128             p = ibuf;
129             memcpy( &len, p, sizeof( u_int16_t ));
130             tkt.length = ntohs( len );
131             p += sizeof( u_int16_t );
132
133             if ( tkt.length <= 0 || tkt.length > MAX_KTXT_LEN ) {
134                 *rbuflen = 0;
135                 LOG(log_info, logtype_default, "krb4_login: tkt.length = %d", tkt.length );
136                 return( AFPERR_BADUAM );
137             }
138
139             memcpy( tkt.dat, p, tkt.length );
140             p += tkt.length;
141
142             strcpy( inst, "*" );
143
144             switch( proto ) {
145                 case AFPPROTO_ASP:
146                     strcpy( princ, "afpserver" );
147                     break;
148                 case AFPPROTO_DSI:
149                     strcpy( princ, "rcmd" );
150                     break;
151             }
152
153             if( (rc = krb_rd_req( &tkt, princ, inst, 0, &ad, "" )) 
154                 != RD_AP_OK ) {
155                 LOG(log_error, logtype_default, 
156                         "krb4_login: krb_rd_req(): %s", krb_err_txt[ rc ] );
157                 *rbuflen = 0;
158                 return( AFPERR_BADUAM );
159             }
160
161             LOG(log_info, logtype_default, "krb4_login: %s.%s@%s", ad.pname, ad.pinst, 
162                 ad.prealm );
163             strcpy( realm, ad.prealm );
164             memcpy( seskey, ad.session, sizeof( C_Block ) );
165             key_sched( (C_Block *)seskey, seskeysched );
166
167             strncpy( username, ad.pname, ulen );
168
169             p = rbuf;
170
171 #ifdef AFS
172             *p = KRB4RPL_DONE;  /* XXX */
173             *rbuflen = 1;
174
175             if (( pwd = uam_getname( obj, ad.pname, strlen(ad.pname) )) == NULL ) {
176                 return AFPERR_PARAM;
177             }
178 /*
179             if (uam_checkuser( pwd ) < 0) {
180                 return AFPERR_NOTAUTH;
181             }
182 */
183             *uam_pwd = pwd;
184             return( AFP_OK ); /* Should this be AFPERR_AUTHCONT? */
185 #else /* AFS */
186             /* get principals */
187             *p++ = KRB4RPL_PRINC;
188             len = strlen( realm );
189             *p++ = len + 1;
190             *p++ = '@';
191             strcpy( p, realm );
192             p += len + 1;
193             break;
194 #endif /* AFS */
195         case KRB4CMD_HELO:
196             p = rbuf;
197             if (krb_get_lrealm( realm, 1 ) != KSUCCESS ) {
198                 LOG(log_error, logtype_default, "krb4_login: can't get local realm!" );
199                 return( AFPERR_NOTAUTH );
200             }
201             *p++ = KRB4RPL_REALM;
202             *p++ = 1;
203             len = strlen( realm );
204             *p++ = len;
205             strcpy( p, realm );
206             p += len + 1;
207             break;
208
209         default:
210             *rbuflen = 0;
211             LOG(log_info, logtype_default, "krb4_login: bad command %d", *ibuf );
212             return( AFPERR_NOTAUTH );
213     }
214
215 #ifdef AFS
216     if ( setpag() < 0 ) {
217         *rbuflen = 0;
218         LOG(log_error, logtype_default, "krb_login: setpag: %s", strerror(errno) );
219         return( AFPERR_BADUAM );
220     }
221 #endif /*AFS*/
222
223     *rbuflen = p - rbuf;
224     return( AFPERR_AUTHCONT );
225 }
226
227 static int krb4_action( void *v1, void *v2, const int i )
228 {
229         return i;
230 }
231
232 /*
233    I have a hunch that problems might arise on platforms 
234    with non-16bit short's and non-32bit int's
235 */
236 static int krb4_logincont(void *obj, struct passwd **uam_pwd,
237                           char *ibuf, size_t ibuflen,
238                           char *rbuf, size_t *rbuflen)
239 {
240     static struct passwd        *pwd;
241     KTEXT_ST            tkt;
242     static AUTH_DAT     ad;
243     int                 rc;
244     u_int16_t           len;
245     char                *p, *username, *servername;
246     CREDENTIALS         cr;
247 #ifdef AFS
248     struct ViceIoctl    vi;
249     struct ClearToken   ct;
250 #endif /* AFS */
251     char                buf[ 1024 ];
252     int                 aint, ulen, snlen;
253
254     if (uam_afpserver_option(obj, UAM_OPTION_USERNAME, &username, &ulen) < 0)
255       return AFPERR_MISC;
256
257     if (uam_afpserver_option(obj, UAM_OPTION_HOSTNAME, &servername, &snlen) < 0)
258       return AFPERR_MISC;
259
260     ibuf++;
261     switch ( rc = *ibuf++ ) {
262         case KRB4CMD_TOKEN :
263 #ifdef AFS
264             p = buf;
265             memcpy( &len, ibuf, sizeof( u_int16_t ) );
266             ibuf += sizeof( len );
267             len = ntohs( len );
268             aint = len;
269             memcpy( p, &aint, sizeof( int ) );
270             p += sizeof( int );
271             memcpy( p, ibuf, len );
272             pcbc_encrypt( (C_Block *)p, (C_Block *)p, len, seskeysched,
273                 seskey, DECRYPT );
274             p += len;
275             ibuf += len;
276
277             memcpy( &len, ibuf, sizeof( u_int16_t ) );
278             ibuf += sizeof( u_int16_t ) );
279             len = ntohs( len );
280
281             if ( len != sizeof( struct ClearToken ) ) {
282                 LOG(log_error, logtype_default, "krb4_logincont: token too short" );
283                 *rbuflen = 0;
284                 return( AFPERR_BADUAM );
285             }
286             memcpy( &ct, ibuf, len );
287
288             pcbc_encrypt( (C_Block *)&ct, (C_Block *)&ct, len, 
289                 seskeysched, seskey, DECRYPT );
290
291             aint = sizeof( struct ClearToken );
292             memcpy( p, &aint, sizeof( int ) );
293             p += sizeof( int );
294             memcpy( p, &ct, sizeof( struct ClearToken ) );
295             p += sizeof( struct ClearToken );
296
297             aint = 0;
298             memcpy( p, &aint, sizeof( int ) );
299             p += sizeof( int );
300
301             lcase( realm );
302             strcpy( p, realm );
303             p += strlen( realm ) + 1;
304
305             vi.in = buf;
306             vi.in_size = p - buf;
307             vi.out = buf;
308             vi.out_size = sizeof( buf );
309
310             if ( pioctl( 0, VIOCSETTOK, &vi, 0 ) < 0 ) {
311                 LOG(log_error, logtype_default, "krb4_logincont: pioctl: %s", strerror(errno) );
312                 *rbuflen = 0;
313                 return( AFPERR_BADUAM );
314             }
315             /* FALL THROUGH */
316
317         case KRB4CMD_SKIP:
318             p = rbuf;
319             *p = KRB4RPL_DONE;  /* XXX */
320             *rbuflen = 1;
321
322             if (( pwd = uam_getname( obj, username, strlen(username) ) ) == NULL ) {
323                 return( AFPERR_NOTAUTH );
324             }
325 /*
326             if (uam_checkuser(pwd) < 0) {
327                 return AFPERR_NOTAUTH;
328             }
329 */
330             *uam_pwd = pwd;
331             return( AFP_OK );
332 #endif /* AFS */
333         default:
334             /* read in the rest */
335             if (uam_afp_read(obj, rbuf, rbuflen, krb4_action) < 0)
336                 return AFPERR_PARAM;
337
338             p = rbuf;
339             switch ( rc = *p++ ) {
340                 case KRB4WRT_SESS :
341                     memcpy( &len, p, sizeof( len ));
342                     tkt.length = ntohs( len );
343                     p += sizeof( short );
344
345                     if ( tkt.length <= 0 || tkt.length > MAX_KTXT_LEN ) {
346                         return( AFPERR_BADUAM );
347                     }
348                     memcpy( tkt.dat, p, tkt.length );
349                     p += tkt.length;
350
351                     if (( rc = krb_rd_req( &tkt, "afpserver", servername, 
352                         0, &ad, "" )) != RD_AP_OK ) {
353                         LOG(log_error, logtype_default, "krb4_logincont: krb_rd_req(): %s", krb_err_txt[ rc ] );
354                         return( AFPERR_BADUAM );
355                     }
356
357                     LOG(log_info, logtype_default, "krb4_login: %s.%s@%s", ad.pname, 
358                         ad.pinst, ad.prealm );
359                     memcpy(realm, ad.prealm, sizeof(realm));
360                     memcpy(seskey, ad.session, sizeof( C_Block ));
361                     key_sched((C_Block *) seskey, seskeysched );
362
363                     strncpy(username, ad.pname, ulen);
364
365                     p = rbuf;
366 #ifndef AFS
367                     *p = KRB4RPL_DONE;  /* XXX */
368                     *rbuflen = 1;
369
370                     if (( pwd = uam_getname( obj, ad.pname, strlen(ad.pname) )) 
371                         == NULL ) {
372                         return( AFPERR_PARAM );
373                     }
374                     *uam_pwd = pwd;
375                     return AFP_OK;
376 #else /* ! AFS */
377                     /* get principals */
378                     *p++ = KRB4RPL_PRINC;
379                     len = strlen( realm );
380                     *p++ = len + 1;
381                     *p++ = '@';
382                     strcpy( p, realm );
383                     p += len + 1;
384                     *rbuflen = p - rbuf;
385                     return( AFPERR_AUTHCONT );
386
387                 case KRB4WRT_TOKEN :
388                     memcpy( &len, p, sizeof( len ));
389                     len = ntohs( len );
390                     p += sizeof( len );
391                     memcpy( &cr, p, len );
392
393                     pcbc_encrypt((C_Block *)&cr, (C_Block *)&cr, len, 
394                         seskeysched, seskey, DES_DECRYPT );
395
396                     p = buf;
397                     cr.ticket_st.length = ntohl( cr.ticket_st.length );
398                     memcpy( p, &cr.ticket_st.length, sizeof( int ));
399                     p += sizeof( int );
400                     memcpy( p, cr.ticket_st.dat, cr.ticket_st.length );
401                     p += cr.ticket_st.length;
402
403                     ct.AuthHandle = ntohl( cr.kvno );
404                     memcpy( ct.HandShakeKey, cr.session, sizeof( cr.session ));
405                     ct.ViceId = 0;
406                     ct.BeginTimestamp = ntohl( cr.issue_date );
407                     ct.EndTimestamp = krb_life_to_time( ntohl( cr.issue_date ),
408                     ntohl( cr.lifetime ));
409
410                     aint = sizeof( struct ClearToken );
411                     memcpy( p, &aint, sizeof( int ));
412                     p += sizeof( int );
413                     memcpy( p, &ct, sizeof( struct ClearToken ));
414                     p += sizeof( struct ClearToken );
415
416                     aint = 0;
417                     memcpy( p, &aint, sizeof( int ));
418                     p += sizeof( int );
419
420                     lcase( realm );
421                     strcpy( p, realm );
422                     p += strlen( realm ) + 1;
423
424                     vi.in = buf;
425                     vi.in_size = p - buf;
426                     vi.out = buf;
427                     vi.out_size = sizeof( buf );
428                     if ( pioctl( 0, VIOCSETTOK, &vi, 0 ) < 0 ) {
429                         LOG(log_error, logtype_default, "krb4_logincont: pioctl: %s", strerror(errno) );
430                         return( AFPERR_BADUAM );
431                     }
432                     /* FALL THROUGH */
433
434                 case KRB4WRT_SKIP :
435                     p = rbuf;
436                     *p = KRB4RPL_DONE;  /* XXX */
437                     *rbuflen = 1;
438
439                     if (( pwd = uam_getname( obj, ad.pname, strlen(ad.pname) )) 
440                         == NULL ) {
441                         return( AFPERR_PARAM );
442                     }
443                     *uam_pwd = pwd;
444                     return AFP_OK;
445 #endif /*AFS*/
446
447                 default:
448                     LOG(log_info, logtype_default, "krb4_logincont: bad command %d", rc );
449                     *rbuflen = 0;
450                     return( AFPERR_NOTAUTH );
451                     break;
452             }
453             break;
454     }
455 }
456
457 #endif /* KRB */
458
459
460 #ifdef AFS
461 #include <rx/rxkad.h>
462 #include <afs/afsint.h>
463
464 char *ka_LocalCell();
465
466 static void
467 addrealm(realm,cells)
468     char *realm;
469         char ***cells;
470 {
471     char **ptr;
472         int temp;
473
474         ptr= *cells;
475
476     for(;*ptr != 0 ;ptr++)
477         if(!strcmp(realm,*ptr))
478             return;
479
480         temp=ptr- *cells;
481         *cells=(char**)realloc(*cells,((2+temp)*sizeof(char*)));
482         ptr= *cells+temp;
483
484     *ptr=(char*)malloc(strlen(realm)+1);
485     strcpy(*ptr++,realm);
486         *ptr=0;
487     return;
488 }
489
490 static int kcheckuser(pwd,passwd)
491         struct passwd *pwd;
492         char *passwd;
493 {
494         int32_t code;
495         char *instance="";
496         char realm[MAXKTCREALMLEN];
497         char lorealm[MAXKTCREALMLEN];
498         char *cell;
499         Date lifetime=MAXKTCTICKETLIFETIME;
500         int rval;
501         char **cells=(char **)malloc(sizeof(char*));
502         char *temp;
503         int rc,cellNum;
504         struct ktc_principal serviceName;
505
506         *cells=0;
507
508         code = ka_Init(0);
509
510         {
511                 char *temp,*temp1;
512                 temp=(char*)malloc(strlen(pwd->pw_dir)+1);
513                 strcpy(temp,pwd->pw_dir);
514                 temp1=temp;
515                 temp=strtok(temp,"/");
516                 temp=strtok('\0',"/");
517                 ka_CellToRealm(temp,realm,0);
518                 addrealm(realm,&cells);
519                 free(temp1);
520         }
521
522         setpag();
523         authenticate(cells,pwd->pw_name,passwd);
524         cellNum=0;
525         rc=ktc_ListTokens(cellNum,&cellNum,&serviceName);
526         if(rc)
527                 rval=1;
528         else{
529                 rval=0;
530         }
531
532         return(rval);
533 }
534
535 static void authenticate(cells,name,passwd)
536         char **cells;
537         char *name;
538         char *passwd;
539 {
540         char **ptr=cells;
541         char *errorstring;
542
543         while(*ptr){
544             ka_UserAuthenticate(name,/*instance*/"",/*cell*/*ptr++,
545                     passwd,/*setpag*/0,&errorstring);
546         }
547 }
548 #endif /* AFS */
549
550 #if defined( UAM_AFSKRB ) && defined( AFS )
551 static int afskrb_login(void *obj, struct passwd *uam_pwd,
552                         char *ibuf, size_t ibuflen, 
553                         char *rbuf, size_t *rbuflen )
554 {
555     KTEXT_ST    authent, rpkt;
556     CREDENTIALS cr;
557     char        *p, *q, *username, servername;
558     int         len, rc, whoserealm, ulen, snlen;
559     short       slen;
560
561     *rbuflen = 0;
562     if (uam_afpserver_option(obj, UAM_OPTION_USERNAME, &username, &ulen) < 0)
563       return AFPERR_MISC;
564
565     if (uam_afpserver_option(obj, UAM_OPTION_HOSTNAME, &servername, &snlen ) < 0)
566       return AFPERR_MISC;
567     
568     len = (unsigned char) *ibuf++;
569     ibuf[ len ] = '\0';
570     if (( p = strchr( ibuf, '@' )) != NULL ) {
571         *p++ = '\0';
572         strcpy( realm, p );
573         ucase( realm );
574         whoserealm = 0;
575     } else {
576         if ( krb_get_lrealm( realm, 1 ) != KSUCCESS ) {
577             return AFPERR_BADUAM;
578         }
579         whoserealm = 1;
580     }
581     if (( p = strchr( ibuf, '.' )) != NULL ) {
582         *p++ = '\0';
583         strcpy( instance, p );
584     } else {
585         *instance = '\0';
586     }
587     strcpy( name, ibuf );
588     /*
589      * We don't have the session key, yet. Get one.
590      */
591     p = rbuf;
592     if ( validseskey == 0 ) {
593         if ( setpag() < 0 ) {
594             LOG(log_error, logtype_default, "krb_login: setpag: %s", strerror(errno) );
595             return AFPERR_BADUAM;
596         }
597         krb_set_tkt_string(( tktfile = mktemp( _PATH_AFPTKT )));
598         if (( rc =  krb_get_svc_in_tkt( "afpserver", servername, realm,
599                 TICKET_GRANTING_TICKET, realm, 255, KEYFILE )) != INTK_OK ) {
600             LOG(log_error, logtype_default, "krb_login: can't get ticket-granting-ticket" );
601             return (( whoserealm ) ? AFPERR_BADUAM : AFPERR_PARAM );
602         }
603         if ( krb_mk_req( &authent, name, instance, realm, 0 ) != KSUCCESS ) {
604             return ( AFPERR_PARAM );
605         }
606         if ( krb_get_cred( name, instance, realm, &cr ) != KSUCCESS ) {
607             return ( AFPERR_BADUAM );
608         }
609
610         if ( unlink( tktfile ) < 0 ) {
611             LOG(log_error, logtype_default, "krb_login: unlink %s: %s", tktfile, strerror(errno) );
612             return ( AFPERR_BADUAM );
613         }
614
615         memcpy( seskey, cr.session, sizeof( C_Block ));
616         key_sched((C_Block *) seskey, seskeysched );
617         validseskey = 1;
618         strncpy(username, name, ulen);
619
620         memcpy( p, authent.dat, authent.length );
621         p += authent.length;
622     }
623
624     if ( kuam_get_in_tkt( name, instance, realm, TICKET_GRANTING_TICKET,
625             realm, 255, &rpkt ) != INTK_OK ) {
626         return ( AFPERR_PARAM );
627     }
628
629
630     q = (char *)rpkt.dat;
631     *p++ = *q++;
632     *p++ = *q++;
633     while ( *q++ )
634         ;
635     while ( *q++ )
636         ;
637     while ( *q++ )
638         ;
639     q += 10;
640
641     len = strlen( realm );
642     strcpy( p, realm );
643     p += len + 1;
644     memcpy( &slen, q, sizeof( short ));
645     memcpy( p, &slen, sizeof( short ));
646     p += sizeof( short );
647     q += sizeof( short );
648     memcpy( p, q, slen );
649     p += slen;
650
651     *rbuflen = p - rbuf;
652     return( AFPERR_AUTHCONT );
653 }
654
655 static int afskrb_logincont(void *obj, struct passwd *uam_pwd,
656                             char *ibuf, size_t ibuflen, 
657                             char *rbuf, size_t *rbuflen )
658 {
659     CREDENTIALS         cr;
660     struct ViceIoctl    vi;
661     struct ClearToken   ct;
662     struct passwd       *pwd;
663     char                buf[ 1024 ], *p;
664     int                 aint;
665     short               clen;
666
667     *rbuflen = 0;
668     if (uam_afpserver_option(obj, UAM_OPTION_USERNAME, &username, NULL) < 0)
669       return AFPERR_MISC;
670     
671     ibuf += 2;
672     memcpy( &clen, ibuf, sizeof( short ));
673     clen = ntohs( clen );
674     ibuf += sizeof( short );
675
676     pcbc_encrypt((C_Block *)ibuf, (C_Block *)ibuf,
677             clen, seskeysched, seskey, DES_DECRYPT );
678     if ( kuam_set_in_tkt( name, instance, realm, TICKET_GRANTING_TICKET,
679             realm, ibuf ) != INTK_OK ) {
680         return ( AFPERR_PARAM );
681     }
682
683     if ( get_ad_tkt( "afs", "", realm, 255 ) != KSUCCESS ) {
684         return ( AFPERR_PARAM );
685     }
686     if ( krb_get_cred( "afs", "", realm, &cr ) != KSUCCESS ) {
687         return ( AFPERR_PARAM );
688     }
689
690     p = buf;
691     memcpy( p, &cr.ticket_st.length, sizeof( int ));
692     p += sizeof( int );
693     memcpy( p, cr.ticket_st.dat, cr.ticket_st.length );
694     p += cr.ticket_st.length;
695
696     ct.AuthHandle = cr.kvno;
697     memcpy( ct.HandShakeKey, cr.session, sizeof( cr.session ));
698     ct.ViceId = 0;
699     ct.BeginTimestamp = cr.issue_date;
700     /* ct.EndTimestamp = cr.issue_date + ( cr.lifetime * 5 * 60 ); */
701     ct.EndTimestamp = krb_life_to_time( cr.issue_date, cr.lifetime );
702
703     aint = sizeof( struct ClearToken );
704     memcpy( p, &aint, sizeof( int ));
705     p += sizeof( int );
706     memcpy( p, &ct, sizeof( struct ClearToken ));
707     p += sizeof( struct ClearToken );
708
709     aint = 0;
710     memcpy( p, &aint, sizeof( int ));
711     p += sizeof( int );
712
713     lcase( realm );
714     strcpy( p, realm );
715     p += strlen( realm ) + 1;
716
717     vi.in = buf;
718     vi.in_size = p - buf;
719     vi.out = buf;
720     vi.out_size = sizeof( buf );
721     if ( pioctl( 0, VIOCSETTOK, &vi, 0 ) < 0 ) {
722         LOG(log_error, logtype_default, "krb_logincont: pioctl: %s", strerror(errno) );
723         return ( AFPERR_BADUAM );
724     }
725
726     if ( unlink( tktfile ) < 0 ) {
727         LOG(log_error, logtype_default, "krb_logincont: %s: %s", tktfile, strerror(errno) );
728         return ( AFPERR_BADUAM );
729     }
730
731     if (( pwd = uam_getname( obj, username, strlen(username) )) == NULL ) {
732         return ( AFPERR_PARAM );
733     }
734
735     if ( logged == 0 ) {
736         logged = 1;
737         LOG(log_info, logtype_default, "authenticated %s.%s@%s", name, instance, realm );
738         *uam_pwd = pwd;
739         return AFP_OK;
740     }
741     LOG(log_info, logtype_default, "re-authenticated %s.%s@%s", name, instance, realm );
742     return( AFP_OK );
743 }
744 #endif /* UAM_AFSKRB AFS */
745
746 static int uam_setup(const char *path)
747 {
748 #ifdef KRB
749    uam_register(UAM_SERVER_LOGIN, path, "Kerberos IV", krb4_login, 
750                 krb4_logincont, NULL);
751    /* uam_afpserver_action(); */
752 #endif /* KRB */
753 #ifdef UAM_AFSKRB
754    uam_register(UAM_SERVER_LOGIN, path, "AFS Kerberos", afskrb_login, 
755                 afskrb_logincont, NULL);
756    /* uam_afpserver_action(); */
757 #endif /* UAM_AFSKRB */
758    return 0;
759 }
760
761 static void uam_cleanup(void)
762 {
763 #ifdef KRB
764    /* uam_afpserver_action(); */
765    uam_unregister(UAM_SERVER_LOGIN, "Kerberos IV");
766 #endif
767 #ifdef UAM_AFSKRB
768    /* uam_afpserver_action(); */
769    uam_unregister(UAM_SERVER_LOGIN, "AFS Kerberos");
770 #endif
771 }
772
773 UAM_MODULE_EXPORT struct uam_export uams_krb4 = {
774   UAM_MODULE_SERVER,
775   UAM_MODULE_VERSION,
776   uam_setup, uam_cleanup
777 };
778
779 #endif /* KRB or UAM_AFSKRB */
780