xref: /titanic_41/usr/src/lib/libnsl/rpc/key_call.c (revision cb6207858a9fcc2feaee22e626912fba281ac969)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*cb620785Sraf  * Common Development and Distribution License (the "License").
6*cb620785Sraf  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
2161961e0fSrobinson 
227c478bd9Sstevel@tonic-gate /*
23*cb620785Sraf  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
26e8031f0aSraf 
277c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
287c478bd9Sstevel@tonic-gate /* All Rights Reserved */
297c478bd9Sstevel@tonic-gate /*
307c478bd9Sstevel@tonic-gate  * Portions of this source code were derived from Berkeley
317c478bd9Sstevel@tonic-gate  * 4.3 BSD under license from the Regents of the University of
327c478bd9Sstevel@tonic-gate  * California.
337c478bd9Sstevel@tonic-gate  */
347c478bd9Sstevel@tonic-gate 
357c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate /*
38e8031f0aSraf  * Interface to keyserver
397c478bd9Sstevel@tonic-gate  *
407c478bd9Sstevel@tonic-gate  * setsecretkey(key) - set your secret key
417c478bd9Sstevel@tonic-gate  * encryptsessionkey(agent, deskey) - encrypt a session key to talk to agent
427c478bd9Sstevel@tonic-gate  * decryptsessionkey(agent, deskey) - decrypt ditto
437c478bd9Sstevel@tonic-gate  * gendeskey(deskey) - generate a secure des key
447c478bd9Sstevel@tonic-gate  */
457c478bd9Sstevel@tonic-gate 
467c478bd9Sstevel@tonic-gate #include "mt.h"
477c478bd9Sstevel@tonic-gate #include "rpc_mt.h"
487c478bd9Sstevel@tonic-gate #include <errno.h>
497c478bd9Sstevel@tonic-gate #include <rpc/rpc.h>
507c478bd9Sstevel@tonic-gate #include <rpc/key_prot.h>
517c478bd9Sstevel@tonic-gate #include <stdio.h>
527c478bd9Sstevel@tonic-gate #include <syslog.h>
537c478bd9Sstevel@tonic-gate #include <string.h>
547c478bd9Sstevel@tonic-gate #include <stdlib.h>
557c478bd9Sstevel@tonic-gate #include <unistd.h>
567c478bd9Sstevel@tonic-gate #include <sys/types.h>
577c478bd9Sstevel@tonic-gate #include <sys/stat.h>
587c478bd9Sstevel@tonic-gate 
597c478bd9Sstevel@tonic-gate #define	CLASSIC_PK_DH(k, a)	(((k) == 192) && ((a) == 0))
607c478bd9Sstevel@tonic-gate 
617c478bd9Sstevel@tonic-gate #ifdef DEBUG
627c478bd9Sstevel@tonic-gate #define	debug(msg)	(void) fprintf(stderr, "%s\n", msg);
637c478bd9Sstevel@tonic-gate #else
647c478bd9Sstevel@tonic-gate #define	debug(msg)
657c478bd9Sstevel@tonic-gate #endif /* DEBUG */
667c478bd9Sstevel@tonic-gate 
677c478bd9Sstevel@tonic-gate int key_call(rpcproc_t, xdrproc_t, char *, xdrproc_t, char *);
687c478bd9Sstevel@tonic-gate int key_call_ext(rpcproc_t, xdrproc_t, char *, xdrproc_t, char *, int);
697c478bd9Sstevel@tonic-gate int key_setnet(struct key_netstarg *);
707c478bd9Sstevel@tonic-gate 
717c478bd9Sstevel@tonic-gate /*
727c478bd9Sstevel@tonic-gate  * Hack to allow the keyserver to use AUTH_DES (for authenticated
737c478bd9Sstevel@tonic-gate  * NIS+ calls, for example).  The only functions that get called
747c478bd9Sstevel@tonic-gate  * are key_encryptsession_pk, key_decryptsession_pk, and key_gendes.
757c478bd9Sstevel@tonic-gate  *
767c478bd9Sstevel@tonic-gate  * The approach is to have the keyserver fill in pointers to local
777c478bd9Sstevel@tonic-gate  * implementations of these functions, and to call those in key_call().
787c478bd9Sstevel@tonic-gate  */
797c478bd9Sstevel@tonic-gate 
807c478bd9Sstevel@tonic-gate bool_t (*__key_encryptsession_pk_LOCAL)() = NULL;
817c478bd9Sstevel@tonic-gate bool_t (*__key_decryptsession_pk_LOCAL)() = NULL;
827c478bd9Sstevel@tonic-gate bool_t (*__key_gendes_LOCAL)() = NULL;
837c478bd9Sstevel@tonic-gate 
847c478bd9Sstevel@tonic-gate 
857c478bd9Sstevel@tonic-gate int
key_setsecret(const char * secretkey)8661961e0fSrobinson key_setsecret(const char *secretkey)
877c478bd9Sstevel@tonic-gate {
887c478bd9Sstevel@tonic-gate 	char netName[MAXNETNAMELEN+1];
897c478bd9Sstevel@tonic-gate 	struct key_netstarg netst;
907c478bd9Sstevel@tonic-gate 	int ret;
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate 	if (getnetname(netName) == 0) {
937c478bd9Sstevel@tonic-gate 		debug("getnetname failed");
947c478bd9Sstevel@tonic-gate 		return (-1);
957c478bd9Sstevel@tonic-gate 	}
967c478bd9Sstevel@tonic-gate 
9761961e0fSrobinson 	(void) memcpy(netst.st_priv_key, secretkey, HEXKEYBYTES);
987c478bd9Sstevel@tonic-gate 	netst.st_pub_key[0] = 0;
997c478bd9Sstevel@tonic-gate 	netst.st_netname = netName;
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate 	/*
1027c478bd9Sstevel@tonic-gate 	 * Actual key login
1037c478bd9Sstevel@tonic-gate 	 * We perform the KEY_NET_PUT instead of the SET_KEY
1047c478bd9Sstevel@tonic-gate 	 * rpc call because key_secretkey_is_set function uses
1057c478bd9Sstevel@tonic-gate 	 * the KEY_NET_GET call which expects the netname to be
1067c478bd9Sstevel@tonic-gate 	 * set along with the key. Keylogin also uses KEY_NET_PUT.
1077c478bd9Sstevel@tonic-gate 	 */
1087c478bd9Sstevel@tonic-gate 	ret = key_setnet(&netst);
1097c478bd9Sstevel@tonic-gate 
1107c478bd9Sstevel@tonic-gate 	/* erase our copy of the secret key */
11161961e0fSrobinson 	(void) memset(netst.st_priv_key, '\0', HEXKEYBYTES);
1127c478bd9Sstevel@tonic-gate 
1137c478bd9Sstevel@tonic-gate 	if (ret == 1)
1147c478bd9Sstevel@tonic-gate 		return (0);
1157c478bd9Sstevel@tonic-gate 
1167c478bd9Sstevel@tonic-gate 	return (-1);
1177c478bd9Sstevel@tonic-gate }
1187c478bd9Sstevel@tonic-gate 
1197c478bd9Sstevel@tonic-gate int
key_setsecret_g(char * secretkey,keylen_t keylen,algtype_t algtype,des_block userkey)1207c478bd9Sstevel@tonic-gate key_setsecret_g(
1217c478bd9Sstevel@tonic-gate 	char *secretkey,
1227c478bd9Sstevel@tonic-gate 	keylen_t keylen,
1237c478bd9Sstevel@tonic-gate 	algtype_t algtype,
1247c478bd9Sstevel@tonic-gate 	des_block userkey)
1257c478bd9Sstevel@tonic-gate {
1267c478bd9Sstevel@tonic-gate 	setkeyarg3 arg;
1277c478bd9Sstevel@tonic-gate 	keystatus status;
1287c478bd9Sstevel@tonic-gate 
12961961e0fSrobinson 	if (CLASSIC_PK_DH(keylen, algtype))
1307c478bd9Sstevel@tonic-gate 		return (key_setsecret(secretkey));
1317c478bd9Sstevel@tonic-gate 	arg.key.keybuf3_len = keylen/4 + 1;
1327c478bd9Sstevel@tonic-gate 	arg.key.keybuf3_val = secretkey;
1337c478bd9Sstevel@tonic-gate 	arg.algtype = algtype;
1347c478bd9Sstevel@tonic-gate 	arg.keylen = keylen;
1357c478bd9Sstevel@tonic-gate 	arg.userkey = userkey;
1367c478bd9Sstevel@tonic-gate 	if (!key_call((rpcproc_t)KEY_SET_3, xdr_setkeyarg3, (char *)&arg,
13761961e0fSrobinson 			xdr_keystatus, (char *)&status))
1387c478bd9Sstevel@tonic-gate 		return (-1);
1397c478bd9Sstevel@tonic-gate 	if (status != KEY_SUCCESS) {
1407c478bd9Sstevel@tonic-gate 		debug("set3 status is nonzero");
1417c478bd9Sstevel@tonic-gate 		return (-1);
1427c478bd9Sstevel@tonic-gate 	}
1437c478bd9Sstevel@tonic-gate 	return (0);
1447c478bd9Sstevel@tonic-gate }
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate int
key_removesecret_g_ext(int use_uid)1477c478bd9Sstevel@tonic-gate key_removesecret_g_ext(int use_uid)
1487c478bd9Sstevel@tonic-gate {
1497c478bd9Sstevel@tonic-gate 	keystatus status;
1507c478bd9Sstevel@tonic-gate 
15161961e0fSrobinson 	if (!key_call_ext((rpcproc_t)KEY_CLEAR_3, xdr_void, NULL,
1527c478bd9Sstevel@tonic-gate 			xdr_keystatus, (char *)&status, use_uid)) {
1537c478bd9Sstevel@tonic-gate 		debug("remove secret key call failed");
1547c478bd9Sstevel@tonic-gate 		return (-1);
1557c478bd9Sstevel@tonic-gate 	}
1567c478bd9Sstevel@tonic-gate 	if (status != KEY_SUCCESS) {
1577c478bd9Sstevel@tonic-gate 		debug("remove secret status is nonzero");
1587c478bd9Sstevel@tonic-gate 		return (-1);
1597c478bd9Sstevel@tonic-gate 	}
1607c478bd9Sstevel@tonic-gate 	return (0);
1617c478bd9Sstevel@tonic-gate }
1627c478bd9Sstevel@tonic-gate 
1637c478bd9Sstevel@tonic-gate /*
1647c478bd9Sstevel@tonic-gate  * Use effective uid.
1657c478bd9Sstevel@tonic-gate  */
1667c478bd9Sstevel@tonic-gate int
key_removesecret_g(void)16761961e0fSrobinson key_removesecret_g(void)
1687c478bd9Sstevel@tonic-gate {
1697c478bd9Sstevel@tonic-gate 	return (key_removesecret_g_ext(0));
1707c478bd9Sstevel@tonic-gate }
1717c478bd9Sstevel@tonic-gate 
1727c478bd9Sstevel@tonic-gate /*
1737c478bd9Sstevel@tonic-gate  * Use real uid.
1747c478bd9Sstevel@tonic-gate  */
1757c478bd9Sstevel@tonic-gate int
key_removesecret_g_ruid(void)17661961e0fSrobinson key_removesecret_g_ruid(void)
1777c478bd9Sstevel@tonic-gate {
1787c478bd9Sstevel@tonic-gate 	return (key_removesecret_g_ext(1));
1797c478bd9Sstevel@tonic-gate }
1807c478bd9Sstevel@tonic-gate 
1817c478bd9Sstevel@tonic-gate /*
1827c478bd9Sstevel@tonic-gate  * key_secretkey_is_set() returns 1 if the keyserver has a secret key
1837c478bd9Sstevel@tonic-gate  * stored for the caller's effective uid if use_ruid is 0 or
1847c478bd9Sstevel@tonic-gate  * stored for the caller's real uid if use_ruid is 1.
1857c478bd9Sstevel@tonic-gate  * it returns 0 otherwise.
1867c478bd9Sstevel@tonic-gate  *
1877c478bd9Sstevel@tonic-gate  * N.B.:  The KEY_NET_GET key call is undocumented.  Applications shouldn't
1887c478bd9Sstevel@tonic-gate  * be using it, because it allows them to get the user's secret key.
1897c478bd9Sstevel@tonic-gate  *
1907c478bd9Sstevel@tonic-gate  */
1917c478bd9Sstevel@tonic-gate int
key_secretkey_is_set_ext(int use_ruid)1927c478bd9Sstevel@tonic-gate key_secretkey_is_set_ext(int use_ruid)
1937c478bd9Sstevel@tonic-gate {
1947c478bd9Sstevel@tonic-gate 	struct key_netstres 	kres;
1957c478bd9Sstevel@tonic-gate 
19661961e0fSrobinson 	(void) memset(&kres, 0, sizeof (kres));
19761961e0fSrobinson 	if (key_call_ext((rpcproc_t)KEY_NET_GET, xdr_void, NULL,
1987c478bd9Sstevel@tonic-gate 			xdr_key_netstres, (char *)&kres, use_ruid) &&
1997c478bd9Sstevel@tonic-gate 	    (kres.status == KEY_SUCCESS) &&
2007c478bd9Sstevel@tonic-gate 	    (kres.key_netstres_u.knet.st_priv_key[0] != 0)) {
2017c478bd9Sstevel@tonic-gate 		/* avoid leaving secret key in memory */
20261961e0fSrobinson 		(void) memset(kres.key_netstres_u.knet.st_priv_key, 0,
20361961e0fSrobinson 							HEXKEYBYTES);
2047c478bd9Sstevel@tonic-gate 		xdr_free(xdr_key_netstres, (char *)&kres);
2057c478bd9Sstevel@tonic-gate 		return (1);
2067c478bd9Sstevel@tonic-gate 	}
2077c478bd9Sstevel@tonic-gate 	return (0);
2087c478bd9Sstevel@tonic-gate }
2097c478bd9Sstevel@tonic-gate 
2107c478bd9Sstevel@tonic-gate /*
2117c478bd9Sstevel@tonic-gate  * Use effective uid.
2127c478bd9Sstevel@tonic-gate  */
2137c478bd9Sstevel@tonic-gate int
key_secretkey_is_set(void)2147c478bd9Sstevel@tonic-gate key_secretkey_is_set(void)
2157c478bd9Sstevel@tonic-gate {
2167c478bd9Sstevel@tonic-gate 	return (key_secretkey_is_set_ext(0));
2177c478bd9Sstevel@tonic-gate }
2187c478bd9Sstevel@tonic-gate 
2197c478bd9Sstevel@tonic-gate /*
2207c478bd9Sstevel@tonic-gate  * Use real uid.
2217c478bd9Sstevel@tonic-gate  */
2227c478bd9Sstevel@tonic-gate int
key_secretkey_is_set_ruid(void)2237c478bd9Sstevel@tonic-gate key_secretkey_is_set_ruid(void)
2247c478bd9Sstevel@tonic-gate {
2257c478bd9Sstevel@tonic-gate 	return (key_secretkey_is_set_ext(1));
2267c478bd9Sstevel@tonic-gate }
2277c478bd9Sstevel@tonic-gate 
2287c478bd9Sstevel@tonic-gate /*
2297c478bd9Sstevel@tonic-gate  * key_secretkey_is_set_g_ext() returns 1 if the keyserver has a secret key
2307c478bd9Sstevel@tonic-gate  * stored for the caller's uid, it returns 0 otherwise.
2317c478bd9Sstevel@tonic-gate  * If (use_ruid == 0), for the caller's effective uid.
2327c478bd9Sstevel@tonic-gate  * If (use_ruid == 1), for the caller's real uid.
2337c478bd9Sstevel@tonic-gate  *
2347c478bd9Sstevel@tonic-gate  * N.B.:  The KEY_NET_GET_3 key call is undocumented.  Applications shouldn't
2357c478bd9Sstevel@tonic-gate  * be using it, because it allows them to get the user's secret key.
2367c478bd9Sstevel@tonic-gate  */
2377c478bd9Sstevel@tonic-gate int
key_secretkey_is_set_g_ext(keylen_t keylen,algtype_t algtype,int use_ruid)2387c478bd9Sstevel@tonic-gate key_secretkey_is_set_g_ext(keylen_t keylen, algtype_t algtype, int use_ruid)
2397c478bd9Sstevel@tonic-gate {
2407c478bd9Sstevel@tonic-gate 	mechtype arg;
2417c478bd9Sstevel@tonic-gate 	key_netstres3 	kres;
2427c478bd9Sstevel@tonic-gate 
2437c478bd9Sstevel@tonic-gate 	/*
2447c478bd9Sstevel@tonic-gate 	 * key_secretkey_is_set_g_ext is tricky because keylen == 0
2457c478bd9Sstevel@tonic-gate 	 * means check if any key exists for the caller (old/new, 192/1024 ...)
2467c478bd9Sstevel@tonic-gate 	 * Rather than handle this on the server side, we call the old
2477c478bd9Sstevel@tonic-gate 	 * routine if keylen == 0 and try the newer stuff only if that fails
2487c478bd9Sstevel@tonic-gate 	 */
24961961e0fSrobinson 	if ((keylen == 0) && key_secretkey_is_set_ext(use_ruid))
2507c478bd9Sstevel@tonic-gate 		return (1);
25161961e0fSrobinson 	if (CLASSIC_PK_DH(keylen, algtype))
2527c478bd9Sstevel@tonic-gate 		return (key_secretkey_is_set_ext(use_ruid));
2537c478bd9Sstevel@tonic-gate 	arg.keylen = keylen;
2547c478bd9Sstevel@tonic-gate 	arg.algtype = algtype;
25561961e0fSrobinson 	(void) memset(&kres, 0, sizeof (kres));
2567c478bd9Sstevel@tonic-gate 	if (key_call_ext((rpcproc_t)KEY_NET_GET_3, xdr_mechtype, (char *)&arg,
2577c478bd9Sstevel@tonic-gate 			xdr_key_netstres3, (char *)&kres, use_ruid) &&
2587c478bd9Sstevel@tonic-gate 	    (kres.status == KEY_SUCCESS) &&
2597c478bd9Sstevel@tonic-gate 	    (kres.key_netstres3_u.knet.st_priv_key.keybuf3_len != 0)) {
2607c478bd9Sstevel@tonic-gate 		/* avoid leaving secret key in memory */
26161961e0fSrobinson 		(void) memset(kres.key_netstres3_u.knet.st_priv_key.keybuf3_val,
26261961e0fSrobinson 			0, kres.key_netstres3_u.knet.st_priv_key.keybuf3_len);
2637c478bd9Sstevel@tonic-gate 		xdr_free(xdr_key_netstres3, (char *)&kres);
2647c478bd9Sstevel@tonic-gate 		return (1);
2657c478bd9Sstevel@tonic-gate 	}
2667c478bd9Sstevel@tonic-gate 	return (0);
2677c478bd9Sstevel@tonic-gate }
2687c478bd9Sstevel@tonic-gate 
2697c478bd9Sstevel@tonic-gate /*
2707c478bd9Sstevel@tonic-gate  * Use effective uid.
2717c478bd9Sstevel@tonic-gate  */
2727c478bd9Sstevel@tonic-gate int
key_secretkey_is_set_g(keylen_t keylen,algtype_t algtype)2737c478bd9Sstevel@tonic-gate key_secretkey_is_set_g(keylen_t keylen, algtype_t algtype)
2747c478bd9Sstevel@tonic-gate {
2757c478bd9Sstevel@tonic-gate 	return (key_secretkey_is_set_g_ext(keylen, algtype, 0));
2767c478bd9Sstevel@tonic-gate }
2777c478bd9Sstevel@tonic-gate 
2787c478bd9Sstevel@tonic-gate /*
2797c478bd9Sstevel@tonic-gate  * Use real uid.
2807c478bd9Sstevel@tonic-gate  */
2817c478bd9Sstevel@tonic-gate int
key_secretkey_is_set_g_ruid(keylen_t keylen,algtype_t algtype)2827c478bd9Sstevel@tonic-gate key_secretkey_is_set_g_ruid(keylen_t keylen, algtype_t algtype)
2837c478bd9Sstevel@tonic-gate {
2847c478bd9Sstevel@tonic-gate 	return (key_secretkey_is_set_g_ext(keylen, algtype, 1));
2857c478bd9Sstevel@tonic-gate }
2867c478bd9Sstevel@tonic-gate 
2877c478bd9Sstevel@tonic-gate 
2887c478bd9Sstevel@tonic-gate int
key_encryptsession_pk(const char * remotename,netobj * remotekey,des_block * deskey)28961961e0fSrobinson key_encryptsession_pk(const char *remotename, netobj *remotekey,
29061961e0fSrobinson 							des_block *deskey)
2917c478bd9Sstevel@tonic-gate {
2927c478bd9Sstevel@tonic-gate 	cryptkeyarg2 arg;
2937c478bd9Sstevel@tonic-gate 	cryptkeyres res;
2947c478bd9Sstevel@tonic-gate 
29561961e0fSrobinson 	arg.remotename = (char *)remotename;
2967c478bd9Sstevel@tonic-gate 	arg.remotekey = *remotekey;
2977c478bd9Sstevel@tonic-gate 	arg.deskey = *deskey;
2987c478bd9Sstevel@tonic-gate 	if (!key_call((rpcproc_t)KEY_ENCRYPT_PK, xdr_cryptkeyarg2, (char *)&arg,
29961961e0fSrobinson 			xdr_cryptkeyres, (char *)&res))
3007c478bd9Sstevel@tonic-gate 		return (-1);
3017c478bd9Sstevel@tonic-gate 	if (res.status != KEY_SUCCESS) {
3027c478bd9Sstevel@tonic-gate 		debug("encrypt status is nonzero");
3037c478bd9Sstevel@tonic-gate 		return (-1);
3047c478bd9Sstevel@tonic-gate 	}
3057c478bd9Sstevel@tonic-gate 	*deskey = res.cryptkeyres_u.deskey;
3067c478bd9Sstevel@tonic-gate 	return (0);
3077c478bd9Sstevel@tonic-gate }
3087c478bd9Sstevel@tonic-gate 
3097c478bd9Sstevel@tonic-gate int
key_encryptsession_pk_g(const char * remotename,const char * remotekey,keylen_t remotekeylen,algtype_t algtype,des_block deskey[],keynum_t keynum)3107c478bd9Sstevel@tonic-gate key_encryptsession_pk_g(
3117c478bd9Sstevel@tonic-gate 	const char *remotename,
3127c478bd9Sstevel@tonic-gate 	const char *remotekey,
3137c478bd9Sstevel@tonic-gate 	keylen_t remotekeylen,
3147c478bd9Sstevel@tonic-gate 	algtype_t algtype,
3157c478bd9Sstevel@tonic-gate 	des_block deskey[],
3167c478bd9Sstevel@tonic-gate 	keynum_t keynum
3177c478bd9Sstevel@tonic-gate )
3187c478bd9Sstevel@tonic-gate {
3197c478bd9Sstevel@tonic-gate 	cryptkeyarg3 arg;
3207c478bd9Sstevel@tonic-gate 	cryptkeyres3 res;
3217c478bd9Sstevel@tonic-gate 
3227c478bd9Sstevel@tonic-gate 	if (CLASSIC_PK_DH(remotekeylen, algtype)) {
3237c478bd9Sstevel@tonic-gate 		int i;
3247c478bd9Sstevel@tonic-gate 		netobj npk;
3257c478bd9Sstevel@tonic-gate 
3267c478bd9Sstevel@tonic-gate 		npk.n_len = remotekeylen/4 + 1;
3277c478bd9Sstevel@tonic-gate 		npk.n_bytes = (char *)remotekey;
3287c478bd9Sstevel@tonic-gate 		for (i = 0; i < keynum; i++) {
32961961e0fSrobinson 			if (key_encryptsession_pk(remotename, &npk, &deskey[i]))
3307c478bd9Sstevel@tonic-gate 				return (-1);
3317c478bd9Sstevel@tonic-gate 		}
3327c478bd9Sstevel@tonic-gate 		return (0);
3337c478bd9Sstevel@tonic-gate 	}
3347c478bd9Sstevel@tonic-gate 	arg.remotename = (char *)remotename;
3357c478bd9Sstevel@tonic-gate 	arg.remotekey.keybuf3_len = remotekeylen/4 + 1;
3367c478bd9Sstevel@tonic-gate 	arg.remotekey.keybuf3_val = (char *)remotekey;
3377c478bd9Sstevel@tonic-gate 	arg.keylen = remotekeylen;
3387c478bd9Sstevel@tonic-gate 	arg.algtype = algtype;
3397c478bd9Sstevel@tonic-gate 	arg.deskey.deskeyarray_len = keynum;
3407c478bd9Sstevel@tonic-gate 	arg.deskey.deskeyarray_val = deskey;
34161961e0fSrobinson 	(void) memset(&res, 0, sizeof (res));
3427c478bd9Sstevel@tonic-gate 	res.cryptkeyres3_u.deskey.deskeyarray_val = deskey;
3437c478bd9Sstevel@tonic-gate 	if (!key_call((rpcproc_t)KEY_ENCRYPT_PK_3,
3447c478bd9Sstevel@tonic-gate 			xdr_cryptkeyarg3, (char *)&arg,
34561961e0fSrobinson 			xdr_cryptkeyres3, (char *)&res))
3467c478bd9Sstevel@tonic-gate 		return (-1);
3477c478bd9Sstevel@tonic-gate 	if (res.status != KEY_SUCCESS) {
3487c478bd9Sstevel@tonic-gate 		debug("encrypt3 status is nonzero");
3497c478bd9Sstevel@tonic-gate 		return (-1);
3507c478bd9Sstevel@tonic-gate 	}
3517c478bd9Sstevel@tonic-gate 	if (res.cryptkeyres3_u.deskey.deskeyarray_len != keynum) {
3527c478bd9Sstevel@tonic-gate 		debug("number of keys don't match");
3537c478bd9Sstevel@tonic-gate 		return (-1);
3547c478bd9Sstevel@tonic-gate 	}
3557c478bd9Sstevel@tonic-gate 	return (0);
3567c478bd9Sstevel@tonic-gate }
3577c478bd9Sstevel@tonic-gate 
3587c478bd9Sstevel@tonic-gate int
key_decryptsession_pk(const char * remotename,netobj * remotekey,des_block * deskey)35961961e0fSrobinson key_decryptsession_pk(const char *remotename, netobj *remotekey,
36061961e0fSrobinson 							des_block *deskey)
3617c478bd9Sstevel@tonic-gate {
3627c478bd9Sstevel@tonic-gate 	cryptkeyarg2 arg;
3637c478bd9Sstevel@tonic-gate 	cryptkeyres res;
3647c478bd9Sstevel@tonic-gate 
36561961e0fSrobinson 	arg.remotename = (char *)remotename;
3667c478bd9Sstevel@tonic-gate 	arg.remotekey = *remotekey;
3677c478bd9Sstevel@tonic-gate 	arg.deskey = *deskey;
3687c478bd9Sstevel@tonic-gate 	if (!key_call((rpcproc_t)KEY_DECRYPT_PK, xdr_cryptkeyarg2, (char *)&arg,
36961961e0fSrobinson 			xdr_cryptkeyres, (char *)&res))
3707c478bd9Sstevel@tonic-gate 		return (-1);
3717c478bd9Sstevel@tonic-gate 	if (res.status != KEY_SUCCESS) {
3727c478bd9Sstevel@tonic-gate 		debug("decrypt status is nonzero");
3737c478bd9Sstevel@tonic-gate 		return (-1);
3747c478bd9Sstevel@tonic-gate 	}
3757c478bd9Sstevel@tonic-gate 	*deskey = res.cryptkeyres_u.deskey;
3767c478bd9Sstevel@tonic-gate 	return (0);
3777c478bd9Sstevel@tonic-gate }
3787c478bd9Sstevel@tonic-gate 
3797c478bd9Sstevel@tonic-gate int
key_decryptsession_pk_g(const char * remotename,const char * remotekey,keylen_t remotekeylen,algtype_t algtype,des_block deskey[],keynum_t keynum)3807c478bd9Sstevel@tonic-gate key_decryptsession_pk_g(
3817c478bd9Sstevel@tonic-gate 	const char *remotename,
3827c478bd9Sstevel@tonic-gate 	const char *remotekey,
3837c478bd9Sstevel@tonic-gate 	keylen_t remotekeylen,
3847c478bd9Sstevel@tonic-gate 	algtype_t algtype,
3857c478bd9Sstevel@tonic-gate 	des_block deskey[],
3867c478bd9Sstevel@tonic-gate 	keynum_t keynum
3877c478bd9Sstevel@tonic-gate )
3887c478bd9Sstevel@tonic-gate {
3897c478bd9Sstevel@tonic-gate 	cryptkeyarg3 arg;
3907c478bd9Sstevel@tonic-gate 	cryptkeyres3 res;
3917c478bd9Sstevel@tonic-gate 
3927c478bd9Sstevel@tonic-gate 	if (CLASSIC_PK_DH(remotekeylen, algtype)) {
3937c478bd9Sstevel@tonic-gate 		int i;
3947c478bd9Sstevel@tonic-gate 		netobj npk;
3957c478bd9Sstevel@tonic-gate 
3967c478bd9Sstevel@tonic-gate 		npk.n_len = remotekeylen/4 + 1;
3977c478bd9Sstevel@tonic-gate 		npk.n_bytes = (char *)remotekey;
3987c478bd9Sstevel@tonic-gate 		for (i = 0; i < keynum; i++) {
39961961e0fSrobinson 			if (key_decryptsession_pk(remotename,
4007c478bd9Sstevel@tonic-gate 					&npk, &deskey[i]))
4017c478bd9Sstevel@tonic-gate 				return (-1);
4027c478bd9Sstevel@tonic-gate 		}
4037c478bd9Sstevel@tonic-gate 		return (0);
4047c478bd9Sstevel@tonic-gate 	}
4057c478bd9Sstevel@tonic-gate 	arg.remotename = (char *)remotename;
4067c478bd9Sstevel@tonic-gate 	arg.remotekey.keybuf3_len = remotekeylen/4 + 1;
4077c478bd9Sstevel@tonic-gate 	arg.remotekey.keybuf3_val = (char *)remotekey;
4087c478bd9Sstevel@tonic-gate 	arg.deskey.deskeyarray_len = keynum;
4097c478bd9Sstevel@tonic-gate 	arg.deskey.deskeyarray_val = deskey;
4107c478bd9Sstevel@tonic-gate 	arg.algtype = algtype;
4117c478bd9Sstevel@tonic-gate 	arg.keylen = remotekeylen;
41261961e0fSrobinson 	(void) memset(&res, 0, sizeof (res));
4137c478bd9Sstevel@tonic-gate 	res.cryptkeyres3_u.deskey.deskeyarray_val = deskey;
4147c478bd9Sstevel@tonic-gate 	if (!key_call((rpcproc_t)KEY_DECRYPT_PK_3,
4157c478bd9Sstevel@tonic-gate 			xdr_cryptkeyarg3, (char *)&arg,
41661961e0fSrobinson 			xdr_cryptkeyres3, (char *)&res))
4177c478bd9Sstevel@tonic-gate 		return (-1);
4187c478bd9Sstevel@tonic-gate 	if (res.status != KEY_SUCCESS) {
4197c478bd9Sstevel@tonic-gate 		debug("decrypt3 status is nonzero");
4207c478bd9Sstevel@tonic-gate 		return (-1);
4217c478bd9Sstevel@tonic-gate 	}
4227c478bd9Sstevel@tonic-gate 	if (res.cryptkeyres3_u.deskey.deskeyarray_len != keynum) {
4237c478bd9Sstevel@tonic-gate 		debug("number of keys don't match");
4247c478bd9Sstevel@tonic-gate 		return (-1);
4257c478bd9Sstevel@tonic-gate 	}
4267c478bd9Sstevel@tonic-gate 	return (0);
4277c478bd9Sstevel@tonic-gate }
4287c478bd9Sstevel@tonic-gate 
4297c478bd9Sstevel@tonic-gate int
key_encryptsession(const char * remotename,des_block * deskey)43061961e0fSrobinson key_encryptsession(const char *remotename, des_block *deskey)
4317c478bd9Sstevel@tonic-gate {
4327c478bd9Sstevel@tonic-gate 	cryptkeyarg arg;
4337c478bd9Sstevel@tonic-gate 	cryptkeyres res;
4347c478bd9Sstevel@tonic-gate 
4357c478bd9Sstevel@tonic-gate 	arg.remotename = (char *)remotename;
4367c478bd9Sstevel@tonic-gate 	arg.deskey = *deskey;
4377c478bd9Sstevel@tonic-gate 	if (!key_call((rpcproc_t)KEY_ENCRYPT, xdr_cryptkeyarg, (char *)&arg,
43861961e0fSrobinson 			xdr_cryptkeyres, (char *)&res))
4397c478bd9Sstevel@tonic-gate 		return (-1);
4407c478bd9Sstevel@tonic-gate 	if (res.status != KEY_SUCCESS) {
4417c478bd9Sstevel@tonic-gate 		debug("encrypt status is nonzero");
4427c478bd9Sstevel@tonic-gate 		return (-1);
4437c478bd9Sstevel@tonic-gate 	}
4447c478bd9Sstevel@tonic-gate 	*deskey = res.cryptkeyres_u.deskey;
4457c478bd9Sstevel@tonic-gate 	return (0);
4467c478bd9Sstevel@tonic-gate }
4477c478bd9Sstevel@tonic-gate 
4487c478bd9Sstevel@tonic-gate int
key_encryptsession_g(const char * remotename,keylen_t keylen,algtype_t algtype,des_block deskey[],keynum_t keynum)4497c478bd9Sstevel@tonic-gate key_encryptsession_g(
4507c478bd9Sstevel@tonic-gate 	const char *remotename,
4517c478bd9Sstevel@tonic-gate 	keylen_t keylen,
4527c478bd9Sstevel@tonic-gate 	algtype_t algtype,
4537c478bd9Sstevel@tonic-gate 	des_block deskey[],
4547c478bd9Sstevel@tonic-gate 	keynum_t keynum
4557c478bd9Sstevel@tonic-gate )
4567c478bd9Sstevel@tonic-gate {
4577c478bd9Sstevel@tonic-gate 	cryptkeyarg3 arg;
4587c478bd9Sstevel@tonic-gate 	cryptkeyres3 res;
4597c478bd9Sstevel@tonic-gate 
46061961e0fSrobinson 	if (CLASSIC_PK_DH(keylen, algtype))
4617c478bd9Sstevel@tonic-gate 		return (key_encryptsession(remotename, deskey));
4627c478bd9Sstevel@tonic-gate 	arg.remotename = (char *)remotename;
4637c478bd9Sstevel@tonic-gate 	arg.algtype = algtype;
4647c478bd9Sstevel@tonic-gate 	arg.keylen = keylen;
4657c478bd9Sstevel@tonic-gate 	arg.deskey.deskeyarray_len = keynum;
4667c478bd9Sstevel@tonic-gate 	arg.deskey.deskeyarray_val = deskey;
4677c478bd9Sstevel@tonic-gate 	arg.remotekey.keybuf3_len = 0;
46861961e0fSrobinson 	(void) memset(&res, 0, sizeof (res));
4697c478bd9Sstevel@tonic-gate 	res.cryptkeyres3_u.deskey.deskeyarray_val = deskey;
4707c478bd9Sstevel@tonic-gate 	if (!key_call((rpcproc_t)KEY_ENCRYPT_3, xdr_cryptkeyarg3, (char *)&arg,
47161961e0fSrobinson 			xdr_cryptkeyres3, (char *)&res))
4727c478bd9Sstevel@tonic-gate 		return (-1);
4737c478bd9Sstevel@tonic-gate 	if (res.status != KEY_SUCCESS) {
4747c478bd9Sstevel@tonic-gate 		debug("encrypt3 status is nonzero");
4757c478bd9Sstevel@tonic-gate 		return (-1);
4767c478bd9Sstevel@tonic-gate 	}
4777c478bd9Sstevel@tonic-gate 	if (res.cryptkeyres3_u.deskey.deskeyarray_len != keynum) {
4787c478bd9Sstevel@tonic-gate 		debug("encrypt3 didn't return same number of keys");
4797c478bd9Sstevel@tonic-gate 		return (-1);
4807c478bd9Sstevel@tonic-gate 	}
4817c478bd9Sstevel@tonic-gate 	return (0);
4827c478bd9Sstevel@tonic-gate }
4837c478bd9Sstevel@tonic-gate 
4847c478bd9Sstevel@tonic-gate 
4857c478bd9Sstevel@tonic-gate int
key_decryptsession(const char * remotename,des_block * deskey)48661961e0fSrobinson key_decryptsession(const char *remotename, des_block *deskey)
4877c478bd9Sstevel@tonic-gate {
4887c478bd9Sstevel@tonic-gate 	cryptkeyarg arg;
4897c478bd9Sstevel@tonic-gate 	cryptkeyres res;
4907c478bd9Sstevel@tonic-gate 
4917c478bd9Sstevel@tonic-gate 	arg.remotename = (char *)remotename;
4927c478bd9Sstevel@tonic-gate 	arg.deskey = *deskey;
4937c478bd9Sstevel@tonic-gate 	if (!key_call((rpcproc_t)KEY_DECRYPT, xdr_cryptkeyarg, (char *)&arg,
49461961e0fSrobinson 			xdr_cryptkeyres, (char *)&res))
4957c478bd9Sstevel@tonic-gate 		return (-1);
4967c478bd9Sstevel@tonic-gate 	if (res.status != KEY_SUCCESS) {
4977c478bd9Sstevel@tonic-gate 		debug("decrypt status is nonzero");
4987c478bd9Sstevel@tonic-gate 		return (-1);
4997c478bd9Sstevel@tonic-gate 	}
5007c478bd9Sstevel@tonic-gate 	*deskey = res.cryptkeyres_u.deskey;
5017c478bd9Sstevel@tonic-gate 	return (0);
5027c478bd9Sstevel@tonic-gate }
5037c478bd9Sstevel@tonic-gate 
5047c478bd9Sstevel@tonic-gate int
key_decryptsession_g(const char * remotename,keylen_t keylen,algtype_t algtype,des_block deskey[],keynum_t keynum)5057c478bd9Sstevel@tonic-gate key_decryptsession_g(
5067c478bd9Sstevel@tonic-gate 	const char *remotename,
5077c478bd9Sstevel@tonic-gate 	keylen_t keylen,
5087c478bd9Sstevel@tonic-gate 	algtype_t algtype,
5097c478bd9Sstevel@tonic-gate 	des_block deskey[],
5107c478bd9Sstevel@tonic-gate 	keynum_t keynum
5117c478bd9Sstevel@tonic-gate )
5127c478bd9Sstevel@tonic-gate {
5137c478bd9Sstevel@tonic-gate 	cryptkeyarg3 arg;
5147c478bd9Sstevel@tonic-gate 	cryptkeyres3 res;
5157c478bd9Sstevel@tonic-gate 
51661961e0fSrobinson 	if (CLASSIC_PK_DH(keylen, algtype))
5177c478bd9Sstevel@tonic-gate 		return (key_decryptsession(remotename, deskey));
5187c478bd9Sstevel@tonic-gate 	arg.remotename = (char *)remotename;
5197c478bd9Sstevel@tonic-gate 	arg.algtype = algtype;
5207c478bd9Sstevel@tonic-gate 	arg.keylen = keylen;
5217c478bd9Sstevel@tonic-gate 	arg.deskey.deskeyarray_len = keynum;
5227c478bd9Sstevel@tonic-gate 	arg.deskey.deskeyarray_val = deskey;
5237c478bd9Sstevel@tonic-gate 	arg.remotekey.keybuf3_len = 0;
52461961e0fSrobinson 	(void) memset(&res, 0, sizeof (res));
5257c478bd9Sstevel@tonic-gate 	res.cryptkeyres3_u.deskey.deskeyarray_val = deskey;
5267c478bd9Sstevel@tonic-gate 	if (!key_call((rpcproc_t)KEY_DECRYPT_3, xdr_cryptkeyarg3, (char *)&arg,
52761961e0fSrobinson 			xdr_cryptkeyres3, (char *)&res))
5287c478bd9Sstevel@tonic-gate 		return (-1);
5297c478bd9Sstevel@tonic-gate 	if (res.status != KEY_SUCCESS) {
5307c478bd9Sstevel@tonic-gate 		debug("decrypt3 status is nonzero");
5317c478bd9Sstevel@tonic-gate 		return (-1);
5327c478bd9Sstevel@tonic-gate 	}
5337c478bd9Sstevel@tonic-gate 	if (res.cryptkeyres3_u.deskey.deskeyarray_len != keynum) {
5347c478bd9Sstevel@tonic-gate 		debug("decrypt3 didn't return same number of keys");
5357c478bd9Sstevel@tonic-gate 		return (-1);
5367c478bd9Sstevel@tonic-gate 	}
5377c478bd9Sstevel@tonic-gate 	return (0);
5387c478bd9Sstevel@tonic-gate }
5397c478bd9Sstevel@tonic-gate 
5407c478bd9Sstevel@tonic-gate int
key_gendes(des_block * key)54161961e0fSrobinson key_gendes(des_block *key)
5427c478bd9Sstevel@tonic-gate {
54361961e0fSrobinson 	if (!key_call((rpcproc_t)KEY_GEN, xdr_void, NULL,
54461961e0fSrobinson 			xdr_des_block, (char *)key))
5457c478bd9Sstevel@tonic-gate 		return (-1);
5467c478bd9Sstevel@tonic-gate 	return (0);
5477c478bd9Sstevel@tonic-gate }
5487c478bd9Sstevel@tonic-gate 
5497c478bd9Sstevel@tonic-gate int
key_gendes_g(des_block deskey[],keynum_t keynum)5507c478bd9Sstevel@tonic-gate key_gendes_g(
5517c478bd9Sstevel@tonic-gate 	des_block deskey[],
5527c478bd9Sstevel@tonic-gate 	keynum_t keynum
5537c478bd9Sstevel@tonic-gate )
5547c478bd9Sstevel@tonic-gate {
5557c478bd9Sstevel@tonic-gate 	deskeyarray res;
5567c478bd9Sstevel@tonic-gate 
5577c478bd9Sstevel@tonic-gate 	res.deskeyarray_val = deskey;
5587c478bd9Sstevel@tonic-gate 	if (!key_call((rpcproc_t)KEY_GEN_3, xdr_keynum_t, (char *)&keynum,
55961961e0fSrobinson 			xdr_deskeyarray, (char *)&res))
5607c478bd9Sstevel@tonic-gate 		return (-1);
5617c478bd9Sstevel@tonic-gate 	if (res.deskeyarray_len != keynum) {
5627c478bd9Sstevel@tonic-gate 		debug("return length doesn't match\n");
5637c478bd9Sstevel@tonic-gate 		return (-1);
5647c478bd9Sstevel@tonic-gate 	}
5657c478bd9Sstevel@tonic-gate 	return (0);
5667c478bd9Sstevel@tonic-gate }
5677c478bd9Sstevel@tonic-gate 
5687c478bd9Sstevel@tonic-gate /*
5697c478bd9Sstevel@tonic-gate  * Call KEY_NET_PUT Operation to the keyserv.
5707c478bd9Sstevel@tonic-gate  *
5717c478bd9Sstevel@tonic-gate  * If use_ruid == 0, use effective uid.
5727c478bd9Sstevel@tonic-gate  * If use_ruid == 1, use real uid.
5737c478bd9Sstevel@tonic-gate  */
5747c478bd9Sstevel@tonic-gate int
key_setnet_ext(struct key_netstarg * arg,int use_ruid)5757c478bd9Sstevel@tonic-gate key_setnet_ext(struct key_netstarg *arg, int use_ruid)
5767c478bd9Sstevel@tonic-gate {
5777c478bd9Sstevel@tonic-gate 	keystatus status;
5787c478bd9Sstevel@tonic-gate 
5797c478bd9Sstevel@tonic-gate 	if (!key_call_ext((rpcproc_t)KEY_NET_PUT, xdr_key_netstarg,
58061961e0fSrobinson 		(char *)arg, xdr_keystatus, (char *)&status, use_ruid))
5817c478bd9Sstevel@tonic-gate 		return (-1);
5827c478bd9Sstevel@tonic-gate 
5837c478bd9Sstevel@tonic-gate 	if (status != KEY_SUCCESS) {
5847c478bd9Sstevel@tonic-gate 		debug("key_setnet status is nonzero");
5857c478bd9Sstevel@tonic-gate 		return (-1);
5867c478bd9Sstevel@tonic-gate 	}
5877c478bd9Sstevel@tonic-gate 	return (1);
5887c478bd9Sstevel@tonic-gate }
5897c478bd9Sstevel@tonic-gate 
5907c478bd9Sstevel@tonic-gate /*
5917c478bd9Sstevel@tonic-gate  * Use effective uid.
5927c478bd9Sstevel@tonic-gate  */
5937c478bd9Sstevel@tonic-gate int
key_setnet(struct key_netstarg * arg)5947c478bd9Sstevel@tonic-gate key_setnet(struct key_netstarg *arg)
5957c478bd9Sstevel@tonic-gate {
5967c478bd9Sstevel@tonic-gate 	return (key_setnet_ext(arg, 0));
5977c478bd9Sstevel@tonic-gate }
5987c478bd9Sstevel@tonic-gate 
5997c478bd9Sstevel@tonic-gate /*
6007c478bd9Sstevel@tonic-gate  * Use real uid.
6017c478bd9Sstevel@tonic-gate  */
6027c478bd9Sstevel@tonic-gate int
key_setnet_ruid(struct key_netstarg * arg)6037c478bd9Sstevel@tonic-gate key_setnet_ruid(struct key_netstarg *arg)
6047c478bd9Sstevel@tonic-gate {
6057c478bd9Sstevel@tonic-gate 	return (key_setnet_ext(arg, 1));
6067c478bd9Sstevel@tonic-gate }
6077c478bd9Sstevel@tonic-gate 
6087c478bd9Sstevel@tonic-gate /*
6097c478bd9Sstevel@tonic-gate  * Input netname, secret and public keys (hex string representation)
6107c478bd9Sstevel@tonic-gate  * of length skeylen/pkeylen (bits), and algorithm type. One, but not
6117c478bd9Sstevel@tonic-gate  * both, of skey or pkey may have zero length. If both lengths are
6127c478bd9Sstevel@tonic-gate  * specified, they must be the same.
6137c478bd9Sstevel@tonic-gate  *
6147c478bd9Sstevel@tonic-gate  * Call KEY_NET_PUT_3 Operation to the keyserv.
6157c478bd9Sstevel@tonic-gate  * Stores the specified netname/pkey/skey triplet in the keyserv.
6167c478bd9Sstevel@tonic-gate  *
6177c478bd9Sstevel@tonic-gate  * If (use_ruid == 1), use real uid.
6187c478bd9Sstevel@tonic-gate  * If (use_ruid == 0), use effective uid.
6197c478bd9Sstevel@tonic-gate  */
6207c478bd9Sstevel@tonic-gate int
key_setnet_g_ext(const char * netname,const char * skey,keylen_t skeylen,const char * pkey,keylen_t pkeylen,algtype_t algtype,int use_ruid)6217c478bd9Sstevel@tonic-gate key_setnet_g_ext(
6227c478bd9Sstevel@tonic-gate 	const char *netname,
6237c478bd9Sstevel@tonic-gate 	const char *skey,
6247c478bd9Sstevel@tonic-gate 	keylen_t skeylen,
6257c478bd9Sstevel@tonic-gate 	const char *pkey,
6267c478bd9Sstevel@tonic-gate 	keylen_t pkeylen,
6277c478bd9Sstevel@tonic-gate 	algtype_t algtype,
6287c478bd9Sstevel@tonic-gate 	int use_ruid)
6297c478bd9Sstevel@tonic-gate {
6307c478bd9Sstevel@tonic-gate 	key_netstarg3 arg;
6317c478bd9Sstevel@tonic-gate 	keystatus status;
6327c478bd9Sstevel@tonic-gate 
6337c478bd9Sstevel@tonic-gate 	arg.st_netname = (char *)netname;
6347c478bd9Sstevel@tonic-gate 	arg.algtype = algtype;
6357c478bd9Sstevel@tonic-gate 	if (skeylen == 0) {
6367c478bd9Sstevel@tonic-gate 		arg.st_priv_key.keybuf3_len = 0;
6377c478bd9Sstevel@tonic-gate 	} else {
6387c478bd9Sstevel@tonic-gate 		arg.st_priv_key.keybuf3_len = skeylen/4 + 1;
6397c478bd9Sstevel@tonic-gate 	}
6407c478bd9Sstevel@tonic-gate 	arg.st_priv_key.keybuf3_val = (char *)skey;
6417c478bd9Sstevel@tonic-gate 	if (pkeylen == 0) {
6427c478bd9Sstevel@tonic-gate 		arg.st_pub_key.keybuf3_len = 0;
6437c478bd9Sstevel@tonic-gate 	} else {
6447c478bd9Sstevel@tonic-gate 		arg.st_pub_key.keybuf3_len = pkeylen/4 + 1;
6457c478bd9Sstevel@tonic-gate 	}
6467c478bd9Sstevel@tonic-gate 	arg.st_pub_key.keybuf3_val = (char *)pkey;
6477c478bd9Sstevel@tonic-gate 	if (skeylen == 0) {
6487c478bd9Sstevel@tonic-gate 		if (pkeylen == 0) {
6497c478bd9Sstevel@tonic-gate 			debug("keylens are both 0");
6507c478bd9Sstevel@tonic-gate 			return (-1);
6517c478bd9Sstevel@tonic-gate 		}
6527c478bd9Sstevel@tonic-gate 		arg.keylen = pkeylen;
6537c478bd9Sstevel@tonic-gate 	} else {
6547c478bd9Sstevel@tonic-gate 		if ((pkeylen != 0) && (skeylen != pkeylen)) {
6557c478bd9Sstevel@tonic-gate 			debug("keylens don't match");
6567c478bd9Sstevel@tonic-gate 			return (-1);
6577c478bd9Sstevel@tonic-gate 		}
6587c478bd9Sstevel@tonic-gate 		arg.keylen = skeylen;
6597c478bd9Sstevel@tonic-gate 	}
6607c478bd9Sstevel@tonic-gate 	if (CLASSIC_PK_DH(arg.keylen, arg.algtype)) {
6617c478bd9Sstevel@tonic-gate 		key_netstarg tmp;
6627c478bd9Sstevel@tonic-gate 
6637c478bd9Sstevel@tonic-gate 		if (skeylen != 0) {
66461961e0fSrobinson 			(void) memcpy(&tmp.st_priv_key, skey,
6657c478bd9Sstevel@tonic-gate 				sizeof (tmp.st_priv_key));
6667c478bd9Sstevel@tonic-gate 		} else {
66761961e0fSrobinson 			(void) memset(&tmp.st_priv_key, 0,
66861961e0fSrobinson 				sizeof (tmp.st_priv_key));
6697c478bd9Sstevel@tonic-gate 		}
6707c478bd9Sstevel@tonic-gate 		if (pkeylen != 0) {
67161961e0fSrobinson 			(void) memcpy(&tmp.st_pub_key, skey,
67261961e0fSrobinson 				sizeof (tmp.st_pub_key));
6737c478bd9Sstevel@tonic-gate 		} else {
67461961e0fSrobinson 			(void) memset(&tmp.st_pub_key, 0,
67561961e0fSrobinson 				sizeof (tmp.st_pub_key));
6767c478bd9Sstevel@tonic-gate 		}
6777c478bd9Sstevel@tonic-gate 		tmp.st_netname = (char *)netname;
6787c478bd9Sstevel@tonic-gate 		return (key_setnet(&tmp));
6797c478bd9Sstevel@tonic-gate 	}
6807c478bd9Sstevel@tonic-gate 	if (!key_call_ext((rpcproc_t)KEY_NET_PUT_3,
6817c478bd9Sstevel@tonic-gate 		xdr_key_netstarg3, (char *)&arg,
6827c478bd9Sstevel@tonic-gate 		xdr_keystatus, (char *)&status, use_ruid)) {
6837c478bd9Sstevel@tonic-gate 		return (-1);
6847c478bd9Sstevel@tonic-gate 	}
6857c478bd9Sstevel@tonic-gate 
6867c478bd9Sstevel@tonic-gate 	if (status != KEY_SUCCESS) {
6877c478bd9Sstevel@tonic-gate 		debug("key_setnet3 status is nonzero");
6887c478bd9Sstevel@tonic-gate 		return (-1);
6897c478bd9Sstevel@tonic-gate 	}
6907c478bd9Sstevel@tonic-gate 	return (0);
6917c478bd9Sstevel@tonic-gate }
6927c478bd9Sstevel@tonic-gate 
6937c478bd9Sstevel@tonic-gate /*
6947c478bd9Sstevel@tonic-gate  * Use effective uid.
6957c478bd9Sstevel@tonic-gate  */
6967c478bd9Sstevel@tonic-gate int
key_setnet_g(const char * netname,const char * skey,keylen_t skeylen,const char * pkey,keylen_t pkeylen,algtype_t algtype)6977c478bd9Sstevel@tonic-gate key_setnet_g(const char *netname, const char *skey, keylen_t skeylen,
6987c478bd9Sstevel@tonic-gate 	const char *pkey, keylen_t pkeylen, algtype_t algtype)
6997c478bd9Sstevel@tonic-gate {
7007c478bd9Sstevel@tonic-gate 	return (key_setnet_g_ext(netname, skey, skeylen, pkey, pkeylen,
7017c478bd9Sstevel@tonic-gate 			algtype, 0));
7027c478bd9Sstevel@tonic-gate }
7037c478bd9Sstevel@tonic-gate 
7047c478bd9Sstevel@tonic-gate /*
7057c478bd9Sstevel@tonic-gate  * Use real uid.
7067c478bd9Sstevel@tonic-gate  */
7077c478bd9Sstevel@tonic-gate int
key_setnet_g_ruid(const char * netname,const char * skey,keylen_t skeylen,const char * pkey,keylen_t pkeylen,algtype_t algtype)7087c478bd9Sstevel@tonic-gate key_setnet_g_ruid(const char *netname, const char *skey, keylen_t skeylen,
7097c478bd9Sstevel@tonic-gate 	const char *pkey, keylen_t pkeylen, algtype_t algtype)
7107c478bd9Sstevel@tonic-gate {
7117c478bd9Sstevel@tonic-gate 	return (key_setnet_g_ext(netname, skey, skeylen, pkey, pkeylen,
7127c478bd9Sstevel@tonic-gate 			algtype, 1));
7137c478bd9Sstevel@tonic-gate }
7147c478bd9Sstevel@tonic-gate 
7157c478bd9Sstevel@tonic-gate int
key_get_conv(char * pkey,des_block * deskey)71661961e0fSrobinson key_get_conv(char *pkey, des_block *deskey)
7177c478bd9Sstevel@tonic-gate {
7187c478bd9Sstevel@tonic-gate 	cryptkeyres res;
7197c478bd9Sstevel@tonic-gate 
7207c478bd9Sstevel@tonic-gate 	if (!key_call((rpcproc_t)KEY_GET_CONV, xdr_keybuf, pkey,
72161961e0fSrobinson 		xdr_cryptkeyres, (char *)&res))
7227c478bd9Sstevel@tonic-gate 		return (-1);
7237c478bd9Sstevel@tonic-gate 	if (res.status != KEY_SUCCESS) {
7247c478bd9Sstevel@tonic-gate 		debug("get_conv status is nonzero");
7257c478bd9Sstevel@tonic-gate 		return (-1);
7267c478bd9Sstevel@tonic-gate 	}
7277c478bd9Sstevel@tonic-gate 	*deskey = res.cryptkeyres_u.deskey;
7287c478bd9Sstevel@tonic-gate 	return (0);
7297c478bd9Sstevel@tonic-gate }
7307c478bd9Sstevel@tonic-gate 
7317c478bd9Sstevel@tonic-gate int
key_get_conv_g(const char * pkey,keylen_t pkeylen,algtype_t algtype,des_block deskey[],keynum_t keynum)7327c478bd9Sstevel@tonic-gate key_get_conv_g(
7337c478bd9Sstevel@tonic-gate 	const char *pkey,
7347c478bd9Sstevel@tonic-gate 	keylen_t pkeylen,
7357c478bd9Sstevel@tonic-gate 	algtype_t algtype,
7367c478bd9Sstevel@tonic-gate 	des_block deskey[],
7377c478bd9Sstevel@tonic-gate 	keynum_t keynum
7387c478bd9Sstevel@tonic-gate )
7397c478bd9Sstevel@tonic-gate {
7407c478bd9Sstevel@tonic-gate 	deskeyarg3 arg;
7417c478bd9Sstevel@tonic-gate 	cryptkeyres3 res;
7427c478bd9Sstevel@tonic-gate 
74361961e0fSrobinson 	if (CLASSIC_PK_DH(pkeylen, algtype))
7447c478bd9Sstevel@tonic-gate 		return (key_get_conv((char *)pkey, deskey));
7457c478bd9Sstevel@tonic-gate 	arg.pub_key.keybuf3_len = pkeylen/4 + 1;
7467c478bd9Sstevel@tonic-gate 	arg.pub_key.keybuf3_val = (char *)pkey;
7477c478bd9Sstevel@tonic-gate 	arg.nkeys = keynum;
7487c478bd9Sstevel@tonic-gate 	arg.algtype = algtype;
7497c478bd9Sstevel@tonic-gate 	arg.keylen = pkeylen;
75061961e0fSrobinson 	(void) memset(&res, 0, sizeof (res));
7517c478bd9Sstevel@tonic-gate 	res.cryptkeyres3_u.deskey.deskeyarray_val = deskey;
7527c478bd9Sstevel@tonic-gate 	if (!key_call((rpcproc_t)KEY_GET_CONV_3, xdr_deskeyarg3, (char *)&arg,
75361961e0fSrobinson 		xdr_cryptkeyres3, (char *)&res))
7547c478bd9Sstevel@tonic-gate 		return (-1);
7557c478bd9Sstevel@tonic-gate 	if (res.status != KEY_SUCCESS) {
7567c478bd9Sstevel@tonic-gate 		debug("get_conv3 status is nonzero");
7577c478bd9Sstevel@tonic-gate 		return (-1);
7587c478bd9Sstevel@tonic-gate 	}
7597c478bd9Sstevel@tonic-gate 	if (res.cryptkeyres3_u.deskey.deskeyarray_len != keynum) {
7607c478bd9Sstevel@tonic-gate 		debug("get_conv3 number of keys dont match");
7617c478bd9Sstevel@tonic-gate 		return (-1);
7627c478bd9Sstevel@tonic-gate 	}
7637c478bd9Sstevel@tonic-gate 	return (0);
7647c478bd9Sstevel@tonic-gate }
7657c478bd9Sstevel@tonic-gate 
7667c478bd9Sstevel@tonic-gate struct  key_call_private {
7677c478bd9Sstevel@tonic-gate 	CLIENT	*client;	/* Client handle */
7687c478bd9Sstevel@tonic-gate 	pid_t	pid;		/* process-id at moment of creation */
7697c478bd9Sstevel@tonic-gate 	int	fd;		/* client handle fd */
7707c478bd9Sstevel@tonic-gate 	dev_t	rdev;		/* device client handle is using */
7717c478bd9Sstevel@tonic-gate };
7727c478bd9Sstevel@tonic-gate 
7737c478bd9Sstevel@tonic-gate static void set_rdev(struct key_call_private *);
7747c478bd9Sstevel@tonic-gate static int check_rdev(struct key_call_private *);
7757c478bd9Sstevel@tonic-gate 
7767c478bd9Sstevel@tonic-gate static void
key_call_destroy(void * vp)7777c478bd9Sstevel@tonic-gate key_call_destroy(void *vp)
7787c478bd9Sstevel@tonic-gate {
7797c478bd9Sstevel@tonic-gate 	struct key_call_private *kcp = (struct key_call_private *)vp;
7807c478bd9Sstevel@tonic-gate 
7817c478bd9Sstevel@tonic-gate 	if (kcp != NULL && kcp->client != NULL) {
78261961e0fSrobinson 		(void) check_rdev(kcp);
7837c478bd9Sstevel@tonic-gate 		clnt_destroy(kcp->client);
7847c478bd9Sstevel@tonic-gate 		free(kcp);
7857c478bd9Sstevel@tonic-gate 	}
7867c478bd9Sstevel@tonic-gate }
7877c478bd9Sstevel@tonic-gate 
788*cb620785Sraf static pthread_key_t key_call_key = PTHREAD_ONCE_KEY_NP;
7897c478bd9Sstevel@tonic-gate 
7907c478bd9Sstevel@tonic-gate void
_key_call_fini(void)7917c478bd9Sstevel@tonic-gate _key_call_fini(void)
7927c478bd9Sstevel@tonic-gate {
793*cb620785Sraf 	struct key_call_private	*kcp;
7947c478bd9Sstevel@tonic-gate 
795*cb620785Sraf 	if ((kcp = pthread_getspecific(key_call_key)) != NULL) {
7967c478bd9Sstevel@tonic-gate 		key_call_destroy(kcp);
7977c478bd9Sstevel@tonic-gate 		(void) pthread_setspecific(key_call_key, NULL);
7987c478bd9Sstevel@tonic-gate 	}
7997c478bd9Sstevel@tonic-gate }
8007c478bd9Sstevel@tonic-gate 
8017c478bd9Sstevel@tonic-gate /*
8027c478bd9Sstevel@tonic-gate  * Keep the handle cached.  This call may be made quite often.
8037c478bd9Sstevel@tonic-gate  */
8047c478bd9Sstevel@tonic-gate static CLIENT *
getkeyserv_handle(int vers,int stale)8057c478bd9Sstevel@tonic-gate getkeyserv_handle(int vers, int stale)
8067c478bd9Sstevel@tonic-gate {
8077c478bd9Sstevel@tonic-gate 	struct key_call_private	*kcp = NULL;
8087c478bd9Sstevel@tonic-gate 	int _update_did();
8097c478bd9Sstevel@tonic-gate 
8107c478bd9Sstevel@tonic-gate 	kcp = thr_get_storage(&key_call_key, sizeof (*kcp), key_call_destroy);
8117c478bd9Sstevel@tonic-gate 	if (kcp == NULL) {
8127c478bd9Sstevel@tonic-gate 		syslog(LOG_CRIT, "getkeyserv_handle: out of memory");
8137c478bd9Sstevel@tonic-gate 		return (NULL);
8147c478bd9Sstevel@tonic-gate 	}
8157c478bd9Sstevel@tonic-gate 
8167c478bd9Sstevel@tonic-gate 	/*
8177c478bd9Sstevel@tonic-gate 	 * if pid has changed, destroy client and rebuild
8187c478bd9Sstevel@tonic-gate 	 * or if stale is '1' then destroy client and rebuild
8197c478bd9Sstevel@tonic-gate 	 */
8207c478bd9Sstevel@tonic-gate 	if (kcp->client &&
8217c478bd9Sstevel@tonic-gate 	    (!check_rdev(kcp) || kcp->pid != getpid() || stale)) {
8227c478bd9Sstevel@tonic-gate 		clnt_destroy(kcp->client);
8237c478bd9Sstevel@tonic-gate 		kcp->client = NULL;
8247c478bd9Sstevel@tonic-gate 	}
8257c478bd9Sstevel@tonic-gate 	if (kcp->client) {
8267c478bd9Sstevel@tonic-gate 		int	fd;
8277c478bd9Sstevel@tonic-gate 		/*
8287c478bd9Sstevel@tonic-gate 		 * Change the version number to the new one.
8297c478bd9Sstevel@tonic-gate 		 */
8307c478bd9Sstevel@tonic-gate 		clnt_control(kcp->client, CLSET_VERS, (void *)&vers);
8317c478bd9Sstevel@tonic-gate 		if (!_update_did(kcp->client, vers)) {
8327c478bd9Sstevel@tonic-gate 			if (rpc_createerr.cf_stat == RPC_SYSTEMERROR)
8337c478bd9Sstevel@tonic-gate 				syslog(LOG_DEBUG, "getkeyserv_handle: "
8347c478bd9Sstevel@tonic-gate 						"out of memory!");
8357c478bd9Sstevel@tonic-gate 			return (NULL);
8367c478bd9Sstevel@tonic-gate 		}
8377c478bd9Sstevel@tonic-gate 		/* Update fd in kcp because it was reopened in _update_did */
8387c478bd9Sstevel@tonic-gate 		if (clnt_control(kcp->client, CLGET_FD, (void *)&fd) &&
8397c478bd9Sstevel@tonic-gate 		    (fd >= 0))
840e8031f0aSraf 			(void) fcntl(fd, F_SETFD, FD_CLOEXEC); /* close exec */
8417c478bd9Sstevel@tonic-gate 		kcp->fd = fd;
8427c478bd9Sstevel@tonic-gate 		return (kcp->client);
8437c478bd9Sstevel@tonic-gate 	}
8447c478bd9Sstevel@tonic-gate 
8457c478bd9Sstevel@tonic-gate 	if ((kcp->client = clnt_door_create(KEY_PROG, vers, 0)) == NULL)
8467c478bd9Sstevel@tonic-gate 		return (NULL);
8477c478bd9Sstevel@tonic-gate 
8487c478bd9Sstevel@tonic-gate 	kcp->pid = getpid();
8497c478bd9Sstevel@tonic-gate 	set_rdev(kcp);
850e8031f0aSraf 	(void) fcntl(kcp->fd, F_SETFD, FD_CLOEXEC);	/* close on exec */
8517c478bd9Sstevel@tonic-gate 
8527c478bd9Sstevel@tonic-gate 	return (kcp->client);
8537c478bd9Sstevel@tonic-gate }
8547c478bd9Sstevel@tonic-gate 
8557c478bd9Sstevel@tonic-gate /*
8567c478bd9Sstevel@tonic-gate  * RPC calls to the keyserv.
8577c478bd9Sstevel@tonic-gate  *
8587c478bd9Sstevel@tonic-gate  * If (use_ruid == 1), use real uid.
8597c478bd9Sstevel@tonic-gate  * If (use_ruid == 0), use effective uid.
8607c478bd9Sstevel@tonic-gate  * Returns  0 on failure, 1 on success
8617c478bd9Sstevel@tonic-gate  */
8627c478bd9Sstevel@tonic-gate int
key_call_ext(rpcproc_t proc,xdrproc_t xdr_arg,char * arg,xdrproc_t xdr_rslt,char * rslt,int use_ruid)86361961e0fSrobinson key_call_ext(rpcproc_t proc, xdrproc_t xdr_arg, char *arg, xdrproc_t xdr_rslt,
86461961e0fSrobinson 						char *rslt, int use_ruid)
8657c478bd9Sstevel@tonic-gate {
8667c478bd9Sstevel@tonic-gate 	CLIENT		*clnt;
8677c478bd9Sstevel@tonic-gate 	struct timeval	wait_time = {0, 0};
8687c478bd9Sstevel@tonic-gate 	enum clnt_stat	status;
8697c478bd9Sstevel@tonic-gate 	int		vers;
8707c478bd9Sstevel@tonic-gate 
8717c478bd9Sstevel@tonic-gate 	if (proc == KEY_ENCRYPT_PK && __key_encryptsession_pk_LOCAL) {
8727c478bd9Sstevel@tonic-gate 		cryptkeyres res;
8737c478bd9Sstevel@tonic-gate 		bool_t r;
8747c478bd9Sstevel@tonic-gate 		r = (*__key_encryptsession_pk_LOCAL)(geteuid(), arg, &res);
8757c478bd9Sstevel@tonic-gate 		if (r == TRUE) {
8767c478bd9Sstevel@tonic-gate /* LINTED pointer alignment */
8777c478bd9Sstevel@tonic-gate 			*(cryptkeyres*)rslt = res;
8787c478bd9Sstevel@tonic-gate 			return (1);
8797c478bd9Sstevel@tonic-gate 		}
8807c478bd9Sstevel@tonic-gate 		return (0);
8817c478bd9Sstevel@tonic-gate 	}
8827c478bd9Sstevel@tonic-gate 	if (proc == KEY_DECRYPT_PK && __key_decryptsession_pk_LOCAL) {
8837c478bd9Sstevel@tonic-gate 		cryptkeyres res;
8847c478bd9Sstevel@tonic-gate 		bool_t r;
8857c478bd9Sstevel@tonic-gate 		r = (*__key_decryptsession_pk_LOCAL)(geteuid(), arg, &res);
8867c478bd9Sstevel@tonic-gate 		if (r == TRUE) {
8877c478bd9Sstevel@tonic-gate /* LINTED pointer alignment */
8887c478bd9Sstevel@tonic-gate 			*(cryptkeyres*)rslt = res;
8897c478bd9Sstevel@tonic-gate 			return (1);
8907c478bd9Sstevel@tonic-gate 		}
8917c478bd9Sstevel@tonic-gate 		return (0);
8927c478bd9Sstevel@tonic-gate 	}
8937c478bd9Sstevel@tonic-gate 	if (proc == KEY_GEN && __key_gendes_LOCAL) {
8947c478bd9Sstevel@tonic-gate 		des_block res;
8957c478bd9Sstevel@tonic-gate 		bool_t r;
8967c478bd9Sstevel@tonic-gate 		r = (*__key_gendes_LOCAL)(geteuid(), 0, &res);
8977c478bd9Sstevel@tonic-gate 		if (r == TRUE) {
8987c478bd9Sstevel@tonic-gate /* LINTED pointer alignment */
8997c478bd9Sstevel@tonic-gate 			*(des_block*)rslt = res;
9007c478bd9Sstevel@tonic-gate 			return (1);
9017c478bd9Sstevel@tonic-gate 		}
9027c478bd9Sstevel@tonic-gate 		return (0);
9037c478bd9Sstevel@tonic-gate 	}
9047c478bd9Sstevel@tonic-gate 
9057c478bd9Sstevel@tonic-gate 	if ((proc == KEY_ENCRYPT_PK) || (proc == KEY_DECRYPT_PK) ||
9067c478bd9Sstevel@tonic-gate 	    (proc == KEY_NET_GET) || (proc == KEY_NET_PUT) ||
9077c478bd9Sstevel@tonic-gate 	    (proc == KEY_GET_CONV))
9087c478bd9Sstevel@tonic-gate 		vers = 2;	/* talk to version 2 */
9097c478bd9Sstevel@tonic-gate 	else
9107c478bd9Sstevel@tonic-gate 		vers = 1;	/* talk to version 1 */
9117c478bd9Sstevel@tonic-gate 
9127c478bd9Sstevel@tonic-gate 	clnt = getkeyserv_handle(vers, 0);
9137c478bd9Sstevel@tonic-gate 	if (clnt == NULL)
9147c478bd9Sstevel@tonic-gate 		return (0);
9157c478bd9Sstevel@tonic-gate 
9167c478bd9Sstevel@tonic-gate 	auth_destroy(clnt->cl_auth);
9177c478bd9Sstevel@tonic-gate 	if (use_ruid)
9187c478bd9Sstevel@tonic-gate 		clnt->cl_auth = authsys_create_ruid();
9197c478bd9Sstevel@tonic-gate 	else
9207c478bd9Sstevel@tonic-gate 		clnt->cl_auth = authnone_create();
9217c478bd9Sstevel@tonic-gate 
9227c478bd9Sstevel@tonic-gate 	status = CLNT_CALL(clnt, proc, xdr_arg, arg, xdr_rslt,
9237c478bd9Sstevel@tonic-gate 			rslt, wait_time);
9247c478bd9Sstevel@tonic-gate 
9257c478bd9Sstevel@tonic-gate 	switch (status) {
9267c478bd9Sstevel@tonic-gate 	case RPC_SUCCESS:
9277c478bd9Sstevel@tonic-gate 		return (1);
9287c478bd9Sstevel@tonic-gate 
9297c478bd9Sstevel@tonic-gate 	case RPC_CANTRECV:
9307c478bd9Sstevel@tonic-gate 		/*
9317c478bd9Sstevel@tonic-gate 		 * keyserv was probably restarted, so we'll try once more
9327c478bd9Sstevel@tonic-gate 		 */
9337c478bd9Sstevel@tonic-gate 		if ((clnt = getkeyserv_handle(vers, 1)) == NULL)
9347c478bd9Sstevel@tonic-gate 			return (0);
9357c478bd9Sstevel@tonic-gate 
9367c478bd9Sstevel@tonic-gate 		auth_destroy(clnt->cl_auth);
9377c478bd9Sstevel@tonic-gate 		if (use_ruid)
9387c478bd9Sstevel@tonic-gate 			clnt->cl_auth = authsys_create_ruid();
9397c478bd9Sstevel@tonic-gate 		else
9407c478bd9Sstevel@tonic-gate 			clnt->cl_auth = authnone_create();
9417c478bd9Sstevel@tonic-gate 
9427c478bd9Sstevel@tonic-gate 
9437c478bd9Sstevel@tonic-gate 		if (CLNT_CALL(clnt, proc, xdr_arg, arg, xdr_rslt, rslt,
9447c478bd9Sstevel@tonic-gate 						wait_time) == RPC_SUCCESS)
9457c478bd9Sstevel@tonic-gate 			return (1);
9467c478bd9Sstevel@tonic-gate 		return (0);
9477c478bd9Sstevel@tonic-gate 
9487c478bd9Sstevel@tonic-gate 	default:
9497c478bd9Sstevel@tonic-gate 		return (0);
9507c478bd9Sstevel@tonic-gate 	}
9517c478bd9Sstevel@tonic-gate }
9527c478bd9Sstevel@tonic-gate 
9537c478bd9Sstevel@tonic-gate /*
9547c478bd9Sstevel@tonic-gate  * Use effective uid.
9557c478bd9Sstevel@tonic-gate  */
9567c478bd9Sstevel@tonic-gate int
key_call(rpcproc_t proc,xdrproc_t xdr_arg,char * arg,xdrproc_t xdr_rslt,char * rslt)9577c478bd9Sstevel@tonic-gate key_call(rpcproc_t proc, xdrproc_t xdr_arg, char *arg, xdrproc_t xdr_rslt,
9587c478bd9Sstevel@tonic-gate 	char *rslt)
9597c478bd9Sstevel@tonic-gate {
9607c478bd9Sstevel@tonic-gate 	return (key_call_ext(proc, xdr_arg, arg, xdr_rslt, rslt, 0));
9617c478bd9Sstevel@tonic-gate }
9627c478bd9Sstevel@tonic-gate 
9637c478bd9Sstevel@tonic-gate /*
9647c478bd9Sstevel@tonic-gate  * Use real uid.
9657c478bd9Sstevel@tonic-gate  */
9667c478bd9Sstevel@tonic-gate int
key_call_ruid(rpcproc_t proc,xdrproc_t xdr_arg,char * arg,xdrproc_t xdr_rslt,char * rslt)9677c478bd9Sstevel@tonic-gate key_call_ruid(rpcproc_t proc, xdrproc_t xdr_arg, char *arg,
9687c478bd9Sstevel@tonic-gate 	xdrproc_t xdr_rslt, char *rslt)
9697c478bd9Sstevel@tonic-gate {
9707c478bd9Sstevel@tonic-gate 	return (key_call_ext(proc, xdr_arg, arg, xdr_rslt, rslt, 1));
9717c478bd9Sstevel@tonic-gate }
9727c478bd9Sstevel@tonic-gate 
97361961e0fSrobinson static void
set_rdev(struct key_call_private * kcp)97461961e0fSrobinson set_rdev(struct key_call_private *kcp)
9757c478bd9Sstevel@tonic-gate {
9767c478bd9Sstevel@tonic-gate 	int fd;
9777c478bd9Sstevel@tonic-gate 	struct stat stbuf;
9787c478bd9Sstevel@tonic-gate 
9797c478bd9Sstevel@tonic-gate 	if (clnt_control(kcp->client, CLGET_FD, (char *)&fd) != TRUE ||
980e8031f0aSraf 	    fstat(fd, &stbuf) == -1) {
9817c478bd9Sstevel@tonic-gate 		syslog(LOG_DEBUG, "keyserv_client:  can't get info");
9827c478bd9Sstevel@tonic-gate 		kcp->fd = -1;
9837c478bd9Sstevel@tonic-gate 		return;
9847c478bd9Sstevel@tonic-gate 	}
9857c478bd9Sstevel@tonic-gate 	kcp->fd = fd;
9867c478bd9Sstevel@tonic-gate 	kcp->rdev = stbuf.st_rdev;
9877c478bd9Sstevel@tonic-gate }
9887c478bd9Sstevel@tonic-gate 
98961961e0fSrobinson static int
check_rdev(struct key_call_private * kcp)99061961e0fSrobinson check_rdev(struct key_call_private *kcp)
9917c478bd9Sstevel@tonic-gate {
9927c478bd9Sstevel@tonic-gate 	struct stat stbuf;
9937c478bd9Sstevel@tonic-gate 
9947c478bd9Sstevel@tonic-gate 	if (kcp->fd == -1)
9957c478bd9Sstevel@tonic-gate 		return (1);    /* can't check it, assume it is okay */
9967c478bd9Sstevel@tonic-gate 
997e8031f0aSraf 	if (fstat(kcp->fd, &stbuf) == -1) {
9987c478bd9Sstevel@tonic-gate 		syslog(LOG_DEBUG, "keyserv_client:  can't stat %d", kcp->fd);
9997c478bd9Sstevel@tonic-gate 		/* could be because file descriptor was closed */
10007c478bd9Sstevel@tonic-gate 		/* it's not our file descriptor, so don't try to close it */
100161961e0fSrobinson 		clnt_control(kcp->client, CLSET_FD_NCLOSE, NULL);
10027c478bd9Sstevel@tonic-gate 
10037c478bd9Sstevel@tonic-gate 		return (0);
10047c478bd9Sstevel@tonic-gate 	}
10057c478bd9Sstevel@tonic-gate 	if (kcp->rdev != stbuf.st_rdev) {
10067c478bd9Sstevel@tonic-gate 		syslog(LOG_DEBUG,
10077c478bd9Sstevel@tonic-gate 		    "keyserv_client:  fd %d changed, old=0x%x, new=0x%x",
10087c478bd9Sstevel@tonic-gate 		    kcp->fd, kcp->rdev, stbuf.st_rdev);
10097c478bd9Sstevel@tonic-gate 		/* it's not our file descriptor, so don't try to close it */
101061961e0fSrobinson 		clnt_control(kcp->client, CLSET_FD_NCLOSE, NULL);
10117c478bd9Sstevel@tonic-gate 		return (0);
10127c478bd9Sstevel@tonic-gate 	}
10137c478bd9Sstevel@tonic-gate 	return (1);    /* fd is okay */
10147c478bd9Sstevel@tonic-gate }
1015