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 2001-2003 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 #include <stdio.h> 30 #include <string.h> 31 #include <stdlib.h> 32 #include <ctype.h> 33 #include <fcntl.h> 34 #include <unistd.h> 35 #include <errno.h> 36 #include <locale.h> 37 #include <sys/stat.h> 38 #include <lber.h> 39 #include <ldap.h> 40 #include <deflt.h> 41 42 #include "ldap_map.h" 43 44 #include "ldap_parse.h" 45 #include "ldap_glob.h" 46 #include "nis_parse_ldap_conf.h" 47 48 __nis_ldap_proxy_info proxyInfo = 49 {NULL, (auth_method_t)NO_VALUE_SET, (tls_method_t)NO_VALUE_SET, NULL, 50 NULL, NULL, NULL, NULL, (follow_referral_t)NO_VALUE_SET}; 51 __nis_config_t ldapConfig; 52 __nisdb_table_mapping_t ldapDBTableMapping; 53 __nis_table_mapping_t *ldapTableMapping = NULL; 54 __yp_domain_context_t ypDomains; 55 56 parse_error p_error = no_parse_error; 57 int cur_line_num = 0; 58 int start_line_num = 0; 59 int seq_num = 0; 60 const char *warn_file = NULL; 61 62 char _key_val[38]; 63 const char *command_line_source = NULL; 64 const char *file_source = NULL; 65 const char *ldap_source = NULL; 66 67 static 68 const char *const *cmdline_config = NULL; 69 static bool_t got_config_data = FALSE; 70 71 /* high level parsing functions functions */ 72 static int parse_ldap_cmd_line(const char *const *cmdline_options, 73 __nis_ldap_proxy_info *proxy_info, __nis_config_t *nis_config, 74 __nis_table_mapping_t **table_mapping, __nis_config_info_t *config_info, 75 __nisdb_table_mapping_t *table_info); 76 static int parse_ldap_default_conf(__nis_ldap_proxy_info *proxy_info, 77 __nis_config_t *nis_config, __nis_config_info_t *config_info, 78 __nisdb_table_mapping_t *table_info); 79 static int parse_ldap_config_file(const char *config_file, 80 __nis_ldap_proxy_info *proxy_info, __nis_config_t *nis_config, 81 __nis_table_mapping_t **table_mapping, __nis_config_info_t *config_info, 82 __nisdb_table_mapping_t *table_info); 83 static int parse_ldap_config_dn_attrs(__nis_ldap_proxy_info *proxy_info, 84 __nis_config_t *nis_config, __nis_table_mapping_t **table_mapping, 85 __nis_config_info_t *config_info, __nisdb_table_mapping_t *table_info); 86 static int yp_parse_ldap_default_conf(__nis_ldap_proxy_info *proxy_info, 87 __nis_config_t *nis_config, __nis_config_info_t *config_info, 88 __nisdb_table_mapping_t *table_info); 89 90 91 /* helper functions */ 92 static config_key get_attrib_num_cmdline(const char *s, 93 const char **begin_s, const char **end_s); 94 static config_key get_file_attr_val(int fd, char **attr_val); 95 static void get_attribute_list( 96 const __nis_ldap_proxy_info *proxy_info, 97 const __nis_config_t *nis_config, 98 const __nis_config_info_t *config_info, 99 const __nisdb_table_mapping_t *table_info, 100 char **ldap_config_attributes); 101 102 /* 103 * FUNCTION: parse_ldap_migration 104 * 105 * Parses the information for LDAP. The values are first 106 * obtained from the command line, secondly from the preference 107 * file, and finally from an LDAP profile (if so configured in 108 * the command line or preference file). Any unset values will 109 * be set to their default values. 110 * 111 * If no command line options, no settings in the /etc/default 112 * configuration file, and no mapping file, then no mapping 113 * should be used. 114 * 115 * RETURN VALUE: 116 * 0 Success 117 * -1 Config file stat/open or parse error 118 * 1 No mapping should be used. 119 * 120 * INPUT: command line parameters, configuration file 121 */ 122 123 int 124 parse_ldap_migration( 125 const char *const *cmdline_options, 126 const char *config_file) 127 { 128 int rc = 0; 129 __nis_config_info_t config_info 130 = {NULL, NULL, (auth_method_t)NO_VALUE_SET, 131 (tls_method_t)NO_VALUE_SET, NULL, 132 NULL, NULL}; 133 struct stat buf; 134 int i = 0; 135 136 p_error = no_parse_error; 137 138 if (verbose) 139 report_info("Getting LDAP configuration", NULL); 140 141 initialize_parse_structs(&proxyInfo, &ldapConfig, &ldapDBTableMapping); 142 143 if (yp2ldap) 144 initialize_yp_parse_structs(&ypDomains); 145 146 if (cmdline_options != NULL) { 147 got_config_data = TRUE; 148 /* NIS to LDAP does not read command line attributes */ 149 if (!yp2ldap) 150 rc = parse_ldap_cmd_line(cmdline_options, &proxyInfo, 151 &ldapConfig, &ldapTableMapping, &config_info, 152 &ldapDBTableMapping); 153 else 154 rc = 0; 155 } 156 157 if (rc == 0) { 158 if (yp2ldap) 159 rc = yp_parse_ldap_default_conf(&proxyInfo, &ldapConfig, 160 &config_info, &ldapDBTableMapping); 161 else 162 rc = parse_ldap_default_conf(&proxyInfo, &ldapConfig, 163 &config_info, &ldapDBTableMapping); 164 } 165 166 if (config_file == NULL) { 167 if (yp2ldap) { 168 if (stat(YP_DEFAULT_MAPPING_FILE, &buf) == 0) 169 config_file = YP_DEFAULT_MAPPING_FILE; 170 } else { 171 if (stat(DEFAULT_MAPPING_FILE, &buf) == 0) 172 config_file = DEFAULT_MAPPING_FILE; 173 } 174 } 175 176 if (rc == 0 && config_file != NULL) { 177 got_config_data = TRUE; 178 warn_file = config_file; 179 cmdline_config = cmdline_options; 180 if (yp2ldap) 181 rc = yp_parse_ldap_config_file(config_file, &proxyInfo, 182 &ldapConfig, &ldapTableMapping, &config_info, 183 &ldapDBTableMapping, &ypDomains); 184 else 185 rc = parse_ldap_config_file(config_file, &proxyInfo, 186 &ldapConfig, &ldapTableMapping, &config_info, 187 &ldapDBTableMapping); 188 189 warn_file = NULL; 190 cmdline_config = NULL; 191 } 192 if (rc == 0 && (config_info.config_dn != NULL) && 193 (config_info.config_dn[0] != '\0')) { 194 rc = parse_ldap_config_dn_attrs(&proxyInfo, 195 &ldapConfig, &ldapTableMapping, &config_info, 196 &ldapDBTableMapping); 197 } 198 199 free_config_info(&config_info); 200 201 if (rc == 0 && got_config_data == FALSE) 202 rc = 1; 203 204 set_default_values(&proxyInfo, &ldapConfig, &ldapDBTableMapping); 205 206 if (yp2ldap == 1 && rc == 0) { 207 rc = second_parser_pass(&ldapTableMapping); 208 if (rc == 0) 209 rc = final_parser_pass(&ldapTableMapping, &ypDomains); 210 if (rc == -2) 211 return (-1); 212 } 213 214 if (rc == 0) 215 rc = finish_parse(&proxyInfo, &ldapTableMapping); 216 217 if (rc == 0) 218 rc = linked2hash(ldapTableMapping); 219 220 if (rc != 0) { 221 free_parse_structs(); 222 } else if (verbose) 223 report_info("LDAP configuration complete", NULL); 224 return (rc); 225 } 226 227 /* 228 * FUNCTION: parse_ldap_cmd_line 229 * 230 * Parses the information for LDAP from the command line 231 * 232 * RETURN VALUE: 0 on success, -1 on failure 233 * 234 * INPUT: command line values 235 */ 236 237 static int 238 parse_ldap_cmd_line( 239 const char *const *cmdline_options, 240 __nis_ldap_proxy_info *proxy_info, 241 __nis_config_t *nis_config, 242 __nis_table_mapping_t **table_mapping, 243 __nis_config_info_t *config_info, 244 __nisdb_table_mapping_t *table_info) 245 { 246 int rc = 0; 247 config_key attrib_num; 248 const char *begin_s; 249 const char *end_s; 250 251 if (verbose) 252 report_info("Command line values: ", NULL); 253 while (*cmdline_options != NULL) { 254 if (verbose) 255 report_info("\t", *cmdline_options); 256 257 attrib_num = get_attrib_num_cmdline( 258 *cmdline_options, &begin_s, &end_s); 259 if (attrib_num == key_bad) { 260 command_line_source = "command line"; 261 report_error(*cmdline_options, NULL); 262 command_line_source = NULL; 263 rc = -1; 264 break; 265 } else if (IS_CONFIG_KEYWORD(attrib_num)) { 266 rc = add_config_attribute(attrib_num, 267 begin_s, end_s - begin_s, config_info); 268 } else if (IS_BIND_INFO(attrib_num)) { 269 rc = add_bind_attribute(attrib_num, 270 begin_s, end_s - begin_s, proxy_info); 271 } else if (IS_OPER_INFO(attrib_num)) { 272 rc = add_operation_attribute(attrib_num, 273 begin_s, end_s - begin_s, nis_config, 274 table_info); 275 } else { 276 rc = add_mapping_attribute(attrib_num, 277 begin_s, end_s - begin_s, table_mapping); 278 } 279 280 if (rc < 0) { 281 command_line_source = "command line"; 282 report_error(begin_s, _key_val); 283 command_line_source = NULL; 284 break; 285 } 286 cmdline_options++; 287 } 288 return (rc); 289 } 290 291 static int 292 parse_ldap_default_conf( 293 __nis_ldap_proxy_info *proxy_info, 294 __nis_config_t *nis_config, 295 __nis_config_info_t *config_info, 296 __nisdb_table_mapping_t *table_info) 297 { 298 int rc = 0; 299 char *ldap_config_attributes[n_config_keys]; 300 char attr_buf[128]; 301 char *attr; 302 static char *attr_val; 303 int defflags; 304 config_key attrib_num; 305 int i; 306 int len; 307 int attr_len; 308 309 if (defopen(ETCCONFFILE) == 0) { 310 file_source = ETCCONFFILE; 311 if (verbose) 312 report_info( 313 "default configuration values: ", NULL); 314 /* Set defread() to be case insensitive */ 315 defflags = defcntl(DC_GETFLAGS, 0); 316 TURNOFF(defflags, DC_CASE); 317 (void) defcntl(DC_SETFLAGS, defflags); 318 319 get_attribute_list(proxy_info, nis_config, config_info, 320 table_info, ldap_config_attributes); 321 i = 0; 322 while ((attr = ldap_config_attributes[i++]) != NULL) { 323 strlcpy(attr_buf, attr, sizeof (attr_buf)); 324 /* 325 * if nisplusUpdateBatching, make sure 326 * we don't match nisplusUpdateBatchingTimeout 327 */ 328 if (strcmp(attr, UPDATE_BATCHING) == 0) { 329 attr_len = strlen(attr); 330 attr_buf[attr_len] = '='; 331 attr_buf[attr_len + 1] = '\0'; 332 attr_val = defread(attr_buf); 333 334 if (attr_val == 0) { 335 attr_buf[attr_len] = ' '; 336 attr_val = defread(attr_buf); 337 } 338 if (attr_val == 0) { 339 attr_buf[attr_len] = '\t'; 340 attr_val = defread(attr_buf); 341 } 342 if (attr_val == 0) { 343 attr_buf[attr_len] = '\n'; 344 attr_val = defread(attr_buf); 345 } 346 } else { 347 attr_val = defread(attr_buf); 348 } 349 if (attr_val == 0) 350 continue; 351 352 got_config_data = TRUE; 353 attrib_num = get_attrib_num(attr, strlen(attr)); 354 if (attrib_num == key_bad) { 355 report_error(attr, NULL); 356 rc = -1; 357 break; 358 } 359 360 /* 361 * Allow either entries of the form 362 * attr val 363 * or 364 * attr = val 365 */ 366 while (is_whitespace(*attr_val)) 367 attr_val++; 368 if (*attr_val == '=') 369 attr_val++; 370 while (is_whitespace(*attr_val)) 371 attr_val++; 372 len = strlen(attr_val); 373 while (len > 0 && 374 is_whitespace(attr_val[len - 1])) 375 len--; 376 377 if (verbose) { 378 report_info("\t", attr); 379 report_info("\t\t", attr_val); 380 } 381 if (IS_BIND_INFO(attrib_num)) { 382 rc = add_bind_attribute(attrib_num, 383 attr_val, len, proxy_info); 384 } else if (IS_OPER_INFO(attrib_num)) { 385 rc = add_operation_attribute(attrib_num, 386 attr_val, len, nis_config, 387 table_info); 388 } 389 if (p_error != no_parse_error) { 390 report_error(attr_val, attr); 391 rc = -1; 392 break; 393 } 394 } 395 file_source = NULL; 396 /* Close the /etc/default file */ 397 (void) defopen(0); 398 } 399 return (rc); 400 } 401 402 static int 403 yp_parse_ldap_default_conf( 404 __nis_ldap_proxy_info *proxy_info, 405 __nis_config_t *nis_config, 406 __nis_config_info_t *config_info, 407 __nisdb_table_mapping_t *table_info) 408 { 409 int rc = 0; 410 char *ldap_config_attributes[n_config_keys]; 411 char attr_buf[128]; 412 char *attr; 413 static char *attr_val; 414 int defflags; 415 config_key attrib_num; 416 int i, len, attr_len; 417 418 if ((defopen(YP_ETCCONFFILE)) == 0) { 419 file_source = YP_ETCCONFFILE; 420 if (verbose) 421 report_info("default configuration values: ", NULL); 422 /* Set defread() to be case insensitive */ 423 defflags = defcntl(DC_GETFLAGS, 0); 424 TURNOFF(defflags, DC_CASE); 425 (void) defcntl(DC_SETFLAGS, defflags); 426 427 get_attribute_list(proxy_info, nis_config, config_info, 428 table_info, ldap_config_attributes); 429 i = 0; 430 while ((attr = ldap_config_attributes[i++]) != NULL) { 431 if ((strlcpy(attr_buf, attr, 432 sizeof (attr_buf))) >= 433 sizeof (attr_buf)) { 434 report_error( 435 "Static buffer attr_buf overflow", NULL); 436 return (-1); 437 } 438 439 if ((attr_val = defread(attr_buf)) == 0) 440 continue; 441 442 got_config_data = TRUE; 443 attrib_num = get_attrib_num(attr, strlen(attr)); 444 if (attrib_num == key_bad) { 445 report_error(attr, NULL); 446 rc = -1; 447 break; 448 } 449 450 /* 451 * Allow either entries of the form 452 * attr val 453 * or 454 * attr = val 455 */ 456 while (is_whitespace(*attr_val)) 457 attr_val++; 458 if (*attr_val == '=') 459 attr_val++; 460 while (is_whitespace(*attr_val)) 461 attr_val++; 462 len = strlen(attr_val); 463 while (len > 0 && 464 is_whitespace(attr_val[len - 1])) 465 len--; 466 467 if (verbose) { 468 report_info("\t", attr); 469 report_info("\t\t", attr_val); 470 } 471 if (IS_YP_BIND_INFO(attrib_num)) { 472 rc = add_bind_attribute(attrib_num, 473 attr_val, len, proxy_info); 474 } else if (IS_YP_OPER_INFO(attrib_num)) { 475 rc = add_operation_attribute(attrib_num, 476 attr_val, len, nis_config, 477 table_info); 478 } 479 if (p_error != no_parse_error) { 480 report_error(attr_val, attr); 481 rc = -1; 482 break; 483 } 484 } 485 file_source = NULL; 486 /* Close the /etc/default file */ 487 (void) defopen(0); 488 } 489 return (rc); 490 } 491 492 /* 493 * FUNCTION: get_attrib_num_cmdline 494 * 495 * Parses the information for LDAP from the command line 496 * The form of the command line request is 497 * -x attribute=value 498 * 499 * RETURN VALUE: 0 on success, -1 on failure 500 * 501 * INPUT: command line values 502 */ 503 504 static config_key 505 get_attrib_num_cmdline( 506 const char *s, 507 const char **begin_s, 508 const char **end_s) 509 { 510 const char *s_end = s + strlen(s); 511 const char *equal_s; 512 const char *s1; 513 config_key attrib_num; 514 515 while (s < s_end && is_whitespace(*s)) 516 s++; 517 518 for (equal_s = s; equal_s < s_end; equal_s++) 519 if (*equal_s == EQUAL_CHAR) 520 break; 521 522 if (equal_s == s_end) { 523 p_error = parse_bad_command_line_attribute_format; 524 return (key_bad); 525 } 526 527 for (s1 = equal_s; s1 > s && is_whitespace(s1[-1]); s1--) 528 ; 529 530 if (s1 == s) { 531 p_error = parse_bad_command_line_attribute_format; 532 return (key_bad); 533 } 534 535 attrib_num = get_attrib_num(s, s1 - s); 536 537 if (attrib_num != key_bad) { 538 s1 = equal_s + 1; 539 while (s1 < s_end && is_whitespace(*s1)) 540 s1++; 541 *begin_s = s1; 542 while (s_end > s1 && is_whitespace(s_end[-1])) 543 s_end--; 544 *end_s = s_end; 545 } 546 547 return (attrib_num); 548 } 549 550 /* 551 * FUNCTION: parse_ldap_config_file 552 * 553 * Parses the information for LDAP from a configuration 554 * file. If no file is specified, /var/nis/NIS+LDAPmapping 555 * is used 556 * 557 * RETURN VALUE: 0 on success, -1 on failure 558 * 559 * INPUT: configuration file name 560 */ 561 562 static int 563 parse_ldap_config_file( 564 const char *config_file, 565 __nis_ldap_proxy_info *proxy_info, 566 __nis_config_t *nis_config, 567 __nis_table_mapping_t **table_mapping, 568 __nis_config_info_t *config_info, 569 __nisdb_table_mapping_t *table_info) 570 { 571 int rc = 0; 572 config_key attrib_num; 573 int fd; 574 char *attr_val; 575 int len; 576 577 if ((fd = open(config_file, O_RDONLY)) == -1) { 578 p_error = parse_open_file_error; 579 report_error(config_file, NULL); 580 return (-1); 581 } 582 583 start_line_num = 1; 584 cur_line_num = 1; 585 586 if (verbose) 587 report_info("Reading configuration from ", config_file); 588 589 file_source = config_file; 590 while ((attrib_num = get_file_attr_val(fd, &attr_val)) > 0) { 591 len = attr_val == NULL ? 0 : strlen(attr_val); 592 if (IS_CONFIG_KEYWORD(attrib_num)) { 593 rc = add_config_attribute(attrib_num, 594 attr_val, len, config_info); 595 } else if (IS_BIND_INFO(attrib_num)) { 596 rc = add_bind_attribute(attrib_num, 597 attr_val, len, proxy_info); 598 } else if (IS_OPER_INFO(attrib_num)) { 599 rc = add_operation_attribute(attrib_num, 600 attr_val, len, nis_config, table_info); 601 } else { 602 rc = add_mapping_attribute(attrib_num, 603 attr_val, len, table_mapping); 604 } 605 606 if (rc < 0) { 607 report_error(attr_val == NULL ? 608 "<no attribute>" : attr_val, _key_val); 609 if (attr_val) 610 free(attr_val); 611 break; 612 } 613 if (attr_val) 614 free(attr_val); 615 } 616 617 (void) close(fd); 618 if (attrib_num == key_bad) { 619 report_error(_key_val, NULL); 620 rc = -1; 621 } 622 start_line_num = 0; 623 file_source = NULL; 624 return (rc); 625 } 626 627 /* 628 * FUNCTION: yp_parse_ldap_config_file 629 * 630 * Parses the information for LDAP from a configuration 631 * file. If no file is specified, /var/yp/NISLDAPmapping 632 * is used 633 * 634 * RETURN VALUE: 0 on success, -1 on failure 635 * 636 * INPUT: configuration file name 637 */ 638 639 int 640 yp_parse_ldap_config_file( 641 const char *config_file, 642 __nis_ldap_proxy_info *proxy_info, 643 __nis_config_t *nis_config, 644 __nis_table_mapping_t **table_mapping, 645 __nis_config_info_t *config_info, 646 __nisdb_table_mapping_t *table_info, 647 __yp_domain_context_t *ypDomains) 648 { 649 int rc = 0; 650 int numDomains = 0; 651 config_key attrib_num; 652 int fd; 653 char *attr_val = NULL; 654 int len; 655 656 if ((fd = open(config_file, O_RDONLY)) == -1) { 657 p_error = parse_open_file_error; 658 report_error(config_file, NULL); 659 return (-1); 660 } 661 662 start_line_num = 1; 663 cur_line_num = 1; 664 665 if (verbose) 666 report_info("Reading configuration from ", config_file); 667 668 file_source = config_file; 669 while ((attrib_num = get_file_attr_val(fd, &attr_val)) > 0) { 670 len = attr_val == NULL ? 0 : strlen(attr_val); 671 if (IS_YP_CONFIG_KEYWORD(attrib_num)) { 672 rc = add_config_attribute(attrib_num, 673 attr_val, len, config_info); 674 } else if (IS_YP_BIND_INFO(attrib_num)) { 675 rc = add_bind_attribute(attrib_num, 676 attr_val, len, proxy_info); 677 } else if (IS_YP_OPER_INFO(attrib_num)) { 678 rc = add_operation_attribute(attrib_num, 679 attr_val, len, nis_config, table_info); 680 } else if (IS_YP_DOMAIN_INFO(attrib_num)) { 681 rc = add_ypdomains_attribute(attrib_num, 682 attr_val, len, ypDomains); 683 } else if (IS_YP_MAP_ATTR(attrib_num)) { 684 rc = add_mapping_attribute(attrib_num, 685 attr_val, len, table_mapping); 686 } else { 687 rc = -1; 688 p_error = parse_unsupported_format; 689 } 690 691 if (rc < 0) { 692 report_error(attr_val == NULL ? 693 "<no attribute>" : attr_val, _key_val); 694 if (attr_val) 695 free(attr_val); 696 break; 697 } 698 if (attr_val) { 699 free(attr_val); 700 attr_val = NULL; 701 } 702 } 703 704 (void) close(fd); 705 if (attrib_num == key_bad) { 706 report_error(_key_val, NULL); 707 rc = -1; 708 } 709 start_line_num = 0; 710 file_source = NULL; 711 return (rc); 712 } 713 714 /* 715 * FUNCTION: get_file_attr_val 716 * 717 * Gets the next attribute from the configuration file. 718 * 719 * RETURN VALUE: The config key if more attributes 720 * no_more_keys if eof 721 * key_bad if error 722 */ 723 724 static config_key 725 get_file_attr_val(int fd, char **attr_val) 726 { 727 char buf[BUFSIZE]; 728 char *start_tag; 729 char *start_val; 730 char *end_val; 731 char *cut_here; 732 char *s; 733 char *a; 734 char *attribute_value; 735 int ret; 736 config_key attrib_num = no_more_keys; 737 int found_quote = 0; 738 739 *attr_val = NULL; 740 741 if ((ret = read_line(fd, buf, sizeof (buf))) > 0) { 742 for (s = buf; is_whitespace(*s); s++) 743 ; 744 745 start_tag = s; 746 while (*s != '\0' && !is_whitespace(*s)) 747 s++; 748 749 if (verbose) 750 report_info("\t", start_tag); 751 attrib_num = get_attrib_num(start_tag, s - start_tag); 752 if (attrib_num == key_bad) 753 return (key_bad); 754 755 while (is_whitespace(*s)) 756 s++; 757 if (*s == '\0') 758 return (attrib_num); 759 start_val = s; 760 761 /* note that read_line will not return a line ending with \ */ 762 for (; *s != '\0'; s++) { 763 if (*s == ESCAPE_CHAR) 764 s++; 765 } 766 while (s > start_val && is_whitespace(s[-1])) 767 s--; 768 769 attribute_value = 770 (char *)calloc(1, (size_t)(s - start_val) + 1); 771 if (attribute_value == NULL) { 772 p_error = parse_no_mem_error; 773 return (key_bad); 774 } 775 attr_val[0] = attribute_value; 776 777 a = *attr_val; 778 end_val = s; 779 cut_here = 0; 780 for (s = start_val; s < end_val; s++) { 781 if (*s == POUND_SIGN) { 782 cut_here = s; 783 while (s < end_val) { 784 if (*s == DOUBLE_QUOTE_CHAR || 785 *s == SINGLE_QUOTE_CHAR) { 786 cut_here = 0; 787 break; 788 } 789 s++; 790 } 791 } 792 } 793 if (cut_here != 0) 794 end_val = cut_here; 795 796 for (s = start_val; s < end_val; s++) 797 *a++ = *s; 798 *a++ = '\0'; 799 } 800 if (ret == -1) 801 return (key_bad); 802 803 return (attrib_num); 804 } 805 806 static LDAP * 807 connect_to_ldap_config_server( 808 char *sever_name, 809 int server_port, 810 __nis_config_info_t *config_info) 811 { 812 int rc = 0; 813 LDAP *ld = NULL; 814 int ldapVersion = LDAP_VERSION3; 815 int derefOption = LDAP_DEREF_ALWAYS; 816 int timelimit = LDAP_NO_LIMIT; 817 int sizelimit = LDAP_NO_LIMIT; 818 int errnum; 819 bool_t retrying = FALSE; 820 int sleep_seconds = 1; 821 struct berval cred; 822 823 if (config_info->tls_method == no_tls) { 824 ld = ldap_init(sever_name, server_port); 825 if (ld == NULL) { 826 p_error = parse_ldap_init_error; 827 report_error(strerror(errno), NULL); 828 return (NULL); 829 } 830 } else { 831 if ((errnum = ldapssl_client_init( 832 config_info->tls_cert_db, NULL)) < 0) { 833 p_error = parse_ldapssl_client_init_error; 834 report_error(ldapssl_err2string(errnum), NULL); 835 return (NULL); 836 } 837 ld = ldapssl_init(sever_name, server_port, 1); 838 if (ld == NULL) { 839 p_error = parse_ldapssl_init_error; 840 report_error(strerror(errno), NULL); 841 return (NULL); 842 } 843 } 844 845 (void) ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, 846 &ldapVersion); 847 (void) ldap_set_option(ld, LDAP_OPT_DEREF, &derefOption); 848 (void) ldap_set_option(ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); 849 (void) ldap_set_option(ld, LDAP_OPT_TIMELIMIT, &timelimit); 850 (void) ldap_set_option(ld, LDAP_OPT_SIZELIMIT, &sizelimit); 851 852 /* 853 * Attempt to bind to the LDAP server. 854 * We will loop until success or until an error other 855 * than LDAP_CONNECT_ERROR or LDAP_SERVER_DOWN 856 */ 857 if (verbose) 858 report_info("Connecting to ", sever_name); 859 860 for (;;) { 861 if (config_info->auth_method == simple) { 862 errnum = ldap_simple_bind_s(ld, config_info->proxy_dn, 863 config_info->proxy_passwd); 864 } else if (config_info->auth_method == cram_md5) { 865 cred.bv_len = strlen(config_info->proxy_passwd); 866 cred.bv_val = config_info->proxy_passwd; 867 errnum = ldap_sasl_cram_md5_bind_s(ld, 868 config_info->proxy_dn, &cred, NULL, NULL); 869 } else if (config_info->auth_method == digest_md5) { 870 cred.bv_len = strlen(config_info->proxy_passwd); 871 cred.bv_val = config_info->proxy_passwd; 872 errnum = ldap_x_sasl_digest_md5_bind_s(ld, 873 config_info->proxy_dn, &cred, NULL, NULL); 874 } else { 875 errnum = ldap_simple_bind_s(ld, NULL, NULL); 876 } 877 878 if (errnum == LDAP_SUCCESS) 879 break; 880 881 if (errnum == LDAP_CONNECT_ERROR || 882 errnum == LDAP_SERVER_DOWN) { 883 if (!retrying) { 884 if (verbose) 885 report_info( 886 "LDAP server unavailable. Retrying...", 887 NULL); 888 retrying = TRUE; 889 } 890 (void) sleep(sleep_seconds); 891 sleep_seconds *= 2; 892 if (sleep_seconds > MAX_LDAP_CONFIG_RETRY_TIME) 893 sleep_seconds = MAX_LDAP_CONFIG_RETRY_TIME; 894 p_error = no_parse_error; 895 continue; 896 } 897 p_error = parse_ldap_bind_error; 898 report_error2(config_info->proxy_dn, ldap_err2string(errnum)); 899 (void) ldap_unbind(ld); 900 return (NULL); 901 } 902 903 if (verbose) 904 report_info("Reading values from ", config_info->config_dn); 905 906 return (ld); 907 } 908 909 /* 910 * FUNCTION: process_ldap_config_result 911 * 912 * Extracts the LDAPMessage containing the nis+/LDAP 913 * configuration 914 * 915 * RETURN VALUE: 0 on success, -1 on failure 916 * 917 * INPUT: LDAP the LDAP connection 918 * LDAPMessage the LDAP message 919 */ 920 921 static int 922 process_ldap_config_result( 923 LDAP *ld, 924 LDAPMessage *resultMsg, 925 __nis_ldap_proxy_info *proxy_info, 926 __nis_config_t *nis_config, 927 __nis_table_mapping_t **table_mapping, 928 __nisdb_table_mapping_t *table_info) 929 { 930 LDAPMessage *e; 931 int errnum; 932 char *attr; 933 BerElement *ber = NULL; 934 config_key attrib_num; 935 char **vals; 936 int n; 937 int i; 938 char *attr_val; 939 int len; 940 int rc = 0; 941 bool_t error_reported = FALSE; 942 943 e = ldap_first_entry(ld, resultMsg); 944 945 if (e != NULL) { 946 for (attr = ldap_first_attribute(ld, e, &ber); 947 attr != NULL; 948 attr = ldap_next_attribute(ld, e, ber)) { 949 if (verbose) 950 report_info("\t", attr); 951 attrib_num = get_attrib_num(attr, strlen(attr)); 952 if (attrib_num == key_bad) { 953 report_error(attr, NULL); 954 break; 955 } 956 if ((vals = ldap_get_values(ld, e, attr)) != NULL) { 957 n = ldap_count_values(vals); 958 /* parse the attribute values */ 959 for (i = 0; i < n; i++) { 960 attr_val = vals[i]; 961 while (is_whitespace(*attr_val)) 962 attr_val++; 963 if (verbose) 964 report_info("\t\t", attr_val); 965 len = strlen(attr_val); 966 while (len > 0 && 967 is_whitespace(attr_val[len - 1])) 968 len--; 969 if (yp2ldap) { 970 if (IS_YP_BIND_INFO(attrib_num)) { 971 rc = add_bind_attribute( 972 attrib_num, attr_val, 973 len, proxy_info); 974 } else if (IS_YP_OPER_INFO( 975 attrib_num)) { 976 rc = add_operation_attribute( 977 attrib_num, attr_val, len, 978 nis_config, table_info); 979 } else if (IS_YP_MAP_ATTR( 980 attrib_num)) { 981 rc = add_mapping_attribute( 982 attrib_num, attr_val, len, 983 table_mapping); 984 } else { 985 p_error = 986 parse_unsupported_format; 987 } 988 } else { 989 if (IS_BIND_INFO(attrib_num)) { 990 rc = add_bind_attribute( 991 attrib_num, attr_val, len, 992 proxy_info); 993 } else if (IS_OPER_INFO(attrib_num)) { 994 rc = add_operation_attribute( 995 attrib_num, attr_val, len, 996 nis_config, 997 table_info); 998 } else { 999 rc = add_mapping_attribute( 1000 attrib_num, attr_val, len, 1001 table_mapping); 1002 } 1003 } 1004 if (p_error != no_parse_error) { 1005 report_error(attr_val, attr); 1006 error_reported = TRUE; 1007 break; 1008 } 1009 } 1010 ldap_value_free(vals); 1011 } else { 1012 (void) ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, 1013 &errnum); 1014 if (errnum != LDAP_SUCCESS) 1015 p_error = parse_ldap_get_values_error; 1016 } 1017 ldap_memfree(attr); 1018 if (p_error != no_parse_error) 1019 break; 1020 } 1021 } else { 1022 errnum = ldap_result2error(ld, resultMsg, FALSE); 1023 if (errnum != LDAP_SUCCESS) 1024 p_error = parse_ldap_search_error; 1025 } 1026 if (ber != NULL) 1027 ber_free(ber, 0); 1028 1029 if (!error_reported && p_error != no_parse_error) { 1030 report_error(ldap_err2string(errnum), 0); 1031 } 1032 1033 if (p_error != no_parse_error) 1034 rc = -1; 1035 return (rc); 1036 } 1037 1038 /* 1039 * FUNCTION: process_ldap_referral 1040 * 1041 * Retrieves the configuration for a referral url 1042 * 1043 * RETURN VALUE: 0 on success, -1 on failure, 1 on skip 1044 * 1045 * INPUT: url the ldap url 1046 * __nis_ldap_proxy_info 1047 */ 1048 1049 static int 1050 process_ldap_referral( 1051 char *url, 1052 char **attrs, 1053 __nis_ldap_proxy_info *proxy_info, 1054 __nis_config_t *nis_config, 1055 __nis_table_mapping_t **table_mapping, 1056 __nis_config_info_t *config_info, 1057 __nisdb_table_mapping_t *table_info) 1058 { 1059 LDAPURLDesc *ludpp = NULL; 1060 int rc; 1061 LDAP *ld = NULL; 1062 int errnum; 1063 LDAPMessage *resultMsg = NULL; 1064 1065 if ((rc = ldap_url_parse(url, &ludpp)) != LDAP_SUCCESS) 1066 return (1); 1067 1068 #ifdef LDAP_URL_OPT_SECURE 1069 if (ludpp->lud_options & LDAP_URL_OPT_SECURE) { 1070 if (config_info->tls_method != ssl_tls) { 1071 ldap_free_urldesc(ludpp); 1072 return (1); 1073 } 1074 } else { 1075 if (config_info->tls_method != no_tls) { 1076 ldap_free_urldesc(ludpp); 1077 return (1); 1078 } 1079 } 1080 #endif 1081 1082 if ((ld = connect_to_ldap_config_server(ludpp->lud_host, 1083 ludpp->lud_port, config_info)) == NULL) { 1084 ldap_free_urldesc(ludpp); 1085 return (-1); 1086 } 1087 1088 errnum = ldap_search_s(ld, config_info->config_dn, LDAP_SCOPE_BASE, 1089 "objectclass=nisplusLDAPconfig", attrs, 0, &resultMsg); 1090 1091 ldap_source = config_info->config_dn; 1092 1093 if (errnum != LDAP_SUCCESS) { 1094 p_error = parse_ldap_search_error; 1095 report_error(ldap_err2string(errnum), 0); 1096 rc = -1; 1097 } else { 1098 rc = process_ldap_config_result(ld, resultMsg, proxy_info, 1099 nis_config, table_mapping, table_info); 1100 } 1101 1102 ldap_source = NULL; 1103 (void) ldap_unbind(ld); 1104 if (resultMsg != NULL) 1105 (void) ldap_msgfree(resultMsg); 1106 1107 return (rc); 1108 } 1109 1110 /* 1111 * FUNCTION: process_ldap_referral_msg 1112 * 1113 * Retrieves the configuration from referred servers 1114 * 1115 * RETURN VALUE: 0 on success, -1 on failure 1116 * 1117 * INPUT: LDAP the LDAP connection 1118 * LDAPMessage the LDAP message 1119 * __nis_ldap_proxy_info 1120 */ 1121 1122 static int 1123 process_ldap_referral_msg( 1124 LDAP *ld, 1125 LDAPMessage *resultMsg, 1126 char **attrs, 1127 __nis_ldap_proxy_info *proxy_info, 1128 __nis_config_t *nis_config, 1129 __nis_table_mapping_t **table_mapping, 1130 __nis_config_info_t *config_info, 1131 __nisdb_table_mapping_t *table_info) 1132 { 1133 int errCode; 1134 char **referralsp = NULL; 1135 int i; 1136 int rc; 1137 1138 rc = ldap_parse_result(ld, resultMsg, &errCode, NULL, NULL, &referralsp, 1139 NULL, 0); 1140 1141 if (rc != LDAP_SUCCESS || errCode != LDAP_REFERRAL) { 1142 p_error = parse_ldap_get_values_error; 1143 report_error(ldap_err2string(errCode), 0); 1144 rc = -1; 1145 } else { 1146 for (i = 0; referralsp[i] != NULL; i++) { 1147 rc = process_ldap_referral(referralsp[i], attrs, 1148 proxy_info, nis_config, table_mapping, 1149 config_info, table_info); 1150 if (rc <= 0) 1151 break; 1152 else 1153 report_info("Cannot use referral \n", 1154 referralsp[i]); 1155 1156 } 1157 if (rc > 0) { 1158 p_error = parse_no_available_referrals_error; 1159 report_error(0, 0); 1160 } 1161 } 1162 1163 if (referralsp) 1164 ldap_value_free(referralsp); 1165 1166 return (rc); 1167 } 1168 1169 /* 1170 * FUNCTION: parse_ldap_config_dn_attrs 1171 * 1172 * Parses the information for LDAP from the LDAP profile 1173 * - the profile object name, the LDAP server, and the 1174 * authentication method must be specified. 1175 * 1176 * RETURN VALUE: 0 on success, -1 on failure 1177 * 1178 * INPUT: __nis_ldap_proxy_info 1179 */ 1180 1181 static int 1182 parse_ldap_config_dn_attrs( 1183 __nis_ldap_proxy_info *proxy_info, 1184 __nis_config_t *nis_config, 1185 __nis_table_mapping_t **table_mapping, 1186 __nis_config_info_t *config_info, 1187 __nisdb_table_mapping_t *table_info) 1188 { 1189 int rc = 0; 1190 LDAP *ld = NULL; 1191 int errnum; 1192 char *ldap_config_attributes[n_config_keys]; 1193 LDAPMessage *resultMsg = NULL; 1194 1195 /* Determine if properly configured for LDAP lookup */ 1196 if (config_info->auth_method == simple && 1197 config_info->proxy_dn == NULL) 1198 p_error = parse_no_proxy_dn_error; 1199 else if (config_info->auth_method == 1200 (auth_method_t)NO_VALUE_SET) 1201 p_error = parse_no_config_auth_error; 1202 else if ((config_info->default_servers == NULL) || 1203 (config_info->default_servers[0] == '\0')) 1204 p_error = parse_no_config_server_addr; 1205 if (p_error != no_parse_error) { 1206 report_error(NULL, NULL); 1207 return (-1); 1208 } 1209 1210 if (config_info->tls_method == (tls_method_t)NO_VALUE_SET) 1211 config_info->tls_method = no_tls; 1212 else if (config_info->tls_method == ssl_tls && 1213 (config_info->tls_cert_db == NULL || 1214 *config_info->tls_cert_db == '\0')) { 1215 p_error = parse_no_config_cert_db; 1216 report_error(NULL, NULL); 1217 return (-1); 1218 } 1219 1220 if (verbose) 1221 report_info( 1222 "Getting configuration from LDAP server(s): ", 1223 config_info->default_servers); 1224 1225 /* Determine which attributes should be retrieved */ 1226 get_attribute_list(proxy_info, nis_config, NULL, table_info, 1227 ldap_config_attributes); 1228 1229 if ((ld = connect_to_ldap_config_server(config_info->default_servers, 0, 1230 config_info)) == NULL) 1231 return (-1); 1232 1233 /* Get the attribute values */ 1234 errnum = ldap_search_s(ld, config_info->config_dn, LDAP_SCOPE_BASE, 1235 "objectclass=nisplusLDAPconfig", 1236 ldap_config_attributes, 0, &resultMsg); 1237 ldap_source = config_info->config_dn; 1238 1239 if (errnum == LDAP_REFERRAL) { 1240 rc = process_ldap_referral_msg(ld, resultMsg, 1241 ldap_config_attributes, proxy_info, nis_config, 1242 table_mapping, config_info, table_info); 1243 } else if (errnum != LDAP_SUCCESS) { 1244 p_error = parse_ldap_search_error; 1245 report_error(ldap_err2string(errnum), 0); 1246 rc = -1; 1247 } else { 1248 rc = process_ldap_config_result(ld, resultMsg, proxy_info, 1249 nis_config, table_mapping, table_info); 1250 } 1251 1252 ldap_source = NULL; 1253 (void) ldap_unbind(ld); 1254 if (resultMsg != NULL) 1255 (void) ldap_msgfree(resultMsg); 1256 1257 return (rc); 1258 } 1259 1260 bool_t 1261 is_cmd_line_option(config_key a_num) 1262 { 1263 const char *const *cmdline_options = cmdline_config; 1264 config_key attrib_num; 1265 const char *begin_s; 1266 const char *end_s; 1267 1268 if (cmdline_options == NULL) 1269 return (FALSE); 1270 1271 while (*cmdline_options != NULL) { 1272 attrib_num = get_attrib_num_cmdline( 1273 *cmdline_options, &begin_s, &end_s); 1274 if (attrib_num == a_num) 1275 break; 1276 cmdline_options++; 1277 } 1278 return (*cmdline_options != NULL); 1279 } 1280 1281 /* 1282 * FUNCTION: get_attribute_list 1283 * 1284 * Get a list of attributes from the LDAP server that have not yet 1285 * been gotten. If config_info is NULL, the associated parameters 1286 * are not needed. 1287 * 1288 * RETURN VALUE: none 1289 * 1290 * INPUT: Returns a list of parameters in attributes 1291 * which is assumed to be of sufficient size. 1292 */ 1293 1294 static void 1295 get_attribute_list( 1296 const __nis_ldap_proxy_info *proxy_info, 1297 const __nis_config_t *nis_config, 1298 const __nis_config_info_t *config_info, 1299 const __nisdb_table_mapping_t *table_info, 1300 char **attributes) 1301 { 1302 int n_attrs; 1303 1304 /* Determine which attributes should be retrieved */ 1305 n_attrs = 0; 1306 1307 if (config_info != NULL) { 1308 if (yp2ldap) { 1309 if (config_info->config_dn == NULL) 1310 attributes[n_attrs++] = YP_CONFIG_DN; 1311 if (config_info->default_servers == NULL) 1312 attributes[n_attrs++] = YP_CONFIG_SERVER_LIST; 1313 if (config_info->auth_method == 1314 (auth_method_t)NO_VALUE_SET) 1315 attributes[n_attrs++] = YP_CONFIG_AUTH_METHOD; 1316 if (config_info->tls_method == 1317 (tls_method_t)NO_VALUE_SET) 1318 attributes[n_attrs++] = YP_CONFIG_TLS_OPTION; 1319 if (config_info->proxy_dn == NULL) 1320 attributes[n_attrs++] = YP_CONFIG_PROXY_USER; 1321 if (config_info->proxy_passwd == NULL) 1322 attributes[n_attrs++] = YP_CONFIG_PROXY_PASSWD; 1323 if (config_info->tls_cert_db == NULL) 1324 attributes[n_attrs++] = YP_CONFIG_TLS_CERT_DB; 1325 } else { 1326 if (config_info->config_dn == NULL) 1327 attributes[n_attrs++] = CONFIG_DN; 1328 if (config_info->default_servers == NULL) 1329 attributes[n_attrs++] = CONFIG_SERVER_LIST; 1330 if (config_info->auth_method == 1331 (auth_method_t)NO_VALUE_SET) 1332 attributes[n_attrs++] = CONFIG_AUTH_METHOD; 1333 if (config_info->tls_method == 1334 (tls_method_t)NO_VALUE_SET) 1335 attributes[n_attrs++] = CONFIG_TLS_OPTION; 1336 if (config_info->proxy_dn == NULL) 1337 attributes[n_attrs++] = CONFIG_PROXY_USER; 1338 if (config_info->proxy_passwd == NULL) 1339 attributes[n_attrs++] = CONFIG_PROXY_PASSWD; 1340 if (config_info->tls_cert_db == NULL) 1341 attributes[n_attrs++] = CONFIG_TLS_CERT_DB; 1342 } 1343 } else { 1344 if (yp2ldap) { 1345 attributes[n_attrs++] = YP_DOMAIN_CONTEXT; 1346 attributes[n_attrs++] = YPPASSWDD_DOMAINS; 1347 attributes[n_attrs++] = YP_DB_ID_MAP; 1348 attributes[n_attrs++] = YP_COMMENT_CHAR; 1349 attributes[n_attrs++] = YP_MAP_FLAGS; 1350 attributes[n_attrs++] = YP_ENTRY_TTL; 1351 attributes[n_attrs++] = YP_NAME_FIELDS; 1352 attributes[n_attrs++] = YP_SPLIT_FIELD; 1353 attributes[n_attrs++] = YP_REPEATED_FIELD_SEPARATORS; 1354 attributes[n_attrs++] = YP_LDAP_OBJECT_DN; 1355 attributes[n_attrs++] = NIS_TO_LDAP_MAP; 1356 attributes[n_attrs++] = LDAP_TO_NIS_MAP; 1357 } else { 1358 attributes[n_attrs++] = DB_ID_MAP; 1359 attributes[n_attrs++] = ENTRY_TTL; 1360 attributes[n_attrs++] = LDAP_OBJECT_DN; 1361 attributes[n_attrs++] = NISPLUS_TO_LDAP_MAP; 1362 attributes[n_attrs++] = LDAP_TO_NISPLUS_MAP; 1363 } 1364 } 1365 1366 if (yp2ldap) { 1367 if (proxy_info->default_servers == NULL) 1368 attributes[n_attrs++] = PREFERRED_SERVERS; 1369 if (proxy_info->auth_method == (auth_method_t)NO_VALUE_SET) 1370 attributes[n_attrs++] = AUTH_METHOD; 1371 if (proxy_info->tls_method == (tls_method_t)NO_VALUE_SET) 1372 attributes[n_attrs++] = YP_TLS_OPTION; 1373 if (proxy_info->tls_cert_db == NULL) 1374 attributes[n_attrs++] = YP_TLS_CERT_DB; 1375 if (proxy_info->default_search_base == NULL) 1376 attributes[n_attrs++] = SEARCH_BASE; 1377 if (proxy_info->proxy_dn == NULL) 1378 attributes[n_attrs++] = YP_PROXY_USER; 1379 if (proxy_info->proxy_passwd == NULL) 1380 attributes[n_attrs++] = YP_PROXY_PASSWD; 1381 if (proxy_info->default_nis_domain == NULL) 1382 attributes[n_attrs++] = YP_LDAP_BASE_DOMAIN; 1383 if (proxy_info->bind_timeout.tv_sec == 1384 (time_t)NO_VALUE_SET) 1385 attributes[n_attrs++] = YP_BIND_TIMEOUT; 1386 if (proxy_info->search_timeout.tv_sec == 1387 (time_t)NO_VALUE_SET) 1388 attributes[n_attrs++] = YP_SEARCH_TIMEOUT; 1389 if (proxy_info->modify_timeout.tv_sec == 1390 (time_t)NO_VALUE_SET) 1391 attributes[n_attrs++] = YP_MODIFY_TIMEOUT; 1392 if (proxy_info->add_timeout.tv_sec == (time_t)NO_VALUE_SET) 1393 attributes[n_attrs++] = YP_ADD_TIMEOUT; 1394 if (proxy_info->delete_timeout.tv_sec == 1395 (time_t)NO_VALUE_SET) 1396 attributes[n_attrs++] = YP_DELETE_TIMEOUT; 1397 if (proxy_info->search_time_limit == (int)NO_VALUE_SET) 1398 attributes[n_attrs++] = YP_SEARCH_TIME_LIMIT; 1399 if (proxy_info->search_size_limit == (int)NO_VALUE_SET) 1400 attributes[n_attrs++] = YP_SEARCH_SIZE_LIMIT; 1401 if (proxy_info->follow_referral == 1402 (follow_referral_t)NO_VALUE_SET) 1403 attributes[n_attrs++] = YP_FOLLOW_REFERRAL; 1404 1405 if (table_info->retrieveError == 1406 (__nis_retrieve_error_t)NO_VALUE_SET) 1407 attributes[n_attrs++] = YP_RETRIEVE_ERROR_ACTION; 1408 if (table_info->retrieveErrorRetry.attempts == NO_VALUE_SET) 1409 attributes[n_attrs++] = YP_RETREIVE_ERROR_ATTEMPTS; 1410 if (table_info->retrieveErrorRetry.timeout == 1411 (time_t)NO_VALUE_SET) 1412 attributes[n_attrs++] = YP_RETREIVE_ERROR_TIMEOUT; 1413 if (table_info->storeError == 1414 (__nis_store_error_t)NO_VALUE_SET) 1415 attributes[n_attrs++] = YP_STORE_ERROR_ACTION; 1416 if (table_info->storeErrorRetry.attempts == NO_VALUE_SET) 1417 attributes[n_attrs++] = YP_STORE_ERROR_ATTEMPTS; 1418 if (table_info->storeErrorRetry.timeout == 1419 (time_t)NO_VALUE_SET) 1420 attributes[n_attrs++] = YP_STORE_ERROR_TIMEOUT; 1421 if (table_info->refreshError == 1422 (__nis_refresh_error_t)NO_VALUE_SET) 1423 attributes[n_attrs++] = REFRESH_ERROR_ACTION; 1424 if (table_info->refreshErrorRetry.attempts == NO_VALUE_SET) 1425 attributes[n_attrs++] = REFRESH_ERROR_ATTEMPTS; 1426 if (table_info->refreshErrorRetry.timeout == 1427 (time_t)NO_VALUE_SET) 1428 attributes[n_attrs++] = REFRESH_ERROR_TIMEOUT; 1429 if (table_info->matchFetch == 1430 (__nis_match_fetch_t)NO_VALUE_SET) 1431 attributes[n_attrs++] = YP_MATCH_FETCH; 1432 } else { 1433 if (proxy_info->default_servers == NULL) 1434 attributes[n_attrs++] = PREFERRED_SERVERS; 1435 if (proxy_info->auth_method == (auth_method_t)NO_VALUE_SET) 1436 attributes[n_attrs++] = AUTH_METHOD; 1437 if (proxy_info->tls_method == (tls_method_t)NO_VALUE_SET) 1438 attributes[n_attrs++] = TLS_OPTION; 1439 if (proxy_info->tls_cert_db == NULL) 1440 attributes[n_attrs++] = TLS_CERT_DB; 1441 if (proxy_info->default_search_base == NULL) 1442 attributes[n_attrs++] = SEARCH_BASE; 1443 if (proxy_info->proxy_dn == NULL) 1444 attributes[n_attrs++] = PROXY_USER; 1445 if (proxy_info->proxy_passwd == NULL) 1446 attributes[n_attrs++] = PROXY_PASSWD; 1447 if (proxy_info->default_nis_domain == NULL) 1448 attributes[n_attrs++] = LDAP_BASE_DOMAIN; 1449 if (proxy_info->bind_timeout.tv_sec == 1450 (time_t)NO_VALUE_SET) 1451 attributes[n_attrs++] = BIND_TIMEOUT; 1452 if (proxy_info->search_timeout.tv_sec == 1453 (time_t)NO_VALUE_SET) 1454 attributes[n_attrs++] = SEARCH_TIMEOUT; 1455 if (proxy_info->modify_timeout.tv_sec == 1456 (time_t)NO_VALUE_SET) 1457 attributes[n_attrs++] = MODIFY_TIMEOUT; 1458 if (proxy_info->add_timeout.tv_sec == (time_t)NO_VALUE_SET) 1459 attributes[n_attrs++] = ADD_TIMEOUT; 1460 if (proxy_info->delete_timeout.tv_sec == 1461 (time_t)NO_VALUE_SET) 1462 attributes[n_attrs++] = DELETE_TIMEOUT; 1463 if (proxy_info->search_time_limit == (int)NO_VALUE_SET) 1464 attributes[n_attrs++] = SEARCH_TIME_LIMIT; 1465 if (proxy_info->search_size_limit == (int)NO_VALUE_SET) 1466 attributes[n_attrs++] = SEARCH_SIZE_LIMIT; 1467 if (proxy_info->follow_referral == 1468 (follow_referral_t)NO_VALUE_SET) 1469 attributes[n_attrs++] = FOLLOW_REFERRAL; 1470 1471 if (table_info->retrieveError == 1472 (__nis_retrieve_error_t)NO_VALUE_SET) 1473 attributes[n_attrs++] = RETRIEVE_ERROR_ACTION; 1474 if (table_info->retrieveErrorRetry.attempts == NO_VALUE_SET) 1475 attributes[n_attrs++] = RETREIVE_ERROR_ATTEMPTS; 1476 if (table_info->retrieveErrorRetry.timeout == 1477 (time_t)NO_VALUE_SET) 1478 attributes[n_attrs++] = RETREIVE_ERROR_TIMEOUT; 1479 if (table_info->storeError == 1480 (__nis_store_error_t)NO_VALUE_SET) 1481 attributes[n_attrs++] = STORE_ERROR_ACTION; 1482 if (table_info->storeErrorRetry.attempts == NO_VALUE_SET) 1483 attributes[n_attrs++] = STORE_ERROR_ATTEMPTS; 1484 if (table_info->storeErrorRetry.timeout == 1485 (time_t)NO_VALUE_SET) 1486 attributes[n_attrs++] = STORE_ERROR_TIMEOUT; 1487 if (table_info->refreshError == 1488 (__nis_refresh_error_t)NO_VALUE_SET) 1489 attributes[n_attrs++] = REFRESH_ERROR_ACTION; 1490 if (table_info->refreshErrorRetry.attempts == NO_VALUE_SET) 1491 attributes[n_attrs++] = REFRESH_ERROR_ATTEMPTS; 1492 if (table_info->refreshErrorRetry.timeout == 1493 (time_t)NO_VALUE_SET) 1494 attributes[n_attrs++] = REFRESH_ERROR_TIMEOUT; 1495 if (table_info->matchFetch == 1496 (__nis_match_fetch_t)NO_VALUE_SET) 1497 attributes[n_attrs++] = MATCH_FETCH; 1498 } 1499 1500 switch (nis_config->initialUpdate) { 1501 case (__nis_initial_update_t)NO_VALUE_SET: 1502 attributes[n_attrs++] = INITIAL_UPDATE_ACTION; 1503 attributes[n_attrs++] = INITIAL_UPDATE_ONLY; 1504 break; 1505 case (__nis_initial_update_t)INITIAL_UPDATE_NO_ACTION: 1506 case (__nis_initial_update_t)NO_INITIAL_UPDATE_NO_ACTION: 1507 attributes[n_attrs++] = INITIAL_UPDATE_ACTION; 1508 break; 1509 case (__nis_initial_update_t)FROM_NO_INITIAL_UPDATE: 1510 case (__nis_initial_update_t)TO_NO_INITIAL_UPDATE: 1511 attributes[n_attrs++] = INITIAL_UPDATE_ONLY; 1512 break; 1513 } 1514 1515 if (nis_config->threadCreationError == 1516 (__nis_thread_creation_error_t)NO_VALUE_SET) 1517 attributes[n_attrs++] = THREAD_CREATE_ERROR_ACTION; 1518 if (nis_config->threadCreationErrorTimeout.attempts == NO_VALUE_SET) 1519 attributes[n_attrs++] = THREAD_CREATE_ERROR_ATTEMPTS; 1520 if (nis_config->threadCreationErrorTimeout.timeout == 1521 (time_t)NO_VALUE_SET) 1522 attributes[n_attrs++] = THREAD_CREATE_ERROR_TIMEOUT; 1523 if (nis_config->dumpError == (__nis_dump_error_t)NO_VALUE_SET) 1524 attributes[n_attrs++] = DUMP_ERROR_ACTION; 1525 if (nis_config->dumpErrorTimeout.attempts == NO_VALUE_SET) 1526 attributes[n_attrs++] = DUMP_ERROR_ATTEMPTS; 1527 if (nis_config->dumpErrorTimeout.timeout == (time_t)NO_VALUE_SET) 1528 attributes[n_attrs++] = DUMP_ERROR_TIMEOUT; 1529 if (nis_config->resyncService == (__nis_resync_service_t)NO_VALUE_SET) 1530 attributes[n_attrs++] = RESYNC; 1531 if (nis_config->updateBatching == 1532 (__nis_update_batching_t)NO_VALUE_SET) 1533 attributes[n_attrs++] = UPDATE_BATCHING; 1534 if (nis_config->updateBatchingTimeout.timeout == (time_t)NO_VALUE_SET) 1535 attributes[n_attrs++] = UPDATE_BATCHING_TIMEOUT; 1536 if (nis_config->numberOfServiceThreads == (int)NO_VALUE_SET) 1537 attributes[n_attrs++] = NUMBER_THEADS; 1538 if (nis_config->emulate_yp == (int)NO_VALUE_SET) 1539 attributes[n_attrs++] = YP_EMULATION; 1540 1541 /* maxRPCRecordSize is not configurable through LDAP profiles */ 1542 if (nis_config->maxRPCRecordSize == (int)NO_VALUE_SET) 1543 attributes[n_attrs++] = MAX_RPC_RECSIZE; 1544 1545 attributes[n_attrs++] = NULL; 1546 } 1547 1548 /* 1549 * Notes on adding new attributes 1550 * 1. Determine where the attribute value will be saved 1551 * Currently, the following structures are defined: 1552 * __nis_config_info_t config_info 1553 * __nis_ldap_proxy_info proxyInfo 1554 * __nis_config_t ldapConfig 1555 * __nisdb_table_mapping_t ldapDBTableMapping 1556 * __nis_table_mapping_t ldapTableMapping 1557 * or add a new structure or variable - this will require 1558 * more code. 1559 * 2. Initialize the value to a known unconfigured value. 1560 * This can be done in initialize_parse_structs or 1561 * parse_ldap_migration. 1562 * 3. In the header file nis_parse_ldap_conf.h, add the name 1563 * of the attribute. (Currently, the attribute name is assumed 1564 * to be the same for the command line, the preference file, 1565 * and LDAP.) The names are grouped logically. Add a corresponding 1566 * config_key to the enum. Note that position in this file is 1567 * essential because the macros such as IS_BIND_INFO depend on 1568 * the sequence. The corresponding macro (IS_CONFIG_KEYWORD, 1569 * IS_BIND_INFO, or IS_OPER_INFO) may need to be adjusted. These 1570 * are used to partition the attributes into smaller chunks. 1571 * 4. Add the correspond entry to the keyword_lookup array in 1572 * nis_parse_ldap_attr.c, which is used to determine the config_key 1573 * from the corresponding key word. 1574 * 5. Add the attribute to the list of attributes to retrieve from 1575 * the LDAP server if no value has been set in the function 1576 * parse_ldap_config_dn_attrs. (This assumes that the attribute 1577 * is not used to get the configuration from the LDAP server.) 1578 * 6. Add logic to parse the individual attribute in 1579 * add_config_attribute, add_bind_attribute, 1580 * add_operation_attribute, or add_mapping_attribute depending 1581 * which group of attributes the added attribute belongs to. 1582 * 7. In set_default_values, if the attribute value has not been set, set 1583 * the default value. If any additional fixup is needed depending 1584 * on other configuration values, it should be done here. 1585 * 8. If an attribute name is a subset of another, parse_ldap_default_conf 1586 * should be modified. 1587 * 9. Add the new attribute to the class action script 1588 * usr/src/pkgdefs/common_files/i.defrpc.nisd, if the user 1589 * configured value has to be preserved across upgrades 1590 */ 1591