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