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 (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #include <stdio.h>
27 #include <string.h>
28 #include <stdlib.h>
29 #include <ctype.h>
30 #include <fcntl.h>
31 #include <unistd.h>
32 #include <errno.h>
33 #include <locale.h>
34 #include <sys/stat.h>
35 #include <lber.h>
36 #include <ldap.h>
37 #include <deflt.h>
38
39 #include "ldap_map.h"
40
41 #include "ldap_parse.h"
42 #include "ldap_glob.h"
43 #include "nis_parse_ldap_conf.h"
44
45 __nis_ldap_proxy_info proxyInfo =
46 {NULL, (auth_method_t)NO_VALUE_SET, (tls_method_t)NO_VALUE_SET, NULL,
47 NULL, NULL, NULL, NULL, (follow_referral_t)NO_VALUE_SET};
48 __nis_config_t ldapConfig;
49 __nisdb_table_mapping_t ldapDBTableMapping;
50 __nis_table_mapping_t *ldapTableMapping = NULL;
51 __yp_domain_context_t ypDomains;
52
53 parse_error p_error = no_parse_error;
54 int cur_line_num = 0;
55 int start_line_num = 0;
56 int seq_num = 0;
57 const char *warn_file = NULL;
58
59 char _key_val[38];
60 const char *command_line_source = NULL;
61 const char *file_source = NULL;
62 const char *ldap_source = NULL;
63
64 static
65 const char *const *cmdline_config = NULL;
66 static bool_t got_config_data = FALSE;
67
68 /* high level parsing functions functions */
69 static int parse_ldap_cmd_line(const char *const *cmdline_options,
70 __nis_ldap_proxy_info *proxy_info, __nis_config_t *nis_config,
71 __nis_table_mapping_t **table_mapping, __nis_config_info_t *config_info,
72 __nisdb_table_mapping_t *table_info);
73 static int parse_ldap_default_conf(__nis_ldap_proxy_info *proxy_info,
74 __nis_config_t *nis_config, __nis_config_info_t *config_info,
75 __nisdb_table_mapping_t *table_info);
76 static int parse_ldap_config_file(const char *config_file,
77 __nis_ldap_proxy_info *proxy_info, __nis_config_t *nis_config,
78 __nis_table_mapping_t **table_mapping, __nis_config_info_t *config_info,
79 __nisdb_table_mapping_t *table_info);
80 static int parse_ldap_config_dn_attrs(__nis_ldap_proxy_info *proxy_info,
81 __nis_config_t *nis_config, __nis_table_mapping_t **table_mapping,
82 __nis_config_info_t *config_info, __nisdb_table_mapping_t *table_info);
83 static int yp_parse_ldap_default_conf(__nis_ldap_proxy_info *proxy_info,
84 __nis_config_t *nis_config, __nis_config_info_t *config_info,
85 __nisdb_table_mapping_t *table_info);
86
87
88 /* helper functions */
89 static config_key get_attrib_num_cmdline(const char *s,
90 const char **begin_s, const char **end_s);
91 static config_key get_file_attr_val(int fd, char **attr_val);
92 static void get_attribute_list(
93 const __nis_ldap_proxy_info *proxy_info,
94 const __nis_config_t *nis_config,
95 const __nis_config_info_t *config_info,
96 const __nisdb_table_mapping_t *table_info,
97 char **ldap_config_attributes);
98
99 /*
100 * FUNCTION: parse_ldap_migration
101 *
102 * Parses the information for LDAP. The values are first
103 * obtained from the command line, secondly from the preference
104 * file, and finally from an LDAP profile (if so configured in
105 * the command line or preference file). Any unset values will
106 * be set to their default values.
107 *
108 * If no command line options, no settings in the /etc/default
109 * configuration file, and no mapping file, then no mapping
110 * should be used.
111 *
112 * RETURN VALUE:
113 * 0 Success
114 * -1 Config file stat/open or parse error
115 * 1 No mapping should be used.
116 *
117 * INPUT: command line parameters, configuration file
118 */
119
120 int
parse_ldap_migration(const char * const * cmdline_options,const char * config_file)121 parse_ldap_migration(
122 const char *const *cmdline_options,
123 const char *config_file)
124 {
125 int rc = 0;
126 __nis_config_info_t config_info
127 = {NULL, NULL, (auth_method_t)NO_VALUE_SET,
128 (tls_method_t)NO_VALUE_SET, NULL,
129 NULL, NULL};
130 struct stat buf;
131 int i = 0;
132
133 p_error = no_parse_error;
134
135 if (verbose)
136 report_info("Getting LDAP configuration", NULL);
137
138 initialize_parse_structs(&proxyInfo, &ldapConfig, &ldapDBTableMapping);
139
140 if (yp2ldap)
141 initialize_yp_parse_structs(&ypDomains);
142
143 if (cmdline_options != NULL) {
144 got_config_data = TRUE;
145 /* NIS to LDAP does not read command line attributes */
146 if (!yp2ldap)
147 rc = parse_ldap_cmd_line(cmdline_options, &proxyInfo,
148 &ldapConfig, &ldapTableMapping, &config_info,
149 &ldapDBTableMapping);
150 else
151 rc = 0;
152 }
153
154 if (rc == 0) {
155 if (yp2ldap)
156 rc = yp_parse_ldap_default_conf(&proxyInfo, &ldapConfig,
157 &config_info, &ldapDBTableMapping);
158 else
159 rc = parse_ldap_default_conf(&proxyInfo, &ldapConfig,
160 &config_info, &ldapDBTableMapping);
161 }
162
163 if (config_file == NULL) {
164 if (yp2ldap) {
165 if (stat(YP_DEFAULT_MAPPING_FILE, &buf) == 0)
166 config_file = YP_DEFAULT_MAPPING_FILE;
167 } else {
168 if (stat(DEFAULT_MAPPING_FILE, &buf) == 0)
169 config_file = DEFAULT_MAPPING_FILE;
170 }
171 }
172
173 if (rc == 0 && config_file != NULL) {
174 got_config_data = TRUE;
175 warn_file = config_file;
176 cmdline_config = cmdline_options;
177 if (yp2ldap)
178 rc = yp_parse_ldap_config_file(config_file, &proxyInfo,
179 &ldapConfig, &ldapTableMapping, &config_info,
180 &ldapDBTableMapping, &ypDomains);
181 else
182 rc = parse_ldap_config_file(config_file, &proxyInfo,
183 &ldapConfig, &ldapTableMapping, &config_info,
184 &ldapDBTableMapping);
185
186 warn_file = NULL;
187 cmdline_config = NULL;
188 }
189 if (rc == 0 && (config_info.config_dn != NULL) &&
190 (config_info.config_dn[0] != '\0')) {
191 rc = parse_ldap_config_dn_attrs(&proxyInfo,
192 &ldapConfig, &ldapTableMapping, &config_info,
193 &ldapDBTableMapping);
194 }
195
196 free_config_info(&config_info);
197
198 if (rc == 0 && got_config_data == FALSE)
199 rc = 1;
200
201 set_default_values(&proxyInfo, &ldapConfig, &ldapDBTableMapping);
202
203 if (yp2ldap == 1 && rc == 0) {
204 rc = second_parser_pass(&ldapTableMapping);
205 if (rc == 0)
206 rc = final_parser_pass(&ldapTableMapping, &ypDomains);
207 if (rc == -2)
208 return (-1);
209 }
210
211 if (rc == 0)
212 rc = finish_parse(&proxyInfo, &ldapTableMapping);
213
214 if (rc == 0)
215 rc = linked2hash(ldapTableMapping);
216
217 if ((rc == 0) && yptol_mode)
218 rc = map_id_list_init();
219
220 if (rc != 0) {
221 free_parse_structs();
222 } else if (verbose)
223 report_info("LDAP configuration complete", NULL);
224 return (rc);
225 }
226
227 /*
228 * FUNCTION: parse_ldap_cmd_line
229 *
230 * Parses the information for LDAP from the command line
231 *
232 * RETURN VALUE: 0 on success, -1 on failure
233 *
234 * INPUT: command line values
235 */
236
237 static int
parse_ldap_cmd_line(const char * const * cmdline_options,__nis_ldap_proxy_info * proxy_info,__nis_config_t * nis_config,__nis_table_mapping_t ** table_mapping,__nis_config_info_t * config_info,__nisdb_table_mapping_t * table_info)238 parse_ldap_cmd_line(
239 const char *const *cmdline_options,
240 __nis_ldap_proxy_info *proxy_info,
241 __nis_config_t *nis_config,
242 __nis_table_mapping_t **table_mapping,
243 __nis_config_info_t *config_info,
244 __nisdb_table_mapping_t *table_info)
245 {
246 int rc = 0;
247 config_key attrib_num;
248 const char *begin_s;
249 const char *end_s;
250
251 if (verbose)
252 report_info("Command line values: ", NULL);
253 while (*cmdline_options != NULL) {
254 if (verbose)
255 report_info("\t", *cmdline_options);
256
257 attrib_num = get_attrib_num_cmdline(
258 *cmdline_options, &begin_s, &end_s);
259 if (attrib_num == key_bad) {
260 command_line_source = "command line";
261 report_error(*cmdline_options, NULL);
262 command_line_source = NULL;
263 rc = -1;
264 break;
265 } else if (IS_CONFIG_KEYWORD(attrib_num)) {
266 rc = add_config_attribute(attrib_num,
267 begin_s, end_s - begin_s, config_info);
268 } else if (IS_BIND_INFO(attrib_num)) {
269 rc = add_bind_attribute(attrib_num,
270 begin_s, end_s - begin_s, proxy_info);
271 } else if (IS_OPER_INFO(attrib_num)) {
272 rc = add_operation_attribute(attrib_num,
273 begin_s, end_s - begin_s, nis_config,
274 table_info);
275 } else {
276 rc = add_mapping_attribute(attrib_num,
277 begin_s, end_s - begin_s, table_mapping);
278 }
279
280 if (rc < 0) {
281 command_line_source = "command line";
282 report_error(begin_s, _key_val);
283 command_line_source = NULL;
284 break;
285 }
286 cmdline_options++;
287 }
288 return (rc);
289 }
290
291 static int
parse_ldap_default_conf(__nis_ldap_proxy_info * proxy_info,__nis_config_t * nis_config,__nis_config_info_t * config_info,__nisdb_table_mapping_t * table_info)292 parse_ldap_default_conf(
293 __nis_ldap_proxy_info *proxy_info,
294 __nis_config_t *nis_config,
295 __nis_config_info_t *config_info,
296 __nisdb_table_mapping_t *table_info)
297 {
298 int rc = 0;
299 char *ldap_config_attributes[n_config_keys];
300 char attr_buf[128];
301 char *attr;
302 char *attr_val;
303 int defflags;
304 config_key attrib_num;
305 int i;
306 int len;
307 int attr_len;
308 void *defp;
309
310 if ((defp = defopen_r(ETCCONFFILE)) != NULL) {
311 file_source = ETCCONFFILE;
312 if (verbose)
313 report_info("default configuration values: ", NULL);
314 /* Set defread_r() to be case insensitive */
315 defflags = defcntl_r(DC_GETFLAGS, 0, defp);
316 TURNOFF(defflags, DC_CASE);
317 (void) defcntl_r(DC_SETFLAGS, defflags, defp);
318
319 get_attribute_list(proxy_info, nis_config, config_info,
320 table_info, ldap_config_attributes);
321 i = 0;
322 while ((attr = ldap_config_attributes[i++]) != NULL) {
323 (void) strlcpy(attr_buf, attr, sizeof (attr_buf));
324 /*
325 * if nisplusUpdateBatching, make sure
326 * we don't match nisplusUpdateBatchingTimeout
327 */
328 if (strcmp(attr, UPDATE_BATCHING) == 0) {
329 attr_len = strlen(attr);
330 attr_buf[attr_len] = '=';
331 attr_buf[attr_len + 1] = '\0';
332 attr_val = defread_r(attr_buf, defp);
333
334 if (attr_val == 0) {
335 attr_buf[attr_len] = ' ';
336 attr_val = defread_r(attr_buf, defp);
337 }
338 if (attr_val == 0) {
339 attr_buf[attr_len] = '\t';
340 attr_val = defread_r(attr_buf, defp);
341 }
342 if (attr_val == 0) {
343 attr_buf[attr_len] = '\n';
344 attr_val = defread_r(attr_buf, defp);
345 }
346 } else {
347 attr_val = defread_r(attr_buf, defp);
348 }
349 if (attr_val == NULL)
350 continue;
351
352 got_config_data = TRUE;
353 attrib_num = get_attrib_num(attr, strlen(attr));
354 if (attrib_num == key_bad) {
355 report_error(attr, NULL);
356 rc = -1;
357 break;
358 }
359
360 /*
361 * Allow either entries of the form
362 * attr val
363 * or
364 * attr = val
365 */
366 while (is_whitespace(*attr_val))
367 attr_val++;
368 if (*attr_val == '=')
369 attr_val++;
370 while (is_whitespace(*attr_val))
371 attr_val++;
372 len = strlen(attr_val);
373 while (len > 0 && is_whitespace(attr_val[len - 1]))
374 len--;
375
376 if (verbose) {
377 report_info("\t", attr);
378 report_info("\t\t", attr_val);
379 }
380 if (IS_BIND_INFO(attrib_num)) {
381 rc = add_bind_attribute(attrib_num,
382 attr_val, len, proxy_info);
383 } else if (IS_OPER_INFO(attrib_num)) {
384 rc = add_operation_attribute(attrib_num,
385 attr_val, len, nis_config,
386 table_info);
387 }
388 if (p_error != no_parse_error) {
389 report_error(attr_val, attr);
390 rc = -1;
391 break;
392 }
393 }
394 file_source = NULL;
395 /* Close the /etc/default file */
396 defclose_r(defp);
397 }
398 return (rc);
399 }
400
401 static int
yp_parse_ldap_default_conf(__nis_ldap_proxy_info * proxy_info,__nis_config_t * nis_config,__nis_config_info_t * config_info,__nisdb_table_mapping_t * table_info)402 yp_parse_ldap_default_conf(
403 __nis_ldap_proxy_info *proxy_info,
404 __nis_config_t *nis_config,
405 __nis_config_info_t *config_info,
406 __nisdb_table_mapping_t *table_info)
407 {
408 int rc = 0;
409 char *ldap_config_attributes[n_config_keys];
410 char attr_buf[128];
411 char *attr;
412 char *attr_val;
413 int defflags;
414 config_key attrib_num;
415 int i, len, attr_len;
416 void *defp;
417
418 if ((defp = defopen_r(YP_ETCCONFFILE)) != NULL) {
419 file_source = YP_ETCCONFFILE;
420 if (verbose)
421 report_info("default configuration values: ", NULL);
422 /* Set defread_r() to be case insensitive */
423 defflags = defcntl_r(DC_GETFLAGS, 0, defp);
424 TURNOFF(defflags, DC_CASE);
425 (void) defcntl_r(DC_SETFLAGS, defflags, defp);
426
427 get_attribute_list(proxy_info, nis_config, config_info,
428 table_info, ldap_config_attributes);
429 i = 0;
430 while ((attr = ldap_config_attributes[i++]) != NULL) {
431 if ((strlcpy(attr_buf, attr, sizeof (attr_buf))) >=
432 sizeof (attr_buf)) {
433 report_error(
434 "Static buffer attr_buf overflow", NULL);
435 defclose_r(defp);
436 return (-1);
437 }
438
439 if ((attr_val = defread_r(attr_buf, defp)) == NULL)
440 continue;
441
442 got_config_data = TRUE;
443 attrib_num = get_attrib_num(attr, strlen(attr));
444 if (attrib_num == key_bad) {
445 report_error(attr, NULL);
446 rc = -1;
447 break;
448 }
449
450 /*
451 * Allow either entries of the form
452 * attr val
453 * or
454 * attr = val
455 */
456 while (is_whitespace(*attr_val))
457 attr_val++;
458 if (*attr_val == '=')
459 attr_val++;
460 while (is_whitespace(*attr_val))
461 attr_val++;
462 len = strlen(attr_val);
463 while (len > 0 && is_whitespace(attr_val[len - 1]))
464 len--;
465
466 if (verbose) {
467 report_info("\t", attr);
468 report_info("\t\t", attr_val);
469 }
470 if (IS_YP_BIND_INFO(attrib_num)) {
471 rc = add_bind_attribute(attrib_num,
472 attr_val, len, proxy_info);
473 } else if (IS_YP_OPER_INFO(attrib_num)) {
474 rc = add_operation_attribute(attrib_num,
475 attr_val, len, nis_config,
476 table_info);
477 }
478 if (p_error != no_parse_error) {
479 report_error(attr_val, attr);
480 rc = -1;
481 break;
482 }
483 }
484 file_source = NULL;
485 /* Close the /etc/default file */
486 defclose_r(defp);
487 }
488 return (rc);
489 }
490
491 /*
492 * FUNCTION: get_attrib_num_cmdline
493 *
494 * Parses the information for LDAP from the command line
495 * The form of the command line request is
496 * -x attribute=value
497 *
498 * RETURN VALUE: 0 on success, -1 on failure
499 *
500 * INPUT: command line values
501 */
502
503 static config_key
get_attrib_num_cmdline(const char * s,const char ** begin_s,const char ** end_s)504 get_attrib_num_cmdline(
505 const char *s,
506 const char **begin_s,
507 const char **end_s)
508 {
509 const char *s_end = s + strlen(s);
510 const char *equal_s;
511 const char *s1;
512 config_key attrib_num;
513
514 while (s < s_end && is_whitespace(*s))
515 s++;
516
517 for (equal_s = s; equal_s < s_end; equal_s++)
518 if (*equal_s == EQUAL_CHAR)
519 break;
520
521 if (equal_s == s_end) {
522 p_error = parse_bad_command_line_attribute_format;
523 return (key_bad);
524 }
525
526 for (s1 = equal_s; s1 > s && is_whitespace(s1[-1]); s1--)
527 ;
528
529 if (s1 == s) {
530 p_error = parse_bad_command_line_attribute_format;
531 return (key_bad);
532 }
533
534 attrib_num = get_attrib_num(s, s1 - s);
535
536 if (attrib_num != key_bad) {
537 s1 = equal_s + 1;
538 while (s1 < s_end && is_whitespace(*s1))
539 s1++;
540 *begin_s = s1;
541 while (s_end > s1 && is_whitespace(s_end[-1]))
542 s_end--;
543 *end_s = s_end;
544 }
545
546 return (attrib_num);
547 }
548
549 /*
550 * FUNCTION: parse_ldap_config_file
551 *
552 * Parses the information for LDAP from a configuration
553 * file. If no file is specified, /var/nis/NIS+LDAPmapping
554 * is used
555 *
556 * RETURN VALUE: 0 on success, -1 on failure
557 *
558 * INPUT: configuration file name
559 */
560
561 static int
parse_ldap_config_file(const char * config_file,__nis_ldap_proxy_info * proxy_info,__nis_config_t * nis_config,__nis_table_mapping_t ** table_mapping,__nis_config_info_t * config_info,__nisdb_table_mapping_t * table_info)562 parse_ldap_config_file(
563 const char *config_file,
564 __nis_ldap_proxy_info *proxy_info,
565 __nis_config_t *nis_config,
566 __nis_table_mapping_t **table_mapping,
567 __nis_config_info_t *config_info,
568 __nisdb_table_mapping_t *table_info)
569 {
570 int rc = 0;
571 config_key attrib_num;
572 int fd;
573 char *attr_val;
574 int len;
575
576 if ((fd = open(config_file, O_RDONLY)) == -1) {
577 p_error = parse_open_file_error;
578 report_error(config_file, NULL);
579 return (-1);
580 }
581
582 start_line_num = 1;
583 cur_line_num = 1;
584
585 if (verbose)
586 report_info("Reading configuration from ", config_file);
587
588 file_source = config_file;
589 while ((attrib_num = get_file_attr_val(fd, &attr_val)) > 0) {
590 len = attr_val == NULL ? 0 : strlen(attr_val);
591 if (IS_CONFIG_KEYWORD(attrib_num)) {
592 rc = add_config_attribute(attrib_num,
593 attr_val, len, config_info);
594 } else if (IS_BIND_INFO(attrib_num)) {
595 rc = add_bind_attribute(attrib_num,
596 attr_val, len, proxy_info);
597 } else if (IS_OPER_INFO(attrib_num)) {
598 rc = add_operation_attribute(attrib_num,
599 attr_val, len, nis_config, table_info);
600 } else {
601 rc = add_mapping_attribute(attrib_num,
602 attr_val, len, table_mapping);
603 }
604
605 if (rc < 0) {
606 report_error(attr_val == NULL ?
607 "<no attribute>" : attr_val, _key_val);
608 if (attr_val)
609 free(attr_val);
610 break;
611 }
612 if (attr_val)
613 free(attr_val);
614 }
615
616 (void) close(fd);
617 if (attrib_num == key_bad) {
618 report_error(_key_val, NULL);
619 rc = -1;
620 }
621 start_line_num = 0;
622 file_source = NULL;
623 return (rc);
624 }
625
626 /*
627 * FUNCTION: yp_parse_ldap_config_file
628 *
629 * Parses the information for LDAP from a configuration
630 * file. If no file is specified, /var/yp/NISLDAPmapping
631 * is used
632 *
633 * RETURN VALUE: 0 on success, -1 on failure
634 *
635 * INPUT: configuration file name
636 */
637
638 int
yp_parse_ldap_config_file(const char * config_file,__nis_ldap_proxy_info * proxy_info,__nis_config_t * nis_config,__nis_table_mapping_t ** table_mapping,__nis_config_info_t * config_info,__nisdb_table_mapping_t * table_info,__yp_domain_context_t * ypDomains)639 yp_parse_ldap_config_file(
640 const char *config_file,
641 __nis_ldap_proxy_info *proxy_info,
642 __nis_config_t *nis_config,
643 __nis_table_mapping_t **table_mapping,
644 __nis_config_info_t *config_info,
645 __nisdb_table_mapping_t *table_info,
646 __yp_domain_context_t *ypDomains)
647 {
648 int rc = 0;
649 int numDomains = 0;
650 config_key attrib_num;
651 int fd;
652 char *attr_val = NULL;
653 int len;
654
655 if ((fd = open(config_file, O_RDONLY)) == -1) {
656 p_error = parse_open_file_error;
657 report_error(config_file, NULL);
658 return (-1);
659 }
660
661 start_line_num = 1;
662 cur_line_num = 1;
663
664 if (verbose)
665 report_info("Reading configuration from ", config_file);
666
667 file_source = config_file;
668 while ((attrib_num = get_file_attr_val(fd, &attr_val)) > 0) {
669 len = attr_val == NULL ? 0 : strlen(attr_val);
670 if (IS_YP_CONFIG_KEYWORD(attrib_num)) {
671 rc = add_config_attribute(attrib_num,
672 attr_val, len, config_info);
673 } else if (IS_YP_BIND_INFO(attrib_num)) {
674 rc = add_bind_attribute(attrib_num,
675 attr_val, len, proxy_info);
676 } else if (IS_YP_OPER_INFO(attrib_num)) {
677 rc = add_operation_attribute(attrib_num,
678 attr_val, len, nis_config, table_info);
679 } else if (IS_YP_DOMAIN_INFO(attrib_num)) {
680 rc = add_ypdomains_attribute(attrib_num,
681 attr_val, len, ypDomains);
682 } else if (IS_YP_MAP_ATTR(attrib_num)) {
683 rc = add_mapping_attribute(attrib_num,
684 attr_val, len, table_mapping);
685 } else {
686 rc = -1;
687 p_error = parse_unsupported_format;
688 }
689
690 if (rc < 0) {
691 report_error(attr_val == NULL ?
692 "<no attribute>" : attr_val, _key_val);
693 if (attr_val)
694 free(attr_val);
695 break;
696 }
697 if (attr_val) {
698 free(attr_val);
699 attr_val = NULL;
700 }
701 }
702
703 (void) close(fd);
704 if (attrib_num == key_bad) {
705 report_error(_key_val, NULL);
706 rc = -1;
707 }
708 start_line_num = 0;
709 file_source = NULL;
710 return (rc);
711 }
712
713 /*
714 * FUNCTION: get_file_attr_val
715 *
716 * Gets the next attribute from the configuration file.
717 *
718 * RETURN VALUE: The config key if more attributes
719 * no_more_keys if eof
720 * key_bad if error
721 */
722
723 static config_key
get_file_attr_val(int fd,char ** attr_val)724 get_file_attr_val(int fd, char **attr_val)
725 {
726 char buf[BUFSIZE];
727 char *start_tag;
728 char *start_val;
729 char *end_val;
730 char *cut_here;
731 char *s;
732 char *a;
733 char *attribute_value;
734 int ret;
735 config_key attrib_num = no_more_keys;
736 int found_quote = 0;
737
738 *attr_val = NULL;
739
740 if ((ret = read_line(fd, buf, sizeof (buf))) > 0) {
741 for (s = buf; is_whitespace(*s); s++)
742 ;
743
744 start_tag = s;
745 while (*s != '\0' && !is_whitespace(*s))
746 s++;
747
748 if (verbose)
749 report_info("\t", start_tag);
750 attrib_num = get_attrib_num(start_tag, s - start_tag);
751 if (attrib_num == key_bad)
752 return (key_bad);
753
754 while (is_whitespace(*s))
755 s++;
756 if (*s == '\0')
757 return (attrib_num);
758 start_val = s;
759
760 /* note that read_line will not return a line ending with \ */
761 for (; *s != '\0'; s++) {
762 if (*s == ESCAPE_CHAR)
763 s++;
764 }
765 while (s > start_val && is_whitespace(s[-1]))
766 s--;
767
768 attribute_value =
769 calloc(1, (size_t)(s - start_val) + 1);
770 if (attribute_value == NULL) {
771 p_error = parse_no_mem_error;
772 return (key_bad);
773 }
774 attr_val[0] = attribute_value;
775
776 a = *attr_val;
777 end_val = s;
778 cut_here = 0;
779 for (s = start_val; s < end_val; s++) {
780 if (*s == POUND_SIGN) {
781 cut_here = s;
782 while (s < end_val) {
783 if (*s == DOUBLE_QUOTE_CHAR ||
784 *s == SINGLE_QUOTE_CHAR) {
785 cut_here = 0;
786 break;
787 }
788 s++;
789 }
790 }
791 }
792 if (cut_here != 0)
793 end_val = cut_here;
794
795 for (s = start_val; s < end_val; s++)
796 *a++ = *s;
797 *a++ = '\0';
798 }
799 if (ret == -1)
800 return (key_bad);
801
802 return (attrib_num);
803 }
804
805 static LDAP *
connect_to_ldap_config_server(char * sever_name,int server_port,__nis_config_info_t * config_info)806 connect_to_ldap_config_server(
807 char *sever_name,
808 int server_port,
809 __nis_config_info_t *config_info)
810 {
811 int rc = 0;
812 LDAP *ld = NULL;
813 int ldapVersion = LDAP_VERSION3;
814 int derefOption = LDAP_DEREF_ALWAYS;
815 int timelimit = LDAP_NO_LIMIT;
816 int sizelimit = LDAP_NO_LIMIT;
817 int errnum;
818 bool_t retrying = FALSE;
819 int sleep_seconds = 1;
820 struct berval cred;
821
822 if (config_info->tls_method == no_tls) {
823 ld = ldap_init(sever_name, server_port);
824 if (ld == NULL) {
825 p_error = parse_ldap_init_error;
826 report_error(strerror(errno), NULL);
827 return (NULL);
828 }
829 } else {
830 if ((errnum = ldapssl_client_init(
831 config_info->tls_cert_db, NULL)) < 0) {
832 p_error = parse_ldapssl_client_init_error;
833 report_error(ldapssl_err2string(errnum), NULL);
834 return (NULL);
835 }
836 ld = ldapssl_init(sever_name, server_port, 1);
837 if (ld == NULL) {
838 p_error = parse_ldapssl_init_error;
839 report_error(strerror(errno), NULL);
840 return (NULL);
841 }
842 }
843
844 (void) ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION,
845 &ldapVersion);
846 (void) ldap_set_option(ld, LDAP_OPT_DEREF, &derefOption);
847 (void) ldap_set_option(ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF);
848 (void) ldap_set_option(ld, LDAP_OPT_TIMELIMIT, &timelimit);
849 (void) ldap_set_option(ld, LDAP_OPT_SIZELIMIT, &sizelimit);
850
851 /*
852 * Attempt to bind to the LDAP server.
853 * We will loop until success or until an error other
854 * than LDAP_CONNECT_ERROR or LDAP_SERVER_DOWN
855 */
856 if (verbose)
857 report_info("Connecting to ", sever_name);
858
859 for (;;) {
860 if (config_info->auth_method == simple) {
861 errnum = ldap_simple_bind_s(ld, config_info->proxy_dn,
862 config_info->proxy_passwd);
863 } else if (config_info->auth_method == cram_md5) {
864 cred.bv_len = strlen(config_info->proxy_passwd);
865 cred.bv_val = config_info->proxy_passwd;
866 errnum = ldap_sasl_cram_md5_bind_s(ld,
867 config_info->proxy_dn, &cred, NULL, NULL);
868 } else if (config_info->auth_method == digest_md5) {
869 cred.bv_len = strlen(config_info->proxy_passwd);
870 cred.bv_val = config_info->proxy_passwd;
871 errnum = ldap_x_sasl_digest_md5_bind_s(ld,
872 config_info->proxy_dn, &cred, NULL, NULL);
873 } else {
874 errnum = ldap_simple_bind_s(ld, NULL, NULL);
875 }
876
877 if (errnum == LDAP_SUCCESS)
878 break;
879
880 if (errnum == LDAP_CONNECT_ERROR ||
881 errnum == LDAP_SERVER_DOWN) {
882 if (!retrying) {
883 if (verbose)
884 report_info(
885 "LDAP server unavailable. Retrying...",
886 NULL);
887 retrying = TRUE;
888 }
889 (void) sleep(sleep_seconds);
890 sleep_seconds *= 2;
891 if (sleep_seconds > MAX_LDAP_CONFIG_RETRY_TIME)
892 sleep_seconds = MAX_LDAP_CONFIG_RETRY_TIME;
893 p_error = no_parse_error;
894 continue;
895 }
896 p_error = parse_ldap_bind_error;
897 report_error2(config_info->proxy_dn, ldap_err2string(errnum));
898 (void) ldap_unbind(ld);
899 return (NULL);
900 }
901
902 if (verbose)
903 report_info("Reading values from ", config_info->config_dn);
904
905 return (ld);
906 }
907
908 /*
909 * FUNCTION: process_ldap_config_result
910 *
911 * Extracts the LDAPMessage containing the nis+/LDAP
912 * configuration
913 *
914 * RETURN VALUE: 0 on success, -1 on failure
915 *
916 * INPUT: LDAP the LDAP connection
917 * LDAPMessage the LDAP message
918 */
919
920 static int
process_ldap_config_result(LDAP * ld,LDAPMessage * resultMsg,__nis_ldap_proxy_info * proxy_info,__nis_config_t * nis_config,__nis_table_mapping_t ** table_mapping,__nisdb_table_mapping_t * table_info)921 process_ldap_config_result(
922 LDAP *ld,
923 LDAPMessage *resultMsg,
924 __nis_ldap_proxy_info *proxy_info,
925 __nis_config_t *nis_config,
926 __nis_table_mapping_t **table_mapping,
927 __nisdb_table_mapping_t *table_info)
928 {
929 LDAPMessage *e;
930 int errnum;
931 char *attr;
932 BerElement *ber = NULL;
933 config_key attrib_num;
934 char **vals;
935 int n;
936 int i;
937 char *attr_val;
938 int len;
939 int rc = 0;
940 bool_t error_reported = FALSE;
941
942 e = ldap_first_entry(ld, resultMsg);
943
944 if (e != NULL) {
945 for (attr = ldap_first_attribute(ld, e, &ber); attr != NULL;
946 attr = ldap_next_attribute(ld, e, ber)) {
947 if (verbose)
948 report_info("\t", attr);
949 attrib_num = get_attrib_num(attr, strlen(attr));
950 if (attrib_num == key_bad) {
951 report_error(attr, NULL);
952 break;
953 }
954 if ((vals = ldap_get_values(ld, e, attr)) != NULL) {
955 n = ldap_count_values(vals);
956 /* parse the attribute values */
957 for (i = 0; i < n; i++) {
958 attr_val = vals[i];
959 while (is_whitespace(*attr_val))
960 attr_val++;
961 if (verbose)
962 report_info("\t\t", attr_val);
963 len = strlen(attr_val);
964 while (len > 0 &&
965 is_whitespace(attr_val[len - 1]))
966 len--;
967 if (yp2ldap) {
968 if (IS_YP_BIND_INFO(attrib_num)) {
969 rc = add_bind_attribute(attrib_num, attr_val,
970 len, proxy_info);
971 } else if (IS_YP_OPER_INFO(attrib_num)) {
972 rc = add_operation_attribute(attrib_num,
973 attr_val, len, nis_config, table_info);
974 } else if (IS_YP_MAP_ATTR(attrib_num)) {
975 rc = add_mapping_attribute(attrib_num, attr_val,
976 len, table_mapping);
977 } else {
978 p_error = parse_unsupported_format;
979 }
980 } else {
981 if (IS_BIND_INFO(attrib_num)) {
982 rc = add_bind_attribute(attrib_num, attr_val,
983 len, proxy_info);
984 } else if (IS_OPER_INFO(attrib_num)) {
985 rc = add_operation_attribute(attrib_num,
986 attr_val, len, nis_config, table_info);
987 } else {
988 rc = add_mapping_attribute(attrib_num, attr_val,
989 len, table_mapping);
990 }
991 }
992 if (p_error != no_parse_error) {
993 report_error(attr_val, attr);
994 error_reported = TRUE;
995 break;
996 }
997 }
998 ldap_value_free(vals);
999 } else {
1000 (void) ldap_get_option(ld,
1001 LDAP_OPT_ERROR_NUMBER, &errnum);
1002 if (errnum != LDAP_SUCCESS)
1003 p_error = parse_ldap_get_values_error;
1004 }
1005 ldap_memfree(attr);
1006 if (p_error != no_parse_error)
1007 break;
1008 }
1009 } else {
1010 errnum = ldap_result2error(ld, resultMsg, FALSE);
1011 if (errnum != LDAP_SUCCESS)
1012 p_error = parse_ldap_search_error;
1013 }
1014 if (ber != NULL)
1015 ber_free(ber, 0);
1016
1017 if (!error_reported && p_error != no_parse_error) {
1018 report_error(ldap_err2string(errnum), 0);
1019 }
1020
1021 if (p_error != no_parse_error)
1022 rc = -1;
1023 return (rc);
1024 }
1025
1026 /*
1027 * FUNCTION: process_ldap_referral
1028 *
1029 * Retrieves the configuration for a referral url
1030 *
1031 * RETURN VALUE: 0 on success, -1 on failure, 1 on skip
1032 *
1033 * INPUT: url the ldap url
1034 * __nis_ldap_proxy_info
1035 */
1036
1037 static int
process_ldap_referral(char * url,char ** attrs,__nis_ldap_proxy_info * proxy_info,__nis_config_t * nis_config,__nis_table_mapping_t ** table_mapping,__nis_config_info_t * config_info,__nisdb_table_mapping_t * table_info)1038 process_ldap_referral(
1039 char *url,
1040 char **attrs,
1041 __nis_ldap_proxy_info *proxy_info,
1042 __nis_config_t *nis_config,
1043 __nis_table_mapping_t **table_mapping,
1044 __nis_config_info_t *config_info,
1045 __nisdb_table_mapping_t *table_info)
1046 {
1047 LDAPURLDesc *ludpp = NULL;
1048 int rc;
1049 LDAP *ld = NULL;
1050 int errnum;
1051 LDAPMessage *resultMsg = NULL;
1052
1053 if ((rc = ldap_url_parse(url, &ludpp)) != LDAP_SUCCESS)
1054 return (1);
1055
1056 #ifdef LDAP_URL_OPT_SECURE
1057 if (ludpp->lud_options & LDAP_URL_OPT_SECURE) {
1058 if (config_info->tls_method != ssl_tls) {
1059 ldap_free_urldesc(ludpp);
1060 return (1);
1061 }
1062 } else {
1063 if (config_info->tls_method != no_tls) {
1064 ldap_free_urldesc(ludpp);
1065 return (1);
1066 }
1067 }
1068 #endif
1069
1070 if ((ld = connect_to_ldap_config_server(ludpp->lud_host,
1071 ludpp->lud_port, config_info)) == NULL) {
1072 ldap_free_urldesc(ludpp);
1073 return (-1);
1074 }
1075
1076 errnum = ldap_search_s(ld, config_info->config_dn, LDAP_SCOPE_BASE,
1077 "objectclass=nisplusLDAPconfig", attrs, 0, &resultMsg);
1078
1079 ldap_source = config_info->config_dn;
1080
1081 if (errnum != LDAP_SUCCESS) {
1082 p_error = parse_ldap_search_error;
1083 report_error(ldap_err2string(errnum), 0);
1084 rc = -1;
1085 } else {
1086 rc = process_ldap_config_result(ld, resultMsg, proxy_info,
1087 nis_config, table_mapping, table_info);
1088 }
1089
1090 ldap_source = NULL;
1091 (void) ldap_unbind(ld);
1092 if (resultMsg != NULL)
1093 (void) ldap_msgfree(resultMsg);
1094
1095 return (rc);
1096 }
1097
1098 /*
1099 * FUNCTION: process_ldap_referral_msg
1100 *
1101 * Retrieves the configuration from referred servers
1102 *
1103 * RETURN VALUE: 0 on success, -1 on failure
1104 *
1105 * INPUT: LDAP the LDAP connection
1106 * LDAPMessage the LDAP message
1107 * __nis_ldap_proxy_info
1108 */
1109
1110 static int
process_ldap_referral_msg(LDAP * ld,LDAPMessage * resultMsg,char ** attrs,__nis_ldap_proxy_info * proxy_info,__nis_config_t * nis_config,__nis_table_mapping_t ** table_mapping,__nis_config_info_t * config_info,__nisdb_table_mapping_t * table_info)1111 process_ldap_referral_msg(
1112 LDAP *ld,
1113 LDAPMessage *resultMsg,
1114 char **attrs,
1115 __nis_ldap_proxy_info *proxy_info,
1116 __nis_config_t *nis_config,
1117 __nis_table_mapping_t **table_mapping,
1118 __nis_config_info_t *config_info,
1119 __nisdb_table_mapping_t *table_info)
1120 {
1121 int errCode;
1122 char **referralsp = NULL;
1123 int i;
1124 int rc;
1125
1126 rc = ldap_parse_result(ld, resultMsg, &errCode, NULL, NULL, &referralsp,
1127 NULL, 0);
1128
1129 if (rc != LDAP_SUCCESS || errCode != LDAP_REFERRAL) {
1130 p_error = parse_ldap_get_values_error;
1131 report_error(ldap_err2string(errCode), 0);
1132 rc = -1;
1133 } else {
1134 for (i = 0; referralsp[i] != NULL; i++) {
1135 rc = process_ldap_referral(referralsp[i], attrs,
1136 proxy_info, nis_config, table_mapping,
1137 config_info, table_info);
1138 if (rc <= 0)
1139 break;
1140 else
1141 report_info("Cannot use referral \n",
1142 referralsp[i]);
1143
1144 }
1145 if (rc > 0) {
1146 p_error = parse_no_available_referrals_error;
1147 report_error(0, 0);
1148 }
1149 }
1150
1151 if (referralsp)
1152 ldap_value_free(referralsp);
1153
1154 return (rc);
1155 }
1156
1157 /*
1158 * FUNCTION: parse_ldap_config_dn_attrs
1159 *
1160 * Parses the information for LDAP from the LDAP profile
1161 * - the profile object name, the LDAP server, and the
1162 * authentication method must be specified.
1163 *
1164 * RETURN VALUE: 0 on success, -1 on failure
1165 *
1166 * INPUT: __nis_ldap_proxy_info
1167 */
1168
1169 static int
parse_ldap_config_dn_attrs(__nis_ldap_proxy_info * proxy_info,__nis_config_t * nis_config,__nis_table_mapping_t ** table_mapping,__nis_config_info_t * config_info,__nisdb_table_mapping_t * table_info)1170 parse_ldap_config_dn_attrs(
1171 __nis_ldap_proxy_info *proxy_info,
1172 __nis_config_t *nis_config,
1173 __nis_table_mapping_t **table_mapping,
1174 __nis_config_info_t *config_info,
1175 __nisdb_table_mapping_t *table_info)
1176 {
1177 int rc = 0;
1178 LDAP *ld = NULL;
1179 int errnum;
1180 char *ldap_config_attributes[n_config_keys];
1181 LDAPMessage *resultMsg = NULL;
1182
1183 /* Determine if properly configured for LDAP lookup */
1184 if (config_info->auth_method == simple &&
1185 config_info->proxy_dn == NULL)
1186 p_error = parse_no_proxy_dn_error;
1187 else if (config_info->auth_method ==
1188 (auth_method_t)NO_VALUE_SET)
1189 p_error = parse_no_config_auth_error;
1190 else if ((config_info->default_servers == NULL) ||
1191 (config_info->default_servers[0] == '\0'))
1192 p_error = parse_no_config_server_addr;
1193 if (p_error != no_parse_error) {
1194 report_error(NULL, NULL);
1195 return (-1);
1196 }
1197
1198 if (config_info->tls_method == (tls_method_t)NO_VALUE_SET)
1199 config_info->tls_method = no_tls;
1200 else if (config_info->tls_method == ssl_tls &&
1201 (config_info->tls_cert_db == NULL ||
1202 *config_info->tls_cert_db == '\0')) {
1203 p_error = parse_no_config_cert_db;
1204 report_error(NULL, NULL);
1205 return (-1);
1206 }
1207
1208 if (verbose)
1209 report_info(
1210 "Getting configuration from LDAP server(s): ",
1211 config_info->default_servers);
1212
1213 /* Determine which attributes should be retrieved */
1214 get_attribute_list(proxy_info, nis_config, NULL, table_info,
1215 ldap_config_attributes);
1216
1217 if ((ld = connect_to_ldap_config_server(config_info->default_servers, 0,
1218 config_info)) == NULL)
1219 return (-1);
1220
1221 /* Get the attribute values */
1222 errnum = ldap_search_s(ld, config_info->config_dn, LDAP_SCOPE_BASE,
1223 "objectclass=nisplusLDAPconfig",
1224 ldap_config_attributes, 0, &resultMsg);
1225 ldap_source = config_info->config_dn;
1226
1227 if (errnum == LDAP_REFERRAL) {
1228 rc = process_ldap_referral_msg(ld, resultMsg,
1229 ldap_config_attributes, proxy_info, nis_config,
1230 table_mapping, config_info, table_info);
1231 } else if (errnum != LDAP_SUCCESS) {
1232 p_error = parse_ldap_search_error;
1233 report_error(ldap_err2string(errnum), 0);
1234 rc = -1;
1235 } else {
1236 rc = process_ldap_config_result(ld, resultMsg, proxy_info,
1237 nis_config, table_mapping, table_info);
1238 }
1239
1240 ldap_source = NULL;
1241 (void) ldap_unbind(ld);
1242 if (resultMsg != NULL)
1243 (void) ldap_msgfree(resultMsg);
1244
1245 return (rc);
1246 }
1247
1248 bool_t
is_cmd_line_option(config_key a_num)1249 is_cmd_line_option(config_key a_num)
1250 {
1251 const char *const *cmdline_options = cmdline_config;
1252 config_key attrib_num;
1253 const char *begin_s;
1254 const char *end_s;
1255
1256 if (cmdline_options == NULL)
1257 return (FALSE);
1258
1259 while (*cmdline_options != NULL) {
1260 attrib_num = get_attrib_num_cmdline(
1261 *cmdline_options, &begin_s, &end_s);
1262 if (attrib_num == a_num)
1263 break;
1264 cmdline_options++;
1265 }
1266 return (*cmdline_options != NULL);
1267 }
1268
1269 /*
1270 * FUNCTION: get_attribute_list
1271 *
1272 * Get a list of attributes from the LDAP server that have not yet
1273 * been gotten. If config_info is NULL, the associated parameters
1274 * are not needed.
1275 *
1276 * RETURN VALUE: none
1277 *
1278 * INPUT: Returns a list of parameters in attributes
1279 * which is assumed to be of sufficient size.
1280 */
1281
1282 static void
get_attribute_list(const __nis_ldap_proxy_info * proxy_info,const __nis_config_t * nis_config,const __nis_config_info_t * config_info,const __nisdb_table_mapping_t * table_info,char ** attributes)1283 get_attribute_list(
1284 const __nis_ldap_proxy_info *proxy_info,
1285 const __nis_config_t *nis_config,
1286 const __nis_config_info_t *config_info,
1287 const __nisdb_table_mapping_t *table_info,
1288 char **attributes)
1289 {
1290 int n_attrs;
1291
1292 /* Determine which attributes should be retrieved */
1293 n_attrs = 0;
1294
1295 if (config_info != NULL) {
1296 if (yp2ldap) {
1297 if (config_info->config_dn == NULL)
1298 attributes[n_attrs++] = YP_CONFIG_DN;
1299 if (config_info->default_servers == NULL)
1300 attributes[n_attrs++] = YP_CONFIG_SERVER_LIST;
1301 if (config_info->auth_method ==
1302 (auth_method_t)NO_VALUE_SET)
1303 attributes[n_attrs++] = YP_CONFIG_AUTH_METHOD;
1304 if (config_info->tls_method ==
1305 (tls_method_t)NO_VALUE_SET)
1306 attributes[n_attrs++] = YP_CONFIG_TLS_OPTION;
1307 if (config_info->proxy_dn == NULL)
1308 attributes[n_attrs++] = YP_CONFIG_PROXY_USER;
1309 if (config_info->proxy_passwd == NULL)
1310 attributes[n_attrs++] = YP_CONFIG_PROXY_PASSWD;
1311 if (config_info->tls_cert_db == NULL)
1312 attributes[n_attrs++] = YP_CONFIG_TLS_CERT_DB;
1313 } else {
1314 if (config_info->config_dn == NULL)
1315 attributes[n_attrs++] = CONFIG_DN;
1316 if (config_info->default_servers == NULL)
1317 attributes[n_attrs++] = CONFIG_SERVER_LIST;
1318 if (config_info->auth_method ==
1319 (auth_method_t)NO_VALUE_SET)
1320 attributes[n_attrs++] = CONFIG_AUTH_METHOD;
1321 if (config_info->tls_method ==
1322 (tls_method_t)NO_VALUE_SET)
1323 attributes[n_attrs++] = CONFIG_TLS_OPTION;
1324 if (config_info->proxy_dn == NULL)
1325 attributes[n_attrs++] = CONFIG_PROXY_USER;
1326 if (config_info->proxy_passwd == NULL)
1327 attributes[n_attrs++] = CONFIG_PROXY_PASSWD;
1328 if (config_info->tls_cert_db == NULL)
1329 attributes[n_attrs++] = CONFIG_TLS_CERT_DB;
1330 }
1331 } else {
1332 if (yp2ldap) {
1333 attributes[n_attrs++] = YP_DOMAIN_CONTEXT;
1334 attributes[n_attrs++] = YPPASSWDD_DOMAINS;
1335 attributes[n_attrs++] = YP_DB_ID_MAP;
1336 attributes[n_attrs++] = YP_COMMENT_CHAR;
1337 attributes[n_attrs++] = YP_MAP_FLAGS;
1338 attributes[n_attrs++] = YP_ENTRY_TTL;
1339 attributes[n_attrs++] = YP_NAME_FIELDS;
1340 attributes[n_attrs++] = YP_SPLIT_FIELD;
1341 attributes[n_attrs++] = YP_REPEATED_FIELD_SEPARATORS;
1342 attributes[n_attrs++] = YP_LDAP_OBJECT_DN;
1343 attributes[n_attrs++] = NIS_TO_LDAP_MAP;
1344 attributes[n_attrs++] = LDAP_TO_NIS_MAP;
1345 } else {
1346 attributes[n_attrs++] = DB_ID_MAP;
1347 attributes[n_attrs++] = ENTRY_TTL;
1348 attributes[n_attrs++] = LDAP_OBJECT_DN;
1349 attributes[n_attrs++] = NISPLUS_TO_LDAP_MAP;
1350 attributes[n_attrs++] = LDAP_TO_NISPLUS_MAP;
1351 }
1352 }
1353
1354 if (yp2ldap) {
1355 if (proxy_info->default_servers == NULL)
1356 attributes[n_attrs++] = PREFERRED_SERVERS;
1357 if (proxy_info->auth_method == (auth_method_t)NO_VALUE_SET)
1358 attributes[n_attrs++] = AUTH_METHOD;
1359 if (proxy_info->tls_method == (tls_method_t)NO_VALUE_SET)
1360 attributes[n_attrs++] = YP_TLS_OPTION;
1361 if (proxy_info->tls_cert_db == NULL)
1362 attributes[n_attrs++] = YP_TLS_CERT_DB;
1363 if (proxy_info->default_search_base == NULL)
1364 attributes[n_attrs++] = SEARCH_BASE;
1365 if (proxy_info->proxy_dn == NULL)
1366 attributes[n_attrs++] = YP_PROXY_USER;
1367 if (proxy_info->proxy_passwd == NULL)
1368 attributes[n_attrs++] = YP_PROXY_PASSWD;
1369 if (proxy_info->default_nis_domain == NULL)
1370 attributes[n_attrs++] = YP_LDAP_BASE_DOMAIN;
1371 if (proxy_info->bind_timeout.tv_sec ==
1372 (time_t)NO_VALUE_SET)
1373 attributes[n_attrs++] = YP_BIND_TIMEOUT;
1374 if (proxy_info->search_timeout.tv_sec ==
1375 (time_t)NO_VALUE_SET)
1376 attributes[n_attrs++] = YP_SEARCH_TIMEOUT;
1377 if (proxy_info->modify_timeout.tv_sec ==
1378 (time_t)NO_VALUE_SET)
1379 attributes[n_attrs++] = YP_MODIFY_TIMEOUT;
1380 if (proxy_info->add_timeout.tv_sec == (time_t)NO_VALUE_SET)
1381 attributes[n_attrs++] = YP_ADD_TIMEOUT;
1382 if (proxy_info->delete_timeout.tv_sec ==
1383 (time_t)NO_VALUE_SET)
1384 attributes[n_attrs++] = YP_DELETE_TIMEOUT;
1385 if (proxy_info->search_time_limit == (int)NO_VALUE_SET)
1386 attributes[n_attrs++] = YP_SEARCH_TIME_LIMIT;
1387 if (proxy_info->search_size_limit == (int)NO_VALUE_SET)
1388 attributes[n_attrs++] = YP_SEARCH_SIZE_LIMIT;
1389 if (proxy_info->follow_referral ==
1390 (follow_referral_t)NO_VALUE_SET)
1391 attributes[n_attrs++] = YP_FOLLOW_REFERRAL;
1392
1393 if (table_info->retrieveError ==
1394 (__nis_retrieve_error_t)NO_VALUE_SET)
1395 attributes[n_attrs++] = YP_RETRIEVE_ERROR_ACTION;
1396 if (table_info->retrieveErrorRetry.attempts == NO_VALUE_SET)
1397 attributes[n_attrs++] = YP_RETREIVE_ERROR_ATTEMPTS;
1398 if (table_info->retrieveErrorRetry.timeout ==
1399 (time_t)NO_VALUE_SET)
1400 attributes[n_attrs++] = YP_RETREIVE_ERROR_TIMEOUT;
1401 if (table_info->storeError ==
1402 (__nis_store_error_t)NO_VALUE_SET)
1403 attributes[n_attrs++] = YP_STORE_ERROR_ACTION;
1404 if (table_info->storeErrorRetry.attempts == NO_VALUE_SET)
1405 attributes[n_attrs++] = YP_STORE_ERROR_ATTEMPTS;
1406 if (table_info->storeErrorRetry.timeout ==
1407 (time_t)NO_VALUE_SET)
1408 attributes[n_attrs++] = YP_STORE_ERROR_TIMEOUT;
1409 if (table_info->refreshError ==
1410 (__nis_refresh_error_t)NO_VALUE_SET)
1411 attributes[n_attrs++] = REFRESH_ERROR_ACTION;
1412 if (table_info->refreshErrorRetry.attempts == NO_VALUE_SET)
1413 attributes[n_attrs++] = REFRESH_ERROR_ATTEMPTS;
1414 if (table_info->refreshErrorRetry.timeout ==
1415 (time_t)NO_VALUE_SET)
1416 attributes[n_attrs++] = REFRESH_ERROR_TIMEOUT;
1417 if (table_info->matchFetch ==
1418 (__nis_match_fetch_t)NO_VALUE_SET)
1419 attributes[n_attrs++] = YP_MATCH_FETCH;
1420 } else {
1421 if (proxy_info->default_servers == NULL)
1422 attributes[n_attrs++] = PREFERRED_SERVERS;
1423 if (proxy_info->auth_method == (auth_method_t)NO_VALUE_SET)
1424 attributes[n_attrs++] = AUTH_METHOD;
1425 if (proxy_info->tls_method == (tls_method_t)NO_VALUE_SET)
1426 attributes[n_attrs++] = TLS_OPTION;
1427 if (proxy_info->tls_cert_db == NULL)
1428 attributes[n_attrs++] = TLS_CERT_DB;
1429 if (proxy_info->default_search_base == NULL)
1430 attributes[n_attrs++] = SEARCH_BASE;
1431 if (proxy_info->proxy_dn == NULL)
1432 attributes[n_attrs++] = PROXY_USER;
1433 if (proxy_info->proxy_passwd == NULL)
1434 attributes[n_attrs++] = PROXY_PASSWD;
1435 if (proxy_info->default_nis_domain == NULL)
1436 attributes[n_attrs++] = LDAP_BASE_DOMAIN;
1437 if (proxy_info->bind_timeout.tv_sec ==
1438 (time_t)NO_VALUE_SET)
1439 attributes[n_attrs++] = BIND_TIMEOUT;
1440 if (proxy_info->search_timeout.tv_sec ==
1441 (time_t)NO_VALUE_SET)
1442 attributes[n_attrs++] = SEARCH_TIMEOUT;
1443 if (proxy_info->modify_timeout.tv_sec ==
1444 (time_t)NO_VALUE_SET)
1445 attributes[n_attrs++] = MODIFY_TIMEOUT;
1446 if (proxy_info->add_timeout.tv_sec == (time_t)NO_VALUE_SET)
1447 attributes[n_attrs++] = ADD_TIMEOUT;
1448 if (proxy_info->delete_timeout.tv_sec ==
1449 (time_t)NO_VALUE_SET)
1450 attributes[n_attrs++] = DELETE_TIMEOUT;
1451 if (proxy_info->search_time_limit == (int)NO_VALUE_SET)
1452 attributes[n_attrs++] = SEARCH_TIME_LIMIT;
1453 if (proxy_info->search_size_limit == (int)NO_VALUE_SET)
1454 attributes[n_attrs++] = SEARCH_SIZE_LIMIT;
1455 if (proxy_info->follow_referral ==
1456 (follow_referral_t)NO_VALUE_SET)
1457 attributes[n_attrs++] = FOLLOW_REFERRAL;
1458
1459 if (table_info->retrieveError ==
1460 (__nis_retrieve_error_t)NO_VALUE_SET)
1461 attributes[n_attrs++] = RETRIEVE_ERROR_ACTION;
1462 if (table_info->retrieveErrorRetry.attempts == NO_VALUE_SET)
1463 attributes[n_attrs++] = RETREIVE_ERROR_ATTEMPTS;
1464 if (table_info->retrieveErrorRetry.timeout ==
1465 (time_t)NO_VALUE_SET)
1466 attributes[n_attrs++] = RETREIVE_ERROR_TIMEOUT;
1467 if (table_info->storeError ==
1468 (__nis_store_error_t)NO_VALUE_SET)
1469 attributes[n_attrs++] = STORE_ERROR_ACTION;
1470 if (table_info->storeErrorRetry.attempts == NO_VALUE_SET)
1471 attributes[n_attrs++] = STORE_ERROR_ATTEMPTS;
1472 if (table_info->storeErrorRetry.timeout ==
1473 (time_t)NO_VALUE_SET)
1474 attributes[n_attrs++] = STORE_ERROR_TIMEOUT;
1475 if (table_info->refreshError ==
1476 (__nis_refresh_error_t)NO_VALUE_SET)
1477 attributes[n_attrs++] = REFRESH_ERROR_ACTION;
1478 if (table_info->refreshErrorRetry.attempts == NO_VALUE_SET)
1479 attributes[n_attrs++] = REFRESH_ERROR_ATTEMPTS;
1480 if (table_info->refreshErrorRetry.timeout ==
1481 (time_t)NO_VALUE_SET)
1482 attributes[n_attrs++] = REFRESH_ERROR_TIMEOUT;
1483 if (table_info->matchFetch ==
1484 (__nis_match_fetch_t)NO_VALUE_SET)
1485 attributes[n_attrs++] = MATCH_FETCH;
1486 }
1487
1488 switch (nis_config->initialUpdate) {
1489 case (__nis_initial_update_t)NO_VALUE_SET:
1490 attributes[n_attrs++] = INITIAL_UPDATE_ACTION;
1491 attributes[n_attrs++] = INITIAL_UPDATE_ONLY;
1492 break;
1493 case (__nis_initial_update_t)INITIAL_UPDATE_NO_ACTION:
1494 case (__nis_initial_update_t)NO_INITIAL_UPDATE_NO_ACTION:
1495 attributes[n_attrs++] = INITIAL_UPDATE_ACTION;
1496 break;
1497 case (__nis_initial_update_t)FROM_NO_INITIAL_UPDATE:
1498 case (__nis_initial_update_t)TO_NO_INITIAL_UPDATE:
1499 attributes[n_attrs++] = INITIAL_UPDATE_ONLY;
1500 break;
1501 }
1502
1503 if (nis_config->threadCreationError ==
1504 (__nis_thread_creation_error_t)NO_VALUE_SET)
1505 attributes[n_attrs++] = THREAD_CREATE_ERROR_ACTION;
1506 if (nis_config->threadCreationErrorTimeout.attempts == NO_VALUE_SET)
1507 attributes[n_attrs++] = THREAD_CREATE_ERROR_ATTEMPTS;
1508 if (nis_config->threadCreationErrorTimeout.timeout ==
1509 (time_t)NO_VALUE_SET)
1510 attributes[n_attrs++] = THREAD_CREATE_ERROR_TIMEOUT;
1511 if (nis_config->dumpError == (__nis_dump_error_t)NO_VALUE_SET)
1512 attributes[n_attrs++] = DUMP_ERROR_ACTION;
1513 if (nis_config->dumpErrorTimeout.attempts == NO_VALUE_SET)
1514 attributes[n_attrs++] = DUMP_ERROR_ATTEMPTS;
1515 if (nis_config->dumpErrorTimeout.timeout == (time_t)NO_VALUE_SET)
1516 attributes[n_attrs++] = DUMP_ERROR_TIMEOUT;
1517 if (nis_config->resyncService == (__nis_resync_service_t)NO_VALUE_SET)
1518 attributes[n_attrs++] = RESYNC;
1519 if (nis_config->updateBatching ==
1520 (__nis_update_batching_t)NO_VALUE_SET)
1521 attributes[n_attrs++] = UPDATE_BATCHING;
1522 if (nis_config->updateBatchingTimeout.timeout == (time_t)NO_VALUE_SET)
1523 attributes[n_attrs++] = UPDATE_BATCHING_TIMEOUT;
1524 if (nis_config->numberOfServiceThreads == (int)NO_VALUE_SET)
1525 attributes[n_attrs++] = NUMBER_THEADS;
1526 if (nis_config->emulate_yp == (int)NO_VALUE_SET)
1527 attributes[n_attrs++] = YP_EMULATION;
1528
1529 /* maxRPCRecordSize is not configurable through LDAP profiles */
1530 if (nis_config->maxRPCRecordSize == (int)NO_VALUE_SET)
1531 attributes[n_attrs++] = MAX_RPC_RECSIZE;
1532
1533 attributes[n_attrs++] = NULL;
1534 }
1535
1536 /*
1537 * Notes on adding new attributes
1538 * 1. Determine where the attribute value will be saved
1539 * Currently, the following structures are defined:
1540 * __nis_config_info_t config_info
1541 * __nis_ldap_proxy_info proxyInfo
1542 * __nis_config_t ldapConfig
1543 * __nisdb_table_mapping_t ldapDBTableMapping
1544 * __nis_table_mapping_t ldapTableMapping
1545 * or add a new structure or variable - this will require
1546 * more code.
1547 * 2. Initialize the value to a known unconfigured value.
1548 * This can be done in initialize_parse_structs or
1549 * parse_ldap_migration.
1550 * 3. In the header file nis_parse_ldap_conf.h, add the name
1551 * of the attribute. (Currently, the attribute name is assumed
1552 * to be the same for the command line, the preference file,
1553 * and LDAP.) The names are grouped logically. Add a corresponding
1554 * config_key to the enum. Note that position in this file is
1555 * essential because the macros such as IS_BIND_INFO depend on
1556 * the sequence. The corresponding macro (IS_CONFIG_KEYWORD,
1557 * IS_BIND_INFO, or IS_OPER_INFO) may need to be adjusted. These
1558 * are used to partition the attributes into smaller chunks.
1559 * 4. Add the correspond entry to the keyword_lookup array in
1560 * nis_parse_ldap_attr.c, which is used to determine the config_key
1561 * from the corresponding key word.
1562 * 5. Add the attribute to the list of attributes to retrieve from
1563 * the LDAP server if no value has been set in the function
1564 * parse_ldap_config_dn_attrs. (This assumes that the attribute
1565 * is not used to get the configuration from the LDAP server.)
1566 * 6. Add logic to parse the individual attribute in
1567 * add_config_attribute, add_bind_attribute,
1568 * add_operation_attribute, or add_mapping_attribute depending
1569 * which group of attributes the added attribute belongs to.
1570 * 7. In set_default_values, if the attribute value has not been set, set
1571 * the default value. If any additional fixup is needed depending
1572 * on other configuration values, it should be done here.
1573 * 8. If an attribute name is a subset of another, parse_ldap_default_conf
1574 * should be modified.
1575 */
1576