1 /* 2 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 | #pragma ident "@(#)ovsec_kadmd.c 1.9 04/09/08 SMI" 6 | #pragma ident "@(#)ovsec_kadmd.c 1.8 04/05/24 SMI" 7 8 /* 9 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 10 * 11 * Openvision retains the copyright to derivative works of 12 * this source code. Do *NOT* create a derivative of this 13 * source code before consulting with your legal department. 14 * Do *NOT* integrate *ANY* of this source code into another 15 * product before consulting with your legal department. 16 * 17 * For further information, read the top-level Openvision 18 * copyright which is contained in the top-level MIT Kerberos 19 * copyright. 20 * 21 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 22 * 23 */ 24 25 26 /* 27 * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved 28 */ 29 30 /* 31 * SUNWresync121 XXX 32 * Beware future resyncers, this file is much diff from MIT (1.0...) 33 */ 34 35 #include <stdio.h> 36 #include <signal.h> 37 #include <syslog.h> 38 #include <sys/types.h> 39 #include <sys/time.h> 40 #include <sys/socket.h> 41 #include <unistd.h> 42 #include <netinet/in.h> 43 #include <arpa/inet.h> /* inet_ntoa */ 44 #include <netdb.h> 45 #include <gssapi/gssapi.h> 46 #include <rpc/rpc.h> 47 #include <kadm5/admin.h> 48 #include <kadm5/kadm_rpc.h> 49 #include <kadm5/server_internal.h> 50 #include <server_acl.h> 51 #include <krb5/adm_proto.h> 52 #include <string.h> 53 #include <gssapi_krb5.h> 54 #include <libintl.h> 55 #include <locale.h> 56 #include <sys/resource.h> 57 + #include <kdb/kdb_log.h> 58 59 + #include <rpc/rpcsec_gss.h> 60 + 61 #ifndef FD_SETSIZE 62 #define FD_SETSIZE 256 63 #endif 64 65 #ifndef MAX 66 #define MAX(a, b) (((a) > (b)) ? (a) : (b)) 67 #endif 68 69 static int signal_request_exit = 0; 70 static int schpw; 71 kadm5_config_params chgpw_params; 72 void kadm_svc_run(void); 70 | void setup_signal_handlers(); 73 | void setup_signal_handlers(iprop_role iproprole); 74 void sig_exit(int); 75 void sig_pipe(int); 76 77 #ifdef POSIX_SIGNALS 78 static struct sigaction s_action; 79 #endif /* POSIX_SIGNALS */ 80 81 #define TIMEOUT 15 82 83 typedef struct _auth_gssapi_name { 84 char *name; 85 gss_OID type; 86 } auth_gssapi_name; 87 88 gss_name_t gss_changepw_name = NULL, gss_oldchangepw_name = NULL; 89 void *global_server_handle; 90 91 /* 92 * This is a kludge, but the server needs these constants to be 93 * compatible with old clients. They are defined in <kadm5/admin.h>, 94 * but only if USE_KADM5_API_VERSION == 1. 95 */ 96 #define OVSEC_KADM_ADMIN_SERVICE_P "ovsec_adm@admin" 97 #define OVSEC_KADM_CHANGEPW_SERVICE_P "ovsec_adm@changepw" 98 99 /* 100 * This enables us to set the keytab that gss_acquire_cred uses, but 101 * it also restricts us to linking against the Kv5 GSS-API library. 102 * Since this is *k*admind, that shouldn't be a problem. 103 */ 104 extern char *krb5_overridekeyname; 105 106 + extern void krb5_iprop_prog_1(); 107 + extern kadm5_ret_t kiprop_get_adm_host_srv_name( 108 + krb5_context, 109 + const char *, 110 + char **); 111 112 /* 113 * Function: usage 114 * 115 * Purpose: print out the server usage message 116 * 117 * Arguments: 118 * Requires: 119 * Effects: 120 * Modifies: 121 */ 122 123 void 124 usage() 125 { 126 fprintf(stderr, gettext("Usage: kadmind [-r realm] [-m] [-d] " 127 "[-p port-number]\n")); 128 exit(1); 129 } ----Unchanged portion omitted---- 181 182 static krb5_context context; /* XXX yuck. the signal handlers need this */ 183 184 in_port_t l_port = 0; /* global local port num, for BSM audits */ 185 186 + int nofork = 0; /* global; don't fork (debug mode) */ 187 + 188 int 189 main(int argc, char *argv[]) 190 { 191 void kadm_1(struct svc_req *, SVCXPRT *); 192 SVCXPRT *transp; 193 extern char *optarg; 194 extern int optind, opterr; 185 | int ret, rlen, nofork, oldnames = 0; 195 | int ret, rlen, oldnames = 0; 196 OM_uint32 OMret, major_status, minor_status; 197 char *whoami; 198 FILE *acl_file; 199 gss_buffer_desc in_buf; 200 struct servent *srv; 201 struct sockaddr_in addr; 202 struct sockaddr_in *sin; 203 int s; 204 int optchar; 205 struct netconfig *nconf; 206 void *handlep; 207 int fd; 208 struct t_info tinfo; 209 struct t_bind tbindstr, *tres; 210 211 struct t_optmgmt req, resp; 212 struct opthdr *opt; 213 char reqbuf[128]; 214 int *ip; 215 struct rlimit rl; 216 217 + char *kiprop_name = NULL; /* IProp svc name */ 218 + kdb_log_context *log_ctx; 219 kadm5_server_handle_t handle; 220 krb5_context ctx; 221 + 222 kadm5_config_params params; 223 auth_gssapi_name names[6]; 224 gss_buffer_desc gssbuf; 225 gss_OID nt_krb5_name_oid; 226 227 int allowed; 228 229 /* This is OID value the Krb5_Name NameType */ 230 gssbuf.value = "{1 2 840 113554 1 2 2 1}"; 231 gssbuf.length = strlen(gssbuf.value); 232 major_status = gss_str_to_oid(&minor_status, &gssbuf, 233 &nt_krb5_name_oid); 234 if (major_status != GSS_S_COMPLETE) { 235 fprintf(stderr, 236 gettext("Couldn't create KRB5 Name NameType OID\n")); 237 display_status("str_to_oid", major_status, minor_status); 238 exit(1); 239 } 240 241 names[0].name = names[1].name = names[2].name = 242 names[3].name = names[4].name = names[5].name =NULL; 243 names[0].type = names[1].type = names[2].type = 244 names[3].type = names[4].type = names[5].type = 245 (gss_OID) nt_krb5_name_oid; 246 247 whoami = (strrchr(argv[0], '/') ? strrchr(argv[0], '/') + 1 : argv[0]); 248 249 (void) setlocale(LC_ALL, ""); 250 251 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 252 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ 253 #endif 254 255 (void) textdomain(TEXT_DOMAIN); 256 257 nofork = 0; 258 259 memset((char *) ¶ms, 0, sizeof (params)); 260 261 while ((optchar = getopt(argc, argv, "r:mdp:")) != EOF) { 262 switch (optchar) { 263 case 'r': 264 if (!optarg) 265 usage(); 266 params.realm = optarg; 267 params.mask |= KADM5_CONFIG_REALM; 268 break; 269 case 'm': 270 params.mkey_from_kbd = 1; 271 params.mask |= KADM5_CONFIG_MKEY_FROM_KBD; 272 break; 273 case 'd': 274 nofork = 1; 275 break; 276 case 'p': 277 if (!optarg) 278 usage(); 279 params.kadmind_port = atoi(optarg); 280 params.mask |= KADM5_CONFIG_KADMIND_PORT; 281 break; 282 case '?': 283 default: 284 usage(); 285 } 286 } 287 288 289 if (getrlimit(RLIMIT_NOFILE, &rl) == 0) { 290 rl.rlim_cur = rl.rlim_max = MAX(rl.rlim_max, FD_SETSIZE); 291 setrlimit(RLIMIT_NOFILE, &rl); 292 } 293 294 if (!nofork && (ret = daemon(0, 0))) { 295 ret = errno; 296 krb5_klog_syslog(LOG_ERR, 297 gettext("Cannot detach from tty: %s"), 298 error_message(ret)); 299 fprintf(stderr, gettext("%s: Cannot detach from tty: %s\n"), 300 whoami, error_message(ret)); 301 krb5_klog_close(context); 302 exit(1); 303 } 304 305 if (ret = krb5_init_context(&context)) { 306 fprintf(stderr, 307 gettext("%s: %s while initializing context, aborting\n"), 308 whoami, error_message(ret)); 309 exit(1); 310 } 311 312 krb5_klog_init(context, "admin_server", whoami, 1); 313 314 315 /* 316 * When using the Horowitz/IETF protocol for 317 * password changing, the default port is 464 318 * (officially recognized by IANA) 319 * 320 * DEFAULT_KPASSWD_PORT -> 464 321 */ 322 chgpw_params.kpasswd_port = DEFAULT_KPASSWD_PORT; 323 chgpw_params.mask |= KADM5_CONFIG_KPASSWD_PORT; 324 chgpw_params.kpasswd_protocol = KRB5_CHGPWD_CHANGEPW_V2; 325 chgpw_params.mask |= KADM5_CONFIG_KPASSWD_PROTOCOL; 326 327 if (ret = kadm5_get_config_params(context, NULL, NULL, &chgpw_params, 328 &chgpw_params)) { 329 krb5_klog_syslog(LOG_ERR, gettext("%s: %s while initializing," 330 " aborting"), whoami, error_message(ret)); 331 fprintf(stderr, 332 gettext("%s: %s while initializing, aborting\n"), 333 whoami, error_message(ret)); 334 krb5_klog_close(context); 335 exit(1); 336 } 337 338 /* 339 * We now setup the socket and bind() to port 464, so that 340 * kadmind can now listen to and process change-pwd requests 341 * from non-Solaris Kerberos V5 clients such as Microsoft, 342 * MIT, AIX, HP etc 343 */ 344 if ((schpw = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 345 krb5_klog_syslog(LOG_ERR, gettext( "cannot create simple " 346 "chpw socket: %s"), error_message(errno)); 347 fprintf(stderr, gettext("Cannot create simple chpw " 348 "socket: %s"), error_message(errno)); 349 krb5_klog_close(context); 350 exit(1); 351 } 352 353 /* 354 * Don't allow socket re-use. This should prevent multiple 355 * daemons from starting at the same time. 356 */ 357 allowed = 0; 358 if (setsockopt(schpw, SOL_SOCKET, SO_REUSEADDR, 359 (char *) &allowed, sizeof(allowed)) < 0) { 360 krb5_klog_syslog(LOG_ERR, gettext("cannot set SO_REUSEADDR " 361 "on simple chpw socket: %s"), 362 error_message(errno)); 363 fprintf(stderr, gettext("Cannot set SO_REUSEADDR on " 364 "simple chpw socket: %s"), error_message(errno)); 365 } 366 367 memset(&addr, 0, sizeof(addr)); 368 addr.sin_family = AF_INET; 369 addr.sin_addr.s_addr = INADDR_ANY; 370 addr.sin_port = htons(chgpw_params.kpasswd_port); 371 372 if (bind(schpw, (struct sockaddr *)&addr, sizeof(addr)) < 0) { 373 char portbuf[32]; 374 int oerrno = errno; 375 fprintf(stderr, gettext("%s: Cannot bind socket.\n"), whoami); 376 fprintf(stderr, gettext("bind: %s\n"), error_message(oerrno)); 377 errno = oerrno; 378 (void) snprintf(portbuf, sizeof (portbuf), "%d", 379 ntohs(addr.sin_port)); 380 krb5_klog_syslog(LOG_ERR, gettext("cannot bind simple " 381 "chpw socket: %s"), error_message(oerrno)); 382 if(oerrno == EADDRINUSE) { 383 char *w = strrchr(whoami, '/'); 384 if (w) { 385 w++; 386 } 387 else { 388 w = whoami; 389 } 390 fprintf(stderr, gettext( 391 "This probably means that another %s process\n" 392 "is already running, or that another program\n" 393 "is using the server port (number %d).\n" 394 "If another %s is already running, you should\n" 395 "kill it before restarting the server.\n"), 396 w, ntohs(addr.sin_port), w); 397 } 398 krb5_klog_close(context); 399 exit(1); 400 } 401 402 if (ret = kadm5_get_config_params(context, NULL, NULL, ¶ms, 403 ¶ms)) { 404 krb5_klog_syslog(LOG_ERR, gettext("%s: %s while initializing," 405 " aborting"), whoami, error_message(ret)); 406 fprintf(stderr, 407 gettext("%s: %s while initializing, aborting\n"), 408 whoami, error_message(ret)); 409 krb5_klog_close(context); 410 exit(1); 411 } 412 #define REQUIRED_PARAMS (KADM5_CONFIG_REALM | KADM5_CONFIG_ACL_FILE | \ 413 KADM5_CONFIG_ADMIN_KEYTAB) 414 415 if ((params.mask & REQUIRED_PARAMS) != REQUIRED_PARAMS) { 416 krb5_klog_syslog(LOG_ERR, 417 gettext("%s: Missing required configuration values " 418 "while initializing, aborting"), whoami, 419 (params.mask & REQUIRED_PARAMS) ^ REQUIRED_PARAMS); 420 fprintf(stderr, 421 gettext("%s: Missing required configuration values " 422 "(%x) while initializing, aborting\n"), whoami, 423 (params.mask & REQUIRED_PARAMS) ^ REQUIRED_PARAMS); 424 krb5_klog_close(context); 425 exit(1); 426 } 427 memset((char *) &addr, 0, sizeof (struct sockaddr_in)); 428 addr.sin_family = AF_INET; 429 addr.sin_addr.s_addr = INADDR_ANY; 430 l_port = addr.sin_port = htons(params.kadmind_port); 431 sin = &addr; 432 433 if ((handlep = setnetconfig()) == (void *) NULL) { 434 (void) krb5_klog_syslog(LOG_ERR, 435 gettext("cannot get any transport information")); 436 krb5_klog_close(context); 437 exit(1); 438 } 439 while (nconf = getnetconfig(handlep)) { 440 if ((nconf->nc_semantics == NC_TPI_COTS_ORD) && 441 (strcmp(nconf->nc_protofmly, NC_INET) == 0) && 442 (strcmp(nconf->nc_proto, NC_TCP) == 0)) 443 break; 444 } 445 446 if (nconf == (struct netconfig *) NULL) { 447 (void) endnetconfig(handlep); 448 krb5_klog_close(context); 449 exit(1); 450 } 451 fd = t_open(nconf->nc_device, O_RDWR, &tinfo); 452 if (fd == -1) { 453 krb5_klog_syslog(LOG_ERR, 454 gettext("unable to open connection for ADMIN server")); 455 krb5_klog_close(context); 456 exit(1); 457 } 458 /* LINTED */ 459 opt = (struct opthdr *) reqbuf; 460 opt->level = SOL_SOCKET; 461 opt->name = SO_REUSEADDR; 462 opt->len = sizeof (int); 463 464 /* LINTED */ 465 ip = (int *) &reqbuf[sizeof (struct opthdr)]; 466 467 /* 468 * The option value is "0". This is supposed to 469 * Prevent socket reuse and thus prevent multiple 470 * daemons from running on the same port. 471 */ 472 *ip = 0; 473 474 req.flags = T_NEGOTIATE; 475 req.opt.len = sizeof (struct opthdr) + opt->len; 476 req.opt.buf = (char *) opt; 477 478 resp.flags = 0; 479 resp.opt.buf = reqbuf; 480 resp.opt.maxlen = sizeof (reqbuf); 481 482 if (t_optmgmt(fd, &req, &resp) < 0 || resp.flags != T_SUCCESS) { 483 t_error("t_optmgmt"); 484 exit(1); 485 } 486 /* Transform addr to netbuf */ 487 488 tres = (struct t_bind *) t_alloc(fd, T_BIND, T_ADDR); 489 if (tres == NULL) { 490 (void) t_close(fd); 491 (void) krb5_klog_syslog(LOG_ERR, 492 gettext("cannot allocate netbuf")); 493 krb5_klog_close(context); 494 exit(1); 495 } 496 tbindstr.qlen = 8; 497 tbindstr.addr.buf = (char *) sin; 498 tbindstr.addr.len = tbindstr.addr.maxlen = __rpc_get_a_size(tinfo.addr); 499 sin = (struct sockaddr_in *) tbindstr.addr.buf; 500 /* SUNWresync121 XXX (void) memset(&addr, 0, sizeof(addr)); */ 501 502 if (t_bind(fd, &tbindstr, tres) < 0) { 503 int oerrno = errno; 504 fprintf(stderr, gettext("%s: Cannot bind socket.\n"), whoami); 505 fprintf(stderr, gettext("bind: %s\n"), error_message(oerrno)); 506 errno = oerrno; 507 krb5_klog_syslog(LOG_ERR, gettext("Cannot bind socket: %s"), 508 error_message(errno)); 509 if (oerrno == EADDRINUSE) { 510 char *w = strrchr(whoami, '/'); 511 512 if (w) { 513 w++; 514 } else { 515 w = whoami; 516 } 517 fprintf(stderr, gettext( 518 "This probably means that another %s " 519 "process is already\n" 520 "running, or that another program is using " 521 "the server port (number %d)\n" 522 "after being assigned it by the RPC " 523 "portmap deamon. If another\n" 524 "%s is already running, you should kill " 525 "it before\n" 526 "restarting the server. If, on the other hand, " 527 "another program is\n" 528 "using the server port, you should kill it " 529 "before running\n" 530 "%s, and ensure that the conflict does " 531 "not occur in the\n" 532 "future by making sure that %s is started " 533 "on reboot\n" 534 "before portmap.\n"), 535 w, ntohs(addr.sin_port), w, w, w); 536 krb5_klog_syslog(LOG_ERR, 537 gettext("Check for already-running %s or for " 538 "another process using port %d"), w, 539 htons(addr.sin_port)); 540 } 541 krb5_klog_close(context); 542 exit(1); 543 } 544 transp = svc_tli_create(fd, nconf, NULL, 0, 0); 545 (void) t_free((char *) tres, T_BIND); 546 if (transp == NULL) { 547 fprintf(stderr, gettext("%s: Cannot create RPC service.\n"), 548 whoami); 549 krb5_klog_syslog(LOG_ERR, gettext("Cannot create RPC service: %m")); 550 krb5_klog_close(context); 551 exit(1); 552 } 553 if (!svc_register(transp, KADM, KADMVERS, kadm_1, 0)) { 554 fprintf(stderr, 555 gettext("%s: Cannot register RPC service.\n"), whoami); 556 krb5_klog_syslog(LOG_ERR, 557 gettext("Cannot register RPC service, failing.")); 558 krb5_klog_close(context); 559 exit(1); 560 } 561 562 + /* 563 + * XXX krb5_defkeyname is an internal library global and should go 564 + * away 565 + */ 566 + krb5_overridekeyname = params.admin_keytab; 567 + 568 (void) kadm5_get_adm_host_srv_name(context, 569 params.realm, &names[0].name); 570 (void) kadm5_get_cpw_host_srv_name(context, 571 params.realm, &names[1].name); 572 names[2].name = KADM5_ADMIN_SERVICE_P; 573 names[3].name = KADM5_CHANGEPW_SERVICE_P; 574 names[4].name = OVSEC_KADM_ADMIN_SERVICE_P; 575 names[5].name = OVSEC_KADM_CHANGEPW_SERVICE_P; 576 577 if (names[0].name == NULL || names[1].name == NULL || 578 names[2].name == NULL || names[3].name == NULL || 579 names[4].name == NULL || names[5].name == NULL) { 580 krb5_klog_syslog(LOG_ERR, 581 gettext("Cannot initialize GSS-API authentication, " 582 "failing.")); 583 fprintf(stderr, 584 gettext("%s: Cannot initialize " 585 "GSS-API authentication.\n"), 586 whoami); 587 krb5_klog_close(context); 588 exit(1); 571 - /* 572 - * XXX krb5_defkeyname is an internal library global and should go 573 - * away 574 - */ 575 - krb5_overridekeyname = params.admin_keytab; 589 } 590 591 /* 592 * Try to acquire creds for the old OV services as well as the new 593 * names, but if that fails just fall back on the new names. 594 */ 595 596 if (rpc_gss_set_svc_name(names[5].name, 597 "kerberos_v5", 0, KADM, KADMVERS) && 598 rpc_gss_set_svc_name(names[4].name, 599 "kerberos_v5", 0, KADM, KADMVERS)) 600 oldnames++; 601 if (rpc_gss_set_svc_name(names[3].name, 602 "kerberos_v5", 0, KADM, KADMVERS)) 603 oldnames++; 604 if (rpc_gss_set_svc_name(names[2].name, 605 "kerberos_v5", 0, KADM, KADMVERS)) 606 oldnames++; 607 if (rpc_gss_set_svc_name(names[0].name, 608 "kerberos_v5", 0, KADM, KADMVERS)) 609 oldnames++; 610 if (rpc_gss_set_svc_name(names[1].name, 611 "kerberos_v5", 0, KADM, KADMVERS)) 612 oldnames++; 613 if (!oldnames) { 614 krb5_klog_syslog(LOG_ERR, 615 gettext("Cannot initialize GSS-API authentication, " 616 "failing.")); 617 fprintf(stderr, 618 gettext("%s:Cannot initialize GSS-API authentication.\n"), 619 whoami); 620 krb5_klog_close(context); 621 exit(1); 622 } 623 624 /* if set_names succeeded, this will too */ 625 in_buf.value = names[1].name; 626 in_buf.length = strlen(names[1].name) + 1; 627 (void) gss_import_name(&OMret, &in_buf, (gss_OID) nt_krb5_name_oid, 628 &gss_changepw_name); 629 if (oldnames) { 630 in_buf.value = names[3].name; 631 in_buf.length = strlen(names[3].name) + 1; 632 (void) gss_import_name(&OMret, &in_buf, 633 (gss_OID) nt_krb5_name_oid, 634 &gss_oldchangepw_name); 635 } 636 if (ret = acl_init(context, 0, params.acl_file)) { 637 krb5_klog_syslog(LOG_ERR, gettext("Cannot initialize acl file: %s"), 638 error_message(ret)); 639 fprintf(stderr, gettext("%s: Cannot initialize acl file: %s\n"), 640 whoami, error_message(ret)); 641 krb5_klog_close(context); 642 exit(1); 643 } 644 if ((ret = kadm5_init("kadmind", NULL, 645 NULL, ¶ms, 646 KADM5_STRUCT_VERSION, 647 KADM5_API_VERSION_2, 648 &global_server_handle)) != KADM5_OK) { 649 krb5_klog_syslog(LOG_ERR, 650 gettext("%s while initializing, aborting"), 651 error_message(ret)); 652 fprintf(stderr, 653 gettext("%s: %s while initializing, aborting\n"), 654 whoami, error_message(ret)); 655 krb5_klog_close(context); 656 exit(1); 657 } 658 659 handle = global_server_handle; 660 ctx = handle->context; 661 + if (params.iprop_enabled == TRUE) 662 + ulog_set_role(ctx, IPROP_MASTER); 663 + else 664 + ulog_set_role(ctx, IPROP_NULL); 665 666 + log_ctx = ctx->kdblog_context; 667 + 668 + if (log_ctx && (log_ctx->iproprole == IPROP_MASTER)) { 669 + /* 670 + * IProp is enabled, so let's map in the update log 671 + * and setup the service. 672 + */ 673 + if (ret = ulog_map(ctx, ¶ms, FKADMIND)) { 674 + fprintf(stderr, 675 + gettext("%s: %s while mapping update log " 676 + "(`%s.ulog')\n"), whoami, error_message(ret), 677 + params.dbname); 678 + krb5_klog_syslog(LOG_ERR, 679 + gettext("%s while mapping update log " 680 + "(`%s.ulog')"), error_message(ret), 681 + params.dbname); 682 + krb5_klog_close(ctx); 683 + exit(1); 684 + } 685 + 686 + 687 + if (nofork) 688 + fprintf(stderr, 689 + "%s: create IPROP svc (PROG=%d, VERS=%d)\n", 690 + whoami, KRB5_IPROP_PROG, KRB5_IPROP_VERS); 691 + 692 + if (!svc_create(krb5_iprop_prog_1, 693 + KRB5_IPROP_PROG, KRB5_IPROP_VERS, 694 + "circuit_v")) { 695 + fprintf(stderr, 696 + gettext("%s: Cannot create IProp RPC service (PROG=%d, VERS=%d)\n"), 697 + whoami, 698 + KRB5_IPROP_PROG, KRB5_IPROP_VERS); 699 + krb5_klog_syslog(LOG_ERR, 700 + gettext("Cannot create IProp RPC service (PROG=%d, VERS=%d), failing."), 701 + KRB5_IPROP_PROG, KRB5_IPROP_VERS); 702 + krb5_klog_close(ctx); 703 + exit(1); 704 + } 705 + 706 + if (ret = kiprop_get_adm_host_srv_name(ctx, 707 + params.realm, 708 + &kiprop_name)) { 709 + krb5_klog_syslog(LOG_ERR, 710 + gettext("%s while getting IProp svc name, failing"), 711 + error_message(ret)); 712 + fprintf(stderr, 713 + gettext("%s: %s while getting IProp svc name, failing\n"), 714 + whoami, error_message(ret)); 715 + krb5_klog_close(ctx); 716 + exit(1); 717 + } 718 + 719 + if (!rpc_gss_set_svc_name(kiprop_name, "kerberos_v5", 0, 720 + KRB5_IPROP_PROG, KRB5_IPROP_VERS)) { 721 + rpc_gss_error_t err; 722 + (void) rpc_gss_get_error(&err); 723 + 724 + krb5_klog_syslog(LOG_ERR, 725 + gettext("Unable to set RPCSEC_GSS service name (`%s'), failing."), 726 + kiprop_name ? kiprop_name : "<null>"); 727 + 728 + fprintf(stderr, 729 + gettext("%s: Unable to set RPCSEC_GSS service name (`%s'), failing.\n"), 730 + whoami, 731 + kiprop_name ? kiprop_name : "<null>"); 732 + 733 + if (nofork) { 734 + fprintf(stderr, 735 + "%s: set svc name (rpcsec err=%d, sys err=%d)\n", 736 + whoami, 737 + err.rpc_gss_error, 738 + err.system_error); 739 + } 740 + 741 + exit(1); 742 + } 743 + free(kiprop_name); 744 + } 745 + 746 + setup_signal_handlers(log_ctx->iproprole); 747 krb5_klog_syslog(LOG_INFO, gettext("starting")); 748 + if (nofork) 749 + fprintf(stderr, "%s: starting...\n", whoami); 750 751 + 752 /* 753 * We now call our own customized async event processing 754 * function kadm_svc_run(), as opposed to svc_run() earlier, 755 * since this enables kadmind to also listen-to/process 756 * non-RPCSEC_GSS based change-pwd requests apart from the 757 * regular, RPCSEC_GSS kpasswd requests from Solaris Krb5 clients. 758 */ 759 kadm_svc_run(); 760 761 krb5_klog_syslog(LOG_INFO, gettext("finished, exiting")); 762 kadm5_destroy(global_server_handle); 763 t_close(fd); 764 krb5_klog_close(context); 765 exit(0); 766 } ----Unchanged portion omitted---- 837 838 839 /* 840 * Function: setup_signal_handlers 841 * 842 * Purpose: Setup signal handling functions with System V's signal(). 843 */ 742 | void setup_signal_handlers() { 844 | void setup_signal_handlers(iprop_role iproprole) { 845 signal(SIGINT, sig_exit); 846 signal(SIGTERM, sig_exit); 847 signal(SIGQUIT, sig_exit); 848 signal(SIGPIPE, sig_pipe); 849 + 850 + /* 851 + * IProp will fork for a full-resync, we don't want to 852 + * wait on it and we don't want the living dead procs either. 853 + */ 854 + if (iproprole == IPROP_MASTER) 855 + (void) signal(SIGCHLD, SIG_IGN); 856 + 857 return; 858 } ----Unchanged portion omitted----