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 /* see RFC2253 section 2.4 */
184 static int ldb_dn_escape_internal(char *dst, const char *src, int len)
193 while (p - src < len) {
194 p += strcspn(p, ",=\n\r+<>#;\\\" ");
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 */
205 if (p == src || (p-src)==(len-1)) {
206 /* if at the beginning or end
207 * of the string then escape */
211 /* otherwise don't escape */
217 /* despite the RFC, windows escapes a #
218 anywhere in the string */
226 /* these must be escaped using \c form */
232 /* any others get \XX form */
234 const char *hexbytes = "0123456789ABCDEF";
235 v = *(const unsigned char *)p;
237 *d++ = hexbytes[v>>4];
238 *d++ = hexbytes[v&0xF];
243 s = p; /* move forward */
246 /* copy the last part (with zero) and return */
250 /* return the length of the resulting string */
251 return (l + (d - dst));
254 char *ldb_dn_escape_value(void *mem_ctx, struct ldb_val value)
261 /* allocate destination string, it will be at most 3 times the source */
262 dst = talloc_array(mem_ctx, char, value.length * 3 + 1);
268 ldb_dn_escape_internal(dst, (const char *)value.data, value.length);
270 dst = talloc_realloc(mem_ctx, dst, char, strlen(dst) + 1);
276 explode a DN string into a ldb_dn structure
277 based on RFC4514 except that we don't support multiple valued RDNs
279 TODO: according to MS-ADTS:3.1.1.5.2 Naming Constraints
280 DN must be compliant with RFC2253
282 static bool ldb_dn_explode(struct ldb_dn *dn)
284 char *p, *ex_name, *ex_value, *data, *d, *dt, *t;
286 bool in_extended = false;
287 bool in_ex_name = false;
288 bool in_ex_value = false;
289 bool in_attr = false;
290 bool in_value = false;
291 bool in_quote = false;
299 if ( ! dn || dn->invalid) return false;
301 if (dn->components) {
305 if (dn->ext_linearized) {
306 parse_dn = dn->ext_linearized;
308 parse_dn = dn->linearized;
315 is_index = (strncmp(parse_dn, "DN=@INDEX:", 10) == 0);
318 if (parse_dn[0] == '\0') {
322 /* Special DNs case */
327 /* make sure we free this if alloced previously before replacing */
328 talloc_free(dn->components);
330 talloc_free(dn->ext_components);
331 dn->ext_components = NULL;
333 /* in the common case we have 3 or more components */
334 /* make sure all components are zeroed, other functions depend on it */
335 dn->components = talloc_zero_array(dn, struct ldb_dn_component, 3);
336 if ( ! dn->components) {
341 /* Components data space is allocated here once */
342 data = talloc_array(dn->components, char, strlen(parse_dn) + 1);
358 if (!in_ex_name && !in_ex_value) {
365 } else if (p[0] == '\0') {
377 if (in_ex_name && *p == '=') {
386 if (in_ex_value && *p == '>') {
387 const struct ldb_dn_extended_syntax *ext_syntax;
388 struct ldb_val ex_val = {
389 .data = (uint8_t *)ex_value,
390 .length = d - ex_value
397 /* Process name and ex_value */
399 dn->ext_components = talloc_realloc(dn,
401 struct ldb_dn_ext_component,
402 dn->ext_comp_num + 1);
403 if ( ! dn->ext_components) {
408 ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, ex_name);
410 /* We don't know about this type of extended DN */
414 dn->ext_components[dn->ext_comp_num].name = talloc_strdup(dn->ext_components, ex_name);
415 if (!dn->ext_components[dn->ext_comp_num].name) {
419 ret = ext_syntax->read_fn(dn->ldb, dn->ext_components,
420 &ex_val, &dn->ext_components[dn->ext_comp_num].value);
421 if (ret != LDB_SUCCESS) {
422 ldb_dn_mark_invalid(dn);
429 /* We have reached the end (extended component only)! */
433 } else if (*p == ';') {
437 ldb_dn_mark_invalid(dn);
456 /* attr names must be ascii only */
457 ldb_dn_mark_invalid(dn);
464 if ( ! isalpha(*p)) {
465 /* not a digit nor an alpha,
466 * invalid attribute name */
467 ldb_dn_mark_invalid(dn);
471 /* Copy this character across from parse_dn,
472 * now we have trimmed out spaces */
479 /* valid only if we are at the end */
484 if (trim && (*p != '=')) {
485 /* spaces/tabs are not allowed */
486 ldb_dn_mark_invalid(dn);
491 /* attribute terminated */
497 /* Terminate this string in d
498 * (which is a copy of parse_dn
499 * with spaces trimmed) */
501 dn->components[dn->comp_num].name = talloc_strdup(dn->components, dt);
502 if ( ! dn->components[dn->comp_num].name) {
514 /* attr names must be ascii only */
515 ldb_dn_mark_invalid(dn);
519 if (is_oid && ( ! (isdigit(*p) || (*p == '.')))) {
520 /* not a digit nor a dot,
521 * invalid attribute oid */
522 ldb_dn_mark_invalid(dn);
525 if ( ! (isalpha(*p) || isdigit(*p) || (*p == '-'))) {
526 /* not ALPHA, DIGIT or HYPHEN */
527 ldb_dn_mark_invalid(dn);
567 /* TODO: support ber encoded values
578 /* ok found value terminator */
592 dn->components[dn->comp_num].value.data = (uint8_t *)talloc_strdup(dn->components, dt);
593 dn->components[dn->comp_num].value.length = l;
594 if ( ! dn->components[dn->comp_num].value.data) {
602 if (dn->comp_num > 2) {
603 dn->components = talloc_realloc(dn,
605 struct ldb_dn_component,
607 if ( ! dn->components) {
611 /* make sure all components are zeroed, other functions depend on this */
612 memset(&dn->components[dn->comp_num], '\0', sizeof(struct ldb_dn_component));
619 /* to main compatibility with earlier
620 versions of ldb indexing, we have to
621 accept the base64 encoded binary index
622 values, which contain a '+' or '='
623 which should normally be escaped */
635 /* a string with not escaped specials is invalid (tested) */
637 ldb_dn_mark_invalid(dn);
664 if (isxdigit(p[0]) && isxdigit(p[1])) {
665 if (sscanf(p, "%02x", &x) != 1) {
666 /* invalid escaping sequence */
667 ldb_dn_mark_invalid(dn);
671 *d++ = (unsigned char)x;
697 if (in_attr || in_quote) {
699 ldb_dn_mark_invalid(dn);
703 /* save last element */
711 dn->components[dn->comp_num].value.length = l;
712 dn->components[dn->comp_num].value.data =
713 (uint8_t *)talloc_strdup(dn->components, dt);
714 if ( ! dn->components[dn->comp_num].value.data) {
726 talloc_free(dn->components);
730 bool ldb_dn_validate(struct ldb_dn *dn)
732 return ldb_dn_explode(dn);
735 const char *ldb_dn_get_linearized(struct ldb_dn *dn)
740 if ( ! dn || ( dn->invalid)) return NULL;
742 if (dn->linearized) return dn->linearized;
744 if ( ! dn->components) {
745 ldb_dn_mark_invalid(dn);
749 if (dn->comp_num == 0) {
750 dn->linearized = talloc_strdup(dn, "");
751 if ( ! dn->linearized) return NULL;
752 return dn->linearized;
755 /* calculate maximum possible length of DN */
756 for (len = 0, i = 0; i < dn->comp_num; i++) {
758 len += strlen(dn->components[i].name);
759 /* max escaped data len */
760 len += (dn->components[i].value.length * 3);
761 len += 2; /* '=' and ',' */
763 dn->linearized = talloc_array(dn, char, len);
764 if ( ! dn->linearized) return NULL;
768 for (i = 0; i < dn->comp_num; i++) {
771 n = dn->components[i].name;
772 while (*n) *d++ = *n++;
777 d += ldb_dn_escape_internal( d,
778 (char *)dn->components[i].value.data,
779 dn->components[i].value.length);
785 /* don't waste more memory than necessary */
786 dn->linearized = talloc_realloc(dn, dn->linearized,
787 char, (d - dn->linearized + 1));
789 return dn->linearized;
792 static int ldb_dn_extended_component_compare(const void *p1, const void *p2)
794 const struct ldb_dn_ext_component *ec1 = (const struct ldb_dn_ext_component *)p1;
795 const struct ldb_dn_ext_component *ec2 = (const struct ldb_dn_ext_component *)p2;
796 return strcmp(ec1->name, ec2->name);
799 char *ldb_dn_get_extended_linearized(void *mem_ctx, struct ldb_dn *dn, int mode)
801 const char *linearized = ldb_dn_get_linearized(dn);
809 if (!ldb_dn_has_extended(dn)) {
810 return talloc_strdup(mem_ctx, linearized);
813 if (!ldb_dn_validate(dn)) {
817 /* sort the extended components by name. The idea is to make
818 * the resulting DNs consistent, plus to ensure that we put
819 * 'DELETED' first, so it can be very quickly recognised
821 qsort(dn->ext_components, dn->ext_comp_num, sizeof(dn->ext_components[0]),
822 ldb_dn_extended_component_compare);
824 for (i = 0; i < dn->ext_comp_num; i++) {
825 const struct ldb_dn_extended_syntax *ext_syntax;
826 const char *name = dn->ext_components[i].name;
827 struct ldb_val ec_val = dn->ext_components[i].value;
831 ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name);
837 ret = ext_syntax->write_clear_fn(dn->ldb, mem_ctx,
839 } else if (mode == 0) {
840 ret = ext_syntax->write_hex_fn(dn->ldb, mem_ctx,
846 if (ret != LDB_SUCCESS) {
851 p = talloc_asprintf(mem_ctx, "<%s=%s>",
854 p = talloc_asprintf_append_buffer(p, ";<%s=%s>",
858 talloc_free(val.data);
865 if (dn->ext_comp_num && *linearized) {
866 p = talloc_asprintf_append_buffer(p, ";%s", linearized);
877 filter out all but an acceptable list of extended DN components
879 void ldb_dn_extended_filter(struct ldb_dn *dn, const char * const *accept)
882 for (i=0; i<dn->ext_comp_num; i++) {
883 if (!ldb_attr_in_list(accept, dn->ext_components[i].name)) {
884 memmove(&dn->ext_components[i],
885 &dn->ext_components[i+1],
886 (dn->ext_comp_num-(i+1))*sizeof(dn->ext_components[0]));
894 char *ldb_dn_alloc_linearized(void *mem_ctx, struct ldb_dn *dn)
896 return talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn));
900 casefold a dn. We need to casefold the attribute names, and canonicalize
901 attribute values of case insensitive attributes.
904 static bool ldb_dn_casefold_internal(struct ldb_dn *dn)
908 if ( ! dn || dn->invalid) return false;
910 if (dn->valid_case) return true;
912 if (( ! dn->components) && ( ! ldb_dn_explode(dn))) {
916 for (i = 0; i < dn->comp_num; i++) {
917 const struct ldb_schema_attribute *a;
919 dn->components[i].cf_name =
920 ldb_attr_casefold(dn->components,
921 dn->components[i].name);
922 if (!dn->components[i].cf_name) {
926 a = ldb_schema_attribute_by_name(dn->ldb,
927 dn->components[i].cf_name);
929 ret = a->syntax->canonicalise_fn(dn->ldb, dn->components,
930 &(dn->components[i].value),
931 &(dn->components[i].cf_value));
937 dn->valid_case = true;
942 for (i = 0; i < dn->comp_num; i++) {
943 LDB_FREE(dn->components[i].cf_name);
944 LDB_FREE(dn->components[i].cf_value.data);
949 const char *ldb_dn_get_casefold(struct ldb_dn *dn)
954 if (dn->casefold) return dn->casefold;
957 dn->casefold = talloc_strdup(dn, dn->linearized);
958 if (!dn->casefold) return NULL;
959 dn->valid_case = true;
963 if ( ! ldb_dn_casefold_internal(dn)) {
967 if (dn->comp_num == 0) {
968 dn->casefold = talloc_strdup(dn, "");
972 /* calculate maximum possible length of DN */
973 for (len = 0, i = 0; i < dn->comp_num; i++) {
975 len += strlen(dn->components[i].cf_name);
976 /* max escaped data len */
977 len += (dn->components[i].cf_value.length * 3);
978 len += 2; /* '=' and ',' */
980 dn->casefold = talloc_array(dn, char, len);
981 if ( ! dn->casefold) return NULL;
985 for (i = 0; i < dn->comp_num; i++) {
988 n = dn->components[i].cf_name;
989 while (*n) *d++ = *n++;
994 d += ldb_dn_escape_internal( d,
995 (char *)dn->components[i].cf_value.data,
996 dn->components[i].cf_value.length);
1001 /* don't waste more memory than necessary */
1002 dn->casefold = talloc_realloc(dn, dn->casefold,
1003 char, strlen(dn->casefold) + 1);
1005 return dn->casefold;
1008 char *ldb_dn_alloc_casefold(void *mem_ctx, struct ldb_dn *dn)
1010 return talloc_strdup(mem_ctx, ldb_dn_get_casefold(dn));
1013 /* Determine if dn is below base, in the ldap tree. Used for
1014 * evaluating a subtree search.
1015 * 0 if they match, otherwise non-zero
1018 int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn)
1023 if ( ! base || base->invalid) return 1;
1024 if ( ! dn || dn->invalid) return -1;
1026 if (( ! base->valid_case) || ( ! dn->valid_case)) {
1027 if (base->linearized && dn->linearized) {
1028 /* try with a normal compare first, if we are lucky
1029 * we will avoid exploding and casfolding */
1031 dif = strlen(dn->linearized) - strlen(base->linearized);
1035 if (strcmp(base->linearized,
1036 &dn->linearized[dif]) == 0) {
1041 if ( ! ldb_dn_casefold_internal(base)) {
1045 if ( ! ldb_dn_casefold_internal(dn)) {
1051 /* if base has more components,
1052 * they don't have the same base */
1053 if (base->comp_num > dn->comp_num) {
1054 return (dn->comp_num - base->comp_num);
1057 if (dn->comp_num == 0) {
1058 if (dn->special && base->special) {
1059 return strcmp(base->linearized, dn->linearized);
1060 } else if (dn->special) {
1062 } else if (base->special) {
1069 n_base = base->comp_num - 1;
1070 n_dn = dn->comp_num - 1;
1072 while (n_base >= 0) {
1073 char *b_name = base->components[n_base].cf_name;
1074 char *dn_name = dn->components[n_dn].cf_name;
1076 char *b_vdata = (char *)base->components[n_base].cf_value.data;
1077 char *dn_vdata = (char *)dn->components[n_dn].cf_value.data;
1079 size_t b_vlen = base->components[n_base].cf_value.length;
1080 size_t dn_vlen = dn->components[n_dn].cf_value.length;
1082 /* compare attr names */
1083 ret = strcmp(b_name, dn_name);
1084 if (ret != 0) return ret;
1086 /* compare attr.cf_value. */
1087 if (b_vlen != dn_vlen) {
1088 return b_vlen - dn_vlen;
1090 ret = strcmp(b_vdata, dn_vdata);
1091 if (ret != 0) return ret;
1100 /* compare DNs using casefolding compare functions.
1102 If they match, then return 0
1105 int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1)
1109 if (( ! dn0) || dn0->invalid || ! dn1 || dn1->invalid) {
1113 if (( ! dn0->valid_case) || ( ! dn1->valid_case)) {
1114 if (dn0->linearized && dn1->linearized) {
1115 /* try with a normal compare first, if we are lucky
1116 * we will avoid exploding and casfolding */
1117 if (strcmp(dn0->linearized, dn1->linearized) == 0) {
1122 if ( ! ldb_dn_casefold_internal(dn0)) {
1126 if ( ! ldb_dn_casefold_internal(dn1)) {
1132 if (dn0->comp_num != dn1->comp_num) {
1133 return (dn1->comp_num - dn0->comp_num);
1136 if (dn0->comp_num == 0) {
1137 if (dn0->special && dn1->special) {
1138 return strcmp(dn0->linearized, dn1->linearized);
1139 } else if (dn0->special) {
1141 } else if (dn1->special) {
1148 for (i = 0; i < dn0->comp_num; i++) {
1149 char *dn0_name = dn0->components[i].cf_name;
1150 char *dn1_name = dn1->components[i].cf_name;
1152 char *dn0_vdata = (char *)dn0->components[i].cf_value.data;
1153 char *dn1_vdata = (char *)dn1->components[i].cf_value.data;
1155 size_t dn0_vlen = dn0->components[i].cf_value.length;
1156 size_t dn1_vlen = dn1->components[i].cf_value.length;
1158 /* compare attr names */
1159 ret = strcmp(dn0_name, dn1_name);
1164 /* compare attr.cf_value. */
1165 if (dn0_vlen != dn1_vlen) {
1166 return dn0_vlen - dn1_vlen;
1168 ret = strcmp(dn0_vdata, dn1_vdata);
1177 static struct ldb_dn_component ldb_dn_copy_component(
1179 struct ldb_dn_component *src)
1181 struct ldb_dn_component dst;
1183 memset(&dst, 0, sizeof(dst));
1189 dst.value = ldb_val_dup(mem_ctx, &(src->value));
1190 if (dst.value.data == NULL) {
1194 dst.name = talloc_strdup(mem_ctx, src->name);
1195 if (dst.name == NULL) {
1196 LDB_FREE(dst.value.data);
1200 if (src->cf_value.data) {
1201 dst.cf_value = ldb_val_dup(mem_ctx, &(src->cf_value));
1202 if (dst.cf_value.data == NULL) {
1203 LDB_FREE(dst.value.data);
1208 dst.cf_name = talloc_strdup(mem_ctx, src->cf_name);
1209 if (dst.cf_name == NULL) {
1210 LDB_FREE(dst.cf_name);
1211 LDB_FREE(dst.value.data);
1216 dst.cf_value.data = NULL;
1223 static struct ldb_dn_ext_component ldb_dn_ext_copy_component(
1225 struct ldb_dn_ext_component *src)
1227 struct ldb_dn_ext_component dst;
1229 memset(&dst, 0, sizeof(dst));
1235 dst.value = ldb_val_dup(mem_ctx, &(src->value));
1236 if (dst.value.data == NULL) {
1240 dst.name = talloc_strdup(mem_ctx, src->name);
1241 if (dst.name == NULL) {
1242 LDB_FREE(dst.value.data);
1249 struct ldb_dn *ldb_dn_copy(void *mem_ctx, struct ldb_dn *dn)
1251 struct ldb_dn *new_dn;
1253 if (!dn || dn->invalid) {
1257 new_dn = talloc_zero(mem_ctx, struct ldb_dn);
1264 if (dn->components) {
1267 new_dn->components =
1268 talloc_zero_array(new_dn,
1269 struct ldb_dn_component,
1271 if ( ! new_dn->components) {
1272 talloc_free(new_dn);
1276 for (i = 0; i < dn->comp_num; i++) {
1277 new_dn->components[i] =
1278 ldb_dn_copy_component(new_dn->components,
1279 &dn->components[i]);
1280 if ( ! new_dn->components[i].value.data) {
1281 talloc_free(new_dn);
1287 if (dn->ext_components) {
1290 new_dn->ext_components =
1291 talloc_zero_array(new_dn,
1292 struct ldb_dn_ext_component,
1294 if ( ! new_dn->ext_components) {
1295 talloc_free(new_dn);
1299 for (i = 0; i < dn->ext_comp_num; i++) {
1300 new_dn->ext_components[i] =
1301 ldb_dn_ext_copy_component(
1302 new_dn->ext_components,
1303 &dn->ext_components[i]);
1304 if ( ! new_dn->ext_components[i].value.data) {
1305 talloc_free(new_dn);
1312 new_dn->casefold = talloc_strdup(new_dn, dn->casefold);
1313 if ( ! new_dn->casefold) {
1314 talloc_free(new_dn);
1319 if (dn->linearized) {
1320 new_dn->linearized = talloc_strdup(new_dn, dn->linearized);
1321 if ( ! new_dn->linearized) {
1322 talloc_free(new_dn);
1327 if (dn->ext_linearized) {
1328 new_dn->ext_linearized = talloc_strdup(new_dn,
1329 dn->ext_linearized);
1330 if ( ! new_dn->ext_linearized) {
1331 talloc_free(new_dn);
1339 /* modify the given dn by adding a base.
1341 * return true if successful and false if not
1342 * if false is returned the dn may be marked invalid
1344 bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base)
1349 if ( !base || base->invalid || !dn || dn->invalid) {
1353 if (dn->components) {
1356 if ( ! ldb_dn_validate(base)) {
1361 if (dn->valid_case) {
1362 if ( ! (s = ldb_dn_get_casefold(base))) {
1367 dn->components = talloc_realloc(dn,
1369 struct ldb_dn_component,
1370 dn->comp_num + base->comp_num);
1371 if ( ! dn->components) {
1372 ldb_dn_mark_invalid(dn);
1376 for (i = 0; i < base->comp_num; dn->comp_num++, i++) {
1377 dn->components[dn->comp_num] =
1378 ldb_dn_copy_component(dn->components,
1379 &base->components[i]);
1380 if (dn->components[dn->comp_num].value.data == NULL) {
1381 ldb_dn_mark_invalid(dn);
1386 if (dn->casefold && s) {
1387 if (*dn->casefold) {
1388 t = talloc_asprintf(dn, "%s,%s",
1391 t = talloc_strdup(dn, s);
1393 LDB_FREE(dn->casefold);
1398 if (dn->linearized) {
1400 s = ldb_dn_get_linearized(base);
1405 if (*dn->linearized) {
1406 t = talloc_asprintf(dn, "%s,%s",
1409 t = talloc_strdup(dn, s);
1412 ldb_dn_mark_invalid(dn);
1415 LDB_FREE(dn->linearized);
1419 /* Wipe the ext_linearized DN,
1420 * the GUID and SID are almost certainly no longer valid */
1421 if (dn->ext_linearized) {
1422 LDB_FREE(dn->ext_linearized);
1425 LDB_FREE(dn->ext_components);
1426 dn->ext_comp_num = 0;
1430 /* modify the given dn by adding a base.
1432 * return true if successful and false if not
1433 * if false is returned the dn may be marked invalid
1435 bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...)
1437 struct ldb_dn *base;
1442 if ( !dn || dn->invalid) {
1446 va_start(ap, base_fmt);
1447 base_str = talloc_vasprintf(dn, base_fmt, ap);
1450 if (base_str == NULL) {
1454 base = ldb_dn_new(base_str, dn->ldb, base_str);
1456 ret = ldb_dn_add_base(dn, base);
1458 talloc_free(base_str);
1463 /* modify the given dn by adding children elements.
1465 * return true if successful and false if not
1466 * if false is returned the dn may be marked invalid
1468 bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child)
1473 if ( !child || child->invalid || !dn || dn->invalid) {
1477 if (dn->components) {
1480 if ( ! ldb_dn_validate(child)) {
1485 if (dn->valid_case) {
1486 if ( ! (s = ldb_dn_get_casefold(child))) {
1491 n = dn->comp_num + child->comp_num;
1493 dn->components = talloc_realloc(dn,
1495 struct ldb_dn_component,
1497 if ( ! dn->components) {
1498 ldb_dn_mark_invalid(dn);
1502 for (i = dn->comp_num - 1, j = n - 1; i >= 0; i--, j--) {
1503 dn->components[j] = dn->components[i];
1506 for (i = 0; i < child->comp_num; i++) {
1508 ldb_dn_copy_component(dn->components,
1509 &child->components[i]);
1510 if (dn->components[i].value.data == NULL) {
1511 ldb_dn_mark_invalid(dn);
1518 if (dn->casefold && s) {
1519 t = talloc_asprintf(dn, "%s,%s", s, dn->casefold);
1520 LDB_FREE(dn->casefold);
1525 if (dn->linearized) {
1527 s = ldb_dn_get_linearized(child);
1532 t = talloc_asprintf(dn, "%s,%s", s, dn->linearized);
1534 ldb_dn_mark_invalid(dn);
1537 LDB_FREE(dn->linearized);
1541 /* Wipe the ext_linearized DN,
1542 * the GUID and SID are almost certainly no longer valid */
1543 LDB_FREE(dn->ext_linearized);
1545 LDB_FREE(dn->ext_components);
1546 dn->ext_comp_num = 0;
1551 /* modify the given dn by adding children elements.
1553 * return true if successful and false if not
1554 * if false is returned the dn may be marked invalid
1556 bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...)
1558 struct ldb_dn *child;
1563 if ( !dn || dn->invalid) {
1567 va_start(ap, child_fmt);
1568 child_str = talloc_vasprintf(dn, child_fmt, ap);
1571 if (child_str == NULL) {
1575 child = ldb_dn_new(child_str, dn->ldb, child_str);
1577 ret = ldb_dn_add_child(dn, child);
1579 talloc_free(child_str);
1584 bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num)
1588 if ( ! ldb_dn_validate(dn)) {
1592 if (dn->comp_num < num) {
1596 /* free components */
1597 for (i = num; i > 0; i--) {
1598 LDB_FREE(dn->components[dn->comp_num - i].name);
1599 LDB_FREE(dn->components[dn->comp_num - i].value.data);
1600 LDB_FREE(dn->components[dn->comp_num - i].cf_name);
1601 LDB_FREE(dn->components[dn->comp_num - i].cf_value.data);
1604 dn->comp_num -= num;
1606 if (dn->valid_case) {
1607 for (i = 0; i < dn->comp_num; i++) {
1608 LDB_FREE(dn->components[i].cf_name);
1609 LDB_FREE(dn->components[i].cf_value.data);
1611 dn->valid_case = false;
1614 LDB_FREE(dn->casefold);
1615 LDB_FREE(dn->linearized);
1617 /* Wipe the ext_linearized DN,
1618 * the GUID and SID are almost certainly no longer valid */
1619 LDB_FREE(dn->ext_linearized);
1621 LDB_FREE(dn->ext_components);
1622 dn->ext_comp_num = 0;
1627 bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num)
1631 if ( ! ldb_dn_validate(dn)) {
1635 if (dn->comp_num < num) {
1639 for (i = 0, j = num; j < dn->comp_num; i++, j++) {
1641 LDB_FREE(dn->components[i].name);
1642 LDB_FREE(dn->components[i].value.data);
1643 LDB_FREE(dn->components[i].cf_name);
1644 LDB_FREE(dn->components[i].cf_value.data);
1646 dn->components[i] = dn->components[j];
1649 dn->comp_num -= num;
1651 if (dn->valid_case) {
1652 for (i = 0; i < dn->comp_num; i++) {
1653 LDB_FREE(dn->components[i].cf_name);
1654 LDB_FREE(dn->components[i].cf_value.data);
1656 dn->valid_case = false;
1659 LDB_FREE(dn->casefold);
1660 LDB_FREE(dn->linearized);
1662 /* Wipe the ext_linearized DN,
1663 * the GUID and SID are almost certainly no longer valid */
1664 LDB_FREE(dn->ext_linearized);
1666 LDB_FREE(dn->ext_components);
1667 dn->ext_comp_num = 0;
1671 struct ldb_dn *ldb_dn_get_parent(void *mem_ctx, struct ldb_dn *dn)
1673 struct ldb_dn *new_dn;
1675 new_dn = ldb_dn_copy(mem_ctx, dn);
1680 if ( ! ldb_dn_remove_child_components(new_dn, 1)) {
1681 talloc_free(new_dn);
1685 /* Wipe the ext_linearized DN,
1686 * the GUID and SID are almost certainly no longer valid */
1687 LDB_FREE(dn->ext_linearized);
1689 LDB_FREE(dn->ext_components);
1690 dn->ext_comp_num = 0;
1694 /* Create a 'canonical name' string from a DN:
1696 ie dc=samba,dc=org -> samba.org/
1697 uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator
1699 There are two formats,
1700 the EX format has the last '/' replaced with a newline (\n).
1703 static char *ldb_dn_canonical(void *mem_ctx, struct ldb_dn *dn, int ex_format) {
1706 char *cracked = NULL;
1707 const char *format = (ex_format ? "\n" : "/" );
1709 if ( ! ldb_dn_validate(dn)) {
1713 tmpctx = talloc_new(mem_ctx);
1715 /* Walk backwards down the DN, grabbing 'dc' components at first */
1716 for (i = dn->comp_num - 1 ; i >= 0; i--) {
1717 if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) {
1721 cracked = talloc_asprintf(tmpctx, "%s.%s",
1722 ldb_dn_escape_value(tmpctx,
1723 dn->components[i].value),
1726 cracked = ldb_dn_escape_value(tmpctx,
1727 dn->components[i].value);
1734 /* Only domain components? Finish here */
1736 cracked = talloc_strdup_append_buffer(cracked, format);
1737 talloc_steal(mem_ctx, cracked);
1741 /* Now walk backwards appending remaining components */
1742 for (; i > 0; i--) {
1743 cracked = talloc_asprintf_append_buffer(cracked, "/%s",
1744 ldb_dn_escape_value(tmpctx,
1745 dn->components[i].value));
1751 /* Last one, possibly a newline for the 'ex' format */
1752 cracked = talloc_asprintf_append_buffer(cracked, "%s%s", format,
1753 ldb_dn_escape_value(tmpctx,
1754 dn->components[i].value));
1756 talloc_steal(mem_ctx, cracked);
1758 talloc_free(tmpctx);
1762 /* Wrapper functions for the above, for the two different string formats */
1763 char *ldb_dn_canonical_string(void *mem_ctx, struct ldb_dn *dn) {
1764 return ldb_dn_canonical(mem_ctx, dn, 0);
1768 char *ldb_dn_canonical_ex_string(void *mem_ctx, struct ldb_dn *dn) {
1769 return ldb_dn_canonical(mem_ctx, dn, 1);
1772 int ldb_dn_get_comp_num(struct ldb_dn *dn)
1774 if ( ! ldb_dn_validate(dn)) {
1777 return dn->comp_num;
1780 const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num)
1782 if ( ! ldb_dn_validate(dn)) {
1785 if (num >= dn->comp_num) return NULL;
1786 return dn->components[num].name;
1789 const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn,
1792 if ( ! ldb_dn_validate(dn)) {
1795 if (num >= dn->comp_num) return NULL;
1796 return &dn->components[num].value;
1799 const char *ldb_dn_get_rdn_name(struct ldb_dn *dn)
1801 if ( ! ldb_dn_validate(dn)) {
1804 if (dn->comp_num == 0) return NULL;
1805 return dn->components[0].name;
1808 const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn)
1810 if ( ! ldb_dn_validate(dn)) {
1813 if (dn->comp_num == 0) return NULL;
1814 return &dn->components[0].value;
1817 int ldb_dn_set_component(struct ldb_dn *dn, int num,
1818 const char *name, const struct ldb_val val)
1823 if ( ! ldb_dn_validate(dn)) {
1824 return LDB_ERR_OTHER;
1827 if (num >= dn->comp_num) {
1828 return LDB_ERR_OTHER;
1831 n = talloc_strdup(dn, name);
1833 return LDB_ERR_OTHER;
1836 v.length = val.length;
1837 v.data = (uint8_t *)talloc_memdup(dn, val.data, v.length+1);
1840 return LDB_ERR_OTHER;
1843 talloc_free(dn->components[num].name);
1844 talloc_free(dn->components[num].value.data);
1845 dn->components[num].name = n;
1846 dn->components[num].value = v;
1848 if (dn->valid_case) {
1850 for (i = 0; i < dn->comp_num; i++) {
1851 LDB_FREE(dn->components[i].cf_name);
1852 LDB_FREE(dn->components[i].cf_value.data);
1854 dn->valid_case = false;
1856 LDB_FREE(dn->casefold);
1857 LDB_FREE(dn->linearized);
1859 /* Wipe the ext_linearized DN,
1860 * the GUID and SID are almost certainly no longer valid */
1861 LDB_FREE(dn->ext_linearized);
1863 dn->ext_comp_num = 0;
1864 LDB_FREE(dn->ext_components);
1868 const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn,
1872 if ( ! ldb_dn_validate(dn)) {
1875 for (i=0; i < dn->ext_comp_num; i++) {
1876 if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) {
1877 return &dn->ext_components[i].value;
1883 int ldb_dn_set_extended_component(struct ldb_dn *dn,
1884 const char *name, const struct ldb_val *val)
1886 struct ldb_dn_ext_component *p;
1890 if ( ! ldb_dn_validate(dn)) {
1891 return LDB_ERR_OTHER;
1894 if (!ldb_dn_extended_syntax_by_name(dn->ldb, name)) {
1895 /* We don't know how to handle this type of thing */
1896 return LDB_ERR_INVALID_DN_SYNTAX;
1899 for (i=0; i < dn->ext_comp_num; i++) {
1900 if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) {
1902 dn->ext_components[i].value =
1903 ldb_val_dup(dn->ext_components, val);
1905 dn->ext_components[i].name =
1906 talloc_strdup(dn->ext_components, name);
1907 if (!dn->ext_components[i].name ||
1908 !dn->ext_components[i].value.data) {
1909 ldb_dn_mark_invalid(dn);
1910 return LDB_ERR_OPERATIONS_ERROR;
1914 if (i != (dn->ext_comp_num - 1)) {
1915 memmove(&dn->ext_components[i],
1916 &dn->ext_components[i+1],
1917 ((dn->ext_comp_num-1) - i) *
1918 sizeof(*dn->ext_components));
1922 dn->ext_components = talloc_realloc(dn,
1924 struct ldb_dn_ext_component,
1926 if (!dn->ext_components) {
1927 ldb_dn_mark_invalid(dn);
1928 return LDB_ERR_OPERATIONS_ERROR;
1936 /* removing a value that doesn't exist is not an error */
1942 p = dn->ext_components
1943 = talloc_realloc(dn,
1945 struct ldb_dn_ext_component,
1946 dn->ext_comp_num + 1);
1947 if (!dn->ext_components) {
1948 ldb_dn_mark_invalid(dn);
1949 return LDB_ERR_OPERATIONS_ERROR;
1952 p[dn->ext_comp_num].value = ldb_val_dup(dn->ext_components, &v2);
1953 p[dn->ext_comp_num].name = talloc_strdup(p, name);
1955 if (!dn->ext_components[i].name || !dn->ext_components[i].value.data) {
1956 ldb_dn_mark_invalid(dn);
1957 return LDB_ERR_OPERATIONS_ERROR;
1959 dn->ext_components = p;
1965 void ldb_dn_remove_extended_components(struct ldb_dn *dn)
1967 dn->ext_comp_num = 0;
1968 LDB_FREE(dn->ext_components);
1971 bool ldb_dn_is_valid(struct ldb_dn *dn)
1973 if ( ! dn) return false;
1974 return ! dn->invalid;
1977 bool ldb_dn_is_special(struct ldb_dn *dn)
1979 if ( ! dn || dn->invalid) return false;
1983 bool ldb_dn_has_extended(struct ldb_dn *dn)
1985 if ( ! dn || dn->invalid) return false;
1986 if (dn->ext_linearized && (dn->ext_linearized[0] == '<')) return true;
1987 return dn->ext_comp_num != 0;
1990 bool ldb_dn_check_special(struct ldb_dn *dn, const char *check)
1992 if ( ! dn || dn->invalid) return false;
1993 return ! strcmp(dn->linearized, check);
1996 bool ldb_dn_is_null(struct ldb_dn *dn)
1998 if ( ! dn || dn->invalid) return false;
1999 if (ldb_dn_has_extended(dn)) return false;
2000 if (dn->linearized && (dn->linearized[0] == '\0')) return true;