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 3 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, see <http://www.gnu.org/licenses/>.
27 * Component: ldb dn creation and manipulation utility functions
29 * Description: - explode a dn into it's own basic elements
30 * and put them in a structure (only if necessary)
31 * - manipulate ldb_dn structures
36 #include "ldb_includes.h"
39 #define LDB_DN_NULL_FAILED(x) if (!(x)) goto failed
41 #define LDB_FREE(x) do { talloc_free(x); x = NULL; } while(0)
44 internal ldb exploded dn structures
46 struct ldb_dn_component {
52 struct ldb_val cf_value;
57 struct ldb_context *ldb;
59 /* Special DNs are always linearized */
68 unsigned int comp_num;
69 struct ldb_dn_component *components;
73 /* strdn may be NULL */
74 struct ldb_dn *ldb_dn_new(void *mem_ctx, struct ldb_context *ldb, const char *strdn)
78 if ( (! mem_ctx) || (! ldb)) return NULL;
80 dn = talloc_zero(mem_ctx, struct ldb_dn);
81 LDB_DN_NULL_FAILED(dn);
86 if (strdn[0] == '@') {
89 if (strncasecmp(strdn, "<GUID=", 6) == 0) {
90 /* this is special DN returned when the
91 * exploded_dn control is used */
93 /* FIXME: add a GUID string to ldb_dn structure */
94 } else if (strncasecmp(strdn, "<SID=", 8) == 0) {
95 /* this is special DN returned when the
96 * exploded_dn control is used */
98 /* FIXME: add a SID string to ldb_dn structure */
99 } else if (strncasecmp(strdn, "<WKGUID=", 8) == 0) {
100 /* this is special DN returned when the
101 * exploded_dn control is used */
103 /* FIXME: add a WKGUID string to ldb_dn structure */
105 dn->linearized = talloc_strdup(dn, strdn);
107 dn->linearized = talloc_strdup(dn, "");
109 LDB_DN_NULL_FAILED(dn->linearized);
118 struct ldb_dn *ldb_dn_new_fmt(void *mem_ctx, struct ldb_context *ldb, const char *new_fmt, ...)
124 if ( (! mem_ctx) || (! ldb)) return NULL;
126 dn = talloc_zero(mem_ctx, struct ldb_dn);
127 LDB_DN_NULL_FAILED(dn);
131 va_start(ap, new_fmt);
132 strdn = talloc_vasprintf(dn, new_fmt, ap);
134 LDB_DN_NULL_FAILED(strdn);
136 if (strdn[0] == '@') {
139 if (strncasecmp(strdn, "<GUID=", 6) == 0) {
140 /* this is special DN returned when the
141 * exploded_dn control is used */
143 /* FIXME: add a GUID string to ldb_dn structure */
144 } else if (strncasecmp(strdn, "<SID=", 8) == 0) {
145 /* this is special DN returned when the
146 * exploded_dn control is used */
148 /* FIXME: add a SID string to ldb_dn structure */
149 } else if (strncasecmp(strdn, "<WKGUID=", 8) == 0) {
150 /* this is special DN returned when the
151 * exploded_dn control is used */
153 /* FIXME: add a WKGUID string to ldb_dn structure */
155 dn->linearized = strdn;
164 static int ldb_dn_escape_internal(char *dst, const char *src, int len)
173 while (p - src < len) {
175 p += strcspn(p, ",=\n+<>#;\\\"");
177 if (p - src == len) /* found no escapable chars */
180 memcpy(d, s, p - s); /* copy the part of the string before the stop */
181 d += (p - s); /* move to current position */
183 if (*p) { /* it is a normal escapable character */
186 } else { /* we have a zero byte in the string */
187 strncpy(d, "\00", 3); /* escape the zero */
189 p++; /* skip the zero */
191 s = p; /* move forward */
194 /* copy the last part (with zero) and return */
198 /* return the length of the resulting string */
199 return (l + (d - dst));
202 char *ldb_dn_escape_value(void *mem_ctx, struct ldb_val value)
209 /* allocate destination string, it will be at most 3 times the source */
210 dst = talloc_array(mem_ctx, char, value.length * 3 + 1);
216 ldb_dn_escape_internal(dst, (const char *)value.data, value.length);
218 dst = talloc_realloc(mem_ctx, dst, char, strlen(dst) + 1);
224 explode a DN string into a ldb_dn structure
225 based on RFC4514 except that we don't support multiple valued RDNs
227 static bool ldb_dn_explode(struct ldb_dn *dn)
229 char *p, *data, *d, *dt, *t;
231 bool in_attr = false;
232 bool in_value = false;
233 bool in_quote = false;
239 if ( ! dn || dn->invalid) return false;
241 if (dn->components) {
245 if ( ! dn->linearized) {
250 if (dn->linearized[0] == '\0') {
254 /* Special DNs case */
259 /* make sure we free this if alloced previously before replacing */
260 talloc_free(dn->components);
262 /* in the common case we have 3 or more components */
263 /* make sure all components are zeroed, other functions depend on this */
264 dn->components = talloc_zero_array(dn, struct ldb_dn_component, 3);
265 if ( ! dn->components) {
270 /* Components data space is allocated here once */
271 data = talloc_array(dn->components, char, strlen(dn->linearized) + 1);
295 /* attr names must be ascii only */
303 if ( ! isalpha(*p)) {
304 /* not a digit nor an alpha, invalid attribute name */
315 /* valid only if we are at the end */
320 if (trim && (*p != '=')) {
321 /* spaces/tabs are not allowed in attribute names */
327 /* attribute terminated */
334 dn->components[dn->comp_num].name = talloc_strdup(dn->components, dt);
335 if ( ! dn->components[dn->comp_num].name) {
347 /* attr names must be ascii only */
352 if (is_oid && ( ! (isdigit(*p) || (*p == '.')))) {
353 /* not a digit nor a dot, invalid attribute oid */
357 if ( ! (isalpha(*p) || isdigit(*p) || (*p == '-'))) {
358 /* not ALPHA, DIGIT or HYPHEN */
399 /* TODO: support ber encoded values
410 /* ok found value terminator */
424 dn->components[dn->comp_num].value.data = (uint8_t *)talloc_strdup(dn->components, dt);
425 dn->components[dn->comp_num].value.length = l;
426 if ( ! dn->components[dn->comp_num].value.data) {
434 if (dn->comp_num > 2) {
435 dn->components = talloc_realloc(dn,
437 struct ldb_dn_component,
439 if ( ! dn->components) {
443 /* make sure all components are zeroed, other functions depend on this */
444 memset(&dn->components[dn->comp_num], '\0', sizeof(struct ldb_dn_component));
457 /* a string with not escaped specials is invalid (tested) */
486 if (sscanf(p, "%02x", &x) != 1) {
487 /* invalid escaping sequence */
494 *d++ = (unsigned char)x;
516 if (in_attr || in_quote) {
522 /* save last element */
530 dn->components[dn->comp_num].value.data = (uint8_t *)talloc_strdup(dn->components, dt);
531 dn->components[dn->comp_num].value.length = l;
533 if ( ! dn->components[dn->comp_num].value.data) {
545 talloc_free(dn->components);
549 bool ldb_dn_validate(struct ldb_dn *dn)
551 return ldb_dn_explode(dn);
554 const char *ldb_dn_get_linearized(struct ldb_dn *dn)
559 if ( ! dn || ( dn->invalid)) return NULL;
561 if (dn->linearized) return dn->linearized;
563 if ( ! dn->components) {
568 if (dn->comp_num == 0) {
569 dn->linearized = talloc_strdup(dn, "");
570 if ( ! dn->linearized) return NULL;
571 return dn->linearized;
574 /* calculate maximum possible length of DN */
575 for (len = 0, i = 0; i < dn->comp_num; i++) {
576 len += strlen(dn->components[i].name); /* name len */
577 len += (dn->components[i].value.length * 3); /* max escaped data len */
578 len += 2; /* '=' and ',' */
580 dn->linearized = talloc_array(dn, char, len);
581 if ( ! dn->linearized) return NULL;
585 for (i = 0; i < dn->comp_num; i++) {
588 n = dn->components[i].name;
589 while (*n) *d++ = *n++;
594 d += ldb_dn_escape_internal( d,
595 (char *)dn->components[i].value.data,
596 dn->components[i].value.length);
602 /* don't waste more memory than necessary */
603 dn->linearized = talloc_realloc(dn, dn->linearized, char, (d - dn->linearized + 1));
605 return dn->linearized;
608 char *ldb_dn_alloc_linearized(void *mem_ctx, struct ldb_dn *dn)
610 return talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn));
614 casefold a dn. We need to casefold the attribute names, and canonicalize
615 attribute values of case insensitive attributes.
618 static bool ldb_dn_casefold_internal(struct ldb_dn *dn)
622 if ( ! dn || dn->invalid) return false;
624 if (dn->valid_case) return true;
626 if (( ! dn->components) && ( ! ldb_dn_explode(dn))) {
630 for (i = 0; i < dn->comp_num; i++) {
631 const struct ldb_schema_attribute *a;
633 dn->components[i].cf_name = ldb_attr_casefold(dn->components, dn->components[i].name);
634 if (!dn->components[i].cf_name) {
638 a = ldb_schema_attribute_by_name(dn->ldb, dn->components[i].cf_name);
639 ret = a->syntax->canonicalise_fn(dn->ldb, dn->components,
640 &(dn->components[i].value),
641 &(dn->components[i].cf_value));
647 dn->valid_case = true;
652 for (i = 0; i < dn->comp_num; i++) {
653 LDB_FREE(dn->components[i].cf_name);
654 LDB_FREE(dn->components[i].cf_value.data);
659 const char *ldb_dn_get_casefold(struct ldb_dn *dn)
664 if (dn->casefold) return dn->casefold;
667 dn->casefold = talloc_strdup(dn, dn->linearized);
668 if (!dn->casefold) return NULL;
669 dn->valid_case = true;
673 if ( ! ldb_dn_casefold_internal(dn)) {
677 if (dn->comp_num == 0) {
678 if (dn->linearized && dn->linearized[0] == '\0') {
679 /* hmm a NULL dn, should we faild casefolding ? */
680 dn->casefold = talloc_strdup(dn, "");
683 /* A DN must be NULL, special, or have components */
688 /* calculate maximum possible length of DN */
689 for (len = 0, i = 0; i < dn->comp_num; i++) {
690 len += strlen(dn->components[i].cf_name); /* name len */
691 len += (dn->components[i].cf_value.length * 3); /* max escaped data len */
692 len += 2; /* '=' and ',' */
694 dn->casefold = talloc_array(dn, char, len);
695 if ( ! dn->casefold) return NULL;
699 for (i = 0; i < dn->comp_num; i++) {
702 n = dn->components[i].cf_name;
703 while (*n) *d++ = *n++;
708 d += ldb_dn_escape_internal( d,
709 (char *)dn->components[i].cf_value.data,
710 dn->components[i].cf_value.length);
715 /* don't waste more memory than necessary */
716 dn->casefold = talloc_realloc(dn, dn->casefold, char, strlen(dn->casefold) + 1);
721 char *ldb_dn_alloc_casefold(void *mem_ctx, struct ldb_dn *dn)
723 return talloc_strdup(mem_ctx, ldb_dn_get_casefold(dn));
726 /* Determine if dn is below base, in the ldap tree. Used for
727 * evaluating a subtree search.
728 * 0 if they match, otherwise non-zero
731 int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn)
736 if ( ! base || base->invalid) return 1;
737 if ( ! dn || dn->invalid) return -1;
739 if (( ! base->valid_case) || ( ! dn->valid_case)) {
740 if (base->linearized && dn->linearized) {
741 /* try with a normal compare first, if we are lucky
742 * we will avoid exploding and casfolding */
744 dif = strlen(dn->linearized) - strlen(base->linearized);
745 if (dif < 0) return dif;
746 if (strcmp(base->linearized, &dn->linearized[dif]) == 0) return 0;
749 if ( ! ldb_dn_casefold_internal(base)) {
753 if ( ! ldb_dn_casefold_internal(dn)) {
759 /* if base has more components,
760 * they don't have the same base */
761 if (base->comp_num > dn->comp_num) {
762 return (dn->comp_num - base->comp_num);
765 if (dn->comp_num == 0) {
766 if (dn->special && base->special) {
767 return strcmp(base->linearized, dn->linearized);
768 } else if (dn->special) {
770 } else if (base->special) {
777 n_base = base->comp_num - 1;
778 n_dn = dn->comp_num - 1;
780 while (n_base >= 0) {
781 /* compare attr names */
782 ret = strcmp(base->components[n_base].cf_name, dn->components[n_dn].cf_name);
783 if (ret != 0) return ret;
785 /* compare attr.cf_value. */
786 if (base->components[n_base].cf_value.length != dn->components[n_dn].cf_value.length) {
787 return base->components[n_base].cf_value.length - dn->components[n_dn].cf_value.length;
789 ret = strcmp((char *)base->components[n_base].cf_value.data, (char *)dn->components[n_dn].cf_value.data);
790 if (ret != 0) return ret;
799 /* compare DNs using casefolding compare functions.
801 If they match, then return 0
804 int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1)
808 if (( ! dn0) || dn0->invalid || ! dn1 || dn1->invalid) return -1;
810 if (( ! dn0->valid_case) || ( ! dn1->valid_case)) {
811 if (dn0->linearized && dn1->linearized) {
812 /* try with a normal compare first, if we are lucky
813 * we will avoid exploding and casfolding */
814 if (strcmp(dn0->linearized, dn1->linearized) == 0) return 0;
817 if ( ! ldb_dn_casefold_internal(dn0)) {
821 if ( ! ldb_dn_casefold_internal(dn1)) {
827 if (dn0->comp_num != dn1->comp_num) {
828 return (dn1->comp_num - dn0->comp_num);
831 if (dn0->comp_num == 0) {
832 if (dn0->special && dn1->special) {
833 return strcmp(dn0->linearized, dn1->linearized);
834 } else if (dn0->special) {
836 } else if (dn1->special) {
843 for (i = 0; i < dn0->comp_num; i++) {
844 /* compare attr names */
845 ret = strcmp(dn0->components[i].cf_name, dn1->components[i].cf_name);
846 if (ret != 0) return ret;
848 /* compare attr.cf_value. */
849 if (dn0->components[i].cf_value.length != dn1->components[i].cf_value.length) {
850 return dn0->components[i].cf_value.length - dn1->components[i].cf_value.length;
852 ret = strcmp((char *)dn0->components[i].cf_value.data, (char *)dn1->components[i].cf_value.data);
853 if (ret != 0) return ret;
859 static struct ldb_dn_component ldb_dn_copy_component(void *mem_ctx, struct ldb_dn_component *src)
861 struct ldb_dn_component dst;
863 memset(&dst, 0, sizeof(dst));
869 dst.value = ldb_val_dup(mem_ctx, &(src->value));
870 if (dst.value.data == NULL) {
874 dst.name = talloc_strdup(mem_ctx, src->name);
875 if (dst.name == NULL) {
876 LDB_FREE(dst.value.data);
880 if (src->cf_value.data) {
881 dst.cf_value = ldb_val_dup(mem_ctx, &(src->cf_value));
882 if (dst.cf_value.data == NULL) {
883 LDB_FREE(dst.value.data);
888 dst.cf_name = talloc_strdup(mem_ctx, src->cf_name);
889 if (dst.cf_name == NULL) {
890 LDB_FREE(dst.cf_name);
891 LDB_FREE(dst.value.data);
896 dst.cf_value.data = NULL;
903 struct ldb_dn *ldb_dn_copy(void *mem_ctx, struct ldb_dn *dn)
905 struct ldb_dn *new_dn;
907 if (!dn || dn->invalid) {
911 new_dn = talloc_zero(mem_ctx, struct ldb_dn);
918 if (dn->components) {
921 new_dn->components = talloc_zero_array(new_dn, struct ldb_dn_component, dn->comp_num);
922 if ( ! new_dn->components) {
927 for (i = 0; i < dn->comp_num; i++) {
928 new_dn->components[i] = ldb_dn_copy_component(new_dn->components, &dn->components[i]);
929 if ( ! new_dn->components[i].value.data) {
937 new_dn->casefold = talloc_strdup(new_dn, dn->casefold);
938 if ( ! new_dn->casefold) {
944 if (dn->linearized) {
945 new_dn->linearized = talloc_strdup(new_dn, dn->linearized);
946 if ( ! new_dn->linearized) {
955 /* modify the given dn by adding a base.
957 * return true if successful and false if not
958 * if false is returned the dn may be marked invalid
960 bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base)
965 if ( !base || base->invalid || !dn || dn->invalid) {
969 if (dn->components) {
972 if ( ! ldb_dn_validate(base)) {
977 if (dn->valid_case) {
978 if ( ! (s = ldb_dn_get_casefold(base))) {
983 dn->components = talloc_realloc(dn,
985 struct ldb_dn_component,
986 dn->comp_num + base->comp_num);
987 if ( ! dn->components) {
992 for (i = 0; i < base->comp_num; dn->comp_num++, i++) {
993 dn->components[dn->comp_num] = ldb_dn_copy_component(dn->components, &base->components[i]);
994 if (dn->components[dn->comp_num].value.data == NULL) {
1000 if (dn->casefold && s) {
1001 if (*dn->casefold) {
1002 t = talloc_asprintf(dn, "%s,%s", dn->casefold, s);
1004 t = talloc_strdup(dn, s);
1006 LDB_FREE(dn->casefold);
1011 if (dn->linearized) {
1013 s = ldb_dn_get_linearized(base);
1018 if (*dn->linearized) {
1019 t = talloc_asprintf(dn, "%s,%s", dn->linearized, s);
1021 t = talloc_strdup(dn, s);
1027 LDB_FREE(dn->linearized);
1034 /* modify the given dn by adding a base.
1036 * return true if successful and false if not
1037 * if false is returned the dn may be marked invalid
1039 bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...)
1041 struct ldb_dn *base;
1046 if ( !dn || dn->invalid) {
1050 va_start(ap, base_fmt);
1051 base_str = talloc_vasprintf(dn, base_fmt, ap);
1054 if (base_str == NULL) {
1058 base = ldb_dn_new(base_str, dn->ldb, base_str);
1060 ret = ldb_dn_add_base(dn, base);
1062 talloc_free(base_str);
1067 /* modify the given dn by adding children elements.
1069 * return true if successful and false if not
1070 * if false is returned the dn may be marked invalid
1072 bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child)
1077 if ( !child || child->invalid || !dn || dn->invalid) {
1081 if (dn->components) {
1084 if ( ! ldb_dn_validate(child)) {
1089 if (dn->valid_case) {
1090 if ( ! (s = ldb_dn_get_casefold(child))) {
1095 n = dn->comp_num + child->comp_num;
1097 dn->components = talloc_realloc(dn,
1099 struct ldb_dn_component,
1101 if ( ! dn->components) {
1106 for (i = dn->comp_num - 1, j = n - 1; i >= 0; i--, j--) {
1107 dn->components[j] = dn->components[i];
1110 for (i = 0; i < child->comp_num; i++) {
1111 dn->components[i] = ldb_dn_copy_component(dn->components, &child->components[i]);
1112 if (dn->components[i].value.data == NULL) {
1120 if (dn->casefold && s) {
1121 t = talloc_asprintf(dn, "%s,%s", s, dn->casefold);
1122 LDB_FREE(dn->casefold);
1127 if (dn->linearized) {
1129 s = ldb_dn_get_linearized(child);
1134 t = talloc_asprintf(dn, "%s,%s", s, dn->linearized);
1139 LDB_FREE(dn->linearized);
1146 /* modify the given dn by adding children elements.
1148 * return true if successful and false if not
1149 * if false is returned the dn may be marked invalid
1151 bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...)
1153 struct ldb_dn *child;
1158 if ( !dn || dn->invalid) {
1162 va_start(ap, child_fmt);
1163 child_str = talloc_vasprintf(dn, child_fmt, ap);
1166 if (child_str == NULL) {
1170 child = ldb_dn_new(child_str, dn->ldb, child_str);
1172 ret = ldb_dn_add_child(dn, child);
1174 talloc_free(child_str);
1179 bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num)
1183 if ( ! ldb_dn_validate(dn)) {
1187 if (dn->comp_num < num) {
1191 /* free components */
1192 for (i = num; i > 0; i--) {
1193 LDB_FREE(dn->components[dn->comp_num - i].name);
1194 LDB_FREE(dn->components[dn->comp_num - i].value.data);
1195 LDB_FREE(dn->components[dn->comp_num - i].cf_name);
1196 LDB_FREE(dn->components[dn->comp_num - i].cf_value.data);
1199 dn->comp_num -= num;
1201 if (dn->valid_case) {
1202 for (i = 0; i < dn->comp_num; i++) {
1203 LDB_FREE(dn->components[i].cf_name);
1204 LDB_FREE(dn->components[i].cf_value.data);
1206 dn->valid_case = false;
1209 LDB_FREE(dn->casefold);
1210 LDB_FREE(dn->linearized);
1215 bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num)
1219 if ( ! ldb_dn_validate(dn)) {
1223 if (dn->comp_num < num) {
1227 for (i = 0, j = num; j < dn->comp_num; i++, j++) {
1229 LDB_FREE(dn->components[i].name);
1230 LDB_FREE(dn->components[i].value.data);
1231 LDB_FREE(dn->components[i].cf_name);
1232 LDB_FREE(dn->components[i].cf_value.data);
1234 dn->components[i] = dn->components[j];
1237 dn->comp_num -= num;
1239 if (dn->valid_case) {
1240 for (i = 0; i < dn->comp_num; i++) {
1241 LDB_FREE(dn->components[i].cf_name);
1242 LDB_FREE(dn->components[i].cf_value.data);
1244 dn->valid_case = false;
1247 LDB_FREE(dn->casefold);
1248 LDB_FREE(dn->linearized);
1253 struct ldb_dn *ldb_dn_get_parent(void *mem_ctx, struct ldb_dn *dn)
1255 struct ldb_dn *new_dn;
1257 new_dn = ldb_dn_copy(mem_ctx, dn);
1262 if ( ! ldb_dn_remove_child_components(new_dn, 1)) {
1263 talloc_free(new_dn);
1270 /* Create a 'canonical name' string from a DN:
1272 ie dc=samba,dc=org -> samba.org/
1273 uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator
1275 There are two formats, the EX format has the last / replaced with a newline (\n).
1278 static char *ldb_dn_canonical(void *mem_ctx, struct ldb_dn *dn, int ex_format) {
1281 char *cracked = NULL;
1283 if ( ! ldb_dn_validate(dn)) {
1287 tmpctx = talloc_new(mem_ctx);
1289 /* Walk backwards down the DN, grabbing 'dc' components at first */
1290 for (i = dn->comp_num - 1 ; i >= 0; i--) {
1291 if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) {
1295 cracked = talloc_asprintf(tmpctx, "%s.%s",
1296 ldb_dn_escape_value(tmpctx, dn->components[i].value),
1299 cracked = ldb_dn_escape_value(tmpctx, dn->components[i].value);
1306 /* Only domain components? Finish here */
1309 cracked = talloc_append_string(tmpctx, cracked, "\n");
1311 cracked = talloc_append_string(tmpctx, cracked, "/");
1313 talloc_steal(mem_ctx, cracked);
1317 /* Now walk backwards appending remaining components */
1318 for (; i > 0; i--) {
1319 cracked = talloc_asprintf_append(cracked, "/%s",
1320 ldb_dn_escape_value(tmpctx, dn->components[i].value));
1326 /* Last one, possibly a newline for the 'ex' format */
1328 cracked = talloc_asprintf_append(cracked, "\n%s",
1329 ldb_dn_escape_value(tmpctx, dn->components[i].value));
1331 cracked = talloc_asprintf_append(cracked, "/%s",
1332 ldb_dn_escape_value(tmpctx, dn->components[i].value));
1335 talloc_steal(mem_ctx, cracked);
1337 talloc_free(tmpctx);
1341 /* Wrapper functions for the above, for the two different string formats */
1342 char *ldb_dn_canonical_string(void *mem_ctx, struct ldb_dn *dn) {
1343 return ldb_dn_canonical(mem_ctx, dn, 0);
1347 char *ldb_dn_canonical_ex_string(void *mem_ctx, struct ldb_dn *dn) {
1348 return ldb_dn_canonical(mem_ctx, dn, 1);
1351 int ldb_dn_get_comp_num(struct ldb_dn *dn)
1353 if ( ! ldb_dn_validate(dn)) {
1356 return dn->comp_num;
1359 const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num)
1361 if ( ! ldb_dn_validate(dn)) {
1364 if (num >= dn->comp_num) return NULL;
1365 return dn->components[num].name;
1368 const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn, unsigned int num)
1370 if ( ! ldb_dn_validate(dn)) {
1373 if (num >= dn->comp_num) return NULL;
1374 return &dn->components[num].value;
1377 const char *ldb_dn_get_rdn_name(struct ldb_dn *dn)
1379 if ( ! ldb_dn_validate(dn)) {
1382 if (dn->comp_num == 0) return NULL;
1383 return dn->components[0].name;
1386 const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn)
1388 if ( ! ldb_dn_validate(dn)) {
1391 if (dn->comp_num == 0) return NULL;
1392 return &dn->components[0].value;
1395 int ldb_dn_set_component(struct ldb_dn *dn, int num, const char *name, const struct ldb_val val)
1400 if ( ! ldb_dn_validate(dn)) {
1401 return LDB_ERR_OTHER;
1404 if (num >= dn->comp_num) {
1405 return LDB_ERR_OTHER;
1408 n = talloc_strdup(dn, name);
1410 return LDB_ERR_OTHER;
1413 v.length = val.length;
1414 v.data = (uint8_t *)talloc_memdup(dn, val.data, v.length+1);
1417 return LDB_ERR_OTHER;
1420 talloc_free(dn->components[num].name);
1421 talloc_free(dn->components[num].value.data);
1422 dn->components[num].name = n;
1423 dn->components[num].value = v;
1425 if (dn->valid_case) {
1427 for (i = 0; i < dn->comp_num; i++) {
1428 LDB_FREE(dn->components[i].cf_name);
1429 LDB_FREE(dn->components[i].cf_value.data);
1431 dn->valid_case = false;
1433 LDB_FREE(dn->casefold);
1434 LDB_FREE(dn->linearized);
1439 bool ldb_dn_is_valid(struct ldb_dn *dn)
1441 if ( ! dn) return false;
1442 return ! dn->invalid;
1445 bool ldb_dn_is_special(struct ldb_dn *dn)
1447 if ( ! dn || dn->invalid) return false;
1451 bool ldb_dn_check_special(struct ldb_dn *dn, const char *check)
1453 if ( ! dn || dn->invalid) return false;
1454 return ! strcmp(dn->linearized, check);
1457 bool ldb_dn_is_null(struct ldb_dn *dn)
1459 if ( ! dn || dn->invalid) return false;
1460 if (dn->linearized && (dn->linearized[0] == '\0')) return true;