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 dn->casefold = talloc_strdup(dn, "");
853 /* calculate maximum possible length of DN */
854 for (len = 0, i = 0; i < dn->comp_num; i++) {
855 len += strlen(dn->components[i].cf_name); /* name len */
856 len += (dn->components[i].cf_value.length * 3); /* max escaped data len */
857 len += 2; /* '=' and ',' */
859 dn->casefold = talloc_array(dn, char, len);
860 if ( ! dn->casefold) return NULL;
864 for (i = 0; i < dn->comp_num; i++) {
867 n = dn->components[i].cf_name;
868 while (*n) *d++ = *n++;
873 d += ldb_dn_escape_internal( d,
874 (char *)dn->components[i].cf_value.data,
875 dn->components[i].cf_value.length);
880 /* don't waste more memory than necessary */
881 dn->casefold = talloc_realloc(dn, dn->casefold, char, strlen(dn->casefold) + 1);
886 char *ldb_dn_alloc_casefold(void *mem_ctx, struct ldb_dn *dn)
888 return talloc_strdup(mem_ctx, ldb_dn_get_casefold(dn));
891 /* Determine if dn is below base, in the ldap tree. Used for
892 * evaluating a subtree search.
893 * 0 if they match, otherwise non-zero
896 int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn)
901 if ( ! base || base->invalid) return 1;
902 if ( ! dn || dn->invalid) return -1;
904 if (( ! base->valid_case) || ( ! dn->valid_case)) {
905 if (base->linearized && dn->linearized) {
906 /* try with a normal compare first, if we are lucky
907 * we will avoid exploding and casfolding */
909 dif = strlen(dn->linearized) - strlen(base->linearized);
910 if (dif < 0) return dif;
911 if (strcmp(base->linearized, &dn->linearized[dif]) == 0) return 0;
914 if ( ! ldb_dn_casefold_internal(base)) {
918 if ( ! ldb_dn_casefold_internal(dn)) {
924 /* if base has more components,
925 * they don't have the same base */
926 if (base->comp_num > dn->comp_num) {
927 return (dn->comp_num - base->comp_num);
930 if (dn->comp_num == 0) {
931 if (dn->special && base->special) {
932 return strcmp(base->linearized, dn->linearized);
933 } else if (dn->special) {
935 } else if (base->special) {
942 n_base = base->comp_num - 1;
943 n_dn = dn->comp_num - 1;
945 while (n_base >= 0) {
946 /* compare attr names */
947 ret = strcmp(base->components[n_base].cf_name, dn->components[n_dn].cf_name);
948 if (ret != 0) return ret;
950 /* compare attr.cf_value. */
951 if (base->components[n_base].cf_value.length != dn->components[n_dn].cf_value.length) {
952 return base->components[n_base].cf_value.length - dn->components[n_dn].cf_value.length;
954 ret = strcmp((char *)base->components[n_base].cf_value.data, (char *)dn->components[n_dn].cf_value.data);
955 if (ret != 0) return ret;
964 /* compare DNs using casefolding compare functions.
966 If they match, then return 0
969 int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1)
973 if (( ! dn0) || dn0->invalid || ! dn1 || dn1->invalid) return -1;
975 if (( ! dn0->valid_case) || ( ! dn1->valid_case)) {
976 if (dn0->linearized && dn1->linearized) {
977 /* try with a normal compare first, if we are lucky
978 * we will avoid exploding and casfolding */
979 if (strcmp(dn0->linearized, dn1->linearized) == 0) return 0;
982 if ( ! ldb_dn_casefold_internal(dn0)) {
986 if ( ! ldb_dn_casefold_internal(dn1)) {
992 if (dn0->comp_num != dn1->comp_num) {
993 return (dn1->comp_num - dn0->comp_num);
996 if (dn0->comp_num == 0) {
997 if (dn0->special && dn1->special) {
998 return strcmp(dn0->linearized, dn1->linearized);
999 } else if (dn0->special) {
1001 } else if (dn1->special) {
1008 for (i = 0; i < dn0->comp_num; i++) {
1009 /* compare attr names */
1010 ret = strcmp(dn0->components[i].cf_name, dn1->components[i].cf_name);
1011 if (ret != 0) return ret;
1013 /* compare attr.cf_value. */
1014 if (dn0->components[i].cf_value.length != dn1->components[i].cf_value.length) {
1015 return dn0->components[i].cf_value.length - dn1->components[i].cf_value.length;
1017 ret = strcmp((char *)dn0->components[i].cf_value.data, (char *)dn1->components[i].cf_value.data);
1018 if (ret != 0) return ret;
1024 static struct ldb_dn_component ldb_dn_copy_component(void *mem_ctx, struct ldb_dn_component *src)
1026 struct ldb_dn_component dst;
1028 memset(&dst, 0, sizeof(dst));
1034 dst.value = ldb_val_dup(mem_ctx, &(src->value));
1035 if (dst.value.data == NULL) {
1039 dst.name = talloc_strdup(mem_ctx, src->name);
1040 if (dst.name == NULL) {
1041 LDB_FREE(dst.value.data);
1045 if (src->cf_value.data) {
1046 dst.cf_value = ldb_val_dup(mem_ctx, &(src->cf_value));
1047 if (dst.cf_value.data == NULL) {
1048 LDB_FREE(dst.value.data);
1053 dst.cf_name = talloc_strdup(mem_ctx, src->cf_name);
1054 if (dst.cf_name == NULL) {
1055 LDB_FREE(dst.cf_name);
1056 LDB_FREE(dst.value.data);
1061 dst.cf_value.data = NULL;
1068 static struct ldb_dn_extended_component ldb_dn_extended_copy_component(void *mem_ctx, struct ldb_dn_extended_component *src)
1070 struct ldb_dn_extended_component dst;
1072 memset(&dst, 0, sizeof(dst));
1078 dst.value = ldb_val_dup(mem_ctx, &(src->value));
1079 if (dst.value.data == NULL) {
1083 dst.name = talloc_strdup(mem_ctx, src->name);
1084 if (dst.name == NULL) {
1085 LDB_FREE(dst.value.data);
1092 struct ldb_dn *ldb_dn_copy(void *mem_ctx, struct ldb_dn *dn)
1094 struct ldb_dn *new_dn;
1096 if (!dn || dn->invalid) {
1100 new_dn = talloc_zero(mem_ctx, struct ldb_dn);
1107 if (dn->components) {
1110 new_dn->components = talloc_zero_array(new_dn, struct ldb_dn_component, dn->comp_num);
1111 if ( ! new_dn->components) {
1112 talloc_free(new_dn);
1116 for (i = 0; i < dn->comp_num; i++) {
1117 new_dn->components[i] = ldb_dn_copy_component(new_dn->components, &dn->components[i]);
1118 if ( ! new_dn->components[i].value.data) {
1119 talloc_free(new_dn);
1125 if (dn->extended_components) {
1128 new_dn->extended_components = talloc_zero_array(new_dn, struct ldb_dn_extended_component, dn->extended_comp_num);
1129 if ( ! new_dn->extended_components) {
1130 talloc_free(new_dn);
1134 for (i = 0; i < dn->extended_comp_num; i++) {
1135 new_dn->extended_components[i] = ldb_dn_extended_copy_component(new_dn->extended_components, &dn->extended_components[i]);
1136 if ( ! new_dn->extended_components[i].value.data) {
1137 talloc_free(new_dn);
1144 new_dn->casefold = talloc_strdup(new_dn, dn->casefold);
1145 if ( ! new_dn->casefold) {
1146 talloc_free(new_dn);
1151 if (dn->linearized) {
1152 new_dn->linearized = talloc_strdup(new_dn, dn->linearized);
1153 if ( ! new_dn->linearized) {
1154 talloc_free(new_dn);
1159 if (dn->extended_linearized) {
1160 new_dn->extended_linearized = talloc_strdup(new_dn, dn->extended_linearized);
1161 if ( ! new_dn->extended_linearized) {
1162 talloc_free(new_dn);
1170 /* modify the given dn by adding a base.
1172 * return true if successful and false if not
1173 * if false is returned the dn may be marked invalid
1175 bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base)
1180 if ( !base || base->invalid || !dn || dn->invalid) {
1184 if (dn->components) {
1187 if ( ! ldb_dn_validate(base)) {
1192 if (dn->valid_case) {
1193 if ( ! (s = ldb_dn_get_casefold(base))) {
1198 dn->components = talloc_realloc(dn,
1200 struct ldb_dn_component,
1201 dn->comp_num + base->comp_num);
1202 if ( ! dn->components) {
1207 for (i = 0; i < base->comp_num; dn->comp_num++, i++) {
1208 dn->components[dn->comp_num] = ldb_dn_copy_component(dn->components, &base->components[i]);
1209 if (dn->components[dn->comp_num].value.data == NULL) {
1215 if (dn->casefold && s) {
1216 if (*dn->casefold) {
1217 t = talloc_asprintf(dn, "%s,%s", dn->casefold, s);
1219 t = talloc_strdup(dn, s);
1221 LDB_FREE(dn->casefold);
1226 if (dn->linearized) {
1228 s = ldb_dn_get_linearized(base);
1233 if (*dn->linearized) {
1234 t = talloc_asprintf(dn, "%s,%s", dn->linearized, s);
1236 t = talloc_strdup(dn, s);
1242 LDB_FREE(dn->linearized);
1246 /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
1247 if (dn->extended_linearized) {
1248 LDB_FREE(dn->extended_linearized);
1251 LDB_FREE(dn->extended_components);
1252 dn->extended_comp_num = 0;
1256 /* modify the given dn by adding a base.
1258 * return true if successful and false if not
1259 * if false is returned the dn may be marked invalid
1261 bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...)
1263 struct ldb_dn *base;
1268 if ( !dn || dn->invalid) {
1272 va_start(ap, base_fmt);
1273 base_str = talloc_vasprintf(dn, base_fmt, ap);
1276 if (base_str == NULL) {
1280 base = ldb_dn_new(base_str, dn->ldb, base_str);
1282 ret = ldb_dn_add_base(dn, base);
1284 talloc_free(base_str);
1289 /* modify the given dn by adding children elements.
1291 * return true if successful and false if not
1292 * if false is returned the dn may be marked invalid
1294 bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child)
1299 if ( !child || child->invalid || !dn || dn->invalid) {
1303 if (dn->components) {
1306 if ( ! ldb_dn_validate(child)) {
1311 if (dn->valid_case) {
1312 if ( ! (s = ldb_dn_get_casefold(child))) {
1317 n = dn->comp_num + child->comp_num;
1319 dn->components = talloc_realloc(dn,
1321 struct ldb_dn_component,
1323 if ( ! dn->components) {
1328 for (i = dn->comp_num - 1, j = n - 1; i >= 0; i--, j--) {
1329 dn->components[j] = dn->components[i];
1332 for (i = 0; i < child->comp_num; i++) {
1333 dn->components[i] = ldb_dn_copy_component(dn->components, &child->components[i]);
1334 if (dn->components[i].value.data == NULL) {
1342 if (dn->casefold && s) {
1343 t = talloc_asprintf(dn, "%s,%s", s, dn->casefold);
1344 LDB_FREE(dn->casefold);
1349 if (dn->linearized) {
1351 s = ldb_dn_get_linearized(child);
1356 t = talloc_asprintf(dn, "%s,%s", s, dn->linearized);
1361 LDB_FREE(dn->linearized);
1365 /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
1366 LDB_FREE(dn->extended_linearized);
1368 LDB_FREE(dn->extended_components);
1369 dn->extended_comp_num = 0;
1374 /* modify the given dn by adding children elements.
1376 * return true if successful and false if not
1377 * if false is returned the dn may be marked invalid
1379 bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...)
1381 struct ldb_dn *child;
1386 if ( !dn || dn->invalid) {
1390 va_start(ap, child_fmt);
1391 child_str = talloc_vasprintf(dn, child_fmt, ap);
1394 if (child_str == NULL) {
1398 child = ldb_dn_new(child_str, dn->ldb, child_str);
1400 ret = ldb_dn_add_child(dn, child);
1402 talloc_free(child_str);
1407 bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num)
1411 if ( ! ldb_dn_validate(dn)) {
1415 if (dn->comp_num < num) {
1419 /* free components */
1420 for (i = num; i > 0; i--) {
1421 LDB_FREE(dn->components[dn->comp_num - i].name);
1422 LDB_FREE(dn->components[dn->comp_num - i].value.data);
1423 LDB_FREE(dn->components[dn->comp_num - i].cf_name);
1424 LDB_FREE(dn->components[dn->comp_num - i].cf_value.data);
1427 dn->comp_num -= num;
1429 if (dn->valid_case) {
1430 for (i = 0; i < dn->comp_num; i++) {
1431 LDB_FREE(dn->components[i].cf_name);
1432 LDB_FREE(dn->components[i].cf_value.data);
1434 dn->valid_case = false;
1437 LDB_FREE(dn->casefold);
1438 LDB_FREE(dn->linearized);
1440 /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
1441 LDB_FREE(dn->extended_linearized);
1443 LDB_FREE(dn->extended_components);
1444 dn->extended_comp_num = 0;
1449 bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num)
1453 if ( ! ldb_dn_validate(dn)) {
1457 if (dn->comp_num < num) {
1461 for (i = 0, j = num; j < dn->comp_num; i++, j++) {
1463 LDB_FREE(dn->components[i].name);
1464 LDB_FREE(dn->components[i].value.data);
1465 LDB_FREE(dn->components[i].cf_name);
1466 LDB_FREE(dn->components[i].cf_value.data);
1468 dn->components[i] = dn->components[j];
1471 dn->comp_num -= num;
1473 if (dn->valid_case) {
1474 for (i = 0; i < dn->comp_num; i++) {
1475 LDB_FREE(dn->components[i].cf_name);
1476 LDB_FREE(dn->components[i].cf_value.data);
1478 dn->valid_case = false;
1481 LDB_FREE(dn->casefold);
1482 LDB_FREE(dn->linearized);
1484 /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
1485 LDB_FREE(dn->extended_linearized);
1487 LDB_FREE(dn->extended_components);
1488 dn->extended_comp_num = 0;
1492 struct ldb_dn *ldb_dn_get_parent(void *mem_ctx, struct ldb_dn *dn)
1494 struct ldb_dn *new_dn;
1496 new_dn = ldb_dn_copy(mem_ctx, dn);
1501 if ( ! ldb_dn_remove_child_components(new_dn, 1)) {
1502 talloc_free(new_dn);
1506 /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
1507 LDB_FREE(dn->extended_linearized);
1509 LDB_FREE(dn->extended_components);
1510 dn->extended_comp_num = 0;
1514 /* Create a 'canonical name' string from a DN:
1516 ie dc=samba,dc=org -> samba.org/
1517 uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator
1519 There are two formats, the EX format has the last / replaced with a newline (\n).
1522 static char *ldb_dn_canonical(void *mem_ctx, struct ldb_dn *dn, int ex_format) {
1525 char *cracked = NULL;
1526 const char *format = (ex_format ? "\n" : "/" );
1528 if ( ! ldb_dn_validate(dn)) {
1532 tmpctx = talloc_new(mem_ctx);
1534 /* Walk backwards down the DN, grabbing 'dc' components at first */
1535 for (i = dn->comp_num - 1 ; i >= 0; i--) {
1536 if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) {
1540 cracked = talloc_asprintf(tmpctx, "%s.%s",
1541 ldb_dn_escape_value(tmpctx, dn->components[i].value),
1544 cracked = ldb_dn_escape_value(tmpctx, dn->components[i].value);
1551 /* Only domain components? Finish here */
1553 cracked = talloc_strdup_append_buffer(cracked, format);
1554 talloc_steal(mem_ctx, cracked);
1558 /* Now walk backwards appending remaining components */
1559 for (; i > 0; i--) {
1560 cracked = talloc_asprintf_append_buffer(cracked, "/%s",
1561 ldb_dn_escape_value(tmpctx, dn->components[i].value));
1567 /* Last one, possibly a newline for the 'ex' format */
1568 cracked = talloc_asprintf_append_buffer(cracked, "%s%s", format,
1569 ldb_dn_escape_value(tmpctx, dn->components[i].value));
1571 talloc_steal(mem_ctx, cracked);
1573 talloc_free(tmpctx);
1577 /* Wrapper functions for the above, for the two different string formats */
1578 char *ldb_dn_canonical_string(void *mem_ctx, struct ldb_dn *dn) {
1579 return ldb_dn_canonical(mem_ctx, dn, 0);
1583 char *ldb_dn_canonical_ex_string(void *mem_ctx, struct ldb_dn *dn) {
1584 return ldb_dn_canonical(mem_ctx, dn, 1);
1587 int ldb_dn_get_comp_num(struct ldb_dn *dn)
1589 if ( ! ldb_dn_validate(dn)) {
1592 return dn->comp_num;
1595 const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num)
1597 if ( ! ldb_dn_validate(dn)) {
1600 if (num >= dn->comp_num) return NULL;
1601 return dn->components[num].name;
1604 const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn, unsigned int num)
1606 if ( ! ldb_dn_validate(dn)) {
1609 if (num >= dn->comp_num) return NULL;
1610 return &dn->components[num].value;
1613 const char *ldb_dn_get_rdn_name(struct ldb_dn *dn)
1615 if ( ! ldb_dn_validate(dn)) {
1618 if (dn->comp_num == 0) return NULL;
1619 return dn->components[0].name;
1622 const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn)
1624 if ( ! ldb_dn_validate(dn)) {
1627 if (dn->comp_num == 0) return NULL;
1628 return &dn->components[0].value;
1631 int ldb_dn_set_component(struct ldb_dn *dn, int num, const char *name, const struct ldb_val val)
1636 if ( ! ldb_dn_validate(dn)) {
1637 return LDB_ERR_OTHER;
1640 if (num >= dn->comp_num) {
1641 return LDB_ERR_OTHER;
1644 n = talloc_strdup(dn, name);
1646 return LDB_ERR_OTHER;
1649 v.length = val.length;
1650 v.data = (uint8_t *)talloc_memdup(dn, val.data, v.length+1);
1653 return LDB_ERR_OTHER;
1656 talloc_free(dn->components[num].name);
1657 talloc_free(dn->components[num].value.data);
1658 dn->components[num].name = n;
1659 dn->components[num].value = v;
1661 if (dn->valid_case) {
1663 for (i = 0; i < dn->comp_num; i++) {
1664 LDB_FREE(dn->components[i].cf_name);
1665 LDB_FREE(dn->components[i].cf_value.data);
1667 dn->valid_case = false;
1669 LDB_FREE(dn->casefold);
1670 LDB_FREE(dn->linearized);
1672 /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
1673 LDB_FREE(dn->extended_linearized);
1675 dn->extended_comp_num = 0;
1676 LDB_FREE(dn->extended_components);
1680 const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn, const char *name)
1683 if ( ! ldb_dn_validate(dn)) {
1686 for (i=0; i < dn->extended_comp_num; i++) {
1687 if (ldb_attr_cmp(dn->extended_components[i].name, name) == 0) {
1688 return &dn->extended_components[i].value;
1694 int ldb_dn_set_extended_component(struct ldb_dn *dn, const char *name, const struct ldb_val *val)
1696 struct ldb_dn_extended_component *p;
1699 if ( ! ldb_dn_validate(dn)) {
1700 return LDB_ERR_OTHER;
1703 for (i=0; i < dn->extended_comp_num; i++) {
1704 if (ldb_attr_cmp(dn->extended_components[i].name, name) == 0) {
1706 dn->extended_components[i].value = ldb_val_dup(dn->extended_components, val);
1708 dn->extended_components[i].name = talloc_strdup(dn->extended_components, name);
1709 if (!dn->extended_components[i].name || !dn->extended_components[i].value.data) {
1711 return LDB_ERR_OPERATIONS_ERROR;
1715 if (i != (dn->extended_comp_num - 1)) {
1716 memmove(&dn->extended_components[i], &dn->extended_components[i+1],
1717 ((dn->extended_comp_num-1) - i)*sizeof(*dn->extended_components));
1719 dn->extended_comp_num--;
1721 dn->extended_components = talloc_realloc(dn,
1722 dn->extended_components,
1723 struct ldb_dn_extended_component,
1724 dn->extended_comp_num);
1725 if (!dn->extended_components) {
1727 return LDB_ERR_OPERATIONS_ERROR;
1734 p = dn->extended_components
1735 = talloc_realloc(dn,
1736 dn->extended_components,
1737 struct ldb_dn_extended_component,
1738 dn->extended_comp_num + 1);
1739 if (!dn->extended_components) {
1741 return LDB_ERR_OPERATIONS_ERROR;
1744 p[dn->extended_comp_num].value = ldb_val_dup(dn->extended_components, val);
1745 p[dn->extended_comp_num].name = talloc_strdup(p, name);
1747 if (!dn->extended_components[i].name || !dn->extended_components[i].value.data) {
1749 return LDB_ERR_OPERATIONS_ERROR;
1751 dn->extended_components = p;
1752 dn->extended_comp_num++;
1757 void ldb_dn_remove_extended_components(struct ldb_dn *dn)
1759 dn->extended_comp_num = 0;
1760 LDB_FREE(dn->extended_components);
1763 bool ldb_dn_is_valid(struct ldb_dn *dn)
1765 if ( ! dn) return false;
1766 return ! dn->invalid;
1769 bool ldb_dn_is_special(struct ldb_dn *dn)
1771 if ( ! dn || dn->invalid) return false;
1775 bool ldb_dn_has_extended(struct ldb_dn *dn)
1777 if ( ! dn || dn->invalid) return false;
1778 if (dn->extended_linearized && (dn->extended_linearized[0] == '<')) return true;
1779 return dn->extended_comp_num != 0;
1782 bool ldb_dn_check_special(struct ldb_dn *dn, const char *check)
1784 if ( ! dn || dn->invalid) return false;
1785 return ! strcmp(dn->linearized, check);
1788 bool ldb_dn_is_null(struct ldb_dn *dn)
1790 if ( ! dn || dn->invalid) return false;
1791 if (ldb_dn_has_extended(dn)) return false;
1792 if (dn->linearized && (dn->linearized[0] == '\0')) return true;