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 /* it is helpful to be able to break on this in gdb */
83 static void ldb_dn_mark_invalid(struct ldb_dn *dn)
88 /* strdn may be NULL */
89 struct ldb_dn *ldb_dn_from_ldb_val(void *mem_ctx,
90 struct ldb_context *ldb,
91 const struct ldb_val *strdn)
95 if (! ldb) return NULL;
97 if (strdn && strdn->data
98 && (strnlen((const char*)strdn->data, strdn->length) != strdn->length)) {
99 /* The RDN must not contain a character with value 0x0 */
103 dn = talloc_zero(mem_ctx, struct ldb_dn);
104 LDB_DN_NULL_FAILED(dn);
108 if (strdn->data && strdn->length) {
109 const char *data = (const char *)strdn->data;
110 size_t length = strdn->length;
112 if (data[0] == '@') {
115 dn->ext_linearized = talloc_strndup(dn, data, length);
116 LDB_DN_NULL_FAILED(dn->ext_linearized);
118 if (data[0] == '<') {
119 const char *p_save, *p = dn->ext_linearized;
128 if (p_save == dn->ext_linearized) {
129 dn->linearized = talloc_strdup(dn, "");
131 dn->linearized = talloc_strdup(dn, p_save);
133 LDB_DN_NULL_FAILED(dn->linearized);
135 dn->linearized = dn->ext_linearized;
136 dn->ext_linearized = NULL;
139 dn->linearized = talloc_strdup(dn, "");
140 LDB_DN_NULL_FAILED(dn->linearized);
150 /* strdn may be NULL */
151 struct ldb_dn *ldb_dn_new(void *mem_ctx,
152 struct ldb_context *ldb,
156 blob.data = discard_const_p(uint8_t, strdn);
157 blob.length = strdn ? strlen(strdn) : 0;
158 return ldb_dn_from_ldb_val(mem_ctx, ldb, &blob);
161 struct ldb_dn *ldb_dn_new_fmt(void *mem_ctx,
162 struct ldb_context *ldb,
163 const char *new_fmt, ...)
168 if ( (! mem_ctx) || (! ldb)) return NULL;
170 va_start(ap, new_fmt);
171 strdn = talloc_vasprintf(mem_ctx, new_fmt, ap);
175 struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb, strdn);
183 static int ldb_dn_escape_internal(char *dst, const char *src, int len)
192 while (p - src < len) {
194 p += strcspn(p, ",=\n+<>#;\\\"");
196 if (p - src == len) /* found no escapable chars */
199 /* copy the part of the string before the stop */
201 d += (p - s); /* move to current position */
203 if (*p) { /* it is a normal escapable character */
206 } else { /* we have a zero byte in the string */
207 strncpy(d, "\00", 3); /* escape the zero */
209 p++; /* skip the zero */
211 s = p; /* move forward */
214 /* copy the last part (with zero) and return */
218 /* return the length of the resulting string */
219 return (l + (d - dst));
222 char *ldb_dn_escape_value(void *mem_ctx, struct ldb_val value)
229 /* allocate destination string, it will be at most 3 times the source */
230 dst = talloc_array(mem_ctx, char, value.length * 3 + 1);
236 ldb_dn_escape_internal(dst, (const char *)value.data, value.length);
238 dst = talloc_realloc(mem_ctx, dst, char, strlen(dst) + 1);
244 explode a DN string into a ldb_dn structure
245 based on RFC4514 except that we don't support multiple valued RDNs
247 TODO: according to MS-ADTS:3.1.1.5.2 Naming Constraints
248 DN must be compliant with RFC2253
250 static bool ldb_dn_explode(struct ldb_dn *dn)
252 char *p, *ex_name, *ex_value, *data, *d, *dt, *t;
254 bool in_extended = false;
255 bool in_ex_name = false;
256 bool in_ex_value = false;
257 bool in_attr = false;
258 bool in_value = false;
259 bool in_quote = false;
267 if ( ! dn || dn->invalid) return false;
269 if (dn->components) {
273 if (dn->ext_linearized) {
274 parse_dn = dn->ext_linearized;
276 parse_dn = dn->linearized;
283 is_index = (strncmp(parse_dn, "DN=@INDEX:", 10) == 0);
286 if (parse_dn[0] == '\0') {
290 /* Special DNs case */
295 /* make sure we free this if alloced previously before replacing */
296 talloc_free(dn->components);
298 talloc_free(dn->ext_components);
299 dn->ext_components = NULL;
301 /* in the common case we have 3 or more components */
302 /* make sure all components are zeroed, other functions depend on it */
303 dn->components = talloc_zero_array(dn, struct ldb_dn_component, 3);
304 if ( ! dn->components) {
309 /* Components data space is allocated here once */
310 data = talloc_array(dn->components, char, strlen(parse_dn) + 1);
326 if (!in_ex_name && !in_ex_value) {
333 } else if (p[0] == '\0') {
345 if (in_ex_name && *p == '=') {
354 if (in_ex_value && *p == '>') {
355 const struct ldb_dn_extended_syntax *ext_syntax;
356 struct ldb_val ex_val = {
357 .data = (uint8_t *)ex_value,
358 .length = d - ex_value
365 /* Process name and ex_value */
367 dn->ext_components = talloc_realloc(dn,
369 struct ldb_dn_ext_component,
370 dn->ext_comp_num + 1);
371 if ( ! dn->ext_components) {
376 ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, ex_name);
378 /* We don't know about this type of extended DN */
382 dn->ext_components[dn->ext_comp_num].name = talloc_strdup(dn->ext_components, ex_name);
383 if (!dn->ext_components[dn->ext_comp_num].name) {
387 ret = ext_syntax->read_fn(dn->ldb, dn->ext_components,
388 &ex_val, &dn->ext_components[dn->ext_comp_num].value);
389 if (ret != LDB_SUCCESS) {
390 ldb_dn_mark_invalid(dn);
397 /* We have reached the end (extended component only)! */
401 } else if (*p == ';') {
405 ldb_dn_mark_invalid(dn);
424 /* attr names must be ascii only */
425 ldb_dn_mark_invalid(dn);
432 if ( ! isalpha(*p)) {
433 /* not a digit nor an alpha,
434 * invalid attribute name */
435 ldb_dn_mark_invalid(dn);
439 /* Copy this character across from parse_dn,
440 * now we have trimmed out spaces */
447 /* valid only if we are at the end */
452 if (trim && (*p != '=')) {
453 /* spaces/tabs are not allowed */
454 ldb_dn_mark_invalid(dn);
459 /* attribute terminated */
465 /* Terminate this string in d
466 * (which is a copy of parse_dn
467 * with spaces trimmed) */
469 dn->components[dn->comp_num].name = talloc_strdup(dn->components, dt);
470 if ( ! dn->components[dn->comp_num].name) {
482 /* attr names must be ascii only */
483 ldb_dn_mark_invalid(dn);
487 if (is_oid && ( ! (isdigit(*p) || (*p == '.')))) {
488 /* not a digit nor a dot,
489 * invalid attribute oid */
490 ldb_dn_mark_invalid(dn);
493 if ( ! (isalpha(*p) || isdigit(*p) || (*p == '-'))) {
494 /* not ALPHA, DIGIT or HYPHEN */
495 ldb_dn_mark_invalid(dn);
535 /* TODO: support ber encoded values
546 /* ok found value terminator */
560 dn->components[dn->comp_num].value.data = (uint8_t *)talloc_strdup(dn->components, dt);
561 dn->components[dn->comp_num].value.length = l;
562 if ( ! dn->components[dn->comp_num].value.data) {
570 if (dn->comp_num > 2) {
571 dn->components = talloc_realloc(dn,
573 struct ldb_dn_component,
575 if ( ! dn->components) {
579 /* make sure all components are zeroed, other functions depend on this */
580 memset(&dn->components[dn->comp_num], '\0', sizeof(struct ldb_dn_component));
587 /* to main compatibility with earlier
588 versions of ldb indexing, we have to
589 accept the base64 encoded binary index
590 values, which contain a '=' */
604 /* a string with not escaped specials is invalid (tested) */
606 ldb_dn_mark_invalid(dn);
633 if (sscanf(p, "%02x", &x) != 1) {
634 /* invalid escaping sequence */
635 ldb_dn_mark_invalid(dn);
641 *d++ = (unsigned char)x;
663 if (in_attr || in_quote) {
665 ldb_dn_mark_invalid(dn);
669 /* save last element */
677 dn->components[dn->comp_num].value.length = l;
678 dn->components[dn->comp_num].value.data =
679 (uint8_t *)talloc_strdup(dn->components, dt);
680 if ( ! dn->components[dn->comp_num].value.data) {
692 talloc_free(dn->components);
696 bool ldb_dn_validate(struct ldb_dn *dn)
698 return ldb_dn_explode(dn);
701 const char *ldb_dn_get_linearized(struct ldb_dn *dn)
706 if ( ! dn || ( dn->invalid)) return NULL;
708 if (dn->linearized) return dn->linearized;
710 if ( ! dn->components) {
711 ldb_dn_mark_invalid(dn);
715 if (dn->comp_num == 0) {
716 dn->linearized = talloc_strdup(dn, "");
717 if ( ! dn->linearized) return NULL;
718 return dn->linearized;
721 /* calculate maximum possible length of DN */
722 for (len = 0, i = 0; i < dn->comp_num; i++) {
724 len += strlen(dn->components[i].name);
725 /* max escaped data len */
726 len += (dn->components[i].value.length * 3);
727 len += 2; /* '=' and ',' */
729 dn->linearized = talloc_array(dn, char, len);
730 if ( ! dn->linearized) return NULL;
734 for (i = 0; i < dn->comp_num; i++) {
737 n = dn->components[i].name;
738 while (*n) *d++ = *n++;
743 d += ldb_dn_escape_internal( d,
744 (char *)dn->components[i].value.data,
745 dn->components[i].value.length);
751 /* don't waste more memory than necessary */
752 dn->linearized = talloc_realloc(dn, dn->linearized,
753 char, (d - dn->linearized + 1));
755 return dn->linearized;
758 char *ldb_dn_get_extended_linearized(void *mem_ctx, struct ldb_dn *dn, int mode)
760 const char *linearized = ldb_dn_get_linearized(dn);
768 if (!ldb_dn_has_extended(dn)) {
769 return talloc_strdup(mem_ctx, linearized);
772 if (!ldb_dn_validate(dn)) {
776 for (i = 0; i < dn->ext_comp_num; i++) {
777 const struct ldb_dn_extended_syntax *ext_syntax;
778 const char *name = dn->ext_components[i].name;
779 struct ldb_val ec_val = dn->ext_components[i].value;
783 ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name);
786 ret = ext_syntax->write_clear_fn(dn->ldb, mem_ctx,
788 } else if (mode == 0) {
789 ret = ext_syntax->write_hex_fn(dn->ldb, mem_ctx,
795 if (ret != LDB_SUCCESS) {
800 p = talloc_asprintf(mem_ctx, "<%s=%s>",
803 p = talloc_asprintf_append_buffer(p, ";<%s=%s>",
807 talloc_free(val.data);
814 if (dn->ext_comp_num && *linearized) {
815 p = talloc_asprintf_append_buffer(p, ";%s", linearized);
827 char *ldb_dn_alloc_linearized(void *mem_ctx, struct ldb_dn *dn)
829 return talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn));
833 casefold a dn. We need to casefold the attribute names, and canonicalize
834 attribute values of case insensitive attributes.
837 static bool ldb_dn_casefold_internal(struct ldb_dn *dn)
841 if ( ! dn || dn->invalid) return false;
843 if (dn->valid_case) return true;
845 if (( ! dn->components) && ( ! ldb_dn_explode(dn))) {
849 for (i = 0; i < dn->comp_num; i++) {
850 const struct ldb_schema_attribute *a;
852 dn->components[i].cf_name =
853 ldb_attr_casefold(dn->components,
854 dn->components[i].name);
855 if (!dn->components[i].cf_name) {
859 a = ldb_schema_attribute_by_name(dn->ldb,
860 dn->components[i].cf_name);
862 ret = a->syntax->canonicalise_fn(dn->ldb, dn->components,
863 &(dn->components[i].value),
864 &(dn->components[i].cf_value));
870 dn->valid_case = true;
875 for (i = 0; i < dn->comp_num; i++) {
876 LDB_FREE(dn->components[i].cf_name);
877 LDB_FREE(dn->components[i].cf_value.data);
882 const char *ldb_dn_get_casefold(struct ldb_dn *dn)
887 if (dn->casefold) return dn->casefold;
890 dn->casefold = talloc_strdup(dn, dn->linearized);
891 if (!dn->casefold) return NULL;
892 dn->valid_case = true;
896 if ( ! ldb_dn_casefold_internal(dn)) {
900 if (dn->comp_num == 0) {
901 dn->casefold = talloc_strdup(dn, "");
905 /* calculate maximum possible length of DN */
906 for (len = 0, i = 0; i < dn->comp_num; i++) {
908 len += strlen(dn->components[i].cf_name);
909 /* max escaped data len */
910 len += (dn->components[i].cf_value.length * 3);
911 len += 2; /* '=' and ',' */
913 dn->casefold = talloc_array(dn, char, len);
914 if ( ! dn->casefold) return NULL;
918 for (i = 0; i < dn->comp_num; i++) {
921 n = dn->components[i].cf_name;
922 while (*n) *d++ = *n++;
927 d += ldb_dn_escape_internal( d,
928 (char *)dn->components[i].cf_value.data,
929 dn->components[i].cf_value.length);
934 /* don't waste more memory than necessary */
935 dn->casefold = talloc_realloc(dn, dn->casefold,
936 char, strlen(dn->casefold) + 1);
941 char *ldb_dn_alloc_casefold(void *mem_ctx, struct ldb_dn *dn)
943 return talloc_strdup(mem_ctx, ldb_dn_get_casefold(dn));
946 /* Determine if dn is below base, in the ldap tree. Used for
947 * evaluating a subtree search.
948 * 0 if they match, otherwise non-zero
951 int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn)
956 if ( ! base || base->invalid) return 1;
957 if ( ! dn || dn->invalid) return -1;
959 if (( ! base->valid_case) || ( ! dn->valid_case)) {
960 if (base->linearized && dn->linearized) {
961 /* try with a normal compare first, if we are lucky
962 * we will avoid exploding and casfolding */
964 dif = strlen(dn->linearized) - strlen(base->linearized);
968 if (strcmp(base->linearized,
969 &dn->linearized[dif]) == 0) {
974 if ( ! ldb_dn_casefold_internal(base)) {
978 if ( ! ldb_dn_casefold_internal(dn)) {
984 /* if base has more components,
985 * they don't have the same base */
986 if (base->comp_num > dn->comp_num) {
987 return (dn->comp_num - base->comp_num);
990 if (dn->comp_num == 0) {
991 if (dn->special && base->special) {
992 return strcmp(base->linearized, dn->linearized);
993 } else if (dn->special) {
995 } else if (base->special) {
1002 n_base = base->comp_num - 1;
1003 n_dn = dn->comp_num - 1;
1005 while (n_base >= 0) {
1006 char *b_name = base->components[n_base].cf_name;
1007 char *dn_name = dn->components[n_dn].cf_name;
1009 char *b_vdata = (char *)base->components[n_base].cf_value.data;
1010 char *dn_vdata = (char *)dn->components[n_dn].cf_value.data;
1012 size_t b_vlen = base->components[n_base].cf_value.length;
1013 size_t dn_vlen = dn->components[n_dn].cf_value.length;
1015 /* compare attr names */
1016 ret = strcmp(b_name, dn_name);
1017 if (ret != 0) return ret;
1019 /* compare attr.cf_value. */
1020 if (b_vlen != dn_vlen) {
1021 return b_vlen - dn_vlen;
1023 ret = strcmp(b_vdata, dn_vdata);
1024 if (ret != 0) return ret;
1033 /* compare DNs using casefolding compare functions.
1035 If they match, then return 0
1038 int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1)
1042 if (( ! dn0) || dn0->invalid || ! dn1 || dn1->invalid) {
1046 if (( ! dn0->valid_case) || ( ! dn1->valid_case)) {
1047 if (dn0->linearized && dn1->linearized) {
1048 /* try with a normal compare first, if we are lucky
1049 * we will avoid exploding and casfolding */
1050 if (strcmp(dn0->linearized, dn1->linearized) == 0) {
1055 if ( ! ldb_dn_casefold_internal(dn0)) {
1059 if ( ! ldb_dn_casefold_internal(dn1)) {
1065 if (dn0->comp_num != dn1->comp_num) {
1066 return (dn1->comp_num - dn0->comp_num);
1069 if (dn0->comp_num == 0) {
1070 if (dn0->special && dn1->special) {
1071 return strcmp(dn0->linearized, dn1->linearized);
1072 } else if (dn0->special) {
1074 } else if (dn1->special) {
1081 for (i = 0; i < dn0->comp_num; i++) {
1082 char *dn0_name = dn0->components[i].cf_name;
1083 char *dn1_name = dn1->components[i].cf_name;
1085 char *dn0_vdata = (char *)dn0->components[i].cf_value.data;
1086 char *dn1_vdata = (char *)dn1->components[i].cf_value.data;
1088 size_t dn0_vlen = dn0->components[i].cf_value.length;
1089 size_t dn1_vlen = dn1->components[i].cf_value.length;
1091 /* compare attr names */
1092 ret = strcmp(dn0_name, dn1_name);
1097 /* compare attr.cf_value. */
1098 if (dn0_vlen != dn1_vlen) {
1099 return dn0_vlen - dn1_vlen;
1101 ret = strcmp(dn0_vdata, dn1_vdata);
1110 static struct ldb_dn_component ldb_dn_copy_component(
1112 struct ldb_dn_component *src)
1114 struct ldb_dn_component dst;
1116 memset(&dst, 0, sizeof(dst));
1122 dst.value = ldb_val_dup(mem_ctx, &(src->value));
1123 if (dst.value.data == NULL) {
1127 dst.name = talloc_strdup(mem_ctx, src->name);
1128 if (dst.name == NULL) {
1129 LDB_FREE(dst.value.data);
1133 if (src->cf_value.data) {
1134 dst.cf_value = ldb_val_dup(mem_ctx, &(src->cf_value));
1135 if (dst.cf_value.data == NULL) {
1136 LDB_FREE(dst.value.data);
1141 dst.cf_name = talloc_strdup(mem_ctx, src->cf_name);
1142 if (dst.cf_name == NULL) {
1143 LDB_FREE(dst.cf_name);
1144 LDB_FREE(dst.value.data);
1149 dst.cf_value.data = NULL;
1156 static struct ldb_dn_ext_component ldb_dn_ext_copy_component(
1158 struct ldb_dn_ext_component *src)
1160 struct ldb_dn_ext_component dst;
1162 memset(&dst, 0, sizeof(dst));
1168 dst.value = ldb_val_dup(mem_ctx, &(src->value));
1169 if (dst.value.data == NULL) {
1173 dst.name = talloc_strdup(mem_ctx, src->name);
1174 if (dst.name == NULL) {
1175 LDB_FREE(dst.value.data);
1182 struct ldb_dn *ldb_dn_copy(void *mem_ctx, struct ldb_dn *dn)
1184 struct ldb_dn *new_dn;
1186 if (!dn || dn->invalid) {
1190 new_dn = talloc_zero(mem_ctx, struct ldb_dn);
1197 if (dn->components) {
1200 new_dn->components =
1201 talloc_zero_array(new_dn,
1202 struct ldb_dn_component,
1204 if ( ! new_dn->components) {
1205 talloc_free(new_dn);
1209 for (i = 0; i < dn->comp_num; i++) {
1210 new_dn->components[i] =
1211 ldb_dn_copy_component(new_dn->components,
1212 &dn->components[i]);
1213 if ( ! new_dn->components[i].value.data) {
1214 talloc_free(new_dn);
1220 if (dn->ext_components) {
1223 new_dn->ext_components =
1224 talloc_zero_array(new_dn,
1225 struct ldb_dn_ext_component,
1227 if ( ! new_dn->ext_components) {
1228 talloc_free(new_dn);
1232 for (i = 0; i < dn->ext_comp_num; i++) {
1233 new_dn->ext_components[i] =
1234 ldb_dn_ext_copy_component(
1235 new_dn->ext_components,
1236 &dn->ext_components[i]);
1237 if ( ! new_dn->ext_components[i].value.data) {
1238 talloc_free(new_dn);
1245 new_dn->casefold = talloc_strdup(new_dn, dn->casefold);
1246 if ( ! new_dn->casefold) {
1247 talloc_free(new_dn);
1252 if (dn->linearized) {
1253 new_dn->linearized = talloc_strdup(new_dn, dn->linearized);
1254 if ( ! new_dn->linearized) {
1255 talloc_free(new_dn);
1260 if (dn->ext_linearized) {
1261 new_dn->ext_linearized = talloc_strdup(new_dn,
1262 dn->ext_linearized);
1263 if ( ! new_dn->ext_linearized) {
1264 talloc_free(new_dn);
1272 /* modify the given dn by adding a base.
1274 * return true if successful and false if not
1275 * if false is returned the dn may be marked invalid
1277 bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base)
1282 if ( !base || base->invalid || !dn || dn->invalid) {
1286 if (dn->components) {
1289 if ( ! ldb_dn_validate(base)) {
1294 if (dn->valid_case) {
1295 if ( ! (s = ldb_dn_get_casefold(base))) {
1300 dn->components = talloc_realloc(dn,
1302 struct ldb_dn_component,
1303 dn->comp_num + base->comp_num);
1304 if ( ! dn->components) {
1305 ldb_dn_mark_invalid(dn);
1309 for (i = 0; i < base->comp_num; dn->comp_num++, i++) {
1310 dn->components[dn->comp_num] =
1311 ldb_dn_copy_component(dn->components,
1312 &base->components[i]);
1313 if (dn->components[dn->comp_num].value.data == NULL) {
1314 ldb_dn_mark_invalid(dn);
1319 if (dn->casefold && s) {
1320 if (*dn->casefold) {
1321 t = talloc_asprintf(dn, "%s,%s",
1324 t = talloc_strdup(dn, s);
1326 LDB_FREE(dn->casefold);
1331 if (dn->linearized) {
1333 s = ldb_dn_get_linearized(base);
1338 if (*dn->linearized) {
1339 t = talloc_asprintf(dn, "%s,%s",
1342 t = talloc_strdup(dn, s);
1345 ldb_dn_mark_invalid(dn);
1348 LDB_FREE(dn->linearized);
1352 /* Wipe the ext_linearized DN,
1353 * the GUID and SID are almost certainly no longer valid */
1354 if (dn->ext_linearized) {
1355 LDB_FREE(dn->ext_linearized);
1358 LDB_FREE(dn->ext_components);
1359 dn->ext_comp_num = 0;
1363 /* modify the given dn by adding a base.
1365 * return true if successful and false if not
1366 * if false is returned the dn may be marked invalid
1368 bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...)
1370 struct ldb_dn *base;
1375 if ( !dn || dn->invalid) {
1379 va_start(ap, base_fmt);
1380 base_str = talloc_vasprintf(dn, base_fmt, ap);
1383 if (base_str == NULL) {
1387 base = ldb_dn_new(base_str, dn->ldb, base_str);
1389 ret = ldb_dn_add_base(dn, base);
1391 talloc_free(base_str);
1396 /* modify the given dn by adding children elements.
1398 * return true if successful and false if not
1399 * if false is returned the dn may be marked invalid
1401 bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child)
1406 if ( !child || child->invalid || !dn || dn->invalid) {
1410 if (dn->components) {
1413 if ( ! ldb_dn_validate(child)) {
1418 if (dn->valid_case) {
1419 if ( ! (s = ldb_dn_get_casefold(child))) {
1424 n = dn->comp_num + child->comp_num;
1426 dn->components = talloc_realloc(dn,
1428 struct ldb_dn_component,
1430 if ( ! dn->components) {
1431 ldb_dn_mark_invalid(dn);
1435 for (i = dn->comp_num - 1, j = n - 1; i >= 0; i--, j--) {
1436 dn->components[j] = dn->components[i];
1439 for (i = 0; i < child->comp_num; i++) {
1441 ldb_dn_copy_component(dn->components,
1442 &child->components[i]);
1443 if (dn->components[i].value.data == NULL) {
1444 ldb_dn_mark_invalid(dn);
1451 if (dn->casefold && s) {
1452 t = talloc_asprintf(dn, "%s,%s", s, dn->casefold);
1453 LDB_FREE(dn->casefold);
1458 if (dn->linearized) {
1460 s = ldb_dn_get_linearized(child);
1465 t = talloc_asprintf(dn, "%s,%s", s, dn->linearized);
1467 ldb_dn_mark_invalid(dn);
1470 LDB_FREE(dn->linearized);
1474 /* Wipe the ext_linearized DN,
1475 * the GUID and SID are almost certainly no longer valid */
1476 LDB_FREE(dn->ext_linearized);
1478 LDB_FREE(dn->ext_components);
1479 dn->ext_comp_num = 0;
1484 /* modify the given dn by adding children elements.
1486 * return true if successful and false if not
1487 * if false is returned the dn may be marked invalid
1489 bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...)
1491 struct ldb_dn *child;
1496 if ( !dn || dn->invalid) {
1500 va_start(ap, child_fmt);
1501 child_str = talloc_vasprintf(dn, child_fmt, ap);
1504 if (child_str == NULL) {
1508 child = ldb_dn_new(child_str, dn->ldb, child_str);
1510 ret = ldb_dn_add_child(dn, child);
1512 talloc_free(child_str);
1517 bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num)
1521 if ( ! ldb_dn_validate(dn)) {
1525 if (dn->comp_num < num) {
1529 /* free components */
1530 for (i = num; i > 0; i--) {
1531 LDB_FREE(dn->components[dn->comp_num - i].name);
1532 LDB_FREE(dn->components[dn->comp_num - i].value.data);
1533 LDB_FREE(dn->components[dn->comp_num - i].cf_name);
1534 LDB_FREE(dn->components[dn->comp_num - i].cf_value.data);
1537 dn->comp_num -= num;
1539 if (dn->valid_case) {
1540 for (i = 0; i < dn->comp_num; i++) {
1541 LDB_FREE(dn->components[i].cf_name);
1542 LDB_FREE(dn->components[i].cf_value.data);
1544 dn->valid_case = false;
1547 LDB_FREE(dn->casefold);
1548 LDB_FREE(dn->linearized);
1550 /* Wipe the ext_linearized DN,
1551 * the GUID and SID are almost certainly no longer valid */
1552 LDB_FREE(dn->ext_linearized);
1554 LDB_FREE(dn->ext_components);
1555 dn->ext_comp_num = 0;
1560 bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num)
1564 if ( ! ldb_dn_validate(dn)) {
1568 if (dn->comp_num < num) {
1572 for (i = 0, j = num; j < dn->comp_num; i++, j++) {
1574 LDB_FREE(dn->components[i].name);
1575 LDB_FREE(dn->components[i].value.data);
1576 LDB_FREE(dn->components[i].cf_name);
1577 LDB_FREE(dn->components[i].cf_value.data);
1579 dn->components[i] = dn->components[j];
1582 dn->comp_num -= num;
1584 if (dn->valid_case) {
1585 for (i = 0; i < dn->comp_num; i++) {
1586 LDB_FREE(dn->components[i].cf_name);
1587 LDB_FREE(dn->components[i].cf_value.data);
1589 dn->valid_case = false;
1592 LDB_FREE(dn->casefold);
1593 LDB_FREE(dn->linearized);
1595 /* Wipe the ext_linearized DN,
1596 * the GUID and SID are almost certainly no longer valid */
1597 LDB_FREE(dn->ext_linearized);
1599 LDB_FREE(dn->ext_components);
1600 dn->ext_comp_num = 0;
1604 struct ldb_dn *ldb_dn_get_parent(void *mem_ctx, struct ldb_dn *dn)
1606 struct ldb_dn *new_dn;
1608 new_dn = ldb_dn_copy(mem_ctx, dn);
1613 if ( ! ldb_dn_remove_child_components(new_dn, 1)) {
1614 talloc_free(new_dn);
1618 /* Wipe the ext_linearized DN,
1619 * the GUID and SID are almost certainly no longer valid */
1620 LDB_FREE(dn->ext_linearized);
1622 LDB_FREE(dn->ext_components);
1623 dn->ext_comp_num = 0;
1627 /* Create a 'canonical name' string from a DN:
1629 ie dc=samba,dc=org -> samba.org/
1630 uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator
1632 There are two formats,
1633 the EX format has the last '/' replaced with a newline (\n).
1636 static char *ldb_dn_canonical(void *mem_ctx, struct ldb_dn *dn, int ex_format) {
1639 char *cracked = NULL;
1640 const char *format = (ex_format ? "\n" : "/" );
1642 if ( ! ldb_dn_validate(dn)) {
1646 tmpctx = talloc_new(mem_ctx);
1648 /* Walk backwards down the DN, grabbing 'dc' components at first */
1649 for (i = dn->comp_num - 1 ; i >= 0; i--) {
1650 if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) {
1654 cracked = talloc_asprintf(tmpctx, "%s.%s",
1655 ldb_dn_escape_value(tmpctx,
1656 dn->components[i].value),
1659 cracked = ldb_dn_escape_value(tmpctx,
1660 dn->components[i].value);
1667 /* Only domain components? Finish here */
1669 cracked = talloc_strdup_append_buffer(cracked, format);
1670 talloc_steal(mem_ctx, cracked);
1674 /* Now walk backwards appending remaining components */
1675 for (; i > 0; i--) {
1676 cracked = talloc_asprintf_append_buffer(cracked, "/%s",
1677 ldb_dn_escape_value(tmpctx,
1678 dn->components[i].value));
1684 /* Last one, possibly a newline for the 'ex' format */
1685 cracked = talloc_asprintf_append_buffer(cracked, "%s%s", format,
1686 ldb_dn_escape_value(tmpctx,
1687 dn->components[i].value));
1689 talloc_steal(mem_ctx, cracked);
1691 talloc_free(tmpctx);
1695 /* Wrapper functions for the above, for the two different string formats */
1696 char *ldb_dn_canonical_string(void *mem_ctx, struct ldb_dn *dn) {
1697 return ldb_dn_canonical(mem_ctx, dn, 0);
1701 char *ldb_dn_canonical_ex_string(void *mem_ctx, struct ldb_dn *dn) {
1702 return ldb_dn_canonical(mem_ctx, dn, 1);
1705 int ldb_dn_get_comp_num(struct ldb_dn *dn)
1707 if ( ! ldb_dn_validate(dn)) {
1710 return dn->comp_num;
1713 const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num)
1715 if ( ! ldb_dn_validate(dn)) {
1718 if (num >= dn->comp_num) return NULL;
1719 return dn->components[num].name;
1722 const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn,
1725 if ( ! ldb_dn_validate(dn)) {
1728 if (num >= dn->comp_num) return NULL;
1729 return &dn->components[num].value;
1732 const char *ldb_dn_get_rdn_name(struct ldb_dn *dn)
1734 if ( ! ldb_dn_validate(dn)) {
1737 if (dn->comp_num == 0) return NULL;
1738 return dn->components[0].name;
1741 const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn)
1743 if ( ! ldb_dn_validate(dn)) {
1746 if (dn->comp_num == 0) return NULL;
1747 return &dn->components[0].value;
1750 int ldb_dn_set_component(struct ldb_dn *dn, int num,
1751 const char *name, const struct ldb_val val)
1756 if ( ! ldb_dn_validate(dn)) {
1757 return LDB_ERR_OTHER;
1760 if (num >= dn->comp_num) {
1761 return LDB_ERR_OTHER;
1764 n = talloc_strdup(dn, name);
1766 return LDB_ERR_OTHER;
1769 v.length = val.length;
1770 v.data = (uint8_t *)talloc_memdup(dn, val.data, v.length+1);
1773 return LDB_ERR_OTHER;
1776 talloc_free(dn->components[num].name);
1777 talloc_free(dn->components[num].value.data);
1778 dn->components[num].name = n;
1779 dn->components[num].value = v;
1781 if (dn->valid_case) {
1783 for (i = 0; i < dn->comp_num; i++) {
1784 LDB_FREE(dn->components[i].cf_name);
1785 LDB_FREE(dn->components[i].cf_value.data);
1787 dn->valid_case = false;
1789 LDB_FREE(dn->casefold);
1790 LDB_FREE(dn->linearized);
1792 /* Wipe the ext_linearized DN,
1793 * the GUID and SID are almost certainly no longer valid */
1794 LDB_FREE(dn->ext_linearized);
1796 dn->ext_comp_num = 0;
1797 LDB_FREE(dn->ext_components);
1801 const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn,
1805 if ( ! ldb_dn_validate(dn)) {
1808 for (i=0; i < dn->ext_comp_num; i++) {
1809 if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) {
1810 return &dn->ext_components[i].value;
1816 int ldb_dn_set_extended_component(struct ldb_dn *dn,
1817 const char *name, const struct ldb_val *val)
1819 struct ldb_dn_ext_component *p;
1822 if ( ! ldb_dn_validate(dn)) {
1823 return LDB_ERR_OTHER;
1826 for (i=0; i < dn->ext_comp_num; i++) {
1827 if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) {
1829 dn->ext_components[i].value =
1830 ldb_val_dup(dn->ext_components, val);
1832 dn->ext_components[i].name =
1833 talloc_strdup(dn->ext_components, name);
1834 if (!dn->ext_components[i].name ||
1835 !dn->ext_components[i].value.data) {
1836 ldb_dn_mark_invalid(dn);
1837 return LDB_ERR_OPERATIONS_ERROR;
1841 if (i != (dn->ext_comp_num - 1)) {
1842 memmove(&dn->ext_components[i],
1843 &dn->ext_components[i+1],
1844 ((dn->ext_comp_num-1) - i) *
1845 sizeof(*dn->ext_components));
1849 dn->ext_components = talloc_realloc(dn,
1851 struct ldb_dn_ext_component,
1853 if (!dn->ext_components) {
1854 ldb_dn_mark_invalid(dn);
1855 return LDB_ERR_OPERATIONS_ERROR;
1862 p = dn->ext_components
1863 = talloc_realloc(dn,
1865 struct ldb_dn_ext_component,
1866 dn->ext_comp_num + 1);
1867 if (!dn->ext_components) {
1868 ldb_dn_mark_invalid(dn);
1869 return LDB_ERR_OPERATIONS_ERROR;
1872 p[dn->ext_comp_num].value = ldb_val_dup(dn->ext_components, val);
1873 p[dn->ext_comp_num].name = talloc_strdup(p, name);
1875 if (!dn->ext_components[i].name || !dn->ext_components[i].value.data) {
1876 ldb_dn_mark_invalid(dn);
1877 return LDB_ERR_OPERATIONS_ERROR;
1879 dn->ext_components = p;
1885 void ldb_dn_remove_extended_components(struct ldb_dn *dn)
1887 dn->ext_comp_num = 0;
1888 LDB_FREE(dn->ext_components);
1891 bool ldb_dn_is_valid(struct ldb_dn *dn)
1893 if ( ! dn) return false;
1894 return ! dn->invalid;
1897 bool ldb_dn_is_special(struct ldb_dn *dn)
1899 if ( ! dn || dn->invalid) return false;
1903 bool ldb_dn_has_extended(struct ldb_dn *dn)
1905 if ( ! dn || dn->invalid) return false;
1906 if (dn->ext_linearized && (dn->ext_linearized[0] == '<')) return true;
1907 return dn->ext_comp_num != 0;
1910 bool ldb_dn_check_special(struct ldb_dn *dn, const char *check)
1912 if ( ! dn || dn->invalid) return false;
1913 return ! strcmp(dn->linearized, check);
1916 bool ldb_dn_is_null(struct ldb_dn *dn)
1918 if ( ! dn || dn->invalid) return false;
1919 if (ldb_dn_has_extended(dn)) return false;
1920 if (dn->linearized && (dn->linearized[0] == '\0')) return true;