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