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