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