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