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