1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 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 <lber.h> 36 #include <ldap.h> 37 #include <syslog.h> 38 39 #include "ldap_parse.h" 40 #include "nis_parse_ldap_conf.h" 41 42 extern FILE *cons; 43 44 static bool_t get_timeval_t(const char *s, int len, struct timeval *t, 45 time_t default_val); 46 static bool_t get_limit(const char *s, int len, int *limit, int default_val); 47 static bool_t get_time_t(const char *s, time_t *t, time_t default_val); 48 static bool_t get_uint_val(const char *attrib_val, int *val, int default_val); 49 static bool_t get_int_val(const char *attrib_val, int *val, int default_val); 50 static void warn_duplicate_val(config_key attrib_num); 51 52 static struct { 53 const char *key_name; 54 config_key key_id; 55 } keyword_lookup[] = { 56 {CONFIG_DN, key_config_dn}, 57 {YP_CONFIG_DN, key_yp_config_dn}, 58 {CONFIG_SERVER_LIST, key_config_server_list}, 59 {YP_CONFIG_SERVER_LIST, key_yp_config_server_list}, 60 {CONFIG_AUTH_METHOD, key_config_auth_method}, 61 {YP_CONFIG_AUTH_METHOD, key_yp_config_auth_method}, 62 {CONFIG_TLS_OPTION, key_config_tls_option}, 63 {YP_CONFIG_TLS_OPTION, key_yp_config_tls_option}, 64 {CONFIG_TLS_CERT_DB, key_config_tls_certificate_db}, 65 {YP_CONFIG_TLS_CERT_DB, key_yp_config_tls_certificate_db}, 66 {CONFIG_PROXY_USER, key_config_proxy_user}, 67 {YP_CONFIG_PROXY_USER, key_yp_config_proxy_user}, 68 {CONFIG_PROXY_PASSWD, key_config_proxy_passwd}, 69 {YP_CONFIG_PROXY_PASSWD, key_yp_config_proxy_passwd}, 70 {PREFERRED_SERVERS, key_preferred_servers}, 71 {AUTH_METHOD, key_auth_method}, 72 {TLS_OPTION, key_tls_option}, 73 {YP_TLS_OPTION, key_yp_tls_option}, 74 {TLS_CERT_DB, key_tls_certificate_db}, 75 {YP_TLS_CERT_DB, key_yp_tls_certificate_db}, 76 {SEARCH_BASE, key_search_base}, 77 {PROXY_USER, key_proxy_user}, 78 {YP_PROXY_USER, key_yp_proxy_user}, 79 {PROXY_PASSWD, key_proxy_passwd}, 80 {YP_PROXY_PASSWD, key_yp_proxy_passwd}, 81 {LDAP_BASE_DOMAIN, key_ldap_base_domain}, 82 {YP_LDAP_BASE_DOMAIN, key_yp_ldap_base_domain}, 83 {BIND_TIMEOUT, key_bind_timeout}, 84 {YP_BIND_TIMEOUT, key_yp_bind_timeout}, 85 {SEARCH_TIMEOUT, key_search_timeout}, 86 {YP_SEARCH_TIMEOUT, key_yp_search_timeout}, 87 {MODIFY_TIMEOUT, key_modify_timeout}, 88 {YP_MODIFY_TIMEOUT, key_yp_modify_timeout}, 89 {ADD_TIMEOUT, key_add_timeout}, 90 {YP_ADD_TIMEOUT, key_yp_add_timeout}, 91 92 {DELETE_TIMEOUT, key_delete_timeout}, 93 {YP_DELETE_TIMEOUT, key_yp_delete_timeout}, 94 {SEARCH_TIME_LIMIT, key_search_time_limit}, 95 {YP_SEARCH_TIME_LIMIT, key_yp_search_time_limit}, 96 {SEARCH_SIZE_LIMIT, key_search_size_limit}, 97 {YP_SEARCH_SIZE_LIMIT, key_yp_search_size_limit}, 98 {FOLLOW_REFERRAL, key_follow_referral}, 99 {YP_FOLLOW_REFERRAL, key_yp_follow_referral}, 100 {INITIAL_UPDATE_ACTION, key_initial_update_action}, 101 {INITIAL_UPDATE_ONLY, key_initial_update_only}, 102 {RETRIEVE_ERROR_ACTION, key_retrieve_error_action}, 103 {YP_RETRIEVE_ERROR_ACTION, key_yp_retrieve_error_action}, 104 {RETREIVE_ERROR_ATTEMPTS, 105 key_retrieve_error_attempts}, 106 {YP_RETREIVE_ERROR_ATTEMPTS, 107 key_yp_retrieve_error_attempts}, 108 {RETREIVE_ERROR_TIMEOUT, 109 key_retreive_error_timeout}, 110 {YP_RETREIVE_ERROR_TIMEOUT, 111 key_yp_retreive_error_timeout}, 112 {STORE_ERROR_ACTION, key_store_error_action}, 113 {YP_STORE_ERROR_ACTION, key_yp_store_error_action}, 114 {STORE_ERROR_ATTEMPTS, key_store_error_attempts}, 115 {YP_STORE_ERROR_ATTEMPTS, key_yp_store_error_attempts}, 116 {STORE_ERROR_TIMEOUT, key_store_error_timeout}, 117 {YP_STORE_ERROR_TIMEOUT, key_yp_store_error_timeout}, 118 119 {REFRESH_ERROR_ACTION, key_refresh_error_action}, 120 121 {REFRESH_ERROR_ATTEMPTS, 122 key_refresh_error_attempts}, 123 {REFRESH_ERROR_TIMEOUT, key_refresh_error_timeout}, 124 {THREAD_CREATE_ERROR_ACTION, 125 key_thread_create_error_action}, 126 {THREAD_CREATE_ERROR_ATTEMPTS, 127 key_thread_create_error_attempts}, 128 {THREAD_CREATE_ERROR_TIMEOUT, 129 key_thread_create_error_timeout}, 130 {DUMP_ERROR_ACTION, key_dump_error_action}, 131 {DUMP_ERROR_ATTEMPTS, key_dump_error_attempts}, 132 {DUMP_ERROR_TIMEOUT, key_dump_error_timeout}, 133 {RESYNC, key_resync}, 134 {UPDATE_BATCHING, key_update_batching}, 135 {UPDATE_BATCHING_TIMEOUT, 136 key_update_batching_timeout}, 137 {MATCH_FETCH, key_match_fetch}, 138 {YP_MATCH_FETCH, key_yp_match_fetch}, 139 {NUMBER_THEADS, key_number_threads}, 140 {YP_EMULATION, key_yp_emulation}, 141 {MAX_RPC_RECSIZE, key_max_rpc_recsize}, 142 {YP_DOMAIN_CONTEXT, key_yp_domain_context}, 143 {YPPASSWDD_DOMAINS, key_yppasswdd_domains}, 144 {DB_ID_MAP, key_db_id_map}, 145 {YP_DB_ID_MAP, key_yp_db_id_map}, 146 {YP_COMMENT_CHAR, key_yp_comment_char}, 147 {YP_MAP_FLAGS, key_yp_map_flags}, 148 {ENTRY_TTL, key_entry_ttl}, 149 {YP_ENTRY_TTL, key_yp_entry_ttl}, 150 {YP_NAME_FIELDS, key_yp_name_fields}, 151 {YP_SPLIT_FIELD, key_yp_split_field}, 152 {YP_REPEATED_FIELD_SEPARATORS, key_yp_repeated_field_separators}, 153 {LDAP_OBJECT_DN, key_ldap_object_dn}, 154 {YP_LDAP_OBJECT_DN, key_yp_ldap_object_dn}, 155 {LDAP_TO_NISPLUS_MAP, key_ldap_to_nisplus_map}, 156 {LDAP_TO_NIS_MAP, key_ldap_to_nis_map}, 157 {NISPLUS_TO_LDAP_MAP, key_nisplus_to_ldap_map}, 158 {NIS_TO_LDAP_MAP, key_nis_to_ldap_map} 159 }; 160 161 /* 162 * FUNCTION: add_config_attribute 163 * 164 * Adds the attribute value to __nis_config_info_t 165 * if the value is not yet set. 166 * 167 * RETURN VALUE: 0 on success, -1 on failure 168 * 169 * INPUT: attribute number and value (assumed to be non-NULL) 170 */ 171 172 int 173 add_config_attribute( 174 config_key attrib_num, 175 const char *attrib_val, 176 int attrib_len, 177 __nis_config_info_t *config_info) 178 { 179 switch (attrib_num) { 180 case key_yp_config_dn: 181 case key_config_dn: 182 if (config_info->config_dn == NULL) { 183 if (!validate_dn(attrib_val, attrib_len)) 184 break; 185 config_info->config_dn = 186 s_strndup(attrib_val, attrib_len); 187 } else { 188 warn_duplicate_val(attrib_num); 189 } 190 break; 191 case key_yp_config_server_list: 192 case key_config_server_list: 193 if (config_info->default_servers == NULL) { 194 config_info->default_servers = 195 s_strndup(attrib_val, attrib_len); 196 } else { 197 warn_duplicate_val(attrib_num); 198 } 199 break; 200 case key_yp_config_auth_method: 201 case key_config_auth_method: 202 if (config_info->auth_method == 203 (auth_method_t)NO_VALUE_SET) { 204 if (same_string("none", attrib_val, 205 attrib_len)) 206 config_info->auth_method = none; 207 else if (same_string("simple", attrib_val, 208 attrib_len)) 209 config_info->auth_method = simple; 210 else if (same_string("sasl/cram-md5", 211 attrib_val, attrib_len)) 212 config_info->auth_method = cram_md5; 213 else if (same_string("sasl/digest-md5", 214 attrib_val, attrib_len)) 215 config_info->auth_method = digest_md5; 216 else 217 p_error = parse_bad_auth_method_error; 218 } else { 219 warn_duplicate_val(attrib_num); 220 } 221 break; 222 case key_yp_config_tls_option: 223 case key_config_tls_option: 224 if (config_info->tls_method == 225 (tls_method_t)NO_VALUE_SET) { 226 if (same_string("none", attrib_val, 227 attrib_len)) 228 config_info->tls_method = no_tls; 229 else if (same_string("ssl", attrib_val, 230 attrib_len)) 231 config_info->tls_method = ssl_tls; 232 else 233 p_error = parse_bad_tls_option_error; 234 } else { 235 warn_duplicate_val(attrib_num); 236 } 237 break; 238 case key_yp_config_tls_certificate_db: 239 case key_config_tls_certificate_db: 240 if (config_info->tls_cert_db == NULL) { 241 config_info->tls_cert_db = 242 s_strndup(attrib_val, attrib_len); 243 } else { 244 warn_duplicate_val(attrib_num); 245 } 246 break; 247 case key_yp_config_proxy_user: 248 case key_config_proxy_user: 249 if (config_info->proxy_dn == NULL) { 250 config_info->proxy_dn = 251 s_strndup(attrib_val, attrib_len); 252 } else { 253 warn_duplicate_val(attrib_num); 254 } 255 break; 256 case key_yp_config_proxy_passwd: 257 case key_config_proxy_passwd: 258 if (config_info->proxy_passwd == NULL) { 259 config_info->proxy_passwd = 260 s_strndup_esc(attrib_val, attrib_len); 261 } else { 262 warn_duplicate_val(attrib_num); 263 } 264 break; 265 default: 266 p_error = parse_internal_error; 267 break; 268 } 269 return (p_error == no_parse_error ? 0 : -1); 270 } 271 272 /* 273 * FUNCTION: add_bind_attribute 274 * 275 * Adds the attribute value to __nis_ldap_proxy_info 276 * if the value is not yet set. 277 * 278 * RETURN VALUE: 0 on success, -1 on failure 279 * 280 * INPUT: attribute number and value (assumed to be non-NULL) 281 */ 282 283 int 284 add_bind_attribute( 285 config_key attrib_num, 286 const char *attrib_val, 287 int attrib_len, 288 __nis_ldap_proxy_info *proxy_info) 289 { 290 struct timeval t; 291 int limit; 292 293 switch (attrib_num) { 294 case key_yp_preferred_servers: 295 case key_preferred_servers: 296 if (proxy_info->default_servers == NULL) { 297 proxy_info->default_servers = 298 s_strndup(attrib_val, attrib_len); 299 } else { 300 warn_duplicate_val(attrib_num); 301 } 302 break; 303 case key_yp_auth_method: 304 case key_auth_method: 305 if (proxy_info->auth_method == 306 (auth_method_t)NO_VALUE_SET) { 307 if (same_string("none", attrib_val, 308 attrib_len)) 309 proxy_info->auth_method = none; 310 else if (same_string("simple", attrib_val, 311 attrib_len)) 312 proxy_info->auth_method = simple; 313 else if (same_string("sasl/cram-md5", 314 attrib_val, attrib_len)) 315 proxy_info->auth_method = cram_md5; 316 else if (same_string("sasl/digest-md5", 317 attrib_val, attrib_len)) 318 proxy_info->auth_method = digest_md5; 319 else 320 p_error = parse_bad_auth_method_error; 321 } else { 322 warn_duplicate_val(attrib_num); 323 } 324 break; 325 case key_yp_tls_option: 326 case key_tls_option: 327 if (proxy_info->tls_method == 328 (tls_method_t)NO_VALUE_SET) { 329 if (same_string("none", attrib_val, 330 attrib_len)) 331 proxy_info->tls_method = no_tls; 332 else if (same_string("ssl", attrib_val, 333 attrib_len)) 334 proxy_info->tls_method = ssl_tls; 335 else 336 p_error = parse_bad_tls_option_error; 337 } else { 338 warn_duplicate_val(attrib_num); 339 } 340 break; 341 case key_yp_tls_certificate_db: 342 case key_tls_certificate_db: 343 if (proxy_info->tls_cert_db == NULL) { 344 proxy_info->tls_cert_db = 345 s_strndup(attrib_val, attrib_len); 346 } else { 347 warn_duplicate_val(attrib_num); 348 } 349 break; 350 case key_yp_search_base: 351 case key_search_base: 352 if (proxy_info->default_search_base == NULL) { 353 if (!validate_dn(attrib_val, attrib_len)) 354 break; 355 proxy_info->default_search_base = 356 s_strndup(attrib_val, attrib_len); 357 } else { 358 warn_duplicate_val(attrib_num); 359 } 360 break; 361 case key_yp_proxy_user: 362 case key_proxy_user: 363 if (proxy_info->proxy_dn == NULL) { 364 proxy_info->proxy_dn = 365 s_strndup(attrib_val, attrib_len); 366 } else { 367 warn_duplicate_val(attrib_num); 368 } 369 break; 370 case key_yp_proxy_passwd: 371 case key_proxy_passwd: 372 if (proxy_info->proxy_passwd == NULL) { 373 proxy_info->proxy_passwd = 374 s_strndup_esc(attrib_val, attrib_len); 375 } else { 376 warn_duplicate_val(attrib_num); 377 } 378 break; 379 case key_yp_ldap_base_domain: 380 case key_ldap_base_domain: 381 if (proxy_info->default_nis_domain == NULL) { 382 proxy_info->default_nis_domain = 383 s_strndup_esc(attrib_val, attrib_len); 384 } else { 385 warn_duplicate_val(attrib_num); 386 } 387 break; 388 case key_yp_bind_timeout: 389 case key_bind_timeout: 390 if (proxy_info->bind_timeout.tv_sec == 391 (time_t)NO_VALUE_SET) { 392 if (!get_timeval_t(attrib_val, attrib_len, &t, 393 DEFAULT_BIND_TIMEOUT)) 394 break; 395 proxy_info->bind_timeout = t; 396 } else { 397 warn_duplicate_val(attrib_num); 398 } 399 break; 400 case key_yp_search_timeout: 401 if (proxy_info->search_timeout.tv_sec == 402 (time_t)NO_VALUE_SET) { 403 if (!get_timeval_t(attrib_val, attrib_len, &t, 404 DEFAULT_YP_SEARCH_TIMEOUT)) 405 break; 406 proxy_info->search_timeout = t; 407 } else { 408 warn_duplicate_val(attrib_num); 409 } 410 break; 411 412 case key_search_timeout: 413 if (proxy_info->search_timeout.tv_sec == 414 (time_t)NO_VALUE_SET) { 415 if (!get_timeval_t(attrib_val, attrib_len, &t, 416 DEFAULT_SEARCH_TIMEOUT)) 417 break; 418 proxy_info->search_timeout = t; 419 } else { 420 warn_duplicate_val(attrib_num); 421 } 422 break; 423 case key_yp_modify_timeout: 424 case key_modify_timeout: 425 if (proxy_info->modify_timeout.tv_sec == 426 (time_t)NO_VALUE_SET) { 427 if (!get_timeval_t(attrib_val, attrib_len, &t, 428 DEFAULT_MODIFY_TIMEOUT)) 429 break; 430 proxy_info->modify_timeout = t; 431 } else { 432 warn_duplicate_val(attrib_num); 433 } 434 break; 435 case key_yp_add_timeout: 436 case key_add_timeout: 437 if (proxy_info->add_timeout.tv_sec == 438 (time_t)NO_VALUE_SET) { 439 if (!get_timeval_t(attrib_val, attrib_len, &t, 440 DEFAULT_ADD_TIMEOUT)) 441 break; 442 proxy_info->add_timeout = t; 443 } else { 444 warn_duplicate_val(attrib_num); 445 } 446 break; 447 case key_yp_delete_timeout: 448 case key_delete_timeout: 449 if (proxy_info->delete_timeout.tv_sec == 450 (time_t)NO_VALUE_SET) { 451 if (!get_timeval_t(attrib_val, attrib_len, &t, 452 DEFAULT_DELETE_TIMEOUT)) 453 break; 454 proxy_info->delete_timeout = t; 455 } else { 456 warn_duplicate_val(attrib_num); 457 } 458 break; 459 case key_yp_search_time_limit: 460 case key_search_time_limit: 461 if (proxy_info->search_time_limit == 462 (int)NO_VALUE_SET) { 463 if (!get_limit(attrib_val, attrib_len, &limit, 464 DEFAULT_SEARCH_TIME_LIMIT)) 465 break; 466 proxy_info->search_time_limit = limit; 467 } else { 468 warn_duplicate_val(attrib_num); 469 } 470 break; 471 case key_yp_search_size_limit: 472 case key_search_size_limit: 473 if (proxy_info->search_size_limit == 474 (int)NO_VALUE_SET) { 475 if (!get_limit(attrib_val, attrib_len, &limit, 476 DEFAULT_SEARCH_SIZE_LIMIT)) 477 break; 478 proxy_info->search_size_limit = limit; 479 } else { 480 warn_duplicate_val(attrib_num); 481 } 482 break; 483 case key_yp_follow_referral: 484 case key_follow_referral: 485 if (proxy_info->follow_referral == 486 (follow_referral_t)NO_VALUE_SET) { 487 if (same_string("yes", attrib_val, attrib_len)) 488 proxy_info->follow_referral = follow; 489 else if (same_string("no", attrib_val, attrib_len)) 490 proxy_info->follow_referral = no_follow; 491 else 492 p_error = parse_yes_or_no_expected_error; 493 } else { 494 warn_duplicate_val(attrib_num); 495 } 496 break; 497 default: 498 p_error = parse_internal_error; 499 break; 500 } 501 return (p_error == no_parse_error ? 0 : -1); 502 } 503 504 /* 505 * FUNCTION: add_operation_attribute 506 * 507 * Adds the attribute value to __nis_config_t and 508 * __nisdb_table_mapping_t if the value is not yet set. 509 * 510 * RETURN VALUE: 0 on success, -1 on failure 511 * 512 * INPUT: attribute number and value (assumed to be non-NULL) 513 */ 514 515 int 516 add_operation_attribute( 517 config_key attrib_num, 518 const char *attrib_val, 519 int attrib_len, 520 __nis_config_t *config_info, 521 __nisdb_table_mapping_t *table_info) 522 { 523 char buf[1024]; 524 int i; 525 int len; 526 time_t timeout; 527 bool_t last_digit = FALSE; 528 529 for (i = 0, len = 0; i < attrib_len; i++) { 530 if (!last_digit && 531 is_whitespace(attrib_val[i])) 532 continue; 533 buf[len++] = attrib_val[i]; 534 if (len >= sizeof (buf)) { 535 p_error = parse_line_too_long; 536 return (-1); 537 } 538 last_digit = isdigit(attrib_val[i]); 539 } 540 buf[len] = '\0'; 541 542 switch (attrib_num) { 543 case key_initial_update_action: 544 if (config_info->initialUpdate == 545 (__nis_initial_update_t)NO_VALUE_SET) { 546 if (strcasecmp("none", buf) == 0) 547 config_info->initialUpdate = ini_none; 548 else if (strcasecmp("from_ldap", buf) == 0) 549 config_info->initialUpdate = 550 (__nis_initial_update_t)FROM_NO_INITIAL_UPDATE; 551 else if (strcasecmp("to_ldap", buf) == 0) 552 config_info->initialUpdate = 553 (__nis_initial_update_t)TO_NO_INITIAL_UPDATE; 554 else 555 p_error = parse_initial_update_action_error; 556 } else if (config_info->initialUpdate == 557 (__nis_initial_update_t)INITIAL_UPDATE_NO_ACTION) { 558 if (strcasecmp("none", buf) == 0) 559 config_info->initialUpdate = ini_none; 560 else if (strcasecmp("from_ldap", buf) == 0) 561 config_info->initialUpdate = from_ldap_update_only; 562 else if (strcasecmp("to_ldap", buf) == 0) 563 config_info->initialUpdate = to_ldap_update_only; 564 else 565 p_error = parse_initial_update_action_error; 566 } else if (config_info->initialUpdate == 567 (__nis_initial_update_t)NO_INITIAL_UPDATE_NO_ACTION) { 568 if (strcasecmp("none", buf) == 0) 569 config_info->initialUpdate = ini_none; 570 else if (strcasecmp("from_ldap", buf) == 0) 571 config_info->initialUpdate = from_ldap; 572 else if (strcasecmp("to_ldap", buf) == 0) 573 config_info->initialUpdate = to_ldap; 574 else 575 p_error = parse_initial_update_action_error; 576 } else { 577 warn_duplicate_val(attrib_num); 578 } 579 break; 580 case key_initial_update_only: 581 if (config_info->initialUpdate == 582 (__nis_initial_update_t)NO_VALUE_SET) { 583 if (strcasecmp("yes", buf) == 0) 584 config_info->initialUpdate = 585 (__nis_initial_update_t) 586 INITIAL_UPDATE_NO_ACTION; 587 else if (strcasecmp("no", buf) == 0) 588 config_info->initialUpdate = 589 (__nis_initial_update_t) 590 NO_INITIAL_UPDATE_NO_ACTION; 591 else 592 p_error = parse_initial_update_only_error; 593 } else if (config_info->initialUpdate == 594 (__nis_initial_update_t)FROM_NO_INITIAL_UPDATE) { 595 if (strcasecmp("yes", buf) == 0) 596 config_info->initialUpdate = from_ldap_update_only; 597 else if (strcasecmp("no", buf) == 0) 598 config_info->initialUpdate = from_ldap; 599 else 600 p_error = parse_initial_update_only_error; 601 } else if (config_info->initialUpdate == 602 (__nis_initial_update_t)TO_NO_INITIAL_UPDATE) { 603 if (strcasecmp("yes", buf) == 0) 604 config_info->initialUpdate = to_ldap_update_only; 605 else if (strcasecmp("no", buf) == 0) 606 config_info->initialUpdate = to_ldap; 607 else 608 p_error = parse_initial_update_only_error; 609 } else if (config_info->initialUpdate != ini_none) { 610 warn_duplicate_val(attrib_num); 611 } 612 break; 613 case key_thread_create_error_action: 614 if (config_info->threadCreationError == 615 (__nis_thread_creation_error_t)NO_VALUE_SET) { 616 if (strcasecmp("pass_error", buf) == 0) 617 config_info->threadCreationError = pass_error; 618 else if (strcasecmp("retry", buf) == 0) 619 config_info->threadCreationError = cre_retry; 620 else 621 p_error = parse_thread_create_error_action_error; 622 } else { 623 warn_duplicate_val(attrib_num); 624 } 625 break; 626 case key_thread_create_error_attempts: 627 if (config_info->threadCreationErrorTimeout.attempts == 628 NO_VALUE_SET) { 629 if (get_int_val(buf, &i, DEFAULT_THREAD_ERROR_ATTEMPTS)) 630 config_info->threadCreationErrorTimeout.attempts = i; 631 } else { 632 warn_duplicate_val(attrib_num); 633 } 634 break; 635 case key_thread_create_error_timeout: 636 if (config_info->threadCreationErrorTimeout.timeout == 637 (time_t)NO_VALUE_SET) { 638 if (get_time_t(buf, &timeout, 639 DEFAULT_THREAD_ERROR_TIME_OUT)) 640 config_info->threadCreationErrorTimeout.timeout = 641 timeout; 642 } else { 643 warn_duplicate_val(attrib_num); 644 } 645 break; 646 case key_dump_error_action: 647 if (config_info->dumpError == 648 (__nis_dump_error_t)NO_VALUE_SET) { 649 if (strcasecmp("rollback", buf) == 0) 650 config_info->dumpError = rollback; 651 else if (strcasecmp("retry", buf) == 0) 652 config_info->dumpError = de_retry; 653 else 654 p_error = parse_dump_error_action_error; 655 } else { 656 warn_duplicate_val(attrib_num); 657 } 658 break; 659 case key_dump_error_attempts: 660 if (config_info->dumpErrorTimeout.attempts == NO_VALUE_SET) { 661 if (get_int_val(buf, &i, DEFAULT_DUMP_ERROR_ATTEMPTS)) 662 config_info->dumpErrorTimeout.attempts = i; 663 } else { 664 warn_duplicate_val(attrib_num); 665 } 666 break; 667 case key_dump_error_timeout: 668 if (config_info->dumpErrorTimeout.timeout == 669 (time_t)NO_VALUE_SET) { 670 if (get_time_t(buf, &timeout, 671 DEFAULT_DUMP_ERROR_TIME_OUT)) 672 config_info->dumpErrorTimeout.timeout = timeout; 673 } else { 674 warn_duplicate_val(attrib_num); 675 } 676 break; 677 case key_resync: 678 if (config_info->resyncService == 679 (__nis_resync_service_t)NO_VALUE_SET) { 680 if (strcasecmp("directory_locked", buf) == 0) 681 config_info->resyncService = directory_locked; 682 else if (strcasecmp("from_copy", buf) == 0) 683 config_info->resyncService = from_copy; 684 else if (strcasecmp("from_live", buf) == 0) 685 config_info->resyncService = from_live; 686 else 687 p_error = parse_resync_error; 688 } else { 689 warn_duplicate_val(attrib_num); 690 } 691 break; 692 case key_update_batching: 693 if (config_info->updateBatching == 694 (__nis_update_batching_t)NO_VALUE_SET) { 695 if (strcasecmp("none", buf) == 0) 696 config_info->updateBatching = upd_none; 697 else if (strcasecmp("accumulate", buf) == 0) { 698 config_info->updateBatching = accumulate; 699 } else if (strcasecmp("bounded_accumulate", buf) == 0) { 700 config_info->updateBatching = bounded_accumulate; 701 } else 702 p_error = parse_update_batching_error; 703 } else { 704 warn_duplicate_val(attrib_num); 705 } 706 break; 707 case key_update_batching_timeout: 708 if (config_info->updateBatchingTimeout.timeout == 709 (time_t)NO_VALUE_SET) { 710 if (get_time_t(buf, &timeout, DEFAULT_BATCHING_TIME_OUT)) 711 config_info->updateBatchingTimeout.timeout = timeout; 712 } else { 713 warn_duplicate_val(attrib_num); 714 } 715 break; 716 case key_number_threads: 717 if (config_info->numberOfServiceThreads == 718 (int)NO_VALUE_SET) { 719 if (get_uint_val(buf, &i, DEFAULT_NUMBER_OF_THREADS)) 720 config_info->numberOfServiceThreads = i; 721 } else { 722 warn_duplicate_val(attrib_num); 723 } 724 break; 725 case key_yp_emulation: 726 if (config_info->emulate_yp == 727 (int)NO_VALUE_SET) { 728 if (strcasecmp("yes", buf) == 0) 729 config_info->emulate_yp = TRUE; 730 } else { 731 warn_duplicate_val(attrib_num); 732 } 733 break; 734 case key_yp_retrieve_error_action: 735 if (table_info->retrieveError == 736 (__nis_retrieve_error_t)NO_VALUE_SET) { 737 if (strcasecmp("use_cached", buf) == 0) 738 table_info->retrieveError = use_cached; 739 else if (strcasecmp("fail", buf) == 0) 740 table_info->retrieveError = fail; 741 else 742 p_error = parse_yp_retrieve_error_action_error; 743 } else { 744 warn_duplicate_val(attrib_num); 745 } 746 break; 747 case key_retrieve_error_action: 748 if (table_info->retrieveError == 749 (__nis_retrieve_error_t)NO_VALUE_SET) { 750 if (strcasecmp("use_cached", buf) == 0) 751 table_info->retrieveError = use_cached; 752 else if (strcasecmp("try_again", buf) == 0) 753 table_info->retrieveError = try_again; 754 else if (strcasecmp("unavail", buf) == 0) 755 table_info->retrieveError = ret_unavail; 756 else if (strcasecmp("no_such_name", buf) == 0) 757 table_info->retrieveError = no_such_name; 758 else if (strcasecmp("retry", buf) == 0) 759 table_info->retrieveError = ret_retry; 760 else 761 p_error = parse_retrieve_error_action_error; 762 } else { 763 warn_duplicate_val(attrib_num); 764 } 765 break; 766 case key_yp_retrieve_error_attempts: 767 case key_retrieve_error_attempts: 768 if (table_info->retrieveErrorRetry.attempts == NO_VALUE_SET) { 769 if (get_int_val(buf, &i, DEFAULT_RETRIEVE_ERROR_ATTEMPTS)) 770 table_info->retrieveErrorRetry.attempts = i; 771 } else { 772 warn_duplicate_val(attrib_num); 773 } 774 break; 775 case key_yp_retreive_error_timeout: 776 case key_retreive_error_timeout: 777 if (table_info->retrieveErrorRetry.timeout == 778 (time_t)NO_VALUE_SET) { 779 if (get_time_t(buf, &timeout, 780 DEFAULT_RETRIEVE_ERROR_TIME_OUT)) 781 table_info->retrieveErrorRetry.timeout = timeout; 782 } else { 783 warn_duplicate_val(attrib_num); 784 } 785 break; 786 case key_yp_store_error_action: 787 if (table_info->storeError == 788 (__nis_store_error_t)NO_VALUE_SET) { 789 if (strcasecmp("retry", buf) == 0) 790 table_info->storeError = sto_retry; 791 else if (strcasecmp("fail", buf) == 0) 792 table_info->storeError = sto_fail; 793 else 794 p_error = parse_yp_store_error_action_error; 795 } else { 796 warn_duplicate_val(attrib_num); 797 } 798 break; 799 case key_store_error_action: 800 if (table_info->storeError == 801 (__nis_store_error_t)NO_VALUE_SET) { 802 if (strcasecmp("system_error", buf) == 0) 803 table_info->storeError = system_error; 804 else if (strcasecmp("unavail", buf) == 0) 805 table_info->storeError = sto_unavail; 806 else if (strcasecmp("retry", buf) == 0) 807 table_info->storeError = sto_retry; 808 else 809 p_error = parse_store_error_action_error; 810 } else { 811 warn_duplicate_val(attrib_num); 812 } 813 break; 814 case key_yp_store_error_attempts: 815 case key_store_error_attempts: 816 if (table_info->storeErrorRetry.attempts == NO_VALUE_SET) { 817 if (get_int_val(buf, &i, 818 DEFAULT_STORE_ERROR_ATTEMPTS)) 819 table_info->storeErrorRetry.attempts = i; 820 } else { 821 warn_duplicate_val(attrib_num); 822 } 823 break; 824 case key_yp_store_error_timeout: 825 case key_store_error_timeout: 826 if (table_info->storeErrorRetry.timeout == 827 (time_t)NO_VALUE_SET) { 828 if (get_time_t(buf, &timeout, 829 DEFAULT_STORE_ERROR_TIME_OUT)) 830 table_info->storeErrorRetry.timeout = timeout; 831 } else { 832 warn_duplicate_val(attrib_num); 833 } 834 break; 835 case key_refresh_error_action: 836 if (table_info->refreshError == 837 (__nis_refresh_error_t)NO_VALUE_SET) { 838 if (strcasecmp("continue_using", buf) == 0) 839 table_info->refreshError = continue_using; 840 else if (strcasecmp("cache_expired", buf) == 0) 841 table_info->refreshError = cache_expired; 842 else if (strcasecmp("tryagain", buf) == 0) 843 table_info->refreshError = tryagain; 844 else if (strcasecmp("retry", buf) == 0) 845 table_info->refreshError = ref_retry; 846 else if (strcasecmp("continue_using,retry", buf) == 0 || 847 strcasecmp("retry,continue_using", buf) == 0) 848 table_info->refreshError = continue_using_retry; 849 else 850 p_error = parse_refresh_error_action_error; 851 } else { 852 warn_duplicate_val(attrib_num); 853 } 854 break; 855 case key_refresh_error_attempts: 856 if (table_info->refreshErrorRetry.attempts == NO_VALUE_SET) { 857 if (get_int_val(buf, &i, DEFAULT_REFRESH_ERROR_ATTEMPTS)) 858 table_info->refreshErrorRetry.attempts = i; 859 } else { 860 warn_duplicate_val(attrib_num); 861 } 862 break; 863 case key_refresh_error_timeout: 864 if (table_info->refreshErrorRetry.timeout == 865 (time_t)NO_VALUE_SET) { 866 if (get_time_t(buf, &timeout, 867 DEFAULT_REFRESH_ERROR_TIME_OUT)) 868 table_info->refreshErrorRetry.timeout = timeout; 869 } else { 870 warn_duplicate_val(attrib_num); 871 } 872 break; 873 case key_yp_match_fetch: 874 case key_match_fetch: 875 if (table_info->matchFetch == 876 (__nis_match_fetch_t)NO_VALUE_SET) { 877 if (strcasecmp("no_match_only", buf) == 0) 878 table_info->matchFetch = no_match_only; 879 else if (strcasecmp("always", buf) == 0) 880 table_info->matchFetch = mat_always; 881 else if (strcasecmp("never", buf) == 0) 882 table_info->matchFetch = mat_never; 883 else 884 p_error = parse_match_fetch_error; 885 } else { 886 warn_duplicate_val(attrib_num); 887 } 888 break; 889 case key_max_rpc_recsize: 890 if (config_info->maxRPCRecordSize == 891 (int)NO_VALUE_SET) { 892 if (get_uint_val(buf, &i, RPC_MAXDATASIZE)) 893 config_info->maxRPCRecordSize = i; 894 } else { 895 warn_duplicate_val(attrib_num); 896 } 897 break; 898 default: 899 p_error = parse_internal_error; 900 break; 901 } 902 903 return (p_error == no_parse_error ? 0 : -1); 904 } 905 906 /* 907 * FUNCTION: get_attrib_num 908 * 909 * Get the attribute number for the corresponding keyword. 910 * 911 * RETURN VALUE: attribute number on success, 912 * key_bad on failure 913 * 914 * INPUT: the attribute name string (assumed to be non-NULL) 915 */ 916 917 config_key 918 get_attrib_num(const char *s, int n) 919 { 920 int k; 921 int i; 922 config_key attrib_num = key_bad; 923 924 k = n < sizeof (_key_val) ? n : sizeof (_key_val) - 1; 925 (void) memcpy(_key_val, s, k); 926 _key_val[k] = '\0'; 927 928 for (i = 0; i < sizeof (keyword_lookup) / 929 sizeof (keyword_lookup[0]); i++) { 930 if (strncasecmp(s, keyword_lookup[i].key_name, n) == 0 && 931 strlen(keyword_lookup[i].key_name) == n) { 932 attrib_num = keyword_lookup[i].key_id; 933 break; 934 } 935 } 936 937 if (attrib_num == key_bad) { 938 p_error = parse_bad_key; 939 } 940 941 return (attrib_num); 942 } 943 944 /* 945 * FUNCTION: get_timeval_t 946 * 947 * Extract time from string 948 * 949 * RETURN VALUE: TRUE if parsed 950 * FALSE otherwise 951 * 952 * INPUT: the attribute value string (assumed to be non-NULL) 953 */ 954 955 static bool_t 956 get_timeval_t( 957 const char *s, 958 int len, 959 struct timeval *t, 960 time_t default_val) 961 { 962 time_t tv_sec = 0; 963 time_t tv_usec = 0; 964 time_t digit; 965 time_t mult = 100000; 966 bool_t got_digit = FALSE; 967 bool_t got_period = FALSE; 968 const char *s_end = s + len; 969 970 while (s < s_end && is_whitespace(*s)) 971 s++; 972 973 while (s < s_end && isdigit(*s)) { 974 digit = (*s++) - '0'; 975 got_digit = TRUE; 976 if (WILL_OVERFLOW_TIME(tv_sec, digit)) 977 tv_sec = TIME_MAX; 978 else 979 tv_sec = tv_sec * 10 + digit; 980 } 981 while (s < s_end && is_whitespace(*s)) 982 s++; 983 984 if (s < s_end && *s == PERIOD_CHAR) { 985 s++; 986 got_period = TRUE; 987 while (s < s_end && isdigit(*s)) { 988 got_digit = TRUE; 989 digit = (*s++) - '0'; 990 tv_usec += digit * mult; 991 mult /= 10; 992 } 993 while (s < s_end && is_whitespace(*s)) 994 s++; 995 } 996 if (s == s_end) { 997 if (!got_digit) { 998 if (got_period) { 999 p_error = parse_bad_time_error; 1000 return (FALSE); 1001 } 1002 tv_sec = default_val; 1003 } 1004 t->tv_sec = tv_sec; 1005 t->tv_usec = tv_usec; 1006 } else 1007 p_error = parse_bad_time_error; 1008 1009 return (s == s_end); 1010 } 1011 1012 /* 1013 * FUNCTION: get_limit 1014 * 1015 * Extract limit from string 1016 * 1017 * RETURN VALUE: TRUE if parsed 1018 * FALSE otherwise 1019 * 1020 * INPUT: the attribute value string (assumed to be non-NULL) 1021 */ 1022 1023 1024 static bool_t 1025 get_limit( 1026 const char *s, 1027 int len, 1028 int *limit, 1029 int default_val) 1030 { 1031 bool_t got_digit = FALSE; 1032 int l = 0; 1033 time_t digit; 1034 const char *s_end = s + len; 1035 1036 while (s < s_end && is_whitespace(*s)) 1037 s++; 1038 1039 while (s < s_end && isdigit(*s)) { 1040 got_digit = TRUE; 1041 digit = (*s++) - '0'; 1042 if (WILL_OVERFLOW_LIMIT(l, digit)) 1043 l = LIMIT_MAX; 1044 else 1045 l = l * 10 + digit; 1046 } 1047 while (s < s_end && is_whitespace(*s)) 1048 s++; 1049 if (s == s_end) { 1050 if (!got_digit) 1051 l = default_val; 1052 *limit = l; 1053 } else 1054 p_error = parse_bad_uint_error; 1055 1056 return (s == s_end); 1057 } 1058 1059 /* 1060 * FUNCTION: get_time_t 1061 * 1062 * Parse a buffer containing a time_t string 1063 * 1064 * RETURN VALUE: TRUE on success, FALSE on failure 1065 * 1066 * INPUT: the attribute value string (assumed to be non-NULL) 1067 */ 1068 1069 static bool_t 1070 get_time_t(const char *s, time_t *t, time_t default_val) 1071 { 1072 bool_t got_digit = FALSE; 1073 time_t timeout = 0; 1074 1075 for (; is_whitespace(*s); s++) 1076 ; 1077 while (isdigit(*s)) { 1078 got_digit = TRUE; 1079 if (WILL_OVERFLOW_TIME(timeout, *s)) 1080 timeout = TIME_MAX; 1081 else 1082 timeout = timeout * 10 + *s - '0'; 1083 s++; 1084 } 1085 for (; is_whitespace(*s); s++) 1086 ; 1087 if (*s != '\0') { 1088 p_error = parse_bad_int_error; 1089 return (FALSE); 1090 } 1091 if (!got_digit) 1092 timeout = default_val; 1093 1094 *t = timeout; 1095 return (TRUE); 1096 } 1097 1098 /* 1099 * FUNCTION: get_uint_val 1100 * 1101 * Parse a buffer containing a non-negative integer 1102 * 1103 * RETURN VALUE: TRUE on success, FALSE on failure 1104 * 1105 * INPUT: the attribute value string (assumed to be non-NULL) 1106 */ 1107 1108 static bool_t 1109 get_uint_val(const char *s, int *val, int default_val) 1110 { 1111 bool_t got_digit = FALSE; 1112 int v = 0; 1113 1114 for (; is_whitespace(*s); s++) 1115 ; 1116 while (isdigit(*s)) { 1117 got_digit = TRUE; 1118 if (WILL_OVERFLOW_INT(v, *s)) 1119 v = INT_MAX; 1120 else 1121 v = v * 10 + *s - '0'; 1122 s++; 1123 } 1124 for (; is_whitespace(*s); s++) 1125 ; 1126 if (*s != '\0') { 1127 p_error = parse_bad_int_error; 1128 return (FALSE); 1129 } 1130 1131 if (!got_digit) 1132 v = default_val; 1133 1134 *val = v; 1135 return (TRUE); 1136 } 1137 1138 /* 1139 * FUNCTION: get_int_val 1140 * 1141 * Parse a buffer containing a non-negative integer 1142 * 1143 * RETURN VALUE: TRUE on success, FALSE on failure 1144 * 1145 * INPUT: the attribute value string (assumed to be non-NULL) 1146 */ 1147 1148 static bool_t 1149 get_int_val(const char *s, int *val, int default_val) 1150 { 1151 bool_t got_digit = FALSE; 1152 int v = 0; 1153 bool_t is_neg = FALSE; 1154 1155 for (; is_whitespace(*s); s++) 1156 ; 1157 if (*s == '-') { 1158 is_neg = TRUE; 1159 s++; 1160 } 1161 while (isdigit(*s)) { 1162 got_digit = TRUE; 1163 if (WILL_OVERFLOW_INT(v, *s)) 1164 v = INT_MAX; 1165 else 1166 v = v * 10 + *s - '0'; 1167 s++; 1168 } 1169 for (; is_whitespace(*s); s++) 1170 ; 1171 if (*s != '\0') { 1172 p_error = parse_bad_int_error; 1173 return (FALSE); 1174 } 1175 1176 if (!got_digit) { 1177 if (is_neg) { 1178 p_error = parse_bad_int_error; 1179 return (FALSE); 1180 } 1181 v = default_val; 1182 } 1183 if (is_neg) 1184 v = -v; 1185 *val = v; 1186 return (TRUE); 1187 } 1188 1189 static void 1190 warn_duplicate_val( 1191 config_key attrib_num) 1192 { 1193 const char *key_name = "Unknown"; 1194 int i; 1195 1196 if (warn_file == NULL || is_cmd_line_option(attrib_num)) 1197 return; 1198 1199 for (i = 0; i < sizeof (keyword_lookup) / 1200 sizeof (keyword_lookup[0]); i++) { 1201 if (attrib_num == keyword_lookup[i].key_id) { 1202 key_name = keyword_lookup[i].key_name; 1203 break; 1204 } 1205 } 1206 if (cons != NULL) { 1207 fprintf(cons, 1208 "Warning: Duplicate value for %s in %s at line:%d\n", 1209 key_name, warn_file, start_line_num); 1210 } else { 1211 syslog(LOG_INFO, 1212 "Duplicate value for %s in %s at line:%d", 1213 key_name, warn_file, start_line_num); 1214 } 1215 } 1216 1217 void 1218 warn_duplicate_map( 1219 const char *db_id, 1220 config_key attrib_num) 1221 { 1222 const char *key_name = "Unknown"; 1223 int i; 1224 1225 if (warn_file == NULL) 1226 return; 1227 1228 for (i = 0; i < sizeof (keyword_lookup) / 1229 sizeof (keyword_lookup[0]); i++) { 1230 if (attrib_num == keyword_lookup[i].key_id) { 1231 key_name = keyword_lookup[i].key_name; 1232 break; 1233 } 1234 } 1235 if (cons != NULL) { 1236 fprintf(cons, 1237 "Warning: Duplicate value for %s:%s in %s at line:%d\n", 1238 key_name, db_id, warn_file, start_line_num); 1239 } else { 1240 syslog(LOG_INFO, 1241 "Duplicate value for %s:%s in %s at line:%d", 1242 key_name, db_id, warn_file, start_line_num); 1243 } 1244 } 1245