5910 libnisdb won't build with modern GCC
[unleashed.git] / usr / src / lib / libnisdb / nis_parse_ldap_yp_util.c
blobced92d8efae4d8aaeeb61144a89b6b94f5235f05
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 if (tobj)
554 free(tobj);
556 if (alias ||
557 (objName = s_strdup(t->objName))
558 == NULL) {
559 if (i)
560 logmsg(MSG_NOTIMECHECK,
561 LOG_ERR,
562 "%s: getfullmapname failed for %s for domain \"%s\"",
563 myself, dupalias,
564 dom);
565 else {
566 p_error =
567 parse_no_mem_error;
568 logmsg(MSG_NOMEM,
569 LOG_ERR,
570 "%s: Cannot allocate memory",
571 myself);
573 if (dupalias)
574 free(dupalias);
575 if (t->objName)
576 free(t->objName);
577 return (2);
580 objs = (char *)strtok_r(objName, " ",
581 &lasts);
586 if (tg != NULL) {
587 if (merge_table_mapping(tg, t)) {
588 logmsg(MSG_NOTIMECHECK, LOG_ERR,
589 "Error merging information from the %s to the %s mapping structure",
590 tg->dbId, t->dbId);
591 objs = NULL;
592 if (objName)
593 free(objName);
594 return (1);
599 * If objName is "map1 map2" then do the second pass.
600 * If it is just "map1" however skip the expansion.
601 * Also skip it if t->objName is null.
603 if (objs && strncasecmp(objs, t->objName,
604 strlen(t->objName))) {
605 t2 = find_table_mapping(objs, strlen(objs),
606 *table_mapping);
607 if (t2) {
608 if (merge_table_mapping(t, t2)) {
609 logmsg(MSG_NOTIMECHECK, LOG_ERR,
610 "Error merging information from the %s to the %s mapping structure",
611 t->dbId, t2->dbId);
612 objs = NULL;
613 if (objName)
614 free(objName);
615 return (1);
617 t->isMaster = 1;
618 } else {
619 t_new = new_merged_mapping(objs, t);
620 if (t_new) {
621 t->isMaster = 1;
622 if (prev != NULL)
623 prev->next = t_new;
624 else
625 *table_mapping = t_new;
626 prev = t_new;
627 prev->next = t;
628 } else {
629 logmsg(MSG_NOTIMECHECK, LOG_ERR,
630 "Error creating a new mapping structure %s",
631 objs);
632 objs = NULL;
633 if (objName)
634 free(objName);
635 return (1);
638 while ((objs = (char *)strtok_r(NULL, " ", &lasts))
639 != NULL) {
640 t2 = find_table_mapping(objs, strlen(objs),
641 *table_mapping);
642 if (t2) {
643 if (merge_table_mapping(t, t2)) {
644 logmsg(MSG_NOTIMECHECK, LOG_ERR,
645 "Error merging information from the %s to the %s mapping structure",
646 t->dbId, t2->dbId);
647 objs = NULL;
648 if (objName)
649 free(objName);
650 return (1);
652 t->isMaster = 1;
653 } else {
655 * create a new t_map with dbId = objs
656 * and copy t->* into new t_map
658 t_new = new_merged_mapping(objs, t);
659 if (t_new) {
660 t->isMaster = 1;
661 if (prev != NULL)
662 prev->next = t_new;
663 else
664 *table_mapping = t_new;
665 prev = t_new;
666 prev->next = t;
667 } else {
668 logmsg(MSG_NOTIMECHECK, LOG_ERR,
669 "Error creating a new mapping structure %s",
670 objs);
671 objs = NULL;
672 if (objName)
673 free(objName);
674 return (1);
678 } /* if objs!= NULL */
680 prev = t;
681 t = t->next;
683 if (objName) {
684 free(objName);
685 objName = NULL;
686 objs = NULL;
688 } /* for t = table_mapping loop */
689 return (0);
692 __nis_table_mapping_t *
693 new_merged_mapping(const char *match,
694 __nis_table_mapping_t *intbl)
697 __nis_table_mapping_t *outtable = NULL;
699 outtable = (__nis_table_mapping_t *)
700 s_calloc(1, sizeof (__nis_table_mapping_t));
701 if (outtable == NULL)
702 return (NULL);
703 initialize_table_mapping(outtable);
704 outtable->dbId = s_strndup(match, strlen(match));
705 if (outtable->dbId == NULL) {
706 free_table_mapping(outtable);
707 outtable = NULL;
708 return (NULL);
710 if (merge_table_mapping(intbl, outtable)) {
711 free_table_mapping(outtable);
712 outtable = NULL;
714 return (outtable);
718 * FUNCTION: final_parser_pass
720 * completes the final expansion of t_map structures linked list.
721 * all structures will have a non-null objPath as well as a objName
722 * in the form of "mapname . domainname ." or "splitfieldname .
723 * domainname .".
725 * RETURN VALUE: 0 on success, -1 on failure, -2 on fatal error.
728 final_parser_pass(
729 __nis_table_mapping_t **table_mapping,
730 __yp_domain_context_t *ypDomains)
732 __nis_table_mapping_t *t;
733 __nis_table_mapping_t *t1, *returned_map;
734 __nis_table_mapping_t *prev = NULL;
735 int i;
736 char *myself = "final_parser_pass";
737 int nm;
738 bool_t r;
739 int del_tbl_flag = 0;
741 if (ypDomains) {
742 if (!ypDomains->numDomains) {
743 p_error = parse_internal_error;
744 logmsg(MSG_NOTIMECHECK, LOG_ERR,
745 "%s:No domains specified.", myself);
746 return (-1);
748 } else {
749 p_error = parse_internal_error;
750 logmsg(MSG_NOTIMECHECK, LOG_ERR,
751 "%s:No domain structure supplied.", myself);
752 return (-1);
754 prev = NULL;
756 for (t = *table_mapping; t != NULL; ) {
758 /* Delete if marked for deletion by second_parser_pass */
759 if (t->isMaster == 1) {
760 if (prev != NULL)
761 prev->next = t->next;
762 else
763 *table_mapping = t->next;
764 t1 = t;
765 t = t->next;
766 free_table_mapping(t1);
767 continue;
770 if (!t->objName && t->dbId) {
771 t->objName = s_strndup(t->dbId, strlen(t->dbId));
772 if (!t->objName) {
773 logmsg(MSG_NOMEM, LOG_ERR,
774 "%s:Could not allocate.", myself);
775 return (-1);
778 i = ypDomains->numDomains;
779 while (i > 0) {
780 if (i == 1) {
781 /* modify existing table_mapping's */
782 nm = checkfullmapname(t->dbId,
783 ypDomains->domainLabels[0],
784 table_mapping, &returned_map);
785 if (nm == 1) {
786 /* delete this mapping structure */
787 logmsg(MSG_NOTIMECHECK,
788 LOG_WARNING,
789 "Mapping structure %s,%s "
790 "already exists.",
791 t->dbId,
792 ypDomains->domainLabels[0]);
793 if (merge_table_mapping(t,
794 returned_map)) {
795 logmsg(MSG_NOTIMECHECK, LOG_ERR,
796 "Error merging information "
797 "from the %s to the %s "
798 "mapping structure.",
799 t->dbId,
800 returned_map->dbId);
801 return (-1);
803 if (del_tbl_flag == 0)
804 del_tbl_flag = 1;
805 } else if (nm == -1) {
806 logmsg(MSG_NOTIMECHECK, LOG_ERR,
807 "Error searching for %s,%s structure",
808 t->dbId,
809 ypDomains->domainLabels[0]);
810 return (-1);
811 } else if (nm == 0 || nm == 2) {
812 if ((append_domainContext(&t,
813 ypDomains->domainLabels[0],
814 ypDomains->domains[0])) != 0) {
815 logmsg(MSG_NOTIMECHECK, LOG_ERR,
816 "Error appending domainContext %s",
817 ypDomains->domainLabels[0]);
818 return (-1);
820 del_tbl_flag = 0;
822 } else { /* if (i > 1) */
823 /* need to create new table_mapping's */
824 nm = checkfullmapname(t->dbId,
825 ypDomains->domainLabels[i - 1],
826 table_mapping, &returned_map);
827 if (nm == -1) {
828 logmsg(MSG_NOTIMECHECK, LOG_ERR,
829 "Error searching for %s,%s structure",
830 t->dbId,
831 ypDomains->domainLabels[i - 1]);
832 return (-1);
833 } else if (nm == 0) {
834 t1 = new_merged_mapping(t->dbId, t);
835 /* we clone ourselves */
836 if (t1) {
837 if ((append_domainContext(&t1,
838 ypDomains->domainLabels[i - 1],
839 ypDomains->domains[i - 1])) != 0) {
840 logmsg(MSG_NOTIMECHECK, LOG_ERR,
841 "Error appending domainContext %s",
842 ypDomains->domainLabels[i - 1]);
843 free(t1);
844 return (-1);
846 if (prev != NULL) {
847 t1->next = prev->next;
848 prev->next = t1;
849 prev = prev->next;
850 } else {
851 t1->next =
852 *table_mapping;
853 *table_mapping = t1;
854 prev = t1;
856 } else { /* if !t1 */
857 p_error = parse_internal_error;
858 logmsg(MSG_NOTIMECHECK, LOG_ERR,
859 "%s:Could not create new table -"
860 " check all instances of %s for errors",
861 myself, t->dbId);
862 return (-1);
864 } else if (nm == 1) {
865 logmsg(MSG_NOTIMECHECK, LOG_WARNING,
866 "Mapping structure %s,%s already exists.",
867 t->dbId,
868 ypDomains->domainLabels[i - 1]);
870 * We should be deleting this, but can't
871 * really do it here, because we need to
872 * match with the domainLabels[0] case
873 * too. So we will just flag it for now.
875 if (merge_table_mapping(t,
876 returned_map)) {
877 logmsg(MSG_NOTIMECHECK, LOG_ERR,
878 "Error merging information from the %s to the %s mapping structure.",
879 t->dbId,
880 returned_map->dbId);
881 return (-1);
883 del_tbl_flag = 1;
884 } else if (nm == 2) {
885 if ((append_domainContext(&t,
886 ypDomains->domainLabels[i - 1],
887 ypDomains->domains[i - 1])) != 0) {
888 logmsg(MSG_NOTIMECHECK, LOG_ERR,
889 "Error appending domainContext %s",
890 ypDomains->domainLabels[i - 1]);
891 return (-1);
893 } /* end of "if (nm == 0)" */
894 } /* end of else if (i > 1) */
898 * 'merge_table_mapping' only copies unexpanded
899 * objectDN values into returned_map. Hence,
900 * read.base and write.base in returned_map
901 * needs to be expanded.
903 if (nm == 1 && returned_map && returned_map->objectDN) {
904 r = make_fqdn(
905 returned_map->objectDN,
906 ypDomains->domains[i - 1]);
907 if (r == TRUE &&
908 returned_map->objectDN->write.base) {
909 r = make_full_dn(
910 &returned_map->objectDN->write.base,
911 ypDomains->domains[i - 1]);
914 if (r == FALSE) {
915 logmsg(MSG_NOTIMECHECK, LOG_ERR,
916 "Error appending domainContext "
917 "%s to %s",
918 ypDomains->domainLabels[i - 1],
919 returned_map->dbId);
920 return (-2);
923 i--;
924 } /* end of while i > 0 loop */
926 if (del_tbl_flag == 1) {
927 if (prev != NULL) {
928 prev->next = t->next;
929 free_table_mapping(t);
930 t = prev->next;
931 } else {
932 *table_mapping = t->next;
933 free_table_mapping(t);
934 t = *table_mapping;
936 del_tbl_flag = 0;
937 } else {
938 prev = t;
939 t = t->next;
941 } /* end of table mapping loop */
943 for (t = *table_mapping; t != NULL; t = t->next) {
944 if (!t->dbId) {
945 logmsg(MSG_NOTIMECHECK, LOG_ERR,
946 "%s:Fatal error: structure with no dbId found.",
947 myself);
948 return (-2);
950 append_dot(&t->dbId);
951 if (!t->objectDN) {
952 p_error = parse_internal_error;
953 logmsg(MSG_NOTIMECHECK, LOG_ERR,
954 "%s:No objectDN for %s.", myself, t->dbId);
955 return (-1);
959 return (0);
963 * FUNCTION: append_mapping_rule
965 * Appends mapping rules to a table_mapping structure
966 * with previously existing rules. flag controls whether
967 * the functions works on the rules From or To LDAP.
969 * RETURN VALUE: 0 on success, >= 1 on failure.
972 static int
973 append_mapping_rule(__nis_mapping_rule_t *src_rule,
974 __nis_table_mapping_t *dst, int flag)
976 __nis_mapping_rule_t **rules = NULL;
978 if (flag == 0) {
979 if (dst->ruleFromLDAP == NULL) {
980 p_error = parse_internal_error;
981 return (1);
983 rules = (__nis_mapping_rule_t **)
984 s_realloc(dst->ruleFromLDAP,
985 (dst->numRulesFromLDAP + 1) *
986 sizeof (__nis_mapping_rule_t *));
987 if (rules == NULL)
988 return (2);
989 dst->ruleFromLDAP = rules;
990 rules[dst->numRulesFromLDAP] = dup_mapping_rule(src_rule);
991 if (rules[dst->numRulesFromLDAP] == NULL) {
992 p_error = parse_no_mem_error;
993 return (2);
995 dst->numRulesFromLDAP++;
996 } else if (flag == 1) {
997 if (dst->ruleToLDAP == NULL) {
998 p_error = parse_internal_error;
999 return (1);
1001 rules = (__nis_mapping_rule_t **)
1002 s_realloc(dst->ruleToLDAP,
1003 (dst->numRulesToLDAP + 1) *
1004 sizeof (__nis_mapping_rule_t *));
1005 if (rules == NULL)
1006 return (2);
1007 dst->ruleToLDAP = rules;
1008 rules[dst->numRulesToLDAP] = dup_mapping_rule(src_rule);
1009 if (rules[dst->numRulesToLDAP] == NULL) {
1010 p_error = parse_no_mem_error;
1011 return (2);
1013 dst->numRulesToLDAP++;
1014 } else
1015 return (1);
1017 return (0);
1021 * FUNCTION: check_domain_specific_order
1023 * Makes sure that an attribute with explicitly specified
1024 * nisLDAPdomainContext is found before its non-domain
1025 * specific counterpart.
1027 * RETURN VALUE: 0 normal exit
1028 * 1 if domain specific attribute found
1029 * after non-domain specific one.
1030 * -1 some error condition
1034 check_domain_specific_order(const char *sd,
1035 config_key attrib_num,
1036 __nis_table_mapping_t *table_mapping,
1037 __yp_domain_context_t *ypDomains)
1039 __nis_table_mapping_t *t;
1040 char *myself = "check_domain_specific_order";
1041 char *type;
1042 char *dbId = 0;
1043 int i, len;
1044 int match = 0;
1046 if (ypDomains) {
1047 if (!ypDomains->numDomains) {
1048 logmsg(MSG_NOTIMECHECK, LOG_ERR,
1049 "%s:No domains specified.", myself);
1050 return (-1);
1052 } else {
1053 logmsg(MSG_NOTIMECHECK, LOG_ERR,
1054 "%s:No domain structure supplied.", myself);
1055 return (-1);
1058 for (i = 0; i < ypDomains->numDomains; i++) {
1059 for (t = table_mapping; t != NULL; t = t->next) {
1060 len = strlen(sd);
1061 if ((strcasecmp(t->dbId, sd) == 0) && (len ==
1062 strlen(t->dbId)))
1063 /* prevent from matching against itself */
1064 continue;
1065 dbId = s_strndup(t->dbId, strlen(t->dbId));
1066 if (dbId == NULL) {
1067 logmsg(MSG_NOMEM, LOG_ERR,
1068 "%s:Memory allocation error.", myself);
1069 return (-1);
1072 if (getfullmapname(&dbId,
1073 ypDomains->domainLabels[i])) {
1074 logmsg(MSG_NOTIMECHECK, LOG_ERR,
1075 "Error getting fully qualified name for %s",
1076 dbId);
1077 free(dbId);
1078 return (-1);
1080 if ((strcasecmp(dbId, sd) == 0) && (len ==
1081 strlen(dbId))) {
1082 match = 0;
1083 switch (attrib_num) {
1084 case key_yp_map_flags:
1085 if (t->usedns_flag != 0 ||
1086 t->securemap_flag != 0)
1087 match = 1;
1088 type = YP_MAP_FLAGS;
1089 break;
1090 case key_yp_comment_char:
1091 if (t->commentChar !=
1092 DEFAULT_COMMENT_CHAR)
1093 match = 1;
1094 type = YP_COMMENT_CHAR;
1095 break;
1096 case key_yp_repeated_field_separators:
1097 if (strcmp(t->separatorStr,
1098 DEFAULT_SEP_STRING) != 0)
1099 match = 1;
1100 type =
1101 YP_REPEATED_FIELD_SEPARATORS;
1102 break;
1103 case key_yp_name_fields:
1104 if (t->e && t->numColumns)
1105 match = 1;
1106 type = YP_NAME_FIELDS;
1107 case key_yp_split_field:
1108 if (t->e && t->numColumns)
1109 match = 1;
1110 type = YP_SPLIT_FIELD;
1111 break;
1112 case key_yp_db_id_map:
1113 if (t->objName)
1114 match = 1;
1115 type = YP_DB_ID_MAP;
1116 break;
1117 case key_yp_entry_ttl:
1118 if (t->initTtlLo !=
1119 (time_t)NO_VALUE_SET)
1120 match = 1;
1121 type = YP_ENTRY_TTL;
1122 break;
1123 case key_yp_ldap_object_dn:
1124 if (t->objectDN)
1125 match = 1;
1126 type = YP_LDAP_OBJECT_DN;
1127 break;
1128 case key_nis_to_ldap_map:
1129 if (t->ruleToLDAP)
1130 match = 1;
1131 type = NIS_TO_LDAP_MAP;
1132 break;
1133 case key_ldap_to_nis_map:
1134 if (t->ruleFromLDAP)
1135 match = 1;
1136 type = LDAP_TO_NIS_MAP;
1137 break;
1138 default:
1139 type = "unknown";
1140 match = 0;
1141 break;
1142 } /* end of switch */
1143 if (match) {
1144 logmsg(MSG_NOTIMECHECK, LOG_ERR,
1145 "Relative attribute '%s' of type '%s' found before fully qualified one '%s'",
1146 t->dbId, type, sd);
1147 free(dbId);
1148 dbId = NULL;
1149 return (1);
1151 } /* end of strncasecmp */
1152 free(dbId);
1153 dbId = NULL;
1154 } /* end of t loop */
1155 } /* end of i loop */
1156 if (dbId)
1157 free(dbId);
1158 dbId = NULL;
1159 return (0);
1163 getfullmapname(char **mapname, const char *domainname)
1165 char *maps = *mapname;
1166 int maplen = strlen(maps);
1167 int domainlen = strlen(domainname);
1169 if (!maplen || !domainlen ||
1170 maps[maplen - 1] == PERIOD_CHAR)
1171 return (1);
1172 else if (strchr(maps, COMMA_CHAR)) {
1173 /* map already has a domain part, do nothing */
1174 return (0);
1175 } else {
1176 append_comma(&maps);
1177 maplen = strlen(maps);
1178 maps = realloc(maps, (maplen + domainlen + 1));
1179 if (maps != NULL) {
1180 if (strlcat(maps, domainname, (maplen + domainlen + 1))
1181 >= (maplen + domainlen + 1))
1182 return (1);
1183 *mapname = maps;
1184 return (0);
1185 } else
1186 return (1);
1191 * FUNCTION: checkfullmapname
1193 * Tries to find out if by appending the table mapping structures
1194 * with each of the provided nisLDAPdomainContexts, an already
1195 * existing fqdn table mapping structure results. That would be the
1196 * case when a full qualified domain specific attribute was present.
1198 * Note that per NISLDAPmapping(4) such an attribute MUST be listed
1199 * in the mapping file BEFORE its non-fqdn counterpart.
1201 * RETURNS: 0 normal exit, 1 if an existing structure found, -1 for all
1202 * errors, 2 if already fqdn. If returning 1 the existing structure is
1203 * in found_map.
1207 checkfullmapname(const char *mapname, const char *domainname,
1208 __nis_table_mapping_t **table_mapping,
1209 __nis_table_mapping_t **found_map)
1211 char *map;
1213 *found_map = NULL;
1215 /* This function does not alter mapname */
1217 if (!mapname || !domainname || *table_mapping == NULL)
1218 return (-1);
1220 if (strchr(mapname, COMMA_CHAR))
1221 return (2);
1223 if ((map = s_strndup(mapname, strlen(mapname))) == 0)
1224 return (-1);
1226 if (getfullmapname(&map, domainname)) {
1227 free(map);
1228 return (-1);
1231 *found_map = find_table_mapping(map, strlen(map), *table_mapping);
1232 if (*found_map) {
1233 free(map);
1234 return (1);
1237 free(map);
1238 return (0);
1242 * FUNCTION: append_domainContext
1244 * Higher level function to append the domains to the appropriate
1245 * fields in a table mapping structure. Calls either getfullmapname()
1246 * or make_full_dn() to do the actual append.
1248 * RETURNS: 0 on success, -1 on any error.
1252 append_domainContext(__nis_table_mapping_t **table_map,
1253 char *DomainLabel, char *Domain)
1255 __nis_table_mapping_t *tmp_map = *table_map;
1256 char *lasts;
1257 char *tmp_dbId = NULL;
1258 char *id = NULL;
1259 int domain_specific = 0;
1260 char *myself = "append_domainContext";
1262 if (!DomainLabel || !Domain || !tmp_map)
1263 return (-1);
1264 if (tmp_map->dbId == NULL || tmp_map->objName == NULL) {
1265 p_error = parse_bad_map_error;
1266 return (-1);
1268 tmp_dbId = s_strndup(tmp_map->dbId, strlen(tmp_map->dbId));
1269 if (!tmp_dbId)
1270 return (-1);
1271 if (strchr(tmp_map->dbId, COMMA_CHAR)) {
1272 domain_specific = 1;
1273 id = (char *)strtok_r(tmp_dbId, COMMA_STRING, &lasts);
1274 if (id)
1275 id = (char *)strtok_r(NULL, COMMA_STRING, &lasts);
1276 else {
1277 free(tmp_dbId);
1278 return (-1);
1280 if (!id) {
1281 free(tmp_dbId);
1282 return (-1);
1284 if (strcasecmp(id, DomainLabel)) {
1285 free(tmp_dbId);
1286 return (0);
1288 } else {
1289 if (getfullmapname(&tmp_map->dbId, DomainLabel)) {
1290 free(tmp_dbId);
1291 return (-1);
1293 append_dot(&tmp_map->dbId);
1295 if (tmp_dbId)
1296 free(tmp_dbId);
1297 tmp_dbId = NULL;
1299 if (getfullmapname(&tmp_map->objName, DomainLabel))
1300 return (-1);
1301 append_dot(&tmp_map->objName);
1304 * If domain specific mapping doesn't have objectDN,
1305 * then don't touch. Most probably, pass for the generic mapping
1306 * will handle this by coping over it's own objectDN
1308 if (domain_specific && tmp_map->objectDN == NULL)
1309 return (0);
1311 if (tmp_map->objectDN == NULL) {
1312 /* Allocate memory to objectDN */
1313 tmp_map->objectDN = (__nis_object_dn_t *)
1314 s_calloc(1, sizeof (__nis_object_dn_t));
1315 if (tmp_map->objectDN == NULL) {
1316 logmsg(MSG_NOMEM, LOG_ERR,
1317 "%s: Cannot allocate memory for objectDN",
1318 myself);
1319 return (2);
1321 tmp_map->objectDN->read.base = NULL;
1322 tmp_map->objectDN->write.base = NULL;
1323 tmp_map->objectDN->read.attrs = NULL;
1324 tmp_map->objectDN->write.attrs = NULL;
1325 tmp_map->objectDN->read.scope = LDAP_SCOPE_ONELEVEL;
1326 tmp_map->objectDN->write.scope = LDAP_SCOPE_UNKNOWN;
1329 if (!make_fqdn(tmp_map->objectDN, Domain))
1330 return (-1);
1331 if (tmp_map->objectDN->write.base) {
1332 if (!make_full_dn(&tmp_map->objectDN->write.base, Domain))
1333 return (-1);
1336 return (0);