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