keyserv.c revision 74627
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 32static char sccsid[] = "@(#)keyserv.c 1.15 94/04/25 SMI"; 33#endif 34static const char rcsid[] = 35 "$FreeBSD: head/usr.sbin/keyserv/keyserv.c 74627 2001-03-22 04:31:30Z alfred $"; 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 75static void randomize __P(( des_block * )); 76static void usage __P(( void )); 77static int getrootkey __P(( des_block *, int )); 78static int root_auth __P(( SVCXPRT *, struct svc_req * )); 79 80#ifdef DEBUG 81static int debugging = 1; 82#else 83static int debugging = 0; 84#endif 85 86static void keyprogram(); 87static des_block masterkey; 88char *getenv(); 89static char ROOTKEY[] = "/etc/.rootkey"; 90 91/* 92 * Hack to allow the keyserver to use AUTH_DES (for authenticated 93 * NIS+ calls, for example). The only functions that get called 94 * are key_encryptsession_pk, key_decryptsession_pk, and key_gendes. 95 * 96 * The approach is to have the keyserver fill in pointers to local 97 * implementations of these functions, and to call those in key_call(). 98 */ 99 100extern cryptkeyres *(*__key_encryptsession_pk_LOCAL)(); 101extern cryptkeyres *(*__key_decryptsession_pk_LOCAL)(); 102extern des_block *(*__key_gendes_LOCAL)(); 103extern int (*__des_crypt_LOCAL)(); 104 105cryptkeyres *key_encrypt_pk_2_svc_prog __P(( uid_t, cryptkeyarg2 * )); 106cryptkeyres *key_decrypt_pk_2_svc_prog __P(( uid_t, cryptkeyarg2 * )); 107des_block *key_gen_1_svc_prog __P(( void *, struct svc_req * )); 108 109int 110main(argc, argv) 111 int argc; 112 char *argv[]; 113{ 114 int nflag = 0; 115 int c; 116 register SVCXPRT *transp; 117 int sock = RPC_ANYSOCK; 118 int warn = 0; 119 char *path = NULL; 120 121 __key_encryptsession_pk_LOCAL = &key_encrypt_pk_2_svc_prog; 122 __key_decryptsession_pk_LOCAL = &key_decrypt_pk_2_svc_prog; 123 __key_gendes_LOCAL = &key_gen_1_svc_prog; 124 125 while ((c = getopt(argc, argv, "ndDvp:")) != -1) 126 switch (c) { 127 case 'n': 128 nflag++; 129 break; 130 case 'd': 131 pk_nodefaultkeys(); 132 break; 133 case 'D': 134 debugging = 1; 135 break; 136 case 'v': 137 warn = 1; 138 break; 139 case 'p': 140 path = optarg; 141 break; 142 default: 143 usage(); 144 } 145 146 load_des(warn, path); 147 __des_crypt_LOCAL = _my_crypt; 148 if (svc_auth_reg(AUTH_DES, _svcauth_des) == -1) 149 errx(1, "failed to register AUTH_DES authenticator"); 150 151 if (optind != argc) { 152 usage(); 153 } 154 155 /* 156 * Initialize 157 */ 158 (void) umask(066); /* paranoia */ 159 if (geteuid() != 0) 160 errx(1, "keyserv must be run as root"); 161 setmodulus(HEXMODULUS); 162 getrootkey(&masterkey, nflag); 163 164 if (svc_create(keyprogram, KEY_PROG, KEY_VERS, 165 "netpath") == 0) { 166 (void) fprintf(stderr, 167 "%s: unable to create service\n", argv[0]); 168 exit(1); 169 } 170 171 if (svc_create(keyprogram, KEY_PROG, KEY_VERS2, 172 "netpath") == 0) { 173 (void) fprintf(stderr, 174 "%s: unable to create service\n", argv[0]); 175 exit(1); 176 } 177 178 if (!debugging) { 179 daemon(0,0); 180 } 181 182 svc_run(); 183 abort(); 184 /* NOTREACHED */ 185} 186 187/* 188 * In the event that we don't get a root password, we try to 189 * randomize the master key the best we can 190 */ 191static void 192randomize(master) 193 des_block *master; 194{ 195 int i; 196 int seed; 197 struct timeval tv; 198 int shift; 199 200 seed = 0; 201 for (i = 0; i < 1024; i++) { 202 (void) gettimeofday(&tv, (struct timezone *) NULL); 203 shift = i % 8 * sizeof (int); 204 seed ^= (tv.tv_usec << shift) | (tv.tv_usec >> (32 - shift)); 205 } 206#ifdef KEYSERV_RANDOM 207 srandom(seed); 208 master->key.low = random(); 209 master->key.high = random(); 210 srandom(seed); 211#else 212 /* use stupid dangerous bad rand() */ 213 srand(seed); 214 master->key.low = rand(); 215 master->key.high = rand(); 216 srand(seed); 217#endif 218} 219 220/* 221 * Try to get root's secret key, by prompting if terminal is a tty, else trying 222 * from standard input. 223 * Returns 1 on success. 224 */ 225static int 226getrootkey(master, prompt) 227 des_block *master; 228 int prompt; 229{ 230 char *passwd; 231 char name[MAXNETNAMELEN + 1]; 232 char secret[HEXKEYBYTES]; 233 key_netstarg netstore; 234 int fd; 235 236 if (!prompt) { 237 /* 238 * Read secret key out of ROOTKEY 239 */ 240 fd = open(ROOTKEY, O_RDONLY, 0); 241 if (fd < 0) { 242 randomize(master); 243 return (0); 244 } 245 if (read(fd, secret, HEXKEYBYTES) < HEXKEYBYTES) { 246 warnx("the key read from %s was too short", ROOTKEY); 247 (void) close(fd); 248 return (0); 249 } 250 (void) close(fd); 251 if (!getnetname(name)) { 252 warnx( 253 "failed to generate host's netname when establishing root's key"); 254 return (0); 255 } 256 memcpy(netstore.st_priv_key, secret, HEXKEYBYTES); 257 memset(netstore.st_pub_key, 0, HEXKEYBYTES); 258 netstore.st_netname = name; 259 if (pk_netput(0, &netstore) != KEY_SUCCESS) { 260 warnx("could not set root's key and netname"); 261 return (0); 262 } 263 return (1); 264 } 265 /* 266 * Decrypt yellow pages publickey entry to get secret key 267 */ 268 passwd = getpass("root password:"); 269 passwd2des(passwd, (char *)master); 270 getnetname(name); 271 if (!getsecretkey(name, secret, passwd)) { 272 warnx("can't find %s's secret key", name); 273 return (0); 274 } 275 if (secret[0] == 0) { 276 warnx("password does not decrypt secret key for %s", name); 277 return (0); 278 } 279 (void) pk_setkey(0, secret); 280 /* 281 * Store it for future use in $ROOTKEY, if possible 282 */ 283 fd = open(ROOTKEY, O_WRONLY|O_TRUNC|O_CREAT, 0); 284 if (fd > 0) { 285 char newline = '\n'; 286 287 write(fd, secret, strlen(secret)); 288 write(fd, &newline, sizeof (newline)); 289 close(fd); 290 } 291 return (1); 292} 293 294/* 295 * Procedures to implement RPC service 296 */ 297char * 298strstatus(status) 299 keystatus status; 300{ 301 switch (status) { 302 case KEY_SUCCESS: 303 return ("KEY_SUCCESS"); 304 case KEY_NOSECRET: 305 return ("KEY_NOSECRET"); 306 case KEY_UNKNOWN: 307 return ("KEY_UNKNOWN"); 308 case KEY_SYSTEMERR: 309 return ("KEY_SYSTEMERR"); 310 default: 311 return ("(bad result code)"); 312 } 313} 314 315keystatus * 316key_set_1_svc_prog(uid, key) 317 uid_t uid; 318 keybuf key; 319{ 320 static keystatus status; 321 322 if (debugging) { 323 (void) fprintf(stderr, "set(%ld, %.*s) = ", uid, 324 (int) sizeof (keybuf), key); 325 } 326 status = pk_setkey(uid, key); 327 if (debugging) { 328 (void) fprintf(stderr, "%s\n", strstatus(status)); 329 (void) fflush(stderr); 330 } 331 return (&status); 332} 333 334cryptkeyres * 335key_encrypt_pk_2_svc_prog(uid, arg) 336 uid_t uid; 337 cryptkeyarg2 *arg; 338{ 339 static cryptkeyres res; 340 341 if (debugging) { 342 (void) fprintf(stderr, "encrypt(%ld, %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 362cryptkeyres * 363key_decrypt_pk_2_svc_prog(uid, arg) 364 uid_t uid; 365 cryptkeyarg2 *arg; 366{ 367 static cryptkeyres res; 368 369 if (debugging) { 370 (void) fprintf(stderr, "decrypt(%ld, %s, %08x%08x) = ", uid, 371 arg->remotename, arg->deskey.key.high, 372 arg->deskey.key.low); 373 } 374 res.cryptkeyres_u.deskey = arg->deskey; 375 res.status = pk_decrypt(uid, arg->remotename, &(arg->remotekey), 376 &res.cryptkeyres_u.deskey); 377 if (debugging) { 378 if (res.status == KEY_SUCCESS) { 379 (void) fprintf(stderr, "%08x%08x\n", 380 res.cryptkeyres_u.deskey.key.high, 381 res.cryptkeyres_u.deskey.key.low); 382 } else { 383 (void) fprintf(stderr, "%s\n", strstatus(res.status)); 384 } 385 (void) fflush(stderr); 386 } 387 return (&res); 388} 389 390keystatus * 391key_net_put_2_svc_prog(uid, arg) 392 uid_t uid; 393 key_netstarg *arg; 394{ 395 static keystatus status; 396 397 if (debugging) { 398 (void) fprintf(stderr, "net_put(%s, %.*s, %.*s) = ", 399 arg->st_netname, (int)sizeof (arg->st_pub_key), 400 arg->st_pub_key, (int)sizeof (arg->st_priv_key), 401 arg->st_priv_key); 402 }; 403 404 status = pk_netput(uid, arg); 405 406 if (debugging) { 407 (void) fprintf(stderr, "%s\n", strstatus(status)); 408 (void) fflush(stderr); 409 } 410 411 return (&status); 412} 413 414key_netstres * 415key_net_get_2_svc_prog(uid, arg) 416 uid_t uid; 417 void *arg; 418{ 419 static key_netstres keynetname; 420 421 if (debugging) 422 (void) fprintf(stderr, "net_get(%ld) = ", uid); 423 424 keynetname.status = pk_netget(uid, &keynetname.key_netstres_u.knet); 425 if (debugging) { 426 if (keynetname.status == KEY_SUCCESS) { 427 fprintf(stderr, "<%s, %.*s, %.*s>\n", 428 keynetname.key_netstres_u.knet.st_netname, 429 (int)sizeof (keynetname.key_netstres_u.knet.st_pub_key), 430 keynetname.key_netstres_u.knet.st_pub_key, 431 (int)sizeof (keynetname.key_netstres_u.knet.st_priv_key), 432 keynetname.key_netstres_u.knet.st_priv_key); 433 } else { 434 (void) fprintf(stderr, "NOT FOUND\n"); 435 } 436 (void) fflush(stderr); 437 } 438 439 return (&keynetname); 440 441} 442 443cryptkeyres * 444key_get_conv_2_svc_prog(uid, arg) 445 uid_t uid; 446 keybuf arg; 447{ 448 static cryptkeyres res; 449 450 if (debugging) 451 (void) fprintf(stderr, "get_conv(%ld, %.*s) = ", uid, 452 (int)sizeof (arg), arg); 453 454 455 res.status = pk_get_conv_key(uid, arg, &res); 456 457 if (debugging) { 458 if (res.status == KEY_SUCCESS) { 459 (void) fprintf(stderr, "%08x%08x\n", 460 res.cryptkeyres_u.deskey.key.high, 461 res.cryptkeyres_u.deskey.key.low); 462 } else { 463 (void) fprintf(stderr, "%s\n", strstatus(res.status)); 464 } 465 (void) fflush(stderr); 466 } 467 return (&res); 468} 469 470 471cryptkeyres * 472key_encrypt_1_svc_prog(uid, arg) 473 uid_t uid; 474 cryptkeyarg *arg; 475{ 476 static cryptkeyres res; 477 478 if (debugging) { 479 (void) fprintf(stderr, "encrypt(%ld, %s, %08x%08x) = ", uid, 480 arg->remotename, arg->deskey.key.high, 481 arg->deskey.key.low); 482 } 483 res.cryptkeyres_u.deskey = arg->deskey; 484 res.status = pk_encrypt(uid, arg->remotename, NULL, 485 &res.cryptkeyres_u.deskey); 486 if (debugging) { 487 if (res.status == KEY_SUCCESS) { 488 (void) fprintf(stderr, "%08x%08x\n", 489 res.cryptkeyres_u.deskey.key.high, 490 res.cryptkeyres_u.deskey.key.low); 491 } else { 492 (void) fprintf(stderr, "%s\n", strstatus(res.status)); 493 } 494 (void) fflush(stderr); 495 } 496 return (&res); 497} 498 499cryptkeyres * 500key_decrypt_1_svc_prog(uid, arg) 501 uid_t uid; 502 cryptkeyarg *arg; 503{ 504 static cryptkeyres res; 505 506 if (debugging) { 507 (void) fprintf(stderr, "decrypt(%ld, %s, %08x%08x) = ", uid, 508 arg->remotename, arg->deskey.key.high, 509 arg->deskey.key.low); 510 } 511 res.cryptkeyres_u.deskey = arg->deskey; 512 res.status = pk_decrypt(uid, arg->remotename, NULL, 513 &res.cryptkeyres_u.deskey); 514 if (debugging) { 515 if (res.status == KEY_SUCCESS) { 516 (void) fprintf(stderr, "%08x%08x\n", 517 res.cryptkeyres_u.deskey.key.high, 518 res.cryptkeyres_u.deskey.key.low); 519 } else { 520 (void) fprintf(stderr, "%s\n", strstatus(res.status)); 521 } 522 (void) fflush(stderr); 523 } 524 return (&res); 525} 526 527/* ARGSUSED */ 528des_block * 529key_gen_1_svc_prog(v, s) 530 void *v; 531 struct svc_req *s; 532{ 533 struct timeval time; 534 static des_block keygen; 535 static des_block key; 536 537 (void) gettimeofday(&time, (struct timezone *) NULL); 538 keygen.key.high += (time.tv_sec ^ time.tv_usec); 539 keygen.key.low += (time.tv_sec ^ time.tv_usec); 540 ecb_crypt((char *)&masterkey, (char *)&keygen, sizeof (keygen), 541 DES_ENCRYPT | DES_HW); 542 key = keygen; 543 des_setparity((char *)&key); 544 if (debugging) { 545 (void) fprintf(stderr, "gen() = %08x%08x\n", key.key.high, 546 key.key.low); 547 (void) fflush(stderr); 548 } 549 return (&key); 550} 551 552getcredres * 553key_getcred_1_svc_prog(uid, name) 554 uid_t uid; 555 netnamestr *name; 556{ 557 static getcredres res; 558 static u_int gids[NGROUPS]; 559 struct unixcred *cred; 560 561 cred = &res.getcredres_u.cred; 562 cred->gids.gids_val = gids; 563 if (!netname2user(*name, (uid_t *) &cred->uid, (gid_t *) &cred->gid, 564 (int *)&cred->gids.gids_len, (gid_t *)gids)) { 565 res.status = KEY_UNKNOWN; 566 } else { 567 res.status = KEY_SUCCESS; 568 } 569 if (debugging) { 570 (void) fprintf(stderr, "getcred(%s) = ", *name); 571 if (res.status == KEY_SUCCESS) { 572 (void) fprintf(stderr, "uid=%d, gid=%d, grouplen=%d\n", 573 cred->uid, cred->gid, cred->gids.gids_len); 574 } else { 575 (void) fprintf(stderr, "%s\n", strstatus(res.status)); 576 } 577 (void) fflush(stderr); 578 } 579 return (&res); 580} 581 582/* 583 * RPC boilerplate 584 */ 585static void 586keyprogram(rqstp, transp) 587 struct svc_req *rqstp; 588 SVCXPRT *transp; 589{ 590 union { 591 keybuf key_set_1_arg; 592 cryptkeyarg key_encrypt_1_arg; 593 cryptkeyarg key_decrypt_1_arg; 594 netnamestr key_getcred_1_arg; 595 cryptkeyarg key_encrypt_2_arg; 596 cryptkeyarg key_decrypt_2_arg; 597 netnamestr key_getcred_2_arg; 598 cryptkeyarg2 key_encrypt_pk_2_arg; 599 cryptkeyarg2 key_decrypt_pk_2_arg; 600 key_netstarg key_net_put_2_arg; 601 netobj key_get_conv_2_arg; 602 } argument; 603 char *result; 604 bool_t(*xdr_argument)(), (*xdr_result)(); 605 char *(*local) (); 606 uid_t uid = -1; 607 int check_auth; 608 609 switch (rqstp->rq_proc) { 610 case NULLPROC: 611 svc_sendreply(transp, xdr_void, (char *)NULL); 612 return; 613 614 case KEY_SET: 615 xdr_argument = xdr_keybuf; 616 xdr_result = xdr_int; 617 local = (char *(*)()) key_set_1_svc_prog; 618 check_auth = 1; 619 break; 620 621 case KEY_ENCRYPT: 622 xdr_argument = xdr_cryptkeyarg; 623 xdr_result = xdr_cryptkeyres; 624 local = (char *(*)()) key_encrypt_1_svc_prog; 625 check_auth = 1; 626 break; 627 628 case KEY_DECRYPT: 629 xdr_argument = xdr_cryptkeyarg; 630 xdr_result = xdr_cryptkeyres; 631 local = (char *(*)()) key_decrypt_1_svc_prog; 632 check_auth = 1; 633 break; 634 635 case KEY_GEN: 636 xdr_argument = xdr_void; 637 xdr_result = xdr_des_block; 638 local = (char *(*)()) key_gen_1_svc_prog; 639 check_auth = 0; 640 break; 641 642 case KEY_GETCRED: 643 xdr_argument = xdr_netnamestr; 644 xdr_result = xdr_getcredres; 645 local = (char *(*)()) key_getcred_1_svc_prog; 646 check_auth = 0; 647 break; 648 649 case KEY_ENCRYPT_PK: 650 xdr_argument = xdr_cryptkeyarg2; 651 xdr_result = xdr_cryptkeyres; 652 local = (char *(*)()) key_encrypt_pk_2_svc_prog; 653 check_auth = 1; 654 break; 655 656 case KEY_DECRYPT_PK: 657 xdr_argument = xdr_cryptkeyarg2; 658 xdr_result = xdr_cryptkeyres; 659 local = (char *(*)()) key_decrypt_pk_2_svc_prog; 660 check_auth = 1; 661 break; 662 663 664 case KEY_NET_PUT: 665 xdr_argument = xdr_key_netstarg; 666 xdr_result = xdr_keystatus; 667 local = (char *(*)()) key_net_put_2_svc_prog; 668 check_auth = 1; 669 break; 670 671 case KEY_NET_GET: 672 xdr_argument = (xdrproc_t) xdr_void; 673 xdr_result = xdr_key_netstres; 674 local = (char *(*)()) key_net_get_2_svc_prog; 675 check_auth = 1; 676 break; 677 678 case KEY_GET_CONV: 679 xdr_argument = (xdrproc_t) xdr_keybuf; 680 xdr_result = xdr_cryptkeyres; 681 local = (char *(*)()) key_get_conv_2_svc_prog; 682 check_auth = 1; 683 break; 684 685 default: 686 svcerr_noproc(transp); 687 return; 688 } 689 if (check_auth) { 690 if (root_auth(transp, rqstp) == 0) { 691 if (debugging) { 692 (void) fprintf(stderr, 693 "not local privileged process\n"); 694 } 695 svcerr_weakauth(transp); 696 return; 697 } 698 if (rqstp->rq_cred.oa_flavor != AUTH_SYS) { 699 if (debugging) { 700 (void) fprintf(stderr, 701 "not unix authentication\n"); 702 } 703 svcerr_weakauth(transp); 704 return; 705 } 706 uid = ((struct authsys_parms *)rqstp->rq_clntcred)->aup_uid; 707 } 708 709 memset((char *) &argument, 0, sizeof (argument)); 710 if (!svc_getargs(transp, xdr_argument, (caddr_t)&argument)) { 711 svcerr_decode(transp); 712 return; 713 } 714 result = (*local) (uid, &argument); 715 if (!svc_sendreply(transp, xdr_result, (char *) result)) { 716 if (debugging) 717 (void) fprintf(stderr, "unable to reply\n"); 718 svcerr_systemerr(transp); 719 } 720 if (!svc_freeargs(transp, xdr_argument, (caddr_t)&argument)) { 721 if (debugging) 722 (void) fprintf(stderr, 723 "unable to free arguments\n"); 724 exit(1); 725 } 726 return; 727} 728 729static int 730root_auth(trans, rqstp) 731 SVCXPRT *trans; 732 struct svc_req *rqstp; 733{ 734 uid_t uid; 735 struct sockaddr_in *remote; 736 737 remote = svc_getcaller(trans); 738 if (remote->sin_family == AF_INET) { 739 if (debugging) 740 fprintf(stderr, "client didn't use AF_UNIX\n"); 741 return (0); 742 } 743 744 if (__rpc_get_local_uid(trans, &uid) < 0) { 745 if (debugging) 746 fprintf(stderr, "__rpc_get_local_uid failed\n"); 747 return (0); 748 } 749 750 if (debugging) 751 fprintf(stderr, "local_uid %ld\n", uid); 752 if (uid == 0) 753 return (1); 754 if (rqstp->rq_cred.oa_flavor == AUTH_SYS) { 755 if (((uid_t) ((struct authunix_parms *) 756 rqstp->rq_clntcred)->aup_uid) 757 == uid) { 758 return (1); 759 } else { 760 if (debugging) 761 fprintf(stderr, 762 "local_uid %ld mismatches auth %ld\n", uid, 763((uid_t) ((struct authunix_parms *)rqstp->rq_clntcred)->aup_uid)); 764 return (0); 765 } 766 } else { 767 if (debugging) 768 fprintf(stderr, "Not auth sys\n"); 769 return (0); 770 } 771} 772 773static void 774usage() 775{ 776 (void) fprintf(stderr, 777 "usage: keyserv [-n] [-D] [-d] [-v] [-p path]\n"); 778 (void) fprintf(stderr, "-d disables the use of default keys\n"); 779 exit(1); 780} 781