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