2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A/*
2N/A * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
2N/A */
2N/A
2N/A#include <stdio.h>
2N/A#include <string.h>
2N/A#include <stdlib.h>
2N/A#include <ctype.h>
2N/A#include <fcntl.h>
2N/A#include <unistd.h>
2N/A#include <errno.h>
2N/A#include <locale.h>
2N/A#include <lber.h>
2N/A#include <ldap.h>
2N/A#include <syslog.h>
2N/A
2N/A#include "ldap_parse.h"
2N/A#include "nis_parse_ldap_conf.h"
2N/A
2N/Aextern FILE *cons;
2N/A
2N/Astatic bool_t get_timeval_t(const char *s, int len, struct timeval *t,
2N/A time_t default_val);
2N/Astatic bool_t get_limit(const char *s, int len, int *limit, int default_val);
2N/Astatic bool_t get_time_t(const char *s, time_t *t, time_t default_val);
2N/Astatic bool_t get_uint_val(const char *attrib_val, int *val, int default_val);
2N/Astatic bool_t get_int_val(const char *attrib_val, int *val, int default_val);
2N/Astatic void warn_duplicate_val(config_key attrib_num);
2N/A
2N/Astatic struct {
2N/A const char *key_name;
2N/A config_key key_id;
2N/A} keyword_lookup[] = {
2N/A {YP_CONFIG_DN, key_yp_config_dn},
2N/A {YP_CONFIG_SERVER_LIST, key_yp_config_server_list},
2N/A {YP_CONFIG_AUTH_METHOD, key_yp_config_auth_method},
2N/A {YP_CONFIG_TLS_OPTION, key_yp_config_tls_option},
2N/A {YP_CONFIG_TLS_CERT_DB, key_yp_config_tls_certificate_db},
2N/A {YP_CONFIG_PROXY_USER, key_yp_config_proxy_user},
2N/A {YP_CONFIG_PROXY_PASSWD, key_yp_config_proxy_passwd},
2N/A {PREFERRED_SERVERS, key_preferred_servers},
2N/A {AUTH_METHOD, key_auth_method},
2N/A {YP_TLS_OPTION, key_yp_tls_option},
2N/A {YP_TLS_CERT_DB, key_yp_tls_certificate_db},
2N/A {SEARCH_BASE, key_search_base},
2N/A {YP_PROXY_USER, key_yp_proxy_user},
2N/A {YP_PROXY_PASSWD, key_yp_proxy_passwd},
2N/A {YP_LDAP_BASE_DOMAIN, key_yp_ldap_base_domain},
2N/A {YP_BIND_TIMEOUT, key_yp_bind_timeout},
2N/A {YP_SEARCH_TIMEOUT, key_yp_search_timeout},
2N/A {YP_MODIFY_TIMEOUT, key_yp_modify_timeout},
2N/A {YP_ADD_TIMEOUT, key_yp_add_timeout},
2N/A
2N/A {YP_DELETE_TIMEOUT, key_yp_delete_timeout},
2N/A {YP_SEARCH_TIME_LIMIT, key_yp_search_time_limit},
2N/A {YP_SEARCH_SIZE_LIMIT, key_yp_search_size_limit},
2N/A {YP_FOLLOW_REFERRAL, key_yp_follow_referral},
2N/A {INITIAL_UPDATE_ACTION, key_initial_update_action},
2N/A {INITIAL_UPDATE_ONLY, key_initial_update_only},
2N/A {YP_RETRIEVE_ERROR_ACTION, key_yp_retrieve_error_action},
2N/A {YP_RETREIVE_ERROR_ATTEMPTS,
2N/A key_yp_retrieve_error_attempts},
2N/A {YP_RETREIVE_ERROR_TIMEOUT,
2N/A key_yp_retreive_error_timeout},
2N/A {YP_STORE_ERROR_ACTION, key_yp_store_error_action},
2N/A {YP_STORE_ERROR_ATTEMPTS, key_yp_store_error_attempts},
2N/A {YP_STORE_ERROR_TIMEOUT, key_yp_store_error_timeout},
2N/A
2N/A {REFRESH_ERROR_ACTION, key_refresh_error_action},
2N/A
2N/A {REFRESH_ERROR_ATTEMPTS,
2N/A key_refresh_error_attempts},
2N/A {REFRESH_ERROR_TIMEOUT, key_refresh_error_timeout},
2N/A {THREAD_CREATE_ERROR_ACTION,
2N/A key_thread_create_error_action},
2N/A {THREAD_CREATE_ERROR_ATTEMPTS,
2N/A key_thread_create_error_attempts},
2N/A {THREAD_CREATE_ERROR_TIMEOUT,
2N/A key_thread_create_error_timeout},
2N/A {DUMP_ERROR_ACTION, key_dump_error_action},
2N/A {DUMP_ERROR_ATTEMPTS, key_dump_error_attempts},
2N/A {DUMP_ERROR_TIMEOUT, key_dump_error_timeout},
2N/A {RESYNC, key_resync},
2N/A {UPDATE_BATCHING, key_update_batching},
2N/A {UPDATE_BATCHING_TIMEOUT,
2N/A key_update_batching_timeout},
2N/A {YP_MATCH_FETCH, key_yp_match_fetch},
2N/A {NUMBER_THREADS, key_number_threads},
2N/A {YP_EMULATION, key_yp_emulation},
2N/A {MAX_RPC_RECSIZE, key_max_rpc_recsize},
2N/A {YP_DOMAIN_CONTEXT, key_yp_domain_context},
2N/A {YPPASSWDD_DOMAINS, key_yppasswdd_domains},
2N/A {YP_DB_ID_MAP, key_yp_db_id_map},
2N/A {YP_COMMENT_CHAR, key_yp_comment_char},
2N/A {YP_MAP_FLAGS, key_yp_map_flags},
2N/A {YP_ENTRY_TTL, key_yp_entry_ttl},
2N/A {YP_NAME_FIELDS, key_yp_name_fields},
2N/A {YP_SPLIT_FIELD, key_yp_split_field},
2N/A {YP_REPEATED_FIELD_SEPARATORS, key_yp_repeated_field_separators},
2N/A {YP_LDAP_OBJECT_DN, key_yp_ldap_object_dn},
2N/A {LDAP_TO_NIS_MAP, key_ldap_to_nis_map},
2N/A {NIS_TO_LDAP_MAP, key_nis_to_ldap_map}
2N/A};
2N/A
2N/A/*
2N/A * FUNCTION: add_config_attribute
2N/A *
2N/A * Adds the attribute value to __nis_config_info_t
2N/A * if the value is not yet set.
2N/A *
2N/A * RETURN VALUE: 0 on success, -1 on failure
2N/A *
2N/A * INPUT: attribute number and value (assumed to be non-NULL)
2N/A */
2N/A
2N/Aint
2N/Aadd_config_attribute(
2N/A config_key attrib_num,
2N/A const char *attrib_val,
2N/A int attrib_len,
2N/A __nis_config_info_t *config_info)
2N/A{
2N/A switch (attrib_num) {
2N/A case key_yp_config_dn:
2N/A if (config_info->config_dn == NULL) {
2N/A if (!validate_dn(attrib_val, attrib_len))
2N/A break;
2N/A config_info->config_dn =
2N/A s_strndup(attrib_val, attrib_len);
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_yp_config_server_list:
2N/A if (config_info->default_servers == NULL) {
2N/A config_info->default_servers =
2N/A s_strndup(attrib_val, attrib_len);
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_yp_config_auth_method:
2N/A if (config_info->auth_method ==
2N/A (auth_method_t)NO_VALUE_SET) {
2N/A if (same_string("none", attrib_val,
2N/A attrib_len))
2N/A config_info->auth_method = none;
2N/A else if (same_string("simple", attrib_val,
2N/A attrib_len))
2N/A config_info->auth_method = simple;
2N/A else if (same_string("sasl/cram-md5",
2N/A attrib_val, attrib_len))
2N/A config_info->auth_method = cram_md5;
2N/A else if (same_string("sasl/digest-md5",
2N/A attrib_val, attrib_len))
2N/A config_info->auth_method = digest_md5;
2N/A else
2N/A p_error = parse_bad_auth_method_error;
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_yp_config_tls_option:
2N/A if (config_info->tls_method ==
2N/A (tls_method_t)NO_VALUE_SET) {
2N/A if (same_string("none", attrib_val,
2N/A attrib_len))
2N/A config_info->tls_method = no_tls;
2N/A else if (same_string("ssl", attrib_val,
2N/A attrib_len))
2N/A config_info->tls_method = ssl_tls;
2N/A else
2N/A p_error = parse_bad_tls_option_error;
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_yp_config_tls_certificate_db:
2N/A if (config_info->tls_cert_db == NULL) {
2N/A config_info->tls_cert_db =
2N/A s_strndup(attrib_val, attrib_len);
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_yp_config_proxy_user:
2N/A if (config_info->proxy_dn == NULL) {
2N/A config_info->proxy_dn =
2N/A s_strndup(attrib_val, attrib_len);
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_yp_config_proxy_passwd:
2N/A if (config_info->proxy_passwd == NULL) {
2N/A config_info->proxy_passwd =
2N/A s_strndup_esc(attrib_val, attrib_len);
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A default:
2N/A p_error = parse_internal_err;
2N/A break;
2N/A }
2N/A return (p_error == no_parse_error ? 0 : -1);
2N/A}
2N/A
2N/A/*
2N/A * FUNCTION: add_bind_attribute
2N/A *
2N/A * Adds the attribute value to __nis_ldap_proxy_info
2N/A * if the value is not yet set.
2N/A *
2N/A * RETURN VALUE: 0 on success, -1 on failure
2N/A *
2N/A * INPUT: attribute number and value (assumed to be non-NULL)
2N/A */
2N/A
2N/Aint
2N/Aadd_bind_attribute(
2N/A config_key attrib_num,
2N/A const char *attrib_val,
2N/A int attrib_len,
2N/A __nis_ldap_proxy_info *proxy_info)
2N/A{
2N/A struct timeval t;
2N/A int limit;
2N/A
2N/A switch (attrib_num) {
2N/A case key_yp_preferred_servers:
2N/A case key_preferred_servers:
2N/A if (proxy_info->default_servers == NULL) {
2N/A proxy_info->default_servers =
2N/A s_strndup(attrib_val, attrib_len);
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_yp_auth_method:
2N/A case key_auth_method:
2N/A if (proxy_info->auth_method ==
2N/A (auth_method_t)NO_VALUE_SET) {
2N/A if (same_string("none", attrib_val,
2N/A attrib_len))
2N/A proxy_info->auth_method = none;
2N/A else if (same_string("simple", attrib_val,
2N/A attrib_len))
2N/A proxy_info->auth_method = simple;
2N/A else if (same_string("sasl/cram-md5",
2N/A attrib_val, attrib_len))
2N/A proxy_info->auth_method = cram_md5;
2N/A else if (same_string("sasl/digest-md5",
2N/A attrib_val, attrib_len))
2N/A proxy_info->auth_method = digest_md5;
2N/A else
2N/A p_error = parse_bad_auth_method_error;
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_yp_tls_option:
2N/A if (proxy_info->tls_method ==
2N/A (tls_method_t)NO_VALUE_SET) {
2N/A if (same_string("none", attrib_val,
2N/A attrib_len))
2N/A proxy_info->tls_method = no_tls;
2N/A else if (same_string("ssl", attrib_val,
2N/A attrib_len))
2N/A proxy_info->tls_method = ssl_tls;
2N/A else
2N/A p_error = parse_bad_tls_option_error;
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_yp_tls_certificate_db:
2N/A if (proxy_info->tls_cert_db == NULL) {
2N/A proxy_info->tls_cert_db =
2N/A s_strndup(attrib_val, attrib_len);
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_yp_search_base:
2N/A if (proxy_info->default_search_base == NULL) {
2N/A if (!validate_dn(attrib_val, attrib_len))
2N/A break;
2N/A proxy_info->default_search_base =
2N/A s_strndup(attrib_val, attrib_len);
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_yp_proxy_user:
2N/A if (proxy_info->proxy_dn == NULL) {
2N/A proxy_info->proxy_dn =
2N/A s_strndup(attrib_val, attrib_len);
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_yp_proxy_passwd:
2N/A if (proxy_info->proxy_passwd == NULL) {
2N/A proxy_info->proxy_passwd =
2N/A s_strndup_esc(attrib_val, attrib_len);
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_yp_ldap_base_domain:
2N/A if (proxy_info->default_nis_domain == NULL) {
2N/A proxy_info->default_nis_domain =
2N/A s_strndup_esc(attrib_val, attrib_len);
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_yp_bind_timeout:
2N/A if (proxy_info->bind_timeout.tv_sec ==
2N/A (time_t)NO_VALUE_SET) {
2N/A if (!get_timeval_t(attrib_val, attrib_len, &t,
2N/A DEFAULT_BIND_TIMEOUT))
2N/A break;
2N/A proxy_info->bind_timeout = t;
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_yp_search_timeout:
2N/A if (proxy_info->search_timeout.tv_sec ==
2N/A (time_t)NO_VALUE_SET) {
2N/A if (!get_timeval_t(attrib_val, attrib_len, &t,
2N/A DEFAULT_YP_SEARCH_TIMEOUT))
2N/A break;
2N/A proxy_info->search_timeout = t;
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A
2N/A case key_yp_modify_timeout:
2N/A if (proxy_info->modify_timeout.tv_sec ==
2N/A (time_t)NO_VALUE_SET) {
2N/A if (!get_timeval_t(attrib_val, attrib_len, &t,
2N/A DEFAULT_MODIFY_TIMEOUT))
2N/A break;
2N/A proxy_info->modify_timeout = t;
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_yp_add_timeout:
2N/A if (proxy_info->add_timeout.tv_sec ==
2N/A (time_t)NO_VALUE_SET) {
2N/A if (!get_timeval_t(attrib_val, attrib_len, &t,
2N/A DEFAULT_ADD_TIMEOUT))
2N/A break;
2N/A proxy_info->add_timeout = t;
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_yp_delete_timeout:
2N/A if (proxy_info->delete_timeout.tv_sec ==
2N/A (time_t)NO_VALUE_SET) {
2N/A if (!get_timeval_t(attrib_val, attrib_len, &t,
2N/A DEFAULT_DELETE_TIMEOUT))
2N/A break;
2N/A proxy_info->delete_timeout = t;
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_yp_search_time_limit:
2N/A if (proxy_info->search_time_limit ==
2N/A (int)NO_VALUE_SET) {
2N/A if (!get_limit(attrib_val, attrib_len, &limit,
2N/A DEFAULT_SEARCH_TIME_LIMIT))
2N/A break;
2N/A proxy_info->search_time_limit = limit;
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_yp_search_size_limit:
2N/A if (proxy_info->search_size_limit ==
2N/A (int)NO_VALUE_SET) {
2N/A if (!get_limit(attrib_val, attrib_len, &limit,
2N/A DEFAULT_SEARCH_SIZE_LIMIT))
2N/A break;
2N/A proxy_info->search_size_limit = limit;
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_yp_follow_referral:
2N/A if (proxy_info->follow_referral ==
2N/A (follow_referral_t)NO_VALUE_SET) {
2N/A if (same_string("yes", attrib_val, attrib_len))
2N/A proxy_info->follow_referral = follow;
2N/A else if (same_string("no", attrib_val,
2N/A attrib_len))
2N/A proxy_info->follow_referral =
2N/A no_follow;
2N/A else
2N/A p_error =
2N/A parse_yes_or_no_expected_error;
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A default:
2N/A p_error = parse_internal_err;
2N/A break;
2N/A }
2N/A return (p_error == no_parse_error ? 0 : -1);
2N/A}
2N/A
2N/A/*
2N/A * FUNCTION: add_operation_attribute
2N/A *
2N/A * Adds the attribute value to __nis_config_t and
2N/A * __nisdb_table_mapping_t if the value is not yet set.
2N/A *
2N/A * RETURN VALUE: 0 on success, -1 on failure
2N/A *
2N/A * INPUT: attribute number and value (assumed to be non-NULL)
2N/A */
2N/A
2N/Aint
2N/Aadd_operation_attribute(
2N/A config_key attrib_num,
2N/A const char *attrib_val,
2N/A int attrib_len,
2N/A __nis_config_t *config_info,
2N/A __nisdb_table_mapping_t *table_info)
2N/A{
2N/A char buf[1024];
2N/A int i;
2N/A int len;
2N/A time_t timeout;
2N/A bool_t last_digit = FALSE;
2N/A
2N/A for (i = 0, len = 0; i < attrib_len; i++) {
2N/A if (!last_digit &&
2N/A is_whitespace(attrib_val[i]))
2N/A continue;
2N/A buf[len++] = attrib_val[i];
2N/A if (len >= sizeof (buf)) {
2N/A p_error = parse_line_too_long;
2N/A return (-1);
2N/A }
2N/A last_digit = isdigit(attrib_val[i]);
2N/A }
2N/A buf[len] = '\0';
2N/A
2N/A switch (attrib_num) {
2N/A case key_initial_update_action:
2N/A if (config_info->initialUpdate ==
2N/A (__nis_initial_update_t)NO_VALUE_SET) {
2N/A if (strcasecmp("none", buf) == 0)
2N/A config_info->initialUpdate = ini_none;
2N/A else if (strcasecmp("from_ldap", buf) == 0)
2N/A config_info->initialUpdate =
2N/A (__nis_initial_update_t)
2N/A FROM_NO_INITIAL_UPDATE;
2N/A else if (strcasecmp("to_ldap", buf) == 0)
2N/A config_info->initialUpdate =
2N/A (__nis_initial_update_t)
2N/A TO_NO_INITIAL_UPDATE;
2N/A else
2N/A p_error =
2N/A parse_initial_update_action_error;
2N/A } else if (config_info->initialUpdate ==
2N/A (__nis_initial_update_t)INITIAL_UPDATE_NO_ACTION) {
2N/A if (strcasecmp("none", buf) == 0)
2N/A config_info->initialUpdate = ini_none;
2N/A else if (strcasecmp("from_ldap", buf) == 0)
2N/A config_info->initialUpdate =
2N/A from_ldap_update_only;
2N/A else if (strcasecmp("to_ldap", buf) == 0)
2N/A config_info->initialUpdate =
2N/A to_ldap_update_only;
2N/A else
2N/A p_error =
2N/A parse_initial_update_action_error;
2N/A } else if (config_info->initialUpdate ==
2N/A (__nis_initial_update_t)
2N/A NO_INITIAL_UPDATE_NO_ACTION) {
2N/A if (strcasecmp("none", buf) == 0)
2N/A config_info->initialUpdate = ini_none;
2N/A else if (strcasecmp("from_ldap", buf) == 0)
2N/A config_info->initialUpdate = from_ldap;
2N/A else if (strcasecmp("to_ldap", buf) == 0)
2N/A config_info->initialUpdate = to_ldap;
2N/A else
2N/A p_error =
2N/A parse_initial_update_action_error;
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_initial_update_only:
2N/A if (config_info->initialUpdate ==
2N/A (__nis_initial_update_t)NO_VALUE_SET) {
2N/A if (strcasecmp("yes", buf) == 0)
2N/A config_info->initialUpdate =
2N/A (__nis_initial_update_t)
2N/A INITIAL_UPDATE_NO_ACTION;
2N/A else if (strcasecmp("no", buf) == 0)
2N/A config_info->initialUpdate =
2N/A (__nis_initial_update_t)
2N/A NO_INITIAL_UPDATE_NO_ACTION;
2N/A else
2N/A p_error =
2N/A parse_initial_update_only_error;
2N/A } else if (config_info->initialUpdate ==
2N/A (__nis_initial_update_t)FROM_NO_INITIAL_UPDATE) {
2N/A if (strcasecmp("yes", buf) == 0)
2N/A config_info->initialUpdate =
2N/A from_ldap_update_only;
2N/A else if (strcasecmp("no", buf) == 0)
2N/A config_info->initialUpdate = from_ldap;
2N/A else
2N/A p_error =
2N/A parse_initial_update_only_error;
2N/A } else if (config_info->initialUpdate ==
2N/A (__nis_initial_update_t)TO_NO_INITIAL_UPDATE) {
2N/A if (strcasecmp("yes", buf) == 0)
2N/A config_info->initialUpdate =
2N/A to_ldap_update_only;
2N/A else if (strcasecmp("no", buf) == 0)
2N/A config_info->initialUpdate = to_ldap;
2N/A else
2N/A p_error =
2N/A parse_initial_update_only_error;
2N/A } else if (config_info->initialUpdate != ini_none) {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_thread_create_error_action:
2N/A if (config_info->threadCreationError ==
2N/A (__nis_thread_creation_error_t)NO_VALUE_SET) {
2N/A if (strcasecmp("pass_error", buf) == 0)
2N/A config_info->threadCreationError =
2N/A pass_error;
2N/A else if (strcasecmp("retry", buf) == 0)
2N/A config_info->threadCreationError =
2N/A cre_retry;
2N/A else
2N/A p_error =
2N/A parse_thr_create_err_action_err;
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_thread_create_error_attempts:
2N/A if (config_info->threadCreationErrorTimeout.attempts ==
2N/A NO_VALUE_SET) {
2N/A if (get_int_val(buf, &i,
2N/A DEFAULT_THREAD_ERROR_ATTEMPTS))
2N/A config_info->
2N/A threadCreationErrorTimeout.attempts
2N/A = i;
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_thread_create_error_timeout:
2N/A if (config_info->threadCreationErrorTimeout.timeout ==
2N/A (time_t)NO_VALUE_SET) {
2N/A if (get_time_t(buf, &timeout,
2N/A DEFAULT_THREAD_ERROR_TIME_OUT))
2N/A config_info->
2N/A threadCreationErrorTimeout.timeout =
2N/A timeout;
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_dump_error_action:
2N/A if (config_info->dumpError ==
2N/A (__nis_dump_error_t)NO_VALUE_SET) {
2N/A if (strcasecmp("rollback", buf) == 0)
2N/A config_info->dumpError = rollback;
2N/A else if (strcasecmp("retry", buf) == 0)
2N/A config_info->dumpError = de_retry;
2N/A else
2N/A p_error = parse_dump_error_action_error;
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_dump_error_attempts:
2N/A if (config_info->dumpErrorTimeout.attempts ==
2N/A NO_VALUE_SET) {
2N/A if (get_int_val(buf, &i,
2N/A DEFAULT_DUMP_ERROR_ATTEMPTS))
2N/A config_info->
2N/A dumpErrorTimeout.attempts = i;
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_dump_error_timeout:
2N/A if (config_info->dumpErrorTimeout.timeout ==
2N/A (time_t)NO_VALUE_SET) {
2N/A if (get_time_t(buf, &timeout,
2N/A DEFAULT_DUMP_ERROR_TIME_OUT))
2N/A config_info->
2N/A dumpErrorTimeout.timeout = timeout;
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_resync:
2N/A if (config_info->resyncService ==
2N/A (__nis_resync_service_t)NO_VALUE_SET) {
2N/A if (strcasecmp("directory_locked", buf) == 0)
2N/A config_info->resyncService =
2N/A directory_locked;
2N/A else if (strcasecmp("from_copy", buf) == 0)
2N/A config_info->resyncService = from_copy;
2N/A else if (strcasecmp("from_live", buf) == 0)
2N/A config_info->resyncService = from_live;
2N/A else
2N/A p_error = parse_resync_error;
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_update_batching:
2N/A if (config_info->updateBatching ==
2N/A (__nis_update_batching_t)NO_VALUE_SET) {
2N/A if (strcasecmp("none", buf) == 0)
2N/A config_info->updateBatching = upd_none;
2N/A else if (strcasecmp("accumulate", buf) == 0) {
2N/A config_info->updateBatching =
2N/A accumulate;
2N/A } else if (strcasecmp("bounded_accumulate",
2N/A buf) == 0) {
2N/A config_info->updateBatching =
2N/A bounded_accumulate;
2N/A } else
2N/A p_error = parse_update_batching_error;
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_update_batching_timeout:
2N/A if (config_info->updateBatchingTimeout.timeout ==
2N/A (time_t)NO_VALUE_SET) {
2N/A if (get_time_t(buf, &timeout,
2N/A DEFAULT_BATCHING_TIME_OUT))
2N/A config_info->
2N/A updateBatchingTimeout.timeout =
2N/A timeout;
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_number_threads:
2N/A if (config_info->numberOfServiceThreads ==
2N/A (int)NO_VALUE_SET) {
2N/A if (get_uint_val(buf, &i,
2N/A DEFAULT_NUMBER_OF_THREADS))
2N/A config_info->numberOfServiceThreads =
2N/A i;
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_yp_emulation:
2N/A if (config_info->emulate_yp ==
2N/A (int)NO_VALUE_SET) {
2N/A if (strcasecmp("yes", buf) == 0)
2N/A config_info->emulate_yp = TRUE;
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_yp_retrieve_error_action:
2N/A if (table_info->retrieveError ==
2N/A (__nis_retrieve_error_t)NO_VALUE_SET) {
2N/A if (strcasecmp("use_cached", buf) == 0)
2N/A table_info->retrieveError = use_cached;
2N/A else if (strcasecmp("fail", buf) == 0)
2N/A table_info->retrieveError = fail;
2N/A else
2N/A p_error =
2N/A parse_yp_retrieve_err_action_err;
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_yp_retrieve_error_attempts:
2N/A if (table_info->retrieveErrorRetry.attempts ==
2N/A NO_VALUE_SET) {
2N/A if (get_int_val(buf, &i,
2N/A DEFAULT_RETRIEVE_ERROR_ATTEMPTS))
2N/A table_info->
2N/A retrieveErrorRetry.attempts = i;
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_yp_retreive_error_timeout:
2N/A if (table_info->retrieveErrorRetry.timeout ==
2N/A (time_t)NO_VALUE_SET) {
2N/A if (get_time_t(buf, &timeout,
2N/A DEFAULT_RETRIEVE_ERROR_TIME_OUT))
2N/A table_info->retrieveErrorRetry.timeout
2N/A = timeout;
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_yp_store_error_action:
2N/A if (table_info->storeError ==
2N/A (__nis_store_error_t)NO_VALUE_SET) {
2N/A if (strcasecmp("retry", buf) == 0)
2N/A table_info->storeError = sto_retry;
2N/A else if (strcasecmp("fail", buf) == 0)
2N/A table_info->storeError = sto_fail;
2N/A else
2N/A p_error =
2N/A parse_yp_store_error_action_error;
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_yp_store_error_attempts:
2N/A if (table_info->storeErrorRetry.attempts ==
2N/A NO_VALUE_SET) {
2N/A if (get_int_val(buf, &i,
2N/A DEFAULT_STORE_ERROR_ATTEMPTS))
2N/A table_info->storeErrorRetry.attempts =
2N/A i;
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_yp_store_error_timeout:
2N/A if (table_info->storeErrorRetry.timeout ==
2N/A (time_t)NO_VALUE_SET) {
2N/A if (get_time_t(buf, &timeout,
2N/A DEFAULT_STORE_ERROR_TIME_OUT))
2N/A table_info->storeErrorRetry.timeout =
2N/A timeout;
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_refresh_error_action:
2N/A if (table_info->refreshError ==
2N/A (__nis_refresh_error_t)NO_VALUE_SET) {
2N/A if (strcasecmp("continue_using", buf) == 0)
2N/A table_info->refreshError =
2N/A continue_using;
2N/A else if (strcasecmp("cache_expired", buf) == 0)
2N/A table_info->refreshError =
2N/A cache_expired;
2N/A else if (strcasecmp("tryagain", buf) == 0)
2N/A table_info->refreshError = tryagain;
2N/A else if (strcasecmp("retry", buf) == 0)
2N/A table_info->refreshError = ref_retry;
2N/A else if (strcasecmp("continue_using,retry",
2N/A buf) == 0 || strcasecmp(
2N/A "retry,continue_using", buf) == 0)
2N/A table_info->refreshError =
2N/A continue_using_retry;
2N/A else
2N/A p_error = parse_refresh_error_action_error;
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_refresh_error_attempts:
2N/A if (table_info->refreshErrorRetry.attempts ==
2N/A NO_VALUE_SET) {
2N/A if (get_int_val(buf, &i,
2N/A DEFAULT_REFRESH_ERROR_ATTEMPTS))
2N/A table_info->refreshErrorRetry.attempts
2N/A = i;
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_refresh_error_timeout:
2N/A if (table_info->refreshErrorRetry.timeout ==
2N/A (time_t)NO_VALUE_SET) {
2N/A if (get_time_t(buf, &timeout,
2N/A DEFAULT_REFRESH_ERROR_TIME_OUT))
2N/A table_info->refreshErrorRetry.timeout = timeout;
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_yp_match_fetch:
2N/A if (table_info->matchFetch ==
2N/A (__nis_match_fetch_t)NO_VALUE_SET) {
2N/A if (strcasecmp("no_match_only", buf) == 0)
2N/A table_info->matchFetch = no_match_only;
2N/A else if (strcasecmp("always", buf) == 0)
2N/A table_info->matchFetch = mat_always;
2N/A else if (strcasecmp("never", buf) == 0)
2N/A table_info->matchFetch = mat_never;
2N/A else
2N/A p_error = parse_match_fetch_error;
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A case key_max_rpc_recsize:
2N/A if (config_info->maxRPCRecordSize ==
2N/A (int)NO_VALUE_SET) {
2N/A if (get_uint_val(buf, &i, RPC_MAXDATASIZE))
2N/A config_info->maxRPCRecordSize = i;
2N/A } else {
2N/A warn_duplicate_val(attrib_num);
2N/A }
2N/A break;
2N/A default:
2N/A p_error = parse_internal_err;
2N/A break;
2N/A }
2N/A
2N/A return (p_error == no_parse_error ? 0 : -1);
2N/A}
2N/A
2N/A/*
2N/A * FUNCTION: get_attrib_num
2N/A *
2N/A * Get the attribute number for the corresponding keyword.
2N/A *
2N/A * RETURN VALUE: attribute number on success,
2N/A * key_bad on failure
2N/A *
2N/A * INPUT: the attribute name string (assumed to be non-NULL)
2N/A */
2N/A
2N/Aconfig_key
2N/Aget_attrib_num(const char *s, int n)
2N/A{
2N/A int k;
2N/A int i;
2N/A config_key attrib_num = key_bad;
2N/A
2N/A k = n < sizeof (_key_val) ? n : sizeof (_key_val) - 1;
2N/A (void) memcpy(_key_val, s, k);
2N/A _key_val[k] = '\0';
2N/A
2N/A for (i = 0; i < sizeof (keyword_lookup) /
2N/A sizeof (keyword_lookup[0]); i++) {
2N/A if (strncasecmp(s, keyword_lookup[i].key_name, n) == 0 &&
2N/A strlen(keyword_lookup[i].key_name) == n) {
2N/A attrib_num = keyword_lookup[i].key_id;
2N/A break;
2N/A }
2N/A }
2N/A
2N/A if (attrib_num == key_bad) {
2N/A p_error = parse_bad_key;
2N/A }
2N/A
2N/A return (attrib_num);
2N/A}
2N/A
2N/A/*
2N/A * FUNCTION: get_timeval_t
2N/A *
2N/A * Extract time from string
2N/A *
2N/A * RETURN VALUE: TRUE if parsed
2N/A * FALSE otherwise
2N/A *
2N/A * INPUT: the attribute value string (assumed to be non-NULL)
2N/A */
2N/A
2N/Astatic bool_t
2N/Aget_timeval_t(
2N/A const char *s,
2N/A int len,
2N/A struct timeval *t,
2N/A time_t default_val)
2N/A{
2N/A time_t tv_sec = 0;
2N/A time_t tv_usec = 0;
2N/A time_t digit;
2N/A time_t mult = 100000;
2N/A bool_t got_digit = FALSE;
2N/A bool_t got_period = FALSE;
2N/A const char *s_end = s + len;
2N/A
2N/A while (s < s_end && is_whitespace(*s))
2N/A s++;
2N/A
2N/A while (s < s_end && isdigit(*s)) {
2N/A digit = (*s++) - '0';
2N/A got_digit = TRUE;
2N/A if (WILL_OVERFLOW_TIME(tv_sec, digit))
2N/A tv_sec = TIME_MAX;
2N/A else
2N/A tv_sec = tv_sec * 10 + digit;
2N/A }
2N/A while (s < s_end && is_whitespace(*s))
2N/A s++;
2N/A
2N/A if (s < s_end && *s == PERIOD_CHAR) {
2N/A s++;
2N/A got_period = TRUE;
2N/A while (s < s_end && isdigit(*s)) {
2N/A got_digit = TRUE;
2N/A digit = (*s++) - '0';
2N/A tv_usec += digit * mult;
2N/A mult /= 10;
2N/A }
2N/A while (s < s_end && is_whitespace(*s))
2N/A s++;
2N/A }
2N/A if (s == s_end) {
2N/A if (!got_digit) {
2N/A if (got_period) {
2N/A p_error = parse_bad_time_error;
2N/A return (FALSE);
2N/A }
2N/A tv_sec = default_val;
2N/A }
2N/A t->tv_sec = tv_sec;
2N/A t->tv_usec = tv_usec;
2N/A } else
2N/A p_error = parse_bad_time_error;
2N/A
2N/A return (s == s_end);
2N/A}
2N/A
2N/A/*
2N/A * FUNCTION: get_limit
2N/A *
2N/A * Extract limit from string
2N/A *
2N/A * RETURN VALUE: TRUE if parsed
2N/A * FALSE otherwise
2N/A *
2N/A * INPUT: the attribute value string (assumed to be non-NULL)
2N/A */
2N/A
2N/A
2N/Astatic bool_t
2N/Aget_limit(
2N/A const char *s,
2N/A int len,
2N/A int *limit,
2N/A int default_val)
2N/A{
2N/A bool_t got_digit = FALSE;
2N/A int l = 0;
2N/A time_t digit;
2N/A const char *s_end = s + len;
2N/A
2N/A while (s < s_end && is_whitespace(*s))
2N/A s++;
2N/A
2N/A while (s < s_end && isdigit(*s)) {
2N/A got_digit = TRUE;
2N/A digit = (*s++) - '0';
2N/A if (WILL_OVERFLOW_LIMIT(l, digit))
2N/A l = LIMIT_MAX;
2N/A else
2N/A l = l * 10 + digit;
2N/A }
2N/A while (s < s_end && is_whitespace(*s))
2N/A s++;
2N/A if (s == s_end) {
2N/A if (!got_digit)
2N/A l = default_val;
2N/A *limit = l;
2N/A } else
2N/A p_error = parse_bad_uint_error;
2N/A
2N/A return (s == s_end);
2N/A}
2N/A
2N/A/*
2N/A * FUNCTION: get_time_t
2N/A *
2N/A * Parse a buffer containing a time_t string
2N/A *
2N/A * RETURN VALUE: TRUE on success, FALSE on failure
2N/A *
2N/A * INPUT: the attribute value string (assumed to be non-NULL)
2N/A */
2N/A
2N/Astatic bool_t
2N/Aget_time_t(const char *s, time_t *t, time_t default_val)
2N/A{
2N/A bool_t got_digit = FALSE;
2N/A time_t timeout = 0;
2N/A
2N/A for (; is_whitespace(*s); s++)
2N/A ;
2N/A while (isdigit(*s)) {
2N/A got_digit = TRUE;
2N/A if (WILL_OVERFLOW_TIME(timeout, *s))
2N/A timeout = TIME_MAX;
2N/A else
2N/A timeout = timeout * 10 + *s - '0';
2N/A s++;
2N/A }
2N/A for (; is_whitespace(*s); s++)
2N/A ;
2N/A if (*s != '\0') {
2N/A p_error = parse_bad_int_error;
2N/A return (FALSE);
2N/A }
2N/A if (!got_digit)
2N/A timeout = default_val;
2N/A
2N/A *t = timeout;
2N/A return (TRUE);
2N/A}
2N/A
2N/A/*
2N/A * FUNCTION: get_uint_val
2N/A *
2N/A * Parse a buffer containing a non-negative integer
2N/A *
2N/A * RETURN VALUE: TRUE on success, FALSE on failure
2N/A *
2N/A * INPUT: the attribute value string (assumed to be non-NULL)
2N/A */
2N/A
2N/Astatic bool_t
2N/Aget_uint_val(const char *s, int *val, int default_val)
2N/A{
2N/A bool_t got_digit = FALSE;
2N/A int v = 0;
2N/A
2N/A for (; is_whitespace(*s); s++)
2N/A ;
2N/A while (isdigit(*s)) {
2N/A got_digit = TRUE;
2N/A if (WILL_OVERFLOW_INT(v, *s))
2N/A v = INT_MAX;
2N/A else
2N/A v = v * 10 + *s - '0';
2N/A s++;
2N/A }
2N/A for (; is_whitespace(*s); s++)
2N/A ;
2N/A if (*s != '\0') {
2N/A p_error = parse_bad_int_error;
2N/A return (FALSE);
2N/A }
2N/A
2N/A if (!got_digit)
2N/A v = default_val;
2N/A
2N/A *val = v;
2N/A return (TRUE);
2N/A}
2N/A
2N/A/*
2N/A * FUNCTION: get_int_val
2N/A *
2N/A * Parse a buffer containing a non-negative integer
2N/A *
2N/A * RETURN VALUE: TRUE on success, FALSE on failure
2N/A *
2N/A * INPUT: the attribute value string (assumed to be non-NULL)
2N/A */
2N/A
2N/Astatic bool_t
2N/Aget_int_val(const char *s, int *val, int default_val)
2N/A{
2N/A bool_t got_digit = FALSE;
2N/A int v = 0;
2N/A bool_t is_neg = FALSE;
2N/A
2N/A for (; is_whitespace(*s); s++)
2N/A ;
2N/A if (*s == '-') {
2N/A is_neg = TRUE;
2N/A s++;
2N/A }
2N/A while (isdigit(*s)) {
2N/A got_digit = TRUE;
2N/A if (WILL_OVERFLOW_INT(v, *s))
2N/A v = INT_MAX;
2N/A else
2N/A v = v * 10 + *s - '0';
2N/A s++;
2N/A }
2N/A for (; is_whitespace(*s); s++)
2N/A ;
2N/A if (*s != '\0') {
2N/A p_error = parse_bad_int_error;
2N/A return (FALSE);
2N/A }
2N/A
2N/A if (!got_digit) {
2N/A if (is_neg) {
2N/A p_error = parse_bad_int_error;
2N/A return (FALSE);
2N/A }
2N/A v = default_val;
2N/A }
2N/A if (is_neg)
2N/A v = -v;
2N/A *val = v;
2N/A return (TRUE);
2N/A}
2N/A
2N/Astatic void
2N/Awarn_duplicate_val(
2N/A config_key attrib_num)
2N/A{
2N/A const char *key_name = "Unknown";
2N/A int i;
2N/A
2N/A if (warn_file == NULL || is_cmd_line_option(attrib_num))
2N/A return;
2N/A
2N/A for (i = 0; i < sizeof (keyword_lookup) /
2N/A sizeof (keyword_lookup[0]); i++) {
2N/A if (attrib_num == keyword_lookup[i].key_id) {
2N/A key_name = keyword_lookup[i].key_name;
2N/A break;
2N/A }
2N/A }
2N/A if (cons != NULL) {
2N/A fprintf(cons,
2N/A "Warning: Duplicate value for %s in %s at line:%d\n",
2N/A key_name, warn_file, start_line_num);
2N/A } else {
2N/A syslog(LOG_INFO,
2N/A "Duplicate value for %s in %s at line:%d",
2N/A key_name, warn_file, start_line_num);
2N/A }
2N/A}
2N/A
2N/Avoid
2N/Awarn_duplicate_map(
2N/A const char *db_id,
2N/A config_key attrib_num)
2N/A{
2N/A const char *key_name = "Unknown";
2N/A int i;
2N/A
2N/A if (warn_file == NULL)
2N/A return;
2N/A
2N/A for (i = 0; i < sizeof (keyword_lookup) /
2N/A sizeof (keyword_lookup[0]); i++) {
2N/A if (attrib_num == keyword_lookup[i].key_id) {
2N/A key_name = keyword_lookup[i].key_name;
2N/A break;
2N/A }
2N/A }
2N/A if (cons != NULL) {
2N/A fprintf(cons,
2N/A "Warning: Duplicate value for %s:%s in %s at line:%d\n",
2N/A key_name, db_id, warn_file, start_line_num);
2N/A } else {
2N/A syslog(LOG_INFO,
2N/A "Duplicate value for %s:%s in %s at line:%d",
2N/A key_name, db_id, warn_file, start_line_num);
2N/A }
2N/A}