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
add_config_attribute(config_key attrib_num,const char * attrib_val,int attrib_len,__nis_config_info_t * config_info)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
add_bind_attribute(config_key attrib_num,const char * attrib_val,int attrib_len,__nis_ldap_proxy_info * proxy_info)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
add_operation_attribute(config_key attrib_num,const char * attrib_val,int attrib_len,__nis_config_t * config_info,__nisdb_table_mapping_t * table_info)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
get_attrib_num(const char * s,int n)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
get_timeval_t(const char * s,int len,struct timeval * t,time_t default_val)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
get_limit(const char * s,int len,int * limit,int default_val)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
get_time_t(const char * s,time_t * t,time_t default_val)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
get_uint_val(const char * s,int * val,int default_val)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
get_int_val(const char * s,int * val,int default_val)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
warn_duplicate_val(config_key attrib_num)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
warn_duplicate_map(const char * db_id,config_key attrib_num)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