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_ext_component {
63 struct ldb_context *ldb;
65 /* Special DNs are always linearized */
75 unsigned int comp_num;
76 struct ldb_dn_component *components;
78 unsigned int ext_comp_num;
79 struct ldb_dn_ext_component *ext_components;
82 /* strdn may be NULL */
83 struct ldb_dn *ldb_dn_from_ldb_val(void *mem_ctx,
84 struct ldb_context *ldb,
85 const struct ldb_val *strdn)
89 if (! ldb) return NULL;
91 if (strdn && strdn->data
92 && (strlen((const char*)strdn->data) != strdn->length)) {
93 /* The RDN must not contain a character with value 0x0 */
97 dn = talloc_zero(mem_ctx, struct ldb_dn);
98 LDB_DN_NULL_FAILED(dn);
102 if (strdn->data && strdn->length) {
103 const char *data = (const char *)strdn->data;
104 size_t length = strdn->length;
106 if (data[0] == '@') {
109 dn->ext_linearized = talloc_strndup(dn, data, length);
110 LDB_DN_NULL_FAILED(dn->ext_linearized);
112 if (data[0] == '<') {
113 const char *p_save, *p = dn->ext_linearized;
122 if (p_save == dn->ext_linearized) {
123 dn->linearized = talloc_strdup(dn, "");
125 dn->linearized = talloc_strdup(dn, p_save);
127 LDB_DN_NULL_FAILED(dn->linearized);
129 dn->linearized = dn->ext_linearized;
130 dn->ext_linearized = NULL;
133 dn->linearized = talloc_strdup(dn, "");
134 LDB_DN_NULL_FAILED(dn->linearized);
144 /* strdn may be NULL */
145 struct ldb_dn *ldb_dn_new(void *mem_ctx,
146 struct ldb_context *ldb,
151 blob.length = strdn ? strlen(strdn) : 0;
152 return ldb_dn_from_ldb_val(mem_ctx, ldb, &blob);
155 struct ldb_dn *ldb_dn_new_fmt(void *mem_ctx,
156 struct ldb_context *ldb,
157 const char *new_fmt, ...)
162 if ( (! mem_ctx) || (! ldb)) return NULL;
164 va_start(ap, new_fmt);
165 strdn = talloc_vasprintf(mem_ctx, new_fmt, ap);
169 struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb, strdn);
177 static int ldb_dn_escape_internal(char *dst, const char *src, int len)
186 while (p - src < len) {
188 p += strcspn(p, ",=\n+<>#;\\\"");
190 if (p - src == len) /* found no escapable chars */
193 /* copy the part of the string before the stop */
195 d += (p - s); /* move to current position */
197 if (*p) { /* it is a normal escapable character */
200 } else { /* we have a zero byte in the string */
201 strncpy(d, "\00", 3); /* escape the zero */
203 p++; /* skip the zero */
205 s = p; /* move forward */
208 /* copy the last part (with zero) and return */
212 /* return the length of the resulting string */
213 return (l + (d - dst));
216 char *ldb_dn_escape_value(void *mem_ctx, struct ldb_val value)
223 /* allocate destination string, it will be at most 3 times the source */
224 dst = talloc_array(mem_ctx, char, value.length * 3 + 1);
230 ldb_dn_escape_internal(dst, (const char *)value.data, value.length);
232 dst = talloc_realloc(mem_ctx, dst, char, strlen(dst) + 1);
238 explode a DN string into a ldb_dn structure
239 based on RFC4514 except that we don't support multiple valued RDNs
241 TODO: according to MS-ADTS:3.1.1.5.2 Naming Constraints
242 DN must be compliant with RFC2253
244 static bool ldb_dn_explode(struct ldb_dn *dn)
246 char *p, *ex_name, *ex_value, *data, *d, *dt, *t;
248 bool in_extended = false;
249 bool in_ex_name = false;
250 bool in_ex_value = false;
251 bool in_attr = false;
252 bool in_value = false;
253 bool in_quote = false;
260 if ( ! dn || dn->invalid) return false;
262 if (dn->components) {
266 if (dn->ext_linearized) {
267 parse_dn = dn->ext_linearized;
269 parse_dn = dn->linearized;
276 /* The RDN size must be less than 255 characters */
277 if (strlen(parse_dn) > 255) {
282 if (parse_dn[0] == '\0') {
286 /* Special DNs case */
291 /* make sure we free this if alloced previously before replacing */
292 talloc_free(dn->components);
294 talloc_free(dn->ext_components);
295 dn->ext_components = NULL;
297 /* in the common case we have 3 or more components */
298 /* make sure all components are zeroed, other functions depend on it */
299 dn->components = talloc_zero_array(dn, struct ldb_dn_component, 3);
300 if ( ! dn->components) {
305 /* Components data space is allocated here once */
306 data = talloc_array(dn->components, char, strlen(parse_dn) + 1);
322 if (!in_ex_name && !in_ex_value) {
329 } else if (p[0] == '\0') {
341 if (in_ex_name && *p == '=') {
350 if (in_ex_value && *p == '>') {
351 const struct ldb_dn_extended_syntax *ext_syntax;
352 struct ldb_val ex_val = {
353 .data = (uint8_t *)ex_value,
354 .length = d - ex_value
361 /* Process name and ex_value */
363 dn->ext_components = talloc_realloc(dn,
365 struct ldb_dn_ext_component,
366 dn->ext_comp_num + 1);
367 if ( ! dn->ext_components) {
372 ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, ex_name);
374 /* We don't know about this type of extended DN */
378 dn->ext_components[dn->ext_comp_num].name = talloc_strdup(dn->ext_components, ex_name);
379 if (!dn->ext_components[dn->ext_comp_num].name) {
383 ret = ext_syntax->read_fn(dn->ldb, dn->ext_components,
384 &ex_val, &dn->ext_components[dn->ext_comp_num].value);
385 if (ret != LDB_SUCCESS) {
393 /* We have reached the end (extended component only)! */
397 } else if (*p == ';') {
420 /* attr names must be ascii only */
428 if ( ! isalpha(*p)) {
429 /* not a digit nor an alpha,
430 * invalid attribute name */
435 /* Copy this character across from parse_dn,
436 * now we have trimmed out spaces */
443 /* valid only if we are at the end */
448 if (trim && (*p != '=')) {
449 /* spaces/tabs are not allowed */
455 /* attribute terminated */
461 /* Terminate this string in d
462 * (which is a copy of parse_dn
463 * with spaces trimmed) */
465 dn->components[dn->comp_num].name = talloc_strdup(dn->components, dt);
466 if ( ! dn->components[dn->comp_num].name) {
478 /* attr names must be ascii only */
483 if (is_oid && ( ! (isdigit(*p) || (*p == '.')))) {
484 /* not a digit nor a dot,
485 * invalid attribute oid */
489 if ( ! (isalpha(*p) || isdigit(*p) || (*p == '-'))) {
490 /* not ALPHA, DIGIT or HYPHEN */
531 /* TODO: support ber encoded values
542 /* ok found value terminator */
556 dn->components[dn->comp_num].value.data = (uint8_t *)talloc_strdup(dn->components, dt);
557 dn->components[dn->comp_num].value.length = l;
558 if ( ! dn->components[dn->comp_num].value.data) {
566 if (dn->comp_num > 2) {
567 dn->components = talloc_realloc(dn,
569 struct ldb_dn_component,
571 if ( ! dn->components) {
575 /* make sure all components are zeroed, other functions depend on this */
576 memset(&dn->components[dn->comp_num], '\0', sizeof(struct ldb_dn_component));
589 /* a string with not escaped specials is invalid (tested) */
618 if (sscanf(p, "%02x", &x) != 1) {
619 /* invalid escaping sequence */
626 *d++ = (unsigned char)x;
648 if (in_attr || in_quote) {
654 /* save last element */
662 dn->components[dn->comp_num].value.length = l;
663 dn->components[dn->comp_num].value.data =
664 (uint8_t *)talloc_strdup(dn->components, dt);
665 if ( ! dn->components[dn->comp_num].value.data) {
677 talloc_free(dn->components);
681 bool ldb_dn_validate(struct ldb_dn *dn)
683 return ldb_dn_explode(dn);
686 const char *ldb_dn_get_linearized(struct ldb_dn *dn)
691 if ( ! dn || ( dn->invalid)) return NULL;
693 if (dn->linearized) return dn->linearized;
695 if ( ! dn->components) {
700 if (dn->comp_num == 0) {
701 dn->linearized = talloc_strdup(dn, "");
702 if ( ! dn->linearized) return NULL;
703 return dn->linearized;
706 /* calculate maximum possible length of DN */
707 for (len = 0, i = 0; i < dn->comp_num; i++) {
709 len += strlen(dn->components[i].name);
710 /* max escaped data len */
711 len += (dn->components[i].value.length * 3);
712 len += 2; /* '=' and ',' */
714 dn->linearized = talloc_array(dn, char, len);
715 if ( ! dn->linearized) return NULL;
719 for (i = 0; i < dn->comp_num; i++) {
722 n = dn->components[i].name;
723 while (*n) *d++ = *n++;
728 d += ldb_dn_escape_internal( d,
729 (char *)dn->components[i].value.data,
730 dn->components[i].value.length);
736 /* don't waste more memory than necessary */
737 dn->linearized = talloc_realloc(dn, dn->linearized,
738 char, (d - dn->linearized + 1));
740 return dn->linearized;
743 char *ldb_dn_get_extended_linearized(void *mem_ctx, struct ldb_dn *dn, int mode)
745 const char *linearized = ldb_dn_get_linearized(dn);
753 if (!ldb_dn_has_extended(dn)) {
754 return talloc_strdup(mem_ctx, linearized);
757 if (!ldb_dn_validate(dn)) {
761 for (i = 0; i < dn->ext_comp_num; i++) {
762 const struct ldb_dn_extended_syntax *ext_syntax;
763 const char *name = dn->ext_components[i].name;
764 struct ldb_val ec_val = dn->ext_components[i].value;
768 ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name);
771 ret = ext_syntax->write_clear_fn(dn->ldb, mem_ctx,
773 } else if (mode == 0) {
774 ret = ext_syntax->write_hex_fn(dn->ldb, mem_ctx,
780 if (ret != LDB_SUCCESS) {
785 p = talloc_asprintf(mem_ctx, "<%s=%s>",
788 p = talloc_asprintf_append(p, ";<%s=%s>",
792 talloc_free(val.data);
799 if (dn->ext_comp_num && *linearized) {
800 p = talloc_asprintf_append(p, ";%s", linearized);
812 char *ldb_dn_alloc_linearized(void *mem_ctx, struct ldb_dn *dn)
814 return talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn));
818 casefold a dn. We need to casefold the attribute names, and canonicalize
819 attribute values of case insensitive attributes.
822 static bool ldb_dn_casefold_internal(struct ldb_dn *dn)
826 if ( ! dn || dn->invalid) return false;
828 if (dn->valid_case) return true;
830 if (( ! dn->components) && ( ! ldb_dn_explode(dn))) {
834 for (i = 0; i < dn->comp_num; i++) {
835 const struct ldb_schema_attribute *a;
837 dn->components[i].cf_name =
838 ldb_attr_casefold(dn->components,
839 dn->components[i].name);
840 if (!dn->components[i].cf_name) {
844 a = ldb_schema_attribute_by_name(dn->ldb,
845 dn->components[i].cf_name);
847 ret = a->syntax->canonicalise_fn(dn->ldb, dn->components,
848 &(dn->components[i].value),
849 &(dn->components[i].cf_value));
855 dn->valid_case = true;
860 for (i = 0; i < dn->comp_num; i++) {
861 LDB_FREE(dn->components[i].cf_name);
862 LDB_FREE(dn->components[i].cf_value.data);
867 const char *ldb_dn_get_casefold(struct ldb_dn *dn)
872 if (dn->casefold) return dn->casefold;
875 dn->casefold = talloc_strdup(dn, dn->linearized);
876 if (!dn->casefold) return NULL;
877 dn->valid_case = true;
881 if ( ! ldb_dn_casefold_internal(dn)) {
885 if (dn->comp_num == 0) {
886 dn->casefold = talloc_strdup(dn, "");
890 /* calculate maximum possible length of DN */
891 for (len = 0, i = 0; i < dn->comp_num; i++) {
893 len += strlen(dn->components[i].cf_name);
894 /* max escaped data len */
895 len += (dn->components[i].cf_value.length * 3);
896 len += 2; /* '=' and ',' */
898 dn->casefold = talloc_array(dn, char, len);
899 if ( ! dn->casefold) return NULL;
903 for (i = 0; i < dn->comp_num; i++) {
906 n = dn->components[i].cf_name;
907 while (*n) *d++ = *n++;
912 d += ldb_dn_escape_internal( d,
913 (char *)dn->components[i].cf_value.data,
914 dn->components[i].cf_value.length);
919 /* don't waste more memory than necessary */
920 dn->casefold = talloc_realloc(dn, dn->casefold,
921 char, strlen(dn->casefold) + 1);
926 char *ldb_dn_alloc_casefold(void *mem_ctx, struct ldb_dn *dn)
928 return talloc_strdup(mem_ctx, ldb_dn_get_casefold(dn));
931 /* Determine if dn is below base, in the ldap tree. Used for
932 * evaluating a subtree search.
933 * 0 if they match, otherwise non-zero
936 int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn)
941 if ( ! base || base->invalid) return 1;
942 if ( ! dn || dn->invalid) return -1;
944 if (( ! base->valid_case) || ( ! dn->valid_case)) {
945 if (base->linearized && dn->linearized) {
946 /* try with a normal compare first, if we are lucky
947 * we will avoid exploding and casfolding */
949 dif = strlen(dn->linearized) - strlen(base->linearized);
953 if (strcmp(base->linearized,
954 &dn->linearized[dif]) == 0) {
959 if ( ! ldb_dn_casefold_internal(base)) {
963 if ( ! ldb_dn_casefold_internal(dn)) {
969 /* if base has more components,
970 * they don't have the same base */
971 if (base->comp_num > dn->comp_num) {
972 return (dn->comp_num - base->comp_num);
975 if (dn->comp_num == 0) {
976 if (dn->special && base->special) {
977 return strcmp(base->linearized, dn->linearized);
978 } else if (dn->special) {
980 } else if (base->special) {
987 n_base = base->comp_num - 1;
988 n_dn = dn->comp_num - 1;
990 while (n_base >= 0) {
991 char *b_name = base->components[n_base].cf_name;
992 char *dn_name = dn->components[n_dn].cf_name;
994 char *b_vdata = (char *)base->components[n_base].cf_value.data;
995 char *dn_vdata = (char *)dn->components[n_dn].cf_value.data;
997 size_t b_vlen = base->components[n_base].cf_value.length;
998 size_t dn_vlen = dn->components[n_dn].cf_value.length;
1000 /* compare attr names */
1001 ret = strcmp(b_name, dn_name);
1002 if (ret != 0) return ret;
1004 /* compare attr.cf_value. */
1005 if (b_vlen != dn_vlen) {
1006 return b_vlen - dn_vlen;
1008 ret = strcmp(b_vdata, dn_vdata);
1009 if (ret != 0) return ret;
1018 /* compare DNs using casefolding compare functions.
1020 If they match, then return 0
1023 int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1)
1027 if (( ! dn0) || dn0->invalid || ! dn1 || dn1->invalid) {
1031 if (( ! dn0->valid_case) || ( ! dn1->valid_case)) {
1032 if (dn0->linearized && dn1->linearized) {
1033 /* try with a normal compare first, if we are lucky
1034 * we will avoid exploding and casfolding */
1035 if (strcmp(dn0->linearized, dn1->linearized) == 0) {
1040 if ( ! ldb_dn_casefold_internal(dn0)) {
1044 if ( ! ldb_dn_casefold_internal(dn1)) {
1050 if (dn0->comp_num != dn1->comp_num) {
1051 return (dn1->comp_num - dn0->comp_num);
1054 if (dn0->comp_num == 0) {
1055 if (dn0->special && dn1->special) {
1056 return strcmp(dn0->linearized, dn1->linearized);
1057 } else if (dn0->special) {
1059 } else if (dn1->special) {
1066 for (i = 0; i < dn0->comp_num; i++) {
1067 char *dn0_name = dn0->components[i].cf_name;
1068 char *dn1_name = dn1->components[i].cf_name;
1070 char *dn0_vdata = (char *)dn0->components[i].cf_value.data;
1071 char *dn1_vdata = (char *)dn1->components[i].cf_value.data;
1073 size_t dn0_vlen = dn0->components[i].cf_value.length;
1074 size_t dn1_vlen = dn1->components[i].cf_value.length;
1076 /* compare attr names */
1077 ret = strcmp(dn0_name, dn1_name);
1082 /* compare attr.cf_value. */
1083 if (dn0_vlen != dn1_vlen) {
1084 return dn0_vlen - dn1_vlen;
1086 ret = strcmp(dn0_vdata, dn1_vdata);
1095 static struct ldb_dn_component ldb_dn_copy_component(
1097 struct ldb_dn_component *src)
1099 struct ldb_dn_component dst;
1101 memset(&dst, 0, sizeof(dst));
1107 dst.value = ldb_val_dup(mem_ctx, &(src->value));
1108 if (dst.value.data == NULL) {
1112 dst.name = talloc_strdup(mem_ctx, src->name);
1113 if (dst.name == NULL) {
1114 LDB_FREE(dst.value.data);
1118 if (src->cf_value.data) {
1119 dst.cf_value = ldb_val_dup(mem_ctx, &(src->cf_value));
1120 if (dst.cf_value.data == NULL) {
1121 LDB_FREE(dst.value.data);
1126 dst.cf_name = talloc_strdup(mem_ctx, src->cf_name);
1127 if (dst.cf_name == NULL) {
1128 LDB_FREE(dst.cf_name);
1129 LDB_FREE(dst.value.data);
1134 dst.cf_value.data = NULL;
1141 static struct ldb_dn_ext_component ldb_dn_ext_copy_component(
1143 struct ldb_dn_ext_component *src)
1145 struct ldb_dn_ext_component dst;
1147 memset(&dst, 0, sizeof(dst));
1153 dst.value = ldb_val_dup(mem_ctx, &(src->value));
1154 if (dst.value.data == NULL) {
1158 dst.name = talloc_strdup(mem_ctx, src->name);
1159 if (dst.name == NULL) {
1160 LDB_FREE(dst.value.data);
1167 struct ldb_dn *ldb_dn_copy(void *mem_ctx, struct ldb_dn *dn)
1169 struct ldb_dn *new_dn;
1171 if (!dn || dn->invalid) {
1175 new_dn = talloc_zero(mem_ctx, struct ldb_dn);
1182 if (dn->components) {
1185 new_dn->components =
1186 talloc_zero_array(new_dn,
1187 struct ldb_dn_component,
1189 if ( ! new_dn->components) {
1190 talloc_free(new_dn);
1194 for (i = 0; i < dn->comp_num; i++) {
1195 new_dn->components[i] =
1196 ldb_dn_copy_component(new_dn->components,
1197 &dn->components[i]);
1198 if ( ! new_dn->components[i].value.data) {
1199 talloc_free(new_dn);
1205 if (dn->ext_components) {
1208 new_dn->ext_components =
1209 talloc_zero_array(new_dn,
1210 struct ldb_dn_ext_component,
1212 if ( ! new_dn->ext_components) {
1213 talloc_free(new_dn);
1217 for (i = 0; i < dn->ext_comp_num; i++) {
1218 new_dn->ext_components[i] =
1219 ldb_dn_ext_copy_component(
1220 new_dn->ext_components,
1221 &dn->ext_components[i]);
1222 if ( ! new_dn->ext_components[i].value.data) {
1223 talloc_free(new_dn);
1230 new_dn->casefold = talloc_strdup(new_dn, dn->casefold);
1231 if ( ! new_dn->casefold) {
1232 talloc_free(new_dn);
1237 if (dn->linearized) {
1238 new_dn->linearized = talloc_strdup(new_dn, dn->linearized);
1239 if ( ! new_dn->linearized) {
1240 talloc_free(new_dn);
1245 if (dn->ext_linearized) {
1246 new_dn->ext_linearized = talloc_strdup(new_dn,
1247 dn->ext_linearized);
1248 if ( ! new_dn->ext_linearized) {
1249 talloc_free(new_dn);
1257 /* modify the given dn by adding a base.
1259 * return true if successful and false if not
1260 * if false is returned the dn may be marked invalid
1262 bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base)
1267 if ( !base || base->invalid || !dn || dn->invalid) {
1271 if (dn->components) {
1274 if ( ! ldb_dn_validate(base)) {
1279 if (dn->valid_case) {
1280 if ( ! (s = ldb_dn_get_casefold(base))) {
1285 dn->components = talloc_realloc(dn,
1287 struct ldb_dn_component,
1288 dn->comp_num + base->comp_num);
1289 if ( ! dn->components) {
1294 for (i = 0; i < base->comp_num; dn->comp_num++, i++) {
1295 dn->components[dn->comp_num] =
1296 ldb_dn_copy_component(dn->components,
1297 &base->components[i]);
1298 if (dn->components[dn->comp_num].value.data == NULL) {
1304 if (dn->casefold && s) {
1305 if (*dn->casefold) {
1306 t = talloc_asprintf(dn, "%s,%s",
1309 t = talloc_strdup(dn, s);
1311 LDB_FREE(dn->casefold);
1316 if (dn->linearized) {
1318 s = ldb_dn_get_linearized(base);
1323 if (*dn->linearized) {
1324 t = talloc_asprintf(dn, "%s,%s",
1327 t = talloc_strdup(dn, s);
1333 LDB_FREE(dn->linearized);
1337 /* Wipe the ext_linearized DN,
1338 * the GUID and SID are almost certainly no longer valid */
1339 if (dn->ext_linearized) {
1340 LDB_FREE(dn->ext_linearized);
1343 LDB_FREE(dn->ext_components);
1344 dn->ext_comp_num = 0;
1348 /* modify the given dn by adding a base.
1350 * return true if successful and false if not
1351 * if false is returned the dn may be marked invalid
1353 bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...)
1355 struct ldb_dn *base;
1360 if ( !dn || dn->invalid) {
1364 va_start(ap, base_fmt);
1365 base_str = talloc_vasprintf(dn, base_fmt, ap);
1368 if (base_str == NULL) {
1372 base = ldb_dn_new(base_str, dn->ldb, base_str);
1374 ret = ldb_dn_add_base(dn, base);
1376 talloc_free(base_str);
1381 /* modify the given dn by adding children elements.
1383 * return true if successful and false if not
1384 * if false is returned the dn may be marked invalid
1386 bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child)
1391 if ( !child || child->invalid || !dn || dn->invalid) {
1395 if (dn->components) {
1398 if ( ! ldb_dn_validate(child)) {
1403 if (dn->valid_case) {
1404 if ( ! (s = ldb_dn_get_casefold(child))) {
1409 n = dn->comp_num + child->comp_num;
1411 dn->components = talloc_realloc(dn,
1413 struct ldb_dn_component,
1415 if ( ! dn->components) {
1420 for (i = dn->comp_num - 1, j = n - 1; i >= 0; i--, j--) {
1421 dn->components[j] = dn->components[i];
1424 for (i = 0; i < child->comp_num; i++) {
1426 ldb_dn_copy_component(dn->components,
1427 &child->components[i]);
1428 if (dn->components[i].value.data == NULL) {
1436 if (dn->casefold && s) {
1437 t = talloc_asprintf(dn, "%s,%s", s, dn->casefold);
1438 LDB_FREE(dn->casefold);
1443 if (dn->linearized) {
1445 s = ldb_dn_get_linearized(child);
1450 t = talloc_asprintf(dn, "%s,%s", s, dn->linearized);
1455 LDB_FREE(dn->linearized);
1459 /* Wipe the ext_linearized DN,
1460 * the GUID and SID are almost certainly no longer valid */
1461 LDB_FREE(dn->ext_linearized);
1463 LDB_FREE(dn->ext_components);
1464 dn->ext_comp_num = 0;
1469 /* modify the given dn by adding children elements.
1471 * return true if successful and false if not
1472 * if false is returned the dn may be marked invalid
1474 bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...)
1476 struct ldb_dn *child;
1481 if ( !dn || dn->invalid) {
1485 va_start(ap, child_fmt);
1486 child_str = talloc_vasprintf(dn, child_fmt, ap);
1489 if (child_str == NULL) {
1493 child = ldb_dn_new(child_str, dn->ldb, child_str);
1495 ret = ldb_dn_add_child(dn, child);
1497 talloc_free(child_str);
1502 bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num)
1506 if ( ! ldb_dn_validate(dn)) {
1510 if (dn->comp_num < num) {
1514 /* free components */
1515 for (i = num; i > 0; i--) {
1516 LDB_FREE(dn->components[dn->comp_num - i].name);
1517 LDB_FREE(dn->components[dn->comp_num - i].value.data);
1518 LDB_FREE(dn->components[dn->comp_num - i].cf_name);
1519 LDB_FREE(dn->components[dn->comp_num - i].cf_value.data);
1522 dn->comp_num -= num;
1524 if (dn->valid_case) {
1525 for (i = 0; i < dn->comp_num; i++) {
1526 LDB_FREE(dn->components[i].cf_name);
1527 LDB_FREE(dn->components[i].cf_value.data);
1529 dn->valid_case = false;
1532 LDB_FREE(dn->casefold);
1533 LDB_FREE(dn->linearized);
1535 /* Wipe the ext_linearized DN,
1536 * the GUID and SID are almost certainly no longer valid */
1537 LDB_FREE(dn->ext_linearized);
1539 LDB_FREE(dn->ext_components);
1540 dn->ext_comp_num = 0;
1545 bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num)
1549 if ( ! ldb_dn_validate(dn)) {
1553 if (dn->comp_num < num) {
1557 for (i = 0, j = num; j < dn->comp_num; i++, j++) {
1559 LDB_FREE(dn->components[i].name);
1560 LDB_FREE(dn->components[i].value.data);
1561 LDB_FREE(dn->components[i].cf_name);
1562 LDB_FREE(dn->components[i].cf_value.data);
1564 dn->components[i] = dn->components[j];
1567 dn->comp_num -= num;
1569 if (dn->valid_case) {
1570 for (i = 0; i < dn->comp_num; i++) {
1571 LDB_FREE(dn->components[i].cf_name);
1572 LDB_FREE(dn->components[i].cf_value.data);
1574 dn->valid_case = false;
1577 LDB_FREE(dn->casefold);
1578 LDB_FREE(dn->linearized);
1580 /* Wipe the ext_linearized DN,
1581 * the GUID and SID are almost certainly no longer valid */
1582 LDB_FREE(dn->ext_linearized);
1584 LDB_FREE(dn->ext_components);
1585 dn->ext_comp_num = 0;
1589 struct ldb_dn *ldb_dn_get_parent(void *mem_ctx, struct ldb_dn *dn)
1591 struct ldb_dn *new_dn;
1593 new_dn = ldb_dn_copy(mem_ctx, dn);
1598 if ( ! ldb_dn_remove_child_components(new_dn, 1)) {
1599 talloc_free(new_dn);
1603 /* Wipe the ext_linearized DN,
1604 * the GUID and SID are almost certainly no longer valid */
1605 LDB_FREE(dn->ext_linearized);
1607 LDB_FREE(dn->ext_components);
1608 dn->ext_comp_num = 0;
1612 /* Create a 'canonical name' string from a DN:
1614 ie dc=samba,dc=org -> samba.org/
1615 uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator
1617 There are two formats,
1618 the EX format has the last '/' replaced with a newline (\n).
1621 static char *ldb_dn_canonical(void *mem_ctx, struct ldb_dn *dn, int ex_format) {
1624 char *cracked = NULL;
1625 const char *format = (ex_format ? "\n" : "/" );
1627 if ( ! ldb_dn_validate(dn)) {
1631 tmpctx = talloc_new(mem_ctx);
1633 /* Walk backwards down the DN, grabbing 'dc' components at first */
1634 for (i = dn->comp_num - 1 ; i >= 0; i--) {
1635 if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) {
1639 cracked = talloc_asprintf(tmpctx, "%s.%s",
1640 ldb_dn_escape_value(tmpctx,
1641 dn->components[i].value),
1644 cracked = ldb_dn_escape_value(tmpctx,
1645 dn->components[i].value);
1652 /* Only domain components? Finish here */
1654 cracked = talloc_strdup_append_buffer(cracked, format);
1655 talloc_steal(mem_ctx, cracked);
1659 /* Now walk backwards appending remaining components */
1660 for (; i > 0; i--) {
1661 cracked = talloc_asprintf_append_buffer(cracked, "/%s",
1662 ldb_dn_escape_value(tmpctx,
1663 dn->components[i].value));
1669 /* Last one, possibly a newline for the 'ex' format */
1670 cracked = talloc_asprintf_append_buffer(cracked, "%s%s", format,
1671 ldb_dn_escape_value(tmpctx,
1672 dn->components[i].value));
1674 talloc_steal(mem_ctx, cracked);
1676 talloc_free(tmpctx);
1680 /* Wrapper functions for the above, for the two different string formats */
1681 char *ldb_dn_canonical_string(void *mem_ctx, struct ldb_dn *dn) {
1682 return ldb_dn_canonical(mem_ctx, dn, 0);
1686 char *ldb_dn_canonical_ex_string(void *mem_ctx, struct ldb_dn *dn) {
1687 return ldb_dn_canonical(mem_ctx, dn, 1);
1690 int ldb_dn_get_comp_num(struct ldb_dn *dn)
1692 if ( ! ldb_dn_validate(dn)) {
1695 return dn->comp_num;
1698 const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num)
1700 if ( ! ldb_dn_validate(dn)) {
1703 if (num >= dn->comp_num) return NULL;
1704 return dn->components[num].name;
1707 const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn,
1710 if ( ! ldb_dn_validate(dn)) {
1713 if (num >= dn->comp_num) return NULL;
1714 return &dn->components[num].value;
1717 const char *ldb_dn_get_rdn_name(struct ldb_dn *dn)
1719 if ( ! ldb_dn_validate(dn)) {
1722 if (dn->comp_num == 0) return NULL;
1723 return dn->components[0].name;
1726 const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn)
1728 if ( ! ldb_dn_validate(dn)) {
1731 if (dn->comp_num == 0) return NULL;
1732 return &dn->components[0].value;
1735 int ldb_dn_set_component(struct ldb_dn *dn, int num,
1736 const char *name, const struct ldb_val val)
1741 if ( ! ldb_dn_validate(dn)) {
1742 return LDB_ERR_OTHER;
1745 if (num >= dn->comp_num) {
1746 return LDB_ERR_OTHER;
1749 n = talloc_strdup(dn, name);
1751 return LDB_ERR_OTHER;
1754 v.length = val.length;
1755 v.data = (uint8_t *)talloc_memdup(dn, val.data, v.length+1);
1758 return LDB_ERR_OTHER;
1761 talloc_free(dn->components[num].name);
1762 talloc_free(dn->components[num].value.data);
1763 dn->components[num].name = n;
1764 dn->components[num].value = v;
1766 if (dn->valid_case) {
1768 for (i = 0; i < dn->comp_num; i++) {
1769 LDB_FREE(dn->components[i].cf_name);
1770 LDB_FREE(dn->components[i].cf_value.data);
1772 dn->valid_case = false;
1774 LDB_FREE(dn->casefold);
1775 LDB_FREE(dn->linearized);
1777 /* Wipe the ext_linearized DN,
1778 * the GUID and SID are almost certainly no longer valid */
1779 LDB_FREE(dn->ext_linearized);
1781 dn->ext_comp_num = 0;
1782 LDB_FREE(dn->ext_components);
1786 const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn,
1790 if ( ! ldb_dn_validate(dn)) {
1793 for (i=0; i < dn->ext_comp_num; i++) {
1794 if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) {
1795 return &dn->ext_components[i].value;
1801 int ldb_dn_set_extended_component(struct ldb_dn *dn,
1802 const char *name, const struct ldb_val *val)
1804 struct ldb_dn_ext_component *p;
1807 if ( ! ldb_dn_validate(dn)) {
1808 return LDB_ERR_OTHER;
1811 for (i=0; i < dn->ext_comp_num; i++) {
1812 if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) {
1814 dn->ext_components[i].value =
1815 ldb_val_dup(dn->ext_components, val);
1817 dn->ext_components[i].name =
1818 talloc_strdup(dn->ext_components, name);
1819 if (!dn->ext_components[i].name ||
1820 !dn->ext_components[i].value.data) {
1822 return LDB_ERR_OPERATIONS_ERROR;
1826 if (i != (dn->ext_comp_num - 1)) {
1827 memmove(&dn->ext_components[i],
1828 &dn->ext_components[i+1],
1829 ((dn->ext_comp_num-1) - i) *
1830 sizeof(*dn->ext_components));
1834 dn->ext_components = talloc_realloc(dn,
1836 struct ldb_dn_ext_component,
1838 if (!dn->ext_components) {
1840 return LDB_ERR_OPERATIONS_ERROR;
1847 p = dn->ext_components
1848 = talloc_realloc(dn,
1850 struct ldb_dn_ext_component,
1851 dn->ext_comp_num + 1);
1852 if (!dn->ext_components) {
1854 return LDB_ERR_OPERATIONS_ERROR;
1857 p[dn->ext_comp_num].value = ldb_val_dup(dn->ext_components, val);
1858 p[dn->ext_comp_num].name = talloc_strdup(p, name);
1860 if (!dn->ext_components[i].name || !dn->ext_components[i].value.data) {
1862 return LDB_ERR_OPERATIONS_ERROR;
1864 dn->ext_components = p;
1870 void ldb_dn_remove_extended_components(struct ldb_dn *dn)
1872 dn->ext_comp_num = 0;
1873 LDB_FREE(dn->ext_components);
1876 bool ldb_dn_is_valid(struct ldb_dn *dn)
1878 if ( ! dn) return false;
1879 return ! dn->invalid;
1882 bool ldb_dn_is_special(struct ldb_dn *dn)
1884 if ( ! dn || dn->invalid) return false;
1888 bool ldb_dn_has_extended(struct ldb_dn *dn)
1890 if ( ! dn || dn->invalid) return false;
1891 if (dn->ext_linearized && (dn->ext_linearized[0] == '<')) return true;
1892 return dn->ext_comp_num != 0;
1895 bool ldb_dn_check_special(struct ldb_dn *dn, const char *check)
1897 if ( ! dn || dn->invalid) return false;
1898 return ! strcmp(dn->linearized, check);
1901 bool ldb_dn_is_null(struct ldb_dn *dn)
1903 if ( ! dn || dn->invalid) return false;
1904 if (ldb_dn_has_extended(dn)) return false;
1905 if (dn->linearized && (dn->linearized[0] == '\0')) return true;