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 */ 25 26 /* 27 * ldapclient command. To make (initiailize) or uninitialize a machines as 28 * and LDAP client. This command MUST be run as root (or it will simply exit). 29 * 30 * -I Install. No file_backup/recover for installing only (no doc). 31 * 32 * init Initialze (create) an LDAP client from a profile stored 33 * in a directory-server. 34 * manual Initialze (create) an LDAP client by hand (-file option 35 * reads from file). 36 * mod Modify the LDAP client configuration on this machine by hand. 37 * list List the contents of the LDAP client cache files. 38 * uninit Uninitialize this machine. 39 * 40 * -v Verbose flag. 41 * -q Quiet flag (mutually exclusive with -v). 42 * 43 * -a attrName=attrVal 44 * <attrName> can be one of the following: 45 * 46 * attributeMap 47 * Attribute map. Can be multiple instances of this option. 48 * (no former option) 49 * authenticationMethod 50 * Authentication method (formerly -a) 51 * bindTimeLimit 52 * Bind time limit. (no former option) 53 * certificatePath 54 * Path to certificates used for secure bind (no former option) 55 * credentialLevel 56 * Client credential level (no former option) 57 * defaultServerList 58 * Default server (no former option) Refer to DUA Config 59 * Schema draft. 60 * defaultSearchBase 61 * Search Base DN. e.g. dc=eng,dc=sun,dc=com (formerly -b) 62 * defaultSearchScope 63 * Search scope. (formerly -s) 64 * domainName 65 * Hosts lookup domain (DNS) Ex. eng.sun.com (formerly -d) 66 * followReferrals 67 * Search dereference. followref or noref (default followref) 68 * (formerly -r) 69 * objectclassMap 70 * Objectclass map. Can be multiple instances of this option. 71 * (no former option) 72 * preferredServerList 73 * Server preference list. Comma ',' seperated list of IPaddr. 74 * (formerly -p) 75 * profileName 76 * Profile name to use for init (ldapclient) or 77 * generate (gen_profile). (formerly -P) 78 * profileTTL 79 * Client info TTL. If set to 0 this information will not be 80 * automatically updated by the ldap_cachemgr(1M). 81 * (formerly -e) 82 * proxyDN 83 * Binding DN. Ex. cn=client,ou=people,cd=eng,dc=sun,dc=com 84 * (formerly -D) 85 * proxyPassword 86 * Client password not needed for authentication "none". 87 * (formerly -w) 88 * adminDN 89 * Administrator DN for updating naming data. 90 * adminPassword 91 * Administrator password 92 * enableShadowUpdate 93 * Allow Administrator to change shadow data in LDAP 94 * searchTimeLimit 95 * Timeout value. (formerly -o) 96 * serviceSearchDescriptor 97 * Service search scope. (no former option) 98 * serviceAuthenticationMethod 99 * Service authenticaion method (no former option) 100 * serviceCredentialLevel 101 * Service credential level (no former option) 102 * 103 */ 104 105 #include <stdlib.h> 106 #include <stdio.h> 107 #include <unistd.h> 108 #include <errno.h> 109 #include <sys/types.h> 110 #include <time.h> 111 #include <sys/param.h> 112 #include <sys/stat.h> 113 #include <sys/systeminfo.h> 114 #include <fcntl.h> 115 #include <xti.h> 116 #include <strings.h> 117 #include <limits.h> 118 #include <locale.h> 119 #include <syslog.h> 120 #include <libscf.h> 121 #include <assert.h> 122 123 #include "standalone.h" 124 125 #if !defined(TEXT_DOMAIN) 126 #define TEXT_DOMAIN "SUNW_OST_OSCMD" 127 #endif 128 129 /* error codes */ 130 /* The manpage doc only allows for SUCCESS(0), FAIL(1) and CRED(2) on exit */ 131 #define CLIENT_SUCCESS 0 132 #define CLIENT_ERR_PARSE -1 133 #define CLIENT_ERR_FAIL 1 134 #define CLIENT_ERR_CREDENTIAL 2 135 #define CLIENT_ERR_MEMORY 3 136 #define CLIENT_ERR_RESTORE 4 137 #define CLIENT_ERR_RENAME 5 138 #define CLIENT_ERR_RECOVER 6 139 #define CLIENT_ERR_TIMEDOUT 7 140 #define CLIENT_ERR_MAINTENANCE 8 141 142 /* Reset flag for start_services() */ 143 #define START_INIT 1 144 #define START_RESET 2 145 #define START_UNINIT 3 146 147 /* Reset flag for stop_services() */ 148 #define STATE_NOSAVE 0 149 #define STATE_SAVE 1 150 151 /* files to (possibiliy) restore */ 152 #define LDAP_RESTORE_DIR "/var/ldap/restore" 153 154 #define DOMAINNAME_DIR "/etc" 155 #define DOMAINNAME_FILE "defaultdomain" 156 #define DOMAINNAME DOMAINNAME_DIR "/" DOMAINNAME_FILE 157 #define DOMAINNAME_BACK LDAP_RESTORE_DIR "/" DOMAINNAME_FILE 158 159 #define NSSWITCH_DIR "/etc" 160 #define NSSWITCH_FILE "nsswitch.conf" 161 #define NSSWITCH_CONF NSSWITCH_DIR "/" NSSWITCH_FILE 162 #define NSSWITCH_BACK LDAP_RESTORE_DIR "/" NSSWITCH_FILE 163 #define NSSWITCH_LDAP "/etc/nsswitch.ldap" 164 165 #define YP_BIND_DIR "/var/yp/binding" 166 167 /* Define the service FMRIs */ 168 #define SENDMAIL_FMRI "network/smtp:sendmail" 169 #define NSCD_FMRI "system/name-service-cache:default" 170 #define AUTOFS_FMRI "system/filesystem/autofs:default" 171 #define LDAP_FMRI "network/ldap/client:default" 172 #define YP_FMRI "network/nis/client:default" 173 #define NS_MILESTONE_FMRI "milestone/name-services:default" 174 175 /* Define flags for checking if services were enabled */ 176 #define SENDMAIL_ON 0x1 177 #define NSCD_ON 0x10 178 #define AUTOFS_ON 0x100 179 180 #define CMD_DOMAIN_START "/usr/bin/domainname" 181 182 /* Command to copy files */ 183 #define CMD_CP "/bin/cp -f" 184 #define CMD_MV "/bin/mv -f" 185 #define CMD_RM "/bin/rm -f" 186 187 #define TO_DEV_NULL " >/dev/null 2>&1" 188 189 /* Files that need to be just removed */ 190 #define LDAP_CACHE_LOG "/var/ldap/cachemgr.log" 191 192 /* Output defines to supress if quiet mode set */ 193 #define CLIENT_FPUTS if (!mode_quiet) (void) fputs 194 #define CLIENT_FPRINTF if (!mode_quiet) (void) fprintf 195 #define CLIENT_FPUTC if (!mode_quiet) (void) fputc 196 197 #define restart_service(fmri, waitflag)\ 198 do_service(fmri, waitflag, RESTART_SERVICE,\ 199 SCF_STATE_STRING_ONLINE) 200 #define start_service(fmri, waitflag) \ 201 do_service(fmri, waitflag, START_SERVICE,\ 202 SCF_STATE_STRING_ONLINE) 203 #define disable_service(fmri, waitflag) \ 204 do_service(fmri, waitflag, STOP_SERVICE,\ 205 SCF_STATE_STRING_DISABLED) 206 207 /* 208 * There isn't a domainName defined as a param, so we set a value here 209 * (1001) should be big enough 210 */ 211 #define LOCAL_DOMAIN_P 1001 212 213 #define START_SERVICE 1 214 #define STOP_SERVICE 2 215 #define RESTART_SERVICE 3 216 217 #define DEFAULT_TIMEOUT 60000000 218 219 #define INIT_WAIT_USECS 50000 220 221 /* Used to turn off profile checking */ 222 #define CACHETTL_OFF "0" 223 224 /* Globals */ 225 static char *cmd; 226 227 static char *dname = NULL; 228 static char dname_buf[BUFSIZ]; 229 230 static boolean_t sysid_install = B_FALSE; 231 232 static int mode_verbose = 0; 233 static int mode_quiet = 0; 234 static int gen = 0; 235 236 static int gStartLdap = 0; 237 static int gStartYp = 0; 238 239 static int enableFlag = 0; 240 241 /* multival_t is used to hold params that can have more than one value */ 242 typedef struct { 243 int count; 244 char **optlist; 245 } multival_t; 246 247 static multival_t *multival_new(); 248 static int multival_add(multival_t *list, char *opt); 249 static void multival_free(multival_t *list); 250 251 /* 252 * clientopts_t is used to hold and pass around the param values from 253 * the cmd line 254 */ 255 typedef struct { 256 multival_t *attributeMap; 257 char *authenticationMethod; 258 char *bindTimeLimit; 259 char *certificatePath; 260 char *credentialLevel; 261 char *defaultSearchBase; 262 char *defaultServerList; 263 char *domainName; 264 char *followReferrals; 265 multival_t *objectclassMap; 266 char *preferredServerList; 267 char *profileName; 268 char *profileTTL; 269 char *proxyDN; 270 char *proxyPassword; 271 char *enableShadowUpdate; 272 char *adminDN; 273 char *adminPassword; 274 char *bindDN; 275 char *bindPasswd; 276 char *defaultSearchScope; 277 char *searchTimeLimit; 278 multival_t *serviceAuthenticationMethod; 279 multival_t *serviceCredentialLevel; 280 multival_t *serviceSearchDescriptor; 281 } clientopts_t; 282 283 static clientopts_t *clientopts_new(); 284 static void clientopts_free(clientopts_t *list); 285 286 extern ns_ldap_error_t *__ns_ldap_print_config(int); 287 extern void __ns_ldap_default_config(); 288 extern int __ns_ldap_download(const char *, char *, char *, ns_ldap_error_t **); 289 290 /* Function prototypes (these could be static) */ 291 static void usage(void); 292 293 static int credCheck(clientopts_t *arglist); 294 static int adminCredCheck(clientopts_t *arglist); 295 static int clientSetParam(clientopts_t *optlist, int paramFlag, char *attrVal); 296 static int parseParam(char *param, char **paramVal); 297 static void dumpargs(clientopts_t *arglist); 298 static int num_args(clientopts_t *arglist); 299 300 static int file_backup(void); 301 static int recover(int saveState); 302 static int mod_backup(void); 303 static int mod_recover(void); 304 static void mod_cleanup(void); 305 306 static int client_list(clientopts_t *arglist); 307 static int client_manual(clientopts_t *arglist); 308 static int client_mod(clientopts_t *arglist); 309 static int client_uninit(clientopts_t *arglist); 310 static int client_genProfile(clientopts_t *arglist); 311 static int client_init(clientopts_t *arglist); 312 static int file_move(const char *from, const char *to); 313 314 static int start_services(int flag); 315 static int stop_services(int saveState); 316 static boolean_t is_service(const char *fmri, const char *state); 317 static int wait_till(const char *fmri, const char *state, useconds_t max, 318 const char *what, boolean_t check_maint); 319 static int do_service(const char *fmri, boolean_t waitflag, int dowhat, 320 const char *state); 321 static useconds_t get_timeout_value(int dowhat, const char *fmri, 322 useconds_t default_val); 323 324 int 325 main(int argc, char **argv) 326 { 327 char *ret_locale, *ret_textdomain; 328 int retcode; 329 int paramFlag; 330 char *attrVal; 331 int sysinfostatus; 332 clientopts_t *optlist = NULL; 333 int op_manual = 0, op_mod = 0, op_uninit = 0; 334 int op_list = 0, op_init = 0, op_genprofile = 0; 335 extern char *optarg; 336 extern int optind; 337 int option; 338 339 ret_locale = setlocale(LC_ALL, ""); 340 if (ret_locale == NULL) { 341 CLIENT_FPUTS(gettext("Unable to set locale.\n"), stderr); 342 } 343 ret_textdomain = textdomain(TEXT_DOMAIN); 344 if (ret_textdomain == NULL) { 345 CLIENT_FPUTS(gettext("Unable to set textdomain.\n"), stderr); 346 } 347 348 openlog("ldapclient", LOG_PID, LOG_USER); 349 350 /* get name that invoked us */ 351 if (cmd = strrchr(argv[0], '/')) 352 ++cmd; 353 else 354 cmd = argv[0]; 355 356 sysinfostatus = sysinfo(SI_SRPC_DOMAIN, dname_buf, BUFSIZ); 357 if (0 < sysinfostatus) 358 dname = &dname_buf[0]; 359 360 optlist = clientopts_new(); 361 if (optlist == NULL) { 362 CLIENT_FPUTS( 363 gettext("Error getting optlist (malloc fail)\n"), 364 stderr); 365 exit(CLIENT_ERR_FAIL); 366 } 367 368 optind = 1; 369 while (optind < argc) { 370 option = getopt(argc, argv, "vqa:ID:w:j:y:z:"); 371 372 switch (option) { 373 case 'v': 374 mode_verbose = 1; 375 break; 376 case 'q': 377 mode_quiet = 1; 378 break; 379 case 'a': 380 attrVal = NULL; 381 paramFlag = parseParam(optarg, &attrVal); 382 if (paramFlag == CLIENT_ERR_PARSE) { 383 CLIENT_FPRINTF(stderr, 384 gettext("Unrecognized " 385 "parameter \"%s\"\n"), 386 optarg); 387 usage(); 388 exit(CLIENT_ERR_FAIL); 389 } 390 if (paramFlag == NS_LDAP_BINDPASSWD_P && 391 optlist->proxyPassword != NULL) { 392 (void) fprintf(stderr, 393 gettext("The -a proxyPassword option is " 394 "mutually exclusive of -y. " 395 "-a proxyPassword is ignored.\n")); 396 break; 397 } 398 if (paramFlag == NS_LDAP_ADMIN_BINDPASSWD_P && 399 optlist->adminPassword != NULL) { 400 (void) fprintf(stderr, 401 gettext("The -a adminPassword option is " 402 "mutually exclusive of -z. " 403 "-a adminPassword is ignored.\n")); 404 break; 405 } 406 retcode = clientSetParam(optlist, paramFlag, attrVal); 407 if (retcode != CLIENT_SUCCESS) { 408 CLIENT_FPRINTF( 409 stderr, 410 gettext("Error (%d) setting " 411 "param \"%s\"\n"), 412 retcode, optarg); 413 usage(); 414 exit(CLIENT_ERR_FAIL); 415 } 416 break; 417 case 'D': 418 optlist->bindDN = strdup(optarg); 419 break; 420 case 'w': 421 if (optlist->bindPasswd != NULL) { 422 CLIENT_FPRINTF(stderr, 423 gettext("The -w option is mutually " 424 "exclusive of -j. -w is ignored.")); 425 break; 426 } 427 428 if (optarg[0] == '-' && optarg[1] == '\0') { 429 /* Ask for a password later */ 430 break; 431 } 432 433 optlist->bindPasswd = strdup(optarg); 434 break; 435 case 'j': 436 if (optlist->bindPasswd != NULL) { 437 (void) fprintf(stderr, 438 gettext("The -w option is mutually " 439 "exclusive of -j. -w is ignored.\n")); 440 free(optlist->bindPasswd); 441 } 442 optlist->bindPasswd = readPwd(optarg); 443 if (optlist->bindPasswd == NULL) { 444 exit(CLIENT_ERR_FAIL); 445 } 446 break; 447 case 'y': 448 if (optlist->proxyPassword != NULL) { 449 (void) fprintf(stderr, 450 gettext("The -a proxyPassword option is " 451 "mutually exclusive of -y. " 452 "-a proxyPassword is ignored.\n")); 453 } 454 optlist->proxyPassword = readPwd(optarg); 455 if (optlist->proxyPassword == NULL) { 456 exit(CLIENT_ERR_FAIL); 457 } 458 break; 459 case 'z': 460 if (optlist->adminPassword != NULL) { 461 (void) fprintf(stderr, 462 gettext("The -a adminPassword option is " 463 "mutually exclusive of -z. " 464 "-a adminPassword is ignored.\n")); 465 } 466 optlist->adminPassword = readPwd(optarg); 467 if (optlist->adminPassword == NULL) { 468 exit(CLIENT_ERR_FAIL); 469 } 470 break; 471 case EOF: 472 if (strcmp(argv[optind], "init") == 0) { 473 op_init = 1; 474 } else if (strcmp(argv[optind], "manual") == 0) { 475 op_manual = 1; 476 } else if (strcmp(argv[optind], "mod") == 0) { 477 op_mod = 1; 478 } else if (strcmp(argv[optind], "list") == 0) { 479 op_list = 1; 480 } else if (strcmp(argv[optind], "uninit") == 0) { 481 op_uninit = 1; 482 } else if (strcmp(argv[optind], "genprofile") == 0) { 483 gen = 1; 484 op_genprofile = 1; 485 } else if (optind == argc-1) { 486 retcode = clientSetParam( 487 optlist, 488 NS_LDAP_SERVERS_P, 489 argv[optind]); /* ipAddr */ 490 if (retcode != CLIENT_SUCCESS) { 491 CLIENT_FPRINTF( 492 stderr, 493 gettext("Error (%d) setting " 494 "serverList param.\n"), 495 retcode); 496 usage(); 497 exit(CLIENT_ERR_FAIL); 498 } 499 } else { 500 CLIENT_FPUTS( 501 gettext("Error parsing " 502 "command line\n"), 503 stderr); 504 usage(); 505 exit(CLIENT_ERR_FAIL); 506 } 507 optind++; /* get past the verb and keep trying */ 508 break; 509 /* Backwards compatibility to support system install */ 510 case 'I': 511 sysid_install = B_TRUE; 512 op_init = 1; 513 mode_quiet = 1; 514 break; 515 case '?': 516 usage(); 517 CLIENT_FPUTS(gettext("\nOr\n\n"), stderr); 518 gen = 1; 519 usage(); 520 exit(CLIENT_ERR_FAIL); 521 break; 522 } 523 524 } 525 526 if ((getuid() != 0) && (!op_genprofile)) { 527 (void) puts( 528 "You must be root (SuperUser) to run this command."); 529 usage(); 530 exit(CLIENT_ERR_FAIL); 531 } 532 533 /* 534 * All command line arguments are finished being parsed now 535 */ 536 537 /* *** Do semantic checking here *** */ 538 539 /* if gen and no no searchBase then err */ 540 if (gen && !optlist->defaultSearchBase) { 541 CLIENT_FPUTS( 542 gettext("ldapclient: Missing required attrName " 543 "defaultSearchBase\n"), 544 stderr); 545 usage(); 546 clientopts_free(optlist); 547 exit(CLIENT_ERR_FAIL); 548 } 549 550 /* 551 * if init or manual, and if adminDN is specified then enableShadowUpdate 552 * must be set to TRUE. 553 */ 554 if ((op_init || op_manual) && 555 (!optlist->enableShadowUpdate || 556 strcasecmp(optlist->enableShadowUpdate, "TRUE") != 0) && 557 (optlist->adminDN || optlist->adminPassword)) { 558 CLIENT_FPUTS( 559 gettext("ldapclient: adminDN and adminPassword must not " 560 "be specified if enableShadowUpdate is not set to TRUE \n"), 561 stderr); 562 usage(); 563 clientopts_free(optlist); 564 exit(CLIENT_ERR_FAIL); 565 } 566 567 /* Only one verb can be specified */ 568 if ((op_init + op_manual + op_mod + op_uninit + 569 op_list + op_genprofile) != 1) { 570 usage(); 571 clientopts_free(optlist); 572 exit(CLIENT_ERR_FAIL); 573 } 574 575 /* *** We passed semantic checking, so now do the operation *** */ 576 577 if (mode_verbose) { 578 CLIENT_FPUTS(gettext("Arguments parsed:\n"), stderr); 579 dumpargs(optlist); 580 } 581 582 583 /* handle "ldapclient list" here. err checking done in func */ 584 if (op_list) { 585 if (mode_verbose) 586 CLIENT_FPUTS( 587 gettext("Handling list option\n"), 588 stderr); 589 retcode = client_list(optlist); 590 } 591 592 /* handle "ldapclient uninit" here */ 593 if (op_uninit) { 594 if (mode_verbose) 595 CLIENT_FPUTS( 596 gettext("Handling uninit option\n"), 597 stderr); 598 retcode = client_uninit(optlist); 599 } 600 601 /* handle "ldapclient init" (profile) */ 602 if (op_init) { 603 if (mode_verbose) 604 CLIENT_FPUTS( 605 gettext("Handling init option\n"), 606 stderr); 607 retcode = client_init(optlist); 608 } 609 610 /* handle "genprofile" here */ 611 if (op_genprofile) { 612 if (mode_verbose) 613 CLIENT_FPUTS( 614 gettext("Handling genProfile\n"), 615 stderr); 616 retcode = client_genProfile(optlist); 617 } 618 619 /* handle "ldapclient manual" here */ 620 if (op_manual) { 621 if (mode_verbose) 622 CLIENT_FPUTS( 623 gettext("Handling manual option\n"), 624 stderr); 625 retcode = client_manual(optlist); 626 } 627 628 /* handle "ldapclient mod" here */ 629 if (op_mod) { 630 if (mode_verbose) 631 CLIENT_FPUTS( 632 gettext("Handling mod option\n"), 633 stderr); 634 retcode = client_mod(optlist); 635 } 636 637 clientopts_free(optlist); 638 if ((retcode == CLIENT_SUCCESS) || 639 (retcode == CLIENT_ERR_FAIL) || 640 (retcode == CLIENT_ERR_CREDENTIAL)) 641 return (retcode); 642 else 643 return (CLIENT_ERR_FAIL); 644 } 645 646 static int 647 client_list(clientopts_t *arglist) 648 { 649 ns_ldap_error_t *errorp; 650 int retcode = CLIENT_SUCCESS; 651 652 if (num_args(arglist) > 0) { 653 CLIENT_FPUTS( 654 gettext("No args supported with \"list\" option\n"), 655 stderr); 656 usage(); 657 return (CLIENT_ERR_FAIL); /* exit code here ? */ 658 } 659 if ((errorp = __ns_ldap_print_config(mode_verbose)) != NULL) { 660 retcode = CLIENT_ERR_FAIL; 661 CLIENT_FPUTS( 662 gettext("Cannot get print configuration\n"), 663 stderr); 664 CLIENT_FPUTS(errorp->message, stderr); 665 (void) __ns_ldap_freeError(&errorp); 666 CLIENT_FPUTC('\n', stderr); 667 } 668 669 return (retcode); 670 } 671 672 static int 673 client_uninit(clientopts_t *arglist) 674 { 675 int retcode = CLIENT_SUCCESS; 676 ns_ldap_self_gssapi_config_t config = NS_LDAP_SELF_GSSAPI_CONFIG_NONE; 677 678 if (mode_verbose) { 679 CLIENT_FPUTS( 680 gettext("Restoring machine to previous " 681 "configuration state\n"), 682 stderr); 683 } 684 685 if (num_args(arglist) > 0) { 686 CLIENT_FPUTS( 687 gettext("No args supported with \"uninit\" option\n"), 688 stderr); 689 usage(); 690 return (CLIENT_ERR_FAIL); 691 } 692 693 (void) __ns_ldap_self_gssapi_config(&config); 694 695 retcode = stop_services(STATE_SAVE); 696 697 if (config != NS_LDAP_SELF_GSSAPI_CONFIG_NONE) 698 (void) system("/usr/sbin/cryptoadm enable metaslot"); 699 700 if (retcode != CLIENT_SUCCESS) { 701 CLIENT_FPUTS( 702 gettext("Errors stopping network services.\n"), stderr); 703 /* restart whatever services we can */ 704 (void) start_services(START_RESET); 705 return (CLIENT_ERR_FAIL); 706 } 707 708 retcode = recover(STATE_SAVE); 709 if (retcode != CLIENT_SUCCESS) { 710 CLIENT_FPUTS( 711 gettext("Cannot recover the configuration on " 712 "this machine.\n"), 713 stderr); 714 (void) start_services(START_RESET); 715 } else { 716 retcode = start_services(START_UNINIT); 717 if (retcode != CLIENT_SUCCESS) { 718 CLIENT_FPUTS( 719 gettext("Config restored but problems " 720 "encountered resetting network " 721 "services.\n"), 722 stderr); 723 } 724 } 725 726 if (retcode == CLIENT_SUCCESS) { 727 CLIENT_FPUTS( 728 gettext("System successfully recovered\n"), 729 stderr); 730 } 731 732 return (retcode); 733 } 734 735 /* 736 * The following macro is used to do a __ns_ldap_setParam(). 737 * On every call, the return code is checked, and if there was 738 * a problem then the error message is printed, the ldaperr 739 * is freed and we return from the function with the offending 740 * error return code. This macro keeps us from having to 741 * repeat this code for every call to setParam as was done 742 * in the previous incarnation of ldapclient. 743 * 744 * assumes a "retcode" variable is available for status 745 */ 746 #define LDAP_SET_PARAM(argval, argdef) \ 747 retcode = 0; \ 748 if (NULL != argval) { \ 749 ns_ldap_error_t *ldaperr; \ 750 retcode = __ns_ldap_setParam(argdef, (void *)argval, &ldaperr); \ 751 if (retcode != NS_LDAP_SUCCESS) { \ 752 if (NULL != ldaperr) { \ 753 CLIENT_FPUTS(ldaperr->message, stderr); \ 754 CLIENT_FPUTC('\n', stderr); \ 755 (void) __ns_ldap_freeError(&ldaperr); \ 756 } \ 757 return (retcode ? CLIENT_ERR_FAIL : CLIENT_SUCCESS); \ 758 } \ 759 } 760 761 /* 762 * The following macro is used to check if an arg has already been set 763 * and issues an error message, a usage message and then returns an error. 764 * This was made into a macro to avoid the duplication of this code many 765 * times in the function below. 766 */ 767 #define LDAP_CHECK_INVALID(arg, param) \ 768 if (arg) { \ 769 CLIENT_FPRINTF(stderr, gettext("Invalid parameter (%s) " \ 770 "specified\n"), param); \ 771 usage(); \ 772 return (CLIENT_ERR_FAIL); \ 773 } 774 775 static int 776 client_manual(clientopts_t *arglist) 777 { 778 int counter; 779 int domain_fp; 780 ns_ldap_error_t *errorp; 781 int ret_copy; 782 int reset_ret; 783 int retcode = CLIENT_SUCCESS; 784 785 if (dname == NULL) { 786 CLIENT_FPUTS( 787 gettext("Manual failed: System domain not set and " 788 "no domainName specified.\n"), 789 stderr); 790 return (CLIENT_ERR_FAIL); 791 } 792 793 if (arglist->defaultSearchBase == NULL) { 794 CLIENT_FPUTS( 795 gettext("Manual failed: Missing required " 796 "defaultSearchBase attribute.\n"), 797 stderr); 798 return (CLIENT_ERR_FAIL); 799 } 800 801 if ((arglist->defaultServerList == NULL) && 802 (arglist->preferredServerList == NULL)) { 803 CLIENT_FPUTS( 804 gettext("Manual failed: Missing required " 805 "defaultServerList or preferredServerList " 806 "attribute.\n"), 807 stderr); 808 return (CLIENT_ERR_FAIL); 809 } 810 811 if (arglist->profileTTL != NULL) { 812 CLIENT_FPUTS( 813 gettext("Manual aborted: profileTTL is not supported " 814 "in manual mode.\n"), 815 stderr); 816 return (CLIENT_ERR_FAIL); 817 } 818 819 if (arglist->profileName != NULL) { 820 CLIENT_FPUTS( 821 gettext("Manual aborted: profileName is not supported " 822 "in manual mode.\n"), 823 stderr); 824 return (CLIENT_ERR_FAIL); 825 } 826 827 LDAP_CHECK_INVALID(arglist->bindDN, "bind DN"); 828 LDAP_CHECK_INVALID(arglist->bindPasswd, "bind password"); 829 830 __ns_ldap_setServer(TRUE); /* Need this for _ns_setParam() */ 831 __ns_ldap_default_config(); 832 833 /* Set version to latest (not version 1) */ 834 LDAP_SET_PARAM(NS_LDAP_VERSION, NS_LDAP_FILE_VERSION_P); 835 836 /* Set profileTTL to 0 since NO profile on manual */ 837 LDAP_SET_PARAM(CACHETTL_OFF, NS_LDAP_CACHETTL_P); 838 839 /* Set additional valid params from command line */ 840 LDAP_SET_PARAM(arglist->authenticationMethod, NS_LDAP_AUTH_P); 841 LDAP_SET_PARAM(arglist->defaultSearchBase, NS_LDAP_SEARCH_BASEDN_P); 842 LDAP_SET_PARAM(arglist->credentialLevel, NS_LDAP_CREDENTIAL_LEVEL_P); 843 LDAP_SET_PARAM(arglist->proxyDN, NS_LDAP_BINDDN_P); 844 LDAP_SET_PARAM(arglist->enableShadowUpdate, 845 NS_LDAP_ENABLE_SHADOW_UPDATE_P); 846 LDAP_SET_PARAM(arglist->adminDN, NS_LDAP_ADMIN_BINDDN_P); 847 LDAP_SET_PARAM(arglist->searchTimeLimit, NS_LDAP_SEARCH_TIME_P); 848 LDAP_SET_PARAM(arglist->preferredServerList, NS_LDAP_SERVER_PREF_P); 849 LDAP_SET_PARAM(arglist->profileName, NS_LDAP_PROFILE_P); 850 LDAP_SET_PARAM(arglist->followReferrals, NS_LDAP_SEARCH_REF_P); 851 LDAP_SET_PARAM(arglist->defaultSearchScope, NS_LDAP_SEARCH_SCOPE_P); 852 LDAP_SET_PARAM(arglist->bindTimeLimit, NS_LDAP_BIND_TIME_P); 853 LDAP_SET_PARAM(arglist->proxyPassword, NS_LDAP_BINDPASSWD_P); 854 LDAP_SET_PARAM(arglist->adminPassword, NS_LDAP_ADMIN_BINDPASSWD_P); 855 LDAP_SET_PARAM(arglist->defaultServerList, NS_LDAP_SERVERS_P); 856 LDAP_SET_PARAM(arglist->certificatePath, NS_LDAP_HOST_CERTPATH_P); 857 858 for (counter = 0; 859 counter < arglist->serviceAuthenticationMethod->count; 860 counter++) { 861 862 LDAP_SET_PARAM( 863 arglist->serviceAuthenticationMethod->optlist[counter], 864 NS_LDAP_SERVICE_AUTH_METHOD_P); 865 } 866 for (counter = 0; 867 counter < arglist->serviceCredentialLevel->count; 868 counter++) { 869 870 LDAP_SET_PARAM( 871 arglist->serviceCredentialLevel->optlist[counter], 872 NS_LDAP_SERVICE_CRED_LEVEL_P); 873 } 874 for (counter = 0; 875 counter < arglist->objectclassMap->count; 876 counter++) { 877 878 LDAP_SET_PARAM(arglist->objectclassMap->optlist[counter], 879 NS_LDAP_OBJECTCLASSMAP_P); 880 } 881 for (counter = 0; counter < arglist->attributeMap->count; counter++) { 882 LDAP_SET_PARAM(arglist->attributeMap->optlist[counter], 883 NS_LDAP_ATTRIBUTEMAP_P); 884 } 885 for (counter = 0; 886 counter < arglist->serviceSearchDescriptor->count; 887 counter++) { 888 889 LDAP_SET_PARAM( 890 arglist->serviceSearchDescriptor->optlist[counter], 891 NS_LDAP_SERVICE_SEARCH_DESC_P); 892 } 893 894 retcode = credCheck(arglist); 895 if (retcode == CLIENT_SUCCESS) 896 retcode = adminCredCheck(arglist); 897 if (retcode != CLIENT_SUCCESS) { 898 CLIENT_FPUTS( 899 gettext("Error in setting up credentials\n"), 900 stderr); 901 return (retcode); 902 } 903 904 if (mode_verbose) 905 CLIENT_FPUTS( 906 gettext("About to modify this machines " 907 "configuration by writing the files\n"), 908 stderr); 909 910 /* get ready to start playing with files */ 911 retcode = stop_services(STATE_SAVE); 912 if (retcode != CLIENT_SUCCESS) { 913 CLIENT_FPUTS( 914 gettext("Errors stopping network services.\n"), stderr); 915 return (CLIENT_ERR_FAIL); 916 } 917 918 /* Save orig versions of files */ 919 retcode = file_backup(); 920 if (retcode == CLIENT_ERR_RESTORE) { 921 CLIENT_FPUTS( 922 gettext("System not in state to enable ldap client.\n"), 923 stderr); 924 925 reset_ret = start_services(START_RESET); 926 if (reset_ret != CLIENT_SUCCESS) { 927 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 928 "starting services during reset\n"), 929 reset_ret); 930 } 931 return (retcode); 932 } else if (retcode != CLIENT_SUCCESS) { 933 CLIENT_FPUTS( 934 gettext("Save of system configuration failed! " 935 "Attempting recovery.\n"), 936 stderr); 937 retcode = recover(STATE_NOSAVE); 938 if (retcode != CLIENT_SUCCESS) { 939 CLIENT_FPUTS( 940 gettext("Recovery of systems configuration " 941 "failed. Manual intervention of " 942 "config files is required.\n"), 943 stderr); 944 return (retcode); 945 } 946 947 reset_ret = start_services(START_RESET); 948 if (reset_ret != CLIENT_SUCCESS) { 949 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 950 "starting services during reset\n"), 951 reset_ret); 952 } 953 954 return (retcode); 955 } 956 957 /* Dump new files */ 958 errorp = __ns_ldap_DumpConfiguration(NSCONFIGFILE); 959 if (errorp != NULL) { 960 CLIENT_FPRINTF(stderr, 961 gettext("%s manual: errorp is not NULL; %s\n"), 962 cmd, errorp->message); 963 retcode = recover(STATE_NOSAVE); 964 if (retcode != CLIENT_SUCCESS) { 965 CLIENT_FPUTS( 966 gettext("Recovery of systems configuration " 967 "failed. Manual intervention of " 968 "config files is required.\n"), 969 stderr); 970 return (retcode); 971 } 972 reset_ret = start_services(START_RESET); 973 if (reset_ret != CLIENT_SUCCESS) { 974 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 975 "starting services during reset\n"), 976 reset_ret); 977 } 978 (void) __ns_ldap_freeError(&errorp); 979 return (CLIENT_ERR_FAIL); 980 } 981 982 /* if (credargs(arglist)) */ 983 errorp = __ns_ldap_DumpConfiguration(NSCREDFILE); 984 if (errorp != NULL) { 985 CLIENT_FPRINTF(stderr, 986 gettext("%s init: errorp is not NULL; %s\n"), 987 cmd, errorp->message); 988 retcode = recover(STATE_NOSAVE); 989 if (retcode != CLIENT_SUCCESS) { 990 CLIENT_FPUTS( 991 gettext("Recovery of systems configuration " 992 "failed. Manual intervention of " 993 "config files is required.\n"), 994 stderr); 995 return (retcode); 996 } 997 reset_ret = start_services(START_RESET); 998 if (reset_ret != CLIENT_SUCCESS) { 999 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 1000 "starting services during reset\n"), 1001 reset_ret); 1002 } 1003 (void) __ns_ldap_freeError(&errorp); 1004 return (CLIENT_ERR_FAIL); 1005 } 1006 1007 ret_copy = system(CMD_CP " " NSSWITCH_LDAP " " NSSWITCH_CONF); 1008 if (ret_copy != 0) { 1009 CLIENT_FPRINTF(stderr, 1010 gettext("Error %d copying (%s) -> (%s)\n"), 1011 ret_copy, NSSWITCH_LDAP, NSSWITCH_CONF); 1012 retcode = recover(STATE_NOSAVE); 1013 if (retcode != CLIENT_SUCCESS) { 1014 CLIENT_FPUTS( 1015 gettext("Recovery of systems configuration " 1016 "failed. Manual intervention of " 1017 "config files is required.\n"), 1018 stderr); 1019 } 1020 reset_ret = start_services(START_RESET); 1021 if (reset_ret != CLIENT_SUCCESS) { 1022 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 1023 "starting services during reset\n"), 1024 reset_ret); 1025 } 1026 return (CLIENT_ERR_FAIL); 1027 } 1028 1029 if ((domain_fp = open(DOMAINNAME, O_WRONLY|O_CREAT|O_TRUNC, 1030 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1) { /* 0644 */ 1031 CLIENT_FPRINTF(stderr, gettext("Cannot open %s\n"), DOMAINNAME); 1032 retcode = recover(STATE_NOSAVE); 1033 if (retcode != CLIENT_SUCCESS) { 1034 CLIENT_FPUTS( 1035 gettext("Recovery of systems configuration " 1036 "failed. Manual intervention of " 1037 "config files is required.\n"), 1038 stderr); 1039 return (CLIENT_ERR_FAIL); 1040 } 1041 reset_ret = start_services(START_RESET); 1042 if (reset_ret != CLIENT_SUCCESS) { 1043 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 1044 "starting services during reset\n"), 1045 reset_ret); 1046 } 1047 return (CLIENT_ERR_FAIL); 1048 } 1049 (void) write(domain_fp, dname, strlen(dname)); 1050 (void) write(domain_fp, "\n", 1); 1051 (void) close(domain_fp); 1052 1053 retcode = start_services(START_INIT); 1054 1055 if (retcode == CLIENT_SUCCESS) { 1056 CLIENT_FPUTS(gettext("System successfully configured\n"), 1057 stderr); 1058 } else { 1059 CLIENT_FPUTS(gettext("Error resetting system.\n" 1060 "Recovering old system settings.\n"), stderr), 1061 1062 /* stop any started services for recover */ 1063 /* don't stomp on history of saved services state */ 1064 reset_ret = stop_services(STATE_NOSAVE); 1065 if (reset_ret != CLIENT_SUCCESS) { 1066 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 1067 "stopping services during reset\n"), 1068 reset_ret); 1069 /* Coninue and try to recover what we can */ 1070 } 1071 reset_ret = recover(STATE_NOSAVE); 1072 if (reset_ret != CLIENT_SUCCESS) { 1073 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 1074 "recovering service files during " 1075 "reset\n"), reset_ret); 1076 /* Continue and start what we can */ 1077 } 1078 reset_ret = start_services(START_RESET); 1079 if (reset_ret != CLIENT_SUCCESS) { 1080 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 1081 "starting services during reset\n"), 1082 reset_ret); 1083 } 1084 } 1085 1086 return (retcode); 1087 } 1088 1089 static int 1090 client_mod(clientopts_t *arglist) 1091 { 1092 int counter; 1093 int domain_fp; 1094 ns_ldap_error_t *errorp; 1095 int reset_ret; 1096 int retcode = CLIENT_SUCCESS; 1097 1098 __ns_ldap_setServer(TRUE); /* Need this for _ns_setParam() */ 1099 if ((errorp = __ns_ldap_LoadConfiguration()) != NULL) { 1100 CLIENT_FPUTS(gettext("Cannot get load configuration\n"), 1101 stderr); 1102 CLIENT_FPUTS(errorp->message, stderr); 1103 CLIENT_FPUTC('\n', stderr); 1104 (void) __ns_ldap_freeError(&errorp); 1105 return (CLIENT_ERR_FAIL); 1106 } 1107 1108 if (arglist->profileTTL != NULL) { 1109 CLIENT_FPUTS( 1110 gettext("Mod aborted: profileTTL modification is " 1111 "not allowed in mod mode.\n"), 1112 stderr); 1113 return (CLIENT_ERR_FAIL); 1114 } 1115 1116 if (arglist->profileName != NULL) { 1117 CLIENT_FPUTS( 1118 gettext("Mod aborted: profileName modification is " 1119 "not allowed. If you want to use profiles " 1120 "generate one with genProfile and load it " 1121 "on the server with ldapadd.\n"), 1122 stderr); 1123 return (CLIENT_ERR_FAIL); 1124 } 1125 1126 LDAP_CHECK_INVALID(arglist->bindDN, "bind DN"); 1127 LDAP_CHECK_INVALID(arglist->bindPasswd, "bind password"); 1128 1129 /* Set additional valid params from command line */ 1130 LDAP_SET_PARAM(arglist->authenticationMethod, NS_LDAP_AUTH_P); 1131 LDAP_SET_PARAM(arglist->defaultSearchBase, NS_LDAP_SEARCH_BASEDN_P); 1132 LDAP_SET_PARAM(arglist->credentialLevel, NS_LDAP_CREDENTIAL_LEVEL_P); 1133 LDAP_SET_PARAM(arglist->proxyDN, NS_LDAP_BINDDN_P); 1134 LDAP_SET_PARAM(arglist->adminDN, NS_LDAP_ADMIN_BINDDN_P); 1135 LDAP_SET_PARAM(arglist->profileTTL, NS_LDAP_CACHETTL_P); 1136 LDAP_SET_PARAM(arglist->searchTimeLimit, NS_LDAP_SEARCH_TIME_P); 1137 LDAP_SET_PARAM(arglist->preferredServerList, NS_LDAP_SERVER_PREF_P); 1138 LDAP_SET_PARAM(arglist->profileName, NS_LDAP_PROFILE_P); 1139 LDAP_SET_PARAM(arglist->followReferrals, NS_LDAP_SEARCH_REF_P); 1140 LDAP_SET_PARAM(arglist->defaultSearchScope, NS_LDAP_SEARCH_SCOPE_P); 1141 LDAP_SET_PARAM(arglist->bindTimeLimit, NS_LDAP_BIND_TIME_P); 1142 LDAP_SET_PARAM(arglist->proxyPassword, NS_LDAP_BINDPASSWD_P); 1143 LDAP_SET_PARAM(arglist->adminPassword, NS_LDAP_ADMIN_BINDPASSWD_P); 1144 LDAP_SET_PARAM(arglist->defaultServerList, NS_LDAP_SERVERS_P); 1145 LDAP_SET_PARAM(arglist->enableShadowUpdate, 1146 NS_LDAP_ENABLE_SHADOW_UPDATE_P); 1147 LDAP_SET_PARAM(arglist->certificatePath, NS_LDAP_HOST_CERTPATH_P); 1148 1149 for (counter = 0; 1150 counter < arglist->serviceAuthenticationMethod->count; 1151 counter++) { 1152 1153 LDAP_SET_PARAM( 1154 arglist->serviceAuthenticationMethod->optlist[counter], 1155 NS_LDAP_SERVICE_AUTH_METHOD_P); 1156 } 1157 for (counter = 0; 1158 counter < arglist->serviceCredentialLevel->count; 1159 counter++) { 1160 1161 LDAP_SET_PARAM( 1162 arglist->serviceCredentialLevel->optlist[counter], 1163 NS_LDAP_SERVICE_CRED_LEVEL_P); 1164 } 1165 for (counter = 0; 1166 counter < arglist->objectclassMap->count; 1167 counter++) { 1168 1169 LDAP_SET_PARAM( 1170 arglist->objectclassMap->optlist[counter], 1171 NS_LDAP_OBJECTCLASSMAP_P); 1172 } 1173 for (counter = 0; 1174 counter < arglist->attributeMap->count; 1175 counter++) { 1176 1177 LDAP_SET_PARAM( 1178 arglist->attributeMap->optlist[counter], 1179 NS_LDAP_ATTRIBUTEMAP_P); 1180 } 1181 for (counter = 0; 1182 counter < arglist->serviceSearchDescriptor->count; 1183 counter++) { 1184 1185 LDAP_SET_PARAM( 1186 arglist->serviceSearchDescriptor->optlist[counter], 1187 NS_LDAP_SERVICE_SEARCH_DESC_P); 1188 } 1189 1190 retcode = credCheck(arglist); 1191 if (retcode == CLIENT_SUCCESS) 1192 retcode = adminCredCheck(arglist); 1193 if (retcode != CLIENT_SUCCESS) { 1194 CLIENT_FPUTS( 1195 gettext("Error in setting up credentials\n"), 1196 stderr); 1197 return (retcode); 1198 } 1199 1200 if (mode_verbose) 1201 CLIENT_FPUTS( 1202 gettext("About to modify this machines configuration " 1203 "by writing the files\n"), 1204 stderr); 1205 1206 /* get ready to start playing with files */ 1207 retcode = stop_services(STATE_SAVE); 1208 if (retcode != CLIENT_SUCCESS) { 1209 CLIENT_FPUTS( 1210 gettext("Errors stopping network services.\n"), stderr); 1211 return (CLIENT_ERR_FAIL); 1212 } 1213 1214 /* Temporarily save orig versions of files */ 1215 retcode = mod_backup(); 1216 if (retcode != CLIENT_SUCCESS) { 1217 CLIENT_FPUTS( 1218 gettext("Unable to backup the ldap client files!\n"), 1219 stderr); 1220 1221 return (retcode); 1222 1223 } 1224 1225 /* Dump new files */ 1226 errorp = __ns_ldap_DumpConfiguration(NSCONFIGFILE); 1227 if (errorp != NULL) { 1228 CLIENT_FPRINTF(stderr, 1229 gettext("%s mod: errorp is not NULL; %s\n"), 1230 cmd, errorp->message); 1231 retcode = mod_recover(); 1232 if (retcode != CLIENT_SUCCESS) { 1233 CLIENT_FPUTS( 1234 gettext("Recovery of systems configuration " 1235 "failed. Manual intervention of " 1236 "config files is required.\n"), 1237 stderr); 1238 } 1239 (void) __ns_ldap_freeError(&errorp); 1240 reset_ret = start_services(START_RESET); 1241 if (reset_ret != CLIENT_SUCCESS) { 1242 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 1243 "starting services during reset\n"), 1244 reset_ret); 1245 } 1246 return (CLIENT_ERR_FAIL); 1247 } 1248 1249 /* if (credargs(arglist)) */ 1250 errorp = __ns_ldap_DumpConfiguration(NSCREDFILE); 1251 if (errorp != NULL) { 1252 CLIENT_FPRINTF(stderr, 1253 gettext("%s mod: errorp is not NULL; %s\n"), 1254 cmd, errorp->message); 1255 retcode = mod_recover(); 1256 if (retcode != CLIENT_SUCCESS) { 1257 CLIENT_FPUTS( 1258 gettext("Recovery of systems configuration " 1259 "failed. Manual intervention of " 1260 "config files is required.\n"), 1261 stderr); 1262 } 1263 (void) __ns_ldap_freeError(&errorp); 1264 reset_ret = start_services(START_RESET); 1265 if (reset_ret != CLIENT_SUCCESS) { 1266 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 1267 "starting services during reset\n"), 1268 reset_ret); 1269 } 1270 return (CLIENT_ERR_FAIL); 1271 } 1272 1273 if ((domain_fp = open(DOMAINNAME, O_WRONLY|O_CREAT|O_TRUNC, 1274 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1) { /* 0644 */ 1275 CLIENT_FPRINTF(stderr, gettext("Cannot open %s\n"), DOMAINNAME); 1276 retcode = mod_recover(); 1277 if (retcode != CLIENT_SUCCESS) { 1278 CLIENT_FPUTS( 1279 gettext("Recovery of systems configuration " 1280 "failed! Machine needs to be " 1281 "fixed!\n"), 1282 stderr); 1283 } 1284 reset_ret = start_services(START_RESET); 1285 if (reset_ret != CLIENT_SUCCESS) { 1286 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 1287 "starting services during reset\n"), 1288 reset_ret); 1289 } 1290 return (CLIENT_ERR_FAIL); 1291 } 1292 (void) write(domain_fp, dname, strlen(dname)); 1293 (void) write(domain_fp, "\n", 1); 1294 (void) close(domain_fp); 1295 1296 retcode = start_services(START_INIT); 1297 1298 if (retcode == CLIENT_SUCCESS) { 1299 CLIENT_FPUTS(gettext("System successfully configured\n"), 1300 stderr); 1301 } else { 1302 CLIENT_FPUTS(gettext("Error resetting system.\n" 1303 "Recovering old system settings.\n"), stderr), 1304 1305 /* stop any started services for recover */ 1306 /* don't stomp on history of saved services state */ 1307 reset_ret = stop_services(STATE_NOSAVE); 1308 if (reset_ret != CLIENT_SUCCESS) { 1309 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 1310 "stopping services during reset\n"), 1311 reset_ret); 1312 /* Coninue and try to recover what we can */ 1313 } 1314 reset_ret = mod_recover(); 1315 if (reset_ret != CLIENT_SUCCESS) { 1316 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 1317 "recovering service files during " 1318 "reset\n"), reset_ret); 1319 /* Continue and start what we can */ 1320 } 1321 reset_ret = start_services(START_RESET); 1322 if (reset_ret != CLIENT_SUCCESS) { 1323 CLIENT_FPRINTF(stderr, gettext("Error (%d) while " 1324 "starting services during reset\n"), 1325 reset_ret); 1326 } 1327 } 1328 1329 /* Cleanup temporary files created by mod_backup() */ 1330 mod_cleanup(); 1331 1332 return (retcode); 1333 } 1334 1335 1336 static int 1337 client_genProfile(clientopts_t *arglist) 1338 { 1339 int counter; 1340 int retcode; /* required for LDAP_SET_PARAM macro */ 1341 ns_ldap_error_t *errorp; 1342 1343 if (mode_verbose) 1344 CLIENT_FPUTS(gettext("About to generate a profile\n"), stderr); 1345 1346 /* *** Check for invalid args *** */ 1347 LDAP_CHECK_INVALID(arglist->proxyDN, "proxyDN"); 1348 LDAP_CHECK_INVALID(arglist->proxyPassword, "proxyPassword"); 1349 LDAP_CHECK_INVALID(arglist->enableShadowUpdate, 1350 "enableShadowUpdate"); 1351 LDAP_CHECK_INVALID(arglist->adminDN, "adminDN"); 1352 LDAP_CHECK_INVALID(arglist->adminPassword, "adminPassword"); 1353 LDAP_CHECK_INVALID(arglist->certificatePath, "certificatePath"); 1354 LDAP_CHECK_INVALID(arglist->domainName, "domainName"); 1355 LDAP_CHECK_INVALID(arglist->bindDN, "bind DN"); 1356 LDAP_CHECK_INVALID(arglist->bindPasswd, "bind password"); 1357 /* *** End check for invalid args *** */ 1358 1359 if (arglist->profileName == NULL) { 1360 if (mode_verbose) 1361 CLIENT_FPUTS( 1362 gettext("No profile specified. " 1363 "Using \"default\"\n"), 1364 stderr); 1365 arglist->profileName = "default"; 1366 } 1367 1368 __ns_ldap_setServer(TRUE); 1369 __ns_ldap_default_config(); 1370 1371 /* Set version to latest (not version 1) */ 1372 LDAP_SET_PARAM(NS_LDAP_VERSION, NS_LDAP_FILE_VERSION_P); 1373 1374 /* Set additional valid params from command line */ 1375 LDAP_SET_PARAM(arglist->authenticationMethod, NS_LDAP_AUTH_P); 1376 LDAP_SET_PARAM(arglist->defaultSearchBase, NS_LDAP_SEARCH_BASEDN_P); 1377 LDAP_SET_PARAM(arglist->credentialLevel, NS_LDAP_CREDENTIAL_LEVEL_P); 1378 LDAP_SET_PARAM(arglist->profileTTL, NS_LDAP_CACHETTL_P); 1379 LDAP_SET_PARAM(arglist->searchTimeLimit, NS_LDAP_SEARCH_TIME_P); 1380 LDAP_SET_PARAM(arglist->preferredServerList, NS_LDAP_SERVER_PREF_P); 1381 LDAP_SET_PARAM(arglist->profileName, NS_LDAP_PROFILE_P); 1382 LDAP_SET_PARAM(arglist->followReferrals, NS_LDAP_SEARCH_REF_P); 1383 LDAP_SET_PARAM(arglist->defaultSearchScope, NS_LDAP_SEARCH_SCOPE_P); 1384 LDAP_SET_PARAM(arglist->bindTimeLimit, NS_LDAP_BIND_TIME_P); 1385 LDAP_SET_PARAM(arglist->defaultServerList, NS_LDAP_SERVERS_P); 1386 1387 for (counter = 0; 1388 counter < arglist->serviceAuthenticationMethod->count; 1389 counter++) { 1390 1391 LDAP_SET_PARAM( 1392 arglist->serviceAuthenticationMethod->optlist[counter], 1393 NS_LDAP_SERVICE_AUTH_METHOD_P); 1394 } 1395 for (counter = 0; 1396 counter < arglist->serviceCredentialLevel->count; 1397 counter++) { 1398 1399 LDAP_SET_PARAM( 1400 arglist->serviceCredentialLevel->optlist[counter], 1401 NS_LDAP_SERVICE_CRED_LEVEL_P); 1402 } 1403 for (counter = 0; 1404 counter < arglist->objectclassMap->count; 1405 counter++) { 1406 1407 LDAP_SET_PARAM( 1408 arglist->objectclassMap->optlist[counter], 1409 NS_LDAP_OBJECTCLASSMAP_P); 1410 } 1411 for (counter = 0; 1412 counter < arglist->attributeMap->count; 1413 counter++) { 1414 1415 LDAP_SET_PARAM( 1416 arglist->attributeMap->optlist[counter], 1417 NS_LDAP_ATTRIBUTEMAP_P); 1418 } 1419 for (counter = 0; 1420 counter < arglist->serviceSearchDescriptor->count; 1421 counter++) { 1422 1423 LDAP_SET_PARAM( 1424 arglist->serviceSearchDescriptor->optlist[counter], 1425 NS_LDAP_SERVICE_SEARCH_DESC_P); 1426 } 1427 1428 errorp = __ns_ldap_DumpLdif(NULL); 1429 if (errorp != NULL) { 1430 CLIENT_FPUTS(errorp->message, stderr); 1431 CLIENT_FPUTC('\n', stderr); 1432 (void) __ns_ldap_freeError(&errorp); 1433 return (CLIENT_ERR_FAIL); 1434 } 1435 1436 return (CLIENT_SUCCESS); 1437 } 1438 1439 /* INET6_ADDRSTRLEN + ":" + <5-digit port> + some round-up */ 1440 #define MAX_HOSTADDR_LEN (INET6_ADDRSTRLEN + 6 + 12) 1441 1442 static int 1443 client_init(clientopts_t *arglist) 1444 { 1445 int profile_fp; 1446 int retcode = CLIENT_SUCCESS; 1447 ns_ldap_error_t *errorp; 1448 int reset_ret; 1449 int ret_copy; 1450 ns_standalone_conf_t cfg = standaloneDefaults; 1451 ns_auth_t auth = {NS_LDAP_AUTH_NONE, 1452 NS_LDAP_TLS_NONE, 1453 NS_LDAP_SASL_NONE, 1454 NS_LDAP_SASLOPT_NONE}; 1455 char peer[MAX_HOSTADDR_LEN]; 1456 ns_auth_t **authMethod; 1457 int **credLevel, i; 1458 char *cred; 1459 1460 if (mode_verbose) 1461 CLIENT_FPUTS( 1462 gettext("About to configure machine by downloading " 1463 "a profile\n"), 1464 stderr); 1465 1466 if (dname == NULL) { 1467 CLIENT_FPUTS( 1468 gettext("Init failed: System domain not set and " 1469 "no domainName specified.\n"), 1470 stderr); 1471 return (CLIENT_ERR_FAIL); 1472 } 1473 1474 if (!arglist->defaultServerList) { 1475 CLIENT_FPUTS(gettext("Missing LDAP server address\n"), stderr); 1476 return (CLIENT_ERR_FAIL); 1477 } 1478 1479 /* *** Check for invalid args *** */ 1480 LDAP_CHECK_INVALID(arglist->defaultSearchBase, 1481 "defaultSearchBase"); 1482 LDAP_CHECK_INVALID(arglist->profileTTL, 1483 "profileTTL"); 1484 LDAP_CHECK_INVALID(arglist->searchTimeLimit, 1485 "searchTimeLimit"); 1486 LDAP_CHECK_INVALID(arglist->preferredServerList, 1487 "preferredServerList"); 1488 LDAP_CHECK_INVALID(arglist->followReferrals, 1489 "followReferrals"); 1490 LDAP_CHECK_INVALID(arglist->defaultSearchScope, 1491 "defaultSearchScope"); 1492 LDAP_CHECK_INVALID(arglist->bindTimeLimit, 1493 "bindTimeLimit"); 1494 1495 LDAP_CHECK_INVALID(arglist->objectclassMap->count, 1496 "objectclassMap"); 1497 LDAP_CHECK_INVALID(arglist->attributeMap->count, 1498 "attributeMap"); 1499 LDAP_CHECK_INVALID(arglist->serviceAuthenticationMethod->count, 1500 "serviceAuthenticationMethod"); 1501 LDAP_CHECK_INVALID(arglist->serviceCredentialLevel->count, 1502 "serviceCredentialLevel"); 1503 LDAP_CHECK_INVALID(arglist->serviceSearchDescriptor->count, 1504 "serviceSearchDescriptor"); 1505 /* *** End check for invalid args *** */ 1506 1507 if (arglist->profileName == NULL) { 1508 if (mode_verbose) 1509 CLIENT_FPUTS( 1510 gettext("No profile specified. " 1511 "Using \"default\"\n"), 1512 stderr); 1513 arglist->profileName = "default"; 1514 } 1515 1516 (void) strncpy(peer, arglist->defaultServerList, MAX_HOSTADDR_LEN - 1); 1517 if (separatePort(peer, &cfg.SA_SERVER, &cfg.SA_PORT) > 0) { 1518 return (CLIENT_ERR_FAIL); 1519 } 1520 1521 if (arglist->bindDN != NULL) { 1522 cfg.SA_CRED = "proxy"; 1523 /* 1524 * We don't want to force users to always specify authentication 1525 * method when we can infer it. If users want SSL, he/she would 1526 * have to specify appropriate -a though. 1527 */ 1528 auth.type = NS_LDAP_AUTH_SIMPLE; 1529 if (arglist->bindPasswd == NULL) { 1530 arglist->bindPasswd = 1531 getpassphrase("Bind Password:"); 1532 if (arglist->bindPasswd == NULL) { 1533 CLIENT_FPUTS(gettext("Get password failed\n"), 1534 stderr); 1535 1536 if (gStartLdap == START_RESET) 1537 (void) start_service(LDAP_FMRI, B_TRUE); 1538 1539 return (CLIENT_ERR_CREDENTIAL); 1540 } 1541 } 1542 } 1543 cfg.SA_BIND_DN = arglist->bindDN; 1544 cfg.SA_BIND_PWD = arglist->bindPasswd; 1545 1546 if (arglist->authenticationMethod != NULL) { 1547 if (__ns_ldap_initAuth(arglist->authenticationMethod, 1548 &auth, &errorp) != NS_LDAP_SUCCESS) { 1549 if (errorp != NULL) { 1550 CLIENT_FPRINTF(stderr, "%s", errorp->message); 1551 (void) __ns_ldap_freeError(&errorp); 1552 } 1553 1554 if (gStartLdap == START_RESET) 1555 (void) start_service(LDAP_FMRI, B_TRUE); 1556 1557 return (CLIENT_ERR_FAIL); 1558 } 1559 cfg.SA_AUTH = &auth; 1560 } 1561 cfg.SA_CRED = arglist->credentialLevel; 1562 1563 cfg.SA_DOMAIN = arglist->domainName; 1564 cfg.SA_PROFILE_NAME = arglist->profileName; 1565 cfg.SA_CERT_PATH = arglist->certificatePath; 1566 1567 cfg.type = NS_LDAP_SERVER; 1568 1569 if (__ns_ldap_initStandalone(&cfg, &errorp) != NS_LDAP_SUCCESS) { 1570 if (errorp != NULL) { 1571 CLIENT_FPRINTF(stderr, "%s", errorp->message); 1572 (void) __ns_ldap_freeError(&errorp); 1573 } 1574 1575 if (gStartLdap == START_RESET) 1576 (void) start_service(LDAP_FMRI, B_TRUE); 1577 1578 return (CLIENT_ERR_FAIL); 1579 } 1580 1581 if (arglist->proxyDN != NULL && arglist->proxyPassword == NULL) { 1582 arglist->proxyPassword = getpassphrase("Proxy Bind Password:"); 1583 if (arglist->proxyPassword == NULL) { 1584 CLIENT_FPUTS(gettext("Get password failed\n"), stderr); 1585 1586 if (gStartLdap == START_RESET) 1587 (void) start_service(LDAP_FMRI, B_TRUE); 1588 1589 return (CLIENT_ERR_CREDENTIAL); 1590 } 1591 } 1592 if (arglist->proxyDN != NULL && arglist->proxyPassword != NULL) { 1593 if (__ns_ldap_setParam(NS_LDAP_BINDDN_P, 1594 arglist->proxyDN, &errorp) != NS_LDAP_SUCCESS) { 1595 if (errorp != NULL) { 1596 CLIENT_FPRINTF(stderr, "%s", errorp->message); 1597 (void) __ns_ldap_freeError(&errorp); 1598 } 1599 return (CLIENT_ERR_CREDENTIAL); 1600 } 1601 if (__ns_ldap_setParam(NS_LDAP_BINDPASSWD_P, 1602 arglist->proxyPassword, &errorp) != NS_LDAP_SUCCESS) { 1603 if (errorp != NULL) { 1604 CLIENT_FPRINTF(stderr, "%s", errorp->message); 1605 (void) __ns_ldap_freeError(&errorp); 1606 } 1607 return (CLIENT_ERR_CREDENTIAL); 1608 } 1609 } 1610 1611 if (arglist->enableShadowUpdate != NULL) { 1612 LDAP_SET_PARAM(arglist->enableShadowUpdate, 1613 NS_LDAP_ENABLE_SHADOW_UPDATE_P); 1614 } 1615 1616 if (arglist->enableShadowUpdate && 1617 strcasecmp(arglist->enableShadowUpdate, "TRUE") == 0 && 1618 arglist->adminDN != NULL && arglist->adminPassword == NULL) { 1619 arglist->adminPassword = getpassphrase("admin Bind Password:"); 1620 if (arglist->adminPassword == NULL) { 1621 CLIENT_FPUTS(gettext("Get password failed\n"), stderr); 1622 1623 if (gStartLdap == START_RESET) 1624 (void) start_service(LDAP_FMRI, B_TRUE); 1625 1626 return (CLIENT_ERR_CREDENTIAL); 1627 } 1628 } 1629 if (arglist->adminDN != NULL && arglist->adminPassword != NULL) { 1630 if (__ns_ldap_setParam(NS_LDAP_ADMIN_BINDDN_P, 1631 arglist->adminDN, &errorp) != NS_LDAP_SUCCESS) { 1632 if (errorp != NULL) { 1633 CLIENT_FPRINTF(stderr, "%s\n", errorp->message); 1634 (void) __ns_ldap_freeError(&errorp); 1635 } 1636 return (CLIENT_ERR_CREDENTIAL); 1637 } 1638 if (__ns_ldap_setParam(NS_LDAP_ADMIN_BINDPASSWD_P, 1639 arglist->adminPassword, &errorp) != NS_LDAP_SUCCESS) { 1640 if (errorp != NULL) { 1641 CLIENT_FPRINTF(stderr, "%s\n", errorp->message); 1642 (void) __ns_ldap_freeError(&errorp); 1643 } 1644 return (CLIENT_ERR_CREDENTIAL); 1645 } 1646 } 1647 1648 if (arglist->authenticationMethod != NULL) { 1649 if (__ns_ldap_getParam(NS_LDAP_AUTH_P, 1650 (void ***)&authMethod, &errorp) != NS_LDAP_SUCCESS) { 1651 if (errorp != NULL) { 1652 CLIENT_FPRINTF(stderr, "%s", errorp->message); 1653 (void) __ns_ldap_freeError(&errorp); 1654 } 1655 return (CLIENT_ERR_CREDENTIAL); 1656 } 1657 1658 if (authMethod != NULL) { 1659 for (i = 0; authMethod[i] != NULL; ++i) { 1660 if (authMethod[i]->type == auth.type) { 1661 break; 1662 } 1663 } 1664 1665 if (authMethod[i] == NULL) { 1666 CLIENT_FPRINTF(stderr, gettext( 1667 "Warning: init authentication method " 1668 "not found in DUAConfigProfile.\n")); 1669 } else { 1670 if (i != 0) { 1671 CLIENT_FPRINTF(stderr, 1672 gettext( 1673 "Warning: init authentication" 1674 "method using secondary " 1675 "authentication method from " 1676 "DUAConfigProfile.\n")); 1677 } 1678 } 1679 (void) __ns_ldap_freeParam((void ***) &authMethod); 1680 } 1681 } 1682 1683 if (arglist->credentialLevel != NULL) { 1684 if (__ns_ldap_getParam(NS_LDAP_CREDENTIAL_LEVEL_P, 1685 (void ***)&credLevel, &errorp) != NS_LDAP_SUCCESS) { 1686 if (errorp != NULL) { 1687 CLIENT_FPRINTF(stderr, "%s", errorp->message); 1688 (void) __ns_ldap_freeError(&errorp); 1689 } 1690 return (CLIENT_ERR_CREDENTIAL); 1691 } 1692 if (credLevel != NULL) { 1693 for (i = 0; credLevel[i] != NULL; ++i) { 1694 switch (*credLevel[i]) { 1695 case NS_LDAP_CRED_ANON : 1696 cred = "none"; 1697 break; 1698 case NS_LDAP_CRED_PROXY : 1699 cred = "proxy"; 1700 break; 1701 case NS_LDAP_CRED_SELF : 1702 cred = "self"; 1703 break; 1704 default: 1705 continue; 1706 break; 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