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