1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  *
3*0Sstevel@tonic-gate  * Portions Copyright %G% Sun Microsystems, Inc.
4*0Sstevel@tonic-gate  * All Rights Reserved
5*0Sstevel@tonic-gate  *
6*0Sstevel@tonic-gate  */
7*0Sstevel@tonic-gate 
8*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
9*0Sstevel@tonic-gate 
10*0Sstevel@tonic-gate /*
11*0Sstevel@tonic-gate  *  Copyright (c) 1993 Regents of the University of Michigan.
12*0Sstevel@tonic-gate  *  All rights reserved.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  *  kbind.c
15*0Sstevel@tonic-gate  */
16*0Sstevel@tonic-gate 
17*0Sstevel@tonic-gate #ifndef lint
18*0Sstevel@tonic-gate static char copyright[] = "@(#) Copyright (c) 1993 Regents of the University of Michigan.\nAll rights reserved.\n";
19*0Sstevel@tonic-gate #endif
20*0Sstevel@tonic-gate 
21*0Sstevel@tonic-gate #ifdef KERBEROS
22*0Sstevel@tonic-gate 
23*0Sstevel@tonic-gate #include <stdio.h>
24*0Sstevel@tonic-gate #include <string.h>
25*0Sstevel@tonic-gate 
26*0Sstevel@tonic-gate #ifdef MACOS
27*0Sstevel@tonic-gate #include <stdlib.h>
28*0Sstevel@tonic-gate #include "macos.h"
29*0Sstevel@tonic-gate #else /* MACOS */
30*0Sstevel@tonic-gate #ifdef DOS
31*0Sstevel@tonic-gate #include "msdos.h"
32*0Sstevel@tonic-gate #endif /* DOS */
33*0Sstevel@tonic-gate #include <krb.h>
34*0Sstevel@tonic-gate #include <stdlib.h>
35*0Sstevel@tonic-gate #if !defined(DOS) && !defined( _WIN32 )
36*0Sstevel@tonic-gate #include <sys/types.h>
37*0Sstevel@tonic-gate #endif /* !DOS && !_WIN32 */
38*0Sstevel@tonic-gate #include <sys/time.h>
39*0Sstevel@tonic-gate #include <sys/socket.h>
40*0Sstevel@tonic-gate #endif /* MACOS */
41*0Sstevel@tonic-gate 
42*0Sstevel@tonic-gate #include "lber.h"
43*0Sstevel@tonic-gate #include "ldap.h"
44*0Sstevel@tonic-gate #include "ldap-private.h"
45*0Sstevel@tonic-gate #include "ldap-int.h"
46*0Sstevel@tonic-gate 
47*0Sstevel@tonic-gate 
48*0Sstevel@tonic-gate 
49*0Sstevel@tonic-gate /*
50*0Sstevel@tonic-gate  * ldap_kerberos_bind1 - initiate a bind to the ldap server using
51*0Sstevel@tonic-gate  * kerberos authentication.  The dn is supplied.  It is assumed the user
52*0Sstevel@tonic-gate  * already has a valid ticket granting ticket.  The msgid of the
53*0Sstevel@tonic-gate  * request is returned on success (suitable for passing to ldap_result()),
54*0Sstevel@tonic-gate  * -1 is returned if there's trouble.
55*0Sstevel@tonic-gate  *
56*0Sstevel@tonic-gate  * Example:
57*0Sstevel@tonic-gate  *	ldap_kerberos_bind1( ld, "cn=manager, o=university of michigan, c=us" )
58*0Sstevel@tonic-gate  */
59*0Sstevel@tonic-gate int
60*0Sstevel@tonic-gate ldap_kerberos_bind1( LDAP *ld, char *dn )
61*0Sstevel@tonic-gate {
62*0Sstevel@tonic-gate 	BerElement	*ber;
63*0Sstevel@tonic-gate 	char		*cred;
64*0Sstevel@tonic-gate 	int		rc, credlen;
65*0Sstevel@tonic-gate 	char		*get_kerberosv4_credentials();
66*0Sstevel@tonic-gate #ifdef STR_TRANSLATION
67*0Sstevel@tonic-gate 	int		str_translation_on;
68*0Sstevel@tonic-gate #endif /* STR_TRANSLATION */
69*0Sstevel@tonic-gate 
70*0Sstevel@tonic-gate 	/*
71*0Sstevel@tonic-gate 	 * The bind request looks like this:
72*0Sstevel@tonic-gate 	 *	BindRequest ::= SEQUENCE {
73*0Sstevel@tonic-gate 	 *		version		INTEGER,
74*0Sstevel@tonic-gate 	 *		name		DistinguishedName,
75*0Sstevel@tonic-gate 	 *		authentication	CHOICE {
76*0Sstevel@tonic-gate 	 *			krbv42ldap	[1] OCTET STRING
77*0Sstevel@tonic-gate 	 *			krbv42dsa	[2] OCTET STRING
78*0Sstevel@tonic-gate 	 *		}
79*0Sstevel@tonic-gate 	 *	}
80*0Sstevel@tonic-gate 	 * all wrapped up in an LDAPMessage sequence.
81*0Sstevel@tonic-gate 	 */
82*0Sstevel@tonic-gate 
83*0Sstevel@tonic-gate #if defined( SUN ) && defined( _REENTRANT )
84*0Sstevel@tonic-gate 	int rv;
85*0Sstevel@tonic-gate 
86*0Sstevel@tonic-gate         LOCK_LDAP(ld);
87*0Sstevel@tonic-gate #endif
88*0Sstevel@tonic-gate 	Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 186, "ldap_kerberos_bind1\n"), 0, 0, 0 );
89*0Sstevel@tonic-gate 
90*0Sstevel@tonic-gate 	if ( dn == NULL )
91*0Sstevel@tonic-gate 		dn = "";
92*0Sstevel@tonic-gate 
93*0Sstevel@tonic-gate 	if ( (cred = get_kerberosv4_credentials( ld, dn, "ldapserver",
94*0Sstevel@tonic-gate 	    &credlen )) == NULL ) {
95*0Sstevel@tonic-gate #if defined( SUN ) && defined( _REENTRANT )
96*0Sstevel@tonic-gate 		UNLOCK_LDAP(ld);
97*0Sstevel@tonic-gate #endif
98*0Sstevel@tonic-gate 		return( -1 );	/* ld_errno should already be set */
99*0Sstevel@tonic-gate 	}
100*0Sstevel@tonic-gate 
101*0Sstevel@tonic-gate 	/* create a message to send */
102*0Sstevel@tonic-gate 	if ( (ber = alloc_ber_with_options( ld )) == NULLBER ) {
103*0Sstevel@tonic-gate 		free( cred );
104*0Sstevel@tonic-gate #if defined( SUN ) && defined( _REENTRANT )
105*0Sstevel@tonic-gate 		UNLOCK_LDAP(ld);
106*0Sstevel@tonic-gate #endif
107*0Sstevel@tonic-gate 		return( -1 );
108*0Sstevel@tonic-gate 	}
109*0Sstevel@tonic-gate 
110*0Sstevel@tonic-gate #ifdef STR_TRANSLATION
111*0Sstevel@tonic-gate 	if (( str_translation_on = (( ber->ber_options &
112*0Sstevel@tonic-gate 	    LBER_TRANSLATE_STRINGS ) != 0 ))) {	/* turn translation off */
113*0Sstevel@tonic-gate 		ber->ber_options &= ~LBER_TRANSLATE_STRINGS;
114*0Sstevel@tonic-gate 	}
115*0Sstevel@tonic-gate #endif /* STR_TRANSLATION */
116*0Sstevel@tonic-gate 
117*0Sstevel@tonic-gate 	/* fill it in */
118*0Sstevel@tonic-gate 	rc = ber_printf( ber, "{it{isto}}", ++ld->ld_msgid, LDAP_REQ_BIND,
119*0Sstevel@tonic-gate 	    ld->ld_version, dn, LDAP_AUTH_KRBV41, cred, credlen );
120*0Sstevel@tonic-gate 
121*0Sstevel@tonic-gate #ifdef STR_TRANSLATION
122*0Sstevel@tonic-gate 	if ( str_translation_on ) {	/* restore translation */
123*0Sstevel@tonic-gate 		ber->ber_options |= LBER_TRANSLATE_STRINGS;
124*0Sstevel@tonic-gate 	}
125*0Sstevel@tonic-gate #endif /* STR_TRANSLATION */
126*0Sstevel@tonic-gate 
127*0Sstevel@tonic-gate 	if ( rc == -1 ) {
128*0Sstevel@tonic-gate 		free( cred );
129*0Sstevel@tonic-gate 		ber_free( ber, 1 );
130*0Sstevel@tonic-gate 		ld->ld_errno = LDAP_ENCODING_ERROR;
131*0Sstevel@tonic-gate #if defined( SUN ) && defined( _REENTRANT )
132*0Sstevel@tonic-gate 		UNLOCK_LDAP(ld);
133*0Sstevel@tonic-gate #endif
134*0Sstevel@tonic-gate 		return( -1 );
135*0Sstevel@tonic-gate 	}
136*0Sstevel@tonic-gate 
137*0Sstevel@tonic-gate 	free( cred );
138*0Sstevel@tonic-gate 
139*0Sstevel@tonic-gate #ifndef NO_CACHE
140*0Sstevel@tonic-gate 	if ( ld->ld_cache != NULL ) {
141*0Sstevel@tonic-gate 		ldap_flush_cache( ld );
142*0Sstevel@tonic-gate 	}
143*0Sstevel@tonic-gate #endif /* !NO_CACHE */
144*0Sstevel@tonic-gate 
145*0Sstevel@tonic-gate 	/* send the message */
146*0Sstevel@tonic-gate #if defined( SUN ) && defined( _REENTRANT )
147*0Sstevel@tonic-gate 	rv = send_initial_request( ld, LDAP_REQ_BIND, dn, ber );
148*0Sstevel@tonic-gate         UNLOCK_LDAP(ld);
149*0Sstevel@tonic-gate 	return ( rv );
150*0Sstevel@tonic-gate #else
151*0Sstevel@tonic-gate 	return ( send_initial_request( ld, LDAP_REQ_BIND, dn, ber ));
152*0Sstevel@tonic-gate #endif
153*0Sstevel@tonic-gate }
154*0Sstevel@tonic-gate 
155*0Sstevel@tonic-gate int
156*0Sstevel@tonic-gate ldap_kerberos_bind1_s( LDAP *ld, char *dn )
157*0Sstevel@tonic-gate {
158*0Sstevel@tonic-gate 	int		msgid;
159*0Sstevel@tonic-gate 	LDAPMessage	*res;
160*0Sstevel@tonic-gate 
161*0Sstevel@tonic-gate 	Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 187, "ldap_kerberos_bind1_s\n"), 0, 0, 0 );
162*0Sstevel@tonic-gate 
163*0Sstevel@tonic-gate 	/* initiate the bind */
164*0Sstevel@tonic-gate 	if ( (msgid = ldap_kerberos_bind1( ld, dn )) == -1 )
165*0Sstevel@tonic-gate 		return( ld->ld_errno );
166*0Sstevel@tonic-gate 
167*0Sstevel@tonic-gate 	/* wait for a result */
168*0Sstevel@tonic-gate 	if ( ldap_result( ld, ld->ld_msgid, 1, (struct timeval *) 0, &res )
169*0Sstevel@tonic-gate 	    == -1 ) {
170*0Sstevel@tonic-gate 		return( ld->ld_errno );	/* ldap_result sets ld_errno */
171*0Sstevel@tonic-gate 	}
172*0Sstevel@tonic-gate 
173*0Sstevel@tonic-gate 	return( ldap_result2error( ld, res, 1 ) );
174*0Sstevel@tonic-gate }
175*0Sstevel@tonic-gate 
176*0Sstevel@tonic-gate /*
177*0Sstevel@tonic-gate  * ldap_kerberos_bind2 - initiate a bind to the X.500 server using
178*0Sstevel@tonic-gate  * kerberos authentication.  The dn is supplied.  It is assumed the user
179*0Sstevel@tonic-gate  * already has a valid ticket granting ticket.  The msgid of the
180*0Sstevel@tonic-gate  * request is returned on success (suitable for passing to ldap_result()),
181*0Sstevel@tonic-gate  * -1 is returned if there's trouble.
182*0Sstevel@tonic-gate  *
183*0Sstevel@tonic-gate  * Example:
184*0Sstevel@tonic-gate  *	ldap_kerberos_bind2( ld, "cn=manager, o=university of michigan, c=us" )
185*0Sstevel@tonic-gate  */
186*0Sstevel@tonic-gate int
187*0Sstevel@tonic-gate ldap_kerberos_bind2( LDAP *ld, char *dn )
188*0Sstevel@tonic-gate {
189*0Sstevel@tonic-gate 	BerElement	*ber;
190*0Sstevel@tonic-gate 	char		*cred;
191*0Sstevel@tonic-gate 	int		rc, credlen;
192*0Sstevel@tonic-gate 	char		*get_kerberosv4_credentials();
193*0Sstevel@tonic-gate #ifdef STR_TRANSLATION
194*0Sstevel@tonic-gate 	int		str_translation_on;
195*0Sstevel@tonic-gate #endif /* STR_TRANSLATION */
196*0Sstevel@tonic-gate 
197*0Sstevel@tonic-gate #if defined( SUN ) && defined( _REENTRANT )
198*0Sstevel@tonic-gate 	int rv;
199*0Sstevel@tonic-gate 
200*0Sstevel@tonic-gate         LOCK_LDAP(ld);
201*0Sstevel@tonic-gate #endif
202*0Sstevel@tonic-gate 	Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 188, "ldap_kerberos_bind2\n"), 0, 0, 0 );
203*0Sstevel@tonic-gate 
204*0Sstevel@tonic-gate 	if ( dn == NULL )
205*0Sstevel@tonic-gate 		dn = "";
206*0Sstevel@tonic-gate 
207*0Sstevel@tonic-gate 	if ( (cred = get_kerberosv4_credentials( ld, dn, "x500dsa", &credlen ))
208*0Sstevel@tonic-gate 	    == NULL ) {
209*0Sstevel@tonic-gate #if defined( SUN ) && defined( _REENTRANT )
210*0Sstevel@tonic-gate 		UNLOCK_LDAP(ld);
211*0Sstevel@tonic-gate #endif
212*0Sstevel@tonic-gate 		return( -1 );	/* ld_errno should already be set */
213*0Sstevel@tonic-gate 	}
214*0Sstevel@tonic-gate 
215*0Sstevel@tonic-gate 	/* create a message to send */
216*0Sstevel@tonic-gate 	if ( (ber = alloc_ber_with_options( ld )) == NULLBER ) {
217*0Sstevel@tonic-gate 		free( cred );
218*0Sstevel@tonic-gate #if defined( SUN ) && defined( _REENTRANT )
219*0Sstevel@tonic-gate 		UNLOCK_LDAP(ld);
220*0Sstevel@tonic-gate #endif
221*0Sstevel@tonic-gate 		return( -1 );
222*0Sstevel@tonic-gate 	}
223*0Sstevel@tonic-gate 
224*0Sstevel@tonic-gate #ifdef STR_TRANSLATION
225*0Sstevel@tonic-gate 	if (( str_translation_on = (( ber->ber_options &
226*0Sstevel@tonic-gate 	    LBER_TRANSLATE_STRINGS ) != 0 ))) {	/* turn translation off */
227*0Sstevel@tonic-gate 		ber->ber_options &= ~LBER_TRANSLATE_STRINGS;
228*0Sstevel@tonic-gate 	}
229*0Sstevel@tonic-gate #endif /* STR_TRANSLATION */
230*0Sstevel@tonic-gate 
231*0Sstevel@tonic-gate 	/* fill it in */
232*0Sstevel@tonic-gate 	rc = ber_printf( ber, "{it{isto}}", ++ld->ld_msgid, LDAP_REQ_BIND,
233*0Sstevel@tonic-gate 	    ld->ld_version, dn, LDAP_AUTH_KRBV42, cred, credlen );
234*0Sstevel@tonic-gate 
235*0Sstevel@tonic-gate 
236*0Sstevel@tonic-gate #ifdef STR_TRANSLATION
237*0Sstevel@tonic-gate 	if ( str_translation_on ) {	/* restore translation */
238*0Sstevel@tonic-gate 		ber->ber_options |= LBER_TRANSLATE_STRINGS;
239*0Sstevel@tonic-gate 	}
240*0Sstevel@tonic-gate #endif /* STR_TRANSLATION */
241*0Sstevel@tonic-gate 
242*0Sstevel@tonic-gate 	free( cred );
243*0Sstevel@tonic-gate 
244*0Sstevel@tonic-gate 	if ( rc == -1 ) {
245*0Sstevel@tonic-gate 		ber_free( ber, 1 );
246*0Sstevel@tonic-gate 		ld->ld_errno = LDAP_ENCODING_ERROR;
247*0Sstevel@tonic-gate #if defined( SUN ) && defined( _REENTRANT )
248*0Sstevel@tonic-gate 		UNLOCK_LDAP(ld);
249*0Sstevel@tonic-gate #endif
250*0Sstevel@tonic-gate 		return( -1 );
251*0Sstevel@tonic-gate 	}
252*0Sstevel@tonic-gate 
253*0Sstevel@tonic-gate 	/* send the message */
254*0Sstevel@tonic-gate #if defined( SUN ) && defined( _REENTRANT )
255*0Sstevel@tonic-gate 	rv = send_initial_request( ld, LDAP_REQ_BIND, dn, ber );
256*0Sstevel@tonic-gate         UNLOCK_LDAP(ld);
257*0Sstevel@tonic-gate 	return ( rv );
258*0Sstevel@tonic-gate #endif
259*0Sstevel@tonic-gate 	return ( send_initial_request( ld, LDAP_REQ_BIND, dn, ber ));
260*0Sstevel@tonic-gate }
261*0Sstevel@tonic-gate 
262*0Sstevel@tonic-gate /* synchronous bind to DSA using kerberos */
263*0Sstevel@tonic-gate int
264*0Sstevel@tonic-gate ldap_kerberos_bind2_s( LDAP *ld, char *dn )
265*0Sstevel@tonic-gate {
266*0Sstevel@tonic-gate 	int		msgid;
267*0Sstevel@tonic-gate 	LDAPMessage	*res;
268*0Sstevel@tonic-gate 
269*0Sstevel@tonic-gate 	Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 189, "ldap_kerberos_bind2_s\n"), 0, 0, 0 );
270*0Sstevel@tonic-gate 
271*0Sstevel@tonic-gate 	/* initiate the bind */
272*0Sstevel@tonic-gate 	if ( (msgid = ldap_kerberos_bind2( ld, dn )) == -1 )
273*0Sstevel@tonic-gate 		return( ld->ld_errno );
274*0Sstevel@tonic-gate 
275*0Sstevel@tonic-gate 	/* wait for a result */
276*0Sstevel@tonic-gate 	if ( ldap_result( ld, ld->ld_msgid, 1, (struct timeval *) 0, &res )
277*0Sstevel@tonic-gate 	    == -1 ) {
278*0Sstevel@tonic-gate 		return( ld->ld_errno );	/* ldap_result sets ld_errno */
279*0Sstevel@tonic-gate 	}
280*0Sstevel@tonic-gate 
281*0Sstevel@tonic-gate 	return( ldap_result2error( ld, res, 1 ) );
282*0Sstevel@tonic-gate }
283*0Sstevel@tonic-gate 
284*0Sstevel@tonic-gate /* synchronous bind to ldap and DSA using kerberos */
285*0Sstevel@tonic-gate int
286*0Sstevel@tonic-gate ldap_kerberos_bind_s( LDAP *ld, char *dn )
287*0Sstevel@tonic-gate {
288*0Sstevel@tonic-gate 	int	err;
289*0Sstevel@tonic-gate 
290*0Sstevel@tonic-gate 	Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 190, "ldap_kerberos_bind_s\n"), 0, 0, 0 );
291*0Sstevel@tonic-gate 
292*0Sstevel@tonic-gate 	if ( (err = ldap_kerberos_bind1_s( ld, dn )) != LDAP_SUCCESS )
293*0Sstevel@tonic-gate 		return( err );
294*0Sstevel@tonic-gate 
295*0Sstevel@tonic-gate 	return( ldap_kerberos_bind2_s( ld, dn ) );
296*0Sstevel@tonic-gate }
297*0Sstevel@tonic-gate 
298*0Sstevel@tonic-gate 
299*0Sstevel@tonic-gate #ifndef AUTHMAN
300*0Sstevel@tonic-gate /*
301*0Sstevel@tonic-gate  * get_kerberosv4_credentials - obtain kerberos v4 credentials for ldap.
302*0Sstevel@tonic-gate  * The dn of the entry to which to bind is supplied.  It's assumed the
303*0Sstevel@tonic-gate  * user already has a tgt.
304*0Sstevel@tonic-gate  */
305*0Sstevel@tonic-gate 
306*0Sstevel@tonic-gate char *
307*0Sstevel@tonic-gate get_kerberosv4_credentials( LDAP *ld, char *who, char *service, int *len )
308*0Sstevel@tonic-gate {
309*0Sstevel@tonic-gate 	KTEXT_ST	ktxt;
310*0Sstevel@tonic-gate 	int		err;
311*0Sstevel@tonic-gate 	char		realm[REALM_SZ], *cred, *krbinstance;
312*0Sstevel@tonic-gate 
313*0Sstevel@tonic-gate 	Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 191, "get_kerberosv4_credentials\n"), 0, 0, 0 );
314*0Sstevel@tonic-gate 
315*0Sstevel@tonic-gate 	if ( (err = krb_get_tf_realm( tkt_string(), realm )) != KSUCCESS ) {
316*0Sstevel@tonic-gate #ifndef NO_USERINTERFACE
317*0Sstevel@tonic-gate 		fprintf( stderr, "krb_get_tf_realm failed (%s)\n",
318*0Sstevel@tonic-gate 		    krb_err_txt[err] );
319*0Sstevel@tonic-gate #endif /* NO_USERINTERFACE */
320*0Sstevel@tonic-gate 		ld->ld_errno = LDAP_INVALID_CREDENTIALS;
321*0Sstevel@tonic-gate 		return( NULL );
322*0Sstevel@tonic-gate 	}
323*0Sstevel@tonic-gate 
324*0Sstevel@tonic-gate #ifdef LDAP_REFERRALS
325*0Sstevel@tonic-gate 	krbinstance = ld->ld_defconn->lconn_krbinstance;
326*0Sstevel@tonic-gate #else /* LDAP_REFERRALS */
327*0Sstevel@tonic-gate 	krbinstance = ld->ld_host;
328*0Sstevel@tonic-gate #endif /* LDAP_REFERRALS */
329*0Sstevel@tonic-gate 
330*0Sstevel@tonic-gate 	if ( (err = krb_mk_req( &ktxt, service, krbinstance, realm, 0 ))
331*0Sstevel@tonic-gate 	    != KSUCCESS ) {
332*0Sstevel@tonic-gate #ifndef NO_USERINTERFACE
333*0Sstevel@tonic-gate 		fprintf( stderr, "krb_mk_req failed (%s)\n", krb_err_txt[err] );
334*0Sstevel@tonic-gate #endif /* NO_USERINTERFACE */
335*0Sstevel@tonic-gate 		ld->ld_errno = LDAP_INVALID_CREDENTIALS;
336*0Sstevel@tonic-gate 		return( NULL );
337*0Sstevel@tonic-gate 	}
338*0Sstevel@tonic-gate 
339*0Sstevel@tonic-gate 	if ( ( cred = malloc( ktxt.length )) == NULL ) {
340*0Sstevel@tonic-gate 		ld->ld_errno = LDAP_NO_MEMORY;
341*0Sstevel@tonic-gate 		return( NULL );
342*0Sstevel@tonic-gate 	}
343*0Sstevel@tonic-gate 
344*0Sstevel@tonic-gate 	*len = ktxt.length;
345*0Sstevel@tonic-gate 	memcpy( cred, ktxt.dat, ktxt.length );
346*0Sstevel@tonic-gate 
347*0Sstevel@tonic-gate 	return( cred );
348*0Sstevel@tonic-gate }
349*0Sstevel@tonic-gate 
350*0Sstevel@tonic-gate #endif /* !AUTHMAN */
351*0Sstevel@tonic-gate #endif /* KERBEROS */
352