126219Swpaul/* 226219Swpaul * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 326219Swpaul * unrestricted use provided that this legend is included on all tape 426219Swpaul * media and as a part of the software program in whole or part. Users 526219Swpaul * may copy or modify Sun RPC without charge, but are not authorized 626219Swpaul * to license or distribute it to anyone else except as part of a product or 726219Swpaul * program developed by the user. 826219Swpaul * 926219Swpaul * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 1026219Swpaul * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 1126219Swpaul * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 1226219Swpaul * 1326219Swpaul * Sun RPC is provided with no support and without any obligation on the 1426219Swpaul * part of Sun Microsystems, Inc. to assist in its use, correction, 1526219Swpaul * modification or enhancement. 1626219Swpaul * 1726219Swpaul * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 1826219Swpaul * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 1926219Swpaul * OR ANY PART THEREOF. 2026219Swpaul * 2126219Swpaul * In no event will Sun Microsystems, Inc. be liable for any lost revenue 2226219Swpaul * or profits or other special, indirect and consequential damages, even if 2326219Swpaul * Sun has been advised of the possibility of such damages. 2426219Swpaul * 2526219Swpaul * Sun Microsystems, Inc. 2626219Swpaul * 2550 Garcia Avenue 2726219Swpaul * Mountain View, California 94043 2826219Swpaul */ 2926219Swpaul/* 3026219Swpaul * Copyright (c) 1988 by Sun Microsystems, Inc. 3126219Swpaul */ 3226219Swpaul/* 3326219Swpaul * auth_des.c, client-side implementation of DES authentication 3426219Swpaul */ 3592990Sobrien 3675094Siedowse#include "namespace.h" 3774462Salfred#include "reentrant.h" 3874462Salfred#include <err.h> 3974462Salfred#include <errno.h> 4026219Swpaul#include <string.h> 4126219Swpaul#include <stdlib.h> 4226219Swpaul#include <unistd.h> 4326219Swpaul#include <sys/cdefs.h> 4426219Swpaul#include <rpc/des_crypt.h> 4574462Salfred#include <syslog.h> 4626219Swpaul#include <rpc/types.h> 4726219Swpaul#include <rpc/auth.h> 4826219Swpaul#include <rpc/auth_des.h> 4974462Salfred#include <rpc/clnt.h> 5074462Salfred#include <rpc/xdr.h> 5126219Swpaul#include <sys/socket.h> 5226219Swpaul#undef NIS 5326219Swpaul#include <rpcsvc/nis.h> 5474462Salfred#include "un-namespace.h" 55156090Sdeischen#include "mt_misc.h" 5626219Swpaul 5726219Swpaul#if defined(LIBC_SCCS) && !defined(lint) 58136581Sobrienstatic char sccsid[] = "@(#)auth_des.c 2.2 88/07/29 4.0 RPCSRC; from 1.9 88/02/08 SMI"; 5926219Swpaul#endif 6092990Sobrien#include <sys/cdefs.h> 6192990Sobrien__FBSDID("$FreeBSD$"); 6226219Swpaul 6374462Salfred#define USEC_PER_SEC 1000000 6474462Salfred#define RTIME_TIMEOUT 5 /* seconds to wait for sync */ 6526219Swpaul 6626219Swpaul#define AUTH_PRIVATE(auth) (struct ad_private *) auth->ah_private 6726219Swpaul#define ALLOC(object_type) (object_type *) mem_alloc(sizeof(object_type)) 6826219Swpaul#define FREE(ptr, size) mem_free((char *)(ptr), (int) size) 6926219Swpaul#define ATTEMPT(xdr_op) if (!(xdr_op)) return (FALSE) 7026219Swpaul 7174462Salfredextern bool_t xdr_authdes_cred( XDR *, struct authdes_cred *); 7274462Salfredextern bool_t xdr_authdes_verf( XDR *, struct authdes_verf *); 7374462Salfredextern int key_encryptsession_pk(); 7426219Swpaul 7574462Salfredextern bool_t __rpc_get_time_offset(struct timeval *, nis_server *, char *, 7674462Salfred char **, char **); 7774462Salfred 7826219Swpaul/* 7926219Swpaul * DES authenticator operations vector 8026219Swpaul */ 8174462Salfredstatic void authdes_nextverf(AUTH *); 8274462Salfredstatic bool_t authdes_marshal(AUTH *, XDR *); 8374462Salfredstatic bool_t authdes_validate(AUTH *, struct opaque_auth *); 8474462Salfredstatic bool_t authdes_refresh(AUTH *, void *); 8574462Salfredstatic void authdes_destroy(AUTH *); 8674462Salfred 8774462Salfredstatic struct auth_ops *authdes_ops(void); 8874462Salfred 8926219Swpaul/* 9026219Swpaul * This struct is pointed to by the ah_private field of an "AUTH *" 9126219Swpaul */ 9226219Swpaulstruct ad_private { 9326219Swpaul char *ad_fullname; /* client's full name */ 9426219Swpaul u_int ad_fullnamelen; /* length of name, rounded up */ 9526219Swpaul char *ad_servername; /* server's full name */ 9626219Swpaul u_int ad_servernamelen; /* length of name, rounded up */ 9726219Swpaul u_int ad_window; /* client specified window */ 9826219Swpaul bool_t ad_dosync; /* synchronize? */ 9974462Salfred struct netbuf ad_syncaddr; /* remote host to synch with */ 10026219Swpaul char *ad_timehost; /* remote host to synch with */ 10126219Swpaul struct timeval ad_timediff; /* server's time - client's time */ 10274462Salfred u_int ad_nickname; /* server's nickname for client */ 10326219Swpaul struct authdes_cred ad_cred; /* storage for credential */ 10426219Swpaul struct authdes_verf ad_verf; /* storage for verifier */ 10526219Swpaul struct timeval ad_timestamp; /* timestamp sent */ 10626219Swpaul des_block ad_xkey; /* encrypted conversation key */ 10726219Swpaul u_char ad_pkey[1024]; /* Server's actual public key */ 10826219Swpaul char *ad_netid; /* Timehost netid */ 10926219Swpaul char *ad_uaddr; /* Timehost uaddr */ 11026219Swpaul nis_server *ad_nis_srvr; /* NIS+ server struct */ 11126219Swpaul}; 11274462Salfred 11374462SalfredAUTH *authdes_pk_seccreate(const char *, netobj *, u_int, const char *, 11474462Salfred const des_block *, nis_server *); 11526219Swpaul 11674462Salfred/* 11774462Salfred * documented version of authdes_seccreate 11874462Salfred */ 11974462Salfred/* 12074462Salfred servername: network name of server 12174462Salfred win: time to live 12274462Salfred timehost: optional hostname to sync with 12374462Salfred ckey: optional conversation key to use 12474462Salfred*/ 12526219Swpaul 12626219SwpaulAUTH * 12774462Salfredauthdes_seccreate(const char *servername, const u_int win, 12874462Salfred const char *timehost, const des_block *ckey) 12926219Swpaul{ 13074462Salfred u_char pkey_data[1024]; 13174462Salfred netobj pkey; 13274462Salfred AUTH *dummy; 13326219Swpaul 13474462Salfred if (! getpublickey(servername, (char *) pkey_data)) { 13574462Salfred syslog(LOG_ERR, 13674462Salfred "authdes_seccreate: no public key found for %s", 13774462Salfred servername); 13874462Salfred return (NULL); 13926219Swpaul } 14026219Swpaul 14174462Salfred pkey.n_bytes = (char *) pkey_data; 14274462Salfred pkey.n_len = (u_int)strlen((char *)pkey_data) + 1; 14374462Salfred dummy = authdes_pk_seccreate(servername, &pkey, win, timehost, 14474462Salfred ckey, NULL); 14574462Salfred return (dummy); 14626219Swpaul} 14726219Swpaul 14826219Swpaul/* 14974462Salfred * Slightly modified version of authdessec_create which takes the public key 15026219Swpaul * of the server principal as an argument. This spares us a call to 15126219Swpaul * getpublickey() which in the nameserver context can cause a deadlock. 15226219Swpaul */ 15326219SwpaulAUTH * 15474462Salfredauthdes_pk_seccreate(const char *servername, netobj *pkey, u_int window, 15574462Salfred const char *timehost, const des_block *ckey, nis_server *srvr) 15626219Swpaul{ 15726219Swpaul AUTH *auth; 15826219Swpaul struct ad_private *ad; 15926219Swpaul char namebuf[MAXNETNAMELEN+1]; 16026219Swpaul 16126219Swpaul /* 16226219Swpaul * Allocate everything now 16326219Swpaul */ 16426219Swpaul auth = ALLOC(AUTH); 16526219Swpaul if (auth == NULL) { 16674462Salfred syslog(LOG_ERR, "authdes_pk_seccreate: out of memory"); 16726219Swpaul return (NULL); 16826219Swpaul } 16926219Swpaul ad = ALLOC(struct ad_private); 17026219Swpaul if (ad == NULL) { 17174462Salfred syslog(LOG_ERR, "authdes_pk_seccreate: out of memory"); 17226219Swpaul goto failed; 17326219Swpaul } 17426219Swpaul ad->ad_fullname = ad->ad_servername = NULL; /* Sanity reasons */ 17526219Swpaul ad->ad_timehost = NULL; 17626219Swpaul ad->ad_netid = NULL; 17726219Swpaul ad->ad_uaddr = NULL; 17826219Swpaul ad->ad_nis_srvr = NULL; 17926219Swpaul ad->ad_timediff.tv_sec = 0; 18026219Swpaul ad->ad_timediff.tv_usec = 0; 18126219Swpaul memcpy(ad->ad_pkey, pkey->n_bytes, pkey->n_len); 18226219Swpaul if (!getnetname(namebuf)) 18326219Swpaul goto failed; 18426219Swpaul ad->ad_fullnamelen = RNDUP((u_int) strlen(namebuf)); 18526219Swpaul ad->ad_fullname = (char *)mem_alloc(ad->ad_fullnamelen + 1); 18626219Swpaul ad->ad_servernamelen = strlen(servername); 18726219Swpaul ad->ad_servername = (char *)mem_alloc(ad->ad_servernamelen + 1); 18826219Swpaul 18926219Swpaul if (ad->ad_fullname == NULL || ad->ad_servername == NULL) { 19074462Salfred syslog(LOG_ERR, "authdes_seccreate: out of memory"); 19126219Swpaul goto failed; 19226219Swpaul } 19326219Swpaul if (timehost != NULL) { 19426219Swpaul ad->ad_timehost = (char *)mem_alloc(strlen(timehost) + 1); 19526219Swpaul if (ad->ad_timehost == NULL) { 19674462Salfred syslog(LOG_ERR, "authdes_seccreate: out of memory"); 19726219Swpaul goto failed; 19826219Swpaul } 19926219Swpaul memcpy(ad->ad_timehost, timehost, strlen(timehost) + 1); 20026219Swpaul ad->ad_dosync = TRUE; 20126219Swpaul } else if (srvr != NULL) { 20226219Swpaul ad->ad_nis_srvr = srvr; /* transient */ 20326219Swpaul ad->ad_dosync = TRUE; 20426219Swpaul } else { 20526219Swpaul ad->ad_dosync = FALSE; 20626219Swpaul } 20726219Swpaul memcpy(ad->ad_fullname, namebuf, ad->ad_fullnamelen + 1); 20826219Swpaul memcpy(ad->ad_servername, servername, ad->ad_servernamelen + 1); 20926219Swpaul ad->ad_window = window; 21026219Swpaul if (ckey == NULL) { 21126219Swpaul if (key_gendes(&auth->ah_key) < 0) { 21274462Salfred syslog(LOG_ERR, 21374462Salfred "authdes_seccreate: keyserv(1m) is unable to generate session key"); 21426219Swpaul goto failed; 21526219Swpaul } 21626219Swpaul } else { 21726219Swpaul auth->ah_key = *ckey; 21826219Swpaul } 21926219Swpaul 22026219Swpaul /* 22126219Swpaul * Set up auth handle 22226219Swpaul */ 22326219Swpaul auth->ah_cred.oa_flavor = AUTH_DES; 22426219Swpaul auth->ah_verf.oa_flavor = AUTH_DES; 22574462Salfred auth->ah_ops = authdes_ops(); 22626219Swpaul auth->ah_private = (caddr_t)ad; 22726219Swpaul 22874462Salfred if (!authdes_refresh(auth, NULL)) { 22926219Swpaul goto failed; 23026219Swpaul } 23126219Swpaul ad->ad_nis_srvr = NULL; /* not needed any longer */ 23226219Swpaul return (auth); 23326219Swpaul 23426219Swpaulfailed: 23526219Swpaul if (auth) 23626219Swpaul FREE(auth, sizeof (AUTH)); 23726219Swpaul if (ad) { 23826219Swpaul if (ad->ad_fullname) 23926219Swpaul FREE(ad->ad_fullname, ad->ad_fullnamelen + 1); 24026219Swpaul if (ad->ad_servername) 24126219Swpaul FREE(ad->ad_servername, ad->ad_servernamelen + 1); 24226219Swpaul if (ad->ad_timehost) 24326219Swpaul FREE(ad->ad_timehost, strlen(ad->ad_timehost) + 1); 24426219Swpaul if (ad->ad_netid) 24574462Salfred FREE(ad->ad_netid, strlen(ad->ad_netid) + 1); 24626219Swpaul if (ad->ad_uaddr) 24774462Salfred FREE(ad->ad_uaddr, strlen(ad->ad_uaddr) + 1); 24826219Swpaul FREE(ad, sizeof (struct ad_private)); 24926219Swpaul } 25026219Swpaul return (NULL); 25126219Swpaul} 25274462Salfred 25326219Swpaul/* 25426219Swpaul * Implement the five authentication operations 25526219Swpaul */ 25626219Swpaul 25726219Swpaul 25826219Swpaul/* 25926219Swpaul * 1. Next Verifier 26026219Swpaul */ 26126219Swpaul/*ARGSUSED*/ 26226219Swpaulstatic void 26374462Salfredauthdes_nextverf(AUTH *auth) 26426219Swpaul{ 26526219Swpaul /* what the heck am I supposed to do??? */ 26626219Swpaul} 26726219Swpaul 26826219Swpaul 26926219Swpaul/* 27026219Swpaul * 2. Marshal 27126219Swpaul */ 27226219Swpaulstatic bool_t 27374462Salfredauthdes_marshal(AUTH *auth, XDR *xdrs) 27426219Swpaul{ 27574462Salfred/* LINTED pointer alignment */ 27626219Swpaul struct ad_private *ad = AUTH_PRIVATE(auth); 27726219Swpaul struct authdes_cred *cred = &ad->ad_cred; 27826219Swpaul struct authdes_verf *verf = &ad->ad_verf; 27926219Swpaul des_block cryptbuf[2]; 28026219Swpaul des_block ivec; 28126219Swpaul int status; 28274462Salfred int len; 28392889Sobrien rpc_inline_t *ixdr; 28426219Swpaul 28526219Swpaul /* 28626219Swpaul * Figure out the "time", accounting for any time difference 28726219Swpaul * with the server if necessary. 28826219Swpaul */ 289239991Sed (void)gettimeofday(&ad->ad_timestamp, NULL); 29026219Swpaul ad->ad_timestamp.tv_sec += ad->ad_timediff.tv_sec; 29126219Swpaul ad->ad_timestamp.tv_usec += ad->ad_timediff.tv_usec; 29274462Salfred while (ad->ad_timestamp.tv_usec >= USEC_PER_SEC) { 29374462Salfred ad->ad_timestamp.tv_usec -= USEC_PER_SEC; 29474462Salfred ad->ad_timestamp.tv_sec++; 29526219Swpaul } 29626219Swpaul 29726219Swpaul /* 29826219Swpaul * XDR the timestamp and possibly some other things, then 29926219Swpaul * encrypt them. 30026219Swpaul */ 30174462Salfred ixdr = (rpc_inline_t *)cryptbuf; 30274462Salfred IXDR_PUT_INT32(ixdr, ad->ad_timestamp.tv_sec); 30374462Salfred IXDR_PUT_INT32(ixdr, ad->ad_timestamp.tv_usec); 30426219Swpaul if (ad->ad_cred.adc_namekind == ADN_FULLNAME) { 30574462Salfred IXDR_PUT_U_INT32(ixdr, ad->ad_window); 30674462Salfred IXDR_PUT_U_INT32(ixdr, ad->ad_window - 1); 30726219Swpaul ivec.key.high = ivec.key.low = 0; 30826219Swpaul status = cbc_crypt((char *)&auth->ah_key, (char *)cryptbuf, 30974462Salfred (u_int) 2 * sizeof (des_block), 31074462Salfred DES_ENCRYPT | DES_HW, (char *)&ivec); 31126219Swpaul } else { 31226219Swpaul status = ecb_crypt((char *)&auth->ah_key, (char *)cryptbuf, 31374462Salfred (u_int) sizeof (des_block), 31474462Salfred DES_ENCRYPT | DES_HW); 31526219Swpaul } 31626219Swpaul if (DES_FAILED(status)) { 31774462Salfred syslog(LOG_ERR, "authdes_marshal: DES encryption failure"); 31826219Swpaul return (FALSE); 31926219Swpaul } 32026219Swpaul ad->ad_verf.adv_xtimestamp = cryptbuf[0]; 32126219Swpaul if (ad->ad_cred.adc_namekind == ADN_FULLNAME) { 32226219Swpaul ad->ad_cred.adc_fullname.window = cryptbuf[1].key.high; 32326219Swpaul ad->ad_verf.adv_winverf = cryptbuf[1].key.low; 32426219Swpaul } else { 32526219Swpaul ad->ad_cred.adc_nickname = ad->ad_nickname; 32626219Swpaul ad->ad_verf.adv_winverf = 0; 32726219Swpaul } 32826219Swpaul 32926219Swpaul /* 33026219Swpaul * Serialize the credential and verifier into opaque 33126219Swpaul * authentication data. 33226219Swpaul */ 33326219Swpaul if (ad->ad_cred.adc_namekind == ADN_FULLNAME) { 33426219Swpaul len = ((1 + 1 + 2 + 1)*BYTES_PER_XDR_UNIT + ad->ad_fullnamelen); 33526219Swpaul } else { 33626219Swpaul len = (1 + 1)*BYTES_PER_XDR_UNIT; 33726219Swpaul } 33826219Swpaul 33926219Swpaul if ((ixdr = xdr_inline(xdrs, 2*BYTES_PER_XDR_UNIT))) { 34074462Salfred IXDR_PUT_INT32(ixdr, AUTH_DES); 34174462Salfred IXDR_PUT_INT32(ixdr, len); 34226219Swpaul } else { 34374462Salfred ATTEMPT(xdr_putint32(xdrs, (int *)&auth->ah_cred.oa_flavor)); 34474462Salfred ATTEMPT(xdr_putint32(xdrs, &len)); 34526219Swpaul } 34626219Swpaul ATTEMPT(xdr_authdes_cred(xdrs, cred)); 34726219Swpaul 34826219Swpaul len = (2 + 1)*BYTES_PER_XDR_UNIT; 34926219Swpaul if ((ixdr = xdr_inline(xdrs, 2*BYTES_PER_XDR_UNIT))) { 35074462Salfred IXDR_PUT_INT32(ixdr, AUTH_DES); 35174462Salfred IXDR_PUT_INT32(ixdr, len); 35226219Swpaul } else { 35374462Salfred ATTEMPT(xdr_putint32(xdrs, (int *)&auth->ah_verf.oa_flavor)); 35474462Salfred ATTEMPT(xdr_putint32(xdrs, &len)); 35526219Swpaul } 35626219Swpaul ATTEMPT(xdr_authdes_verf(xdrs, verf)); 35726219Swpaul return (TRUE); 35826219Swpaul} 35926219Swpaul 36026219Swpaul 36126219Swpaul/* 36226219Swpaul * 3. Validate 36326219Swpaul */ 36426219Swpaulstatic bool_t 36574462Salfredauthdes_validate(AUTH *auth, struct opaque_auth *rverf) 36626219Swpaul{ 36774462Salfred/* LINTED pointer alignment */ 36826219Swpaul struct ad_private *ad = AUTH_PRIVATE(auth); 36926219Swpaul struct authdes_verf verf; 37026219Swpaul int status; 37192889Sobrien uint32_t *ixdr; 37274462Salfred des_block buf; 37326219Swpaul 37426219Swpaul if (rverf->oa_length != (2 + 1) * BYTES_PER_XDR_UNIT) { 37526219Swpaul return (FALSE); 37626219Swpaul } 37774462Salfred/* LINTED pointer alignment */ 37874462Salfred ixdr = (uint32_t *)rverf->oa_base; 37974462Salfred buf.key.high = (uint32_t)*ixdr++; 38074462Salfred buf.key.low = (uint32_t)*ixdr++; 38174462Salfred verf.adv_int_u = (uint32_t)*ixdr++; 38226219Swpaul 38326219Swpaul /* 38426219Swpaul * Decrypt the timestamp 38526219Swpaul */ 38674462Salfred status = ecb_crypt((char *)&auth->ah_key, (char *)&buf, 38774462Salfred (u_int)sizeof (des_block), DES_DECRYPT | DES_HW); 38826219Swpaul 38926219Swpaul if (DES_FAILED(status)) { 39074462Salfred syslog(LOG_ERR, "authdes_validate: DES decryption failure"); 39126219Swpaul return (FALSE); 39226219Swpaul } 39326219Swpaul 39426219Swpaul /* 39574462Salfred * xdr the decrypted timestamp 39626219Swpaul */ 39774462Salfred/* LINTED pointer alignment */ 39874462Salfred ixdr = (uint32_t *)buf.c; 39974462Salfred verf.adv_timestamp.tv_sec = IXDR_GET_INT32(ixdr) + 1; 40074462Salfred verf.adv_timestamp.tv_usec = IXDR_GET_INT32(ixdr); 40126219Swpaul 40226219Swpaul /* 40326219Swpaul * validate 40426219Swpaul */ 40526219Swpaul if (bcmp((char *)&ad->ad_timestamp, (char *)&verf.adv_timestamp, 40626219Swpaul sizeof(struct timeval)) != 0) { 40774462Salfred syslog(LOG_DEBUG, "authdes_validate: verifier mismatch"); 40826219Swpaul return (FALSE); 40926219Swpaul } 41026219Swpaul 41126219Swpaul /* 41226219Swpaul * We have a nickname now, let's use it 41326219Swpaul */ 41474462Salfred ad->ad_nickname = verf.adv_nickname; 41574462Salfred ad->ad_cred.adc_namekind = ADN_NICKNAME; 41674462Salfred return (TRUE); 41726219Swpaul} 41826219Swpaul 41926219Swpaul/* 42026219Swpaul * 4. Refresh 42126219Swpaul */ 42274462Salfred/*ARGSUSED*/ 42326219Swpaulstatic bool_t 42474462Salfredauthdes_refresh(AUTH *auth, void *dummy) 42526219Swpaul{ 42674462Salfred/* LINTED pointer alignment */ 42726219Swpaul struct ad_private *ad = AUTH_PRIVATE(auth); 42826219Swpaul struct authdes_cred *cred = &ad->ad_cred; 42974462Salfred int ok; 43026219Swpaul netobj pkey; 43126219Swpaul 43274462Salfred if (ad->ad_dosync) { 43374462Salfred ok = __rpc_get_time_offset(&ad->ad_timediff, ad->ad_nis_srvr, 43474462Salfred ad->ad_timehost, &(ad->ad_uaddr), 43574462Salfred &(ad->ad_netid)); 43674462Salfred if (! ok) { 43774462Salfred /* 43874462Salfred * Hope the clocks are synced! 43974462Salfred */ 44074462Salfred ad->ad_dosync = 0; 44174462Salfred syslog(LOG_DEBUG, 44274462Salfred "authdes_refresh: unable to synchronize clock"); 44374462Salfred } 44426219Swpaul } 44526219Swpaul ad->ad_xkey = auth->ah_key; 44626219Swpaul pkey.n_bytes = (char *)(ad->ad_pkey); 44774462Salfred pkey.n_len = (u_int)strlen((char *)ad->ad_pkey) + 1; 44826219Swpaul if (key_encryptsession_pk(ad->ad_servername, &pkey, &ad->ad_xkey) < 0) { 44974462Salfred syslog(LOG_INFO, 45074462Salfred "authdes_refresh: keyserv(1m) is unable to encrypt session key"); 45126219Swpaul return (FALSE); 45226219Swpaul } 45326219Swpaul cred->adc_fullname.key = ad->ad_xkey; 45426219Swpaul cred->adc_namekind = ADN_FULLNAME; 45526219Swpaul cred->adc_fullname.name = ad->ad_fullname; 45626219Swpaul return (TRUE); 45726219Swpaul} 45826219Swpaul 45926219Swpaul 46026219Swpaul/* 46126219Swpaul * 5. Destroy 46226219Swpaul */ 46326219Swpaulstatic void 46474462Salfredauthdes_destroy(AUTH *auth) 46526219Swpaul{ 46674462Salfred/* LINTED pointer alignment */ 46726219Swpaul struct ad_private *ad = AUTH_PRIVATE(auth); 46826219Swpaul 46926219Swpaul FREE(ad->ad_fullname, ad->ad_fullnamelen + 1); 47026219Swpaul FREE(ad->ad_servername, ad->ad_servernamelen + 1); 47174462Salfred if (ad->ad_timehost) 47274462Salfred FREE(ad->ad_timehost, strlen(ad->ad_timehost) + 1); 47374462Salfred if (ad->ad_netid) 47474462Salfred FREE(ad->ad_netid, strlen(ad->ad_netid) + 1); 47574462Salfred if (ad->ad_uaddr) 47674462Salfred FREE(ad->ad_uaddr, strlen(ad->ad_uaddr) + 1); 47774462Salfred FREE(ad, sizeof (struct ad_private)); 47826219Swpaul FREE(auth, sizeof(AUTH)); 47926219Swpaul} 48026219Swpaul 48174462Salfredstatic struct auth_ops * 48274462Salfredauthdes_ops(void) 48326219Swpaul{ 48474462Salfred static struct auth_ops ops; 48526219Swpaul 48674462Salfred /* VARIABLES PROTECTED BY ops_lock: ops */ 48774462Salfred 48874462Salfred mutex_lock(&authdes_ops_lock); 48974462Salfred if (ops.ah_nextverf == NULL) { 49074462Salfred ops.ah_nextverf = authdes_nextverf; 49174462Salfred ops.ah_marshal = authdes_marshal; 49274462Salfred ops.ah_validate = authdes_validate; 49374462Salfred ops.ah_refresh = authdes_refresh; 49474462Salfred ops.ah_destroy = authdes_destroy; 49574462Salfred } 49674462Salfred mutex_unlock(&authdes_ops_lock); 49774462Salfred return (&ops); 49826219Swpaul} 499