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