4 Copyright (C) Simo Sorce 2005
6 ** NOTE! The following LGPL license applies to the ldb
7 ** library. This does NOT imply that all of Samba is released
10 This library is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Lesser General Public
12 License as published by the Free Software Foundation; either
13 version 2 of the License, or (at your option) any later version.
15 This library is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Lesser General Public License for more details.
20 You should have received a copy of the GNU Lesser General Public
21 License along with this library; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 * Component: ldb dn creation and manipulation utility functions
30 * Description: - explode a dn into it's own basic elements
31 * and put them in a structure (only if necessary)
32 * - manipulate ldb_dn structures
38 #include "ldb_includes.h"
40 #define LDB_DN_NULL_FAILED(x) if (!(x)) goto failed
42 #define LDB_FREE(x) do { talloc_free(x); x = NULL; } while(0)
45 internal ldb exploded dn structures
47 struct ldb_dn_component {
53 struct ldb_val cf_value;
58 struct ldb_context *ldb;
60 /* Special DNs are always linearized */
69 unsigned int comp_num;
70 struct ldb_dn_component *components;
74 /* strdn may be NULL */
75 struct ldb_dn *ldb_dn_new(void *mem_ctx, struct ldb_context *ldb, const char *strdn)
79 if ( (! mem_ctx) || (! ldb)) return NULL;
81 dn = talloc_zero(mem_ctx, struct ldb_dn);
82 LDB_DN_NULL_FAILED(dn);
87 if (strdn[0] == '@') {
90 if (strncasecmp(strdn, "<GUID=", 6) == 0) {
91 /* this is special DN returned when the
92 * exploded_dn control is used */
94 /* FIXME: add a GUID string to ldb_dn structure */
95 } else if (strncasecmp(strdn, "<SID=", 8) == 0) {
96 /* this is special DN returned when the
97 * exploded_dn control is used */
99 /* FIXME: add a SID string to ldb_dn structure */
100 } else if (strncasecmp(strdn, "<WKGUID=", 8) == 0) {
101 /* this is special DN returned when the
102 * exploded_dn control is used */
104 /* FIXME: add a WKGUID string to ldb_dn structure */
106 dn->linearized = talloc_strdup(dn, strdn);
108 dn->linearized = talloc_strdup(dn, "");
110 LDB_DN_NULL_FAILED(dn->linearized);
119 struct ldb_dn *ldb_dn_new_fmt(void *mem_ctx, struct ldb_context *ldb, const char *new_fmt, ...)
125 if ( (! mem_ctx) || (! ldb)) return NULL;
127 dn = talloc_zero(mem_ctx, struct ldb_dn);
128 LDB_DN_NULL_FAILED(dn);
132 va_start(ap, new_fmt);
133 strdn = talloc_vasprintf(dn, new_fmt, ap);
135 LDB_DN_NULL_FAILED(strdn);
137 if (strdn[0] == '@') {
140 if (strncasecmp(strdn, "<GUID=", 6) == 0) {
141 /* this is special DN returned when the
142 * exploded_dn control is used */
144 /* FIXME: add a GUID string to ldb_dn structure */
145 } else if (strncasecmp(strdn, "<SID=", 8) == 0) {
146 /* this is special DN returned when the
147 * exploded_dn control is used */
149 /* FIXME: add a SID string to ldb_dn structure */
150 } else if (strncasecmp(strdn, "<WKGUID=", 8) == 0) {
151 /* this is special DN returned when the
152 * exploded_dn control is used */
154 /* FIXME: add a WKGUID string to ldb_dn structure */
156 dn->linearized = strdn;
165 static int ldb_dn_escape_internal(char *dst, const char *src, int len)
174 while (p - src < len) {
176 p += strcspn(p, ",=\n+<>#;\\\"");
178 if (p - src == len) /* found no escapable chars */
181 memcpy(d, s, p - s); /* copy the part of the string before the stop */
182 d += (p - s); /* move to current position */
184 if (*p) { /* it is a normal escapable character */
187 } else { /* we have a zero byte in the string */
188 strncpy(d, "\00", 3); /* escape the zero */
190 p++; /* skip the zero */
192 s = p; /* move forward */
195 /* copy the last part (with zero) and return */
199 /* return the length of the resulting string */
200 return (l + (d - dst));
203 char *ldb_dn_escape_value(void *mem_ctx, struct ldb_val value)
210 /* allocate destination string, it will be at most 3 times the source */
211 dst = talloc_array(mem_ctx, char, value.length * 3 + 1);
217 ldb_dn_escape_internal(dst, (const char *)value.data, value.length);
219 dst = talloc_realloc(mem_ctx, dst, char, strlen(dst) + 1);
225 explode a DN string into a ldb_dn structure
226 based on RFC4514 except that we don't support multiple valued RDNs
228 static bool ldb_dn_explode(struct ldb_dn *dn)
230 char *p, *data, *d, *dt, *t;
232 bool in_attr = false;
233 bool in_value = false;
234 bool in_quote = false;
240 if ( ! dn || dn->invalid) return false;
242 if (dn->components) {
246 if ( ! dn->linearized) {
251 if (dn->linearized[0] == '\0') {
255 /* Special DNs case */
260 /* make sure we free this if alloced previously before replacing */
261 talloc_free(dn->components);
263 /* in the common case we have 3 or more components */
264 /* make sure all components are zeroed, other functions depend on this */
265 dn->components = talloc_zero_array(dn, struct ldb_dn_component, 3);
266 if ( ! dn->components) {
271 /* Components data space is allocated here once */
272 data = talloc_array(dn->components, char, strlen(dn->linearized) + 1);
298 if ( ! isalpha(*p)) {
299 /* not a digit nor an alpha, invalid attribute name */
310 /* valid only if we are at the end */
315 if (trim && (*p != '=')) {
316 /* spaces/tabs are not allowed in attribute names */
322 /* attribute terminated */
329 dn->components[dn->comp_num].name = talloc_strdup(dn->components, dt);
330 if ( ! dn->components[dn->comp_num].name) {
341 if (is_oid && ( ! (isdigit(*p) || (*p == '.')))) {
342 /* not a digit nor a dot, invalid attribute oid */
346 if ( ! (isalpha(*p) || isdigit(*p) || (*p == '-'))) {
347 /* not ALPHA, DIGIT or HYPHEN */
388 /* TODO: support ber encoded values
399 /* ok found value terminator */
413 dn->components[dn->comp_num].value.data = (uint8_t *)talloc_strdup(dn->components, dt);
414 dn->components[dn->comp_num].value.length = l;
415 if ( ! dn->components[dn->comp_num].value.data) {
423 if (dn->comp_num > 2) {
424 dn->components = talloc_realloc(dn,
426 struct ldb_dn_component,
428 if ( ! dn->components) {
432 /* make sure all components are zeroed, other functions depend on this */
433 memset(&dn->components[dn->comp_num], '\0', sizeof(struct ldb_dn_component));
446 /* a string with not escaped specials is invalid (tested) */
475 if (sscanf(p, "%02x", &x) != 1) {
476 /* invalid escaping sequence */
483 *d++ = (unsigned char)x;
505 if (in_attr || in_quote) {
511 /* save last element */
519 dn->components[dn->comp_num].value.data = (uint8_t *)talloc_strdup(dn->components, dt);
520 dn->components[dn->comp_num].value.length = l;
522 if ( ! dn->components[dn->comp_num].value.data) {
534 talloc_free(dn->components);
538 bool ldb_dn_validate(struct ldb_dn *dn)
540 return ldb_dn_explode(dn);
543 const char *ldb_dn_get_linearized(struct ldb_dn *dn)
548 if ( ! dn || ( dn->invalid)) return NULL;
550 if (dn->linearized) return dn->linearized;
552 if ( ! dn->components) {
557 if (dn->comp_num == 0) {
558 dn->linearized = talloc_strdup(dn, "");
559 if ( ! dn->linearized) return NULL;
560 return dn->linearized;
563 /* calculate maximum possible length of DN */
564 for (len = 0, i = 0; i < dn->comp_num; i++) {
565 len += strlen(dn->components[i].name); /* name len */
566 len += (dn->components[i].value.length * 3); /* max escaped data len */
567 len += 2; /* '=' and ',' */
569 dn->linearized = talloc_array(dn, char, len);
570 if ( ! dn->linearized) return NULL;
574 for (i = 0; i < dn->comp_num; i++) {
577 n = dn->components[i].name;
578 while (*n) *d++ = *n++;
583 d += ldb_dn_escape_internal( d,
584 (char *)dn->components[i].value.data,
585 dn->components[i].value.length);
591 /* don't waste more memory than necessary */
592 dn->linearized = talloc_realloc(dn, dn->linearized, char, (d - dn->linearized + 1));
594 return dn->linearized;
597 char *ldb_dn_alloc_linearized(void *mem_ctx, struct ldb_dn *dn)
599 return talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn));
603 casefold a dn. We need to casefold the attribute names, and canonicalize
604 attribute values of case insensitive attributes.
607 static bool ldb_dn_casefold_internal(struct ldb_dn *dn)
611 if ( ! dn || dn->invalid) return false;
613 if (dn->valid_case) return true;
615 if (( ! dn->components) && ( ! ldb_dn_explode(dn))) {
619 for (i = 0; i < dn->comp_num; i++) {
620 const struct ldb_schema_attribute *a;
622 dn->components[i].cf_name = ldb_attr_casefold(dn->components, dn->components[i].name);
623 if (!dn->components[i].cf_name) {
627 a = ldb_schema_attribute_by_name(dn->ldb, dn->components[i].cf_name);
628 ret = a->syntax->canonicalise_fn(dn->ldb, dn->components,
629 &(dn->components[i].value),
630 &(dn->components[i].cf_value));
636 dn->valid_case = true;
641 for (i = 0; i < dn->comp_num; i++) {
642 LDB_FREE(dn->components[i].cf_name);
643 LDB_FREE(dn->components[i].cf_value.data);
648 const char *ldb_dn_get_casefold(struct ldb_dn *dn)
653 if (dn->casefold) return dn->casefold;
656 dn->casefold = talloc_strdup(dn, dn->linearized);
657 if (!dn->casefold) return NULL;
658 dn->valid_case = true;
662 if ( ! ldb_dn_casefold_internal(dn)) {
666 if (dn->comp_num == 0) {
667 if (dn->linearized && dn->linearized[0] == '\0') {
668 /* hmm a NULL dn, should we faild casefolding ? */
669 dn->casefold = talloc_strdup(dn, "");
672 /* A DN must be NULL, special, or have components */
677 /* calculate maximum possible length of DN */
678 for (len = 0, i = 0; i < dn->comp_num; i++) {
679 len += strlen(dn->components[i].cf_name); /* name len */
680 len += (dn->components[i].cf_value.length * 3); /* max escaped data len */
681 len += 2; /* '=' and ',' */
683 dn->casefold = talloc_array(dn, char, len);
684 if ( ! dn->casefold) return NULL;
688 for (i = 0; i < dn->comp_num; i++) {
691 n = dn->components[i].cf_name;
692 while (*n) *d++ = *n++;
697 d += ldb_dn_escape_internal( d,
698 (char *)dn->components[i].cf_value.data,
699 dn->components[i].cf_value.length);
704 /* don't waste more memory than necessary */
705 dn->casefold = talloc_realloc(dn, dn->casefold, char, strlen(dn->casefold) + 1);
710 char *ldb_dn_alloc_casefold(void *mem_ctx, struct ldb_dn *dn)
712 return talloc_strdup(mem_ctx, ldb_dn_get_casefold(dn));
715 /* Determine if dn is below base, in the ldap tree. Used for
716 * evaluating a subtree search.
717 * 0 if they match, otherwise non-zero
720 int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn)
725 if ( ! base || base->invalid) return 1;
726 if ( ! dn || dn->invalid) return -1;
728 if (( ! base->valid_case) || ( ! dn->valid_case)) {
729 if (base->linearized && dn->linearized) {
730 /* try with a normal compare first, if we are lucky
731 * we will avoid exploding and casfolding */
733 dif = strlen(dn->linearized) - strlen(base->linearized);
734 if (dif < 0) return dif;
735 if (strcmp(base->linearized, &dn->linearized[dif]) == 0) return 0;
738 if ( ! ldb_dn_casefold_internal(base)) {
742 if ( ! ldb_dn_casefold_internal(dn)) {
748 /* if base has more components,
749 * they don't have the same base */
750 if (base->comp_num > dn->comp_num) {
751 return (dn->comp_num - base->comp_num);
754 if (dn->comp_num == 0) {
755 if (dn->special && base->special) {
756 return strcmp(base->linearized, dn->linearized);
757 } else if (dn->special) {
759 } else if (base->special) {
766 n_base = base->comp_num - 1;
767 n_dn = dn->comp_num - 1;
769 while (n_base >= 0) {
770 /* compare attr names */
771 ret = strcmp(base->components[n_base].cf_name, dn->components[n_dn].cf_name);
772 if (ret != 0) return ret;
774 /* compare attr.cf_value. */
775 if (base->components[n_base].cf_value.length != dn->components[n_dn].cf_value.length) {
776 return base->components[n_base].cf_value.length - dn->components[n_dn].cf_value.length;
778 ret = strcmp((char *)base->components[n_base].cf_value.data, (char *)dn->components[n_dn].cf_value.data);
779 if (ret != 0) return ret;
788 /* compare DNs using casefolding compare functions.
790 If they match, then return 0
793 int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1)
797 if (( ! dn0) || dn0->invalid || ! dn1 || dn1->invalid) return -1;
799 if (( ! dn0->valid_case) || ( ! dn1->valid_case)) {
800 if (dn0->linearized && dn1->linearized) {
801 /* try with a normal compare first, if we are lucky
802 * we will avoid exploding and casfolding */
803 if (strcmp(dn0->linearized, dn1->linearized) == 0) return 0;
806 if ( ! ldb_dn_casefold_internal(dn0)) {
810 if ( ! ldb_dn_casefold_internal(dn1)) {
816 if (dn0->comp_num != dn1->comp_num) {
817 return (dn1->comp_num - dn0->comp_num);
820 if (dn0->comp_num == 0) {
821 if (dn0->special && dn1->special) {
822 return strcmp(dn0->linearized, dn1->linearized);
823 } else if (dn0->special) {
825 } else if (dn1->special) {
832 for (i = 0; i < dn0->comp_num; i++) {
833 /* compare attr names */
834 ret = strcmp(dn0->components[i].cf_name, dn1->components[i].cf_name);
835 if (ret != 0) return ret;
837 /* compare attr.cf_value. */
838 if (dn0->components[i].cf_value.length != dn1->components[i].cf_value.length) {
839 return dn0->components[i].cf_value.length - dn1->components[i].cf_value.length;
841 ret = strcmp((char *)dn0->components[i].cf_value.data, (char *)dn1->components[i].cf_value.data);
842 if (ret != 0) return ret;
848 static struct ldb_dn_component ldb_dn_copy_component(void *mem_ctx, struct ldb_dn_component *src)
850 struct ldb_dn_component dst;
852 memset(&dst, 0, sizeof(dst));
858 dst.value = ldb_val_dup(mem_ctx, &(src->value));
859 if (dst.value.data == NULL) {
863 dst.name = talloc_strdup(mem_ctx, src->name);
864 if (dst.name == NULL) {
865 LDB_FREE(dst.value.data);
869 if (src->cf_value.data) {
870 dst.cf_value = ldb_val_dup(mem_ctx, &(src->cf_value));
871 if (dst.cf_value.data == NULL) {
872 LDB_FREE(dst.value.data);
877 dst.cf_name = talloc_strdup(mem_ctx, src->cf_name);
878 if (dst.cf_name == NULL) {
879 LDB_FREE(dst.cf_name);
880 LDB_FREE(dst.value.data);
885 dst.cf_value.data = NULL;
892 struct ldb_dn *ldb_dn_copy(void *mem_ctx, struct ldb_dn *dn)
894 struct ldb_dn *new_dn;
896 if (!dn || dn->invalid) {
900 new_dn = talloc_zero(mem_ctx, struct ldb_dn);
907 if (dn->components) {
910 new_dn->components = talloc_zero_array(new_dn, struct ldb_dn_component, dn->comp_num);
911 if ( ! new_dn->components) {
916 for (i = 0; i < dn->comp_num; i++) {
917 new_dn->components[i] = ldb_dn_copy_component(new_dn->components, &dn->components[i]);
918 if ( ! new_dn->components[i].value.data) {
926 new_dn->casefold = talloc_strdup(new_dn, dn->casefold);
927 if ( ! new_dn->casefold) {
933 if (dn->linearized) {
934 new_dn->linearized = talloc_strdup(new_dn, dn->linearized);
935 if ( ! new_dn->linearized) {
944 /* modify the given dn by adding a base.
946 * return true if successful and false if not
947 * if false is returned the dn may be marked invalid
949 bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base)
954 if ( !base || base->invalid || !dn || dn->invalid) {
958 if (dn->components) {
961 if ( ! ldb_dn_validate(base)) {
966 if (dn->valid_case) {
967 if ( ! (s = ldb_dn_get_casefold(base))) {
972 dn->components = talloc_realloc(dn,
974 struct ldb_dn_component,
975 dn->comp_num + base->comp_num);
976 if ( ! dn->components) {
981 for (i = 0; i < base->comp_num; dn->comp_num++, i++) {
982 dn->components[dn->comp_num] = ldb_dn_copy_component(dn->components, &base->components[i]);
983 if (dn->components[dn->comp_num].value.data == NULL) {
989 if (dn->casefold && s) {
991 t = talloc_asprintf(dn, "%s,%s", dn->casefold, s);
993 t = talloc_strdup(dn, s);
995 LDB_FREE(dn->casefold);
1000 if (dn->linearized) {
1002 s = ldb_dn_get_linearized(base);
1007 if (*dn->linearized) {
1008 t = talloc_asprintf(dn, "%s,%s", dn->linearized, s);
1010 t = talloc_strdup(dn, s);
1016 LDB_FREE(dn->linearized);
1023 /* modify the given dn by adding a base.
1025 * return true if successful and false if not
1026 * if false is returned the dn may be marked invalid
1028 bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...)
1030 struct ldb_dn *base;
1035 if ( !dn || dn->invalid) {
1039 va_start(ap, base_fmt);
1040 base_str = talloc_vasprintf(dn, base_fmt, ap);
1043 if (base_str == NULL) {
1047 base = ldb_dn_new(base_str, dn->ldb, base_str);
1049 ret = ldb_dn_add_base(dn, base);
1051 talloc_free(base_str);
1056 /* modify the given dn by adding children elements.
1058 * return true if successful and false if not
1059 * if false is returned the dn may be marked invalid
1061 bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child)
1066 if ( !child || child->invalid || !dn || dn->invalid) {
1070 if (dn->components) {
1073 if ( ! ldb_dn_validate(child)) {
1078 if (dn->valid_case) {
1079 if ( ! (s = ldb_dn_get_casefold(child))) {
1084 n = dn->comp_num + child->comp_num;
1086 dn->components = talloc_realloc(dn,
1088 struct ldb_dn_component,
1090 if ( ! dn->components) {
1095 for (i = dn->comp_num - 1, j = n - 1; i >= 0; i--, j--) {
1096 dn->components[j] = dn->components[i];
1099 for (i = 0; i < child->comp_num; i++) {
1100 dn->components[i] = ldb_dn_copy_component(dn->components, &child->components[i]);
1101 if (dn->components[i].value.data == NULL) {
1109 if (dn->casefold && s) {
1110 t = talloc_asprintf(dn, "%s,%s", s, dn->casefold);
1111 LDB_FREE(dn->casefold);
1116 if (dn->linearized) {
1118 s = ldb_dn_get_linearized(child);
1123 t = talloc_asprintf(dn, "%s,%s", s, dn->linearized);
1128 LDB_FREE(dn->linearized);
1135 /* modify the given dn by adding children elements.
1137 * return true if successful and false if not
1138 * if false is returned the dn may be marked invalid
1140 bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...)
1142 struct ldb_dn *child;
1147 if ( !dn || dn->invalid) {
1151 va_start(ap, child_fmt);
1152 child_str = talloc_vasprintf(dn, child_fmt, ap);
1155 if (child_str == NULL) {
1159 child = ldb_dn_new(child_str, dn->ldb, child_str);
1161 ret = ldb_dn_add_child(dn, child);
1163 talloc_free(child_str);
1168 bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num)
1172 if ( ! ldb_dn_validate(dn)) {
1176 if (dn->comp_num < num) {
1180 /* free components */
1181 for (i = num; i > 0; i--) {
1182 LDB_FREE(dn->components[dn->comp_num - i].name);
1183 LDB_FREE(dn->components[dn->comp_num - i].value.data);
1184 LDB_FREE(dn->components[dn->comp_num - i].cf_name);
1185 LDB_FREE(dn->components[dn->comp_num - i].cf_value.data);
1188 dn->comp_num -= num;
1190 if (dn->valid_case) {
1191 for (i = 0; i < dn->comp_num; i++) {
1192 LDB_FREE(dn->components[i].cf_name);
1193 LDB_FREE(dn->components[i].cf_value.data);
1195 dn->valid_case = false;
1198 LDB_FREE(dn->casefold);
1199 LDB_FREE(dn->linearized);
1204 bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num)
1208 if ( ! ldb_dn_validate(dn)) {
1212 if (dn->comp_num < num) {
1216 for (i = 0, j = num; j < dn->comp_num; i++, j++) {
1218 LDB_FREE(dn->components[i].name);
1219 LDB_FREE(dn->components[i].value.data);
1220 LDB_FREE(dn->components[i].cf_name);
1221 LDB_FREE(dn->components[i].cf_value.data);
1223 dn->components[i] = dn->components[j];
1226 dn->comp_num -= num;
1228 if (dn->valid_case) {
1229 for (i = 0; i < dn->comp_num; i++) {
1230 LDB_FREE(dn->components[i].cf_name);
1231 LDB_FREE(dn->components[i].cf_value.data);
1233 dn->valid_case = false;
1236 LDB_FREE(dn->casefold);
1237 LDB_FREE(dn->linearized);
1242 struct ldb_dn *ldb_dn_get_parent(void *mem_ctx, struct ldb_dn *dn)
1244 struct ldb_dn *new_dn;
1246 new_dn = ldb_dn_copy(mem_ctx, dn);
1251 if ( ! ldb_dn_remove_child_components(new_dn, 1)) {
1252 talloc_free(new_dn);
1259 /* Create a 'canonical name' string from a DN:
1261 ie dc=samba,dc=org -> samba.org/
1262 uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator
1264 There are two formats, the EX format has the last / replaced with a newline (\n).
1267 static char *ldb_dn_canonical(void *mem_ctx, struct ldb_dn *dn, int ex_format) {
1270 char *cracked = NULL;
1272 if ( ! ldb_dn_validate(dn)) {
1276 tmpctx = talloc_new(mem_ctx);
1278 /* Walk backwards down the DN, grabbing 'dc' components at first */
1279 for (i = dn->comp_num - 1 ; i >= 0; i--) {
1280 if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) {
1284 cracked = talloc_asprintf(tmpctx, "%s.%s",
1285 ldb_dn_escape_value(tmpctx, dn->components[i].value),
1288 cracked = ldb_dn_escape_value(tmpctx, dn->components[i].value);
1295 /* Only domain components? Finish here */
1298 cracked = talloc_append_string(tmpctx, cracked, "\n");
1300 cracked = talloc_append_string(tmpctx, cracked, "/");
1302 talloc_steal(mem_ctx, cracked);
1306 /* Now walk backwards appending remaining components */
1307 for (; i > 0; i--) {
1308 cracked = talloc_asprintf_append(cracked, "/%s",
1309 ldb_dn_escape_value(tmpctx, dn->components[i].value));
1315 /* Last one, possibly a newline for the 'ex' format */
1317 cracked = talloc_asprintf_append(cracked, "\n%s",
1318 ldb_dn_escape_value(tmpctx, dn->components[i].value));
1320 cracked = talloc_asprintf_append(cracked, "/%s",
1321 ldb_dn_escape_value(tmpctx, dn->components[i].value));
1324 talloc_steal(mem_ctx, cracked);
1326 talloc_free(tmpctx);
1330 /* Wrapper functions for the above, for the two different string formats */
1331 char *ldb_dn_canonical_string(void *mem_ctx, struct ldb_dn *dn) {
1332 return ldb_dn_canonical(mem_ctx, dn, 0);
1336 char *ldb_dn_canonical_ex_string(void *mem_ctx, struct ldb_dn *dn) {
1337 return ldb_dn_canonical(mem_ctx, dn, 1);
1340 int ldb_dn_get_comp_num(struct ldb_dn *dn)
1342 if ( ! ldb_dn_validate(dn)) {
1345 return dn->comp_num;
1348 const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num)
1350 if ( ! ldb_dn_validate(dn)) {
1353 if (num >= dn->comp_num) return NULL;
1354 return dn->components[num].name;
1357 const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn, unsigned int num)
1359 if ( ! ldb_dn_validate(dn)) {
1362 if (num >= dn->comp_num) return NULL;
1363 return &dn->components[num].value;
1366 const char *ldb_dn_get_rdn_name(struct ldb_dn *dn)
1368 if ( ! ldb_dn_validate(dn)) {
1371 if (dn->comp_num == 0) return NULL;
1372 return dn->components[0].name;
1375 const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn)
1377 if ( ! ldb_dn_validate(dn)) {
1380 if (dn->comp_num == 0) return NULL;
1381 return &dn->components[0].value;
1384 int ldb_dn_set_component(struct ldb_dn *dn, int num, const char *name, const struct ldb_val val)
1389 if ( ! ldb_dn_validate(dn)) {
1390 return LDB_ERR_OTHER;
1393 if (num >= dn->comp_num) {
1394 return LDB_ERR_OTHER;
1397 n = talloc_strdup(dn, name);
1399 return LDB_ERR_OTHER;
1402 v.length = val.length;
1403 v.data = (uint8_t *)talloc_memdup(dn, val.data, v.length+1);
1406 return LDB_ERR_OTHER;
1409 talloc_free(dn->components[num].name);
1410 talloc_free(dn->components[num].value.data);
1411 dn->components[num].name = n;
1412 dn->components[num].value = v;
1414 if (dn->valid_case) {
1416 for (i = 0; i < dn->comp_num; i++) {
1417 LDB_FREE(dn->components[i].cf_name);
1418 LDB_FREE(dn->components[i].cf_value.data);
1420 dn->valid_case = false;
1422 LDB_FREE(dn->casefold);
1423 LDB_FREE(dn->linearized);
1428 bool ldb_dn_is_valid(struct ldb_dn *dn)
1430 if ( ! dn) return false;
1431 return ! dn->invalid;
1434 bool ldb_dn_is_special(struct ldb_dn *dn)
1436 if ( ! dn || dn->invalid) return false;
1440 bool ldb_dn_check_special(struct ldb_dn *dn, const char *check)
1442 if ( ! dn || dn->invalid) return false;
1443 return ! strcmp(dn->linearized, check);
1446 bool ldb_dn_is_null(struct ldb_dn *dn)
1448 if ( ! dn || dn->invalid) return false;
1449 if (dn->linearized && (dn->linearized[0] == '\0')) return true;