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