4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
30 * Portions of this source code were derived from Berkeley
31 * 4.3 BSD under license from the Regents of the University of
35 #pragma ident "%Z%%M% %I% %E% SMI"
38 * Interface to keyserver
40 * setsecretkey(key) - set your secret key
41 * encryptsessionkey(agent, deskey) - encrypt a session key to talk to agent
42 * decryptsessionkey(agent, deskey) - decrypt ditto
43 * gendeskey(deskey) - generate a secure des key
50 #include <rpc/key_prot.h>
56 #include <sys/types.h>
59 #define CLASSIC_PK_DH(k, a) (((k) == 192) && ((a) == 0))
62 #define debug(msg) (void) fprintf(stderr, "%s\n", msg);
67 int key_call(rpcproc_t
, xdrproc_t
, char *, xdrproc_t
, char *);
68 int key_call_ext(rpcproc_t
, xdrproc_t
, char *, xdrproc_t
, char *, int);
69 int key_setnet(struct key_netstarg
*);
72 * Hack to allow the keyserver to use AUTH_DES (for authenticated
73 * NIS+ calls, for example). The only functions that get called
74 * are key_encryptsession_pk, key_decryptsession_pk, and key_gendes.
76 * The approach is to have the keyserver fill in pointers to local
77 * implementations of these functions, and to call those in key_call().
80 bool_t (*__key_encryptsession_pk_LOCAL
)() = NULL
;
81 bool_t (*__key_decryptsession_pk_LOCAL
)() = NULL
;
82 bool_t (*__key_gendes_LOCAL
)() = NULL
;
86 key_setsecret(const char *secretkey
)
88 char netName
[MAXNETNAMELEN
+1];
89 struct key_netstarg netst
;
92 if (getnetname(netName
) == 0) {
93 debug("getnetname failed");
97 (void) memcpy(netst
.st_priv_key
, secretkey
, HEXKEYBYTES
);
98 netst
.st_pub_key
[0] = 0;
99 netst
.st_netname
= netName
;
103 * We perform the KEY_NET_PUT instead of the SET_KEY
104 * rpc call because key_secretkey_is_set function uses
105 * the KEY_NET_GET call which expects the netname to be
106 * set along with the key. Keylogin also uses KEY_NET_PUT.
108 ret
= key_setnet(&netst
);
110 /* erase our copy of the secret key */
111 (void) memset(netst
.st_priv_key
, '\0', HEXKEYBYTES
);
129 if (CLASSIC_PK_DH(keylen
, algtype
))
130 return (key_setsecret(secretkey
));
131 arg
.key
.keybuf3_len
= keylen
/4 + 1;
132 arg
.key
.keybuf3_val
= secretkey
;
133 arg
.algtype
= algtype
;
135 arg
.userkey
= userkey
;
136 if (!key_call((rpcproc_t
)KEY_SET_3
, xdr_setkeyarg3
, (char *)&arg
,
137 xdr_keystatus
, (char *)&status
))
139 if (status
!= KEY_SUCCESS
) {
140 debug("set3 status is nonzero");
147 key_removesecret_g_ext(int use_uid
)
151 if (!key_call_ext((rpcproc_t
)KEY_CLEAR_3
, xdr_void
, NULL
,
152 xdr_keystatus
, (char *)&status
, use_uid
)) {
153 debug("remove secret key call failed");
156 if (status
!= KEY_SUCCESS
) {
157 debug("remove secret status is nonzero");
167 key_removesecret_g(void)
169 return (key_removesecret_g_ext(0));
176 key_removesecret_g_ruid(void)
178 return (key_removesecret_g_ext(1));
182 * key_secretkey_is_set() returns 1 if the keyserver has a secret key
183 * stored for the caller's effective uid if use_ruid is 0 or
184 * stored for the caller's real uid if use_ruid is 1.
185 * it returns 0 otherwise.
187 * N.B.: The KEY_NET_GET key call is undocumented. Applications shouldn't
188 * be using it, because it allows them to get the user's secret key.
192 key_secretkey_is_set_ext(int use_ruid
)
194 struct key_netstres kres
;
196 (void) memset(&kres
, 0, sizeof (kres
));
197 if (key_call_ext((rpcproc_t
)KEY_NET_GET
, xdr_void
, NULL
,
198 xdr_key_netstres
, (char *)&kres
, use_ruid
) &&
199 (kres
.status
== KEY_SUCCESS
) &&
200 (kres
.key_netstres_u
.knet
.st_priv_key
[0] != 0)) {
201 /* avoid leaving secret key in memory */
202 (void) memset(kres
.key_netstres_u
.knet
.st_priv_key
, 0,
204 xdr_free(xdr_key_netstres
, (char *)&kres
);
214 key_secretkey_is_set(void)
216 return (key_secretkey_is_set_ext(0));
223 key_secretkey_is_set_ruid(void)
225 return (key_secretkey_is_set_ext(1));
229 * key_secretkey_is_set_g_ext() returns 1 if the keyserver has a secret key
230 * stored for the caller's uid, it returns 0 otherwise.
231 * If (use_ruid == 0), for the caller's effective uid.
232 * If (use_ruid == 1), for the caller's real uid.
234 * N.B.: The KEY_NET_GET_3 key call is undocumented. Applications shouldn't
235 * be using it, because it allows them to get the user's secret key.
238 key_secretkey_is_set_g_ext(keylen_t keylen
, algtype_t algtype
, int use_ruid
)
244 * key_secretkey_is_set_g_ext is tricky because keylen == 0
245 * means check if any key exists for the caller (old/new, 192/1024 ...)
246 * Rather than handle this on the server side, we call the old
247 * routine if keylen == 0 and try the newer stuff only if that fails
249 if ((keylen
== 0) && key_secretkey_is_set_ext(use_ruid
))
251 if (CLASSIC_PK_DH(keylen
, algtype
))
252 return (key_secretkey_is_set_ext(use_ruid
));
254 arg
.algtype
= algtype
;
255 (void) memset(&kres
, 0, sizeof (kres
));
256 if (key_call_ext((rpcproc_t
)KEY_NET_GET_3
, xdr_mechtype
, (char *)&arg
,
257 xdr_key_netstres3
, (char *)&kres
, use_ruid
) &&
258 (kres
.status
== KEY_SUCCESS
) &&
259 (kres
.key_netstres3_u
.knet
.st_priv_key
.keybuf3_len
!= 0)) {
260 /* avoid leaving secret key in memory */
261 (void) memset(kres
.key_netstres3_u
.knet
.st_priv_key
.keybuf3_val
,
262 0, kres
.key_netstres3_u
.knet
.st_priv_key
.keybuf3_len
);
263 xdr_free(xdr_key_netstres3
, (char *)&kres
);
273 key_secretkey_is_set_g(keylen_t keylen
, algtype_t algtype
)
275 return (key_secretkey_is_set_g_ext(keylen
, algtype
, 0));
282 key_secretkey_is_set_g_ruid(keylen_t keylen
, algtype_t algtype
)
284 return (key_secretkey_is_set_g_ext(keylen
, algtype
, 1));
289 key_encryptsession_pk(const char *remotename
, netobj
*remotekey
,
295 arg
.remotename
= (char *)remotename
;
296 arg
.remotekey
= *remotekey
;
297 arg
.deskey
= *deskey
;
298 if (!key_call((rpcproc_t
)KEY_ENCRYPT_PK
, xdr_cryptkeyarg2
, (char *)&arg
,
299 xdr_cryptkeyres
, (char *)&res
))
301 if (res
.status
!= KEY_SUCCESS
) {
302 debug("encrypt status is nonzero");
305 *deskey
= res
.cryptkeyres_u
.deskey
;
310 key_encryptsession_pk_g(
311 const char *remotename
,
312 const char *remotekey
,
313 keylen_t remotekeylen
,
322 if (CLASSIC_PK_DH(remotekeylen
, algtype
)) {
326 npk
.n_len
= remotekeylen
/4 + 1;
327 npk
.n_bytes
= (char *)remotekey
;
328 for (i
= 0; i
< keynum
; i
++) {
329 if (key_encryptsession_pk(remotename
, &npk
, &deskey
[i
]))
334 arg
.remotename
= (char *)remotename
;
335 arg
.remotekey
.keybuf3_len
= remotekeylen
/4 + 1;
336 arg
.remotekey
.keybuf3_val
= (char *)remotekey
;
337 arg
.keylen
= remotekeylen
;
338 arg
.algtype
= algtype
;
339 arg
.deskey
.deskeyarray_len
= keynum
;
340 arg
.deskey
.deskeyarray_val
= deskey
;
341 (void) memset(&res
, 0, sizeof (res
));
342 res
.cryptkeyres3_u
.deskey
.deskeyarray_val
= deskey
;
343 if (!key_call((rpcproc_t
)KEY_ENCRYPT_PK_3
,
344 xdr_cryptkeyarg3
, (char *)&arg
,
345 xdr_cryptkeyres3
, (char *)&res
))
347 if (res
.status
!= KEY_SUCCESS
) {
348 debug("encrypt3 status is nonzero");
351 if (res
.cryptkeyres3_u
.deskey
.deskeyarray_len
!= keynum
) {
352 debug("number of keys don't match");
359 key_decryptsession_pk(const char *remotename
, netobj
*remotekey
,
365 arg
.remotename
= (char *)remotename
;
366 arg
.remotekey
= *remotekey
;
367 arg
.deskey
= *deskey
;
368 if (!key_call((rpcproc_t
)KEY_DECRYPT_PK
, xdr_cryptkeyarg2
, (char *)&arg
,
369 xdr_cryptkeyres
, (char *)&res
))
371 if (res
.status
!= KEY_SUCCESS
) {
372 debug("decrypt status is nonzero");
375 *deskey
= res
.cryptkeyres_u
.deskey
;
380 key_decryptsession_pk_g(
381 const char *remotename
,
382 const char *remotekey
,
383 keylen_t remotekeylen
,
392 if (CLASSIC_PK_DH(remotekeylen
, algtype
)) {
396 npk
.n_len
= remotekeylen
/4 + 1;
397 npk
.n_bytes
= (char *)remotekey
;
398 for (i
= 0; i
< keynum
; i
++) {
399 if (key_decryptsession_pk(remotename
,
405 arg
.remotename
= (char *)remotename
;
406 arg
.remotekey
.keybuf3_len
= remotekeylen
/4 + 1;
407 arg
.remotekey
.keybuf3_val
= (char *)remotekey
;
408 arg
.deskey
.deskeyarray_len
= keynum
;
409 arg
.deskey
.deskeyarray_val
= deskey
;
410 arg
.algtype
= algtype
;
411 arg
.keylen
= remotekeylen
;
412 (void) memset(&res
, 0, sizeof (res
));
413 res
.cryptkeyres3_u
.deskey
.deskeyarray_val
= deskey
;
414 if (!key_call((rpcproc_t
)KEY_DECRYPT_PK_3
,
415 xdr_cryptkeyarg3
, (char *)&arg
,
416 xdr_cryptkeyres3
, (char *)&res
))
418 if (res
.status
!= KEY_SUCCESS
) {
419 debug("decrypt3 status is nonzero");
422 if (res
.cryptkeyres3_u
.deskey
.deskeyarray_len
!= keynum
) {
423 debug("number of keys don't match");
430 key_encryptsession(const char *remotename
, des_block
*deskey
)
435 arg
.remotename
= (char *)remotename
;
436 arg
.deskey
= *deskey
;
437 if (!key_call((rpcproc_t
)KEY_ENCRYPT
, xdr_cryptkeyarg
, (char *)&arg
,
438 xdr_cryptkeyres
, (char *)&res
))
440 if (res
.status
!= KEY_SUCCESS
) {
441 debug("encrypt status is nonzero");
444 *deskey
= res
.cryptkeyres_u
.deskey
;
449 key_encryptsession_g(
450 const char *remotename
,
460 if (CLASSIC_PK_DH(keylen
, algtype
))
461 return (key_encryptsession(remotename
, deskey
));
462 arg
.remotename
= (char *)remotename
;
463 arg
.algtype
= algtype
;
465 arg
.deskey
.deskeyarray_len
= keynum
;
466 arg
.deskey
.deskeyarray_val
= deskey
;
467 arg
.remotekey
.keybuf3_len
= 0;
468 (void) memset(&res
, 0, sizeof (res
));
469 res
.cryptkeyres3_u
.deskey
.deskeyarray_val
= deskey
;
470 if (!key_call((rpcproc_t
)KEY_ENCRYPT_3
, xdr_cryptkeyarg3
, (char *)&arg
,
471 xdr_cryptkeyres3
, (char *)&res
))
473 if (res
.status
!= KEY_SUCCESS
) {
474 debug("encrypt3 status is nonzero");
477 if (res
.cryptkeyres3_u
.deskey
.deskeyarray_len
!= keynum
) {
478 debug("encrypt3 didn't return same number of keys");
486 key_decryptsession(const char *remotename
, des_block
*deskey
)
491 arg
.remotename
= (char *)remotename
;
492 arg
.deskey
= *deskey
;
493 if (!key_call((rpcproc_t
)KEY_DECRYPT
, xdr_cryptkeyarg
, (char *)&arg
,
494 xdr_cryptkeyres
, (char *)&res
))
496 if (res
.status
!= KEY_SUCCESS
) {
497 debug("decrypt status is nonzero");
500 *deskey
= res
.cryptkeyres_u
.deskey
;
505 key_decryptsession_g(
506 const char *remotename
,
516 if (CLASSIC_PK_DH(keylen
, algtype
))
517 return (key_decryptsession(remotename
, deskey
));
518 arg
.remotename
= (char *)remotename
;
519 arg
.algtype
= algtype
;
521 arg
.deskey
.deskeyarray_len
= keynum
;
522 arg
.deskey
.deskeyarray_val
= deskey
;
523 arg
.remotekey
.keybuf3_len
= 0;
524 (void) memset(&res
, 0, sizeof (res
));
525 res
.cryptkeyres3_u
.deskey
.deskeyarray_val
= deskey
;
526 if (!key_call((rpcproc_t
)KEY_DECRYPT_3
, xdr_cryptkeyarg3
, (char *)&arg
,
527 xdr_cryptkeyres3
, (char *)&res
))
529 if (res
.status
!= KEY_SUCCESS
) {
530 debug("decrypt3 status is nonzero");
533 if (res
.cryptkeyres3_u
.deskey
.deskeyarray_len
!= keynum
) {
534 debug("decrypt3 didn't return same number of keys");
541 key_gendes(des_block
*key
)
543 if (!key_call((rpcproc_t
)KEY_GEN
, xdr_void
, NULL
,
544 xdr_des_block
, (char *)key
))
557 res
.deskeyarray_val
= deskey
;
558 if (!key_call((rpcproc_t
)KEY_GEN_3
, xdr_keynum_t
, (char *)&keynum
,
559 xdr_deskeyarray
, (char *)&res
))
561 if (res
.deskeyarray_len
!= keynum
) {
562 debug("return length doesn't match\n");
569 * Call KEY_NET_PUT Operation to the keyserv.
571 * If use_ruid == 0, use effective uid.
572 * If use_ruid == 1, use real uid.
575 key_setnet_ext(struct key_netstarg
*arg
, int use_ruid
)
579 if (!key_call_ext((rpcproc_t
)KEY_NET_PUT
, xdr_key_netstarg
,
580 (char *)arg
, xdr_keystatus
, (char *)&status
, use_ruid
))
583 if (status
!= KEY_SUCCESS
) {
584 debug("key_setnet status is nonzero");
594 key_setnet(struct key_netstarg
*arg
)
596 return (key_setnet_ext(arg
, 0));
603 key_setnet_ruid(struct key_netstarg
*arg
)
605 return (key_setnet_ext(arg
, 1));
609 * Input netname, secret and public keys (hex string representation)
610 * of length skeylen/pkeylen (bits), and algorithm type. One, but not
611 * both, of skey or pkey may have zero length. If both lengths are
612 * specified, they must be the same.
614 * Call KEY_NET_PUT_3 Operation to the keyserv.
615 * Stores the specified netname/pkey/skey triplet in the keyserv.
617 * If (use_ruid == 1), use real uid.
618 * If (use_ruid == 0), use effective uid.
633 arg
.st_netname
= (char *)netname
;
634 arg
.algtype
= algtype
;
636 arg
.st_priv_key
.keybuf3_len
= 0;
638 arg
.st_priv_key
.keybuf3_len
= skeylen
/4 + 1;
640 arg
.st_priv_key
.keybuf3_val
= (char *)skey
;
642 arg
.st_pub_key
.keybuf3_len
= 0;
644 arg
.st_pub_key
.keybuf3_len
= pkeylen
/4 + 1;
646 arg
.st_pub_key
.keybuf3_val
= (char *)pkey
;
649 debug("keylens are both 0");
652 arg
.keylen
= pkeylen
;
654 if ((pkeylen
!= 0) && (skeylen
!= pkeylen
)) {
655 debug("keylens don't match");
658 arg
.keylen
= skeylen
;
660 if (CLASSIC_PK_DH(arg
.keylen
, arg
.algtype
)) {
664 (void) memcpy(&tmp
.st_priv_key
, skey
,
665 sizeof (tmp
.st_priv_key
));
667 (void) memset(&tmp
.st_priv_key
, 0,
668 sizeof (tmp
.st_priv_key
));
671 (void) memcpy(&tmp
.st_pub_key
, skey
,
672 sizeof (tmp
.st_pub_key
));
674 (void) memset(&tmp
.st_pub_key
, 0,
675 sizeof (tmp
.st_pub_key
));
677 tmp
.st_netname
= (char *)netname
;
678 return (key_setnet(&tmp
));
680 if (!key_call_ext((rpcproc_t
)KEY_NET_PUT_3
,
681 xdr_key_netstarg3
, (char *)&arg
,
682 xdr_keystatus
, (char *)&status
, use_ruid
)) {
686 if (status
!= KEY_SUCCESS
) {
687 debug("key_setnet3 status is nonzero");
697 key_setnet_g(const char *netname
, const char *skey
, keylen_t skeylen
,
698 const char *pkey
, keylen_t pkeylen
, algtype_t algtype
)
700 return (key_setnet_g_ext(netname
, skey
, skeylen
, pkey
, pkeylen
,
708 key_setnet_g_ruid(const char *netname
, const char *skey
, keylen_t skeylen
,
709 const char *pkey
, keylen_t pkeylen
, algtype_t algtype
)
711 return (key_setnet_g_ext(netname
, skey
, skeylen
, pkey
, pkeylen
,
716 key_get_conv(char *pkey
, des_block
*deskey
)
720 if (!key_call((rpcproc_t
)KEY_GET_CONV
, xdr_keybuf
, pkey
,
721 xdr_cryptkeyres
, (char *)&res
))
723 if (res
.status
!= KEY_SUCCESS
) {
724 debug("get_conv status is nonzero");
727 *deskey
= res
.cryptkeyres_u
.deskey
;
743 if (CLASSIC_PK_DH(pkeylen
, algtype
))
744 return (key_get_conv((char *)pkey
, deskey
));
745 arg
.pub_key
.keybuf3_len
= pkeylen
/4 + 1;
746 arg
.pub_key
.keybuf3_val
= (char *)pkey
;
748 arg
.algtype
= algtype
;
749 arg
.keylen
= pkeylen
;
750 (void) memset(&res
, 0, sizeof (res
));
751 res
.cryptkeyres3_u
.deskey
.deskeyarray_val
= deskey
;
752 if (!key_call((rpcproc_t
)KEY_GET_CONV_3
, xdr_deskeyarg3
, (char *)&arg
,
753 xdr_cryptkeyres3
, (char *)&res
))
755 if (res
.status
!= KEY_SUCCESS
) {
756 debug("get_conv3 status is nonzero");
759 if (res
.cryptkeyres3_u
.deskey
.deskeyarray_len
!= keynum
) {
760 debug("get_conv3 number of keys dont match");
766 struct key_call_private
{
767 CLIENT
*client
; /* Client handle */
768 pid_t pid
; /* process-id at moment of creation */
769 int fd
; /* client handle fd */
770 dev_t rdev
; /* device client handle is using */
773 static void set_rdev(struct key_call_private
*);
774 static int check_rdev(struct key_call_private
*);
777 key_call_destroy(void *vp
)
779 struct key_call_private
*kcp
= (struct key_call_private
*)vp
;
781 if (kcp
!= NULL
&& kcp
->client
!= NULL
) {
782 (void) check_rdev(kcp
);
783 clnt_destroy(kcp
->client
);
788 static pthread_key_t key_call_key
= PTHREAD_ONCE_KEY_NP
;
793 struct key_call_private
*kcp
;
795 if ((kcp
= pthread_getspecific(key_call_key
)) != NULL
) {
796 key_call_destroy(kcp
);
797 (void) pthread_setspecific(key_call_key
, NULL
);
802 * Keep the handle cached. This call may be made quite often.
805 getkeyserv_handle(int vers
, int stale
)
807 struct key_call_private
*kcp
= NULL
;
810 kcp
= thr_get_storage(&key_call_key
, sizeof (*kcp
), key_call_destroy
);
812 syslog(LOG_CRIT
, "getkeyserv_handle: out of memory");
817 * if pid has changed, destroy client and rebuild
818 * or if stale is '1' then destroy client and rebuild
821 (!check_rdev(kcp
) || kcp
->pid
!= getpid() || stale
)) {
822 clnt_destroy(kcp
->client
);
828 * Change the version number to the new one.
830 clnt_control(kcp
->client
, CLSET_VERS
, (void *)&vers
);
831 if (!_update_did(kcp
->client
, vers
)) {
832 if (rpc_createerr
.cf_stat
== RPC_SYSTEMERROR
)
833 syslog(LOG_DEBUG
, "getkeyserv_handle: "
837 /* Update fd in kcp because it was reopened in _update_did */
838 if (clnt_control(kcp
->client
, CLGET_FD
, (void *)&fd
) &&
840 (void) fcntl(fd
, F_SETFD
, FD_CLOEXEC
); /* close exec */
842 return (kcp
->client
);
845 if ((kcp
->client
= clnt_door_create(KEY_PROG
, vers
, 0)) == NULL
)
850 (void) fcntl(kcp
->fd
, F_SETFD
, FD_CLOEXEC
); /* close on exec */
852 return (kcp
->client
);
856 * RPC calls to the keyserv.
858 * If (use_ruid == 1), use real uid.
859 * If (use_ruid == 0), use effective uid.
860 * Returns 0 on failure, 1 on success
863 key_call_ext(rpcproc_t proc
, xdrproc_t xdr_arg
, char *arg
, xdrproc_t xdr_rslt
,
864 char *rslt
, int use_ruid
)
867 struct timeval wait_time
= {0, 0};
868 enum clnt_stat status
;
871 if (proc
== KEY_ENCRYPT_PK
&& __key_encryptsession_pk_LOCAL
) {
874 r
= (*__key_encryptsession_pk_LOCAL
)(geteuid(), arg
, &res
);
876 /* LINTED pointer alignment */
877 *(cryptkeyres
*)rslt
= res
;
882 if (proc
== KEY_DECRYPT_PK
&& __key_decryptsession_pk_LOCAL
) {
885 r
= (*__key_decryptsession_pk_LOCAL
)(geteuid(), arg
, &res
);
887 /* LINTED pointer alignment */
888 *(cryptkeyres
*)rslt
= res
;
893 if (proc
== KEY_GEN
&& __key_gendes_LOCAL
) {
896 r
= (*__key_gendes_LOCAL
)(geteuid(), 0, &res
);
898 /* LINTED pointer alignment */
899 *(des_block
*)rslt
= res
;
905 if ((proc
== KEY_ENCRYPT_PK
) || (proc
== KEY_DECRYPT_PK
) ||
906 (proc
== KEY_NET_GET
) || (proc
== KEY_NET_PUT
) ||
907 (proc
== KEY_GET_CONV
))
908 vers
= 2; /* talk to version 2 */
910 vers
= 1; /* talk to version 1 */
912 clnt
= getkeyserv_handle(vers
, 0);
916 auth_destroy(clnt
->cl_auth
);
918 clnt
->cl_auth
= authsys_create_ruid();
920 clnt
->cl_auth
= authnone_create();
922 status
= CLNT_CALL(clnt
, proc
, xdr_arg
, arg
, xdr_rslt
,
931 * keyserv was probably restarted, so we'll try once more
933 if ((clnt
= getkeyserv_handle(vers
, 1)) == NULL
)
936 auth_destroy(clnt
->cl_auth
);
938 clnt
->cl_auth
= authsys_create_ruid();
940 clnt
->cl_auth
= authnone_create();
943 if (CLNT_CALL(clnt
, proc
, xdr_arg
, arg
, xdr_rslt
, rslt
,
944 wait_time
) == RPC_SUCCESS
)
957 key_call(rpcproc_t proc
, xdrproc_t xdr_arg
, char *arg
, xdrproc_t xdr_rslt
,
960 return (key_call_ext(proc
, xdr_arg
, arg
, xdr_rslt
, rslt
, 0));
967 key_call_ruid(rpcproc_t proc
, xdrproc_t xdr_arg
, char *arg
,
968 xdrproc_t xdr_rslt
, char *rslt
)
970 return (key_call_ext(proc
, xdr_arg
, arg
, xdr_rslt
, rslt
, 1));
974 set_rdev(struct key_call_private
*kcp
)
979 if (clnt_control(kcp
->client
, CLGET_FD
, (char *)&fd
) != TRUE
||
980 fstat(fd
, &stbuf
) == -1) {
981 syslog(LOG_DEBUG
, "keyserv_client: can't get info");
986 kcp
->rdev
= stbuf
.st_rdev
;
990 check_rdev(struct key_call_private
*kcp
)
995 return (1); /* can't check it, assume it is okay */
997 if (fstat(kcp
->fd
, &stbuf
) == -1) {
998 syslog(LOG_DEBUG
, "keyserv_client: can't stat %d", kcp
->fd
);
999 /* could be because file descriptor was closed */
1000 /* it's not our file descriptor, so don't try to close it */
1001 clnt_control(kcp
->client
, CLSET_FD_NCLOSE
, NULL
);
1005 if (kcp
->rdev
!= stbuf
.st_rdev
) {
1007 "keyserv_client: fd %d changed, old=0x%x, new=0x%x",
1008 kcp
->fd
, kcp
->rdev
, stbuf
.st_rdev
);
1009 /* it's not our file descriptor, so don't try to close it */
1010 clnt_control(kcp
->client
, CLSET_FD_NCLOSE
, NULL
);
1013 return (1); /* fd is okay */