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_private.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;
55 struct ldb_dn_extended_component {
63 struct ldb_context *ldb;
65 /* Special DNs are always linearized */
72 char *extended_linearized;
75 unsigned int comp_num;
76 struct ldb_dn_component *components;
78 unsigned int extended_comp_num;
79 struct ldb_dn_extended_component *extended_components;
82 /* strdn may be NULL */
83 struct ldb_dn *ldb_dn_from_ldb_val(void *mem_ctx, struct ldb_context *ldb, const struct ldb_val *strdn)
87 if (! ldb) return NULL;
89 dn = talloc_zero(mem_ctx, struct ldb_dn);
90 LDB_DN_NULL_FAILED(dn);
94 if (strdn->data && strdn->length) {
95 if (strdn->data[0] == '@') {
98 dn->extended_linearized = talloc_strndup(dn, (const char *)strdn->data, strdn->length);
99 LDB_DN_NULL_FAILED(dn->extended_linearized);
101 if (strdn->data[0] == '<') {
102 const char *p_save, *p = dn->extended_linearized;
111 if (p_save == dn->extended_linearized) {
112 dn->linearized = talloc_strdup(dn, "");
114 dn->linearized = talloc_strdup(dn, p_save);
116 LDB_DN_NULL_FAILED(dn->linearized);
118 dn->linearized = dn->extended_linearized;
119 dn->extended_linearized = NULL;
122 dn->linearized = talloc_strdup(dn, "");
123 LDB_DN_NULL_FAILED(dn->linearized);
133 /* strdn may be NULL */
134 struct ldb_dn *ldb_dn_new(void *mem_ctx, struct ldb_context *ldb, const char *strdn)
138 blob.length = strdn ? strlen(strdn) : 0;
139 return ldb_dn_from_ldb_val(mem_ctx, ldb, &blob);
142 struct ldb_dn *ldb_dn_new_fmt(void *mem_ctx, struct ldb_context *ldb, const char *new_fmt, ...)
147 if ( (! mem_ctx) || (! ldb)) return NULL;
149 va_start(ap, new_fmt);
150 strdn = talloc_vasprintf(mem_ctx, new_fmt, ap);
154 struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb, strdn);
162 static int ldb_dn_escape_internal(char *dst, const char *src, int len)
171 while (p - src < len) {
173 p += strcspn(p, ",=\n+<>#;\\\"");
175 if (p - src == len) /* found no escapable chars */
178 memcpy(d, s, p - s); /* copy the part of the string before the stop */
179 d += (p - s); /* move to current position */
181 if (*p) { /* it is a normal escapable character */
184 } else { /* we have a zero byte in the string */
185 strncpy(d, "\00", 3); /* escape the zero */
187 p++; /* skip the zero */
189 s = p; /* move forward */
192 /* copy the last part (with zero) and return */
196 /* return the length of the resulting string */
197 return (l + (d - dst));
200 char *ldb_dn_escape_value(void *mem_ctx, struct ldb_val value)
207 /* allocate destination string, it will be at most 3 times the source */
208 dst = talloc_array(mem_ctx, char, value.length * 3 + 1);
214 ldb_dn_escape_internal(dst, (const char *)value.data, value.length);
216 dst = talloc_realloc(mem_ctx, dst, char, strlen(dst) + 1);
222 explode a DN string into a ldb_dn structure
223 based on RFC4514 except that we don't support multiple valued RDNs
225 static bool ldb_dn_explode(struct ldb_dn *dn)
227 char *p, *ex_name, *ex_value, *data, *d, *dt, *t;
229 bool in_extended = false;
230 bool in_ex_name = false;
231 bool in_ex_value = false;
232 bool in_attr = false;
233 bool in_value = false;
234 bool in_quote = false;
241 if ( ! dn || dn->invalid) return false;
243 if (dn->components) {
247 if (dn->extended_linearized) {
248 parse_dn = dn->extended_linearized;
250 parse_dn = dn->linearized;
258 if (parse_dn[0] == '\0') {
262 /* Special DNs case */
267 /* make sure we free this if alloced previously before replacing */
268 talloc_free(dn->components);
270 talloc_free(dn->extended_components);
271 dn->extended_components = NULL;
273 /* in the common case we have 3 or more components */
274 /* make sure all components are zeroed, other functions depend on this */
275 dn->components = talloc_zero_array(dn, struct ldb_dn_component, 3);
276 if ( ! dn->components) {
281 /* Components data space is allocated here once */
282 data = talloc_array(dn->components, char, strlen(parse_dn) + 1);
298 if (!in_ex_name && !in_ex_value) {
305 } else if (p[0] == '\0') {
317 if (in_ex_name && *p == '=') {
326 if (in_ex_value && *p == '>') {
327 const struct ldb_dn_extended_syntax *extended_syntax;
328 struct ldb_val ex_val = {
330 .length = d - ex_value
337 /* Process name and ex_value */
339 dn->extended_components = talloc_realloc(dn,
340 dn->extended_components,
341 struct ldb_dn_extended_component,
342 dn->extended_comp_num + 1);
343 if ( ! dn->extended_components) {
348 extended_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, ex_name);
349 if (!extended_syntax) {
350 /* We don't know about this type of extended DN */
354 dn->extended_components[dn->extended_comp_num].name = talloc_strdup(dn->extended_components, ex_name);
355 if (!dn->extended_components[dn->extended_comp_num].name) {
359 ret = extended_syntax->read_fn(dn->ldb, dn->extended_components,
360 &ex_val, &dn->extended_components[dn->extended_comp_num].value);
361 if (ret != LDB_SUCCESS) {
366 dn->extended_comp_num++;
369 /* We have reached the end (extended component only)! */
373 } else if (*p == ';') {
396 /* attr names must be ascii only */
404 if ( ! isalpha(*p)) {
405 /* not a digit nor an alpha, invalid attribute name */
410 /* Copy this character across from parse_dn, now we have trimmed out spaces */
417 /* valid only if we are at the end */
422 if (trim && (*p != '=')) {
423 /* spaces/tabs are not allowed in attribute names */
429 /* attribute terminated */
435 /* Terminate this string in d (which is a copy of parse_dn with spaces trimmed) */
437 dn->components[dn->comp_num].name = talloc_strdup(dn->components, dt);
438 if ( ! dn->components[dn->comp_num].name) {
450 /* attr names must be ascii only */
455 if (is_oid && ( ! (isdigit(*p) || (*p == '.')))) {
456 /* not a digit nor a dot, invalid attribute oid */
460 if ( ! (isalpha(*p) || isdigit(*p) || (*p == '-'))) {
461 /* not ALPHA, DIGIT or HYPHEN */
502 /* TODO: support ber encoded values
513 /* ok found value terminator */
527 dn->components[dn->comp_num].value.data = (uint8_t *)talloc_strdup(dn->components, dt);
528 dn->components[dn->comp_num].value.length = l;
529 if ( ! dn->components[dn->comp_num].value.data) {
537 if (dn->comp_num > 2) {
538 dn->components = talloc_realloc(dn,
540 struct ldb_dn_component,
542 if ( ! dn->components) {
546 /* make sure all components are zeroed, other functions depend on this */
547 memset(&dn->components[dn->comp_num], '\0', sizeof(struct ldb_dn_component));
560 /* a string with not escaped specials is invalid (tested) */
589 if (sscanf(p, "%02x", &x) != 1) {
590 /* invalid escaping sequence */
597 *d++ = (unsigned char)x;
619 if (in_attr || in_quote) {
625 /* save last element */
633 dn->components[dn->comp_num].value.data = (uint8_t *)talloc_strdup(dn->components, dt);
634 dn->components[dn->comp_num].value.length = l;
636 if ( ! dn->components[dn->comp_num].value.data) {
648 talloc_free(dn->components);
652 bool ldb_dn_validate(struct ldb_dn *dn)
654 return ldb_dn_explode(dn);
657 const char *ldb_dn_get_linearized(struct ldb_dn *dn)
662 if ( ! dn || ( dn->invalid)) return NULL;
664 if (dn->linearized) return dn->linearized;
666 if ( ! dn->components) {
671 if (dn->comp_num == 0) {
672 dn->linearized = talloc_strdup(dn, "");
673 if ( ! dn->linearized) return NULL;
674 return dn->linearized;
677 /* calculate maximum possible length of DN */
678 for (len = 0, i = 0; i < dn->comp_num; i++) {
679 len += strlen(dn->components[i].name); /* name len */
680 len += (dn->components[i].value.length * 3); /* max escaped data len */
681 len += 2; /* '=' and ',' */
683 dn->linearized = talloc_array(dn, char, len);
684 if ( ! dn->linearized) return NULL;
688 for (i = 0; i < dn->comp_num; i++) {
691 n = dn->components[i].name;
692 while (*n) *d++ = *n++;
697 d += ldb_dn_escape_internal( d,
698 (char *)dn->components[i].value.data,
699 dn->components[i].value.length);
705 /* don't waste more memory than necessary */
706 dn->linearized = talloc_realloc(dn, dn->linearized, char, (d - dn->linearized + 1));
708 return dn->linearized;
711 char *ldb_dn_get_extended_linearized(void *mem_ctx, struct ldb_dn *dn, int mode)
713 const char *linearized = ldb_dn_get_linearized(dn);
721 if (!ldb_dn_has_extended(dn)) {
722 return talloc_strdup(mem_ctx, linearized);
725 if (!ldb_dn_validate(dn)) {
729 for (i=0; i < dn->extended_comp_num; i++) {
732 const struct ldb_dn_extended_syntax *extended_syntax;
733 const char *name = dn->extended_components[i].name;
735 extended_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name);
738 ret = extended_syntax->write_clear_fn(dn->ldb, mem_ctx,
739 &dn->extended_components[i].value,
741 } else if (mode == 0) {
742 ret = extended_syntax->write_hex_fn(dn->ldb, mem_ctx,
743 &dn->extended_components[i].value,
749 if (ret != LDB_SUCCESS) {
754 p = talloc_asprintf(mem_ctx, "<%s=%s>", dn->extended_components[i].name, val.data);
756 p = talloc_asprintf_append(p, ";<%s=%s>", dn->extended_components[i].name, val.data);
759 talloc_free(val.data);
766 if (dn->extended_comp_num && *linearized) {
767 p = talloc_asprintf_append(p, ";%s", linearized);
779 char *ldb_dn_alloc_linearized(void *mem_ctx, struct ldb_dn *dn)
781 return talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn));
785 casefold a dn. We need to casefold the attribute names, and canonicalize
786 attribute values of case insensitive attributes.
789 static bool ldb_dn_casefold_internal(struct ldb_dn *dn)
793 if ( ! dn || dn->invalid) return false;
795 if (dn->valid_case) return true;
797 if (( ! dn->components) && ( ! ldb_dn_explode(dn))) {
801 for (i = 0; i < dn->comp_num; i++) {
802 const struct ldb_schema_attribute *a;
804 dn->components[i].cf_name = ldb_attr_casefold(dn->components, dn->components[i].name);
805 if (!dn->components[i].cf_name) {
809 a = ldb_schema_attribute_by_name(dn->ldb, dn->components[i].cf_name);
810 ret = a->syntax->canonicalise_fn(dn->ldb, dn->components,
811 &(dn->components[i].value),
812 &(dn->components[i].cf_value));
818 dn->valid_case = true;
823 for (i = 0; i < dn->comp_num; i++) {
824 LDB_FREE(dn->components[i].cf_name);
825 LDB_FREE(dn->components[i].cf_value.data);
830 const char *ldb_dn_get_casefold(struct ldb_dn *dn)
835 if (dn->casefold) return dn->casefold;
838 dn->casefold = talloc_strdup(dn, dn->linearized);
839 if (!dn->casefold) return NULL;
840 dn->valid_case = true;
844 if ( ! ldb_dn_casefold_internal(dn)) {
848 if (dn->comp_num == 0) {
849 if (dn->linearized && dn->linearized[0] == '\0') {
850 /* hmm a NULL dn, should we faild casefolding ? */
851 dn->casefold = talloc_strdup(dn, "");
854 /* A DN must be NULL, special, or have components */
859 /* calculate maximum possible length of DN */
860 for (len = 0, i = 0; i < dn->comp_num; i++) {
861 len += strlen(dn->components[i].cf_name); /* name len */
862 len += (dn->components[i].cf_value.length * 3); /* max escaped data len */
863 len += 2; /* '=' and ',' */
865 dn->casefold = talloc_array(dn, char, len);
866 if ( ! dn->casefold) return NULL;
870 for (i = 0; i < dn->comp_num; i++) {
873 n = dn->components[i].cf_name;
874 while (*n) *d++ = *n++;
879 d += ldb_dn_escape_internal( d,
880 (char *)dn->components[i].cf_value.data,
881 dn->components[i].cf_value.length);
886 /* don't waste more memory than necessary */
887 dn->casefold = talloc_realloc(dn, dn->casefold, char, strlen(dn->casefold) + 1);
892 char *ldb_dn_alloc_casefold(void *mem_ctx, struct ldb_dn *dn)
894 return talloc_strdup(mem_ctx, ldb_dn_get_casefold(dn));
897 /* Determine if dn is below base, in the ldap tree. Used for
898 * evaluating a subtree search.
899 * 0 if they match, otherwise non-zero
902 int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn)
907 if ( ! base || base->invalid) return 1;
908 if ( ! dn || dn->invalid) return -1;
910 if (( ! base->valid_case) || ( ! dn->valid_case)) {
911 if (base->linearized && dn->linearized) {
912 /* try with a normal compare first, if we are lucky
913 * we will avoid exploding and casfolding */
915 dif = strlen(dn->linearized) - strlen(base->linearized);
916 if (dif < 0) return dif;
917 if (strcmp(base->linearized, &dn->linearized[dif]) == 0) return 0;
920 if ( ! ldb_dn_casefold_internal(base)) {
924 if ( ! ldb_dn_casefold_internal(dn)) {
930 /* if base has more components,
931 * they don't have the same base */
932 if (base->comp_num > dn->comp_num) {
933 return (dn->comp_num - base->comp_num);
936 if (dn->comp_num == 0) {
937 if (dn->special && base->special) {
938 return strcmp(base->linearized, dn->linearized);
939 } else if (dn->special) {
941 } else if (base->special) {
948 n_base = base->comp_num - 1;
949 n_dn = dn->comp_num - 1;
951 while (n_base >= 0) {
952 /* compare attr names */
953 ret = strcmp(base->components[n_base].cf_name, dn->components[n_dn].cf_name);
954 if (ret != 0) return ret;
956 /* compare attr.cf_value. */
957 if (base->components[n_base].cf_value.length != dn->components[n_dn].cf_value.length) {
958 return base->components[n_base].cf_value.length - dn->components[n_dn].cf_value.length;
960 ret = strcmp((char *)base->components[n_base].cf_value.data, (char *)dn->components[n_dn].cf_value.data);
961 if (ret != 0) return ret;
970 /* compare DNs using casefolding compare functions.
972 If they match, then return 0
975 int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1)
979 if (( ! dn0) || dn0->invalid || ! dn1 || dn1->invalid) return -1;
981 if (( ! dn0->valid_case) || ( ! dn1->valid_case)) {
982 if (dn0->linearized && dn1->linearized) {
983 /* try with a normal compare first, if we are lucky
984 * we will avoid exploding and casfolding */
985 if (strcmp(dn0->linearized, dn1->linearized) == 0) return 0;
988 if ( ! ldb_dn_casefold_internal(dn0)) {
992 if ( ! ldb_dn_casefold_internal(dn1)) {
998 if (dn0->comp_num != dn1->comp_num) {
999 return (dn1->comp_num - dn0->comp_num);
1002 if (dn0->comp_num == 0) {
1003 if (dn0->special && dn1->special) {
1004 return strcmp(dn0->linearized, dn1->linearized);
1005 } else if (dn0->special) {
1007 } else if (dn1->special) {
1014 for (i = 0; i < dn0->comp_num; i++) {
1015 /* compare attr names */
1016 ret = strcmp(dn0->components[i].cf_name, dn1->components[i].cf_name);
1017 if (ret != 0) return ret;
1019 /* compare attr.cf_value. */
1020 if (dn0->components[i].cf_value.length != dn1->components[i].cf_value.length) {
1021 return dn0->components[i].cf_value.length - dn1->components[i].cf_value.length;
1023 ret = strcmp((char *)dn0->components[i].cf_value.data, (char *)dn1->components[i].cf_value.data);
1024 if (ret != 0) return ret;
1030 static struct ldb_dn_component ldb_dn_copy_component(void *mem_ctx, struct ldb_dn_component *src)
1032 struct ldb_dn_component dst;
1034 memset(&dst, 0, sizeof(dst));
1040 dst.value = ldb_val_dup(mem_ctx, &(src->value));
1041 if (dst.value.data == NULL) {
1045 dst.name = talloc_strdup(mem_ctx, src->name);
1046 if (dst.name == NULL) {
1047 LDB_FREE(dst.value.data);
1051 if (src->cf_value.data) {
1052 dst.cf_value = ldb_val_dup(mem_ctx, &(src->cf_value));
1053 if (dst.cf_value.data == NULL) {
1054 LDB_FREE(dst.value.data);
1059 dst.cf_name = talloc_strdup(mem_ctx, src->cf_name);
1060 if (dst.cf_name == NULL) {
1061 LDB_FREE(dst.cf_name);
1062 LDB_FREE(dst.value.data);
1067 dst.cf_value.data = NULL;
1074 static struct ldb_dn_extended_component ldb_dn_extended_copy_component(void *mem_ctx, struct ldb_dn_extended_component *src)
1076 struct ldb_dn_extended_component dst;
1078 memset(&dst, 0, sizeof(dst));
1084 dst.value = ldb_val_dup(mem_ctx, &(src->value));
1085 if (dst.value.data == NULL) {
1089 dst.name = talloc_strdup(mem_ctx, src->name);
1090 if (dst.name == NULL) {
1091 LDB_FREE(dst.value.data);
1098 struct ldb_dn *ldb_dn_copy(void *mem_ctx, struct ldb_dn *dn)
1100 struct ldb_dn *new_dn;
1102 if (!dn || dn->invalid) {
1106 new_dn = talloc_zero(mem_ctx, struct ldb_dn);
1113 if (dn->components) {
1116 new_dn->components = talloc_zero_array(new_dn, struct ldb_dn_component, dn->comp_num);
1117 if ( ! new_dn->components) {
1118 talloc_free(new_dn);
1122 for (i = 0; i < dn->comp_num; i++) {
1123 new_dn->components[i] = ldb_dn_copy_component(new_dn->components, &dn->components[i]);
1124 if ( ! new_dn->components[i].value.data) {
1125 talloc_free(new_dn);
1131 if (dn->extended_components) {
1134 new_dn->extended_components = talloc_zero_array(new_dn, struct ldb_dn_extended_component, dn->extended_comp_num);
1135 if ( ! new_dn->extended_components) {
1136 talloc_free(new_dn);
1140 for (i = 0; i < dn->extended_comp_num; i++) {
1141 new_dn->extended_components[i] = ldb_dn_extended_copy_component(new_dn->extended_components, &dn->extended_components[i]);
1142 if ( ! new_dn->extended_components[i].value.data) {
1143 talloc_free(new_dn);
1150 new_dn->casefold = talloc_strdup(new_dn, dn->casefold);
1151 if ( ! new_dn->casefold) {
1152 talloc_free(new_dn);
1157 if (dn->linearized) {
1158 new_dn->linearized = talloc_strdup(new_dn, dn->linearized);
1159 if ( ! new_dn->linearized) {
1160 talloc_free(new_dn);
1165 if (dn->extended_linearized) {
1166 new_dn->extended_linearized = talloc_strdup(new_dn, dn->extended_linearized);
1167 if ( ! new_dn->extended_linearized) {
1168 talloc_free(new_dn);
1176 /* modify the given dn by adding a base.
1178 * return true if successful and false if not
1179 * if false is returned the dn may be marked invalid
1181 bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base)
1186 if ( !base || base->invalid || !dn || dn->invalid) {
1190 if (dn->components) {
1193 if ( ! ldb_dn_validate(base)) {
1198 if (dn->valid_case) {
1199 if ( ! (s = ldb_dn_get_casefold(base))) {
1204 dn->components = talloc_realloc(dn,
1206 struct ldb_dn_component,
1207 dn->comp_num + base->comp_num);
1208 if ( ! dn->components) {
1213 for (i = 0; i < base->comp_num; dn->comp_num++, i++) {
1214 dn->components[dn->comp_num] = ldb_dn_copy_component(dn->components, &base->components[i]);
1215 if (dn->components[dn->comp_num].value.data == NULL) {
1221 if (dn->casefold && s) {
1222 if (*dn->casefold) {
1223 t = talloc_asprintf(dn, "%s,%s", dn->casefold, s);
1225 t = talloc_strdup(dn, s);
1227 LDB_FREE(dn->casefold);
1232 if (dn->linearized) {
1234 s = ldb_dn_get_linearized(base);
1239 if (*dn->linearized) {
1240 t = talloc_asprintf(dn, "%s,%s", dn->linearized, s);
1242 t = talloc_strdup(dn, s);
1248 LDB_FREE(dn->linearized);
1252 /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
1253 if (dn->extended_linearized) {
1254 LDB_FREE(dn->extended_linearized);
1257 LDB_FREE(dn->extended_components);
1258 dn->extended_comp_num = 0;
1262 /* modify the given dn by adding a base.
1264 * return true if successful and false if not
1265 * if false is returned the dn may be marked invalid
1267 bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...)
1269 struct ldb_dn *base;
1274 if ( !dn || dn->invalid) {
1278 va_start(ap, base_fmt);
1279 base_str = talloc_vasprintf(dn, base_fmt, ap);
1282 if (base_str == NULL) {
1286 base = ldb_dn_new(base_str, dn->ldb, base_str);
1288 ret = ldb_dn_add_base(dn, base);
1290 talloc_free(base_str);
1295 /* modify the given dn by adding children elements.
1297 * return true if successful and false if not
1298 * if false is returned the dn may be marked invalid
1300 bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child)
1305 if ( !child || child->invalid || !dn || dn->invalid) {
1309 if (dn->components) {
1312 if ( ! ldb_dn_validate(child)) {
1317 if (dn->valid_case) {
1318 if ( ! (s = ldb_dn_get_casefold(child))) {
1323 n = dn->comp_num + child->comp_num;
1325 dn->components = talloc_realloc(dn,
1327 struct ldb_dn_component,
1329 if ( ! dn->components) {
1334 for (i = dn->comp_num - 1, j = n - 1; i >= 0; i--, j--) {
1335 dn->components[j] = dn->components[i];
1338 for (i = 0; i < child->comp_num; i++) {
1339 dn->components[i] = ldb_dn_copy_component(dn->components, &child->components[i]);
1340 if (dn->components[i].value.data == NULL) {
1348 if (dn->casefold && s) {
1349 t = talloc_asprintf(dn, "%s,%s", s, dn->casefold);
1350 LDB_FREE(dn->casefold);
1355 if (dn->linearized) {
1357 s = ldb_dn_get_linearized(child);
1362 t = talloc_asprintf(dn, "%s,%s", s, dn->linearized);
1367 LDB_FREE(dn->linearized);
1371 /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
1372 LDB_FREE(dn->extended_linearized);
1374 LDB_FREE(dn->extended_components);
1375 dn->extended_comp_num = 0;
1380 /* modify the given dn by adding children elements.
1382 * return true if successful and false if not
1383 * if false is returned the dn may be marked invalid
1385 bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...)
1387 struct ldb_dn *child;
1392 if ( !dn || dn->invalid) {
1396 va_start(ap, child_fmt);
1397 child_str = talloc_vasprintf(dn, child_fmt, ap);
1400 if (child_str == NULL) {
1404 child = ldb_dn_new(child_str, dn->ldb, child_str);
1406 ret = ldb_dn_add_child(dn, child);
1408 talloc_free(child_str);
1413 bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num)
1417 if ( ! ldb_dn_validate(dn)) {
1421 if (dn->comp_num < num) {
1425 /* free components */
1426 for (i = num; i > 0; i--) {
1427 LDB_FREE(dn->components[dn->comp_num - i].name);
1428 LDB_FREE(dn->components[dn->comp_num - i].value.data);
1429 LDB_FREE(dn->components[dn->comp_num - i].cf_name);
1430 LDB_FREE(dn->components[dn->comp_num - i].cf_value.data);
1433 dn->comp_num -= num;
1435 if (dn->valid_case) {
1436 for (i = 0; i < dn->comp_num; i++) {
1437 LDB_FREE(dn->components[i].cf_name);
1438 LDB_FREE(dn->components[i].cf_value.data);
1440 dn->valid_case = false;
1443 LDB_FREE(dn->casefold);
1444 LDB_FREE(dn->linearized);
1446 /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
1447 LDB_FREE(dn->extended_linearized);
1449 LDB_FREE(dn->extended_components);
1450 dn->extended_comp_num = 0;
1455 bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num)
1459 if ( ! ldb_dn_validate(dn)) {
1463 if (dn->comp_num < num) {
1467 for (i = 0, j = num; j < dn->comp_num; i++, j++) {
1469 LDB_FREE(dn->components[i].name);
1470 LDB_FREE(dn->components[i].value.data);
1471 LDB_FREE(dn->components[i].cf_name);
1472 LDB_FREE(dn->components[i].cf_value.data);
1474 dn->components[i] = dn->components[j];
1477 dn->comp_num -= num;
1479 if (dn->valid_case) {
1480 for (i = 0; i < dn->comp_num; i++) {
1481 LDB_FREE(dn->components[i].cf_name);
1482 LDB_FREE(dn->components[i].cf_value.data);
1484 dn->valid_case = false;
1487 LDB_FREE(dn->casefold);
1488 LDB_FREE(dn->linearized);
1490 /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
1491 LDB_FREE(dn->extended_linearized);
1493 LDB_FREE(dn->extended_components);
1494 dn->extended_comp_num = 0;
1498 struct ldb_dn *ldb_dn_get_parent(void *mem_ctx, struct ldb_dn *dn)
1500 struct ldb_dn *new_dn;
1502 new_dn = ldb_dn_copy(mem_ctx, dn);
1507 if ( ! ldb_dn_remove_child_components(new_dn, 1)) {
1508 talloc_free(new_dn);
1512 /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
1513 LDB_FREE(dn->extended_linearized);
1515 LDB_FREE(dn->extended_components);
1516 dn->extended_comp_num = 0;
1520 /* Create a 'canonical name' string from a DN:
1522 ie dc=samba,dc=org -> samba.org/
1523 uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator
1525 There are two formats, the EX format has the last / replaced with a newline (\n).
1528 static char *ldb_dn_canonical(void *mem_ctx, struct ldb_dn *dn, int ex_format) {
1531 char *cracked = NULL;
1532 const char *format = (ex_format ? "\n" : "/" );
1534 if ( ! ldb_dn_validate(dn)) {
1538 tmpctx = talloc_new(mem_ctx);
1540 /* Walk backwards down the DN, grabbing 'dc' components at first */
1541 for (i = dn->comp_num - 1 ; i >= 0; i--) {
1542 if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) {
1546 cracked = talloc_asprintf(tmpctx, "%s.%s",
1547 ldb_dn_escape_value(tmpctx, dn->components[i].value),
1550 cracked = ldb_dn_escape_value(tmpctx, dn->components[i].value);
1557 /* Only domain components? Finish here */
1559 cracked = talloc_strdup_append_buffer(cracked, format);
1560 talloc_steal(mem_ctx, cracked);
1564 /* Now walk backwards appending remaining components */
1565 for (; i > 0; i--) {
1566 cracked = talloc_asprintf_append_buffer(cracked, "/%s",
1567 ldb_dn_escape_value(tmpctx, dn->components[i].value));
1573 /* Last one, possibly a newline for the 'ex' format */
1574 cracked = talloc_asprintf_append_buffer(cracked, "%s%s", format,
1575 ldb_dn_escape_value(tmpctx, dn->components[i].value));
1577 talloc_steal(mem_ctx, cracked);
1579 talloc_free(tmpctx);
1583 /* Wrapper functions for the above, for the two different string formats */
1584 char *ldb_dn_canonical_string(void *mem_ctx, struct ldb_dn *dn) {
1585 return ldb_dn_canonical(mem_ctx, dn, 0);
1589 char *ldb_dn_canonical_ex_string(void *mem_ctx, struct ldb_dn *dn) {
1590 return ldb_dn_canonical(mem_ctx, dn, 1);
1593 int ldb_dn_get_comp_num(struct ldb_dn *dn)
1595 if ( ! ldb_dn_validate(dn)) {
1598 return dn->comp_num;
1601 const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num)
1603 if ( ! ldb_dn_validate(dn)) {
1606 if (num >= dn->comp_num) return NULL;
1607 return dn->components[num].name;
1610 const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn, unsigned int num)
1612 if ( ! ldb_dn_validate(dn)) {
1615 if (num >= dn->comp_num) return NULL;
1616 return &dn->components[num].value;
1619 const char *ldb_dn_get_rdn_name(struct ldb_dn *dn)
1621 if ( ! ldb_dn_validate(dn)) {
1624 if (dn->comp_num == 0) return NULL;
1625 return dn->components[0].name;
1628 const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn)
1630 if ( ! ldb_dn_validate(dn)) {
1633 if (dn->comp_num == 0) return NULL;
1634 return &dn->components[0].value;
1637 int ldb_dn_set_component(struct ldb_dn *dn, int num, const char *name, const struct ldb_val val)
1642 if ( ! ldb_dn_validate(dn)) {
1643 return LDB_ERR_OTHER;
1646 if (num >= dn->comp_num) {
1647 return LDB_ERR_OTHER;
1650 n = talloc_strdup(dn, name);
1652 return LDB_ERR_OTHER;
1655 v.length = val.length;
1656 v.data = (uint8_t *)talloc_memdup(dn, val.data, v.length+1);
1659 return LDB_ERR_OTHER;
1662 talloc_free(dn->components[num].name);
1663 talloc_free(dn->components[num].value.data);
1664 dn->components[num].name = n;
1665 dn->components[num].value = v;
1667 if (dn->valid_case) {
1669 for (i = 0; i < dn->comp_num; i++) {
1670 LDB_FREE(dn->components[i].cf_name);
1671 LDB_FREE(dn->components[i].cf_value.data);
1673 dn->valid_case = false;
1675 LDB_FREE(dn->casefold);
1676 LDB_FREE(dn->linearized);
1678 /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
1679 LDB_FREE(dn->extended_linearized);
1681 dn->extended_comp_num = 0;
1682 LDB_FREE(dn->extended_components);
1686 const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn, const char *name)
1689 if ( ! ldb_dn_validate(dn)) {
1692 for (i=0; i < dn->extended_comp_num; i++) {
1693 if (ldb_attr_cmp(dn->extended_components[i].name, name) == 0) {
1694 return &dn->extended_components[i].value;
1700 int ldb_dn_set_extended_component(struct ldb_dn *dn, const char *name, const struct ldb_val *val)
1702 struct ldb_dn_extended_component *p;
1705 if ( ! ldb_dn_validate(dn)) {
1706 return LDB_ERR_OTHER;
1709 for (i=0; i < dn->extended_comp_num; i++) {
1710 if (ldb_attr_cmp(dn->extended_components[i].name, name) == 0) {
1712 dn->extended_components[i].value = ldb_val_dup(dn->extended_components, val);
1714 dn->extended_components[i].name = talloc_strdup(dn->extended_components, name);
1715 if (!dn->extended_components[i].name || !dn->extended_components[i].value.data) {
1717 return LDB_ERR_OPERATIONS_ERROR;
1721 if (i != (dn->extended_comp_num - 1)) {
1722 memmove(&dn->extended_components[i], &dn->extended_components[i+1],
1723 ((dn->extended_comp_num-1) - i)*sizeof(*dn->extended_components));
1725 dn->extended_comp_num--;
1727 dn->extended_components = talloc_realloc(dn,
1728 dn->extended_components,
1729 struct ldb_dn_extended_component,
1730 dn->extended_comp_num);
1731 if (!dn->extended_components) {
1733 return LDB_ERR_OPERATIONS_ERROR;
1740 p = dn->extended_components
1741 = talloc_realloc(dn,
1742 dn->extended_components,
1743 struct ldb_dn_extended_component,
1744 dn->extended_comp_num + 1);
1745 if (!dn->extended_components) {
1747 return LDB_ERR_OPERATIONS_ERROR;
1750 p[dn->extended_comp_num].value = ldb_val_dup(dn->extended_components, val);
1751 p[dn->extended_comp_num].name = talloc_strdup(p, name);
1753 if (!dn->extended_components[i].name || !dn->extended_components[i].value.data) {
1755 return LDB_ERR_OPERATIONS_ERROR;
1757 dn->extended_components = p;
1758 dn->extended_comp_num++;
1763 void ldb_dn_remove_extended_components(struct ldb_dn *dn)
1765 dn->extended_comp_num = 0;
1766 LDB_FREE(dn->extended_components);
1769 bool ldb_dn_is_valid(struct ldb_dn *dn)
1771 if ( ! dn) return false;
1772 return ! dn->invalid;
1775 bool ldb_dn_is_special(struct ldb_dn *dn)
1777 if ( ! dn || dn->invalid) return false;
1781 bool ldb_dn_has_extended(struct ldb_dn *dn)
1783 if ( ! dn || dn->invalid) return false;
1784 if (dn->extended_linearized && (dn->extended_linearized[0] == '<')) return true;
1785 return dn->extended_comp_num != 0;
1788 bool ldb_dn_check_special(struct ldb_dn *dn, const char *check)
1790 if ( ! dn || dn->invalid) return false;
1791 return ! strcmp(dn->linearized, check);
1794 bool ldb_dn_is_null(struct ldb_dn *dn)
1796 if ( ! dn || dn->invalid) return false;
1797 if (ldb_dn_has_extended(dn)) return false;
1798 if (dn->linearized && (dn->linearized[0] == '\0')) return true;