2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26
27 #include <lber.h>
28 #include <ldap.h>
29 #include <strings.h>
30
31 #include "nisdb_mt.h"
32
33 #include "ldap_util.h"
34 #include "ldap_val.h"
35 #include "ldap_attr.h"
36 #include "ldap_ldap.h"
37 #include "ldap_ruleval.h"
38
39
40 /*
41 * Free an array of 'count' rule-value elements.
92 * Return an array of 'count' __nis_rule_value_t elements, initialized
93 * to be copies of 'rvIn' if supplied; empty otherwise.
94 */
95 __nis_rule_value_t *
96 initRuleValue(int count, __nis_rule_value_t *rvIn) {
97 return (growRuleValue(0, count, 0, rvIn));
98 }
99
100 static const __nis_rule_value_t rvZero = {0};
101
102 /*
103 * Grow 'old' from 'oldCount' to 'newCount' elements, initialize the
104 * new portion to 'rvIn' (empty if not supplied), and return a pointer
105 * to the result. Following a call to this function, the caller must
106 * refer only to the returned array, not to 'old'.
107 */
108 __nis_rule_value_t *
109 growRuleValue(int oldCount, int newCount, __nis_rule_value_t *old,
110 __nis_rule_value_t *rvIn) {
111 __nis_rule_value_t *rv;
112 int i, j;
113 char *myself = "growRuleValue";
114
115 if (newCount <= 0 || newCount <= oldCount)
116 return (old);
117
118 if (oldCount <= 0) {
119 oldCount = 0;
120 old = 0;
121 }
122
123 if (rvIn == 0)
124 rvIn = (__nis_rule_value_t *)&rvZero;
125
126 rv = realloc(old, newCount * sizeof (rv[0]));
127 if (rv == 0) {
128 logmsg(MSG_NOMEM, LOG_ERR,
129 "%s: realloc(%d ((%d+%d)*%d)) => 0",
130 myself, (oldCount+newCount) * sizeof (rv[0]),
131 oldCount, newCount, sizeof (rv[0]));
132 freeRuleValue(old, oldCount);
408 return (-1);
409
410 return (addVal2RuleValue(myself, 1, 1, type, name, value, valueLen,
411 &rv->numColumns, &rv->colName, &rv->colVal));
412 }
413
414 int
415 addSCol2RuleValue(char *name, char *value, __nis_rule_value_t *rv) {
416 return (addCol2RuleValue(vt_string, name, value, slen(value), rv));
417 }
418
419 /*
420 * Given a table mapping, a NIS+ DB query, and (optionally) an existing
421 * and compatible __nis_rule_value_t, return a new __nis_rule_value_t
422 * with the values from the query added.
423 */
424 __nis_rule_value_t *
425 buildNisPlusRuleValue(__nis_table_mapping_t *t, db_query *q,
426 __nis_rule_value_t *rv) {
427 int i;
428 __nis_single_value_t *sv;
429 char *myself = "buildNisPlusRuleValue";
430
431 if (t == 0 || q == 0)
432 return (0);
433
434 rv = initRuleValue(1, rv);
435 if (rv == 0)
436 return (0);
437
438 for (i = 0; i < q->components.components_len; i++) {
439 int ic;
440 int iv, v, dup;
441 int len;
442
443 /* Ignore out-of-range column index */
444 if (q->components.components_val[i].which_index >=
445 t->numColumns)
446 continue;
447
448 /*
449 * Add the query value. A NULL value indicates deletion,
450 * but addCol2RuleValue() takes care of that for us.
451 */
452 if (addCol2RuleValue(vt_string,
453 t->column[q->components.components_val[i].
454 which_index],
455 q->components.components_val[i].index_value->
456 itemvalue.itemvalue_val,
457 q->components.components_val[i].index_value->
458 itemvalue.itemvalue_len, rv) != 0) {
459 freeRuleValue(rv, 1);
460 rv = 0;
461 break;
600 vold = val;
601 }
602 return (val);
603 }
604
605 /*
606 * Derive values for the LDAP attributes specified by the rule 'r',
607 * and add them to the rule-value 'rv'.
608 *
609 * If 'doAssign' is set, out-of-context assignments are performed,
610 * otherwise not.
611 */
612 __nis_rule_value_t *
613 addLdapRuleValue(__nis_table_mapping_t *t,
614 __nis_mapping_rule_t *r,
615 __nis_mapping_item_type_t lnative,
616 __nis_mapping_item_type_t rnative,
617 __nis_rule_value_t *rv,
618 int doAssign, int *stat) {
619 int i, j;
620 char **new;
621 __nis_value_t *rval, *lval;
622 __nis_buffer_t b = {0, 0};
623 __nis_mapping_item_t *litem;
624 int numItems;
625 char **dn = 0;
626 int numDN = 0;
627 char *myself = "addLdapRuleValue";
628
629
630 /* Do we have the required values ? */
631 if (rv == 0)
632 return (0);
633
634 /*
635 * Establish appropriate search base. For rnative == mit_nisplus,
636 * we're deriving LDAP attribute values from NIS+ columns; in other
637 * words, we're writing to LDAP, and should use the write.base value.
638 */
639 __nisdb_get_tsd()->searchBase = (rnative == mit_nisplus) ?
640 t->objectDN->write.base : t->objectDN->read.base;
641
642 /* Set escapeFlag if LHS is "dn" to escape special chars */
728 /*
729 * If we don't have an 'lval' (probably because all litem[i]:s
730 * were out-of-context assignments), we're done.
731 */
732 if (lval == 0 || lval->numVals <= 0) {
733 freeValue(lval, 1);
734 freeValue(rval, 1);
735 return (rv);
736 }
737
738 for (i = 0, j = 0; i < lval->numVals; i++) {
739 /* Special case: rval->numVals < 0 means deletion */
740 if (rval->numVals < 0) {
741 (void) addAttr2RuleValue(rval->type,
742 lval->val[i].value, 0, 0, rv);
743 continue;
744 }
745 /* If we're out of values, repeat the last one */
746 if (j >= rval->numVals)
747 j = (rval->numVals > 0) ? rval->numVals-1 : 0;
748 for (0; j < rval->numVals; j++) {
749 /*
750 * If this is the 'dn', and the value ends in a
751 * comma, append the appropriate search base.
752 */
753 if (strcasecmp("dn", lval->val[i].value) == 0 &&
754 lastChar(&rval->val[j]) == ',' &&
755 t->objectDN->write.scope !=
756 LDAP_SCOPE_UNKNOWN) {
757 void *nval;
758 int nlen = -1;
759
760 nval = appendString2SingleVal(
761 t->objectDN->write.base, &rval->val[j],
762 &nlen);
763 if (nval != 0 && nlen >= 0) {
764 sfree(rval->val[j].value);
765 rval->val[j].value = nval;
766 rval->val[j].length = nlen;
767 }
768 }
|
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
28 #include <lber.h>
29 #include <ldap.h>
30 #include <strings.h>
31
32 #include "nisdb_mt.h"
33
34 #include "ldap_util.h"
35 #include "ldap_val.h"
36 #include "ldap_attr.h"
37 #include "ldap_ldap.h"
38 #include "ldap_ruleval.h"
39
40
41 /*
42 * Free an array of 'count' rule-value elements.
93 * Return an array of 'count' __nis_rule_value_t elements, initialized
94 * to be copies of 'rvIn' if supplied; empty otherwise.
95 */
96 __nis_rule_value_t *
97 initRuleValue(int count, __nis_rule_value_t *rvIn) {
98 return (growRuleValue(0, count, 0, rvIn));
99 }
100
101 static const __nis_rule_value_t rvZero = {0};
102
103 /*
104 * Grow 'old' from 'oldCount' to 'newCount' elements, initialize the
105 * new portion to 'rvIn' (empty if not supplied), and return a pointer
106 * to the result. Following a call to this function, the caller must
107 * refer only to the returned array, not to 'old'.
108 */
109 __nis_rule_value_t *
110 growRuleValue(int oldCount, int newCount, __nis_rule_value_t *old,
111 __nis_rule_value_t *rvIn) {
112 __nis_rule_value_t *rv;
113 int i;
114 char *myself = "growRuleValue";
115
116 if (newCount <= 0 || newCount <= oldCount)
117 return (old);
118
119 if (oldCount <= 0) {
120 oldCount = 0;
121 old = 0;
122 }
123
124 if (rvIn == 0)
125 rvIn = (__nis_rule_value_t *)&rvZero;
126
127 rv = realloc(old, newCount * sizeof (rv[0]));
128 if (rv == 0) {
129 logmsg(MSG_NOMEM, LOG_ERR,
130 "%s: realloc(%d ((%d+%d)*%d)) => 0",
131 myself, (oldCount+newCount) * sizeof (rv[0]),
132 oldCount, newCount, sizeof (rv[0]));
133 freeRuleValue(old, oldCount);
409 return (-1);
410
411 return (addVal2RuleValue(myself, 1, 1, type, name, value, valueLen,
412 &rv->numColumns, &rv->colName, &rv->colVal));
413 }
414
415 int
416 addSCol2RuleValue(char *name, char *value, __nis_rule_value_t *rv) {
417 return (addCol2RuleValue(vt_string, name, value, slen(value), rv));
418 }
419
420 /*
421 * Given a table mapping, a NIS+ DB query, and (optionally) an existing
422 * and compatible __nis_rule_value_t, return a new __nis_rule_value_t
423 * with the values from the query added.
424 */
425 __nis_rule_value_t *
426 buildNisPlusRuleValue(__nis_table_mapping_t *t, db_query *q,
427 __nis_rule_value_t *rv) {
428 int i;
429
430 if (t == 0 || q == 0)
431 return (0);
432
433 rv = initRuleValue(1, rv);
434 if (rv == 0)
435 return (0);
436
437 for (i = 0; i < q->components.components_len; i++) {
438
439 /* Ignore out-of-range column index */
440 if (q->components.components_val[i].which_index >=
441 t->numColumns)
442 continue;
443
444 /*
445 * Add the query value. A NULL value indicates deletion,
446 * but addCol2RuleValue() takes care of that for us.
447 */
448 if (addCol2RuleValue(vt_string,
449 t->column[q->components.components_val[i].
450 which_index],
451 q->components.components_val[i].index_value->
452 itemvalue.itemvalue_val,
453 q->components.components_val[i].index_value->
454 itemvalue.itemvalue_len, rv) != 0) {
455 freeRuleValue(rv, 1);
456 rv = 0;
457 break;
596 vold = val;
597 }
598 return (val);
599 }
600
601 /*
602 * Derive values for the LDAP attributes specified by the rule 'r',
603 * and add them to the rule-value 'rv'.
604 *
605 * If 'doAssign' is set, out-of-context assignments are performed,
606 * otherwise not.
607 */
608 __nis_rule_value_t *
609 addLdapRuleValue(__nis_table_mapping_t *t,
610 __nis_mapping_rule_t *r,
611 __nis_mapping_item_type_t lnative,
612 __nis_mapping_item_type_t rnative,
613 __nis_rule_value_t *rv,
614 int doAssign, int *stat) {
615 int i, j;
616 __nis_value_t *rval, *lval;
617 __nis_mapping_item_t *litem;
618 int numItems;
619 char **dn = 0;
620 int numDN = 0;
621 char *myself = "addLdapRuleValue";
622
623
624 /* Do we have the required values ? */
625 if (rv == 0)
626 return (0);
627
628 /*
629 * Establish appropriate search base. For rnative == mit_nisplus,
630 * we're deriving LDAP attribute values from NIS+ columns; in other
631 * words, we're writing to LDAP, and should use the write.base value.
632 */
633 __nisdb_get_tsd()->searchBase = (rnative == mit_nisplus) ?
634 t->objectDN->write.base : t->objectDN->read.base;
635
636 /* Set escapeFlag if LHS is "dn" to escape special chars */
722 /*
723 * If we don't have an 'lval' (probably because all litem[i]:s
724 * were out-of-context assignments), we're done.
725 */
726 if (lval == 0 || lval->numVals <= 0) {
727 freeValue(lval, 1);
728 freeValue(rval, 1);
729 return (rv);
730 }
731
732 for (i = 0, j = 0; i < lval->numVals; i++) {
733 /* Special case: rval->numVals < 0 means deletion */
734 if (rval->numVals < 0) {
735 (void) addAttr2RuleValue(rval->type,
736 lval->val[i].value, 0, 0, rv);
737 continue;
738 }
739 /* If we're out of values, repeat the last one */
740 if (j >= rval->numVals)
741 j = (rval->numVals > 0) ? rval->numVals-1 : 0;
742 for (; j < rval->numVals; j++) {
743 /*
744 * If this is the 'dn', and the value ends in a
745 * comma, append the appropriate search base.
746 */
747 if (strcasecmp("dn", lval->val[i].value) == 0 &&
748 lastChar(&rval->val[j]) == ',' &&
749 t->objectDN->write.scope !=
750 LDAP_SCOPE_UNKNOWN) {
751 void *nval;
752 int nlen = -1;
753
754 nval = appendString2SingleVal(
755 t->objectDN->write.base, &rval->val[j],
756 &nlen);
757 if (nval != 0 && nlen >= 0) {
758 sfree(rval->val[j].value);
759 rval->val[j].value = nval;
760 rval->val[j].length = nlen;
761 }
762 }
|