1 /* 2 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 3 * unrestricted use provided that this legend is included on all tape 4 * media and as a part of the software program in whole or part. Users 5 * may copy or modify Sun RPC without charge, but are not authorized 6 * to license or distribute it to anyone else except as part of a product or 7 * program developed by the user. 8 * 9 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 10 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 11 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 12 * 13 * Sun RPC is provided with no support and without any obligation on the 14 * part of Sun Microsystems, Inc. to assist in its use, correction, 15 * modification or enhancement. 16 * 17 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 18 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 19 * OR ANY PART THEREOF. 20 * 21 * In no event will Sun Microsystems, Inc. be liable for any lost revenue 22 * or profits or other special, indirect and consequential damages, even if 23 * Sun has been advised of the possibility of such damages. 24 * 25 * Sun Microsystems, Inc. 26 * 2550 Garcia Avenue 27 * Mountain View, California 94043 28 */ 29 30 #ifndef lint 31 #if 0 32 static char sccsid[] = "@(#)keyserv.c 1.15 94/04/25 SMI"; 33 #endif 34 static const char rcsid[] = 35 "$FreeBSD$"; 36 #endif /* not lint */ 37 38 /* 39 * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc. 40 */ 41 42 /* 43 * Keyserver 44 * Store secret keys per uid. Do public key encryption and decryption 45 * operations. Generate "random" keys. 46 * Do not talk to anything but a local root 47 * process on the local transport only 48 */ 49 50 #include <err.h> 51 #include <pwd.h> 52 #include <stdio.h> 53 #include <stdlib.h> 54 #include <string.h> 55 #include <unistd.h> 56 #include <sys/stat.h> 57 #include <sys/types.h> 58 #include <rpc/rpc.h> 59 #include <sys/param.h> 60 #include <sys/file.h> 61 #include <rpc/des_crypt.h> 62 #include <rpc/des.h> 63 #include <rpc/key_prot.h> 64 #include <rpcsvc/crypt.h> 65 #include "keyserv.h" 66 67 #ifndef NGROUPS 68 #define NGROUPS 16 69 #endif 70 71 #ifndef KEYSERVSOCK 72 #define KEYSERVSOCK "/var/run/keyservsock" 73 #endif 74 75 static void randomize( des_block * ); 76 static void usage( void ); 77 static int getrootkey( des_block *, int ); 78 static int root_auth( SVCXPRT *, struct svc_req * ); 79 80 #ifdef DEBUG 81 static int debugging = 1; 82 #else 83 static int debugging = 0; 84 #endif 85 86 static void keyprogram(struct svc_req *rqstp, SVCXPRT *transp); 87 static des_block masterkey; 88 static char ROOTKEY[] = "/etc/.rootkey"; 89 90 /* 91 * Hack to allow the keyserver to use AUTH_DES (for authenticated 92 * NIS+ calls, for example). The only functions that get called 93 * are key_encryptsession_pk, key_decryptsession_pk, and key_gendes. 94 * 95 * The approach is to have the keyserver fill in pointers to local 96 * implementations of these functions, and to call those in key_call(). 97 */ 98 99 extern cryptkeyres *(*__key_encryptsession_pk_LOCAL)(); 100 extern cryptkeyres *(*__key_decryptsession_pk_LOCAL)(); 101 extern des_block *(*__key_gendes_LOCAL)(); 102 extern int (*__des_crypt_LOCAL)(); 103 104 cryptkeyres *key_encrypt_pk_2_svc_prog( uid_t, cryptkeyarg2 * ); 105 cryptkeyres *key_decrypt_pk_2_svc_prog( uid_t, cryptkeyarg2 * ); 106 des_block *key_gen_1_svc_prog( void *, struct svc_req * ); 107 108 int 109 main(int argc, char *argv[]) 110 { 111 int nflag = 0; 112 int c; 113 int warn = 0; 114 char *path = NULL; 115 void *localhandle; 116 register SVCXPRT *transp; 117 struct netconfig *nconf = NULL; 118 119 __key_encryptsession_pk_LOCAL = &key_encrypt_pk_2_svc_prog; 120 __key_decryptsession_pk_LOCAL = &key_decrypt_pk_2_svc_prog; 121 __key_gendes_LOCAL = &key_gen_1_svc_prog; 122 123 while ((c = getopt(argc, argv, "ndDvp:")) != -1) 124 switch (c) { 125 case 'n': 126 nflag++; 127 break; 128 case 'd': 129 pk_nodefaultkeys(); 130 break; 131 case 'D': 132 debugging = 1; 133 break; 134 case 'v': 135 warn = 1; 136 break; 137 case 'p': 138 path = optarg; 139 break; 140 default: 141 usage(); 142 } 143 144 load_des(warn, path); 145 __des_crypt_LOCAL = _my_crypt; 146 if (svc_auth_reg(AUTH_DES, _svcauth_des) == -1) 147 errx(1, "failed to register AUTH_DES authenticator"); 148 149 if (optind != argc) { 150 usage(); 151 } 152 153 /* 154 * Initialize 155 */ 156 (void) umask(S_IXUSR|S_IXGRP|S_IXOTH); 157 if (geteuid() != 0) 158 errx(1, "keyserv must be run as root"); 159 setmodulus(HEXMODULUS); 160 getrootkey(&masterkey, nflag); 161 162 rpcb_unset(KEY_PROG, KEY_VERS, NULL); 163 rpcb_unset(KEY_PROG, KEY_VERS2, NULL); 164 165 if (svc_create(keyprogram, KEY_PROG, KEY_VERS, 166 "netpath") == 0) { 167 (void) fprintf(stderr, 168 "%s: unable to create service\n", argv[0]); 169 exit(1); 170 } 171 172 if (svc_create(keyprogram, KEY_PROG, KEY_VERS2, 173 "netpath") == 0) { 174 (void) fprintf(stderr, 175 "%s: unable to create service\n", argv[0]); 176 exit(1); 177 } 178 179 localhandle = setnetconfig(); 180 while ((nconf = getnetconfig(localhandle)) != NULL) { 181 if (nconf->nc_protofmly != NULL && 182 strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) 183 break; 184 } 185 186 if (nconf == NULL) 187 errx(1, "getnetconfig: %s", nc_sperror()); 188 189 unlink(KEYSERVSOCK); 190 rpcb_unset(CRYPT_PROG, CRYPT_VERS, nconf); 191 transp = svcunix_create(RPC_ANYSOCK, 0, 0, KEYSERVSOCK); 192 if (transp == NULL) 193 errx(1, "cannot create AF_LOCAL service"); 194 if (!svc_reg(transp, KEY_PROG, KEY_VERS, keyprogram, nconf)) 195 errx(1, "unable to register (KEY_PROG, KEY_VERS, unix)"); 196 if (!svc_reg(transp, KEY_PROG, KEY_VERS2, keyprogram, nconf)) 197 errx(1, "unable to register (KEY_PROG, KEY_VERS2, unix)"); 198 if (!svc_reg(transp, CRYPT_PROG, CRYPT_VERS, crypt_prog_1, nconf)) 199 errx(1, "unable to register (CRYPT_PROG, CRYPT_VERS, unix)"); 200 201 endnetconfig(localhandle); 202 203 (void) umask(066); /* paranoia */ 204 205 if (!debugging) { 206 daemon(0,0); 207 } 208 209 signal(SIGPIPE, SIG_IGN); 210 211 svc_run(); 212 abort(); 213 /* NOTREACHED */ 214 } 215 216 /* 217 * In the event that we don't get a root password, we try to 218 * randomize the master key the best we can 219 */ 220 static void 221 randomize(des_block *master) 222 { 223 master->key.low = arc4random(); 224 master->key.high = arc4random(); 225 } 226 227 /* 228 * Try to get root's secret key, by prompting if terminal is a tty, else trying 229 * from standard input. 230 * Returns 1 on success. 231 */ 232 static int 233 getrootkey(des_block *master, int prompt) 234 { 235 char *passwd; 236 char name[MAXNETNAMELEN + 1]; 237 char secret[HEXKEYBYTES]; 238 key_netstarg netstore; 239 int fd; 240 241 if (!prompt) { 242 /* 243 * Read secret key out of ROOTKEY 244 */ 245 fd = open(ROOTKEY, O_RDONLY, 0); 246 if (fd < 0) { 247 randomize(master); 248 return (0); 249 } 250 if (read(fd, secret, HEXKEYBYTES) < HEXKEYBYTES) { 251 warnx("the key read from %s was too short", ROOTKEY); 252 (void) close(fd); 253 return (0); 254 } 255 (void) close(fd); 256 if (!getnetname(name)) { 257 warnx( 258 "failed to generate host's netname when establishing root's key"); 259 return (0); 260 } 261 memcpy(netstore.st_priv_key, secret, HEXKEYBYTES); 262 memset(netstore.st_pub_key, 0, HEXKEYBYTES); 263 netstore.st_netname = name; 264 if (pk_netput(0, &netstore) != KEY_SUCCESS) { 265 warnx("could not set root's key and netname"); 266 return (0); 267 } 268 return (1); 269 } 270 /* 271 * Decrypt yellow pages publickey entry to get secret key 272 */ 273 passwd = getpass("root password:"); 274 passwd2des(passwd, (char *)master); 275 getnetname(name); 276 if (!getsecretkey(name, secret, passwd)) { 277 warnx("can't find %s's secret key", name); 278 return (0); 279 } 280 if (secret[0] == 0) { 281 warnx("password does not decrypt secret key for %s", name); 282 return (0); 283 } 284 (void) pk_setkey(0, secret); 285 /* 286 * Store it for future use in $ROOTKEY, if possible 287 */ 288 fd = open(ROOTKEY, O_WRONLY|O_TRUNC|O_CREAT, 0); 289 if (fd > 0) { 290 char newline = '\n'; 291 292 write(fd, secret, strlen(secret)); 293 write(fd, &newline, sizeof (newline)); 294 close(fd); 295 } 296 return (1); 297 } 298 299 /* 300 * Procedures to implement RPC service 301 */ 302 char * 303 strstatus(keystatus status) 304 { 305 switch (status) { 306 case KEY_SUCCESS: 307 return ("KEY_SUCCESS"); 308 case KEY_NOSECRET: 309 return ("KEY_NOSECRET"); 310 case KEY_UNKNOWN: 311 return ("KEY_UNKNOWN"); 312 case KEY_SYSTEMERR: 313 return ("KEY_SYSTEMERR"); 314 default: 315 return ("(bad result code)"); 316 } 317 } 318 319 keystatus * 320 key_set_1_svc_prog(uid_t uid, keybuf key) 321 { 322 static keystatus status; 323 324 if (debugging) { 325 (void) fprintf(stderr, "set(%u, %.*s) = ", uid, 326 (int) sizeof (keybuf), key); 327 } 328 status = pk_setkey(uid, key); 329 if (debugging) { 330 (void) fprintf(stderr, "%s\n", strstatus(status)); 331 (void) fflush(stderr); 332 } 333 return (&status); 334 } 335 336 cryptkeyres * 337 key_encrypt_pk_2_svc_prog(uid_t uid, cryptkeyarg2 *arg) 338 { 339 static cryptkeyres res; 340 341 if (debugging) { 342 (void) fprintf(stderr, "encrypt(%u, %s, %08x%08x) = ", uid, 343 arg->remotename, arg->deskey.key.high, 344 arg->deskey.key.low); 345 } 346 res.cryptkeyres_u.deskey = arg->deskey; 347 res.status = pk_encrypt(uid, arg->remotename, &(arg->remotekey), 348 &res.cryptkeyres_u.deskey); 349 if (debugging) { 350 if (res.status == KEY_SUCCESS) { 351 (void) fprintf(stderr, "%08x%08x\n", 352 res.cryptkeyres_u.deskey.key.high, 353 res.cryptkeyres_u.deskey.key.low); 354 } else { 355 (void) fprintf(stderr, "%s\n", strstatus(res.status)); 356 } 357 (void) fflush(stderr); 358 } 359 return (&res); 360 } 361 362 cryptkeyres * 363 key_decrypt_pk_2_svc_prog(uid_t uid, cryptkeyarg2 *arg) 364 { 365 static cryptkeyres res; 366 367 if (debugging) { 368 (void) fprintf(stderr, "decrypt(%u, %s, %08x%08x) = ", uid, 369 arg->remotename, arg->deskey.key.high, 370 arg->deskey.key.low); 371 } 372 res.cryptkeyres_u.deskey = arg->deskey; 373 res.status = pk_decrypt(uid, arg->remotename, &(arg->remotekey), 374 &res.cryptkeyres_u.deskey); 375 if (debugging) { 376 if (res.status == KEY_SUCCESS) { 377 (void) fprintf(stderr, "%08x%08x\n", 378 res.cryptkeyres_u.deskey.key.high, 379 res.cryptkeyres_u.deskey.key.low); 380 } else { 381 (void) fprintf(stderr, "%s\n", strstatus(res.status)); 382 } 383 (void) fflush(stderr); 384 } 385 return (&res); 386 } 387 388 keystatus * 389 key_net_put_2_svc_prog(uid_t uid, key_netstarg *arg) 390 { 391 static keystatus status; 392 393 if (debugging) { 394 (void) fprintf(stderr, "net_put(%s, %.*s, %.*s) = ", 395 arg->st_netname, (int)sizeof (arg->st_pub_key), 396 arg->st_pub_key, (int)sizeof (arg->st_priv_key), 397 arg->st_priv_key); 398 } 399 400 status = pk_netput(uid, arg); 401 402 if (debugging) { 403 (void) fprintf(stderr, "%s\n", strstatus(status)); 404 (void) fflush(stderr); 405 } 406 407 return (&status); 408 } 409 410 key_netstres * 411 key_net_get_2_svc_prog(uid_t uid, void *arg) 412 { 413 static key_netstres keynetname; 414 415 if (debugging) 416 (void) fprintf(stderr, "net_get(%u) = ", uid); 417 418 keynetname.status = pk_netget(uid, &keynetname.key_netstres_u.knet); 419 if (debugging) { 420 if (keynetname.status == KEY_SUCCESS) { 421 fprintf(stderr, "<%s, %.*s, %.*s>\n", 422 keynetname.key_netstres_u.knet.st_netname, 423 (int)sizeof (keynetname.key_netstres_u.knet.st_pub_key), 424 keynetname.key_netstres_u.knet.st_pub_key, 425 (int)sizeof (keynetname.key_netstres_u.knet.st_priv_key), 426 keynetname.key_netstres_u.knet.st_priv_key); 427 } else { 428 (void) fprintf(stderr, "NOT FOUND\n"); 429 } 430 (void) fflush(stderr); 431 } 432 433 return (&keynetname); 434 435 } 436 437 cryptkeyres * 438 key_get_conv_2_svc_prog(uid_t uid, keybuf arg) 439 { 440 static cryptkeyres res; 441 442 if (debugging) 443 (void) fprintf(stderr, "get_conv(%u, %.*s) = ", uid, 444 (int)sizeof (keybuf), arg); 445 446 447 res.status = pk_get_conv_key(uid, arg, &res); 448 449 if (debugging) { 450 if (res.status == KEY_SUCCESS) { 451 (void) fprintf(stderr, "%08x%08x\n", 452 res.cryptkeyres_u.deskey.key.high, 453 res.cryptkeyres_u.deskey.key.low); 454 } else { 455 (void) fprintf(stderr, "%s\n", strstatus(res.status)); 456 } 457 (void) fflush(stderr); 458 } 459 return (&res); 460 } 461 462 463 cryptkeyres * 464 key_encrypt_1_svc_prog(uid_t uid, cryptkeyarg *arg) 465 { 466 static cryptkeyres res; 467 468 if (debugging) { 469 (void) fprintf(stderr, "encrypt(%u, %s, %08x%08x) = ", uid, 470 arg->remotename, arg->deskey.key.high, 471 arg->deskey.key.low); 472 } 473 res.cryptkeyres_u.deskey = arg->deskey; 474 res.status = pk_encrypt(uid, arg->remotename, NULL, 475 &res.cryptkeyres_u.deskey); 476 if (debugging) { 477 if (res.status == KEY_SUCCESS) { 478 (void) fprintf(stderr, "%08x%08x\n", 479 res.cryptkeyres_u.deskey.key.high, 480 res.cryptkeyres_u.deskey.key.low); 481 } else { 482 (void) fprintf(stderr, "%s\n", strstatus(res.status)); 483 } 484 (void) fflush(stderr); 485 } 486 return (&res); 487 } 488 489 cryptkeyres * 490 key_decrypt_1_svc_prog(uid_t uid, cryptkeyarg *arg) 491 { 492 static cryptkeyres res; 493 494 if (debugging) { 495 (void) fprintf(stderr, "decrypt(%u, %s, %08x%08x) = ", uid, 496 arg->remotename, arg->deskey.key.high, 497 arg->deskey.key.low); 498 } 499 res.cryptkeyres_u.deskey = arg->deskey; 500 res.status = pk_decrypt(uid, arg->remotename, NULL, 501 &res.cryptkeyres_u.deskey); 502 if (debugging) { 503 if (res.status == KEY_SUCCESS) { 504 (void) fprintf(stderr, "%08x%08x\n", 505 res.cryptkeyres_u.deskey.key.high, 506 res.cryptkeyres_u.deskey.key.low); 507 } else { 508 (void) fprintf(stderr, "%s\n", strstatus(res.status)); 509 } 510 (void) fflush(stderr); 511 } 512 return (&res); 513 } 514 515 /* ARGSUSED */ 516 des_block * 517 key_gen_1_svc_prog(void *v, struct svc_req *s) 518 { 519 struct timeval time; 520 static des_block keygen; 521 static des_block key; 522 523 (void)gettimeofday(&time, NULL); 524 keygen.key.high += (time.tv_sec ^ time.tv_usec); 525 keygen.key.low += (time.tv_sec ^ time.tv_usec); 526 ecb_crypt((char *)&masterkey, (char *)&keygen, sizeof (keygen), 527 DES_ENCRYPT | DES_HW); 528 key = keygen; 529 des_setparity((char *)&key); 530 if (debugging) { 531 (void) fprintf(stderr, "gen() = %08x%08x\n", key.key.high, 532 key.key.low); 533 (void) fflush(stderr); 534 } 535 return (&key); 536 } 537 538 getcredres * 539 key_getcred_1_svc_prog(uid_t uid, netnamestr *name) 540 { 541 static getcredres res; 542 static u_int gids[NGROUPS]; 543 struct unixcred *cred; 544 545 cred = &res.getcredres_u.cred; 546 cred->gids.gids_val = gids; 547 if (!netname2user(*name, (uid_t *) &cred->uid, (gid_t *) &cred->gid, 548 (int *)&cred->gids.gids_len, (gid_t *)gids)) { 549 res.status = KEY_UNKNOWN; 550 } else { 551 res.status = KEY_SUCCESS; 552 } 553 if (debugging) { 554 (void) fprintf(stderr, "getcred(%s) = ", *name); 555 if (res.status == KEY_SUCCESS) { 556 (void) fprintf(stderr, "uid=%d, gid=%d, grouplen=%d\n", 557 cred->uid, cred->gid, cred->gids.gids_len); 558 } else { 559 (void) fprintf(stderr, "%s\n", strstatus(res.status)); 560 } 561 (void) fflush(stderr); 562 } 563 return (&res); 564 } 565 566 /* 567 * RPC boilerplate 568 */ 569 static void 570 keyprogram(struct svc_req *rqstp, SVCXPRT *transp) 571 { 572 union { 573 keybuf key_set_1_arg; 574 cryptkeyarg key_encrypt_1_arg; 575 cryptkeyarg key_decrypt_1_arg; 576 netnamestr key_getcred_1_arg; 577 cryptkeyarg key_encrypt_2_arg; 578 cryptkeyarg key_decrypt_2_arg; 579 netnamestr key_getcred_2_arg; 580 cryptkeyarg2 key_encrypt_pk_2_arg; 581 cryptkeyarg2 key_decrypt_pk_2_arg; 582 key_netstarg key_net_put_2_arg; 583 netobj key_get_conv_2_arg; 584 } argument; 585 char *result; 586 xdrproc_t xdr_argument, xdr_result; 587 typedef void *(svc_cb)(uid_t uid, void *arg); 588 svc_cb *local; 589 uid_t uid = -1; 590 int check_auth; 591 592 switch (rqstp->rq_proc) { 593 case NULLPROC: 594 svc_sendreply(transp, (xdrproc_t)xdr_void, NULL); 595 return; 596 597 case KEY_SET: 598 xdr_argument = (xdrproc_t)xdr_keybuf; 599 xdr_result = (xdrproc_t)xdr_int; 600 local = (svc_cb *)key_set_1_svc_prog; 601 check_auth = 1; 602 break; 603 604 case KEY_ENCRYPT: 605 xdr_argument = (xdrproc_t)xdr_cryptkeyarg; 606 xdr_result = (xdrproc_t)xdr_cryptkeyres; 607 local = (svc_cb *)key_encrypt_1_svc_prog; 608 check_auth = 1; 609 break; 610 611 case KEY_DECRYPT: 612 xdr_argument = (xdrproc_t)xdr_cryptkeyarg; 613 xdr_result = (xdrproc_t)xdr_cryptkeyres; 614 local = (svc_cb *)key_decrypt_1_svc_prog; 615 check_auth = 1; 616 break; 617 618 case KEY_GEN: 619 xdr_argument = (xdrproc_t)xdr_void; 620 xdr_result = (xdrproc_t)xdr_des_block; 621 local = (svc_cb *)key_gen_1_svc_prog; 622 check_auth = 0; 623 break; 624 625 case KEY_GETCRED: 626 xdr_argument = (xdrproc_t)xdr_netnamestr; 627 xdr_result = (xdrproc_t)xdr_getcredres; 628 local = (svc_cb *)key_getcred_1_svc_prog; 629 check_auth = 0; 630 break; 631 632 case KEY_ENCRYPT_PK: 633 xdr_argument = (xdrproc_t)xdr_cryptkeyarg2; 634 xdr_result = (xdrproc_t)xdr_cryptkeyres; 635 local = (svc_cb *)key_encrypt_pk_2_svc_prog; 636 check_auth = 1; 637 break; 638 639 case KEY_DECRYPT_PK: 640 xdr_argument = (xdrproc_t)xdr_cryptkeyarg2; 641 xdr_result = (xdrproc_t)xdr_cryptkeyres; 642 local = (svc_cb *)key_decrypt_pk_2_svc_prog; 643 check_auth = 1; 644 break; 645 646 647 case KEY_NET_PUT: 648 xdr_argument = (xdrproc_t)xdr_key_netstarg; 649 xdr_result = (xdrproc_t)xdr_keystatus; 650 local = (svc_cb *)key_net_put_2_svc_prog; 651 check_auth = 1; 652 break; 653 654 case KEY_NET_GET: 655 xdr_argument = (xdrproc_t) xdr_void; 656 xdr_result = (xdrproc_t)xdr_key_netstres; 657 local = (svc_cb *)key_net_get_2_svc_prog; 658 check_auth = 1; 659 break; 660 661 case KEY_GET_CONV: 662 xdr_argument = (xdrproc_t) xdr_keybuf; 663 xdr_result = (xdrproc_t)xdr_cryptkeyres; 664 local = (svc_cb *)key_get_conv_2_svc_prog; 665 check_auth = 1; 666 break; 667 668 default: 669 svcerr_noproc(transp); 670 return; 671 } 672 if (check_auth) { 673 if (root_auth(transp, rqstp) == 0) { 674 if (debugging) { 675 (void) fprintf(stderr, 676 "not local privileged process\n"); 677 } 678 svcerr_weakauth(transp); 679 return; 680 } 681 if (rqstp->rq_cred.oa_flavor != AUTH_SYS) { 682 if (debugging) { 683 (void) fprintf(stderr, 684 "not unix authentication\n"); 685 } 686 svcerr_weakauth(transp); 687 return; 688 } 689 uid = ((struct authsys_parms *)rqstp->rq_clntcred)->aup_uid; 690 } 691 692 memset(&argument, 0, sizeof (argument)); 693 if (!svc_getargs(transp, xdr_argument, &argument)) { 694 svcerr_decode(transp); 695 return; 696 } 697 result = (*local) (uid, &argument); 698 if (!svc_sendreply(transp, xdr_result, result)) { 699 if (debugging) 700 (void) fprintf(stderr, "unable to reply\n"); 701 svcerr_systemerr(transp); 702 } 703 if (!svc_freeargs(transp, xdr_argument, &argument)) { 704 if (debugging) 705 (void) fprintf(stderr, 706 "unable to free arguments\n"); 707 exit(1); 708 } 709 return; 710 } 711 712 static int 713 root_auth(SVCXPRT *trans, struct svc_req *rqstp) 714 { 715 uid_t uid; 716 struct sockaddr *remote; 717 718 remote = svc_getrpccaller(trans)->buf; 719 if (remote->sa_family != AF_UNIX) { 720 if (debugging) 721 fprintf(stderr, "client didn't use AF_UNIX\n"); 722 return (0); 723 } 724 725 if (__rpc_get_local_uid(trans, &uid) < 0) { 726 if (debugging) 727 fprintf(stderr, "__rpc_get_local_uid failed\n"); 728 return (0); 729 } 730 731 if (debugging) 732 fprintf(stderr, "local_uid %u\n", uid); 733 if (uid == 0) 734 return (1); 735 if (rqstp->rq_cred.oa_flavor == AUTH_SYS) { 736 if (((uid_t) ((struct authunix_parms *) 737 rqstp->rq_clntcred)->aup_uid) 738 == uid) { 739 return (1); 740 } else { 741 if (debugging) 742 fprintf(stderr, 743 "local_uid %u mismatches auth %u\n", uid, 744 ((uid_t) ((struct authunix_parms *)rqstp->rq_clntcred)->aup_uid)); 745 return (0); 746 } 747 } else { 748 if (debugging) 749 fprintf(stderr, "Not auth sys\n"); 750 return (0); 751 } 752 } 753 754 static void 755 usage(void) 756 { 757 (void) fprintf(stderr, 758 "usage: keyserv [-n] [-D] [-d] [-v] [-p path]\n"); 759 (void) fprintf(stderr, "-d disables the use of default keys\n"); 760 exit(1); 761 } 762