1 /* 2 * CDDL HEADER START 3 * 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. 7 * 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. 12 * 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] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 * Copyright 2012 Milan Jurik. All rights reserved. 25 */ 26 27 /* 28 * ldapclient command. To make (initiailize) or uninitialize a machines as 29 * and LDAP client. This command MUST be run as root (or it will simply exit). 30 * 31 * -I Install. No file_backup/recover for installing only (no doc). 32 * 33 * init Initialze (create) an LDAP client from a profile stored 34 * in a directory-server. 35 * manual Initialze (create) an LDAP client by hand (-file option 36 * reads from file). 37 * mod Modify the LDAP client configuration on this machine by hand. 38 * list List the contents of the LDAP client cache files. 39 * uninit Uninitialize this machine. 40 * 41 * -v Verbose flag. 42 * -q Quiet flag (mutually exclusive with -v). 43 * 44 * -a attrName=attrVal 45 * <attrName> can be one of the following: 46 * 47 * attributeMap 48 * Attribute map. Can be multiple instances of this option. 49 * (no former option) 50 * authenticationMethod 51 * Authentication method (formerly -a) 52 * bindTimeLimit 53 * Bind time limit. (no former option) 54 * certificatePath 55 * Path to certificates used for secure bind (no former option) 56 * credentialLevel 57 * Client credential level (no former option) 58 * defaultServerList 59 * Default server (no former option) Refer to DUA Config 60 * Schema draft. 61 * defaultSearchBase 62 * Search Base DN. e.g. dc=eng,dc=sun,dc=com (formerly -b) 63 * defaultSearchScope 64 * Search scope. (formerly -s) 65 * domainName 66 * Hosts lookup domain (DNS) Ex. eng.sun.com (formerly -d) 67 * followReferrals 68 * Search dereference. followref or noref (default followref) 69 * (formerly -r) 70 * objectclassMap 71 * Objectclass map. Can be multiple instances of this option. 72 * (no former option) 73 * preferredServerList 74 * Server preference list. Comma ',' seperated list of IPaddr. 75 * (formerly -p) 76 * profileName 77 * Profile name to use for init (ldapclient) or 78 * generate (gen_profile). (formerly -P) 79 * profileTTL 80 * Client info TTL. If set to 0 this information will not be 81 * automatically updated by the ldap_cachemgr(1M). 82 * (formerly -e) 83 * proxyDN 84 * Binding DN. Ex. cn=client,ou=people,cd=eng,dc=sun,dc=com 85 * (formerly -D) 86 * proxyPassword 87 * Client password not needed for authentication "none". 88 * (formerly -w) 89 * adminDN 90 * Administrator DN for updating naming data. 91 * adminPassword 92 * Administrator password 93 * enableShadowUpdate 94 * Allow Administrator to change shadow data in LDAP 95 * searchTimeLimit 96 * Timeout value. (formerly -o) 97 * serviceSearchDescriptor 98 * Service search scope. (no former option) 99 * serviceAuthenticationMethod 100 * Service authenticaion method (no former option) 101 * serviceCredentialLevel 102 * Service credential level (no former option) 103 * 104 */ 105 106 #include <stdlib.h> 107 #include <stdio.h> 108 #include <unistd.h> 109 #include <errno.h> 110 #include <sys/types.h> 111 #include <time.h> 112 #include <sys/param.h> 113 #include <sys/stat.h> 114 #include <sys/systeminfo.h> 115 #include <fcntl.h> 116 #include <xti.h> 117 #include <strings.h> 118 #include <limits.h> 119 #include <locale.h> 120 #include <syslog.h> 121 #include <libscf.h> 122 #include <assert.h> 123 124 #include "standalone.h" 125 126 #if !defined(TEXT_DOMAIN) 127 #define TEXT_DOMAIN "SUNW_OST_OSCMD" 128 #endif 129 130 /* error codes */ 131 /* The manpage doc only allows for SUCCESS(0), FAIL(1) and CRED(2) on exit */ 132 #define CLIENT_SUCCESS 0 133 #define CLIENT_ERR_PARSE -1 134 #define CLIENT_ERR_FAIL 1 135 #define CLIENT_ERR_CREDENTIAL 2 136 #define CLIENT_ERR_MEMORY 3 137 #define CLIENT_ERR_RESTORE 4 138 #define CLIENT_ERR_RENAME 5 139 #define CLIENT_ERR_RECOVER 6 140 #define CLIENT_ERR_TIMEDOUT 7 141 #define CLIENT_ERR_MAINTENANCE 8 142 143 /* Reset flag for start_services() */ 144 #define START_INIT 1 145 #define START_RESET 2 146 #define START_UNINIT 3 147 148 /* Reset flag for stop_services() */ 149 #define STATE_NOSAVE 0 150 #define STATE_SAVE 1 151 152 /* files to (possibiliy) restore */ 153 #define LDAP_RESTORE_DIR "/var/ldap/restore" 154 155 #define DOMAINNAME_DIR "/etc" 156 #define DOMAINNAME_FILE "defaultdomain" 157 #define DOMAINNAME DOMAINNAME_DIR "/" DOMAINNAME_FILE 158 #define DOMAINNAME_BACK LDAP_RESTORE_DIR "/" DOMAINNAME_FILE 159 160 #define NSSWITCH_DIR "/etc" 161 #define NSSWITCH_FILE "nsswitch.conf" 162 #define NSSWITCH_CONF NSSWITCH_DIR "/" NSSWITCH_FILE 163 #define NSSWITCH_BACK LDAP_RESTORE_DIR "/" NSSWITCH_FILE 164 #define NSSWITCH_LDAP "/etc/nsswitch.ldap" 165 166 #define YP_BIND_DIR "/var/yp/binding" 167 168 /* Define the service FMRIs */ 169 #define SENDMAIL_FMRI "network/smtp:sendmail" 170 #define NSCD_FMRI "system/name-service-cache:default" 171 #define AUTOFS_FMRI "system/filesystem/autofs:default" 172 #define LDAP_FMRI "network/ldap/client:default" 173 #define YP_FMRI "network/nis/client:default" 174 #define NS_MILESTONE_FMRI "milestone/name-services:default" 175 176 /* Define flags for checking if services were enabled */ 177 #define SENDMAIL_ON 0x1 178 #define NSCD_ON 0x10 179 #define AUTOFS_ON 0x100 180 181 #define CMD_DOMAIN_START "/usr/bin/domainname" 182 183 /* Command to copy files */ 184 #define CMD_CP "/bin/cp -f" 185 #define CMD_MV "/bin/mv -f" 186 #define CMD_RM "/bin/rm -f" 187 188 #define TO_DEV_NULL " >/dev/null 2>&1" 189 190 /* Files that need to be just removed */ 191 #define LDAP_CACHE_LOG "/var/ldap/cachemgr.log" 192 193 /* Output defines to supress if quiet mode set */ 194 #define CLIENT_FPUTS if (!mode_quiet) (void) fputs 195 #define CLIENT_FPRINTF if (!mode_quiet) (void) fprintf 196 #define CLIENT_FPUTC if (!mode_quiet) (void) fputc 197 198 #define restart_service(fmri, waitflag)\ 199 do_service(fmri, waitflag, RESTART_SERVICE,\ 200 SCF_STATE_STRING_ONLINE) 201 #define start_service(fmri, waitflag) \ 202 do_service(fmri, waitflag, START_SERVICE,\ 203 SCF_STATE_STRING_ONLINE) 204 #define disable_service(fmri, waitflag) \ 205 do_service(fmri, waitflag, STOP_SERVICE,\ 206 SCF_STATE_STRING_DISABLED) 207 208 /* 209 * There isn't a domainName defined as a param, so we set a value here 210 * (1001) should be big enough 211 */ 212 #define LOCAL_DOMAIN_P 1001 213 214 #define START_SERVICE 1 215 #define STOP_SERVICE 2 216 #define RESTART_SERVICE 3 217 218 #define DEFAULT_TIMEOUT 60000000 219 220 #define INIT_WAIT_USECS 50000 221 222 /* Used to turn off profile checking */ 223 #define CACHETTL_OFF "0" 224 225 /* Globals */ 226 static char *cmd; 227 228 static char *dname = NULL; 229 static char dname_buf[BUFSIZ]; 230 231 static boolean_t sysid_install = B_FALSE; 232 233 static int mode_verbose = 0; 234 static int mode_quiet = 0; 235 static int gen = 0; 236 237 static int gStartLdap = 0; 238 static int gStartYp = 0; 239 240 static int enableFlag = 0; 241 242 /* multival_t is used to hold params that can have more than one value */ 243 typedef struct { 244 int count; 245 char **optlist; 246 } multival_t; 247 248 static multival_t *multival_new(); 249 static int multival_add(multival_t *list, char *opt); 250 static void multival_free(multival_t *list); 251 252 /* 253 * clientopts_t is used to hold and pass around the param values from 254 * the cmd line 255 */ 256 typedef struct { 257 multival_t *attributeMap; 258 char *authenticationMethod; 259 char *bindTimeLimit; 260 char *certificatePath; 261 char *credentialLevel; 262 char *defaultSearchBase; 263 char *defaultServerList; 264 char *domainName; 265 char *followReferrals; 266 multival_t *objectclassMap; 267 char *preferredServerList; 268 char *profileName; 269 char *profileTTL; 270 char *proxyDN; 271 char *proxyPassword; 272 char *enableShadowUpdate; 273 char *adminDN; 274 char *adminPassword; 275 char *bindDN; 276 char *bindPasswd; 277 char *defaultSearchScope; 278 char *searchTimeLimit; 279 multival_t *serviceAuthenticationMethod; 280 multival_t *serviceCredentialLevel; 281 multival_t *serviceSearchDescriptor; 282 } clientopts_t; 283 284 static clientopts_t *clientopts_new(); 285 static void clientopts_free(clientopts_t *list); 286 287 extern ns_ldap_error_t *__ns_ldap_print_config(int); 288 extern void __ns_ldap_default_config(); 289 extern int __ns_ldap_download(const char *, char *, char *, ns_ldap_error_t **); 290 291 /* Function prototypes (these could be static) */ 292 static void usage(void); 293 294 static int credCheck(clientopts_t *arglist); 295 static int adminCredCheck(clientopts_t *arglist); 296 static int clientSetParam(clientopts_t *optlist, int paramFlag, char *attrVal); 297 static int parseParam(char *param, char **paramVal); 298 static void dumpargs(clientopts_t *arglist); 299 static int num_args(clientopts_t *arglist); 300 301 static int file_backup(void); 302 static int recover(int saveState); 303 static int mod_backup(void); 304 static int mod_recover(void); 305 static void mod_cleanup(void); 306 307 static int client_list(clientopts_t *arglist); 308 static int client_manual(clientopts_t *arglist); 309 static int client_mod(clientopts_t *arglist); 310 static int client_uninit(clientopts_t *arglist); 311 static int client_genProfile(clientopts_t *arglist); 312 static int client_init(clientopts_t *arglist); 313 static int file_move(const char *from, const char *to); 314 315 static int start_services(int flag); 316 static int stop_services(int saveState); 317 static boolean_t is_service(const char *fmri, const char *state); 318 static int wait_till(const char *fmri, const char *state, useconds_t max, 319 const char *what, boolean_t check_maint); 320 static int do_service(const char *fmri, boolean_t waitflag, int dowhat, 321 const char *state); 322 static useconds_t get_timeout_value(int dowhat, const char *fmri, 323 useconds_t default_val); 324 325 int 326 main(int argc, char **argv) 327 { 328 char *ret_locale, *ret_textdomain; 329 int retcode; 330 int paramFlag; 331 char *attrVal; 332 int sysinfostatus; 333 clientopts_t *optlist = NULL; 334 int op_manual = 0, op_mod = 0, op_uninit = 0; 335 int op_list = 0, op_init = 0, op_genprofile = 0; 336 extern char *optarg; 337 extern int optind; 338 int option; 339 340 ret_locale = setlocale(LC_ALL, ""); 341 if (ret_locale == NULL) { 342 CLIENT_FPUTS(gettext("Unable to set locale.\n"), stderr); 343 } 344 ret_textdomain = textdomain(TEXT_DOMAIN); 345 if (ret_textdomain == NULL) { 346 CLIENT_FPUTS(gettext("Unable to set textdomain.\n"), stderr); 347 } 348 349 openlog("ldapclient", LOG_PID, LOG_USER); 350 351 /* get name that invoked us */ 352 if (cmd = strrchr(argv[0], '/')) 353 ++cmd; 354 else 355 cmd = argv[0]; 356 357 sysinfostatus = sysinfo(SI_SRPC_DOMAIN, dname_buf, BUFSIZ); 358 if (0 < sysinfostatus) 359 dname = &dname_buf[0]; 360 361 optlist = clientopts_new(); 362 if (optlist == NULL) { 363 CLIENT_FPUTS( 364 gettext("Error getting optlist (malloc fail)\n"), 365 stderr); 366 exit(CLIENT_ERR_FAIL); 367 } 368 369 optind = 1; 370 while (optind < argc) { 371 option = getopt(argc, argv, "vqa:ID:w:j:y:z:"); 372 373 switch (option) { 374 case 'v': 375 mode_verbose = 1; 376 break; 377 case 'q': 378 mode_quiet = 1; 379 break; 380 case 'a': 381 attrVal = NULL; 382 paramFlag = parseParam(optarg, &attrVal); 383 if (paramFlag == CLIENT_ERR_PARSE) { 384 CLIENT_FPRINTF(stderr, 385 gettext("Unrecognized " 386 "parameter \"%s\"\n"), 387 optarg); 388 usage(); 389 exit(CLIENT_ERR_FAIL); 390 } 391 if (paramFlag == NS_LDAP_BINDPASSWD_P && 392 optlist->proxyPassword != NULL) { 393 (void) fprintf(stderr, 394 gettext("The -a proxyPassword option is " 395 "mutually exclusive of -y. " 396 "-a proxyPassword is ignored.\n")); 397 break; 398 } 399 if (paramFlag == NS_LDAP_ADMIN_BINDPASSWD_P && 400 optlist->adminPassword != NULL) { 401 (void) fprintf(stderr, 402 gettext("The -a adminPassword option is " 403 "mutually exclusive of -z. " 404 "-a adminPassword is ignored.\n")); 405 break; 406 } 407 retcode = clientSetParam(optlist, paramFlag, attrVal); 408 if (retcode != CLIENT_SUCCESS) { 409 CLIENT_FPRINTF( 410 stderr, 411 gettext("Error (%d) setting " 412 "param \"%s\"\n"), 413 retcode, optarg); 414 usage(); 415 exit(CLIENT_ERR_FAIL); 416 } 417 break; 418 case 'D': 419 optlist->bindDN = strdup(optarg); 420 break; 421 case 'w': 422 if (optlist->bindPasswd != NULL) { 423 CLIENT_FPRINTF(stderr, 424 gettext("The -w option is mutually " 425 "exclusive of -j. -w is ignored.")); 426 break; 427 } 428 429 if (optarg[0] == '-' && optarg[1] == '\0') { 430 /* Ask for a password later */ 431 break; 432 } 433 434 optlist->bindPasswd = strdup(optarg); 435 break; 436 case 'j': 437 if (optlist->bindPasswd != NULL) { 438 (void) fprintf(stderr, 439 gettext("The -w option is mutually " 440 "exclusive of -j. -w is ignored.\n")); 441 free(optlist->bindPasswd); 442 } 443 optlist->bindPasswd = readPwd(optarg); 444 if (optlist->bindPasswd == NULL) { 445 exit(CLIENT_ERR_FAIL); 446 } 447 break; 448 case 'y': 449 if (optlist->proxyPassword != NULL) { 450 (void) fprintf(stderr, 451 gettext("The -a proxyPassword option is " 452 "mutually exclusive of -y. " 453 "-a proxyPassword is ignored.\n")); 454 } 455 optlist->proxyPassword = readPwd(optarg); 456 if (optlist->proxyPassword == NULL) { 457 exit(CLIENT_ERR_FAIL); 458 } 459 break; 460 case 'z': 461 if (optlist->adminPassword != NULL) { 462 (void) fprintf(stderr, 463 gettext("The -a adminPassword option is " 464 "mutually exclusive of -z. " 465 "-a adminPassword is ignored.\n")); 466 } 467 optlist->adminPassword = readPwd(optarg); 468 if (optlist->adminPassword == NULL) { 469 exit(CLIENT_ERR_FAIL); 470 } 471 break; 472 case EOF: 473 if (strcmp(argv[optind], "init") == 0) { 474 op_init = 1; 475 } else if (strcmp(argv[optind], "manual") == 0) { 476 op_manual = 1; 477 } else if (strcmp(argv[optind], "mod") == 0) { 478 op_mod = 1; 479 } else if (strcmp(argv[optind], "list") == 0) { 480 op_list = 1; 481 } else if (strcmp(argv[optind], "uninit") == 0) { 482 op_uninit = 1; 483 } else if (strcmp(argv[optind], "genprofile") == 0) { 484 gen = 1; 485 op_genprofile = 1; 486 } else if (optind == argc-1) { 487 retcode = clientSetParam( 488 optlist, 489 NS_LDAP_SERVERS_P, 490 argv[optind]); /* ipAddr */ 491 if (retcode != CLIENT_SUCCESS) { 492 CLIENT_FPRINTF( 493 stderr, 494 gettext("Error (%d) setting " 495 "serverList param.\n"), 496 retcode); 497 usage(); 498 exit(CLIENT_ERR_FAIL); 499 } 500 } else { 501 CLIENT_FPUTS( 502 gettext("Error parsing " 503 "command line\n"), 504 stderr); 505 usage(); 506 exit(CLIENT_ERR_FAIL); 507 } 508 optind++; /* get past the verb and keep trying */ 509 break; 510 /* Backwards compatibility to support system install */ 511 case 'I': 512 sysid_install = B_TRUE; 513 op_init = 1; 514 mode_quiet = 1; 515 break; 516 case '?': 517 usage(); 518 CLIENT_FPUTS(gettext("\nOr\n\n"), stderr); 519 gen = 1; 520 usage(); 521 exit(CLIENT_ERR_FAIL); 522 break; 523 } 524 525 } 526 527 if ((getuid() != 0) && (!op_genprofile)) { 528 (void) puts( 529 "You must be root (SuperUser) to run this command."); 530 usage(); 531 exit(CLIENT_ERR_FAIL); 532 } 533 534 /* 535 * All command line arguments are finished being parsed now 536 */ 537 538 /* *** Do semantic checking here *** */ 539 540 /* if gen and no no searchBase then err */ 541 if (gen && !optlist->defaultSearchBase) { 542 CLIENT_FPUTS( 543 gettext("ldapclient: Missing required attrName " 544 "defaultSearchBase\n"), 545 stderr); 546 usage(); 547 clientopts_free(optlist); 548 exit(CLIENT_ERR_FAIL); 549 } 550 551 /* 552 * if init or manual, and if adminDN is specified then enableShadowUpdate 553 * must be set to TRUE. 554 */ 555 if ((op_init || op_manual) && 556 (!optlist->enableShadowUpdate || 557 strcasecmp(optlist->enableShadowUpdate, "TRUE") != 0) && 558 (optlist->adminDN || optlist->adminPassword)) { 559 CLIENT_FPUTS( 560 gettext("ldapclient: adminDN and adminPassword must not " 561 "be specified if enableShadowUpdate is not set to TRUE \n"), 562 stderr); 563 usage(); 564 clientopts_free(optlist); 565 exit(CLIENT_ERR_FAIL); 566 } 567 568 /* Only one verb can be specified */ 569 if ((op_init + op_manual + op_mod + op_uninit + 570 op_list + op_genprofile) != 1) { 571 usage(); 572 clientopts_free(optlist); 573 exit(CLIENT_ERR_FAIL); 574 } 575 576 /* *** We passed semantic checking, so now do the operation *** */ 577 578 if (mode_verbose) { 579 CLIENT_FPUTS(gettext("Arguments parsed:\n"), stderr); 580 dumpargs(optlist); 581 } 582 583 584 /* handle "ldapclient list" here. err checking done in func */ 585 if (op_list) { 586 if (mode_verbose) 587 CLIENT_FPUTS( 588 gettext("Handling list option\n"), 589 stderr); 590 retcode = client_list(optlist); 591 } 592 593 /* handle "ldapclient uninit" here */ 594 if (op_uninit) { 595 if (mode_verbose) 596 CLIENT_FPUTS( 597 gettext("Handling uninit option\n"), 598 stderr); 599 retcode = client_uninit(optlist); 600 } 601 602 /* handle "ldapclient init" (profile) */ 603 if (op_init) { 604 if (mode_verbose) 605 CLIENT_FPUTS( 606 gettext("Handling init option\n"), 607 stderr); 608 retcode = client_init(optlist); 609 } 610 611 /* handle "genprofile" here */ 612 if (op_genprofile) { 613 if (mode_verbose) 614 CLIENT_FPUTS( 615 gettext("Handling genProfile\n"), 616 stderr); 617 retcode = client_genProfile(optlist); 618 } 619 620 /* handle "ldapclient manual" here */ 621 if (op_manual) { 622 if (mode_verbose) 623 CLIENT_FPUTS( 624 gettext("Handling manual option\n"), 625 stderr); 626 retcode = client_manual(optlist); 627 } 628 629 /* handle "ldapclient mod" here */ 630 if (op_mod) { 631 if (mode_verbose) 632 CLIENT_FPUTS( 633 gettext("Handling mod option\n"), 634 stderr); 635 retcode = client_mod(optlist); 636 } 637 638 clientopts_free(optlist); 639 if ((retcode == CLIENT_SUCCESS) || 640 (retcode == CLIENT_ERR_FAIL) || 641 (retcode == CLIENT_ERR_CREDENTIAL)) 642 return (retcode); 643 else 644 return (CLIENT_ERR_FAIL); 645 } 646 647 static int 648 client_list(clientopts_t *arglist) 649 { 650 ns_ldap_error_t *errorp; 651 int retcode = CLIENT_SUCCESS; 652 653 if (num_args(arglist) > 0) { 654 CLIENT_FPUTS( 655 gettext("No args supported with \"list\" option\n"), 656 stderr); 657 usage(); 658 return (CLIENT_ERR_FAIL); /* exit code here ? */ 659 } 660 if ((errorp = __ns_ldap_print_config(mode_verbose)) != NULL) { 661 retcode = CLIENT_ERR_FAIL; 662 CLIENT_FPUTS( 663 gettext("Cannot get print configuration\n"), 664 stderr); 665 CLIENT_FPUTS(errorp->message, stderr); 666 (void) __ns_ldap_freeError(&errorp); 667 CLIENT_FPUTC('\n', stderr); 668 } 669 670 return (retcode); 671 } 672 673 static int 674 client_uninit(clientopts_t *arglist) 675 { 676 int retcode = CLIENT_SUCCESS; 677 ns_ldap_self_gssapi_config_t config = NS_LDAP_SELF_GSSAPI_CONFIG_NONE; 678 679 if (mode_verbose) { 680 CLIENT_FPUTS( 681 gettext("Restoring machine to previous " 682 "configuration state\n"), 683 stderr); 684 } 685 686 if (num_args(arglist) > 0) { 687 CLIENT_FPUTS( 688 gettext("No args supported with \"uninit\" option\n"), 689 stderr); 690 usage(); 691 return (CLIENT_ERR_FAIL); 692 } 693 694 (void) __ns_ldap_self_gssapi_config(&config); 695 696 retcode = stop_services(STATE_SAVE); 697 698 if (config != NS_LDAP_SELF_GSSAPI_CONFIG_NONE) 699 (void) system("/usr/sbin/cryptoadm enable metaslot"); 700 701 if (retcode != CLIENT_SUCCESS) { 702 CLIENT_FPUTS( 703 gettext("Errors stopping network services.\n"), stderr); 704 /* restart whatever services we can */ 705 (void) start_services(START_RESET); 706 return (CLIENT_ERR_FAIL); 707 } 708 709 retcode = recover(STATE_SAVE); 710 if (retcode != CLIENT_SUCCESS) { 711 CLIENT_FPUTS( 712 gettext("Cannot recover the configuration on " 713 "this machine.\n"), 714 stderr); 715 (void) start_services(START_RESET); 716 } else { 717 retcode = start_services(START_UNINIT); 718 if (retcode != CLIENT_SUCCESS) { 719 CLIENT_FPUTS( 720 gettext("Config restored but problems " 721 "encountered resetting network " 722 "services.\n"), 723 stderr); 724 } 725 } 726 727 if (retcode == CLIENT_SUCCESS) { 728 CLIENT_FPUTS( 729 gettext("System successfully recovered\n"), 730 stderr); 731 } 732 733 return (retcode); 734 } 735 736 /* 737 * The following macro is used to do a __ns_ldap_setParam(). 738 * On every call, the return code is checked, and if there was 739 * a problem then the error message is printed, the ldaperr 740 * is freed and we return from the function with the offending 741 * error return code. This macro keeps us from having to 742 * repeat this code for every call to setParam as was done 743 * in the previous incarnation of ldapclient. 744 * 745 * assumes a "retcode" variable is available for status 746 */ 747 #define LDAP_SET_PARAM(argval, argdef) \ 748 retcode = 0; \ 749 if (NULL != argval) { \ 750 ns_ldap_error_t *ldaperr; \ 751 retcode = __ns_ldap_setParam(argdef, (void *)argval, &ldaperr); \ 752 if (retcode != NS_LDAP_SUCCESS) { \ 753 if (NULL != ldaperr) { \ 754 CLIENT_FPUTS(ldaperr->message, stderr); \ 755 CLIENT_FPUTC('\n', stderr); \ 756 (void) __ns_ldap_freeError(&ldaperr); \ 757 } \ 758 return (retcode ? CLIENT_ERR_FAIL : CLIENT_SUCCESS); \ 759 } \ 760 } 761 762 /* 763 * The following macro is used to check if an arg has already been set 764 * and issues an error message, a usage message and then returns an error. 765 * This was made into a macro to avoid the duplication of this code many 766 * times in the function below. 767 */ 768 #define LDAP_CHECK_INVALID(arg, param) \ 769 if (arg) { \ 770 CLIENT_FPRINTF(stderr, gettext("Invalid parameter (%s) " \ 771 "specified\n"), param); \ 772 usage(); \ 773 return (CLIENT_ERR_FAIL); \ 774 } 775 776 static int 777 client_manual(clientopts_t *arglist) 778 { 779 int counter; 780 int domain_fp; 781 ns_ldap_error_t *errorp; 782 int ret_copy; 783 int reset_ret; 784 int retcode = CLIENT_SUCCESS; 785 786 if (dname == NULL) { 787 CLIENT_FPUTS( 788 gettext("Manual failed: System domain not set and " 789 "no domainName specified.\n"), 790 stderr); 791 return (CLIENT_ERR_FAIL); 792 } 793 794 if (arglist->defaultSearchBase == NULL) { 795 CLIENT_FPUTS( 796 gettext("Manual failed: Missing required " 797 "defaultSearchBase attribute.\n"), 798 stderr); 799 return (CLIENT_ERR_FAIL); 800 } 801 802 if ((arglist->defaultServerList == NULL) && 803 (arglist->preferredServerList == NULL)) { 804 CLIENT_FPUTS( 805 gettext("Manual failed: Missing required " 806 "defaultServerList or preferredServerList " 807 "attribute.\n"), 808 stderr); 809 return (CLIENT_ERR_FAIL); 810 } 811 812 if (arglist->profileTTL != NULL) { 813 CLIENT_FPUTS( 814 gettext("Manual aborted: profileTTL is not supported " 815 "in manual mode.\n"), 816 stderr); 817 return (CLIENT_ERR_FAIL); 818 } 819 820 if (arglist->profileName != NULL) { 821 CLIENT_FPUTS( 822 gettext("Manual aborted: profileName is not supported " 823 "in manual mode.\n"), 824 stderr); 825 return (CLIENT_ERR_FAIL); 826 } 827 828 LDAP_CHECK_INVALID(arglist->bindDN, "bind DN"); 829 LDAP_CHECK_INVALID(arglist->bindPasswd, "bind password"); 830 831 __ns_ldap_setServer(TRUE); /* Need this for _ns_setParam() */ 832 __ns_ldap_default_config(); 833 834 /* Set version to latest (not version 1) */ 835 LDAP_SET_PARAM(NS_LDAP_VERSION, NS_LDAP_FILE_VERSION_P); 836 837 /* Set profileTTL to 0 since NO profile on manual */ 838 LDAP_SET_PARAM(CACHETTL_OFF, NS_LDAP_CACHETTL_P); 839 840 /* Set additional valid params from command line */ 841 LDAP_SET_PARAM(arglist->authenticationMethod, NS_LDAP_AUTH_P); 842 LDAP_SET_PARAM(arglist->defaultSearchBase, NS_LDAP_SEARCH_BASEDN_P); 843 LDAP_SET_PARAM(arglist->credentialLevel, NS_LDAP_CREDENTIAL_LEVEL_P); 844 LDAP_SET_PARAM(arglist->proxyDN, NS_LDAP_BINDDN_P); 845 LDAP_SET_PARAM(arglist->enableShadowUpdate, 846 NS_LDAP_ENABLE_SHADOW_UPDATE_P); 847 LDAP_SET_PARAM(arglist->adminDN, NS_LDAP_ADMIN_BINDDN_P); 848 LDAP_SET_PARAM(arglist->searchTimeLimit, NS_LDAP_SEARCH_TIME_P); 849 LDAP_SET_PARAM(arglist->preferredServerList, NS_LDAP_SERVER_PREF_P); 850 LDAP_SET_PARAM(arglist->profileName, NS_LDAP_PROFILE_P); 851 LDAP_SET_PARAM(arglist->followReferrals, NS_LDAP_SEARCH_REF_P); 852 LDAP_SET_PARAM(arglist->defaultSearchScope, NS_LDAP_SEARCH_SCOPE_P); 853 LDAP_SET_PARAM(arglist->bindTimeLimit, NS_LDAP_BIND_TIME_P); 854 LDAP_SET_PARAM(arglist->proxyPassword, NS_LDAP_BINDPASSWD_P); 855 LDAP_SET_PARAM(arglist->adminPassword, NS_LDAP_ADMIN_BINDPASSWD_P); 856 LDAP_SET_PARAM(arglist->defaultServerList, NS_LDAP_SERVERS_P); 857 LDAP_SET_PARAM(arglist->certificatePath, NS_LDAP_HOST_CERTPATH_P); 858 859 for (counter = 0; 860 counter < arglist->serviceAuthenticationMethod->count; 861 counter++) { 862 863 LDAP_SET_PARAM( 864 arglist->serviceAuthenticationMethod->optlist[counter], 865 NS_LDAP_SERVICE_AUTH_METHOD_P); 866 } 867 for (counter = 0; 868 counter < arglist->serviceCredentialLevel->count; 869 counter++) { 870 871 LDAP_SET_PARAM( 872 arglist->serviceCredentialLevel->optlist[counter], 873 NS_LDAP_SERVICE_CRED_LEVEL_P); 874 } 875 for (counter = 0; 876 counter < arglist->objectclassMap->count; 877 counter++) { 878 879 LDAP_SET_PARAM(arglist->objectclassMap->optlist[counter], 880 NS_LDAP_OBJECTCLASSMAP_P); 881 } 882 for (counter = 0; counter < arglist->attributeMap->count; counter++) { 883 LDAP_SET_PARAM(arglist->attributeMap->optlist[counter], 884 NS_LDAP_ATTRIBUTEMAP_P); 885 } 886 for (counter = 0; 887 counter < arglist->serviceSearchDescriptor->count; 888 counter++) { 889 890 LDAP_SET_PARAM( 891 arglist->serviceSearchDescriptor->optlist[counter], 892 NS_LDAP_SERVICE_SEARCH_DESC_P); 893 } 894 895 retcode = credCheck(arglist); 896 if (retcode == CLIENT_SUCCESS) 897 retcode = adminCredCheck(arglist); 898 if (retcode != CLIENT_SUCCESS) { 899 CLIENT_FPUTS( 900 gettext("Error in setting up credentials\n"), 901 stderr); 902 return (retcode); 903 } 904 905 if (mode_verbose) 906 CLIENT_FPUTS( 907 gettext("About to modify this machines " 908 "configuration by writing the files\n"), 909 stderr); 910 911 /* get ready to start playing with files */ 912 retcode = stop_services(STATE_SAVE); 913 if (retcode != CLIENT_SUCCESS) { 914 CLIENT_FPUTS( 915 gettext("Errors stopping network services.\n"), stderr); 916 return (CLIENT_ERR_FAIL); 917 } 918 919 /* Save orig versions of files */ 920 retcode = file_backup(); 921 if (retcode == CLIENT_ERR_RESTORE) { 922 CLIENT_FPUTS( 923 gettext("System not in state to enable ldap client.\n"), 924 stderr); 925 926 reset_ret = start_services(START_RESET); 927 if (reset_ret != CLIENT_SUCCESS) { 928 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 929 "starting services during reset\n"), 930 reset_ret); 931 } 932 return (retcode); 933 } else if (retcode != CLIENT_SUCCESS) { 934 CLIENT_FPUTS( 935 gettext("Save of system configuration failed! " 936 "Attempting recovery.\n"), 937 stderr); 938 retcode = recover(STATE_NOSAVE); 939 if (retcode != CLIENT_SUCCESS) { 940 CLIENT_FPUTS( 941 gettext("Recovery of systems configuration " 942 "failed. Manual intervention of " 943 "config files is required.\n"), 944 stderr); 945 return (retcode); 946 } 947 948 reset_ret = start_services(START_RESET); 949 if (reset_ret != CLIENT_SUCCESS) { 950 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 951 "starting services during reset\n"), 952 reset_ret); 953 } 954 955 return (retcode); 956 } 957 958 /* Dump new files */ 959 errorp = __ns_ldap_DumpConfiguration(NSCONFIGFILE); 960 if (errorp != NULL) { 961 CLIENT_FPRINTF(stderr, 962 gettext("%s manual: errorp is not NULL; %s\n"), 963 cmd, errorp->message); 964 retcode = recover(STATE_NOSAVE); 965 if (retcode != CLIENT_SUCCESS) { 966 CLIENT_FPUTS( 967 gettext("Recovery of systems configuration " 968 "failed. Manual intervention of " 969 "config files is required.\n"), 970 stderr); 971 return (retcode); 972 } 973 reset_ret = start_services(START_RESET); 974 if (reset_ret != CLIENT_SUCCESS) { 975 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 976 "starting services during reset\n"), 977 reset_ret); 978 } 979 (void) __ns_ldap_freeError(&errorp); 980 return (CLIENT_ERR_FAIL); 981 } 982 983 /* if (credargs(arglist)) */ 984 errorp = __ns_ldap_DumpConfiguration(NSCREDFILE); 985 if (errorp != NULL) { 986 CLIENT_FPRINTF(stderr, 987 gettext("%s init: errorp is not NULL; %s\n"), 988 cmd, errorp->message); 989 retcode = recover(STATE_NOSAVE); 990 if (retcode != CLIENT_SUCCESS) { 991 CLIENT_FPUTS( 992 gettext("Recovery of systems configuration " 993 "failed. Manual intervention of " 994 "config files is required.\n"), 995 stderr); 996 return (retcode); 997 } 998 reset_ret = start_services(START_RESET); 999 if (reset_ret != CLIENT_SUCCESS) { 1000 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 1001 "starting services during reset\n"), 1002 reset_ret); 1003 } 1004 (void) __ns_ldap_freeError(&errorp); 1005 return (CLIENT_ERR_FAIL); 1006 } 1007 1008 ret_copy = system(CMD_CP " " NSSWITCH_LDAP " " NSSWITCH_CONF); 1009 if (ret_copy != 0) { 1010 CLIENT_FPRINTF(stderr, 1011 gettext("Error %d copying (%s) -> (%s)\n"), 1012 ret_copy, NSSWITCH_LDAP, NSSWITCH_CONF); 1013 retcode = recover(STATE_NOSAVE); 1014 if (retcode != CLIENT_SUCCESS) { 1015 CLIENT_FPUTS( 1016 gettext("Recovery of systems configuration " 1017 "failed. Manual intervention of " 1018 "config files is required.\n"), 1019 stderr); 1020 } 1021 reset_ret = start_services(START_RESET); 1022 if (reset_ret != CLIENT_SUCCESS) { 1023 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 1024 "starting services during reset\n"), 1025 reset_ret); 1026 } 1027 return (CLIENT_ERR_FAIL); 1028 } 1029 1030 if ((domain_fp = open(DOMAINNAME, O_WRONLY|O_CREAT|O_TRUNC, 1031 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1) { /* 0644 */ 1032 CLIENT_FPRINTF(stderr, gettext("Cannot open %s\n"), DOMAINNAME); 1033 retcode = recover(STATE_NOSAVE); 1034 if (retcode != CLIENT_SUCCESS) { 1035 CLIENT_FPUTS( 1036 gettext("Recovery of systems configuration " 1037 "failed. Manual intervention of " 1038 "config files is required.\n"), 1039 stderr); 1040 return (CLIENT_ERR_FAIL); 1041 } 1042 reset_ret = start_services(START_RESET); 1043 if (reset_ret != CLIENT_SUCCESS) { 1044 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 1045 "starting services during reset\n"), 1046 reset_ret); 1047 } 1048 return (CLIENT_ERR_FAIL); 1049 } 1050 (void) write(domain_fp, dname, strlen(dname)); 1051 (void) write(domain_fp, "\n", 1); 1052 (void) close(domain_fp); 1053 1054 retcode = start_services(START_INIT); 1055 1056 if (retcode == CLIENT_SUCCESS) { 1057 CLIENT_FPUTS(gettext("System successfully configured\n"), 1058 stderr); 1059 } else { 1060 CLIENT_FPUTS(gettext("Error resetting system.\n" 1061 "Recovering old system settings.\n"), stderr), 1062 1063 /* stop any started services for recover */ 1064 /* don't stomp on history of saved services state */ 1065 reset_ret = stop_services(STATE_NOSAVE); 1066 if (reset_ret != CLIENT_SUCCESS) { 1067 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 1068 "stopping services during reset\n"), 1069 reset_ret); 1070 /* Coninue and try to recover what we can */ 1071 } 1072 reset_ret = recover(STATE_NOSAVE); 1073 if (reset_ret != CLIENT_SUCCESS) { 1074 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 1075 "recovering service files during " 1076 "reset\n"), reset_ret); 1077 /* Continue and start what we can */ 1078 } 1079 reset_ret = start_services(START_RESET); 1080 if (reset_ret != CLIENT_SUCCESS) { 1081 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 1082 "starting services during reset\n"), 1083 reset_ret); 1084 } 1085 } 1086 1087 return (retcode); 1088 } 1089 1090 static int 1091 client_mod(clientopts_t *arglist) 1092 { 1093 int counter; 1094 int domain_fp; 1095 ns_ldap_error_t *errorp; 1096 int reset_ret; 1097 int retcode = CLIENT_SUCCESS; 1098 1099 __ns_ldap_setServer(TRUE); /* Need this for _ns_setParam() */ 1100 if ((errorp = __ns_ldap_LoadConfiguration()) != NULL) { 1101 CLIENT_FPUTS(gettext("Cannot get load configuration\n"), 1102 stderr); 1103 CLIENT_FPUTS(errorp->message, stderr); 1104 CLIENT_FPUTC('\n', stderr); 1105 (void) __ns_ldap_freeError(&errorp); 1106 return (CLIENT_ERR_FAIL); 1107 } 1108 1109 if (arglist->profileTTL != NULL) { 1110 CLIENT_FPUTS( 1111 gettext("Mod aborted: profileTTL modification is " 1112 "not allowed in mod mode.\n"), 1113 stderr); 1114 return (CLIENT_ERR_FAIL); 1115 } 1116 1117 if (arglist->profileName != NULL) { 1118 CLIENT_FPUTS( 1119 gettext("Mod aborted: profileName modification is " 1120 "not allowed. If you want to use profiles " 1121 "generate one with genProfile and load it " 1122 "on the server with ldapadd.\n"), 1123 stderr); 1124 return (CLIENT_ERR_FAIL); 1125 } 1126 1127 LDAP_CHECK_INVALID(arglist->bindDN, "bind DN"); 1128 LDAP_CHECK_INVALID(arglist->bindPasswd, "bind password"); 1129 1130 /* Set additional valid params from command line */ 1131 LDAP_SET_PARAM(arglist->authenticationMethod, NS_LDAP_AUTH_P); 1132 LDAP_SET_PARAM(arglist->defaultSearchBase, NS_LDAP_SEARCH_BASEDN_P); 1133 LDAP_SET_PARAM(arglist->credentialLevel, NS_LDAP_CREDENTIAL_LEVEL_P); 1134 LDAP_SET_PARAM(arglist->proxyDN, NS_LDAP_BINDDN_P); 1135 LDAP_SET_PARAM(arglist->adminDN, NS_LDAP_ADMIN_BINDDN_P); 1136 LDAP_SET_PARAM(arglist->profileTTL, NS_LDAP_CACHETTL_P); 1137 LDAP_SET_PARAM(arglist->searchTimeLimit, NS_LDAP_SEARCH_TIME_P); 1138 LDAP_SET_PARAM(arglist->preferredServerList, NS_LDAP_SERVER_PREF_P); 1139 LDAP_SET_PARAM(arglist->profileName, NS_LDAP_PROFILE_P); 1140 LDAP_SET_PARAM(arglist->followReferrals, NS_LDAP_SEARCH_REF_P); 1141 LDAP_SET_PARAM(arglist->defaultSearchScope, NS_LDAP_SEARCH_SCOPE_P); 1142 LDAP_SET_PARAM(arglist->bindTimeLimit, NS_LDAP_BIND_TIME_P); 1143 LDAP_SET_PARAM(arglist->proxyPassword, NS_LDAP_BINDPASSWD_P); 1144 LDAP_SET_PARAM(arglist->adminPassword, NS_LDAP_ADMIN_BINDPASSWD_P); 1145 LDAP_SET_PARAM(arglist->defaultServerList, NS_LDAP_SERVERS_P); 1146 LDAP_SET_PARAM(arglist->enableShadowUpdate, 1147 NS_LDAP_ENABLE_SHADOW_UPDATE_P); 1148 LDAP_SET_PARAM(arglist->certificatePath, NS_LDAP_HOST_CERTPATH_P); 1149 1150 for (counter = 0; 1151 counter < arglist->serviceAuthenticationMethod->count; 1152 counter++) { 1153 1154 LDAP_SET_PARAM( 1155 arglist->serviceAuthenticationMethod->optlist[counter], 1156 NS_LDAP_SERVICE_AUTH_METHOD_P); 1157 } 1158 for (counter = 0; 1159 counter < arglist->serviceCredentialLevel->count; 1160 counter++) { 1161 1162 LDAP_SET_PARAM( 1163 arglist->serviceCredentialLevel->optlist[counter], 1164 NS_LDAP_SERVICE_CRED_LEVEL_P); 1165 } 1166 for (counter = 0; 1167 counter < arglist->objectclassMap->count; 1168 counter++) { 1169 1170 LDAP_SET_PARAM( 1171 arglist->objectclassMap->optlist[counter], 1172 NS_LDAP_OBJECTCLASSMAP_P); 1173 } 1174 for (counter = 0; 1175 counter < arglist->attributeMap->count; 1176 counter++) { 1177 1178 LDAP_SET_PARAM( 1179 arglist->attributeMap->optlist[counter], 1180 NS_LDAP_ATTRIBUTEMAP_P); 1181 } 1182 for (counter = 0; 1183 counter < arglist->serviceSearchDescriptor->count; 1184 counter++) { 1185 1186 LDAP_SET_PARAM( 1187 arglist->serviceSearchDescriptor->optlist[counter], 1188 NS_LDAP_SERVICE_SEARCH_DESC_P); 1189 } 1190 1191 retcode = credCheck(arglist); 1192 if (retcode == CLIENT_SUCCESS) 1193 retcode = adminCredCheck(arglist); 1194 if (retcode != CLIENT_SUCCESS) { 1195 CLIENT_FPUTS( 1196 gettext("Error in setting up credentials\n"), 1197 stderr); 1198 return (retcode); 1199 } 1200 1201 if (mode_verbose) 1202 CLIENT_FPUTS( 1203 gettext("About to modify this machines configuration " 1204 "by writing the files\n"), 1205 stderr); 1206 1207 /* get ready to start playing with files */ 1208 retcode = stop_services(STATE_SAVE); 1209 if (retcode != CLIENT_SUCCESS) { 1210 CLIENT_FPUTS( 1211 gettext("Errors stopping network services.\n"), stderr); 1212 return (CLIENT_ERR_FAIL); 1213 } 1214 1215 /* Temporarily save orig versions of files */ 1216 retcode = mod_backup(); 1217 if (retcode != CLIENT_SUCCESS) { 1218 CLIENT_FPUTS( 1219 gettext("Unable to backup the ldap client files!\n"), 1220 stderr); 1221 1222 return (retcode); 1223 1224 } 1225 1226 /* Dump new files */ 1227 errorp = __ns_ldap_DumpConfiguration(NSCONFIGFILE); 1228 if (errorp != NULL) { 1229 CLIENT_FPRINTF(stderr, 1230 gettext("%s mod: errorp is not NULL; %s\n"), 1231 cmd, errorp->message); 1232 retcode = mod_recover(); 1233 if (retcode != CLIENT_SUCCESS) { 1234 CLIENT_FPUTS( 1235 gettext("Recovery of systems configuration " 1236 "failed. Manual intervention of " 1237 "config files is required.\n"), 1238 stderr); 1239 } 1240 (void) __ns_ldap_freeError(&errorp); 1241 reset_ret = start_services(START_RESET); 1242 if (reset_ret != CLIENT_SUCCESS) { 1243 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 1244 "starting services during reset\n"), 1245 reset_ret); 1246 } 1247 return (CLIENT_ERR_FAIL); 1248 } 1249 1250 /* if (credargs(arglist)) */ 1251 errorp = __ns_ldap_DumpConfiguration(NSCREDFILE); 1252 if (errorp != NULL) { 1253 CLIENT_FPRINTF(stderr, 1254 gettext("%s mod: errorp is not NULL; %s\n"), 1255 cmd, errorp->message); 1256 retcode = mod_recover(); 1257 if (retcode != CLIENT_SUCCESS) { 1258 CLIENT_FPUTS( 1259 gettext("Recovery of systems configuration " 1260 "failed. Manual intervention of " 1261 "config files is required.\n"), 1262 stderr); 1263 } 1264 (void) __ns_ldap_freeError(&errorp); 1265 reset_ret = start_services(START_RESET); 1266 if (reset_ret != CLIENT_SUCCESS) { 1267 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 1268 "starting services during reset\n"), 1269 reset_ret); 1270 } 1271 return (CLIENT_ERR_FAIL); 1272 } 1273 1274 if ((domain_fp = open(DOMAINNAME, O_WRONLY|O_CREAT|O_TRUNC, 1275 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1) { /* 0644 */ 1276 CLIENT_FPRINTF(stderr, gettext("Cannot open %s\n"), DOMAINNAME); 1277 retcode = mod_recover(); 1278 if (retcode != CLIENT_SUCCESS) { 1279 CLIENT_FPUTS( 1280 gettext("Recovery of systems configuration " 1281 "failed! Machine needs to be " 1282 "fixed!\n"), 1283 stderr); 1284 } 1285 reset_ret = start_services(START_RESET); 1286 if (reset_ret != CLIENT_SUCCESS) { 1287 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 1288 "starting services during reset\n"), 1289 reset_ret); 1290 } 1291 return (CLIENT_ERR_FAIL); 1292 } 1293 (void) write(domain_fp, dname, strlen(dname)); 1294 (void) write(domain_fp, "\n", 1); 1295 (void) close(domain_fp); 1296 1297 retcode = start_services(START_INIT); 1298 1299 if (retcode == CLIENT_SUCCESS) { 1300 CLIENT_FPUTS(gettext("System successfully configured\n"), 1301 stderr); 1302 } else { 1303 CLIENT_FPUTS(gettext("Error resetting system.\n" 1304 "Recovering old system settings.\n"), stderr), 1305 1306 /* stop any started services for recover */ 1307 /* don't stomp on history of saved services state */ 1308 reset_ret = stop_services(STATE_NOSAVE); 1309 if (reset_ret != CLIENT_SUCCESS) { 1310 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 1311 "stopping services during reset\n"), 1312 reset_ret); 1313 /* Coninue and try to recover what we can */ 1314 } 1315 reset_ret = mod_recover(); 1316 if (reset_ret != CLIENT_SUCCESS) { 1317 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 1318 "recovering service files during " 1319 "reset\n"), reset_ret); 1320 /* Continue and start what we can */ 1321 } 1322 reset_ret = start_services(START_RESET); 1323 if (reset_ret != CLIENT_SUCCESS) { 1324 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 1325 "starting services during reset\n"), 1326 reset_ret); 1327 } 1328 } 1329 1330 /* Cleanup temporary files created by mod_backup() */ 1331 mod_cleanup(); 1332 1333 return (retcode); 1334 } 1335 1336 1337 static int 1338 client_genProfile(clientopts_t *arglist) 1339 { 1340 int counter; 1341 int retcode; /* required for LDAP_SET_PARAM macro */ 1342 ns_ldap_error_t *errorp; 1343 1344 if (mode_verbose) 1345 CLIENT_FPUTS(gettext("About to generate a profile\n"), stderr); 1346 1347 /* *** Check for invalid args *** */ 1348 LDAP_CHECK_INVALID(arglist->proxyDN, "proxyDN"); 1349 LDAP_CHECK_INVALID(arglist->proxyPassword, "proxyPassword"); 1350 LDAP_CHECK_INVALID(arglist->enableShadowUpdate, 1351 "enableShadowUpdate"); 1352 LDAP_CHECK_INVALID(arglist->adminDN, "adminDN"); 1353 LDAP_CHECK_INVALID(arglist->adminPassword, "adminPassword"); 1354 LDAP_CHECK_INVALID(arglist->certificatePath, "certificatePath"); 1355 LDAP_CHECK_INVALID(arglist->domainName, "domainName"); 1356 LDAP_CHECK_INVALID(arglist->bindDN, "bind DN"); 1357 LDAP_CHECK_INVALID(arglist->bindPasswd, "bind password"); 1358 /* *** End check for invalid args *** */ 1359 1360 if (arglist->profileName == NULL) { 1361 if (mode_verbose) 1362 CLIENT_FPUTS( 1363 gettext("No profile specified. " 1364 "Using \"default\"\n"), 1365 stderr); 1366 arglist->profileName = "default"; 1367 } 1368 1369 __ns_ldap_setServer(TRUE); 1370 __ns_ldap_default_config(); 1371 1372 /* Set version to latest (not version 1) */ 1373 LDAP_SET_PARAM(NS_LDAP_VERSION, NS_LDAP_FILE_VERSION_P); 1374 1375 /* Set additional valid params from command line */ 1376 LDAP_SET_PARAM(arglist->authenticationMethod, NS_LDAP_AUTH_P); 1377 LDAP_SET_PARAM(arglist->defaultSearchBase, NS_LDAP_SEARCH_BASEDN_P); 1378 LDAP_SET_PARAM(arglist->credentialLevel, NS_LDAP_CREDENTIAL_LEVEL_P); 1379 LDAP_SET_PARAM(arglist->profileTTL, NS_LDAP_CACHETTL_P); 1380 LDAP_SET_PARAM(arglist->searchTimeLimit, NS_LDAP_SEARCH_TIME_P); 1381 LDAP_SET_PARAM(arglist->preferredServerList, NS_LDAP_SERVER_PREF_P); 1382 LDAP_SET_PARAM(arglist->profileName, NS_LDAP_PROFILE_P); 1383 LDAP_SET_PARAM(arglist->followReferrals, NS_LDAP_SEARCH_REF_P); 1384 LDAP_SET_PARAM(arglist->defaultSearchScope, NS_LDAP_SEARCH_SCOPE_P); 1385 LDAP_SET_PARAM(arglist->bindTimeLimit, NS_LDAP_BIND_TIME_P); 1386 LDAP_SET_PARAM(arglist->defaultServerList, NS_LDAP_SERVERS_P); 1387 1388 for (counter = 0; 1389 counter < arglist->serviceAuthenticationMethod->count; 1390 counter++) { 1391 1392 LDAP_SET_PARAM( 1393 arglist->serviceAuthenticationMethod->optlist[counter], 1394 NS_LDAP_SERVICE_AUTH_METHOD_P); 1395 } 1396 for (counter = 0; 1397 counter < arglist->serviceCredentialLevel->count; 1398 counter++) { 1399 1400 LDAP_SET_PARAM( 1401 arglist->serviceCredentialLevel->optlist[counter], 1402 NS_LDAP_SERVICE_CRED_LEVEL_P); 1403 } 1404 for (counter = 0; 1405 counter < arglist->objectclassMap->count; 1406 counter++) { 1407 1408 LDAP_SET_PARAM( 1409 arglist->objectclassMap->optlist[counter], 1410 NS_LDAP_OBJECTCLASSMAP_P); 1411 } 1412 for (counter = 0; 1413 counter < arglist->attributeMap->count; 1414 counter++) { 1415 1416 LDAP_SET_PARAM( 1417 arglist->attributeMap->optlist[counter], 1418 NS_LDAP_ATTRIBUTEMAP_P); 1419 } 1420 for (counter = 0; 1421 counter < arglist->serviceSearchDescriptor->count; 1422 counter++) { 1423 1424 LDAP_SET_PARAM( 1425 arglist->serviceSearchDescriptor->optlist[counter], 1426 NS_LDAP_SERVICE_SEARCH_DESC_P); 1427 } 1428 1429 errorp = __ns_ldap_DumpLdif(NULL); 1430 if (errorp != NULL) { 1431 CLIENT_FPUTS(errorp->message, stderr); 1432 CLIENT_FPUTC('\n', stderr); 1433 (void) __ns_ldap_freeError(&errorp); 1434 return (CLIENT_ERR_FAIL); 1435 } 1436 1437 return (CLIENT_SUCCESS); 1438 } 1439 1440 /* INET6_ADDRSTRLEN + ":" + <5-digit port> + some round-up */ 1441 #define MAX_HOSTADDR_LEN (INET6_ADDRSTRLEN + 6 + 12) 1442 1443 static int 1444 client_init(clientopts_t *arglist) 1445 { 1446 int profile_fp; 1447 int retcode = CLIENT_SUCCESS; 1448 ns_ldap_error_t *errorp; 1449 int reset_ret; 1450 int ret_copy; 1451 ns_standalone_conf_t cfg = standaloneDefaults; 1452 ns_auth_t auth = {NS_LDAP_AUTH_NONE, 1453 NS_LDAP_TLS_NONE, 1454 NS_LDAP_SASL_NONE, 1455 NS_LDAP_SASLOPT_NONE}; 1456 char peer[MAX_HOSTADDR_LEN]; 1457 ns_auth_t **authMethod; 1458 int **credLevel, i; 1459 char *cred; 1460 1461 if (mode_verbose) 1462 CLIENT_FPUTS( 1463 gettext("About to configure machine by downloading " 1464 "a profile\n"), 1465 stderr); 1466 1467 if (dname == NULL) { 1468 CLIENT_FPUTS( 1469 gettext("Init failed: System domain not set and " 1470 "no domainName specified.\n"), 1471 stderr); 1472 return (CLIENT_ERR_FAIL); 1473 } 1474 1475 if (!arglist->defaultServerList) { 1476 CLIENT_FPUTS(gettext("Missing LDAP server address\n"), stderr); 1477 return (CLIENT_ERR_FAIL); 1478 } 1479 1480 /* *** Check for invalid args *** */ 1481 LDAP_CHECK_INVALID(arglist->defaultSearchBase, 1482 "defaultSearchBase"); 1483 LDAP_CHECK_INVALID(arglist->profileTTL, 1484 "profileTTL"); 1485 LDAP_CHECK_INVALID(arglist->searchTimeLimit, 1486 "searchTimeLimit"); 1487 LDAP_CHECK_INVALID(arglist->preferredServerList, 1488 "preferredServerList"); 1489 LDAP_CHECK_INVALID(arglist->followReferrals, 1490 "followReferrals"); 1491 LDAP_CHECK_INVALID(arglist->defaultSearchScope, 1492 "defaultSearchScope"); 1493 LDAP_CHECK_INVALID(arglist->bindTimeLimit, 1494 "bindTimeLimit"); 1495 1496 LDAP_CHECK_INVALID(arglist->objectclassMap->count, 1497 "objectclassMap"); 1498 LDAP_CHECK_INVALID(arglist->attributeMap->count, 1499 "attributeMap"); 1500 LDAP_CHECK_INVALID(arglist->serviceAuthenticationMethod->count, 1501 "serviceAuthenticationMethod"); 1502 LDAP_CHECK_INVALID(arglist->serviceCredentialLevel->count, 1503 "serviceCredentialLevel"); 1504 LDAP_CHECK_INVALID(arglist->serviceSearchDescriptor->count, 1505 "serviceSearchDescriptor"); 1506 /* *** End check for invalid args *** */ 1507 1508 if (arglist->profileName == NULL) { 1509 if (mode_verbose) 1510 CLIENT_FPUTS( 1511 gettext("No profile specified. " 1512 "Using \"default\"\n"), 1513 stderr); 1514 arglist->profileName = "default"; 1515 } 1516 1517 (void) strncpy(peer, arglist->defaultServerList, MAX_HOSTADDR_LEN - 1); 1518 if (separatePort(peer, &cfg.SA_SERVER, &cfg.SA_PORT) > 0) { 1519 return (CLIENT_ERR_FAIL); 1520 } 1521 1522 if (arglist->bindDN != NULL) { 1523 cfg.SA_CRED = "proxy"; 1524 /* 1525 * We don't want to force users to always specify authentication 1526 * method when we can infer it. If users want SSL, he/she would 1527 * have to specify appropriate -a though. 1528 */ 1529 auth.type = NS_LDAP_AUTH_SIMPLE; 1530 if (arglist->bindPasswd == NULL) { 1531 arglist->bindPasswd = 1532 getpassphrase("Bind Password:"); 1533 if (arglist->bindPasswd == NULL) { 1534 CLIENT_FPUTS(gettext("Get password failed\n"), 1535 stderr); 1536 1537 if (gStartLdap == START_RESET) 1538 (void) start_service(LDAP_FMRI, B_TRUE); 1539 1540 return (CLIENT_ERR_CREDENTIAL); 1541 } 1542 } 1543 } 1544 cfg.SA_BIND_DN = arglist->bindDN; 1545 cfg.SA_BIND_PWD = arglist->bindPasswd; 1546 1547 if (arglist->authenticationMethod != NULL) { 1548 if (__ns_ldap_initAuth(arglist->authenticationMethod, 1549 &auth, &errorp) != NS_LDAP_SUCCESS) { 1550 if (errorp != NULL) { 1551 CLIENT_FPRINTF(stderr, "%s", errorp->message); 1552 (void) __ns_ldap_freeError(&errorp); 1553 } 1554 1555 if (gStartLdap == START_RESET) 1556 (void) start_service(LDAP_FMRI, B_TRUE); 1557 1558 return (CLIENT_ERR_FAIL); 1559 } 1560 cfg.SA_AUTH = &auth; 1561 } 1562 cfg.SA_CRED = arglist->credentialLevel; 1563 1564 cfg.SA_DOMAIN = arglist->domainName; 1565 cfg.SA_PROFILE_NAME = arglist->profileName; 1566 cfg.SA_CERT_PATH = arglist->certificatePath; 1567 1568 cfg.type = NS_LDAP_SERVER; 1569 1570 if (__ns_ldap_initStandalone(&cfg, &errorp) != NS_LDAP_SUCCESS) { 1571 if (errorp != NULL) { 1572 CLIENT_FPRINTF(stderr, "%s", errorp->message); 1573 (void) __ns_ldap_freeError(&errorp); 1574 } 1575 1576 if (gStartLdap == START_RESET) 1577 (void) start_service(LDAP_FMRI, B_TRUE); 1578 1579 return (CLIENT_ERR_FAIL); 1580 } 1581 1582 if (arglist->proxyDN != NULL && arglist->proxyPassword == NULL) { 1583 arglist->proxyPassword = getpassphrase("Proxy Bind Password:"); 1584 if (arglist->proxyPassword == NULL) { 1585 CLIENT_FPUTS(gettext("Get password failed\n"), stderr); 1586 1587 if (gStartLdap == START_RESET) 1588 (void) start_service(LDAP_FMRI, B_TRUE); 1589 1590 return (CLIENT_ERR_CREDENTIAL); 1591 } 1592 } 1593 if (arglist->proxyDN != NULL && arglist->proxyPassword != NULL) { 1594 if (__ns_ldap_setParam(NS_LDAP_BINDDN_P, 1595 arglist->proxyDN, &errorp) != NS_LDAP_SUCCESS) { 1596 if (errorp != NULL) { 1597 CLIENT_FPRINTF(stderr, "%s", errorp->message); 1598 (void) __ns_ldap_freeError(&errorp); 1599 } 1600 return (CLIENT_ERR_CREDENTIAL); 1601 } 1602 if (__ns_ldap_setParam(NS_LDAP_BINDPASSWD_P, 1603 arglist->proxyPassword, &errorp) != NS_LDAP_SUCCESS) { 1604 if (errorp != NULL) { 1605 CLIENT_FPRINTF(stderr, "%s", errorp->message); 1606 (void) __ns_ldap_freeError(&errorp); 1607 } 1608 return (CLIENT_ERR_CREDENTIAL); 1609 } 1610 } 1611 1612 if (arglist->enableShadowUpdate != NULL) { 1613 LDAP_SET_PARAM(arglist->enableShadowUpdate, 1614 NS_LDAP_ENABLE_SHADOW_UPDATE_P); 1615 } 1616 1617 if (arglist->enableShadowUpdate && 1618 strcasecmp(arglist->enableShadowUpdate, "TRUE") == 0 && 1619 arglist->adminDN != NULL && arglist->adminPassword == NULL) { 1620 arglist->adminPassword = getpassphrase("admin Bind Password:"); 1621 if (arglist->adminPassword == NULL) { 1622 CLIENT_FPUTS(gettext("Get password failed\n"), stderr); 1623 1624 if (gStartLdap == START_RESET) 1625 (void) start_service(LDAP_FMRI, B_TRUE); 1626 1627 return (CLIENT_ERR_CREDENTIAL); 1628 } 1629 } 1630 if (arglist->adminDN != NULL && arglist->adminPassword != NULL) { 1631 if (__ns_ldap_setParam(NS_LDAP_ADMIN_BINDDN_P, 1632 arglist->adminDN, &errorp) != NS_LDAP_SUCCESS) { 1633 if (errorp != NULL) { 1634 CLIENT_FPRINTF(stderr, "%s\n", errorp->message); 1635 (void) __ns_ldap_freeError(&errorp); 1636 } 1637 return (CLIENT_ERR_CREDENTIAL); 1638 } 1639 if (__ns_ldap_setParam(NS_LDAP_ADMIN_BINDPASSWD_P, 1640 arglist->adminPassword, &errorp) != NS_LDAP_SUCCESS) { 1641 if (errorp != NULL) { 1642 CLIENT_FPRINTF(stderr, "%s\n", errorp->message); 1643 (void) __ns_ldap_freeError(&errorp); 1644 } 1645 return (CLIENT_ERR_CREDENTIAL); 1646 } 1647 } 1648 1649 if (arglist->authenticationMethod != NULL) { 1650 if (__ns_ldap_getParam(NS_LDAP_AUTH_P, 1651 (void ***)&authMethod, &errorp) != NS_LDAP_SUCCESS) { 1652 if (errorp != NULL) { 1653 CLIENT_FPRINTF(stderr, "%s", errorp->message); 1654 (void) __ns_ldap_freeError(&errorp); 1655 } 1656 return (CLIENT_ERR_CREDENTIAL); 1657 } 1658 1659 if (authMethod != NULL) { 1660 for (i = 0; authMethod[i] != NULL; ++i) { 1661 if (authMethod[i]->type == auth.type) { 1662 break; 1663 } 1664 } 1665 1666 if (authMethod[i] == NULL) { 1667 CLIENT_FPRINTF(stderr, gettext( 1668 "Warning: init authentication method " 1669 "not found in DUAConfigProfile.\n")); 1670 } else { 1671 if (i != 0) { 1672 CLIENT_FPRINTF(stderr, 1673 gettext( 1674 "Warning: init authentication" 1675 "method using secondary " 1676 "authentication method from " 1677 "DUAConfigProfile.\n")); 1678 } 1679 } 1680 (void) __ns_ldap_freeParam((void ***) &authMethod); 1681 } 1682 } 1683 1684 if (arglist->credentialLevel != NULL) { 1685 if (__ns_ldap_getParam(NS_LDAP_CREDENTIAL_LEVEL_P, 1686 (void ***)&credLevel, &errorp) != NS_LDAP_SUCCESS) { 1687 if (errorp != NULL) { 1688 CLIENT_FPRINTF(stderr, "%s", errorp->message); 1689 (void) __ns_ldap_freeError(&errorp); 1690 } 1691 return (CLIENT_ERR_CREDENTIAL); 1692 } 1693 if (credLevel != NULL) { 1694 for (i = 0; credLevel[i] != NULL; ++i) { 1695 switch (*credLevel[i]) { 1696 case NS_LDAP_CRED_ANON : 1697 cred = "none"; 1698 break; 1699 case NS_LDAP_CRED_PROXY : 1700 cred = "proxy"; 1701 break; 1702 case NS_LDAP_CRED_SELF : 1703 cred = "self"; 1704 break; 1705 default: 1706 continue; 1707 } 1708 if (strcmp(cred, 1709 arglist->credentialLevel) == 0) { 1710 break; 1711 } 1712 } 1713 if (credLevel[i] == NULL) { 1714 CLIENT_FPRINTF(stderr, gettext( 1715 "Warning: init credential level not found " 1716 "in DUAConfigProfile.\n")); 1717 } else { 1718 if (i != 0) { 1719 CLIENT_FPRINTF(stderr, 1720 gettext("Warning: " 1721 "init credential level using " 1722 "secondary credential level from " 1723 "DUAConfigProfile.\n")); 1724 } 1725 } 1726 (void) __ns_ldap_freeParam((void ***) &credLevel); 1727 } 1728 } 1729 1730 retcode = credCheck(arglist); 1731 if (retcode == CLIENT_SUCCESS) 1732 retcode = adminCredCheck(arglist); 1733 if (retcode != CLIENT_SUCCESS) { 1734 CLIENT_FPUTS( 1735 gettext("Error in setting up credentials\n"), stderr); 1736 1737 if (gStartLdap == START_RESET) 1738 (void) start_service(LDAP_FMRI, B_TRUE); 1739 1740 return (retcode); 1741 } 1742 1743 if (mode_verbose) 1744 CLIENT_FPUTS( 1745 gettext("About to modify this machines configuration " 1746 "by writing the files\n"), 1747 stderr); 1748 1749 /* get ready to start playing with files */ 1750 retcode = stop_services(STATE_SAVE); 1751 if (retcode != CLIENT_SUCCESS) { 1752 CLIENT_FPUTS( 1753 gettext("Errors stopping network services.\n"), stderr); 1754 1755 if (gStartLdap == START_RESET) 1756 (void) start_service(LDAP_FMRI, B_TRUE); 1757 1758 return (CLIENT_ERR_FAIL); 1759 } 1760 1761 /* Save orig versions of files */ 1762 retcode = file_backup(); 1763 if (retcode == CLIENT_ERR_RESTORE) { 1764 CLIENT_FPUTS( 1765 gettext("System not in state to enable ldap client.\n"), 1766 stderr); 1767 1768 return (retcode); 1769 1770 } else if (retcode != CLIENT_SUCCESS) { 1771 CLIENT_FPUTS( 1772 gettext("Save of system configuration failed. " 1773 "Attempting recovery.\n"), 1774 stderr); 1775 retcode = recover(STATE_NOSAVE); 1776 if (retcode != CLIENT_SUCCESS) { 1777 CLIENT_FPUTS( 1778 gettext("Recovery of systems configuration " 1779 "failed. Manual intervention of " 1780 "config files is required.\n"), 1781 stderr); 1782 } 1783 1784 reset_ret = start_services(START_RESET); 1785 if (reset_ret != CLIENT_SUCCESS) { 1786 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 1787 "starting services during reset\n"), 1788 reset_ret); 1789 } 1790 1791 return (retcode); 1792 } 1793 1794 /* Dump new files */ 1795 errorp = __ns_ldap_DumpConfiguration(NSCONFIGFILE); 1796 if (NULL != errorp) { 1797 CLIENT_FPRINTF(stderr, 1798 gettext("%s init: errorp is not NULL; %s\n"), 1799 cmd, errorp->message); 1800 retcode = recover(STATE_NOSAVE); 1801 if (retcode != CLIENT_SUCCESS) { 1802 CLIENT_FPUTS( 1803 gettext("Recovery of systems configuration " 1804 "failed. Manual intervention of " 1805 "config files is required.\n"), 1806 stderr); 1807 return (CLIENT_ERR_FAIL); 1808 } 1809 (void) __ns_ldap_freeError(&errorp); 1810 reset_ret = start_services(START_RESET); 1811 if (reset_ret != CLIENT_SUCCESS) { 1812 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 1813 "starting services during reset\n"), 1814 reset_ret); 1815 } 1816 return (CLIENT_ERR_FAIL); 1817 } 1818 1819 /* if (credargs(arglist)) */ 1820 errorp = __ns_ldap_DumpConfiguration(NSCREDFILE); 1821 if (NULL != errorp) { 1822 CLIENT_FPRINTF(stderr, 1823 gettext("%s init: errorp is not NULL; %s\n"), 1824 cmd, errorp->message); 1825 retcode = recover(STATE_NOSAVE); 1826 if (retcode != CLIENT_SUCCESS) { 1827 CLIENT_FPUTS( 1828 gettext("Recovery of systems configuration " 1829 "failed. Manual intervention of " 1830 "config files is required.\n"), 1831 stderr); 1832 return (CLIENT_ERR_FAIL); 1833 } 1834 (void) __ns_ldap_freeError(&errorp); 1835 reset_ret = start_services(START_RESET); 1836 if (reset_ret != CLIENT_SUCCESS) { 1837 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 1838 "starting services during reset\n"), 1839 reset_ret); 1840 } 1841 return (CLIENT_ERR_FAIL); 1842 } 1843 1844 ret_copy = system(CMD_CP " " NSSWITCH_LDAP " " NSSWITCH_CONF); 1845 if (ret_copy != 0) { 1846 CLIENT_FPRINTF(stderr, 1847 gettext("Error %d copying (%s) -> (%s)\n"), 1848 ret_copy, NSSWITCH_LDAP, NSSWITCH_CONF); 1849 retcode = recover(STATE_NOSAVE); 1850 if (retcode != CLIENT_SUCCESS) { 1851 CLIENT_FPUTS( 1852 gettext("Recovery of systems configuration " 1853 "failed. Manual intervention of " 1854 "config files is required.\n"), 1855 stderr); 1856 } 1857 reset_ret = start_services(START_RESET); 1858 if (reset_ret != CLIENT_SUCCESS) { 1859 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 1860 "starting services during reset\n"), 1861 reset_ret); 1862 } 1863 return (CLIENT_ERR_FAIL); 1864 } 1865 1866 if ((profile_fp = open(DOMAINNAME, O_WRONLY|O_CREAT|O_TRUNC, 1867 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1) { /* 0644 */ 1868 CLIENT_FPRINTF(stderr, gettext("Cannot open %s\n"), DOMAINNAME); 1869 retcode = recover(STATE_NOSAVE); 1870 if (retcode != CLIENT_SUCCESS) { 1871 CLIENT_FPUTS( 1872 gettext("Recovery of systems configuration " 1873 "failed. Manual intervention of " 1874 "config files is required.\n"), 1875 stderr); 1876 return (CLIENT_ERR_FAIL); 1877 } 1878 reset_ret = start_services(START_RESET); 1879 if (reset_ret != CLIENT_SUCCESS) { 1880 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 1881 "starting services during reset\n"), 1882 reset_ret); 1883 } 1884 return (CLIENT_ERR_FAIL); 1885 } 1886 (void) write(profile_fp, dname, strlen(dname)); 1887 (void) write(profile_fp, "\n", 1); 1888 (void) close(profile_fp); 1889 1890 retcode = start_services(START_INIT); 1891 1892 if (retcode == CLIENT_SUCCESS) { 1893 CLIENT_FPUTS(gettext("System successfully configured\n"), 1894 stderr); 1895 } else { 1896 CLIENT_FPUTS(gettext("Error resetting system.\n" 1897 "Recovering old system settings.\n"), stderr), 1898 1899 /* stop any started services for recover */ 1900 /* don't stomp on history of saved services state */ 1901 reset_ret = stop_services(STATE_NOSAVE); 1902 if (reset_ret != CLIENT_SUCCESS) { 1903 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 1904 "stopping services during reset\n"), 1905 reset_ret); 1906 /* Coninue and try to recover what we can */ 1907 } 1908 reset_ret = recover(STATE_NOSAVE); 1909 if (reset_ret != CLIENT_SUCCESS) { 1910 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 1911 "recovering service files during " 1912 "reset\n"), reset_ret); 1913 /* Continue and start what we can */ 1914 } 1915 reset_ret = start_services(START_RESET); 1916 if (reset_ret != CLIENT_SUCCESS) { 1917 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 1918 "starting services during reset\n"), 1919 reset_ret); 1920 } 1921 } 1922 1923 return (retcode); 1924 } 1925 1926 1927 static void 1928 usage(void) 1929 { 1930 if (mode_quiet) 1931 return; 1932 1933 if (gen == 0) { 1934 CLIENT_FPRINTF(stderr, 1935 gettext("Usage: %s [-v | -q] init | manual | mod | " 1936 "list | uninit [<args>]\n"), 1937 cmd); 1938 1939 CLIENT_FPRINTF(stderr, 1940 gettext("\n %s [-v | -q] [-a authenticationMethod]" 1941 " [-D bindDN]\n\t[-w bindPassword] [-j passswdFile]" 1942 " [-y proxyPasswordFile]\n\t" 1943 "[-z adminPasswordFile] init [<args>]\n"), 1944 cmd); 1945 1946 CLIENT_FPUTS( 1947 gettext("\nSet up a server or workstation as a " 1948 "client of an LDAP namespace.\n"), 1949 stderr); 1950 } else { /* genprofile */ 1951 CLIENT_FPRINTF(stderr, 1952 gettext("Usage: %s [-v | -q] genprofile " 1953 "-a profileName=<name> " 1954 "-a defaultSearchBase=<base> <args>\n"), 1955 cmd); 1956 1957 CLIENT_FPUTS( 1958 gettext("\nGenerate a profile used to set up clients " 1959 "of an LDAP namespace.\n"), 1960 stderr); 1961 } 1962 CLIENT_FPUTS( 1963 gettext("<args> take the form of \'-a attrName=attrVal\' as " 1964 "described in the\n"), 1965 stderr); 1966 CLIENT_FPUTS(gettext("man page: ldapclient(1M)\n"), stderr); 1967 } 1968 1969 1970 /* 1971 * stop_services is called to stop network services prior to their 1972 * config files being moved/changed. In case a later recovery is needed 1973 * (an error occurs during config), we detect whether the service is 1974 * running and store that info so that a reset will only start services 1975 * that were stopped here. 1976 * 1977 * In terms of SMF, this translates to disabling the services. So we 1978 * try to disable them if they are in any other state 1979 * 1980 * Stop order : 1981 * sendmail, nscd, autofs, ldap.client, nisd (rpc), inetinit(domainname) 1982 */ 1983 static int 1984 stop_services(int saveState) 1985 { 1986 int ret; 1987 1988 if (mode_verbose) { 1989 CLIENT_FPUTS(gettext("Stopping network services\n"), stderr); 1990 } 1991 1992 if (!is_service(SENDMAIL_FMRI, SCF_STATE_STRING_DISABLED)) { 1993 if (mode_verbose) 1994 CLIENT_FPUTS(gettext("Stopping sendmail\n"), stderr); 1995 ret = disable_service(SENDMAIL_FMRI, B_TRUE); 1996 if (ret != CLIENT_SUCCESS) { 1997 /* Not serious, but tell user what to do */ 1998 CLIENT_FPRINTF(stderr, gettext("Stopping sendmail " 1999 "failed with (%d). You may need to restart " 2000 "it manually for changes to take effect.\n"), 2001 ret); 2002 } else enableFlag |= SENDMAIL_ON; 2003 } else { 2004 if (mode_verbose) 2005 CLIENT_FPUTS(gettext("sendmail not running\n"), stderr); 2006 } 2007 2008 if (!is_service(NSCD_FMRI, SCF_STATE_STRING_DISABLED)) { 2009 if (mode_verbose) 2010 CLIENT_FPUTS(gettext("Stopping nscd\n"), stderr); 2011 ret = disable_service(NSCD_FMRI, B_TRUE); 2012 if (ret != CLIENT_SUCCESS) { 2013 CLIENT_FPRINTF(stderr, gettext("Stopping nscd " 2014 "failed with (%d)\n"), ret); 2015 return (CLIENT_ERR_FAIL); 2016 } else enableFlag |= NSCD_ON; 2017 } else { 2018 if (mode_verbose) 2019 CLIENT_FPUTS(gettext("nscd not running\n"), stderr); 2020 } 2021 2022 if (!is_service(AUTOFS_FMRI, SCF_STATE_STRING_DISABLED)) { 2023 if (mode_verbose) 2024 CLIENT_FPUTS(gettext("Stopping autofs\n"), stderr); 2025 ret = disable_service(AUTOFS_FMRI, B_TRUE); 2026 if (ret != CLIENT_SUCCESS) { 2027 /* Not serious, but tell user what to do */ 2028 CLIENT_FPRINTF(stderr, gettext("Stopping autofs " 2029 "failed with (%d). You may need to restart " 2030 "it manually for changes to take effect.\n"), 2031 ret); 2032 } else enableFlag |= AUTOFS_ON; 2033 } else { 2034 if (mode_verbose) 2035 CLIENT_FPUTS(gettext("autofs not running\n"), stderr); 2036 } 2037 2038 if (!is_service(LDAP_FMRI, SCF_STATE_STRING_DISABLED)) { 2039 if (saveState) 2040 gStartLdap = START_RESET; 2041 if (mode_verbose) 2042 CLIENT_FPUTS(gettext("Stopping ldap\n"), stderr); 2043 ret = disable_service(LDAP_FMRI, B_TRUE); 2044 if (ret != CLIENT_SUCCESS) { 2045 CLIENT_FPRINTF(stderr, gettext("Stopping ldap " 2046 "failed with (%d)\n"), ret); 2047 return (CLIENT_ERR_FAIL); 2048 } 2049 } else { 2050 if (mode_verbose) 2051 CLIENT_FPUTS(gettext("ldap not running\n"), 2052 stderr); 2053 } 2054 2055 if (!is_service(YP_FMRI, SCF_STATE_STRING_DISABLED)) { 2056 if (saveState) 2057 gStartYp = START_RESET; 2058 if (mode_verbose) 2059 CLIENT_FPUTS(gettext("Stopping nis(yp)\n"), stderr); 2060 ret = disable_service(YP_FMRI, B_TRUE); 2061 if (ret != 0) { 2062 CLIENT_FPRINTF(stderr, gettext("Stopping nis(yp) " 2063 "failed with (%d)\n"), ret); 2064 return (CLIENT_ERR_FAIL); 2065 } 2066 } else { 2067 if (mode_verbose) 2068 CLIENT_FPUTS(gettext("nis(yp) not running\n"), 2069 stderr); 2070 } 2071 2072 return (CLIENT_SUCCESS); 2073 } 2074 2075 /* 2076 * start_services is called to start up network services after config 2077 * files have all been setup or recovered. In the case of an error, the 2078 * files will be recovered and start_services will be called with the 2079 * "reset" flag set so that only those services that were earlier stopped 2080 * will be started. If it is not a reset, then the services associated 2081 * with files "recovered" will attempt to be started. 2082 */ 2083 static int 2084 start_services(int flag) 2085 { 2086 int sysret, retcode = CLIENT_SUCCESS, rc = NS_LDAP_SUCCESS; 2087 FILE *domain_fp; 2088 char domainname[BUFSIZ]; 2089 char cmd_domain_start[BUFSIZ]; 2090 int domainlen; 2091 ns_ldap_self_gssapi_config_t config = NS_LDAP_SELF_GSSAPI_CONFIG_NONE; 2092 ns_ldap_error_t *errorp = NULL; 2093 2094 if (mode_verbose) { 2095 CLIENT_FPUTS(gettext("Starting network services\n"), stderr); 2096 } 2097 2098 /* Read in current defaultdomain so we can set it */ 2099 domain_fp = fopen(DOMAINNAME, "r"); 2100 if (domain_fp == NULL) { 2101 CLIENT_FPRINTF(stderr, gettext("Error opening defaultdomain " 2102 "(%d)\n"), errno); 2103 /* if we did an ldap init, we must have domain */ 2104 if (flag == START_INIT) 2105 return (CLIENT_ERR_FAIL); 2106 } else { 2107 if (fgets(domainname, BUFSIZ, domain_fp) == NULL) { 2108 CLIENT_FPUTS(gettext("Error reading defaultdomain\n"), 2109 stderr); 2110 return (CLIENT_ERR_FAIL); 2111 } 2112 2113 if (fclose(domain_fp) != 0) { 2114 CLIENT_FPRINTF(stderr, 2115 gettext("Error closing defaultdomain (%d)\n"), 2116 errno); 2117 return (CLIENT_ERR_FAIL); 2118 } 2119 domainlen = strlen(domainname); 2120 /* sanity check to make sure sprintf will fit */ 2121 if (domainlen > (BUFSIZE - sizeof (CMD_DOMAIN_START) - 2122 sizeof (TO_DEV_NULL) - 3)) { 2123 CLIENT_FPUTS(gettext("Specified domainname is " 2124 "too large\n"), stderr); 2125 return (CLIENT_ERR_FAIL); 2126 } 2127 if (domainname[domainlen-1] == '\n') 2128 domainname[domainlen-1] = 0; 2129 /* buffer size is checked above */ 2130 (void) snprintf(cmd_domain_start, BUFSIZ, "%s %s %s", 2131 CMD_DOMAIN_START, domainname, TO_DEV_NULL); 2132 } 2133 2134 /* 2135 * We can be starting services after an init in which case 2136 * we want to start ldap and not start yp. 2137 */ 2138 if (flag == START_INIT) { 2139 sysret = system(cmd_domain_start); 2140 if (mode_verbose) 2141 CLIENT_FPRINTF(stderr, "start: %s %s... %s\n", 2142 CMD_DOMAIN_START, domainname, 2143 (sysret == 0) ? gettext("success") : 2144 gettext("failed")); 2145 if (sysret != 0) { 2146 CLIENT_FPRINTF(stderr, gettext("\"%s\" returned: %d\n"), 2147 CMD_DOMAIN_START, sysret); 2148 2149 retcode = CLIENT_ERR_FAIL; 2150 } 2151 2152 if ((rc = __ns_ldap_self_gssapi_config(&config)) != 2153 NS_LDAP_SUCCESS) { 2154 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 2155 "checking sasl/GSSAPI configuration\n"), 2156 rc); 2157 retcode = CLIENT_ERR_FAIL; 2158 } 2159 2160 if (config != NS_LDAP_SELF_GSSAPI_CONFIG_NONE) { 2161 2162 rc = __ns_ldap_check_dns_preq( 2163 1, mode_verbose, mode_quiet, 2164 NSSWITCH_LDAP, config, &errorp); 2165 if (errorp) 2166 (void) __ns_ldap_freeError(&errorp); 2167 2168 if (rc != NS_LDAP_SUCCESS) 2169 retcode = CLIENT_ERR_FAIL; 2170 } 2171 2172 if (rc == NS_LDAP_SUCCESS && 2173 start_service(LDAP_FMRI, B_TRUE) != CLIENT_SUCCESS) 2174 retcode = CLIENT_ERR_FAIL; 2175 2176 if (config != NS_LDAP_SELF_GSSAPI_CONFIG_NONE && 2177 rc == NS_LDAP_SUCCESS && retcode == CLIENT_SUCCESS) { 2178 rc = __ns_ldap_check_gssapi_preq( 2179 1, mode_verbose, mode_quiet, config, 2180 &errorp); 2181 if (errorp) 2182 (void) __ns_ldap_freeError(&errorp); 2183 2184 if (rc != NS_LDAP_SUCCESS) 2185 retcode = CLIENT_ERR_FAIL; 2186 2187 } 2188 /* No YP after init */ 2189 /* 2190 * Or we can be starting services after an uninit or error 2191 * recovery. We want to start whatever services were running 2192 * before. In the case of error recovery, it is the services 2193 * that were running before we stopped them (flags set in 2194 * stop_services). If it is an uninit then we determine 2195 * which services to start based on the files we recovered 2196 * (flags set in recover). 2197 */ 2198 } else { 2199 /* uninit and recover should set flags of what to start */ 2200 if (domain_fp) { 2201 sysret = system(cmd_domain_start); 2202 if (mode_verbose) 2203 CLIENT_FPRINTF(stderr, "start: %s %s... %s\n", 2204 CMD_DOMAIN_START, domainname, 2205 (sysret == 0) ? gettext("success") : 2206 gettext("failed")); 2207 if (sysret != 0) { 2208 CLIENT_FPRINTF(stderr, gettext("\"%s\" " 2209 "returned: %d\n"), 2210 CMD_DOMAIN_START, sysret); 2211 2212 retcode = CLIENT_ERR_FAIL; 2213 } 2214 } 2215 2216 if (gStartLdap == flag) { 2217 if (!(is_service(LDAP_FMRI, SCF_STATE_STRING_ONLINE))) 2218 if (start_service(LDAP_FMRI, B_TRUE) 2219 != CLIENT_SUCCESS) 2220 retcode = CLIENT_ERR_FAIL; 2221 } 2222 2223 if (gStartYp == flag) { 2224 if (!(is_service(YP_FMRI, SCF_STATE_STRING_ONLINE))) 2225 (void) start_service(YP_FMRI, B_TRUE); 2226 } 2227 } 2228 if ((enableFlag & AUTOFS_ON) && 2229 !(is_service(AUTOFS_FMRI, SCF_STATE_STRING_ONLINE))) 2230 (void) start_service(AUTOFS_FMRI, B_TRUE); 2231 2232 if ((enableFlag & NSCD_ON) && 2233 !(is_service(NSCD_FMRI, SCF_STATE_STRING_ONLINE))) 2234 (void) start_service(NSCD_FMRI, B_TRUE); 2235 2236 #if 0 2237 if (flag == START_INIT && config != NS_LDAP_SELF_GSSAPI_CONFIG_NONE && 2238 retcode == CLIENT_SUCCESS && 2239 !(is_service(NSCD_FMRI, SCF_STATE_STRING_ONLINE))) { 2240 CLIENT_FPRINTF(stderr, "start: %s\n", 2241 gettext("self/sasl/GSSAPI is configured" 2242 " but nscd is not online")); 2243 retcode = CLIENT_ERR_FAIL; 2244 } 2245 #endif 2246 2247 if ((enableFlag & SENDMAIL_ON) && 2248 !(is_service(SENDMAIL_FMRI, SCF_STATE_STRING_ONLINE))) 2249 (void) start_service(SENDMAIL_FMRI, B_TRUE); 2250 2251 /* 2252 * Restart name-service milestone so that any consumer 2253 * which depends on it will be restarted. 2254 */ 2255 (void) restart_service(NS_MILESTONE_FMRI, B_TRUE); 2256 return (retcode); 2257 } 2258 2259 /* 2260 * credCheck is called to check if credentials are required for this 2261 * configuration. Currently, this means that if any credentialLevel is 2262 * proxy and any authenticationMethod is something other than none, then 2263 * credential info is required (proxyDN and proxyPassword). 2264 */ 2265 static int 2266 credCheck(clientopts_t *arglist) 2267 { 2268 int counter; 2269 int **credLevel; 2270 ns_auth_t **authMethod; 2271 char **proxyDN, **proxyPassword; 2272 ns_ldap_error_t *errorp; 2273 int credProxy, authNotNone; 2274 int retcode; 2275 2276 /* If credentialLevel is proxy, make sure we have proxyDN and proxyPassword */ 2277 retcode = __ns_ldap_getParam(NS_LDAP_CREDENTIAL_LEVEL_P, 2278 (void ***)&credLevel, &errorp); 2279 if (retcode != 0) { 2280 CLIENT_FPRINTF(stderr, 2281 gettext("Error %d while trying to retrieve " 2282 "credLevel\n"), 2283 retcode); 2284 return (CLIENT_ERR_FAIL); 2285 } 2286 retcode = __ns_ldap_getParam(NS_LDAP_AUTH_P, 2287 (void ***)&authMethod, &errorp); 2288 if (retcode != 0) { 2289 CLIENT_FPRINTF(stderr, 2290 gettext("Error %d while trying to retrieve " 2291 "authMethod\n"), retcode); 2292 return (CLIENT_ERR_FAIL); 2293 } 2294 retcode = __ns_ldap_getParam(NS_LDAP_BINDDN_P, 2295 (void ***)&proxyDN, &errorp); 2296 if (retcode != 0) { 2297 CLIENT_FPRINTF(stderr, 2298 gettext("Error %d while trying to retrieve proxyDN\n"), 2299 retcode); 2300 return (CLIENT_ERR_FAIL); 2301 } 2302 retcode = __ns_ldap_getParam(NS_LDAP_BINDPASSWD_P, 2303 (void ***)&proxyPassword, &errorp); 2304 if (retcode != 0) { 2305 CLIENT_FPRINTF(stderr, 2306 gettext("Error %d while trying to retrieve " 2307 "proxyPassword\n"), retcode); 2308 return (CLIENT_ERR_FAIL); 2309 } 2310 2311 if (mode_verbose) { 2312 CLIENT_FPRINTF(stderr, 2313 gettext("Proxy DN: %s\n"), 2314 (proxyDN && proxyDN[0]) ? proxyDN[0] : "NULL"); 2315 CLIENT_FPRINTF(stderr, 2316 gettext("Proxy password: %s\n"), 2317 (proxyPassword && proxyPassword[0]) ? 2318 proxyPassword[0] : "NULL"); 2319 } 2320 2321 credProxy = 0; /* flag to indicate if we have a credLevel of proxy */ 2322 for (counter = 0; credLevel && credLevel[counter] != NULL; counter++) { 2323 if (mode_verbose) 2324 CLIENT_FPRINTF(stderr, 2325 gettext("Credential level: %d\n"), 2326 *credLevel[counter]); 2327 if (*credLevel[counter] == NS_LDAP_CRED_PROXY) { 2328 credProxy = 1; 2329 break; 2330 } 2331 } 2332 2333 authNotNone = 0; /* flag for authMethod other than none */ 2334 for (counter = 0; 2335 authMethod && authMethod[counter] != NULL; 2336 counter++) { 2337 2338 if (mode_verbose) 2339 CLIENT_FPRINTF(stderr, 2340 gettext("Authentication method: %d\n"), 2341 authMethod[counter]->type); 2342 if (authMethod[counter]->type != NS_LDAP_AUTH_NONE && 2343 !(authMethod[counter]->type == NS_LDAP_AUTH_TLS && 2344 authMethod[counter]->tlstype == NS_LDAP_TLS_NONE)) { 2345 authNotNone = 1; 2346 break; 2347 } 2348 } 2349 2350 /* First, if we don't need proxyDN/Password then just return ok */ 2351 if (!(credProxy && authNotNone)) { 2352 if (mode_verbose) 2353 CLIENT_FPUTS( 2354 gettext("No proxyDN/proxyPassword required\n"), 2355 stderr); 2356 return (CLIENT_SUCCESS); 2357 } 2358 2359 /* Now let's check if we have the cred stuff we need */ 2360 if (!proxyDN || !proxyDN[0]) { 2361 CLIENT_FPUTS( 2362 gettext("credentialLevel is proxy and no proxyDN " 2363 "specified\n"), 2364 stderr); 2365 return (CLIENT_ERR_CREDENTIAL); 2366 } 2367 2368 /* If we need proxyPassword (prompt) */ 2369 if (!proxyPassword || !proxyPassword[0]) { 2370 CLIENT_FPUTS( 2371 gettext("credentialLevel requires proxyPassword\n"), 2372 stderr); 2373 arglist->proxyPassword = getpassphrase("Proxy Bind Password:"); 2374 if (arglist->proxyPassword == NULL) { 2375 CLIENT_FPUTS(gettext("Get password failed\n"), stderr); 2376 return (CLIENT_ERR_CREDENTIAL); 2377 } 2378 LDAP_SET_PARAM(arglist->proxyPassword, NS_LDAP_BINDPASSWD_P); 2379 if (retcode != 0) { 2380 CLIENT_FPUTS( 2381 gettext("setParam proxyPassword failed.\n"), 2382 stderr); 2383 return (CLIENT_ERR_CREDENTIAL); 2384 } 2385 } 2386 2387 return (CLIENT_SUCCESS); 2388 } 2389 2390 /* 2391 * adminCredCheck is called to check if the admin credential is required 2392 * for this configuration. This means that if enableShadowUpdate is set 2393 * to TRUE then credential info is required (adminDN and adminPassword). 2394 * One exception is that if there is a 'self' credentialLevel and 2395 * 'sasl/GSSAPI' authenticationMethod (i.e., possibly using Kerberos 2396 * host credential) then adminDN and adminPassword are not required. 2397 */ 2398 static int 2399 adminCredCheck(clientopts_t *arglist) 2400 { 2401 int counter; 2402 int **enabled = NULL; 2403 int **credLevel = NULL; 2404 char **adminDN = NULL; 2405 char **adminPassword = NULL; 2406 ns_auth_t **authMethod = NULL; 2407 ns_ldap_error_t *errorp = NULL; 2408 int credSelf, authSASLgss; 2409 int retcode, rc; 2410 2411 /* If shadow update not enabled, then no need to check */ 2412 retcode = __ns_ldap_getParam(NS_LDAP_ENABLE_SHADOW_UPDATE_P, 2413 (void ***)&enabled, &errorp); 2414 if (retcode != 0) { 2415 CLIENT_FPRINTF(stderr, 2416 gettext("Error %d while trying to retrieve " 2417 "enableShadowUpdate\n"), retcode); 2418 rc = CLIENT_ERR_FAIL; 2419 goto out; 2420 } 2421 if (enabled == NULL || 2422 *enabled[0] != NS_LDAP_ENABLE_SHADOW_UPDATE_TRUE) { 2423 if (mode_verbose) 2424 CLIENT_FPUTS( 2425 gettext("Shadow Update is not enabled, " 2426 "no adminDN/adminPassword is required.\n"), stderr); 2427 rc = CLIENT_SUCCESS; 2428 goto out; 2429 } 2430 2431 /* get credentialLevel */ 2432 retcode = __ns_ldap_getParam(NS_LDAP_CREDENTIAL_LEVEL_P, 2433 (void ***)&credLevel, &errorp); 2434 if (retcode != 0) { 2435 CLIENT_FPRINTF(stderr, 2436 gettext("Error %d while trying to retrieve credLevel\n"), 2437 retcode); 2438 rc = CLIENT_ERR_FAIL; 2439 goto out; 2440 } 2441 2442 /* get AuthenticationMethod */ 2443 retcode = __ns_ldap_getParam(NS_LDAP_AUTH_P, 2444 (void ***)&authMethod, &errorp); 2445 if (retcode != 0) { 2446 CLIENT_FPRINTF(stderr, 2447 gettext("Error %d while trying to retrieve authMethod\n"), 2448 retcode); 2449 rc = CLIENT_ERR_FAIL; 2450 goto out; 2451 } 2452 2453 /* get adminDN */ 2454 retcode = __ns_ldap_getParam(NS_LDAP_ADMIN_BINDDN_P, 2455 (void ***)&adminDN, &errorp); 2456 if (retcode != 0) { 2457 CLIENT_FPRINTF(stderr, 2458 gettext("Error %d while trying to retrieve adminDN\n"), 2459 retcode); 2460 rc = CLIENT_ERR_FAIL; 2461 goto out; 2462 } 2463 2464 /* get adminPassword */ 2465 retcode = __ns_ldap_getParam(NS_LDAP_ADMIN_BINDPASSWD_P, 2466 (void ***)&adminPassword, &errorp); 2467 if (retcode != 0) { 2468 CLIENT_FPRINTF(stderr, 2469 gettext("Error %d while trying to retrieve " 2470 "adminPassword\n"), retcode); 2471 rc = CLIENT_ERR_FAIL; 2472 goto out; 2473 } 2474 2475 if (mode_verbose) { 2476 CLIENT_FPRINTF(stderr, 2477 gettext("admin DN: %s\n"), 2478 (adminDN && adminDN[0]) ? adminDN[0] : "NULL"); 2479 CLIENT_FPRINTF(stderr, 2480 gettext("admin password: %s\n"), 2481 (adminPassword && adminPassword[0]) ? 2482 adminPassword[0] : "NULL"); 2483 } 2484 2485 credSelf = 0; /* flag to indicate if we have a credLevel of self */ 2486 for (counter = 0; credLevel && credLevel[counter] != NULL; counter++) { 2487 if (mode_verbose) 2488 CLIENT_FPRINTF(stderr, 2489 gettext("Credential level: %d\n"), 2490 *credLevel[counter]); 2491 if (*credLevel[counter] == NS_LDAP_CRED_SELF) { 2492 credSelf = 1; 2493 break; 2494 } 2495 } 2496 2497 authSASLgss = 0; /* flag for authMethod of SASL/gssapi */ 2498 for (counter = 0; 2499 authMethod && authMethod[counter] != NULL; 2500 counter++) { 2501 2502 if (mode_verbose) 2503 CLIENT_FPRINTF(stderr, 2504 gettext("Authentication sasl mechanism: %d\n"), 2505 authMethod[counter]->saslmech); 2506 if (authMethod[counter]->saslmech == NS_LDAP_SASL_GSSAPI) { 2507 authSASLgss = 1; 2508 break; 2509 } 2510 } 2511 2512 /* First, if we don't need adminDN/adminPassword then just return ok */ 2513 if (credSelf && authSASLgss) { 2514 if (mode_verbose) 2515 CLIENT_FPUTS( 2516 gettext("A credential Level of self and an " 2517 "authentication method of sasl/GSSAPI is " 2518 "configured, no adminDN/adminPassword " 2519 "is required.\n"), stderr); 2520 rc = CLIENT_SUCCESS; 2521 goto out; 2522 } 2523 2524 /* Now let's check if we have the cred stuff we need */ 2525 if (adminDN == NULL || adminDN[0] == '\0') { 2526 CLIENT_FPUTS( 2527 gettext("Shadow Update is enabled, but " 2528 "no adminDN is configured.\n"), stderr); 2529 rc = CLIENT_ERR_CREDENTIAL; 2530 goto out; 2531 } 2532 2533 /* If we need adminPassword (prompt) */ 2534 if (adminPassword == NULL || adminPassword[0] == '\0') { 2535 CLIENT_FPUTS( 2536 gettext("Shadow Update requires adminPassword\n"), 2537 stderr); 2538 arglist->adminPassword = getpassphrase("admin Password:"); 2539 if (arglist->adminPassword == NULL) { 2540 CLIENT_FPUTS(gettext("Unable to get admin password\n"), 2541 stderr); 2542 rc = CLIENT_ERR_CREDENTIAL; 2543 goto out; 2544 } 2545 LDAP_SET_PARAM(arglist->adminPassword, 2546 NS_LDAP_ADMIN_BINDPASSWD_P); 2547 if (retcode != 0) { 2548 CLIENT_FPUTS( 2549 gettext("setParam adminPassword failed.\n"), 2550 stderr); 2551 rc = CLIENT_ERR_CREDENTIAL; 2552 goto out; 2553 } 2554 } 2555 2556 rc = CLIENT_SUCCESS; 2557 2558 out: 2559 if (enabled != NULL) 2560 (void) __ns_ldap_freeParam((void ***)&enabled); 2561 if (credLevel != NULL) 2562 (void) __ns_ldap_freeParam((void ***)&credLevel); 2563 if (authMethod != NULL) 2564 (void) __ns_ldap_freeParam((void ***)&authMethod); 2565 if (adminDN != NULL) 2566 (void) __ns_ldap_freeParam((void ***)&adminDN); 2567 if (adminPassword != NULL) 2568 (void) __ns_ldap_freeParam((void ***)&adminPassword); 2569 2570 return (rc); 2571 } 2572 2573 /* 2574 * try to restore the previous name space on this machine 2575 */ 2576 static int 2577 recover(int saveState) 2578 { 2579 struct stat buf; 2580 int stat_ret, retcode, fd; 2581 int domain = 0, domainlen; 2582 char yp_dir[BUFSIZE], yp_dir_back[BUFSIZE]; 2583 char name[BUFSIZ]; 2584 char *ldap_conf_file, *ldap_cred_file; 2585 char ldap_file_back[BUFSIZE], ldap_cred_back[BUFSIZE]; 2586 2587 /* If running as Sysid Install become a no-op */ 2588 if (sysid_install == B_TRUE) 2589 return (CLIENT_SUCCESS); 2590 2591 stat_ret = stat(LDAP_RESTORE_DIR, &buf); 2592 if (stat_ret != 0) { 2593 CLIENT_FPUTS( 2594 gettext("Cannot recover. No backup files " 2595 "found.\n"), 2596 stderr); 2597 CLIENT_FPUTS( 2598 gettext("\t Either this machine was not initialized\n"), 2599 stderr); 2600 CLIENT_FPUTS( 2601 gettext("\t by ldapclient or the backup files " 2602 "have been\n"), 2603 stderr); 2604 CLIENT_FPUTS( 2605 gettext("\t removed manually or with an \"uninit\"\n"), 2606 stderr); 2607 return (CLIENT_ERR_RESTORE); /* invalid backup */ 2608 } 2609 2610 /* 2611 * Get domainname. Allow no domainname for the case where "files" 2612 * config was backed up. 2613 */ 2614 stat_ret = stat(DOMAINNAME_BACK, &buf); 2615 if (mode_verbose) 2616 CLIENT_FPRINTF(stderr, 2617 gettext("recover: stat(%s)=%d\n"), 2618 DOMAINNAME_BACK, stat_ret); 2619 if (stat_ret == 0) { 2620 if (mode_verbose) 2621 CLIENT_FPRINTF(stderr, 2622 gettext("recover: open(%s)\n"), 2623 DOMAINNAME_BACK); 2624 fd = open(DOMAINNAME_BACK, O_RDONLY); 2625 if (mode_verbose) 2626 CLIENT_FPRINTF(stderr, 2627 gettext("recover: read(%s)\n"), 2628 DOMAINNAME_BACK); 2629 domainlen = read(fd, &(name[0]), BUFSIZ-1); 2630 (void) close(fd); 2631 if (domainlen < 0) { 2632 CLIENT_FPUTS( 2633 gettext("Cannot recover. Cannot determine " 2634 "previous domain name.\n"), 2635 stderr); 2636 return (CLIENT_ERR_RESTORE); /* invalid backup */ 2637 } else { 2638 char *ptr; 2639 2640 ptr = strchr(&(name[0]), '\n'); 2641 if (ptr != NULL) 2642 *ptr = '\0'; 2643 else 2644 name[domainlen] = '\0'; 2645 2646 if (mode_verbose) 2647 CLIENT_FPRINTF(stderr, 2648 gettext("recover: old domainname " 2649 "\"%s\"\n"), name); 2650 2651 if (strlen(name) == 0) 2652 domain = 0; 2653 else 2654 domain = 1; /* flag that we have domain */ 2655 2656 } 2657 } 2658 2659 2660 /* 2661 * we can recover at this point 2662 * remove LDAP config files before restore 2663 */ 2664 (void) unlink(NSCONFIGFILE); 2665 (void) unlink(NSCREDFILE); 2666 2667 ldap_conf_file = strrchr(NSCONFIGFILE, '/') + 1; 2668 ldap_cred_file = strrchr(NSCREDFILE, '/') + 1; 2669 2670 (void) strlcpy(ldap_file_back, LDAP_RESTORE_DIR "/", BUFSIZE); 2671 (void) strlcat(ldap_file_back, ldap_conf_file, BUFSIZE); 2672 2673 stat_ret = stat(ldap_file_back, &buf); 2674 if (mode_verbose) 2675 CLIENT_FPRINTF(stderr, 2676 gettext("recover: stat(%s)=%d\n"), 2677 ldap_file_back, stat_ret); 2678 if (stat_ret == 0) { 2679 if (saveState) 2680 gStartLdap = START_UNINIT; 2681 retcode = file_move(ldap_file_back, NSCONFIGFILE); 2682 if (mode_verbose) 2683 CLIENT_FPRINTF(stderr, 2684 gettext("recover: file_move(%s, %s)=%d\n"), 2685 ldap_file_back, NSCONFIGFILE, retcode); 2686 if (retcode != 0) 2687 CLIENT_FPRINTF(stderr, 2688 gettext("recover: file_move(%s, %s) failed\n"), 2689 ldap_file_back, NSCONFIGFILE); 2690 } 2691 2692 (void) strlcpy(ldap_cred_back, LDAP_RESTORE_DIR "/", BUFSIZE); 2693 (void) strlcat(ldap_cred_back, ldap_cred_file, BUFSIZE); 2694 2695 stat_ret = stat(ldap_cred_back, &buf); 2696 if (mode_verbose) 2697 CLIENT_FPRINTF(stderr, 2698 gettext("recover: stat(%s)=%d\n"), 2699 ldap_cred_back, stat_ret); 2700 if (stat_ret == 0) { 2701 retcode = file_move(ldap_cred_back, NSCREDFILE); 2702 if (mode_verbose) 2703 CLIENT_FPRINTF(stderr, 2704 gettext("recover: file_move(%s, %s)=%d\n"), 2705 ldap_cred_back, NSCREDFILE, retcode); 2706 if (retcode != 0) 2707 CLIENT_FPRINTF(stderr, 2708 gettext("recover: file_move(%s, %s) failed\n"), 2709 ldap_cred_back, NSCREDFILE); 2710 } 2711 2712 /* Check for recovery of NIS(YP) if we have a domainname */ 2713 if (domain) { 2714 /* "name" would have to be huge for this, but just in case */ 2715 if (strlen(name) >= (BUFSIZE - strlen(LDAP_RESTORE_DIR))) 2716 return (CLIENT_ERR_FAIL); 2717 if (strlen(name) >= (BUFSIZE - strlen(YP_BIND_DIR))) 2718 return (CLIENT_ERR_FAIL); 2719 2720 (void) strlcpy(yp_dir_back, LDAP_RESTORE_DIR "/", BUFSIZE); 2721 (void) strlcat(yp_dir_back, name, BUFSIZE); 2722 stat_ret = stat(yp_dir_back, &buf); 2723 if (mode_verbose) 2724 CLIENT_FPRINTF(stderr, 2725 gettext("recover: stat(%s)=%d\n"), 2726 yp_dir_back, stat_ret); 2727 if (stat_ret == 0) { 2728 (void) strlcpy(yp_dir, YP_BIND_DIR "/", BUFSIZE); 2729 (void) strlcat(yp_dir, name, BUFSIZE); 2730 retcode = file_move(yp_dir_back, yp_dir); 2731 if (mode_verbose) 2732 CLIENT_FPRINTF(stderr, 2733 gettext("recover: file_move(%s, " 2734 "%s)=%d\n"), 2735 yp_dir_back, yp_dir, retcode); 2736 if (retcode != 0) { 2737 CLIENT_FPRINTF(stderr, 2738 gettext("recover: file_move(%s, " 2739 "%s) failed!\n"), 2740 yp_dir_back, yp_dir); 2741 } else { 2742 if (saveState) 2743 gStartYp = START_UNINIT; 2744 } 2745 } 2746 } 2747 2748 /* restore machine configuration */ 2749 stat_ret = stat(NSSWITCH_BACK, &buf); 2750 if (mode_verbose) 2751 CLIENT_FPRINTF(stderr, 2752 gettext("recover: stat(%s)=%d\n"), 2753 NSSWITCH_BACK, stat_ret); 2754 if (stat_ret == 0) { 2755 retcode = file_move(NSSWITCH_BACK, NSSWITCH_CONF); 2756 if (mode_verbose) 2757 CLIENT_FPRINTF(stderr, 2758 gettext("recover: file_move(%s, %s)=%d\n"), 2759 NSSWITCH_BACK, NSSWITCH_CONF, retcode); 2760 if (retcode != 0) 2761 CLIENT_FPRINTF(stderr, 2762 gettext("recover: file_move(%s, %s) failed\n"), 2763 NSSWITCH_BACK, NSSWITCH_CONF); 2764 } 2765 2766 stat_ret = stat(DOMAINNAME_BACK, &buf); 2767 if (mode_verbose) 2768 CLIENT_FPRINTF(stderr, 2769 gettext("recover: stat(%s)=%d\n"), 2770 DOMAINNAME_BACK, stat_ret); 2771 if (stat_ret == 0) { 2772 retcode = file_move(DOMAINNAME_BACK, DOMAINNAME); 2773 if (mode_verbose) 2774 CLIENT_FPRINTF(stderr, 2775 gettext("recover: file_move(%s, %s)=%d\n"), 2776 DOMAINNAME_BACK, DOMAINNAME, retcode); 2777 if (retcode != 0) 2778 CLIENT_FPRINTF(stderr, 2779 gettext("recover: file_move(%s, %s) failed\n"), 2780 DOMAINNAME_BACK, DOMAINNAME); 2781 } 2782 2783 retcode = rmdir(LDAP_RESTORE_DIR); 2784 if (retcode != 0) { 2785 CLIENT_FPRINTF(stderr, 2786 gettext("Error removing \"%s\" directory.\n"), 2787 LDAP_RESTORE_DIR); 2788 } 2789 2790 return (CLIENT_SUCCESS); 2791 } 2792 2793 /* 2794 * try to save the current state of this machine. 2795 * this just overwrites any old saved configration files. 2796 * 2797 * This function should only be called after network services have been stopped. 2798 * 2799 * Returns 0 on successful save 2800 * Otherwise returns -1 2801 */ 2802 static int 2803 file_backup(void) 2804 { 2805 struct stat buf; 2806 int domain_stat, conf_stat, ldap_stat; 2807 int yp_stat, restore_stat; 2808 int retcode, namelen, ret; 2809 char yp_dir[BUFSIZ], yp_dir_back[BUFSIZ]; 2810 char name[BUFSIZ]; 2811 char *ldap_conf_file, *ldap_cred_file; 2812 char ldap_file_back[BUFSIZE], ldap_cred_back[BUFSIZE]; 2813 2814 ret = CLIENT_SUCCESS; 2815 /* If running as Sysid Install become a no-op */ 2816 if (sysid_install == B_TRUE) 2817 return (CLIENT_SUCCESS); 2818 2819 /* If existing backup files, clear for this run */ 2820 restore_stat = stat(LDAP_RESTORE_DIR, &buf); 2821 if (restore_stat == 0) { 2822 if (mode_verbose) { 2823 CLIENT_FPUTS( 2824 gettext("Removing existing restore " 2825 "directory\n"), 2826 stderr); 2827 } 2828 (void) system("/bin/rm -fr " LDAP_RESTORE_DIR); 2829 restore_stat = stat(LDAP_RESTORE_DIR, &buf); 2830 if (restore_stat == 0) { 2831 CLIENT_FPRINTF(stderr, 2832 gettext("Unable to remove backup " 2833 "directory (%s)\n"), 2834 LDAP_RESTORE_DIR); 2835 return (CLIENT_ERR_RESTORE); 2836 } 2837 } 2838 2839 retcode = mkdir(LDAP_RESTORE_DIR, 0755); 2840 if (retcode != 0) { 2841 CLIENT_FPRINTF(stderr, 2842 gettext("file_backup: Failed to make %s backup " 2843 "directory. mkdir=%d\n"), 2844 LDAP_RESTORE_DIR, retcode); 2845 return (CLIENT_ERR_FAIL); 2846 } 2847 2848 conf_stat = stat(NSSWITCH_CONF, &buf); 2849 if (mode_verbose) 2850 CLIENT_FPRINTF(stderr, 2851 gettext("file_backup: stat(%s)=%d\n"), 2852 NSSWITCH_CONF, conf_stat); 2853 if (conf_stat == 0) { 2854 if (mode_verbose) 2855 CLIENT_FPRINTF(stderr, 2856 gettext("file_backup: (%s -> %s)\n"), 2857 NSSWITCH_CONF, NSSWITCH_BACK); 2858 retcode = file_move(NSSWITCH_CONF, NSSWITCH_BACK); 2859 if (retcode != 0) { 2860 CLIENT_FPRINTF(stderr, 2861 gettext("file_backup: file_move(%s, %s) failed " 2862 "with %d\n"), 2863 NSSWITCH_CONF, NSSWITCH_BACK, retcode); 2864 ret = CLIENT_ERR_RENAME; 2865 } 2866 } else { 2867 if (mode_verbose) 2868 CLIENT_FPRINTF(stderr, 2869 gettext("file_backup: No %s file.\n"), 2870 NSSWITCH_CONF); 2871 } 2872 2873 domain_stat = stat(DOMAINNAME, &buf); 2874 if (mode_verbose) 2875 CLIENT_FPRINTF(stderr, 2876 gettext("file_backup: stat(%s)=%d\n"), 2877 DOMAINNAME, domain_stat); 2878 if ((domain_stat == 0) && (buf.st_size > 0)) { 2879 if (mode_verbose) 2880 CLIENT_FPRINTF(stderr, 2881 gettext("file_backup: (%s -> %s)\n"), 2882 DOMAINNAME, DOMAINNAME_BACK); 2883 retcode = file_move(DOMAINNAME, DOMAINNAME_BACK); 2884 if (retcode != 0) { 2885 CLIENT_FPRINTF(stderr, 2886 gettext("file_backup: file_move(%s, %s) failed " 2887 "with %d\n"), 2888 DOMAINNAME, DOMAINNAME_BACK, retcode); 2889 ret = CLIENT_ERR_RENAME; 2890 } 2891 } else { 2892 if (mode_verbose) 2893 if (domain_stat != 0) { 2894 CLIENT_FPRINTF(stderr, 2895 gettext("file_backup: No %s file.\n"), 2896 DOMAINNAME); 2897 } else { 2898 CLIENT_FPRINTF(stderr, 2899 gettext("file_backup: Empty %s " 2900 "file.\n"), 2901 DOMAINNAME); 2902 } 2903 } 2904 2905 namelen = BUFSIZ; 2906 (void) sysinfo(SI_SRPC_DOMAIN, &(name[0]), namelen); 2907 namelen = strlen(name); 2908 2909 if (mode_verbose) 2910 CLIENT_FPRINTF(stderr, 2911 gettext("file_backup: nis domain is \"%s\"\n"), 2912 (namelen > 0) ? name : "EMPTY"); 2913 /* check for domain name if not set cannot save NIS(YP) state */ 2914 if (namelen > 0) { 2915 /* moving /var/yp/binding will cause ypbind to core dump */ 2916 (void) strlcpy(yp_dir, YP_BIND_DIR "/", BUFSIZE); 2917 (void) strlcat(yp_dir, name, BUFSIZE); 2918 yp_stat = stat(yp_dir, &buf); 2919 if (mode_verbose) 2920 CLIENT_FPRINTF(stderr, 2921 gettext("file_backup: stat(%s)=%d\n"), 2922 yp_dir, yp_stat); 2923 if (yp_stat == 0) { 2924 (void) strlcpy(yp_dir_back, LDAP_RESTORE_DIR "/", 2925 BUFSIZE); 2926 (void) strlcat(yp_dir_back, name, BUFSIZE); 2927 if (mode_verbose) 2928 CLIENT_FPRINTF(stderr, 2929 gettext("file_backup: (%s -> %s)\n"), 2930 yp_dir, yp_dir_back); 2931 retcode = file_move(yp_dir, yp_dir_back); 2932 if (retcode != 0) { 2933 CLIENT_FPRINTF(stderr, 2934 gettext("file_backup: file_move(%s, %s)" 2935 " failed with %d\n"), 2936 yp_dir, yp_dir_back, retcode); 2937 ret = CLIENT_ERR_RENAME; 2938 } 2939 } else { 2940 if (mode_verbose) 2941 CLIENT_FPRINTF(stderr, 2942 gettext("file_backup: No %s " 2943 "directory.\n"), yp_dir); 2944 } 2945 } 2946 2947 2948 /* point to file name, not path delim (/) */ 2949 ldap_conf_file = strrchr(NSCONFIGFILE, '/') + 1; 2950 ldap_cred_file = strrchr(NSCREDFILE, '/') + 1; 2951 2952 ldap_stat = stat(NSCONFIGFILE, &buf); 2953 if (mode_verbose) 2954 CLIENT_FPRINTF(stderr, 2955 gettext("file_backup: stat(%s)=%d\n"), 2956 NSCONFIGFILE, ldap_stat); 2957 if (ldap_stat == 0) { 2958 (void) strlcpy(ldap_file_back, LDAP_RESTORE_DIR "/", BUFSIZE); 2959 (void) strlcat(ldap_file_back, ldap_conf_file, BUFSIZE); 2960 if (mode_verbose) 2961 CLIENT_FPRINTF(stderr, 2962 gettext("file_backup: (%s -> %s)\n"), 2963 NSCONFIGFILE, ldap_file_back); 2964 retcode = file_move(NSCONFIGFILE, ldap_file_back); 2965 if (retcode != 0) { 2966 CLIENT_FPRINTF(stderr, 2967 gettext("file_backup: file_move(%s, %s) failed " 2968 "with %d\n"), 2969 NSCONFIGFILE, ldap_file_back, retcode); 2970 ret = CLIENT_ERR_RENAME; 2971 } 2972 2973 (void) strlcpy(ldap_cred_back, LDAP_RESTORE_DIR "/", BUFSIZE); 2974 (void) strlcat(ldap_cred_back, ldap_cred_file, BUFSIZE); 2975 if (mode_verbose) 2976 CLIENT_FPRINTF(stderr, 2977 gettext("file_backup: (%s -> %s)\n"), 2978 NSCREDFILE, ldap_cred_back); 2979 retcode = file_move(NSCREDFILE, ldap_cred_back); 2980 if (retcode != 0) { 2981 CLIENT_FPRINTF(stderr, 2982 gettext("file_backup: file_move(%s, %s) failed " 2983 "with %d\n"), 2984 NSCREDFILE, ldap_cred_back, retcode); 2985 ret = CLIENT_ERR_RENAME; 2986 } 2987 } else { 2988 if (mode_verbose) 2989 CLIENT_FPRINTF(stderr, 2990 gettext("file_backup: No %s file.\n"), 2991 NSCONFIGFILE); 2992 } 2993 2994 return (ret); 2995 } 2996 2997 /* 2998 * mod_backup() 2999 * 3000 * This function is used to temporily backup the LDAP client files in /var/ldap 3001 * that the "mod" operation needs to update. If an error occurs then the 3002 * function mod_recover() can be invoke to recover the unmodified files. 3003 */ 3004 static int 3005 mod_backup(void) 3006 { 3007 int rc; 3008 int retcode = CLIENT_SUCCESS; 3009 3010 rc = system(CMD_CP " " NSCONFIGFILE " " NSCONFIGFILE ".mod"); 3011 retcode += rc; 3012 if (mode_verbose) 3013 CLIENT_FPRINTF(stderr, 3014 gettext("mod_backup: backup %s for %s\n"), 3015 rc ? "failed" : "successful", NSCONFIGFILE); 3016 3017 rc = system(CMD_CP " " NSCREDFILE " " NSCREDFILE ".mod"); 3018 retcode += rc; 3019 if (mode_verbose) 3020 CLIENT_FPRINTF(stderr, 3021 gettext("mod_backup: backup %s for %s\n"), 3022 rc ? "failed" : "successful", NSCREDFILE); 3023 3024 rc = system(CMD_CP " " DOMAINNAME " " DOMAINNAME ".mod"); 3025 retcode += rc; 3026 if (mode_verbose) 3027 CLIENT_FPRINTF(stderr, 3028 gettext("mod_backup: backup %s for %s\n"), 3029 rc ? "failed" : "successful", DOMAINNAME); 3030 3031 if (retcode != CLIENT_SUCCESS) 3032 retcode = CLIENT_ERR_RENAME; 3033 return (retcode); 3034 } 3035 3036 /* 3037 * mod_recover() 3038 * 3039 * This function is used to recover the temporily backed up files by 3040 * the mod_backup() function if an error occurs during the "mod" 3041 * operation. 3042 */ 3043 static int 3044 mod_recover(void) 3045 { 3046 int rc; 3047 int retcode = CLIENT_SUCCESS; 3048 3049 rc = system(CMD_MV " " NSCONFIGFILE ".mod " NSCONFIGFILE); 3050 retcode += rc; 3051 if (mode_verbose) 3052 CLIENT_FPRINTF(stderr, 3053 gettext("mod_recover: recovery %s for %s\n"), 3054 rc ? "failed" : "successful", NSCONFIGFILE); 3055 3056 rc = system(CMD_MV " " NSCREDFILE ".mod " NSCREDFILE); 3057 retcode += rc; 3058 if (mode_verbose) 3059 CLIENT_FPRINTF(stderr, 3060 gettext("mod_recover: recovery %s for %s\n"), 3061 rc ? "failed" : "successful", NSCREDFILE); 3062 3063 rc = system(CMD_MV " " DOMAINNAME ".mod " DOMAINNAME); 3064 retcode += rc; 3065 if (mode_verbose) 3066 CLIENT_FPRINTF(stderr, 3067 gettext("mod_recover: recovery %s for %s\n"), 3068 rc ? "failed" : "successful", DOMAINNAME); 3069 3070 if (retcode != CLIENT_SUCCESS) 3071 retcode = CLIENT_ERR_RENAME; 3072 return (retcode); 3073 } 3074 3075 /* 3076 * mod_cleanup() 3077 * 3078 * This function removes the .mod files in /var/ldap. 3079 */ 3080 static void 3081 mod_cleanup(void) 3082 { 3083 (void) system(CMD_RM " " NSCONFIGFILE ".mod " TO_DEV_NULL); 3084 (void) system(CMD_RM " " NSCREDFILE ".mod " TO_DEV_NULL); 3085 (void) system(CMD_RM " " DOMAINNAME ".mod " TO_DEV_NULL); 3086 } 3087 3088 #define MAX_DN_ARRAY 100 3089 #define LDAP_NAMINGCONTEXTS "namingcontexts" 3090 3091 static multival_t * 3092 multival_new() 3093 { 3094 multival_t *hold; 3095 3096 hold = calloc(1, sizeof (multival_t)); 3097 if (hold == NULL) { 3098 CLIENT_FPUTS( 3099 gettext("multival_new: Memory allocation error\n"), 3100 stderr); 3101 } 3102 return (hold); /* NULL -> error */ 3103 } 3104 3105 static int 3106 multival_add(multival_t *list, char *opt) 3107 { 3108 if (opt == NULL) { 3109 CLIENT_FPUTS( 3110 gettext("Empty value passed to multival_add\n"), 3111 stderr); 3112 return (CLIENT_ERR_FAIL); 3113 } 3114 3115 if (list->count == 0) { 3116 list->optlist = (char **)malloc(sizeof (char **)); 3117 } else { 3118 list->optlist = (char **)realloc(list->optlist, 3119 (list->count + 1) * sizeof (char **)); 3120 } 3121 3122 if (list->optlist == NULL) { 3123 CLIENT_FPUTS(gettext("Error allocating memory\n"), stderr); 3124 return (CLIENT_ERR_MEMORY); /* 0 is success */ 3125 } 3126 3127 list->optlist[list->count] = opt; 3128 list->count++; 3129 3130 return (CLIENT_SUCCESS); 3131 } 3132 3133 static void 3134 multival_free(multival_t *list) 3135 { 3136 if (list == NULL) 3137 return; 3138 3139 if (list->optlist != NULL) 3140 free(list->optlist); 3141 free(list); 3142 } 3143 3144 static clientopts_t * 3145 clientopts_new() 3146 { 3147 clientopts_t *hold; 3148 3149 hold = calloc(1, sizeof (clientopts_t)); 3150 if (NULL == hold) { 3151 CLIENT_FPUTS(gettext("Error allocating memory for " 3152 "clientopts structure\n"), stderr); 3153 return (hold); /* NULL -> error */ 3154 } 3155 3156 hold->serviceAuthenticationMethod = multival_new(); 3157 if (NULL == hold->serviceAuthenticationMethod) { 3158 CLIENT_FPUTS(gettext("Error allocating memory for " 3159 "serviceAuthenticationMethod\n"), stderr); 3160 free(hold); 3161 return (NULL); /* NULL -> error */ 3162 } 3163 3164 hold->serviceCredentialLevel = multival_new(); 3165 if (NULL == hold->serviceCredentialLevel) { 3166 CLIENT_FPUTS(gettext("Error allocating memory for " 3167 "serviceCredentialLevel\n"), stderr); 3168 multival_free(hold->serviceAuthenticationMethod); 3169 free(hold); 3170 return (NULL); /* NULL -> error */ 3171 } 3172 3173 hold->objectclassMap = multival_new(); 3174 if (NULL == hold->objectclassMap) { 3175 CLIENT_FPUTS(gettext("Error allocating memory for " 3176 "objectclassMap\n"), stderr); 3177 multival_free(hold->serviceAuthenticationMethod); 3178 multival_free(hold->serviceCredentialLevel); 3179 free(hold); 3180 return (NULL); /* NULL -> error */ 3181 } 3182 3183 hold->attributeMap = multival_new(); 3184 if (NULL == hold->attributeMap) { 3185 CLIENT_FPUTS(gettext("Error allocating memory for " 3186 "attributeMap\n"), stderr); 3187 multival_free(hold->serviceAuthenticationMethod); 3188 multival_free(hold->serviceCredentialLevel); 3189 multival_free(hold->objectclassMap); 3190 free(hold); 3191 return (NULL); /* NULL -> error */ 3192 } 3193 3194 hold->serviceSearchDescriptor = multival_new(); 3195 if (NULL == hold->serviceSearchDescriptor) { 3196 CLIENT_FPUTS(gettext("Error allocating memory for " 3197 "serviceSearchDescriptor\n"), stderr); 3198 multival_free(hold->serviceAuthenticationMethod); 3199 multival_free(hold->serviceCredentialLevel); 3200 multival_free(hold->objectclassMap); 3201 multival_free(hold->attributeMap); 3202 free(hold); 3203 return (NULL); /* NULL -> error */ 3204 } 3205 3206 return (hold); 3207 } 3208 3209 static void 3210 clientopts_free(clientopts_t *list) 3211 { 3212 if (NULL == list) 3213 return; 3214 3215 multival_free(list->serviceAuthenticationMethod); 3216 multival_free(list->serviceCredentialLevel); 3217 multival_free(list->objectclassMap); 3218 multival_free(list->attributeMap); 3219 multival_free(list->serviceSearchDescriptor); 3220 3221 free(list); 3222 3223 } 3224 3225 static void 3226 multival_list(char *opt, multival_t *list) 3227 { 3228 int i; 3229 3230 if (list->count == 0) 3231 return; 3232 3233 (void) puts(opt); 3234 for (i = 0; i < list->count; i++) { 3235 (void) printf("\t\targ[%d]: %s\n", i, list->optlist[i]); 3236 } 3237 } 3238 3239 /* return the number of arguments specified in the command line */ 3240 static int 3241 num_args(clientopts_t *list) 3242 { 3243 int arg_count = 0; 3244 3245 arg_count += list->authenticationMethod ? 1 : 0; 3246 arg_count += list->serviceAuthenticationMethod->count; 3247 arg_count += list->defaultSearchBase ? 1 : 0; 3248 arg_count += list->credentialLevel ? 1 : 0; 3249 arg_count += list->serviceCredentialLevel->count; 3250 arg_count += list->domainName ? 1 : 0; 3251 arg_count += list->proxyDN ? 1 : 0; 3252 arg_count += list->enableShadowUpdate ? 1 : 0; 3253 arg_count += list->adminDN ? 1 : 0; 3254 arg_count += list->profileTTL ? 1 : 0; 3255 arg_count += list->objectclassMap->count; 3256 arg_count += list->searchTimeLimit ? 1 : 0; 3257 arg_count += list->preferredServerList ? 1 : 0; 3258 arg_count += list->profileName ? 1 : 0; 3259 arg_count += list->followReferrals ? 1 : 0; 3260 arg_count += list->attributeMap->count; 3261 arg_count += list->defaultSearchScope ? 1 : 0; 3262 arg_count += list->serviceSearchDescriptor->count; 3263 arg_count += list->bindTimeLimit ? 1 : 0; 3264 arg_count += list->proxyPassword ? 1 : 0; 3265 arg_count += list->adminPassword ? 1 : 0; 3266 arg_count += list->defaultServerList ? 1 : 0; 3267 arg_count += list->certificatePath ? 1 : 0; 3268 3269 return (arg_count); 3270 } 3271 3272 #define CLIENT_PRINT(opt, str) if (str) \ 3273 (void) printf("%s%s\n", (opt), (str)) 3274 3275 static void 3276 dumpargs(clientopts_t *list) 3277 { 3278 CLIENT_PRINT("\tauthenticationMethod: ", list->authenticationMethod); 3279 multival_list("\tserviceAuthenticationMethod: ", 3280 list->serviceAuthenticationMethod); 3281 CLIENT_PRINT("\tdefaultSearchBase: ", list->defaultSearchBase); 3282 CLIENT_PRINT("\tcredentialLevel: ", list->credentialLevel); 3283 multival_list("\tserviceCredentialLevel: ", 3284 list->serviceCredentialLevel); 3285 CLIENT_PRINT("\tdomainName: ", list->domainName); 3286 CLIENT_PRINT("\tproxyDN: ", list->proxyDN); 3287 CLIENT_PRINT("\tadminDN: ", list->adminDN); 3288 CLIENT_PRINT("\tenableShadowUpdate: ", list->enableShadowUpdate); 3289 CLIENT_PRINT("\tprofileTTL: ", list->profileTTL); 3290 multival_list("\tobjectclassMap: ", list->objectclassMap); 3291 CLIENT_PRINT("\tsearchTimeLimit: ", list->searchTimeLimit); 3292 CLIENT_PRINT("\tpreferredServerList: ", list->preferredServerList); 3293 CLIENT_PRINT("\tprofileName: ", list->profileName); 3294 CLIENT_PRINT("\tfollowReferrals: ", list->followReferrals); 3295 multival_list("\tattributeMap: ", list->attributeMap); 3296 CLIENT_PRINT("\tdefaultSearchScope: ", list->defaultSearchScope); 3297 multival_list("\tserviceSearchDescriptor: ", 3298 list->serviceSearchDescriptor); 3299 CLIENT_PRINT("\tbindTimeLimit: ", list->bindTimeLimit); 3300 CLIENT_PRINT("\tproxyPassword: ", list->proxyPassword); 3301 CLIENT_PRINT("\tadminPassword: ", list->adminPassword); 3302 CLIENT_PRINT("\tdefaultServerList: ", list->defaultServerList); 3303 CLIENT_PRINT("\tcertificatePath: ", list->certificatePath); 3304 } 3305 3306 3307 /* These definitions are only used in parseParam() below. */ 3308 struct param { 3309 char *name; 3310 int index; 3311 }; 3312 3313 static struct param paramArray[] = { 3314 {"proxyDN", NS_LDAP_BINDDN_P}, 3315 {"proxyPassword", NS_LDAP_BINDPASSWD_P}, 3316 {"defaultServerList", NS_LDAP_SERVERS_P}, 3317 {"defaultSearchBase", NS_LDAP_SEARCH_BASEDN_P}, 3318 {"authenticationMethod", NS_LDAP_AUTH_P}, 3319 {"followReferrals", NS_LDAP_SEARCH_REF_P}, 3320 {"profileTTL", NS_LDAP_CACHETTL_P}, 3321 {"certificatePath", NS_LDAP_HOST_CERTPATH_P}, 3322 {"defaultSearchScope", NS_LDAP_SEARCH_SCOPE_P}, 3323 {"bindTimeLimit", NS_LDAP_BIND_TIME_P}, 3324 {"searchTimeLimit", NS_LDAP_SEARCH_TIME_P}, 3325 {"preferredServerList", NS_LDAP_SERVER_PREF_P}, 3326 {"profileName", NS_LDAP_PROFILE_P}, 3327 {"credentialLevel", NS_LDAP_CREDENTIAL_LEVEL_P}, 3328 {"serviceSearchDescriptor", NS_LDAP_SERVICE_SEARCH_DESC_P}, 3329 {"attributeMap", NS_LDAP_ATTRIBUTEMAP_P}, 3330 {"objectclassMap", NS_LDAP_OBJECTCLASSMAP_P}, 3331 {"serviceAuthenticationMethod", NS_LDAP_SERVICE_AUTH_METHOD_P}, 3332 {"serviceCredentialLevel", NS_LDAP_SERVICE_CRED_LEVEL_P}, 3333 {"domainName", LOCAL_DOMAIN_P}, 3334 {"enableShadowUpdate", NS_LDAP_ENABLE_SHADOW_UPDATE_P}, 3335 {"adminDN", NS_LDAP_ADMIN_BINDDN_P}, 3336 {"adminPassword", NS_LDAP_ADMIN_BINDPASSWD_P}, 3337 {NULL, 0} 3338 }; 3339 3340 static int 3341 parseParam(char *param, char **paramVal) 3342 { 3343 char *val = NULL; 3344 int counter; 3345 3346 if (mode_verbose) { 3347 CLIENT_FPRINTF(stderr, gettext("Parsing %s\n"), param); 3348 } 3349 3350 val = strchr(param, '='); 3351 if (val == NULL) { 3352 CLIENT_FPUTS( 3353 gettext("Didn\'t find \'=\' character in string\n"), 3354 stderr); 3355 paramVal = NULL; 3356 return (CLIENT_ERR_PARSE); 3357 } 3358 3359 *val = '\0'; 3360 3361 for (counter = 0; paramArray[counter].name != NULL; counter++) { 3362 if (strcasecmp(paramArray[counter].name, param) == 0) { 3363 *paramVal = val+1; 3364 *val = '='; /* restore original param */ 3365 return (paramArray[counter].index); 3366 } 3367 } 3368 3369 /* Not found */ 3370 *val = '='; /* restore original param */ 3371 *paramVal = NULL; 3372 return (CLIENT_ERR_PARSE); 3373 } 3374 3375 /* 3376 * The following macro checks if an option has already been specified 3377 * and errs out with usage if so 3378 */ 3379 #define CLIENT_OPT_CHECK(opt, optarg) \ 3380 if (optarg) { \ 3381 CLIENT_FPUTS(gettext("Invalid use of option\n"), stderr); \ 3382 usage(); \ 3383 clientopts_free(optlist); \ 3384 return (CLIENT_ERR_FAIL); \ 3385 } 3386 3387 static int 3388 clientSetParam(clientopts_t *optlist, int paramFlag, char *attrVal) 3389 { 3390 int retcode = 0; 3391 int counter; 3392 3393 3394 switch (paramFlag) { 3395 case NS_LDAP_AUTH_P: 3396 CLIENT_OPT_CHECK(paramFlag, optlist->authenticationMethod); 3397 optlist->authenticationMethod = attrVal; 3398 break; 3399 3400 case NS_LDAP_SERVICE_AUTH_METHOD_P: /* multiple allowed */ 3401 retcode = multival_add(optlist->serviceAuthenticationMethod, 3402 attrVal); 3403 if (retcode != CLIENT_SUCCESS) { 3404 CLIENT_FPRINTF(stderr, 3405 gettext("Error processing attrVal %s\n"), 3406 attrVal?attrVal:"NULL"); 3407 usage(); 3408 clientopts_free(optlist); 3409 return (CLIENT_ERR_FAIL); 3410 } 3411 break; 3412 3413 case NS_LDAP_SEARCH_BASEDN_P: 3414 CLIENT_OPT_CHECK(paramFlag, optlist->defaultSearchBase); 3415 optlist->defaultSearchBase = attrVal; 3416 break; 3417 3418 case NS_LDAP_CREDENTIAL_LEVEL_P: 3419 CLIENT_OPT_CHECK(paramFlag, optlist->credentialLevel); 3420 optlist->credentialLevel = attrVal; 3421 break; 3422 3423 case NS_LDAP_SERVICE_CRED_LEVEL_P: /* multiple allowed */ 3424 retcode = multival_add(optlist->serviceCredentialLevel, 3425 attrVal); 3426 if (retcode != CLIENT_SUCCESS) { 3427 CLIENT_FPRINTF(stderr, 3428 gettext("Error processing attrVal %s\n"), 3429 attrVal?attrVal:"NULL"); 3430 usage(); 3431 clientopts_free(optlist); 3432 return (CLIENT_ERR_FAIL); 3433 } 3434 break; 3435 3436 case LOCAL_DOMAIN_P: 3437 CLIENT_OPT_CHECK(paramFlag, optlist->domainName); 3438 optlist->domainName = attrVal; 3439 dname = optlist->domainName; 3440 break; 3441 3442 case NS_LDAP_BINDDN_P: 3443 CLIENT_OPT_CHECK(paramFlag, optlist->proxyDN); 3444 optlist->proxyDN = attrVal; 3445 break; 3446 3447 case NS_LDAP_ENABLE_SHADOW_UPDATE_P: 3448 CLIENT_OPT_CHECK(paramFlag, optlist->enableShadowUpdate); 3449 optlist->enableShadowUpdate = attrVal; 3450 break; 3451 3452 case NS_LDAP_ADMIN_BINDDN_P: 3453 CLIENT_OPT_CHECK(paramFlag, optlist->adminDN); 3454 optlist->adminDN = attrVal; 3455 break; 3456 3457 case NS_LDAP_CACHETTL_P: 3458 CLIENT_OPT_CHECK(paramFlag, optlist->profileTTL); 3459 optlist->profileTTL = attrVal; 3460 break; 3461 3462 case NS_LDAP_OBJECTCLASSMAP_P: /* multiple allowed */ 3463 retcode = multival_add(optlist->objectclassMap, attrVal); 3464 if (retcode != CLIENT_SUCCESS) { 3465 CLIENT_FPRINTF(stderr, 3466 gettext("Error processing attrVal %s\n"), 3467 attrVal?attrVal:"NULL"); 3468 usage(); 3469 clientopts_free(optlist); 3470 return (CLIENT_ERR_FAIL); 3471 } 3472 break; 3473 3474 case NS_LDAP_SEARCH_TIME_P: 3475 CLIENT_OPT_CHECK(paramFlag, optlist->searchTimeLimit); 3476 optlist->searchTimeLimit = attrVal; 3477 break; 3478 3479 case NS_LDAP_SERVER_PREF_P: 3480 CLIENT_OPT_CHECK(paramFlag, optlist->preferredServerList); 3481 optlist->preferredServerList = attrVal; 3482 /* replace ',' chars with ' ' for proper syntax */ 3483 for (counter = 0; 3484 counter < strlen(optlist->preferredServerList); 3485 counter++) { 3486 3487 if (optlist->preferredServerList[counter] == ',') 3488 optlist->preferredServerList[counter] = ' '; 3489 } 3490 break; 3491 3492 case NS_LDAP_PROFILE_P: 3493 CLIENT_OPT_CHECK(paramFlag, optlist->profileName); 3494 optlist->profileName = attrVal; 3495 break; 3496 3497 case NS_LDAP_SEARCH_REF_P: 3498 CLIENT_OPT_CHECK(paramFlag, optlist->followReferrals); 3499 if (0 == strcasecmp(attrVal, "followref")) 3500 optlist->followReferrals = "TRUE"; 3501 else if (0 == strcasecmp(attrVal, "noref")) 3502 optlist->followReferrals = "FALSE"; 3503 else 3504 optlist->followReferrals = attrVal; 3505 break; 3506 3507 case NS_LDAP_ATTRIBUTEMAP_P: /* multiple allowed */ 3508 retcode = multival_add(optlist->attributeMap, attrVal); 3509 if (retcode != CLIENT_SUCCESS) { 3510 CLIENT_FPRINTF(stderr, 3511 gettext("Error processing attrVal %s\n"), 3512 attrVal?attrVal:"NULL"); 3513 usage(); 3514 clientopts_free(optlist); 3515 return (CLIENT_ERR_FAIL); 3516 } 3517 break; 3518 3519 case NS_LDAP_SEARCH_SCOPE_P: 3520 CLIENT_OPT_CHECK(paramFlag, optlist->defaultSearchScope); 3521 optlist->defaultSearchScope = attrVal; 3522 break; 3523 3524 case NS_LDAP_SERVICE_SEARCH_DESC_P: /* multiple allowed */ 3525 retcode = multival_add(optlist->serviceSearchDescriptor, 3526 attrVal); 3527 if (retcode != CLIENT_SUCCESS) { 3528 CLIENT_FPRINTF(stderr, 3529 gettext("Error processing attrVal %s\n"), 3530 attrVal?attrVal:"NULL"); 3531 usage(); 3532 clientopts_free(optlist); 3533 return (CLIENT_ERR_FAIL); 3534 } 3535 break; 3536 3537 case NS_LDAP_BIND_TIME_P: 3538 CLIENT_OPT_CHECK(paramFlag, optlist->bindTimeLimit); 3539 optlist->bindTimeLimit = attrVal; 3540 break; 3541 3542 case NS_LDAP_BINDPASSWD_P: 3543 CLIENT_OPT_CHECK(paramFlag, optlist->proxyPassword); 3544 optlist->proxyPassword = attrVal; 3545 break; 3546 3547 case NS_LDAP_ADMIN_BINDPASSWD_P: 3548 CLIENT_OPT_CHECK(paramFlag, optlist->adminPassword); 3549 optlist->adminPassword = attrVal; 3550 break; 3551 3552 case NS_LDAP_HOST_CERTPATH_P: 3553 CLIENT_OPT_CHECK(paramFlag, optlist->certificatePath); 3554 optlist->certificatePath = attrVal; 3555 break; 3556 3557 case NS_LDAP_SERVERS_P: 3558 CLIENT_OPT_CHECK(paramFlag, optlist->defaultServerList); 3559 optlist->defaultServerList = attrVal; 3560 break; 3561 3562 default: 3563 usage(); 3564 return (CLIENT_ERR_FAIL); 3565 /* break; lint doesn't like break before end of switch */ 3566 } 3567 3568 return (retcode); 3569 } 3570 3571 /* 3572 * file_move() - Used to move a config file (backup/restore). 3573 * 3574 * This function uses a system() call with /bin/mv to handle the 3575 * case where the backup directory (/var) is on a different file 3576 * system than the config file (typically /etc). 3577 */ 3578 static int 3579 file_move(const char *from, const char *to) 3580 { 3581 int retcode; 3582 char mvCommand[] = CMD_MV; 3583 char cmd_buffer[(2 * MAXPATHLEN) + sizeof (mvCommand) + 3]; 3584 3585 (void) snprintf(cmd_buffer, sizeof (cmd_buffer), "%s %s %s", 3586 mvCommand, from, to); 3587 3588 /* 3589 * This function should only be used internally to move 3590 * system files to/from the backup directory. For security 3591 * reasons (this is run as root), don't use this function 3592 * with arguments passed into the program. 3593 */ 3594 retcode = system(cmd_buffer); 3595 3596 return (retcode); 3597 } 3598 3599 3600 /* 3601 * Manipulate the service as instructed by "dowhat" 3602 */ 3603 static int 3604 do_service(const char *fmri, boolean_t waitflag, int dowhat, 3605 const char *state) { 3606 3607 int status; 3608 boolean_t is_maint; 3609 const char *what = gettext("not set"); 3610 useconds_t max; 3611 3612 /* Check if we are in maintenance */ 3613 is_maint = is_service(fmri, SCF_STATE_STRING_MAINT); 3614 3615 switch (dowhat) { 3616 case START_SERVICE: 3617 what = gettext("start"); 3618 status = smf_enable_instance(fmri, 3619 (sysid_install == B_TRUE)?SMF_TEMPORARY:0); 3620 break; 3621 case STOP_SERVICE: 3622 what = gettext("stop"); 3623 status = smf_disable_instance(fmri, 3624 (sysid_install == B_TRUE)?SMF_TEMPORARY:0); 3625 break; 3626 case RESTART_SERVICE: 3627 what = gettext("restart"); 3628 status = smf_restart_instance(fmri); 3629 break; 3630 default: 3631 /* coding error; will not happen */ 3632 assert(0); 3633 } 3634 3635 /* 3636 * If the service was previously in maintenance then we need to 3637 * clear it immediately. The "dowhat" action will set the 3638 * enabled property of the service as intended by the caller while 3639 * clear will actually cause it to be enabled/disabled. 3640 * We assume that the caller has called us after taking some 3641 * recovery action. Even if it's not the case, we don't lose 3642 * anything. 3643 */ 3644 if (status == 0 && is_maint == B_TRUE) { 3645 if (mode_verbose) 3646 CLIENT_FPRINTF(stderr, 3647 "%s: %s... %s\n", 3648 what, 3649 fmri, 3650 gettext("restoring from maintenance state")); 3651 status = smf_restore_instance(fmri); 3652 } 3653 3654 if (status == 0) { 3655 /* Check if we need to wait ? */ 3656 if (waitflag == B_FALSE) { 3657 if (mode_verbose) 3658 CLIENT_FPRINTF(stderr, 3659 "%s: %s... %s\n", 3660 what, 3661 fmri, 3662 gettext("success")); 3663 return (CLIENT_SUCCESS); 3664 } 3665 3666 /* Otherwise wait for max seconds (from the manifest) */ 3667 max = get_timeout_value(dowhat, fmri, DEFAULT_TIMEOUT); 3668 status = wait_till(fmri, state, max, what, !is_maint); 3669 if (status == CLIENT_SUCCESS) 3670 return (CLIENT_SUCCESS); 3671 /* For error fall through for corrective action */ 3672 } else { 3673 /* Well, service failed ... */ 3674 if (mode_verbose) 3675 CLIENT_FPRINTF(stderr, "%s: %s... %s: %s\n", 3676 what, 3677 fmri, 3678 gettext("failed"), 3679 scf_strerror(scf_error())); 3680 status = CLIENT_ERR_FAIL; 3681 /* For error fall through for corrective action */ 3682 } 3683 3684 /* 3685 * If service is still offline after start/restart, then transitioning 3686 * failed and guess is restarter failed to apply the timeout as well. 3687 * So instead of leaving it offline, let's just disable it until we have 3688 * some other mechanism available from smf to handle such situation. 3689 */ 3690 if (dowhat != STOP_SERVICE) 3691 if (is_service(fmri, SCF_STATE_STRING_OFFLINE)) { 3692 if (mode_verbose) 3693 CLIENT_FPRINTF(stderr, 3694 "%s: %s... %s\n", 3695 what, 3696 fmri, 3697 gettext("offline to disable")); 3698 (void) disable_service(fmri, waitflag); 3699 } 3700 3701 return (status); 3702 } 3703 3704 3705 /* 3706 * Wait for "max" usecs for the service described by "fmri" to change 3707 * to "state". If check_maint is true then return immediately if 3708 * service goes into maintenance 3709 */ 3710 static int 3711 wait_till(const char *fmri, const char *state, useconds_t max, 3712 const char *what, boolean_t check_maint) { 3713 char *st; 3714 useconds_t usecs = INIT_WAIT_USECS; 3715 3716 for (; max > 0; max -= usecs) { 3717 /* incremental wait */ 3718 usecs *= 2; 3719 usecs = (usecs > max)?max:usecs; 3720 if (mode_verbose) 3721 CLIENT_FPRINTF(stderr, 3722 "%s: %s %u %s\n", 3723 what, gettext("sleep"), usecs, 3724 gettext("microseconds")); 3725 (void) usleep(usecs); 3726 3727 /* Check state after the wait */ 3728 if ((st = smf_get_state(fmri)) != NULL) { 3729 if (strcmp(st, state) == 0) { 3730 if (mode_verbose) 3731 CLIENT_FPRINTF(stderr, 3732 "%s: %s... %s\n", 3733 what, 3734 fmri, 3735 gettext("success")); 3736 free(st); 3737 return (CLIENT_SUCCESS); 3738 } 3739 3740 /* 3741 * If service has gone into maintenance then 3742 * we will time out anyway, so we are better 3743 * off returning now 3744 */ 3745 if (check_maint && 3746 strcmp(st, SCF_STATE_STRING_MAINT) == 0) { 3747 if (mode_verbose) 3748 CLIENT_FPRINTF(stderr, 3749 "%s: %s... %s\n", 3750 what, 3751 fmri, 3752 gettext("maintenance")); 3753 free(st); 3754 return (CLIENT_ERR_MAINTENANCE); 3755 } 3756 free(st); 3757 } else { 3758 if (mode_verbose) 3759 CLIENT_FPRINTF(stderr, 3760 "%s: %s... %s: %s\n", 3761 what, 3762 fmri, 3763 gettext("failed"), 3764 scf_strerror(scf_error())); 3765 return (CLIENT_ERR_FAIL); 3766 } 3767 } 3768 3769 /* Timed out waiting */ 3770 if (mode_verbose) 3771 CLIENT_FPRINTF(stderr, 3772 "%s: %s... %s\n", 3773 what, 3774 fmri, 3775 gettext("timed out")); 3776 return (CLIENT_ERR_TIMEDOUT); 3777 } 3778 3779 3780 static boolean_t 3781 is_service(const char *fmri, const char *state) { 3782 char *st; 3783 boolean_t result = B_FALSE; 3784 3785 if ((st = smf_get_state(fmri)) != NULL) { 3786 if (strcmp(st, state) == 0) 3787 result = B_TRUE; 3788 free(st); 3789 } 3790 return (result); 3791 } 3792 3793 3794 /* 3795 * 3796 * get_timeout_val : returns the timeout value set in fmri manifest 3797 * inputs : action(start/stop) 3798 * fmri(defined fmri string) 3799 * Returns default if error, the timeout val otherwise 3800 * 3801 */ 3802 3803 static useconds_t 3804 get_timeout_value(int dowhat, const char *fmri, useconds_t default_val) 3805 { 3806 scf_simple_prop_t *sp = NULL; 3807 uint64_t *cp = NULL; 3808 int timeout = default_val/1000000; 3809 char *action = NULL; 3810 const char *actionstr = NULL; 3811 3812 switch (dowhat) { 3813 case START_SERVICE: 3814 case RESTART_SERVICE: 3815 action = "start"; 3816 actionstr = gettext("start"); 3817 break; 3818 case STOP_SERVICE: 3819 action = "stop"; 3820 actionstr = gettext("stop"); 3821 break; 3822 default: 3823 assert(0); 3824 } 3825 3826 3827 sp = scf_simple_prop_get(NULL, fmri, action, SCF_PROPERTY_TIMEOUT); 3828 if (sp == NULL) { 3829 if (mode_verbose) 3830 CLIENT_FPRINTF(stderr, "%s: %s... %s: %s\n", 3831 actionstr, 3832 fmri, 3833 gettext("failed to retrieve timeout property"), 3834 scf_strerror(scf_error())); 3835 return (default_val); 3836 } 3837 3838 cp = scf_simple_prop_next_count(sp); 3839 if (cp == NULL) { 3840 if (mode_verbose) 3841 CLIENT_FPRINTF(stderr, "%s: %s... %s: %s\n", 3842 actionstr, 3843 fmri, 3844 gettext("failed to retrieve timeout value"), 3845 scf_strerror(scf_error())); 3846 scf_simple_prop_free(sp); 3847 return (default_val); 3848 } 3849 3850 if (*cp != 0) 3851 timeout = *cp; 3852 scf_simple_prop_free(sp); 3853 return (timeout * 1000000); 3854 } 3855