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