sd: remove 'ssd' driver support
[unleashed/tickless.git] / usr / src / lib / libnisdb / nis_parse_ldap_yp_util.c
blob1d0786e5d83f4eada6b5f6f8f6870d98dc6e2741
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
23 * Copyright 2015 Gary Mills
24 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
28 #include <stdio.h>
29 #include <string.h>
30 #include <stdlib.h>
31 #include <ctype.h>
32 #include <fcntl.h>
33 #include <errno.h>
34 #include <syslog.h>
36 #include "ldap_parse.h"
37 #include "nis_parse_ldap_conf.h"
38 #include "nis_parse_ldap_util.h"
39 #include "ldap_util.h"
41 /* Forward declarations */
42 int getfullmapname(char **, const char *);
43 int checkfullmapname(const char *, const char *, __nis_table_mapping_t **,
44 __nis_table_mapping_t **);
45 int append_domainContext(__nis_table_mapping_t **, char *, char *);
47 static int merge_table_mapping(__nis_table_mapping_t *in,
48 __nis_table_mapping_t *out);
49 __nis_table_mapping_t *new_merged_mapping(const char *,
50 __nis_table_mapping_t *intbl);
51 static int append_mapping_rule(__nis_mapping_rule_t *src_rule,
52 __nis_table_mapping_t *tbl, int flag);
55 static int copy_object_dn(__nis_object_dn_t *in,
56 __nis_object_dn_t *newdn);
59 * FUNCTION: initialize_table_mapping
61 * Initialize the __nis_table_mapping_t structure.
63 * INPUT: __nis_table_mapping_t
66 void
67 initialize_table_mapping(
68 __nis_table_mapping_t *mapping)
70 if (mapping != NULL) {
71 mapping->dbId = NULL;
73 mapping->index.numIndexes = 0;
74 mapping->index.name = NULL;
75 mapping->index.value = NULL;
77 mapping->numColumns = 0;
78 mapping->column = NULL;
80 mapping->initTtlLo = (time_t)NO_VALUE_SET;
81 mapping->initTtlHi = (time_t)NO_VALUE_SET;
82 mapping->ttl = (time_t)NO_VALUE_SET;
84 mapping->usedns_flag = 0;
85 mapping->securemap_flag = 0;
86 mapping->commentChar = DEFAULT_COMMENT_CHAR;
87 mapping->numSplits = 0;
89 mapping->objectDN = NULL;
91 mapping->separatorStr = DEFAULT_SEP_STRING;
93 mapping->numRulesFromLDAP = 0;
94 mapping->numRulesToLDAP = 0;
96 mapping->ruleFromLDAP = NULL;
97 mapping->ruleToLDAP = NULL;
99 mapping->e = NULL;
100 mapping->objName = NULL;
101 mapping->objPath = NULL;
102 mapping->obj = NULL;
103 mapping->isMaster = 0;
104 mapping->seq_num = NO_VALUE_SET;
109 * FUNCTION: initialize_yp_parse_structs
111 * Initialize the __yp_domain_context_t structure.
113 * INPUT: __yp_domain_context_t
116 void
117 initialize_yp_parse_structs(
118 __yp_domain_context_t *ypDomains)
120 ypDomains->numDomains = 0;
121 ypDomains->domainLabels = NULL;
122 ypDomains->domains = NULL;
123 ypDomains->numYppasswdd = 0;
124 ypDomains->yppasswddDomainLabels = NULL;
128 * FUNCTION: merge_table_mapping
130 * Merges information from one table_mapping struct
131 * into another
133 * INPUT: Source and Destination table_mapping structs.
134 * RETURN: 0 on success and > 0 on error.
137 static int
138 merge_table_mapping(
139 __nis_table_mapping_t *in,
140 __nis_table_mapping_t *out)
142 int i;
143 int orig_num_rules;
144 int append;
146 if (in == NULL)
147 return (1);
149 if (in->dbId == NULL)
150 return (1);
153 * If 'in' is generic (non-expanded) and 'out' is domain-specific,
154 * then rules from 'in' should not be appended to those in 'out'.
156 if (!strchr(in->dbId, COMMA_CHAR) && strchr(out->dbId, COMMA_CHAR))
157 append = 0;
158 else
159 append = 1;
162 if (!out->index.numIndexes && in->index.numIndexes > 0) {
163 if (!dup_index(&in->index, &out->index))
164 return (1);
167 /* add_column() increments numColumns, so we don't */
168 if (!out->numColumns && in->numColumns > 0) {
169 for (i = 0; i < in->numColumns; i++) {
170 if (!add_column(out, in->column[i]))
171 return (1);
175 if (out->commentChar == DEFAULT_COMMENT_CHAR &&
176 in->commentChar != DEFAULT_COMMENT_CHAR)
177 out->commentChar = in->commentChar;
179 if (out->usedns_flag == 0)
180 out->usedns_flag = in->usedns_flag;
182 if (out->securemap_flag == 0)
183 out->securemap_flag = in->securemap_flag;
185 if ((strcmp(out->separatorStr, DEFAULT_SEP_STRING) == 0) &&
186 (strcmp(in->separatorStr, DEFAULT_SEP_STRING) != 0)) {
187 out->separatorStr = s_strdup(in->separatorStr);
188 if (!out->separatorStr)
189 return (2);
192 if (!out->numSplits && !out->e && in->e) {
193 out->numSplits = in->numSplits;
194 out->e = (__nis_mapping_element_t *)
195 s_calloc(1, (in->numSplits+1) *
196 sizeof (__nis_mapping_element_t));
197 if (!out->e)
198 return (2);
199 for (i = 0; i <= in->numSplits; i++) {
200 if (!dup_mapping_element(&in->e[i], &out->e[i])) {
201 for (; i > 0; i--) {
202 free_mapping_element(&out->e[i - 1]);
204 out->e = NULL;
205 return (1);
210 if (out->initTtlLo == (time_t)NO_VALUE_SET &&
211 in->initTtlLo != (time_t)NO_VALUE_SET)
212 out->initTtlLo = in->initTtlLo;
214 if (out->initTtlHi == (time_t)NO_VALUE_SET &&
215 in->initTtlHi != (time_t)NO_VALUE_SET)
216 out->initTtlHi = in->initTtlHi;
218 if (out->ttl == (time_t)NO_VALUE_SET &&
219 in->ttl != (time_t)NO_VALUE_SET)
220 out->ttl = in->ttl;
222 if (!out->numRulesFromLDAP && in->numRulesFromLDAP) {
223 out->ruleFromLDAP = dup_mapping_rules(in->ruleFromLDAP,
224 in->numRulesFromLDAP);
225 if (!out->ruleFromLDAP)
226 return (1);
227 out->numRulesFromLDAP = in->numRulesFromLDAP;
228 } else if (append && out->numRulesFromLDAP && in->numRulesFromLDAP) {
229 orig_num_rules = out->numRulesFromLDAP;
230 for (i = 0; i < in->numRulesFromLDAP; i++) {
231 if (append_mapping_rule(in->ruleFromLDAP[i], out, 0)) {
232 for (i = out->numRulesFromLDAP;
233 i > orig_num_rules; i--) {
234 free_mapping_rule(out->ruleFromLDAP[i]);
235 out->ruleFromLDAP[i] = NULL;
237 return (1);
243 if (!out->numRulesToLDAP && in->numRulesToLDAP) {
244 out->ruleToLDAP = dup_mapping_rules(in->ruleToLDAP,
245 in->numRulesToLDAP);
246 if (!out->ruleToLDAP)
247 return (1);
248 out->numRulesToLDAP = in->numRulesToLDAP;
249 } else if (append && out->numRulesToLDAP && in->numRulesToLDAP) {
250 orig_num_rules = out->numRulesToLDAP;
251 for (i = 0; i < in->numRulesToLDAP; i++) {
252 if (append_mapping_rule(in->ruleToLDAP[i], out, 1)) {
253 for (i = out->numRulesToLDAP;
254 i > orig_num_rules; i--) {
255 free_mapping_rule(out->ruleToLDAP[i]);
256 out->ruleToLDAP[i] = NULL;
258 return (1);
262 if (!out->objectDN && in->objectDN) {
263 out->objectDN = (__nis_object_dn_t *)
264 s_calloc(1, sizeof (__nis_object_dn_t));
265 if (!out->objectDN)
266 return (2);
267 if (copy_object_dn(in->objectDN, out->objectDN)) {
268 free_object_dn(out->objectDN);
269 out->objectDN = NULL;
270 return (1);
274 if (!out->objName && in->objName) {
275 if (!strchr(in->objName, SPACE_CHAR)) {
276 /* objName has no space- a single map dbIdMapping */
277 out->objName = s_strndup(in->objName,
278 strlen(in->objName));
279 if (!out->objName)
280 return (2);
284 if (!out->objName && out->dbId) {
285 out->objName = s_strndup(out->dbId, strlen(out->dbId));
286 if (!out->objName)
287 return (2);
290 if (out->seq_num == NO_VALUE_SET && in->seq_num >= 0)
291 out->seq_num = in->seq_num;
293 return (p_error == no_parse_error ? 0 : 1);
297 * FUNCTION: copy_object_dn
299 * Copies a __nis_object_dn_t structure.
301 * RETURN: 0 on success, > 0 on failure.
303 * NOTE: The caller MUST free newdn using
304 * free_object_dn() if return value != 0 (error condition)
307 static int
308 copy_object_dn(__nis_object_dn_t *in, __nis_object_dn_t *newdn)
310 if (in == NULL) {
311 p_error = parse_no_object_dn;
312 return (1);
314 while (in != NULL) {
315 if (in->read.base == NULL) {
316 newdn->read.base = NULL;
317 } else {
318 newdn->read.base = s_strndup(
319 in->read.base, strlen(in->read.base));
320 if (newdn->read.base == NULL)
321 return (2);
323 newdn->read.scope = in->read.scope;
324 if (in->read.attrs) {
325 newdn->read.attrs = s_strndup(
326 in->read.attrs, strlen(in->read.attrs));
327 if (newdn->read.attrs == NULL) {
328 return (2);
330 } else {
331 newdn->read.attrs = NULL;
333 newdn->read.element = in->read.element;
334 if (in->write.base != NULL) {
335 newdn->write.base = s_strndup(
336 in->write.base, strlen(in->write.base));
337 if (newdn->write.base == NULL)
338 return (2);
339 } else {
340 newdn->write.base = NULL;
342 newdn->write.scope = in->write.scope;
343 if (in->write.attrs != NULL) {
344 newdn->write.attrs = s_strndup(
345 in->write.attrs, strlen(in->write.attrs));
346 if (newdn->write.attrs == NULL) {
347 return (2);
349 } else {
350 newdn->write.attrs = NULL;
352 newdn->write.element = in->write.element;
353 if (in->dbIdName) {
354 newdn->dbIdName = s_strndup(in->dbIdName,
355 strlen(in->dbIdName));
356 if (newdn->dbIdName == NULL)
357 return (2);
360 if (in->delDisp)
361 newdn->delDisp = in->delDisp;
363 if (in->dbId && in->numDbIds > 0) {
364 newdn->dbId = dup_mapping_rules(in->dbId,
365 in->numDbIds);
366 if (!newdn->dbId)
367 return (1);
368 newdn->numDbIds = in->numDbIds;
370 if (in->next != NULL) {
371 newdn->next = (__nis_object_dn_t *)s_calloc(1,
372 sizeof (__nis_object_dn_t));
373 if (newdn->next == NULL)
374 return (1);
375 newdn = newdn->next;
376 in = in->next;
377 } else {
378 return (0);
380 } /* End of while on in */
382 return (0);
386 * FUNCTION: free_yp_domain_context
388 * Frees __yp_domain_context_t
390 * INPUT: __yp_domain_context_t
392 void
393 free_yp_domain_context(__yp_domain_context_t *domains)
395 int i;
397 if (domains != NULL) {
398 for (i = 0; i < domains->numDomains; i++) {
399 if (domains->domains[i] != NULL) {
400 free(domains->domains[i]);
401 domains->domains[i] = NULL;
403 if (domains->domainLabels[i] != NULL) {
404 free(domains->domainLabels[i]);
405 domains->domainLabels[i] = NULL;
408 domains->domains = NULL;
409 domains->domainLabels = NULL;
410 for (i = 0; i < domains->numYppasswdd; i++) {
411 if (domains->yppasswddDomainLabels[i] != NULL) {
412 free(domains->yppasswddDomainLabels[i]);
413 domains->yppasswddDomainLabels[i] =
414 NULL;
417 domains->yppasswddDomainLabels = NULL;
418 domains->numDomains = 0;
419 domains = NULL;
424 * FUNCTION: second_parser_pass
426 * Prepares the linked list of table_mappings for processing
427 * by finish_parse(), adding, merging and deleting structures
428 * as necessary. Also adds dummy objectDN info. for splitField's.
430 * RETURN VALUE: 0 on success, > 0 on failure.
433 second_parser_pass(__nis_table_mapping_t **table_mapping)
435 __nis_table_mapping_t *t, *t2;
436 __nis_table_mapping_t *t_new = NULL, *tg;
437 __nis_table_mapping_t *prev = NULL;
438 char *objs, *dom;
439 char *objName = NULL;
440 char *lasts;
441 char *tobj, *alias, *dupalias, *tmp;
442 char *myself = "second_parser_pass";
443 int i = 0, len;
445 prev = NULL;
446 for (t = *table_mapping; t != NULL; ) {
448 * Temporarily using this field to flag deletion.
449 * 0 : don't delete
450 * 1 : delete
451 * The mapping structure will be deleted in final_parser_pass
453 t->isMaster = 0;
455 if (!t->dbId) {
456 p_error = parse_bad_map_error;
457 logmsg(MSG_NOTIMECHECK, LOG_ERR,
458 "%s: no dbId field", myself);
459 return (1);
461 tg = NULL;
462 dom = strchr(t->dbId, COMMA_CHAR);
463 if (t->objName != NULL) {
464 objName = strdup(t->objName);
465 if (objName == NULL) {
466 p_error = parse_no_mem_error;
467 logmsg(MSG_NOMEM, LOG_ERR,
468 "%s: Cannot allocate memory for objName",
469 myself);
470 return (1);
472 objs = (char *)strtok_r(objName, " ", &lasts);
473 /* Get the generic mapping */
474 if (dom != NULL) {
475 tg = find_table_mapping(t->dbId, dom - t->dbId,
476 *table_mapping);
478 } else {
479 objs = NULL;
480 if (dom == NULL) {
481 t->objName = s_strndup(t->dbId,
482 strlen(t->dbId));
483 if (!t->objName) {
484 logmsg(MSG_NOMEM, LOG_ERR,
485 "%s: Cannot allocate memory for "
486 "t->objName", myself);
487 objs = NULL;
488 return (2);
490 } else {
491 /* Force relationship for domain specific */
493 /* Get the generic mapping */
494 tg = find_table_mapping(t->dbId, dom - t->dbId,
495 *table_mapping);
496 if (tg == NULL || tg->objName == NULL) {
497 /* If not found, use dbId for objName */
498 t->objName = s_strndup(t->dbId,
499 strlen(t->dbId));
500 if (t->objName == NULL) {
501 logmsg(MSG_NOMEM, LOG_ERR,
502 "%s: Cannot allocate memory for t->objName",
503 myself);
504 return (2);
506 } else {
507 dom++;
508 tobj = s_strndup(tg->objName,
509 strlen(tg->objName));
510 if (tobj == NULL) {
511 logmsg(MSG_NOMEM, LOG_ERR,
512 "%s: Cannot allocate memory for t->objName",
513 myself);
514 return (2);
516 alias = (char *)strtok_r(tobj, " ",
517 &lasts);
519 /* Loop 'breaks' on errors */
520 while (alias) {
521 tmp = NULL;
522 dupalias = s_strndup(alias,
523 strlen(alias));
524 if (!dupalias)
525 break;
526 if (getfullmapname(&dupalias,
527 dom)) {
528 i = 1;
529 break;
531 if (t->objName == NULL)
532 t->objName = dupalias;
533 else {
534 len = strlen(t->objName)
535 + strlen(dupalias) +
537 tmp = s_calloc(1, len);
538 if (tmp == NULL)
539 break;
540 snprintf(tmp, len,
541 "%s %s",
542 t->objName,
543 dupalias);
544 free(dupalias);
545 dupalias = NULL;
546 free(t->objName);
547 t->objName = tmp;
549 alias = (char *)strtok_r(NULL,
550 " ", &lasts);
553 free(tobj);
555 if (alias ||
556 (objName = s_strdup(t->objName))
557 == NULL) {
558 if (i)
559 logmsg(MSG_NOTIMECHECK,
560 LOG_ERR,
561 "%s: getfullmapname failed for %s for domain \"%s\"",
562 myself, dupalias,
563 dom);
564 else {
565 p_error =
566 parse_no_mem_error;
567 logmsg(MSG_NOMEM,
568 LOG_ERR,
569 "%s: Cannot allocate memory",
570 myself);
572 free(dupalias);
573 free(t->objName);
574 return (2);
577 objs = (char *)strtok_r(objName, " ",
578 &lasts);
583 if (tg != NULL) {
584 if (merge_table_mapping(tg, t)) {
585 logmsg(MSG_NOTIMECHECK, LOG_ERR,
586 "Error merging information from the %s to the %s mapping structure",
587 tg->dbId, t->dbId);
588 objs = NULL;
589 free(objName);
590 return (1);
595 * If objName is "map1 map2" then do the second pass.
596 * If it is just "map1" however skip the expansion.
597 * Also skip it if t->objName is null.
599 if (objs && strncasecmp(objs, t->objName,
600 strlen(t->objName))) {
601 t2 = find_table_mapping(objs, strlen(objs),
602 *table_mapping);
603 if (t2) {
604 if (merge_table_mapping(t, t2)) {
605 logmsg(MSG_NOTIMECHECK, LOG_ERR,
606 "Error merging information from the %s to the %s mapping structure",
607 t->dbId, t2->dbId);
608 objs = NULL;
609 free(objName);
610 return (1);
612 t->isMaster = 1;
613 } else {
614 t_new = new_merged_mapping(objs, t);
615 if (t_new) {
616 t->isMaster = 1;
617 if (prev != NULL)
618 prev->next = t_new;
619 else
620 *table_mapping = t_new;
621 prev = t_new;
622 prev->next = t;
623 } else {
624 logmsg(MSG_NOTIMECHECK, LOG_ERR,
625 "Error creating a new mapping structure %s",
626 objs);
627 objs = NULL;
628 free(objName);
629 return (1);
632 while ((objs = (char *)strtok_r(NULL, " ", &lasts))
633 != NULL) {
634 t2 = find_table_mapping(objs, strlen(objs),
635 *table_mapping);
636 if (t2) {
637 if (merge_table_mapping(t, t2)) {
638 logmsg(MSG_NOTIMECHECK, LOG_ERR,
639 "Error merging information from the %s to the %s mapping structure",
640 t->dbId, t2->dbId);
641 objs = NULL;
642 free(objName);
643 return (1);
645 t->isMaster = 1;
646 } else {
648 * create a new t_map with dbId = objs
649 * and copy t->* into new t_map
651 t_new = new_merged_mapping(objs, t);
652 if (t_new) {
653 t->isMaster = 1;
654 if (prev != NULL)
655 prev->next = t_new;
656 else
657 *table_mapping = t_new;
658 prev = t_new;
659 prev->next = t;
660 } else {
661 logmsg(MSG_NOTIMECHECK, LOG_ERR,
662 "Error creating a new mapping structure %s",
663 objs);
664 objs = NULL;
665 free(objName);
666 return (1);
670 } /* if objs!= NULL */
672 prev = t;
673 t = t->next;
675 if (objName) {
676 free(objName);
677 objName = NULL;
678 objs = NULL;
680 } /* for t = table_mapping loop */
681 return (0);
684 __nis_table_mapping_t *
685 new_merged_mapping(const char *match,
686 __nis_table_mapping_t *intbl)
689 __nis_table_mapping_t *outtable = NULL;
691 outtable = (__nis_table_mapping_t *)
692 s_calloc(1, sizeof (__nis_table_mapping_t));
693 if (outtable == NULL)
694 return (NULL);
695 initialize_table_mapping(outtable);
696 outtable->dbId = s_strndup(match, strlen(match));
697 if (outtable->dbId == NULL) {
698 free_table_mapping(outtable);
699 outtable = NULL;
700 return (NULL);
702 if (merge_table_mapping(intbl, outtable)) {
703 free_table_mapping(outtable);
704 outtable = NULL;
706 return (outtable);
710 * FUNCTION: final_parser_pass
712 * completes the final expansion of t_map structures linked list.
713 * all structures will have a non-null objPath as well as a objName
714 * in the form of "mapname . domainname ." or "splitfieldname .
715 * domainname .".
717 * RETURN VALUE: 0 on success, -1 on failure, -2 on fatal error.
720 final_parser_pass(
721 __nis_table_mapping_t **table_mapping,
722 __yp_domain_context_t *ypDomains)
724 __nis_table_mapping_t *t;
725 __nis_table_mapping_t *t1, *returned_map;
726 __nis_table_mapping_t *prev = NULL;
727 int i;
728 char *myself = "final_parser_pass";
729 int nm;
730 bool_t r;
731 int del_tbl_flag = 0;
733 if (ypDomains) {
734 if (!ypDomains->numDomains) {
735 p_error = parse_internal_error;
736 logmsg(MSG_NOTIMECHECK, LOG_ERR,
737 "%s:No domains specified.", myself);
738 return (-1);
740 } else {
741 p_error = parse_internal_error;
742 logmsg(MSG_NOTIMECHECK, LOG_ERR,
743 "%s:No domain structure supplied.", myself);
744 return (-1);
746 prev = NULL;
748 for (t = *table_mapping; t != NULL; ) {
750 /* Delete if marked for deletion by second_parser_pass */
751 if (t->isMaster == 1) {
752 if (prev != NULL)
753 prev->next = t->next;
754 else
755 *table_mapping = t->next;
756 t1 = t;
757 t = t->next;
758 free_table_mapping(t1);
759 continue;
762 if (!t->objName && t->dbId) {
763 t->objName = s_strndup(t->dbId, strlen(t->dbId));
764 if (!t->objName) {
765 logmsg(MSG_NOMEM, LOG_ERR,
766 "%s:Could not allocate.", myself);
767 return (-1);
770 i = ypDomains->numDomains;
771 while (i > 0) {
772 if (i == 1) {
773 /* modify existing table_mapping's */
774 nm = checkfullmapname(t->dbId,
775 ypDomains->domainLabels[0],
776 table_mapping, &returned_map);
777 if (nm == 1) {
778 /* delete this mapping structure */
779 logmsg(MSG_NOTIMECHECK,
780 LOG_WARNING,
781 "Mapping structure %s,%s "
782 "already exists.",
783 t->dbId,
784 ypDomains->domainLabels[0]);
785 if (merge_table_mapping(t,
786 returned_map)) {
787 logmsg(MSG_NOTIMECHECK, LOG_ERR,
788 "Error merging information "
789 "from the %s to the %s "
790 "mapping structure.",
791 t->dbId,
792 returned_map->dbId);
793 return (-1);
795 if (del_tbl_flag == 0)
796 del_tbl_flag = 1;
797 } else if (nm == -1) {
798 logmsg(MSG_NOTIMECHECK, LOG_ERR,
799 "Error searching for %s,%s structure",
800 t->dbId,
801 ypDomains->domainLabels[0]);
802 return (-1);
803 } else if (nm == 0 || nm == 2) {
804 if ((append_domainContext(&t,
805 ypDomains->domainLabels[0],
806 ypDomains->domains[0])) != 0) {
807 logmsg(MSG_NOTIMECHECK, LOG_ERR,
808 "Error appending domainContext %s",
809 ypDomains->domainLabels[0]);
810 return (-1);
812 del_tbl_flag = 0;
814 } else { /* if (i > 1) */
815 /* need to create new table_mapping's */
816 nm = checkfullmapname(t->dbId,
817 ypDomains->domainLabels[i - 1],
818 table_mapping, &returned_map);
819 if (nm == -1) {
820 logmsg(MSG_NOTIMECHECK, LOG_ERR,
821 "Error searching for %s,%s structure",
822 t->dbId,
823 ypDomains->domainLabels[i - 1]);
824 return (-1);
825 } else if (nm == 0) {
826 t1 = new_merged_mapping(t->dbId, t);
827 /* we clone ourselves */
828 if (t1) {
829 if ((append_domainContext(&t1,
830 ypDomains->domainLabels[i - 1],
831 ypDomains->domains[i - 1])) != 0) {
832 logmsg(MSG_NOTIMECHECK, LOG_ERR,
833 "Error appending domainContext %s",
834 ypDomains->domainLabels[i - 1]);
835 free(t1);
836 return (-1);
838 if (prev != NULL) {
839 t1->next = prev->next;
840 prev->next = t1;
841 prev = prev->next;
842 } else {
843 t1->next =
844 *table_mapping;
845 *table_mapping = t1;
846 prev = t1;
848 } else { /* if !t1 */
849 p_error = parse_internal_error;
850 logmsg(MSG_NOTIMECHECK, LOG_ERR,
851 "%s:Could not create new table -"
852 " check all instances of %s for errors",
853 myself, t->dbId);
854 return (-1);
856 } else if (nm == 1) {
857 logmsg(MSG_NOTIMECHECK, LOG_WARNING,
858 "Mapping structure %s,%s already exists.",
859 t->dbId,
860 ypDomains->domainLabels[i - 1]);
862 * We should be deleting this, but can't
863 * really do it here, because we need to
864 * match with the domainLabels[0] case
865 * too. So we will just flag it for now.
867 if (merge_table_mapping(t,
868 returned_map)) {
869 logmsg(MSG_NOTIMECHECK, LOG_ERR,
870 "Error merging information from the %s to the %s mapping structure.",
871 t->dbId,
872 returned_map->dbId);
873 return (-1);
875 del_tbl_flag = 1;
876 } else if (nm == 2) {
877 if ((append_domainContext(&t,
878 ypDomains->domainLabels[i - 1],
879 ypDomains->domains[i - 1])) != 0) {
880 logmsg(MSG_NOTIMECHECK, LOG_ERR,
881 "Error appending domainContext %s",
882 ypDomains->domainLabels[i - 1]);
883 return (-1);
885 } /* end of "if (nm == 0)" */
886 } /* end of else if (i > 1) */
890 * 'merge_table_mapping' only copies unexpanded
891 * objectDN values into returned_map. Hence,
892 * read.base and write.base in returned_map
893 * needs to be expanded.
895 if (nm == 1 && returned_map && returned_map->objectDN) {
896 r = make_fqdn(
897 returned_map->objectDN,
898 ypDomains->domains[i - 1]);
899 if (r == TRUE &&
900 returned_map->objectDN->write.base) {
901 r = make_full_dn(
902 &returned_map->objectDN->write.base,
903 ypDomains->domains[i - 1]);
906 if (r == FALSE) {
907 logmsg(MSG_NOTIMECHECK, LOG_ERR,
908 "Error appending domainContext "
909 "%s to %s",
910 ypDomains->domainLabels[i - 1],
911 returned_map->dbId);
912 return (-2);
915 i--;
916 } /* end of while i > 0 loop */
918 if (del_tbl_flag == 1) {
919 if (prev != NULL) {
920 prev->next = t->next;
921 free_table_mapping(t);
922 t = prev->next;
923 } else {
924 *table_mapping = t->next;
925 free_table_mapping(t);
926 t = *table_mapping;
928 del_tbl_flag = 0;
929 } else {
930 prev = t;
931 t = t->next;
933 } /* end of table mapping loop */
935 for (t = *table_mapping; t != NULL; t = t->next) {
936 if (!t->dbId) {
937 logmsg(MSG_NOTIMECHECK, LOG_ERR,
938 "%s:Fatal error: structure with no dbId found.",
939 myself);
940 return (-2);
942 append_dot(&t->dbId);
943 if (!t->objectDN) {
944 p_error = parse_internal_error;
945 logmsg(MSG_NOTIMECHECK, LOG_ERR,
946 "%s:No objectDN for %s.", myself, t->dbId);
947 return (-1);
951 return (0);
955 * FUNCTION: append_mapping_rule
957 * Appends mapping rules to a table_mapping structure
958 * with previously existing rules. flag controls whether
959 * the functions works on the rules From or To LDAP.
961 * RETURN VALUE: 0 on success, >= 1 on failure.
964 static int
965 append_mapping_rule(__nis_mapping_rule_t *src_rule,
966 __nis_table_mapping_t *dst, int flag)
968 __nis_mapping_rule_t **rules = NULL;
970 if (flag == 0) {
971 if (dst->ruleFromLDAP == NULL) {
972 p_error = parse_internal_error;
973 return (1);
975 rules = (__nis_mapping_rule_t **)
976 s_realloc(dst->ruleFromLDAP,
977 (dst->numRulesFromLDAP + 1) *
978 sizeof (__nis_mapping_rule_t *));
979 if (rules == NULL)
980 return (2);
981 dst->ruleFromLDAP = rules;
982 rules[dst->numRulesFromLDAP] = dup_mapping_rule(src_rule);
983 if (rules[dst->numRulesFromLDAP] == NULL) {
984 p_error = parse_no_mem_error;
985 return (2);
987 dst->numRulesFromLDAP++;
988 } else if (flag == 1) {
989 if (dst->ruleToLDAP == NULL) {
990 p_error = parse_internal_error;
991 return (1);
993 rules = (__nis_mapping_rule_t **)
994 s_realloc(dst->ruleToLDAP,
995 (dst->numRulesToLDAP + 1) *
996 sizeof (__nis_mapping_rule_t *));
997 if (rules == NULL)
998 return (2);
999 dst->ruleToLDAP = rules;
1000 rules[dst->numRulesToLDAP] = dup_mapping_rule(src_rule);
1001 if (rules[dst->numRulesToLDAP] == NULL) {
1002 p_error = parse_no_mem_error;
1003 return (2);
1005 dst->numRulesToLDAP++;
1006 } else
1007 return (1);
1009 return (0);
1013 * FUNCTION: check_domain_specific_order
1015 * Makes sure that an attribute with explicitly specified
1016 * nisLDAPdomainContext is found before its non-domain
1017 * specific counterpart.
1019 * RETURN VALUE: 0 normal exit
1020 * 1 if domain specific attribute found
1021 * after non-domain specific one.
1022 * -1 some error condition
1026 check_domain_specific_order(const char *sd,
1027 config_key attrib_num,
1028 __nis_table_mapping_t *table_mapping,
1029 __yp_domain_context_t *ypDomains)
1031 __nis_table_mapping_t *t;
1032 char *myself = "check_domain_specific_order";
1033 char *type;
1034 char *dbId = 0;
1035 int i, len;
1036 int match = 0;
1038 if (ypDomains) {
1039 if (!ypDomains->numDomains) {
1040 logmsg(MSG_NOTIMECHECK, LOG_ERR,
1041 "%s:No domains specified.", myself);
1042 return (-1);
1044 } else {
1045 logmsg(MSG_NOTIMECHECK, LOG_ERR,
1046 "%s:No domain structure supplied.", myself);
1047 return (-1);
1050 for (i = 0; i < ypDomains->numDomains; i++) {
1051 for (t = table_mapping; t != NULL; t = t->next) {
1052 len = strlen(sd);
1053 if ((strcasecmp(t->dbId, sd) == 0) && (len ==
1054 strlen(t->dbId)))
1055 /* prevent from matching against itself */
1056 continue;
1057 dbId = s_strndup(t->dbId, strlen(t->dbId));
1058 if (dbId == NULL) {
1059 logmsg(MSG_NOMEM, LOG_ERR,
1060 "%s:Memory allocation error.", myself);
1061 return (-1);
1064 if (getfullmapname(&dbId,
1065 ypDomains->domainLabels[i])) {
1066 logmsg(MSG_NOTIMECHECK, LOG_ERR,
1067 "Error getting fully qualified name for %s",
1068 dbId);
1069 free(dbId);
1070 return (-1);
1072 if ((strcasecmp(dbId, sd) == 0) && (len ==
1073 strlen(dbId))) {
1074 match = 0;
1075 switch (attrib_num) {
1076 case key_yp_map_flags:
1077 if (t->usedns_flag != 0 ||
1078 t->securemap_flag != 0)
1079 match = 1;
1080 type = YP_MAP_FLAGS;
1081 break;
1082 case key_yp_comment_char:
1083 if (t->commentChar !=
1084 DEFAULT_COMMENT_CHAR)
1085 match = 1;
1086 type = YP_COMMENT_CHAR;
1087 break;
1088 case key_yp_repeated_field_separators:
1089 if (strcmp(t->separatorStr,
1090 DEFAULT_SEP_STRING) != 0)
1091 match = 1;
1092 type =
1093 YP_REPEATED_FIELD_SEPARATORS;
1094 break;
1095 case key_yp_name_fields:
1096 if (t->e && t->numColumns)
1097 match = 1;
1098 type = YP_NAME_FIELDS;
1099 case key_yp_split_field:
1100 if (t->e && t->numColumns)
1101 match = 1;
1102 type = YP_SPLIT_FIELD;
1103 break;
1104 case key_yp_db_id_map:
1105 if (t->objName)
1106 match = 1;
1107 type = YP_DB_ID_MAP;
1108 break;
1109 case key_yp_entry_ttl:
1110 if (t->initTtlLo !=
1111 (time_t)NO_VALUE_SET)
1112 match = 1;
1113 type = YP_ENTRY_TTL;
1114 break;
1115 case key_yp_ldap_object_dn:
1116 if (t->objectDN)
1117 match = 1;
1118 type = YP_LDAP_OBJECT_DN;
1119 break;
1120 case key_nis_to_ldap_map:
1121 if (t->ruleToLDAP)
1122 match = 1;
1123 type = NIS_TO_LDAP_MAP;
1124 break;
1125 case key_ldap_to_nis_map:
1126 if (t->ruleFromLDAP)
1127 match = 1;
1128 type = LDAP_TO_NIS_MAP;
1129 break;
1130 default:
1131 type = "unknown";
1132 match = 0;
1133 break;
1134 } /* end of switch */
1135 if (match) {
1136 logmsg(MSG_NOTIMECHECK, LOG_ERR,
1137 "Relative attribute '%s' of type '%s' found before fully qualified one '%s'",
1138 t->dbId, type, sd);
1139 free(dbId);
1140 dbId = NULL;
1141 return (1);
1143 } /* end of strncasecmp */
1144 free(dbId);
1145 dbId = NULL;
1146 } /* end of t loop */
1147 } /* end of i loop */
1148 free(dbId);
1149 dbId = NULL;
1150 return (0);
1154 getfullmapname(char **mapname, const char *domainname)
1156 char *maps = *mapname;
1157 int maplen = strlen(maps);
1158 int domainlen = strlen(domainname);
1160 if (!maplen || !domainlen ||
1161 maps[maplen - 1] == PERIOD_CHAR)
1162 return (1);
1163 else if (strchr(maps, COMMA_CHAR)) {
1164 /* map already has a domain part, do nothing */
1165 return (0);
1166 } else {
1167 append_comma(&maps);
1168 maplen = strlen(maps);
1169 maps = realloc(maps, (maplen + domainlen + 1));
1170 if (maps != NULL) {
1171 if (strlcat(maps, domainname, (maplen + domainlen + 1))
1172 >= (maplen + domainlen + 1))
1173 return (1);
1174 *mapname = maps;
1175 return (0);
1176 } else
1177 return (1);
1182 * FUNCTION: checkfullmapname
1184 * Tries to find out if by appending the table mapping structures
1185 * with each of the provided nisLDAPdomainContexts, an already
1186 * existing fqdn table mapping structure results. That would be the
1187 * case when a full qualified domain specific attribute was present.
1189 * Note that per NISLDAPmapping(4) such an attribute MUST be listed
1190 * in the mapping file BEFORE its non-fqdn counterpart.
1192 * RETURNS: 0 normal exit, 1 if an existing structure found, -1 for all
1193 * errors, 2 if already fqdn. If returning 1 the existing structure is
1194 * in found_map.
1198 checkfullmapname(const char *mapname, const char *domainname,
1199 __nis_table_mapping_t **table_mapping,
1200 __nis_table_mapping_t **found_map)
1202 char *map;
1204 *found_map = NULL;
1206 /* This function does not alter mapname */
1208 if (!mapname || !domainname || *table_mapping == NULL)
1209 return (-1);
1211 if (strchr(mapname, COMMA_CHAR))
1212 return (2);
1214 if ((map = s_strndup(mapname, strlen(mapname))) == 0)
1215 return (-1);
1217 if (getfullmapname(&map, domainname)) {
1218 free(map);
1219 return (-1);
1222 *found_map = find_table_mapping(map, strlen(map), *table_mapping);
1223 if (*found_map) {
1224 free(map);
1225 return (1);
1228 free(map);
1229 return (0);
1233 * FUNCTION: append_domainContext
1235 * Higher level function to append the domains to the appropriate
1236 * fields in a table mapping structure. Calls either getfullmapname()
1237 * or make_full_dn() to do the actual append.
1239 * RETURNS: 0 on success, -1 on any error.
1243 append_domainContext(__nis_table_mapping_t **table_map,
1244 char *DomainLabel, char *Domain)
1246 __nis_table_mapping_t *tmp_map = *table_map;
1247 char *lasts;
1248 char *tmp_dbId = NULL;
1249 char *id = NULL;
1250 int domain_specific = 0;
1251 char *myself = "append_domainContext";
1253 if (!DomainLabel || !Domain || !tmp_map)
1254 return (-1);
1255 if (tmp_map->dbId == NULL || tmp_map->objName == NULL) {
1256 p_error = parse_bad_map_error;
1257 return (-1);
1259 tmp_dbId = s_strndup(tmp_map->dbId, strlen(tmp_map->dbId));
1260 if (!tmp_dbId)
1261 return (-1);
1262 if (strchr(tmp_map->dbId, COMMA_CHAR)) {
1263 domain_specific = 1;
1264 id = (char *)strtok_r(tmp_dbId, COMMA_STRING, &lasts);
1265 if (id)
1266 id = (char *)strtok_r(NULL, COMMA_STRING, &lasts);
1267 else {
1268 free(tmp_dbId);
1269 return (-1);
1271 if (!id) {
1272 free(tmp_dbId);
1273 return (-1);
1275 if (strcasecmp(id, DomainLabel)) {
1276 free(tmp_dbId);
1277 return (0);
1279 } else {
1280 if (getfullmapname(&tmp_map->dbId, DomainLabel)) {
1281 free(tmp_dbId);
1282 return (-1);
1284 append_dot(&tmp_map->dbId);
1286 free(tmp_dbId);
1287 tmp_dbId = NULL;
1289 if (getfullmapname(&tmp_map->objName, DomainLabel))
1290 return (-1);
1291 append_dot(&tmp_map->objName);
1294 * If domain specific mapping doesn't have objectDN,
1295 * then don't touch. Most probably, pass for the generic mapping
1296 * will handle this by coping over it's own objectDN
1298 if (domain_specific && tmp_map->objectDN == NULL)
1299 return (0);
1301 if (tmp_map->objectDN == NULL) {
1302 /* Allocate memory to objectDN */
1303 tmp_map->objectDN = (__nis_object_dn_t *)
1304 s_calloc(1, sizeof (__nis_object_dn_t));
1305 if (tmp_map->objectDN == NULL) {
1306 logmsg(MSG_NOMEM, LOG_ERR,
1307 "%s: Cannot allocate memory for objectDN",
1308 myself);
1309 return (2);
1311 tmp_map->objectDN->read.base = NULL;
1312 tmp_map->objectDN->write.base = NULL;
1313 tmp_map->objectDN->read.attrs = NULL;
1314 tmp_map->objectDN->write.attrs = NULL;
1315 tmp_map->objectDN->read.scope = LDAP_SCOPE_ONELEVEL;
1316 tmp_map->objectDN->write.scope = LDAP_SCOPE_UNKNOWN;
1319 if (!make_fqdn(tmp_map->objectDN, Domain))
1320 return (-1);
1321 if (tmp_map->objectDN->write.base) {
1322 if (!make_full_dn(&tmp_map->objectDN->write.base, Domain))
1323 return (-1);
1326 return (0);