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