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