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 struct ldb_val extra_val;
85 /* it is helpful to be able to break on this in gdb */
86 static void ldb_dn_mark_invalid(struct ldb_dn *dn)
91 /* strdn may be NULL */
92 struct ldb_dn *ldb_dn_from_ldb_val(void *mem_ctx,
93 struct ldb_context *ldb,
94 const struct ldb_val *strdn)
98 if (! ldb) return NULL;
100 if (strdn && strdn->data
101 && (strnlen((const char*)strdn->data, strdn->length) != strdn->length)) {
102 /* The RDN must not contain a character with value 0x0 */
106 /* if the DN starts with B: then it has a binary blob
107 * attached. Called the binary dn parser, which will call back
108 * here for the rest of the DN */
109 if (strdn->data && strncmp((char *)strdn->data, "B:", 2) == 0) {
110 return ldb_dn_binary_from_ldb_val(mem_ctx, ldb, strdn);
113 dn = talloc_zero(mem_ctx, struct ldb_dn);
114 LDB_DN_NULL_FAILED(dn);
118 if (strdn->data && strdn->length) {
119 const char *data = (const char *)strdn->data;
120 size_t length = strdn->length;
122 if (data[0] == '@') {
125 dn->ext_linearized = talloc_strndup(dn, data, length);
126 LDB_DN_NULL_FAILED(dn->ext_linearized);
128 if (data[0] == '<') {
129 const char *p_save, *p = dn->ext_linearized;
138 if (p_save == dn->ext_linearized) {
139 dn->linearized = talloc_strdup(dn, "");
141 dn->linearized = talloc_strdup(dn, p_save);
143 LDB_DN_NULL_FAILED(dn->linearized);
145 dn->linearized = dn->ext_linearized;
146 dn->ext_linearized = NULL;
149 dn->linearized = talloc_strdup(dn, "");
150 LDB_DN_NULL_FAILED(dn->linearized);
161 a version of strhex_to_str internal to ldb, for use by the binary
164 static size_t ldb_strhex_to_str(char *p, size_t p_len, const char *strhex,
168 size_t num_chars = 0;
169 uint8_t lonybble, hinybble;
170 const char *hexchars = "0123456789ABCDEF";
171 char *p1 = NULL, *p2 = NULL;
173 for (i = 0; i < strhex_len && strhex[i] != 0; i++) {
174 if (!(p1 = strchr(hexchars, toupper((unsigned char)strhex[i]))))
177 i++; /* next hex digit */
179 if (!(p2 = strchr(hexchars, toupper((unsigned char)strhex[i]))))
182 /* get the two nybbles */
183 hinybble = PTR_DIFF(p1, hexchars);
184 lonybble = PTR_DIFF(p2, hexchars);
186 if (num_chars >= p_len) {
190 p[num_chars] = (hinybble << 4) | lonybble;
199 /* strdn may be NULL */
200 struct ldb_dn *ldb_dn_binary_from_ldb_val(void *mem_ctx,
201 struct ldb_context *ldb,
202 const struct ldb_val *strdn)
217 if (strdn && strdn->data
218 && (strlen((const char*)strdn->data) != strdn->length)) {
219 /* The RDN must not contain a character with value 0x0 */
223 if (!strdn->data || strdn->length == 0) {
228 tmp_ctx = talloc_new(mem_ctx);
229 if (tmp_ctx == NULL) {
233 data = (const char *)strdn->data;
235 if (data[0] != 'B') {
236 ldb_debug(ldb, LDB_DEBUG_TRACE, __location__ ": no prefix?\n");
241 linearized = talloc_strndup(tmp_ctx, data, len);
242 if (linearized == NULL) {
246 ldb_debug(ldb, LDB_DEBUG_TRACE, __location__ ": processing DN '%s'\n", linearized);
259 blen = strtoul(p1, &p2, 10);
261 ldb_debug(ldb, LDB_DEBUG_TRACE, __location__ ": failed\n");
265 ldb_debug(ldb, LDB_DEBUG_TRACE, __location__ ": failed\n");
269 ldb_debug(ldb, LDB_DEBUG_TRACE, __location__ ": failed\n");
272 len -= PTR_DIFF(p2,p1);//???
277 ldb_debug(ldb, LDB_DEBUG_TRACE, __location__ ": blen=%u len=%u\n", (unsigned)blen, (unsigned)len);
283 ldb_debug(ldb, LDB_DEBUG_TRACE, __location__ ": %s", p2);
288 bval.length = (blen/2)+1;
289 bval.data = talloc_size(tmp_ctx, bval.length);
290 if (bval.data == NULL) {
291 ldb_debug(ldb, LDB_DEBUG_TRACE, __location__ ": err\n");
294 bval.data[bval.length-1] = 0;
296 bval.length = ldb_strhex_to_str((char *)bval.data, bval.length,
299 dval.data = (uint8_t *)dn_str;
300 dval.length = strlen(dn_str);
302 dn = ldb_dn_from_ldb_val(mem_ctx, ldb, &dval);
304 ldb_debug(ldb, LDB_DEBUG_TRACE, __location__ ": err\n");
307 dn->extra_type = data[0];
308 dn->extra_val = bval;
309 talloc_steal(dn, bval.data);
312 old = dn->linearized;
313 dn->linearized = talloc_asprintf(dn, "%s%s", linearized, dn->linearized);
315 if (dn->ext_linearized) {
316 old = dn->ext_linearized;
317 dn->ext_linearized = talloc_asprintf(dn, "%s%s", linearized, dn->ext_linearized);
323 talloc_free(tmp_ctx);
327 /* strdn may be NULL */
328 struct ldb_dn *ldb_dn_new(void *mem_ctx,
329 struct ldb_context *ldb,
333 blob.data = discard_const_p(uint8_t, strdn);
334 blob.length = strdn ? strlen(strdn) : 0;
335 return ldb_dn_from_ldb_val(mem_ctx, ldb, &blob);
338 struct ldb_dn *ldb_dn_new_fmt(void *mem_ctx,
339 struct ldb_context *ldb,
340 const char *new_fmt, ...)
345 if ( (! mem_ctx) || (! ldb)) return NULL;
347 va_start(ap, new_fmt);
348 strdn = talloc_vasprintf(mem_ctx, new_fmt, ap);
352 struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb, strdn);
360 static int ldb_dn_escape_internal(char *dst, const char *src, int len)
369 while (p - src < len) {
371 p += strcspn(p, ",=\n+<>#;\\\"");
373 if (p - src == len) /* found no escapable chars */
376 /* copy the part of the string before the stop */
378 d += (p - s); /* move to current position */
380 if (*p) { /* it is a normal escapable character */
383 } else { /* we have a zero byte in the string */
384 strncpy(d, "\00", 3); /* escape the zero */
386 p++; /* skip the zero */
388 s = p; /* move forward */
391 /* copy the last part (with zero) and return */
395 /* return the length of the resulting string */
396 return (l + (d - dst));
399 char *ldb_dn_escape_value(void *mem_ctx, struct ldb_val value)
406 /* allocate destination string, it will be at most 3 times the source */
407 dst = talloc_array(mem_ctx, char, value.length * 3 + 1);
413 ldb_dn_escape_internal(dst, (const char *)value.data, value.length);
415 dst = talloc_realloc(mem_ctx, dst, char, strlen(dst) + 1);
421 explode a DN string into a ldb_dn structure
422 based on RFC4514 except that we don't support multiple valued RDNs
424 TODO: according to MS-ADTS:3.1.1.5.2 Naming Constraints
425 DN must be compliant with RFC2253
427 static bool ldb_dn_explode(struct ldb_dn *dn)
429 char *p, *ex_name, *ex_value, *data, *d, *dt, *t;
431 bool in_extended = false;
432 bool in_ex_name = false;
433 bool in_ex_value = false;
434 bool in_attr = false;
435 bool in_value = false;
436 bool in_quote = false;
444 if ( ! dn || dn->invalid) return false;
446 if (dn->components) {
450 if (dn->ext_linearized) {
451 parse_dn = dn->ext_linearized;
453 parse_dn = dn->linearized;
460 is_index = (strncmp(parse_dn, "DN=@INDEX:", 10) == 0);
462 if (strncmp(parse_dn, "B:", 2) == 0) {
463 parse_dn = strchr(parse_dn, ':');
464 parse_dn = strchr(parse_dn+1, ':');
465 parse_dn = strchr(parse_dn+1, ':');
470 if (parse_dn[0] == '\0') {
474 /* Special DNs case */
479 /* make sure we free this if alloced previously before replacing */
480 talloc_free(dn->components);
482 talloc_free(dn->ext_components);
483 dn->ext_components = NULL;
485 /* in the common case we have 3 or more components */
486 /* make sure all components are zeroed, other functions depend on it */
487 dn->components = talloc_zero_array(dn, struct ldb_dn_component, 3);
488 if ( ! dn->components) {
493 /* Components data space is allocated here once */
494 data = talloc_array(dn->components, char, strlen(parse_dn) + 1);
510 if (!in_ex_name && !in_ex_value) {
517 } else if (p[0] == '\0') {
529 if (in_ex_name && *p == '=') {
538 if (in_ex_value && *p == '>') {
539 const struct ldb_dn_extended_syntax *ext_syntax;
540 struct ldb_val ex_val = {
541 .data = (uint8_t *)ex_value,
542 .length = d - ex_value
549 /* Process name and ex_value */
551 dn->ext_components = talloc_realloc(dn,
553 struct ldb_dn_ext_component,
554 dn->ext_comp_num + 1);
555 if ( ! dn->ext_components) {
560 ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, ex_name);
562 /* We don't know about this type of extended DN */
566 dn->ext_components[dn->ext_comp_num].name = talloc_strdup(dn->ext_components, ex_name);
567 if (!dn->ext_components[dn->ext_comp_num].name) {
571 ret = ext_syntax->read_fn(dn->ldb, dn->ext_components,
572 &ex_val, &dn->ext_components[dn->ext_comp_num].value);
573 if (ret != LDB_SUCCESS) {
574 ldb_dn_mark_invalid(dn);
581 /* We have reached the end (extended component only)! */
585 } else if (*p == ';') {
589 ldb_dn_mark_invalid(dn);
608 /* attr names must be ascii only */
609 ldb_dn_mark_invalid(dn);
616 if ( ! isalpha(*p)) {
617 /* not a digit nor an alpha,
618 * invalid attribute name */
619 ldb_dn_mark_invalid(dn);
623 /* Copy this character across from parse_dn,
624 * now we have trimmed out spaces */
631 /* valid only if we are at the end */
636 if (trim && (*p != '=')) {
637 /* spaces/tabs are not allowed */
638 ldb_dn_mark_invalid(dn);
643 /* attribute terminated */
649 /* Terminate this string in d
650 * (which is a copy of parse_dn
651 * with spaces trimmed) */
653 dn->components[dn->comp_num].name = talloc_strdup(dn->components, dt);
654 if ( ! dn->components[dn->comp_num].name) {
666 /* attr names must be ascii only */
667 ldb_dn_mark_invalid(dn);
671 if (is_oid && ( ! (isdigit(*p) || (*p == '.')))) {
672 /* not a digit nor a dot,
673 * invalid attribute oid */
674 ldb_dn_mark_invalid(dn);
677 if ( ! (isalpha(*p) || isdigit(*p) || (*p == '-'))) {
678 /* not ALPHA, DIGIT or HYPHEN */
679 ldb_dn_mark_invalid(dn);
719 /* TODO: support ber encoded values
730 /* ok found value terminator */
744 dn->components[dn->comp_num].value.data = (uint8_t *)talloc_strdup(dn->components, dt);
745 dn->components[dn->comp_num].value.length = l;
746 if ( ! dn->components[dn->comp_num].value.data) {
754 if (dn->comp_num > 2) {
755 dn->components = talloc_realloc(dn,
757 struct ldb_dn_component,
759 if ( ! dn->components) {
763 /* make sure all components are zeroed, other functions depend on this */
764 memset(&dn->components[dn->comp_num], '\0', sizeof(struct ldb_dn_component));
771 /* to main compatibility with earlier
772 versions of ldb indexing, we have to
773 accept the base64 encoded binary index
774 values, which contain a '=' */
788 /* a string with not escaped specials is invalid (tested) */
790 ldb_dn_mark_invalid(dn);
817 if (sscanf(p, "%02x", &x) != 1) {
818 /* invalid escaping sequence */
819 ldb_dn_mark_invalid(dn);
825 *d++ = (unsigned char)x;
847 if (in_attr || in_quote) {
849 ldb_dn_mark_invalid(dn);
853 /* save last element */
861 dn->components[dn->comp_num].value.length = l;
862 dn->components[dn->comp_num].value.data =
863 (uint8_t *)talloc_strdup(dn->components, dt);
864 if ( ! dn->components[dn->comp_num].value.data) {
876 talloc_free(dn->components);
880 bool ldb_dn_validate(struct ldb_dn *dn)
882 return ldb_dn_explode(dn);
885 static char *data_blob_hex_string_upper(TALLOC_CTX *mem_ctx, const struct ldb_val *blob)
890 hex_string = talloc_array(mem_ctx, char, (blob->length*2)+1);
895 for (i = 0; i < blob->length; i++)
896 slprintf(&hex_string[i*2], 3, "%02X", blob->data[i]);
898 hex_string[(blob->length*2)] = '\0';
903 const char *ldb_dn_get_linearized(struct ldb_dn *dn)
907 char *extra_prefix = NULL;
909 if ( ! dn || ( dn->invalid)) return NULL;
911 if (dn->linearized) return dn->linearized;
913 if ( ! dn->components) {
914 ldb_dn_mark_invalid(dn);
918 if (dn->extra_type == 'B') {
919 char *hexstr = data_blob_hex_string_upper(dn, &dn->extra_val);
920 extra_prefix = talloc_asprintf(dn, "B:%u:%s:", (unsigned)(dn->extra_val.length*2), hexstr);
924 if (dn->comp_num == 0) {
925 dn->linearized = talloc_strdup(dn, "");
926 if ( ! dn->linearized) return NULL;
927 return dn->linearized;
930 /* calculate maximum possible length of DN */
931 for (len = 0, i = 0; i < dn->comp_num; i++) {
933 len += strlen(dn->components[i].name);
934 /* max escaped data len */
935 len += (dn->components[i].value.length * 3);
936 len += 2; /* '=' and ',' */
938 dn->linearized = talloc_array(dn, char, len);
939 if ( ! dn->linearized) return NULL;
943 for (i = 0; i < dn->comp_num; i++) {
946 n = dn->components[i].name;
947 while (*n) *d++ = *n++;
952 d += ldb_dn_escape_internal( d,
953 (char *)dn->components[i].value.data,
954 dn->components[i].value.length);
960 /* don't waste more memory than necessary */
961 dn->linearized = talloc_realloc(dn, dn->linearized,
962 char, (d - dn->linearized + 1));
965 char *old = dn->linearized;
966 dn->linearized = talloc_asprintf(dn, "%s%s", extra_prefix, old);
968 talloc_free(extra_prefix);
971 return dn->linearized;
974 char *ldb_dn_get_extended_linearized(void *mem_ctx, struct ldb_dn *dn, int mode)
976 const char *linearized = ldb_dn_get_linearized(dn);
984 if (!ldb_dn_has_extended(dn)) {
985 return talloc_strdup(mem_ctx, linearized);
988 if (!ldb_dn_validate(dn)) {
992 if (dn->extra_type == 'B') {
993 char *hexstr = data_blob_hex_string_upper(mem_ctx, &dn->extra_val);
994 p = talloc_asprintf(mem_ctx, "B:%u:%s:", (unsigned)(dn->extra_val.length*2), hexstr);
997 p = talloc_strdup(mem_ctx, "");
1000 for (i = 0; i < dn->ext_comp_num; i++) {
1001 const struct ldb_dn_extended_syntax *ext_syntax;
1002 const char *name = dn->ext_components[i].name;
1003 struct ldb_val ec_val = dn->ext_components[i].value;
1007 ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name);
1010 ret = ext_syntax->write_clear_fn(dn->ldb, mem_ctx,
1012 } else if (mode == 0) {
1013 ret = ext_syntax->write_hex_fn(dn->ldb, mem_ctx,
1019 if (ret != LDB_SUCCESS) {
1024 p = talloc_asprintf_append_buffer(p, "<%s=%s>", name, val.data);
1026 p = talloc_asprintf_append_buffer(p, ";<%s=%s>",name, val.data);
1029 talloc_free(val.data);
1036 if (dn->ext_comp_num && *linearized) {
1037 if (strncmp(linearized, "B:", 2) == 0) {
1038 linearized = strchr(linearized, ':');
1039 linearized = strchr(linearized+1, ':');
1040 linearized = strchr(linearized+1, ':');
1043 p = talloc_asprintf_append_buffer(p, ";%s", linearized);
1055 char *ldb_dn_alloc_linearized(void *mem_ctx, struct ldb_dn *dn)
1057 return talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn));
1061 casefold a dn. We need to casefold the attribute names, and canonicalize
1062 attribute values of case insensitive attributes.
1065 static bool ldb_dn_casefold_internal(struct ldb_dn *dn)
1069 if ( ! dn || dn->invalid) return false;
1071 if (dn->valid_case) return true;
1073 if (( ! dn->components) && ( ! ldb_dn_explode(dn))) {
1077 for (i = 0; i < dn->comp_num; i++) {
1078 const struct ldb_schema_attribute *a;
1080 dn->components[i].cf_name =
1081 ldb_attr_casefold(dn->components,
1082 dn->components[i].name);
1083 if (!dn->components[i].cf_name) {
1087 a = ldb_schema_attribute_by_name(dn->ldb,
1088 dn->components[i].cf_name);
1090 ret = a->syntax->canonicalise_fn(dn->ldb, dn->components,
1091 &(dn->components[i].value),
1092 &(dn->components[i].cf_value));
1098 dn->valid_case = true;
1103 for (i = 0; i < dn->comp_num; i++) {
1104 LDB_FREE(dn->components[i].cf_name);
1105 LDB_FREE(dn->components[i].cf_value.data);
1110 const char *ldb_dn_get_casefold(struct ldb_dn *dn)
1115 if (dn->casefold) return dn->casefold;
1118 dn->casefold = talloc_strdup(dn, dn->linearized);
1119 if (!dn->casefold) return NULL;
1120 dn->valid_case = true;
1121 return dn->casefold;
1124 if ( ! ldb_dn_casefold_internal(dn)) {
1128 if (dn->comp_num == 0) {
1129 dn->casefold = talloc_strdup(dn, "");
1130 return dn->casefold;
1133 /* calculate maximum possible length of DN */
1134 for (len = 0, i = 0; i < dn->comp_num; i++) {
1136 len += strlen(dn->components[i].cf_name);
1137 /* max escaped data len */
1138 len += (dn->components[i].cf_value.length * 3);
1139 len += 2; /* '=' and ',' */
1141 dn->casefold = talloc_array(dn, char, len);
1142 if ( ! dn->casefold) return NULL;
1146 for (i = 0; i < dn->comp_num; i++) {
1149 n = dn->components[i].cf_name;
1150 while (*n) *d++ = *n++;
1155 d += ldb_dn_escape_internal( d,
1156 (char *)dn->components[i].cf_value.data,
1157 dn->components[i].cf_value.length);
1162 /* don't waste more memory than necessary */
1163 dn->casefold = talloc_realloc(dn, dn->casefold,
1164 char, strlen(dn->casefold) + 1);
1166 return dn->casefold;
1169 char *ldb_dn_alloc_casefold(void *mem_ctx, struct ldb_dn *dn)
1171 return talloc_strdup(mem_ctx, ldb_dn_get_casefold(dn));
1174 /* Determine if dn is below base, in the ldap tree. Used for
1175 * evaluating a subtree search.
1176 * 0 if they match, otherwise non-zero
1179 int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn)
1184 if ( ! base || base->invalid) return 1;
1185 if ( ! dn || dn->invalid) return -1;
1187 if (( ! base->valid_case) || ( ! dn->valid_case)) {
1188 if (base->linearized && dn->linearized) {
1189 /* try with a normal compare first, if we are lucky
1190 * we will avoid exploding and casfolding */
1192 dif = strlen(dn->linearized) - strlen(base->linearized);
1196 if (strcmp(base->linearized,
1197 &dn->linearized[dif]) == 0) {
1202 if ( ! ldb_dn_casefold_internal(base)) {
1206 if ( ! ldb_dn_casefold_internal(dn)) {
1212 /* if base has more components,
1213 * they don't have the same base */
1214 if (base->comp_num > dn->comp_num) {
1215 return (dn->comp_num - base->comp_num);
1218 if (dn->comp_num == 0) {
1219 if (dn->special && base->special) {
1220 return strcmp(base->linearized, dn->linearized);
1221 } else if (dn->special) {
1223 } else if (base->special) {
1230 n_base = base->comp_num - 1;
1231 n_dn = dn->comp_num - 1;
1233 while (n_base >= 0) {
1234 char *b_name = base->components[n_base].cf_name;
1235 char *dn_name = dn->components[n_dn].cf_name;
1237 char *b_vdata = (char *)base->components[n_base].cf_value.data;
1238 char *dn_vdata = (char *)dn->components[n_dn].cf_value.data;
1240 size_t b_vlen = base->components[n_base].cf_value.length;
1241 size_t dn_vlen = dn->components[n_dn].cf_value.length;
1243 /* compare attr names */
1244 ret = strcmp(b_name, dn_name);
1245 if (ret != 0) return ret;
1247 /* compare attr.cf_value. */
1248 if (b_vlen != dn_vlen) {
1249 return b_vlen - dn_vlen;
1251 ret = strcmp(b_vdata, dn_vdata);
1252 if (ret != 0) return ret;
1261 /* compare DNs using casefolding compare functions.
1263 If they match, then return 0
1266 int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1)
1270 if (( ! dn0) || dn0->invalid || ! dn1 || dn1->invalid) {
1274 if (( ! dn0->valid_case) || ( ! dn1->valid_case)) {
1275 if (dn0->linearized && dn1->linearized) {
1276 /* try with a normal compare first, if we are lucky
1277 * we will avoid exploding and casfolding */
1278 if (strcmp(dn0->linearized, dn1->linearized) == 0) {
1283 if ( ! ldb_dn_casefold_internal(dn0)) {
1287 if ( ! ldb_dn_casefold_internal(dn1)) {
1293 if (dn0->comp_num != dn1->comp_num) {
1294 return (dn1->comp_num - dn0->comp_num);
1297 if (dn0->comp_num == 0) {
1298 if (dn0->special && dn1->special) {
1299 return strcmp(dn0->linearized, dn1->linearized);
1300 } else if (dn0->special) {
1302 } else if (dn1->special) {
1309 for (i = 0; i < dn0->comp_num; i++) {
1310 char *dn0_name = dn0->components[i].cf_name;
1311 char *dn1_name = dn1->components[i].cf_name;
1313 char *dn0_vdata = (char *)dn0->components[i].cf_value.data;
1314 char *dn1_vdata = (char *)dn1->components[i].cf_value.data;
1316 size_t dn0_vlen = dn0->components[i].cf_value.length;
1317 size_t dn1_vlen = dn1->components[i].cf_value.length;
1319 /* compare attr names */
1320 ret = strcmp(dn0_name, dn1_name);
1325 /* compare attr.cf_value. */
1326 if (dn0_vlen != dn1_vlen) {
1327 return dn0_vlen - dn1_vlen;
1329 ret = strcmp(dn0_vdata, dn1_vdata);
1338 static struct ldb_dn_component ldb_dn_copy_component(
1340 struct ldb_dn_component *src)
1342 struct ldb_dn_component dst;
1344 memset(&dst, 0, sizeof(dst));
1350 dst.value = ldb_val_dup(mem_ctx, &(src->value));
1351 if (dst.value.data == NULL) {
1355 dst.name = talloc_strdup(mem_ctx, src->name);
1356 if (dst.name == NULL) {
1357 LDB_FREE(dst.value.data);
1361 if (src->cf_value.data) {
1362 dst.cf_value = ldb_val_dup(mem_ctx, &(src->cf_value));
1363 if (dst.cf_value.data == NULL) {
1364 LDB_FREE(dst.value.data);
1369 dst.cf_name = talloc_strdup(mem_ctx, src->cf_name);
1370 if (dst.cf_name == NULL) {
1371 LDB_FREE(dst.cf_name);
1372 LDB_FREE(dst.value.data);
1377 dst.cf_value.data = NULL;
1384 static struct ldb_dn_ext_component ldb_dn_ext_copy_component(
1386 struct ldb_dn_ext_component *src)
1388 struct ldb_dn_ext_component dst;
1390 memset(&dst, 0, sizeof(dst));
1396 dst.value = ldb_val_dup(mem_ctx, &(src->value));
1397 if (dst.value.data == NULL) {
1401 dst.name = talloc_strdup(mem_ctx, src->name);
1402 if (dst.name == NULL) {
1403 LDB_FREE(dst.value.data);
1410 struct ldb_dn *ldb_dn_copy(void *mem_ctx, struct ldb_dn *dn)
1412 struct ldb_dn *new_dn;
1414 if (!dn || dn->invalid) {
1418 new_dn = talloc_zero(mem_ctx, struct ldb_dn);
1425 if (dn->components) {
1428 new_dn->components =
1429 talloc_zero_array(new_dn,
1430 struct ldb_dn_component,
1432 if ( ! new_dn->components) {
1433 talloc_free(new_dn);
1437 for (i = 0; i < dn->comp_num; i++) {
1438 new_dn->components[i] =
1439 ldb_dn_copy_component(new_dn->components,
1440 &dn->components[i]);
1441 if ( ! new_dn->components[i].value.data) {
1442 talloc_free(new_dn);
1448 if (dn->ext_components) {
1451 new_dn->ext_components =
1452 talloc_zero_array(new_dn,
1453 struct ldb_dn_ext_component,
1455 if ( ! new_dn->ext_components) {
1456 talloc_free(new_dn);
1460 for (i = 0; i < dn->ext_comp_num; i++) {
1461 new_dn->ext_components[i] =
1462 ldb_dn_ext_copy_component(
1463 new_dn->ext_components,
1464 &dn->ext_components[i]);
1465 if ( ! new_dn->ext_components[i].value.data) {
1466 talloc_free(new_dn);
1473 new_dn->casefold = talloc_strdup(new_dn, dn->casefold);
1474 if ( ! new_dn->casefold) {
1475 talloc_free(new_dn);
1480 if (dn->linearized) {
1481 new_dn->linearized = talloc_strdup(new_dn, dn->linearized);
1482 if ( ! new_dn->linearized) {
1483 talloc_free(new_dn);
1488 if (dn->ext_linearized) {
1489 new_dn->ext_linearized = talloc_strdup(new_dn,
1490 dn->ext_linearized);
1491 if ( ! new_dn->ext_linearized) {
1492 talloc_free(new_dn);
1500 /* modify the given dn by adding a base.
1502 * return true if successful and false if not
1503 * if false is returned the dn may be marked invalid
1505 bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base)
1510 if ( !base || base->invalid || !dn || dn->invalid) {
1514 if (dn->components) {
1517 if ( ! ldb_dn_validate(base)) {
1522 if (dn->valid_case) {
1523 if ( ! (s = ldb_dn_get_casefold(base))) {
1528 dn->components = talloc_realloc(dn,
1530 struct ldb_dn_component,
1531 dn->comp_num + base->comp_num);
1532 if ( ! dn->components) {
1533 ldb_dn_mark_invalid(dn);
1537 for (i = 0; i < base->comp_num; dn->comp_num++, i++) {
1538 dn->components[dn->comp_num] =
1539 ldb_dn_copy_component(dn->components,
1540 &base->components[i]);
1541 if (dn->components[dn->comp_num].value.data == NULL) {
1542 ldb_dn_mark_invalid(dn);
1547 if (dn->casefold && s) {
1548 if (*dn->casefold) {
1549 t = talloc_asprintf(dn, "%s,%s",
1552 t = talloc_strdup(dn, s);
1554 LDB_FREE(dn->casefold);
1559 if (dn->linearized) {
1561 s = ldb_dn_get_linearized(base);
1566 if (*dn->linearized) {
1567 t = talloc_asprintf(dn, "%s,%s",
1570 t = talloc_strdup(dn, s);
1573 ldb_dn_mark_invalid(dn);
1576 LDB_FREE(dn->linearized);
1580 /* Wipe the ext_linearized DN,
1581 * the GUID and SID are almost certainly no longer valid */
1582 if (dn->ext_linearized) {
1583 LDB_FREE(dn->ext_linearized);
1586 LDB_FREE(dn->ext_components);
1587 dn->ext_comp_num = 0;
1591 /* modify the given dn by adding a base.
1593 * return true if successful and false if not
1594 * if false is returned the dn may be marked invalid
1596 bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...)
1598 struct ldb_dn *base;
1603 if ( !dn || dn->invalid) {
1607 va_start(ap, base_fmt);
1608 base_str = talloc_vasprintf(dn, base_fmt, ap);
1611 if (base_str == NULL) {
1615 base = ldb_dn_new(base_str, dn->ldb, base_str);
1617 ret = ldb_dn_add_base(dn, base);
1619 talloc_free(base_str);
1624 /* modify the given dn by adding children elements.
1626 * return true if successful and false if not
1627 * if false is returned the dn may be marked invalid
1629 bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child)
1634 if ( !child || child->invalid || !dn || dn->invalid) {
1638 if (dn->components) {
1641 if ( ! ldb_dn_validate(child)) {
1646 if (dn->valid_case) {
1647 if ( ! (s = ldb_dn_get_casefold(child))) {
1652 n = dn->comp_num + child->comp_num;
1654 dn->components = talloc_realloc(dn,
1656 struct ldb_dn_component,
1658 if ( ! dn->components) {
1659 ldb_dn_mark_invalid(dn);
1663 for (i = dn->comp_num - 1, j = n - 1; i >= 0; i--, j--) {
1664 dn->components[j] = dn->components[i];
1667 for (i = 0; i < child->comp_num; i++) {
1669 ldb_dn_copy_component(dn->components,
1670 &child->components[i]);
1671 if (dn->components[i].value.data == NULL) {
1672 ldb_dn_mark_invalid(dn);
1679 if (dn->casefold && s) {
1680 t = talloc_asprintf(dn, "%s,%s", s, dn->casefold);
1681 LDB_FREE(dn->casefold);
1686 if (dn->linearized) {
1688 s = ldb_dn_get_linearized(child);
1693 t = talloc_asprintf(dn, "%s,%s", s, dn->linearized);
1695 ldb_dn_mark_invalid(dn);
1698 LDB_FREE(dn->linearized);
1702 /* Wipe the ext_linearized DN,
1703 * the GUID and SID are almost certainly no longer valid */
1704 LDB_FREE(dn->ext_linearized);
1706 LDB_FREE(dn->ext_components);
1707 dn->ext_comp_num = 0;
1712 /* modify the given dn by adding children elements.
1714 * return true if successful and false if not
1715 * if false is returned the dn may be marked invalid
1717 bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...)
1719 struct ldb_dn *child;
1724 if ( !dn || dn->invalid) {
1728 va_start(ap, child_fmt);
1729 child_str = talloc_vasprintf(dn, child_fmt, ap);
1732 if (child_str == NULL) {
1736 child = ldb_dn_new(child_str, dn->ldb, child_str);
1738 ret = ldb_dn_add_child(dn, child);
1740 talloc_free(child_str);
1745 bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num)
1749 if ( ! ldb_dn_validate(dn)) {
1753 if (dn->comp_num < num) {
1757 /* free components */
1758 for (i = num; i > 0; i--) {
1759 LDB_FREE(dn->components[dn->comp_num - i].name);
1760 LDB_FREE(dn->components[dn->comp_num - i].value.data);
1761 LDB_FREE(dn->components[dn->comp_num - i].cf_name);
1762 LDB_FREE(dn->components[dn->comp_num - i].cf_value.data);
1765 dn->comp_num -= num;
1767 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;
1775 LDB_FREE(dn->casefold);
1776 LDB_FREE(dn->linearized);
1778 /* Wipe the ext_linearized DN,
1779 * the GUID and SID are almost certainly no longer valid */
1780 LDB_FREE(dn->ext_linearized);
1782 LDB_FREE(dn->ext_components);
1783 dn->ext_comp_num = 0;
1788 bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num)
1792 if ( ! ldb_dn_validate(dn)) {
1796 if (dn->comp_num < num) {
1800 for (i = 0, j = num; j < dn->comp_num; i++, j++) {
1802 LDB_FREE(dn->components[i].name);
1803 LDB_FREE(dn->components[i].value.data);
1804 LDB_FREE(dn->components[i].cf_name);
1805 LDB_FREE(dn->components[i].cf_value.data);
1807 dn->components[i] = dn->components[j];
1810 dn->comp_num -= num;
1812 if (dn->valid_case) {
1813 for (i = 0; i < dn->comp_num; i++) {
1814 LDB_FREE(dn->components[i].cf_name);
1815 LDB_FREE(dn->components[i].cf_value.data);
1817 dn->valid_case = false;
1820 LDB_FREE(dn->casefold);
1821 LDB_FREE(dn->linearized);
1823 /* Wipe the ext_linearized DN,
1824 * the GUID and SID are almost certainly no longer valid */
1825 LDB_FREE(dn->ext_linearized);
1827 LDB_FREE(dn->ext_components);
1828 dn->ext_comp_num = 0;
1832 struct ldb_dn *ldb_dn_get_parent(void *mem_ctx, struct ldb_dn *dn)
1834 struct ldb_dn *new_dn;
1836 new_dn = ldb_dn_copy(mem_ctx, dn);
1841 if ( ! ldb_dn_remove_child_components(new_dn, 1)) {
1842 talloc_free(new_dn);
1846 /* Wipe the ext_linearized DN,
1847 * the GUID and SID are almost certainly no longer valid */
1848 LDB_FREE(dn->ext_linearized);
1850 LDB_FREE(dn->ext_components);
1851 dn->ext_comp_num = 0;
1855 /* Create a 'canonical name' string from a DN:
1857 ie dc=samba,dc=org -> samba.org/
1858 uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator
1860 There are two formats,
1861 the EX format has the last '/' replaced with a newline (\n).
1864 static char *ldb_dn_canonical(void *mem_ctx, struct ldb_dn *dn, int ex_format) {
1867 char *cracked = NULL;
1868 const char *format = (ex_format ? "\n" : "/" );
1870 if ( ! ldb_dn_validate(dn)) {
1874 tmpctx = talloc_new(mem_ctx);
1876 /* Walk backwards down the DN, grabbing 'dc' components at first */
1877 for (i = dn->comp_num - 1 ; i >= 0; i--) {
1878 if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) {
1882 cracked = talloc_asprintf(tmpctx, "%s.%s",
1883 ldb_dn_escape_value(tmpctx,
1884 dn->components[i].value),
1887 cracked = ldb_dn_escape_value(tmpctx,
1888 dn->components[i].value);
1895 /* Only domain components? Finish here */
1897 cracked = talloc_strdup_append_buffer(cracked, format);
1898 talloc_steal(mem_ctx, cracked);
1902 /* Now walk backwards appending remaining components */
1903 for (; i > 0; i--) {
1904 cracked = talloc_asprintf_append_buffer(cracked, "/%s",
1905 ldb_dn_escape_value(tmpctx,
1906 dn->components[i].value));
1912 /* Last one, possibly a newline for the 'ex' format */
1913 cracked = talloc_asprintf_append_buffer(cracked, "%s%s", format,
1914 ldb_dn_escape_value(tmpctx,
1915 dn->components[i].value));
1917 talloc_steal(mem_ctx, cracked);
1919 talloc_free(tmpctx);
1923 /* Wrapper functions for the above, for the two different string formats */
1924 char *ldb_dn_canonical_string(void *mem_ctx, struct ldb_dn *dn) {
1925 return ldb_dn_canonical(mem_ctx, dn, 0);
1929 char *ldb_dn_canonical_ex_string(void *mem_ctx, struct ldb_dn *dn) {
1930 return ldb_dn_canonical(mem_ctx, dn, 1);
1933 int ldb_dn_get_comp_num(struct ldb_dn *dn)
1935 if ( ! ldb_dn_validate(dn)) {
1938 return dn->comp_num;
1941 const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num)
1943 if ( ! ldb_dn_validate(dn)) {
1946 if (num >= dn->comp_num) return NULL;
1947 return dn->components[num].name;
1950 const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn,
1953 if ( ! ldb_dn_validate(dn)) {
1956 if (num >= dn->comp_num) return NULL;
1957 return &dn->components[num].value;
1960 const char *ldb_dn_get_rdn_name(struct ldb_dn *dn)
1962 if ( ! ldb_dn_validate(dn)) {
1965 if (dn->comp_num == 0) return NULL;
1966 return dn->components[0].name;
1969 const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn)
1971 if ( ! ldb_dn_validate(dn)) {
1974 if (dn->comp_num == 0) return NULL;
1975 return &dn->components[0].value;
1978 int ldb_dn_set_component(struct ldb_dn *dn, int num,
1979 const char *name, const struct ldb_val val)
1984 if ( ! ldb_dn_validate(dn)) {
1985 return LDB_ERR_OTHER;
1988 if (num >= dn->comp_num) {
1989 return LDB_ERR_OTHER;
1992 n = talloc_strdup(dn, name);
1994 return LDB_ERR_OTHER;
1997 v.length = val.length;
1998 v.data = (uint8_t *)talloc_memdup(dn, val.data, v.length+1);
2001 return LDB_ERR_OTHER;
2004 talloc_free(dn->components[num].name);
2005 talloc_free(dn->components[num].value.data);
2006 dn->components[num].name = n;
2007 dn->components[num].value = v;
2009 if (dn->valid_case) {
2011 for (i = 0; i < dn->comp_num; i++) {
2012 LDB_FREE(dn->components[i].cf_name);
2013 LDB_FREE(dn->components[i].cf_value.data);
2015 dn->valid_case = false;
2017 LDB_FREE(dn->casefold);
2018 LDB_FREE(dn->linearized);
2020 /* Wipe the ext_linearized DN,
2021 * the GUID and SID are almost certainly no longer valid */
2022 LDB_FREE(dn->ext_linearized);
2024 dn->ext_comp_num = 0;
2025 LDB_FREE(dn->ext_components);
2029 const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn,
2033 if ( ! ldb_dn_validate(dn)) {
2036 for (i=0; i < dn->ext_comp_num; i++) {
2037 if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) {
2038 return &dn->ext_components[i].value;
2044 int ldb_dn_set_extended_component(struct ldb_dn *dn,
2045 const char *name, const struct ldb_val *val)
2047 struct ldb_dn_ext_component *p;
2050 if ( ! ldb_dn_validate(dn)) {
2051 return LDB_ERR_OTHER;
2054 for (i=0; i < dn->ext_comp_num; i++) {
2055 if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) {
2057 dn->ext_components[i].value =
2058 ldb_val_dup(dn->ext_components, val);
2060 dn->ext_components[i].name =
2061 talloc_strdup(dn->ext_components, name);
2062 if (!dn->ext_components[i].name ||
2063 !dn->ext_components[i].value.data) {
2064 ldb_dn_mark_invalid(dn);
2065 return LDB_ERR_OPERATIONS_ERROR;
2069 if (i != (dn->ext_comp_num - 1)) {
2070 memmove(&dn->ext_components[i],
2071 &dn->ext_components[i+1],
2072 ((dn->ext_comp_num-1) - i) *
2073 sizeof(*dn->ext_components));
2077 dn->ext_components = talloc_realloc(dn,
2079 struct ldb_dn_ext_component,
2081 if (!dn->ext_components) {
2082 ldb_dn_mark_invalid(dn);
2083 return LDB_ERR_OPERATIONS_ERROR;
2090 p = dn->ext_components
2091 = talloc_realloc(dn,
2093 struct ldb_dn_ext_component,
2094 dn->ext_comp_num + 1);
2095 if (!dn->ext_components) {
2096 ldb_dn_mark_invalid(dn);
2097 return LDB_ERR_OPERATIONS_ERROR;
2100 p[dn->ext_comp_num].value = ldb_val_dup(dn->ext_components, val);
2101 p[dn->ext_comp_num].name = talloc_strdup(p, name);
2103 if (!dn->ext_components[i].name || !dn->ext_components[i].value.data) {
2104 ldb_dn_mark_invalid(dn);
2105 return LDB_ERR_OPERATIONS_ERROR;
2107 dn->ext_components = p;
2113 void ldb_dn_remove_extended_components(struct ldb_dn *dn)
2115 dn->ext_comp_num = 0;
2116 LDB_FREE(dn->ext_components);
2119 bool ldb_dn_is_valid(struct ldb_dn *dn)
2121 if ( ! dn) return false;
2122 return ! dn->invalid;
2125 bool ldb_dn_is_special(struct ldb_dn *dn)
2127 if ( ! dn || dn->invalid) return false;
2131 bool ldb_dn_has_extended(struct ldb_dn *dn)
2133 if ( ! dn || dn->invalid) return false;
2134 if (dn->ext_linearized && strchr(dn->ext_linearized,'<')) return true;
2135 return dn->ext_comp_num != 0;
2138 bool ldb_dn_check_special(struct ldb_dn *dn, const char *check)
2140 if ( ! dn || dn->invalid) return false;
2141 return ! strcmp(dn->linearized, check);
2144 bool ldb_dn_is_null(struct ldb_dn *dn)
2146 if ( ! dn || dn->invalid) return false;
2147 if (ldb_dn_has_extended(dn)) return false;
2148 if (dn->linearized && (dn->linearized[0] == '\0')) return true;
2152 int ldb_dn_get_binary(struct ldb_dn *dn, struct ldb_val *val)
2155 if (dn->extra_type != 'B') {
2158 *val = dn->extra_val;
2162 int ldb_dn_set_binary(struct ldb_dn *dn, struct ldb_val *val)
2164 dn->extra_type = 'B';
2165 dn->extra_val.data = talloc_memdup(dn, val->data, val->length);
2166 dn->extra_val.length = val->length;
2168 talloc_free(dn->linearized);
2169 talloc_free(dn->ext_linearized);
2170 dn->linearized = NULL;
2171 dn->ext_linearized = NULL;