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, MERCHANTABILITY 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 * @(#)keyserv.c 1.15 94/04/25 SMI 30 * $FreeBSD: src/usr.sbin/keyserv/keyserv.c,v 1.12 2007/11/07 10:53:35 kevlo Exp $ 31 */ 32 33 /* 34 * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc. 35 */ 36 37 /* 38 * Keyserver 39 * Store secret keys per uid. Do public key encryption and decryption 40 * operations. Generate "random" keys. 41 * Do not talk to anything but a local root 42 * process on the local transport only 43 */ 44 45 #include <err.h> 46 #include <fcntl.h> 47 #include <pwd.h> 48 #include <stdio.h> 49 #include <stdlib.h> 50 #include <string.h> 51 #include <unistd.h> 52 #include <sys/stat.h> 53 #include <sys/types.h> 54 #include <rpc/rpc.h> 55 #include <sys/param.h> 56 #include <rpc/des_crypt.h> 57 #include <rpc/des.h> 58 #include <rpc/key_prot.h> 59 #include <rpcsvc/crypt.h> 60 #include "keyserv.h" 61 62 #ifndef NGROUPS 63 #define NGROUPS 16 64 #endif 65 66 #ifndef KEYSERVSOCK 67 #define KEYSERVSOCK "/var/run/keyservsock" 68 #endif 69 70 static void randomize( des_block * ); 71 static void usage( void ); 72 static int getrootkey( des_block *, int ); 73 static int root_auth( SVCXPRT *, struct svc_req * ); 74 75 #ifdef DEBUG 76 static int debugging = 1; 77 #else 78 static int debugging = 0; 79 #endif 80 81 static void keyprogram(); 82 static des_block masterkey; 83 char *getenv(); 84 static char ROOTKEY[] = "/etc/.rootkey"; 85 86 /* 87 * Hack to allow the keyserver to use AUTH_DES (for authenticated 88 * NIS+ calls, for example). The only functions that get called 89 * are key_encryptsession_pk, key_decryptsession_pk, and key_gendes. 90 * 91 * The approach is to have the keyserver fill in pointers to local 92 * implementations of these functions, and to call those in key_call(). 93 */ 94 95 extern cryptkeyres *(*__key_encryptsession_pk_LOCAL)(); 96 extern cryptkeyres *(*__key_decryptsession_pk_LOCAL)(); 97 extern des_block *(*__key_gendes_LOCAL)(); 98 extern int (*__des_crypt_LOCAL)(); 99 100 cryptkeyres *key_encrypt_pk_2_svc_prog( uid_t, cryptkeyarg2 * ); 101 cryptkeyres *key_decrypt_pk_2_svc_prog( uid_t, cryptkeyarg2 * ); 102 des_block *key_gen_1_svc_prog( void *, struct svc_req * ); 103 104 int 105 main(int argc, char **argv) 106 { 107 int nflag = 0; 108 int c; 109 int warn = 0; 110 char *path = NULL; 111 void *localhandle; 112 SVCXPRT *transp; 113 struct netconfig *nconf = NULL; 114 115 __key_encryptsession_pk_LOCAL = &key_encrypt_pk_2_svc_prog; 116 __key_decryptsession_pk_LOCAL = &key_decrypt_pk_2_svc_prog; 117 __key_gendes_LOCAL = &key_gen_1_svc_prog; 118 119 while ((c = getopt(argc, argv, "ndDvp:")) != -1) 120 switch (c) { 121 case 'n': 122 nflag++; 123 break; 124 case 'd': 125 pk_nodefaultkeys(); 126 break; 127 case 'D': 128 debugging = 1; 129 break; 130 case 'v': 131 warn = 1; 132 break; 133 case 'p': 134 path = optarg; 135 break; 136 default: 137 usage(); 138 } 139 140 load_des(warn, path); 141 __des_crypt_LOCAL = _my_crypt; 142 if (svc_auth_reg(AUTH_DES, _svcauth_des) == -1) 143 errx(1, "failed to register AUTH_DES authenticator"); 144 145 if (optind != argc) { 146 usage(); 147 } 148 149 /* 150 * Initialize 151 */ 152 umask(S_IXUSR|S_IXGRP|S_IXOTH); 153 if (geteuid() != 0) 154 errx(1, "keyserv must be run as root"); 155 setmodulus(HEXMODULUS); 156 getrootkey(&masterkey, nflag); 157 158 rpcb_unset(KEY_PROG, KEY_VERS, NULL); 159 rpcb_unset(KEY_PROG, KEY_VERS2, NULL); 160 161 if (svc_create(keyprogram, KEY_PROG, KEY_VERS, 162 "netpath") == 0) { 163 fprintf(stderr, "%s: unable to create service\n", argv[0]); 164 exit(1); 165 } 166 167 if (svc_create(keyprogram, KEY_PROG, KEY_VERS2, 168 "netpath") == 0) { 169 fprintf(stderr, "%s: unable to create service\n", argv[0]); 170 exit(1); 171 } 172 173 localhandle = setnetconfig(); 174 while ((nconf = getnetconfig(localhandle)) != NULL) { 175 if (nconf->nc_protofmly != NULL && 176 strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) 177 break; 178 } 179 180 if (nconf == NULL) 181 errx(1, "getnetconfig: %s", nc_sperror()); 182 183 unlink(KEYSERVSOCK); 184 rpcb_unset(CRYPT_PROG, CRYPT_VERS, nconf); 185 transp = svcunix_create(RPC_ANYSOCK, 0, 0, KEYSERVSOCK); 186 if (transp == NULL) 187 errx(1, "cannot create AF_LOCAL service"); 188 if (!svc_reg(transp, KEY_PROG, KEY_VERS, keyprogram, nconf)) 189 errx(1, "unable to register (KEY_PROG, KEY_VERS, unix)"); 190 if (!svc_reg(transp, KEY_PROG, KEY_VERS2, keyprogram, nconf)) 191 errx(1, "unable to register (KEY_PROG, KEY_VERS2, unix)"); 192 if (!svc_reg(transp, CRYPT_PROG, CRYPT_VERS, crypt_prog_1, nconf)) 193 errx(1, "unable to register (CRYPT_PROG, CRYPT_VERS, unix)"); 194 195 endnetconfig(localhandle); 196 197 umask(066); /* paranoia */ 198 199 if (!debugging) { 200 daemon(0,0); 201 } 202 203 signal(SIGPIPE, SIG_IGN); 204 205 svc_run(); 206 abort(); 207 /* NOTREACHED */ 208 } 209 210 /* 211 * In the event that we don't get a root password, we try to 212 * randomize the master key the best we can 213 */ 214 static void 215 randomize(des_block *master) 216 { 217 #ifdef KEYSERV_RANDOM 218 master->key.low = arc4random(); 219 master->key.high = arc4random(); 220 #else 221 /* use stupid dangerous bad rand() */ 222 sranddev(); 223 master->key.low = rand(); 224 master->key.high = rand(); 225 #endif 226 } 227 228 /* 229 * Try to get root's secret key, by prompting if terminal is a tty, else trying 230 * from standard input. 231 * Returns 1 on success. 232 */ 233 static int 234 getrootkey(des_block *master, int prompt) 235 { 236 char *passwd; 237 char name[MAXNETNAMELEN + 1]; 238 char secret[HEXKEYBYTES]; 239 key_netstarg netstore; 240 int fd; 241 242 if (!prompt) { 243 /* 244 * Read secret key out of ROOTKEY 245 */ 246 fd = open(ROOTKEY, O_RDONLY, 0); 247 if (fd < 0) { 248 randomize(master); 249 return (0); 250 } 251 if (read(fd, secret, HEXKEYBYTES) < HEXKEYBYTES) { 252 warnx("the key read from %s was too short", ROOTKEY); 253 close(fd); 254 return (0); 255 } 256 close(fd); 257 if (!getnetname(name)) { 258 warnx( 259 "failed to generate host's netname when establishing root's key"); 260 return (0); 261 } 262 memcpy(netstore.st_priv_key, secret, HEXKEYBYTES); 263 memset(netstore.st_pub_key, 0, HEXKEYBYTES); 264 netstore.st_netname = name; 265 if (pk_netput(0, &netstore) != KEY_SUCCESS) { 266 warnx("could not set root's key and netname"); 267 return (0); 268 } 269 return (1); 270 } 271 /* 272 * Decrypt yellow pages publickey entry to get secret key 273 */ 274 passwd = getpass("root password:"); 275 passwd2des(passwd, (char *)master); 276 getnetname(name); 277 if (!getsecretkey(name, secret, passwd)) { 278 warnx("can't find %s's secret key", name); 279 return (0); 280 } 281 if (secret[0] == 0) { 282 warnx("password does not decrypt secret key for %s", name); 283 return (0); 284 } 285 pk_setkey(0, secret); 286 /* 287 * Store it for future use in $ROOTKEY, if possible 288 */ 289 fd = open(ROOTKEY, O_WRONLY|O_TRUNC|O_CREAT, 0); 290 if (fd > 0) { 291 char newline = '\n'; 292 293 write(fd, secret, strlen(secret)); 294 write(fd, &newline, sizeof (newline)); 295 close(fd); 296 } 297 return (1); 298 } 299 300 /* 301 * Procedures to implement RPC service 302 */ 303 char * 304 strstatus(keystatus status) 305 { 306 switch (status) { 307 case KEY_SUCCESS: 308 return ("KEY_SUCCESS"); 309 case KEY_NOSECRET: 310 return ("KEY_NOSECRET"); 311 case KEY_UNKNOWN: 312 return ("KEY_UNKNOWN"); 313 case KEY_SYSTEMERR: 314 return ("KEY_SYSTEMERR"); 315 default: 316 return ("(bad result code)"); 317 } 318 } 319 320 keystatus * 321 key_set_1_svc_prog(uid_t uid, keybuf key) 322 { 323 static keystatus status; 324 325 if (debugging) { 326 fprintf(stderr, "set(%d, %.*s) = ", uid, 327 (int) sizeof (keybuf), key); 328 } 329 status = pk_setkey(uid, key); 330 if (debugging) { 331 fprintf(stderr, "%s\n", strstatus(status)); 332 fflush(stderr); 333 } 334 return (&status); 335 } 336 337 cryptkeyres * 338 key_encrypt_pk_2_svc_prog(uid_t uid, cryptkeyarg2 *arg) 339 { 340 static cryptkeyres res; 341 342 if (debugging) { 343 fprintf(stderr, "encrypt(%d, %s, %08x%08x) = ", uid, 344 arg->remotename, arg->deskey.key.high, 345 arg->deskey.key.low); 346 } 347 res.cryptkeyres_u.deskey = arg->deskey; 348 res.status = pk_encrypt(uid, arg->remotename, &(arg->remotekey), 349 &res.cryptkeyres_u.deskey); 350 if (debugging) { 351 if (res.status == KEY_SUCCESS) { 352 fprintf(stderr, "%08x%08x\n", 353 res.cryptkeyres_u.deskey.key.high, 354 res.cryptkeyres_u.deskey.key.low); 355 } else { 356 fprintf(stderr, "%s\n", strstatus(res.status)); 357 } 358 fflush(stderr); 359 } 360 return (&res); 361 } 362 363 cryptkeyres * 364 key_decrypt_pk_2_svc_prog(uid_t uid, cryptkeyarg2 *arg) 365 { 366 static cryptkeyres res; 367 368 if (debugging) { 369 fprintf(stderr, "decrypt(%d, %s, %08x%08x) = ", uid, 370 arg->remotename, arg->deskey.key.high, 371 arg->deskey.key.low); 372 } 373 res.cryptkeyres_u.deskey = arg->deskey; 374 res.status = pk_decrypt(uid, arg->remotename, &(arg->remotekey), 375 &res.cryptkeyres_u.deskey); 376 if (debugging) { 377 if (res.status == KEY_SUCCESS) { 378 fprintf(stderr, "%08x%08x\n", 379 res.cryptkeyres_u.deskey.key.high, 380 res.cryptkeyres_u.deskey.key.low); 381 } else { 382 fprintf(stderr, "%s\n", strstatus(res.status)); 383 } 384 fflush(stderr); 385 } 386 return (&res); 387 } 388 389 keystatus * 390 key_net_put_2_svc_prog(uid_t uid, key_netstarg *arg) 391 { 392 static keystatus status; 393 394 if (debugging) { 395 fprintf(stderr, "net_put(%s, %.*s, %.*s) = ", 396 arg->st_netname, (int)sizeof (arg->st_pub_key), 397 arg->st_pub_key, (int)sizeof (arg->st_priv_key), 398 arg->st_priv_key); 399 } 400 401 status = pk_netput(uid, arg); 402 403 if (debugging) { 404 fprintf(stderr, "%s\n", strstatus(status)); 405 fflush(stderr); 406 } 407 408 return (&status); 409 } 410 411 key_netstres * 412 key_net_get_2_svc_prog(uid_t uid, void *arg) 413 { 414 static key_netstres keynetname; 415 416 if (debugging) 417 fprintf(stderr, "net_get(%d) = ", uid); 418 419 keynetname.status = pk_netget(uid, &keynetname.key_netstres_u.knet); 420 if (debugging) { 421 if (keynetname.status == KEY_SUCCESS) { 422 fprintf(stderr, "<%s, %.*s, %.*s>\n", 423 keynetname.key_netstres_u.knet.st_netname, 424 (int)sizeof (keynetname.key_netstres_u.knet.st_pub_key), 425 keynetname.key_netstres_u.knet.st_pub_key, 426 (int)sizeof (keynetname.key_netstres_u.knet.st_priv_key), 427 keynetname.key_netstres_u.knet.st_priv_key); 428 } else { 429 fprintf(stderr, "NOT FOUND\n"); 430 } 431 fflush(stderr); 432 } 433 434 return (&keynetname); 435 436 } 437 438 cryptkeyres * 439 key_get_conv_2_svc_prog(uid_t uid, keybuf arg) 440 { 441 static cryptkeyres res; 442 443 if (debugging) 444 fprintf(stderr, "get_conv(%d, %.*s) = ", uid, 445 (int)sizeof (keybuf), arg); 446 447 448 res.status = pk_get_conv_key(uid, arg, &res); 449 450 if (debugging) { 451 if (res.status == KEY_SUCCESS) { 452 fprintf(stderr, "%08x%08x\n", 453 res.cryptkeyres_u.deskey.key.high, 454 res.cryptkeyres_u.deskey.key.low); 455 } else { 456 fprintf(stderr, "%s\n", strstatus(res.status)); 457 } 458 fflush(stderr); 459 } 460 return (&res); 461 } 462 463 464 cryptkeyres * 465 key_encrypt_1_svc_prog(uid_t uid, cryptkeyarg *arg) 466 { 467 static cryptkeyres res; 468 469 if (debugging) { 470 fprintf(stderr, "encrypt(%d, %s, %08x%08x) = ", uid, 471 arg->remotename, arg->deskey.key.high, 472 arg->deskey.key.low); 473 } 474 res.cryptkeyres_u.deskey = arg->deskey; 475 res.status = pk_encrypt(uid, arg->remotename, NULL, 476 &res.cryptkeyres_u.deskey); 477 if (debugging) { 478 if (res.status == KEY_SUCCESS) { 479 fprintf(stderr, "%08x%08x\n", 480 res.cryptkeyres_u.deskey.key.high, 481 res.cryptkeyres_u.deskey.key.low); 482 } else { 483 fprintf(stderr, "%s\n", strstatus(res.status)); 484 } 485 fflush(stderr); 486 } 487 return (&res); 488 } 489 490 cryptkeyres * 491 key_decrypt_1_svc_prog(uid_t uid, cryptkeyarg *arg) 492 { 493 static cryptkeyres res; 494 495 if (debugging) { 496 fprintf(stderr, "decrypt(%d, %s, %08x%08x) = ", uid, 497 arg->remotename, arg->deskey.key.high, 498 arg->deskey.key.low); 499 } 500 res.cryptkeyres_u.deskey = arg->deskey; 501 res.status = pk_decrypt(uid, arg->remotename, NULL, 502 &res.cryptkeyres_u.deskey); 503 if (debugging) { 504 if (res.status == KEY_SUCCESS) { 505 fprintf(stderr, "%08x%08x\n", 506 res.cryptkeyres_u.deskey.key.high, 507 res.cryptkeyres_u.deskey.key.low); 508 } else { 509 fprintf(stderr, "%s\n", strstatus(res.status)); 510 } 511 fflush(stderr); 512 } 513 return (&res); 514 } 515 516 /* ARGSUSED */ 517 des_block * 518 key_gen_1_svc_prog(void *v, struct svc_req *s) 519 { 520 struct timeval time; 521 static des_block keygen; 522 static des_block key; 523 524 gettimeofday(&time, NULL); 525 keygen.key.high += (time.tv_sec ^ time.tv_usec); 526 keygen.key.low += (time.tv_sec ^ time.tv_usec); 527 ecb_crypt((char *)&masterkey, (char *)&keygen, sizeof (keygen), 528 DES_ENCRYPT | DES_HW); 529 key = keygen; 530 des_setparity((char *)&key); 531 if (debugging) { 532 fprintf(stderr, "gen() = %08x%08x\n", key.key.high, 533 key.key.low); 534 fflush(stderr); 535 } 536 return (&key); 537 } 538 539 getcredres * 540 key_getcred_1_svc_prog(uid_t uid, netnamestr *name) 541 { 542 static getcredres res; 543 static u_int gids[NGROUPS]; 544 struct unixcred *cred; 545 546 cred = &res.getcredres_u.cred; 547 cred->gids.gids_val = gids; 548 if (!netname2user(*name, (uid_t *) &cred->uid, (gid_t *) &cred->gid, 549 (int *)&cred->gids.gids_len, (gid_t *)gids)) { 550 res.status = KEY_UNKNOWN; 551 } else { 552 res.status = KEY_SUCCESS; 553 } 554 if (debugging) { 555 fprintf(stderr, "getcred(%s) = ", *name); 556 if (res.status == KEY_SUCCESS) { 557 fprintf(stderr, "uid=%d, gid=%d, grouplen=%d\n", 558 cred->uid, cred->gid, cred->gids.gids_len); 559 } else { 560 fprintf(stderr, "%s\n", strstatus(res.status)); 561 } 562 fflush(stderr); 563 } 564 return (&res); 565 } 566 567 /* 568 * RPC boilerplate 569 */ 570 static void 571 keyprogram(struct svc_req *rqstp, SVCXPRT *transp) 572 { 573 union { 574 keybuf key_set_1_arg; 575 cryptkeyarg key_encrypt_1_arg; 576 cryptkeyarg key_decrypt_1_arg; 577 netnamestr key_getcred_1_arg; 578 cryptkeyarg key_encrypt_2_arg; 579 cryptkeyarg key_decrypt_2_arg; 580 netnamestr key_getcred_2_arg; 581 cryptkeyarg2 key_encrypt_pk_2_arg; 582 cryptkeyarg2 key_decrypt_pk_2_arg; 583 key_netstarg key_net_put_2_arg; 584 netobj key_get_conv_2_arg; 585 } argument; 586 char *result; 587 xdrproc_t xdr_argument, xdr_result; 588 char *(*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 = (char *(*)()) 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 = (char *(*)()) 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 = (char *(*)()) 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 = (char *(*)()) 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 = (char *(*)()) 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 = (char *(*)()) 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 = (char *(*)()) 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 = (char *(*)()) 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 = (char *(*)()) 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 = (char *(*)()) 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 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 fprintf(stderr, "not unix authentication\n"); 684 } 685 svcerr_weakauth(transp); 686 return; 687 } 688 uid = ((struct authsys_parms *)rqstp->rq_clntcred)->aup_uid; 689 } 690 691 memset(&argument, 0, sizeof (argument)); 692 if (!svc_getargs(transp, xdr_argument, &argument)) { 693 svcerr_decode(transp); 694 return; 695 } 696 result = (*local) (uid, &argument); 697 if (!svc_sendreply(transp, xdr_result, result)) { 698 if (debugging) 699 fprintf(stderr, "unable to reply\n"); 700 svcerr_systemerr(transp); 701 } 702 if (!svc_freeargs(transp, xdr_argument, &argument)) { 703 if (debugging) 704 fprintf(stderr, "unable to free arguments\n"); 705 exit(1); 706 } 707 return; 708 } 709 710 static int 711 root_auth(SVCXPRT *trans, struct svc_req *rqstp) 712 { 713 uid_t uid; 714 struct sockaddr *remote; 715 716 remote = svc_getrpccaller(trans)->buf; 717 if (remote->sa_family != AF_UNIX) { 718 if (debugging) 719 fprintf(stderr, "client didn't use AF_UNIX\n"); 720 return (0); 721 } 722 723 if (__rpc_get_local_uid(trans, &uid) < 0) { 724 if (debugging) 725 fprintf(stderr, "__rpc_get_local_uid failed\n"); 726 return (0); 727 } 728 729 if (debugging) 730 fprintf(stderr, "local_uid %d\n", uid); 731 if (uid == 0) 732 return (1); 733 if (rqstp->rq_cred.oa_flavor == AUTH_SYS) { 734 if (((uid_t) ((struct authunix_parms *) 735 rqstp->rq_clntcred)->aup_uid) 736 == uid) { 737 return (1); 738 } else { 739 if (debugging) 740 fprintf(stderr, 741 "local_uid %d mismatches auth %u\n", uid, 742 ((uid_t) ((struct authunix_parms *)rqstp->rq_clntcred)->aup_uid)); 743 return (0); 744 } 745 } else { 746 if (debugging) 747 fprintf(stderr, "Not auth sys\n"); 748 return (0); 749 } 750 } 751 752 static void 753 usage(void) 754 { 755 fprintf(stderr, "usage: keyserv [-n] [-D] [-d] [-v] [-p path]\n"); 756 fprintf(stderr, "-d disables the use of default keys\n"); 757 exit(1); 758 } 759