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;
443 if ( ! dn || dn->invalid) return false;
445 if (dn->components) {
449 if (dn->ext_linearized) {
450 parse_dn = dn->ext_linearized;
452 parse_dn = dn->linearized;
460 if (strncmp(parse_dn, "B:", 2) == 0) {
461 parse_dn = strchr(parse_dn, ':');
462 parse_dn = strchr(parse_dn+1, ':');
463 parse_dn = strchr(parse_dn+1, ':');
468 if (parse_dn[0] == '\0') {
472 /* Special DNs case */
477 /* make sure we free this if alloced previously before replacing */
478 talloc_free(dn->components);
480 talloc_free(dn->ext_components);
481 dn->ext_components = NULL;
483 /* in the common case we have 3 or more components */
484 /* make sure all components are zeroed, other functions depend on it */
485 dn->components = talloc_zero_array(dn, struct ldb_dn_component, 3);
486 if ( ! dn->components) {
491 /* Components data space is allocated here once */
492 data = talloc_array(dn->components, char, strlen(parse_dn) + 1);
508 if (!in_ex_name && !in_ex_value) {
515 } else if (p[0] == '\0') {
527 if (in_ex_name && *p == '=') {
536 if (in_ex_value && *p == '>') {
537 const struct ldb_dn_extended_syntax *ext_syntax;
538 struct ldb_val ex_val = {
539 .data = (uint8_t *)ex_value,
540 .length = d - ex_value
547 /* Process name and ex_value */
549 dn->ext_components = talloc_realloc(dn,
551 struct ldb_dn_ext_component,
552 dn->ext_comp_num + 1);
553 if ( ! dn->ext_components) {
558 ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, ex_name);
560 /* We don't know about this type of extended DN */
564 dn->ext_components[dn->ext_comp_num].name = talloc_strdup(dn->ext_components, ex_name);
565 if (!dn->ext_components[dn->ext_comp_num].name) {
569 ret = ext_syntax->read_fn(dn->ldb, dn->ext_components,
570 &ex_val, &dn->ext_components[dn->ext_comp_num].value);
571 if (ret != LDB_SUCCESS) {
572 ldb_dn_mark_invalid(dn);
579 /* We have reached the end (extended component only)! */
583 } else if (*p == ';') {
587 ldb_dn_mark_invalid(dn);
606 /* attr names must be ascii only */
607 ldb_dn_mark_invalid(dn);
614 if ( ! isalpha(*p)) {
615 /* not a digit nor an alpha,
616 * invalid attribute name */
617 ldb_dn_mark_invalid(dn);
621 /* Copy this character across from parse_dn,
622 * now we have trimmed out spaces */
629 /* valid only if we are at the end */
634 if (trim && (*p != '=')) {
635 /* spaces/tabs are not allowed */
636 ldb_dn_mark_invalid(dn);
641 /* attribute terminated */
647 /* Terminate this string in d
648 * (which is a copy of parse_dn
649 * with spaces trimmed) */
651 dn->components[dn->comp_num].name = talloc_strdup(dn->components, dt);
652 if ( ! dn->components[dn->comp_num].name) {
664 /* attr names must be ascii only */
665 ldb_dn_mark_invalid(dn);
669 if (is_oid && ( ! (isdigit(*p) || (*p == '.')))) {
670 /* not a digit nor a dot,
671 * invalid attribute oid */
672 ldb_dn_mark_invalid(dn);
675 if ( ! (isalpha(*p) || isdigit(*p) || (*p == '-'))) {
676 /* not ALPHA, DIGIT or HYPHEN */
677 ldb_dn_mark_invalid(dn);
717 /* TODO: support ber encoded values
728 /* ok found value terminator */
742 dn->components[dn->comp_num].value.data = (uint8_t *)talloc_strdup(dn->components, dt);
743 dn->components[dn->comp_num].value.length = l;
744 if ( ! dn->components[dn->comp_num].value.data) {
752 if (dn->comp_num > 2) {
753 dn->components = talloc_realloc(dn,
755 struct ldb_dn_component,
757 if ( ! dn->components) {
761 /* make sure all components are zeroed, other functions depend on this */
762 memset(&dn->components[dn->comp_num], '\0', sizeof(struct ldb_dn_component));
775 /* a string with not escaped specials is invalid (tested) */
777 ldb_dn_mark_invalid(dn);
804 if (sscanf(p, "%02x", &x) != 1) {
805 /* invalid escaping sequence */
806 ldb_dn_mark_invalid(dn);
812 *d++ = (unsigned char)x;
834 if (in_attr || in_quote) {
836 ldb_dn_mark_invalid(dn);
840 /* save last element */
848 dn->components[dn->comp_num].value.length = l;
849 dn->components[dn->comp_num].value.data =
850 (uint8_t *)talloc_strdup(dn->components, dt);
851 if ( ! dn->components[dn->comp_num].value.data) {
863 talloc_free(dn->components);
867 bool ldb_dn_validate(struct ldb_dn *dn)
869 return ldb_dn_explode(dn);
872 static char *data_blob_hex_string_upper(TALLOC_CTX *mem_ctx, const struct ldb_val *blob)
877 hex_string = talloc_array(mem_ctx, char, (blob->length*2)+1);
882 for (i = 0; i < blob->length; i++)
883 slprintf(&hex_string[i*2], 3, "%02X", blob->data[i]);
885 hex_string[(blob->length*2)] = '\0';
890 const char *ldb_dn_get_linearized(struct ldb_dn *dn)
894 char *extra_prefix = NULL;
896 if ( ! dn || ( dn->invalid)) return NULL;
898 if (dn->linearized) return dn->linearized;
900 if ( ! dn->components) {
901 ldb_dn_mark_invalid(dn);
905 if (dn->extra_type == 'B') {
906 char *hexstr = data_blob_hex_string_upper(dn, &dn->extra_val);
907 extra_prefix = talloc_asprintf(dn, "B:%u:%s:", (unsigned)(dn->extra_val.length*2), hexstr);
911 if (dn->comp_num == 0) {
912 dn->linearized = talloc_strdup(dn, "");
913 if ( ! dn->linearized) return NULL;
914 return dn->linearized;
917 /* calculate maximum possible length of DN */
918 for (len = 0, i = 0; i < dn->comp_num; i++) {
920 len += strlen(dn->components[i].name);
921 /* max escaped data len */
922 len += (dn->components[i].value.length * 3);
923 len += 2; /* '=' and ',' */
925 dn->linearized = talloc_array(dn, char, len);
926 if ( ! dn->linearized) return NULL;
930 for (i = 0; i < dn->comp_num; i++) {
933 n = dn->components[i].name;
934 while (*n) *d++ = *n++;
939 d += ldb_dn_escape_internal( d,
940 (char *)dn->components[i].value.data,
941 dn->components[i].value.length);
947 /* don't waste more memory than necessary */
948 dn->linearized = talloc_realloc(dn, dn->linearized,
949 char, (d - dn->linearized + 1));
952 char *old = dn->linearized;
953 dn->linearized = talloc_asprintf(dn, "%s%s", extra_prefix, old);
955 talloc_free(extra_prefix);
958 return dn->linearized;
961 char *ldb_dn_get_extended_linearized(void *mem_ctx, struct ldb_dn *dn, int mode)
963 const char *linearized = ldb_dn_get_linearized(dn);
971 if (!ldb_dn_has_extended(dn)) {
972 return talloc_strdup(mem_ctx, linearized);
975 if (!ldb_dn_validate(dn)) {
979 if (dn->extra_type == 'B') {
980 char *hexstr = data_blob_hex_string_upper(mem_ctx, &dn->extra_val);
981 p = talloc_asprintf(mem_ctx, "B:%u:%s:", (unsigned)(dn->extra_val.length*2), hexstr);
984 p = talloc_strdup(mem_ctx, "");
987 for (i = 0; i < dn->ext_comp_num; i++) {
988 const struct ldb_dn_extended_syntax *ext_syntax;
989 const char *name = dn->ext_components[i].name;
990 struct ldb_val ec_val = dn->ext_components[i].value;
994 ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name);
997 ret = ext_syntax->write_clear_fn(dn->ldb, mem_ctx,
999 } else if (mode == 0) {
1000 ret = ext_syntax->write_hex_fn(dn->ldb, mem_ctx,
1006 if (ret != LDB_SUCCESS) {
1011 p = talloc_asprintf_append_buffer(p, "<%s=%s>", name, val.data);
1013 p = talloc_asprintf_append_buffer(p, ";<%s=%s>",name, val.data);
1016 talloc_free(val.data);
1023 if (dn->ext_comp_num && *linearized) {
1024 if (strncmp(linearized, "B:", 2) == 0) {
1025 linearized = strchr(linearized, ':');
1026 linearized = strchr(linearized+1, ':');
1027 linearized = strchr(linearized+1, ':');
1030 p = talloc_asprintf_append_buffer(p, ";%s", linearized);
1042 char *ldb_dn_alloc_linearized(void *mem_ctx, struct ldb_dn *dn)
1044 return talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn));
1048 casefold a dn. We need to casefold the attribute names, and canonicalize
1049 attribute values of case insensitive attributes.
1052 static bool ldb_dn_casefold_internal(struct ldb_dn *dn)
1056 if ( ! dn || dn->invalid) return false;
1058 if (dn->valid_case) return true;
1060 if (( ! dn->components) && ( ! ldb_dn_explode(dn))) {
1064 for (i = 0; i < dn->comp_num; i++) {
1065 const struct ldb_schema_attribute *a;
1067 dn->components[i].cf_name =
1068 ldb_attr_casefold(dn->components,
1069 dn->components[i].name);
1070 if (!dn->components[i].cf_name) {
1074 a = ldb_schema_attribute_by_name(dn->ldb,
1075 dn->components[i].cf_name);
1077 ret = a->syntax->canonicalise_fn(dn->ldb, dn->components,
1078 &(dn->components[i].value),
1079 &(dn->components[i].cf_value));
1085 dn->valid_case = true;
1090 for (i = 0; i < dn->comp_num; i++) {
1091 LDB_FREE(dn->components[i].cf_name);
1092 LDB_FREE(dn->components[i].cf_value.data);
1097 const char *ldb_dn_get_casefold(struct ldb_dn *dn)
1102 if (dn->casefold) return dn->casefold;
1105 dn->casefold = talloc_strdup(dn, dn->linearized);
1106 if (!dn->casefold) return NULL;
1107 dn->valid_case = true;
1108 return dn->casefold;
1111 if ( ! ldb_dn_casefold_internal(dn)) {
1115 if (dn->comp_num == 0) {
1116 dn->casefold = talloc_strdup(dn, "");
1117 return dn->casefold;
1120 /* calculate maximum possible length of DN */
1121 for (len = 0, i = 0; i < dn->comp_num; i++) {
1123 len += strlen(dn->components[i].cf_name);
1124 /* max escaped data len */
1125 len += (dn->components[i].cf_value.length * 3);
1126 len += 2; /* '=' and ',' */
1128 dn->casefold = talloc_array(dn, char, len);
1129 if ( ! dn->casefold) return NULL;
1133 for (i = 0; i < dn->comp_num; i++) {
1136 n = dn->components[i].cf_name;
1137 while (*n) *d++ = *n++;
1142 d += ldb_dn_escape_internal( d,
1143 (char *)dn->components[i].cf_value.data,
1144 dn->components[i].cf_value.length);
1149 /* don't waste more memory than necessary */
1150 dn->casefold = talloc_realloc(dn, dn->casefold,
1151 char, strlen(dn->casefold) + 1);
1153 return dn->casefold;
1156 char *ldb_dn_alloc_casefold(void *mem_ctx, struct ldb_dn *dn)
1158 return talloc_strdup(mem_ctx, ldb_dn_get_casefold(dn));
1161 /* Determine if dn is below base, in the ldap tree. Used for
1162 * evaluating a subtree search.
1163 * 0 if they match, otherwise non-zero
1166 int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn)
1171 if ( ! base || base->invalid) return 1;
1172 if ( ! dn || dn->invalid) return -1;
1174 if (( ! base->valid_case) || ( ! dn->valid_case)) {
1175 if (base->linearized && dn->linearized) {
1176 /* try with a normal compare first, if we are lucky
1177 * we will avoid exploding and casfolding */
1179 dif = strlen(dn->linearized) - strlen(base->linearized);
1183 if (strcmp(base->linearized,
1184 &dn->linearized[dif]) == 0) {
1189 if ( ! ldb_dn_casefold_internal(base)) {
1193 if ( ! ldb_dn_casefold_internal(dn)) {
1199 /* if base has more components,
1200 * they don't have the same base */
1201 if (base->comp_num > dn->comp_num) {
1202 return (dn->comp_num - base->comp_num);
1205 if (dn->comp_num == 0) {
1206 if (dn->special && base->special) {
1207 return strcmp(base->linearized, dn->linearized);
1208 } else if (dn->special) {
1210 } else if (base->special) {
1217 n_base = base->comp_num - 1;
1218 n_dn = dn->comp_num - 1;
1220 while (n_base >= 0) {
1221 char *b_name = base->components[n_base].cf_name;
1222 char *dn_name = dn->components[n_dn].cf_name;
1224 char *b_vdata = (char *)base->components[n_base].cf_value.data;
1225 char *dn_vdata = (char *)dn->components[n_dn].cf_value.data;
1227 size_t b_vlen = base->components[n_base].cf_value.length;
1228 size_t dn_vlen = dn->components[n_dn].cf_value.length;
1230 /* compare attr names */
1231 ret = strcmp(b_name, dn_name);
1232 if (ret != 0) return ret;
1234 /* compare attr.cf_value. */
1235 if (b_vlen != dn_vlen) {
1236 return b_vlen - dn_vlen;
1238 ret = strcmp(b_vdata, dn_vdata);
1239 if (ret != 0) return ret;
1248 /* compare DNs using casefolding compare functions.
1250 If they match, then return 0
1253 int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1)
1257 if (( ! dn0) || dn0->invalid || ! dn1 || dn1->invalid) {
1261 if (( ! dn0->valid_case) || ( ! dn1->valid_case)) {
1262 if (dn0->linearized && dn1->linearized) {
1263 /* try with a normal compare first, if we are lucky
1264 * we will avoid exploding and casfolding */
1265 if (strcmp(dn0->linearized, dn1->linearized) == 0) {
1270 if ( ! ldb_dn_casefold_internal(dn0)) {
1274 if ( ! ldb_dn_casefold_internal(dn1)) {
1280 if (dn0->comp_num != dn1->comp_num) {
1281 return (dn1->comp_num - dn0->comp_num);
1284 if (dn0->comp_num == 0) {
1285 if (dn0->special && dn1->special) {
1286 return strcmp(dn0->linearized, dn1->linearized);
1287 } else if (dn0->special) {
1289 } else if (dn1->special) {
1296 for (i = 0; i < dn0->comp_num; i++) {
1297 char *dn0_name = dn0->components[i].cf_name;
1298 char *dn1_name = dn1->components[i].cf_name;
1300 char *dn0_vdata = (char *)dn0->components[i].cf_value.data;
1301 char *dn1_vdata = (char *)dn1->components[i].cf_value.data;
1303 size_t dn0_vlen = dn0->components[i].cf_value.length;
1304 size_t dn1_vlen = dn1->components[i].cf_value.length;
1306 /* compare attr names */
1307 ret = strcmp(dn0_name, dn1_name);
1312 /* compare attr.cf_value. */
1313 if (dn0_vlen != dn1_vlen) {
1314 return dn0_vlen - dn1_vlen;
1316 ret = strcmp(dn0_vdata, dn1_vdata);
1325 static struct ldb_dn_component ldb_dn_copy_component(
1327 struct ldb_dn_component *src)
1329 struct ldb_dn_component dst;
1331 memset(&dst, 0, sizeof(dst));
1337 dst.value = ldb_val_dup(mem_ctx, &(src->value));
1338 if (dst.value.data == NULL) {
1342 dst.name = talloc_strdup(mem_ctx, src->name);
1343 if (dst.name == NULL) {
1344 LDB_FREE(dst.value.data);
1348 if (src->cf_value.data) {
1349 dst.cf_value = ldb_val_dup(mem_ctx, &(src->cf_value));
1350 if (dst.cf_value.data == NULL) {
1351 LDB_FREE(dst.value.data);
1356 dst.cf_name = talloc_strdup(mem_ctx, src->cf_name);
1357 if (dst.cf_name == NULL) {
1358 LDB_FREE(dst.cf_name);
1359 LDB_FREE(dst.value.data);
1364 dst.cf_value.data = NULL;
1371 static struct ldb_dn_ext_component ldb_dn_ext_copy_component(
1373 struct ldb_dn_ext_component *src)
1375 struct ldb_dn_ext_component dst;
1377 memset(&dst, 0, sizeof(dst));
1383 dst.value = ldb_val_dup(mem_ctx, &(src->value));
1384 if (dst.value.data == NULL) {
1388 dst.name = talloc_strdup(mem_ctx, src->name);
1389 if (dst.name == NULL) {
1390 LDB_FREE(dst.value.data);
1397 struct ldb_dn *ldb_dn_copy(void *mem_ctx, struct ldb_dn *dn)
1399 struct ldb_dn *new_dn;
1401 if (!dn || dn->invalid) {
1405 new_dn = talloc_zero(mem_ctx, struct ldb_dn);
1412 if (dn->components) {
1415 new_dn->components =
1416 talloc_zero_array(new_dn,
1417 struct ldb_dn_component,
1419 if ( ! new_dn->components) {
1420 talloc_free(new_dn);
1424 for (i = 0; i < dn->comp_num; i++) {
1425 new_dn->components[i] =
1426 ldb_dn_copy_component(new_dn->components,
1427 &dn->components[i]);
1428 if ( ! new_dn->components[i].value.data) {
1429 talloc_free(new_dn);
1435 if (dn->ext_components) {
1438 new_dn->ext_components =
1439 talloc_zero_array(new_dn,
1440 struct ldb_dn_ext_component,
1442 if ( ! new_dn->ext_components) {
1443 talloc_free(new_dn);
1447 for (i = 0; i < dn->ext_comp_num; i++) {
1448 new_dn->ext_components[i] =
1449 ldb_dn_ext_copy_component(
1450 new_dn->ext_components,
1451 &dn->ext_components[i]);
1452 if ( ! new_dn->ext_components[i].value.data) {
1453 talloc_free(new_dn);
1460 new_dn->casefold = talloc_strdup(new_dn, dn->casefold);
1461 if ( ! new_dn->casefold) {
1462 talloc_free(new_dn);
1467 if (dn->linearized) {
1468 new_dn->linearized = talloc_strdup(new_dn, dn->linearized);
1469 if ( ! new_dn->linearized) {
1470 talloc_free(new_dn);
1475 if (dn->ext_linearized) {
1476 new_dn->ext_linearized = talloc_strdup(new_dn,
1477 dn->ext_linearized);
1478 if ( ! new_dn->ext_linearized) {
1479 talloc_free(new_dn);
1487 /* modify the given dn by adding a base.
1489 * return true if successful and false if not
1490 * if false is returned the dn may be marked invalid
1492 bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base)
1497 if ( !base || base->invalid || !dn || dn->invalid) {
1501 if (dn->components) {
1504 if ( ! ldb_dn_validate(base)) {
1509 if (dn->valid_case) {
1510 if ( ! (s = ldb_dn_get_casefold(base))) {
1515 dn->components = talloc_realloc(dn,
1517 struct ldb_dn_component,
1518 dn->comp_num + base->comp_num);
1519 if ( ! dn->components) {
1520 ldb_dn_mark_invalid(dn);
1524 for (i = 0; i < base->comp_num; dn->comp_num++, i++) {
1525 dn->components[dn->comp_num] =
1526 ldb_dn_copy_component(dn->components,
1527 &base->components[i]);
1528 if (dn->components[dn->comp_num].value.data == NULL) {
1529 ldb_dn_mark_invalid(dn);
1534 if (dn->casefold && s) {
1535 if (*dn->casefold) {
1536 t = talloc_asprintf(dn, "%s,%s",
1539 t = talloc_strdup(dn, s);
1541 LDB_FREE(dn->casefold);
1546 if (dn->linearized) {
1548 s = ldb_dn_get_linearized(base);
1553 if (*dn->linearized) {
1554 t = talloc_asprintf(dn, "%s,%s",
1557 t = talloc_strdup(dn, s);
1560 ldb_dn_mark_invalid(dn);
1563 LDB_FREE(dn->linearized);
1567 /* Wipe the ext_linearized DN,
1568 * the GUID and SID are almost certainly no longer valid */
1569 if (dn->ext_linearized) {
1570 LDB_FREE(dn->ext_linearized);
1573 LDB_FREE(dn->ext_components);
1574 dn->ext_comp_num = 0;
1578 /* modify the given dn by adding a base.
1580 * return true if successful and false if not
1581 * if false is returned the dn may be marked invalid
1583 bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...)
1585 struct ldb_dn *base;
1590 if ( !dn || dn->invalid) {
1594 va_start(ap, base_fmt);
1595 base_str = talloc_vasprintf(dn, base_fmt, ap);
1598 if (base_str == NULL) {
1602 base = ldb_dn_new(base_str, dn->ldb, base_str);
1604 ret = ldb_dn_add_base(dn, base);
1606 talloc_free(base_str);
1611 /* modify the given dn by adding children elements.
1613 * return true if successful and false if not
1614 * if false is returned the dn may be marked invalid
1616 bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child)
1621 if ( !child || child->invalid || !dn || dn->invalid) {
1625 if (dn->components) {
1628 if ( ! ldb_dn_validate(child)) {
1633 if (dn->valid_case) {
1634 if ( ! (s = ldb_dn_get_casefold(child))) {
1639 n = dn->comp_num + child->comp_num;
1641 dn->components = talloc_realloc(dn,
1643 struct ldb_dn_component,
1645 if ( ! dn->components) {
1646 ldb_dn_mark_invalid(dn);
1650 for (i = dn->comp_num - 1, j = n - 1; i >= 0; i--, j--) {
1651 dn->components[j] = dn->components[i];
1654 for (i = 0; i < child->comp_num; i++) {
1656 ldb_dn_copy_component(dn->components,
1657 &child->components[i]);
1658 if (dn->components[i].value.data == NULL) {
1659 ldb_dn_mark_invalid(dn);
1666 if (dn->casefold && s) {
1667 t = talloc_asprintf(dn, "%s,%s", s, dn->casefold);
1668 LDB_FREE(dn->casefold);
1673 if (dn->linearized) {
1675 s = ldb_dn_get_linearized(child);
1680 t = talloc_asprintf(dn, "%s,%s", s, dn->linearized);
1682 ldb_dn_mark_invalid(dn);
1685 LDB_FREE(dn->linearized);
1689 /* Wipe the ext_linearized DN,
1690 * the GUID and SID are almost certainly no longer valid */
1691 LDB_FREE(dn->ext_linearized);
1693 LDB_FREE(dn->ext_components);
1694 dn->ext_comp_num = 0;
1699 /* modify the given dn by adding children elements.
1701 * return true if successful and false if not
1702 * if false is returned the dn may be marked invalid
1704 bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...)
1706 struct ldb_dn *child;
1711 if ( !dn || dn->invalid) {
1715 va_start(ap, child_fmt);
1716 child_str = talloc_vasprintf(dn, child_fmt, ap);
1719 if (child_str == NULL) {
1723 child = ldb_dn_new(child_str, dn->ldb, child_str);
1725 ret = ldb_dn_add_child(dn, child);
1727 talloc_free(child_str);
1732 bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num)
1736 if ( ! ldb_dn_validate(dn)) {
1740 if (dn->comp_num < num) {
1744 /* free components */
1745 for (i = num; i > 0; i--) {
1746 LDB_FREE(dn->components[dn->comp_num - i].name);
1747 LDB_FREE(dn->components[dn->comp_num - i].value.data);
1748 LDB_FREE(dn->components[dn->comp_num - i].cf_name);
1749 LDB_FREE(dn->components[dn->comp_num - i].cf_value.data);
1752 dn->comp_num -= num;
1754 if (dn->valid_case) {
1755 for (i = 0; i < dn->comp_num; i++) {
1756 LDB_FREE(dn->components[i].cf_name);
1757 LDB_FREE(dn->components[i].cf_value.data);
1759 dn->valid_case = false;
1762 LDB_FREE(dn->casefold);
1763 LDB_FREE(dn->linearized);
1765 /* Wipe the ext_linearized DN,
1766 * the GUID and SID are almost certainly no longer valid */
1767 LDB_FREE(dn->ext_linearized);
1769 LDB_FREE(dn->ext_components);
1770 dn->ext_comp_num = 0;
1775 bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num)
1779 if ( ! ldb_dn_validate(dn)) {
1783 if (dn->comp_num < num) {
1787 for (i = 0, j = num; j < dn->comp_num; i++, j++) {
1789 LDB_FREE(dn->components[i].name);
1790 LDB_FREE(dn->components[i].value.data);
1791 LDB_FREE(dn->components[i].cf_name);
1792 LDB_FREE(dn->components[i].cf_value.data);
1794 dn->components[i] = dn->components[j];
1797 dn->comp_num -= num;
1799 if (dn->valid_case) {
1800 for (i = 0; i < dn->comp_num; i++) {
1801 LDB_FREE(dn->components[i].cf_name);
1802 LDB_FREE(dn->components[i].cf_value.data);
1804 dn->valid_case = false;
1807 LDB_FREE(dn->casefold);
1808 LDB_FREE(dn->linearized);
1810 /* Wipe the ext_linearized DN,
1811 * the GUID and SID are almost certainly no longer valid */
1812 LDB_FREE(dn->ext_linearized);
1814 LDB_FREE(dn->ext_components);
1815 dn->ext_comp_num = 0;
1819 struct ldb_dn *ldb_dn_get_parent(void *mem_ctx, struct ldb_dn *dn)
1821 struct ldb_dn *new_dn;
1823 new_dn = ldb_dn_copy(mem_ctx, dn);
1828 if ( ! ldb_dn_remove_child_components(new_dn, 1)) {
1829 talloc_free(new_dn);
1833 /* Wipe the ext_linearized DN,
1834 * the GUID and SID are almost certainly no longer valid */
1835 LDB_FREE(dn->ext_linearized);
1837 LDB_FREE(dn->ext_components);
1838 dn->ext_comp_num = 0;
1842 /* Create a 'canonical name' string from a DN:
1844 ie dc=samba,dc=org -> samba.org/
1845 uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator
1847 There are two formats,
1848 the EX format has the last '/' replaced with a newline (\n).
1851 static char *ldb_dn_canonical(void *mem_ctx, struct ldb_dn *dn, int ex_format) {
1854 char *cracked = NULL;
1855 const char *format = (ex_format ? "\n" : "/" );
1857 if ( ! ldb_dn_validate(dn)) {
1861 tmpctx = talloc_new(mem_ctx);
1863 /* Walk backwards down the DN, grabbing 'dc' components at first */
1864 for (i = dn->comp_num - 1 ; i >= 0; i--) {
1865 if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) {
1869 cracked = talloc_asprintf(tmpctx, "%s.%s",
1870 ldb_dn_escape_value(tmpctx,
1871 dn->components[i].value),
1874 cracked = ldb_dn_escape_value(tmpctx,
1875 dn->components[i].value);
1882 /* Only domain components? Finish here */
1884 cracked = talloc_strdup_append_buffer(cracked, format);
1885 talloc_steal(mem_ctx, cracked);
1889 /* Now walk backwards appending remaining components */
1890 for (; i > 0; i--) {
1891 cracked = talloc_asprintf_append_buffer(cracked, "/%s",
1892 ldb_dn_escape_value(tmpctx,
1893 dn->components[i].value));
1899 /* Last one, possibly a newline for the 'ex' format */
1900 cracked = talloc_asprintf_append_buffer(cracked, "%s%s", format,
1901 ldb_dn_escape_value(tmpctx,
1902 dn->components[i].value));
1904 talloc_steal(mem_ctx, cracked);
1906 talloc_free(tmpctx);
1910 /* Wrapper functions for the above, for the two different string formats */
1911 char *ldb_dn_canonical_string(void *mem_ctx, struct ldb_dn *dn) {
1912 return ldb_dn_canonical(mem_ctx, dn, 0);
1916 char *ldb_dn_canonical_ex_string(void *mem_ctx, struct ldb_dn *dn) {
1917 return ldb_dn_canonical(mem_ctx, dn, 1);
1920 int ldb_dn_get_comp_num(struct ldb_dn *dn)
1922 if ( ! ldb_dn_validate(dn)) {
1925 return dn->comp_num;
1928 const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num)
1930 if ( ! ldb_dn_validate(dn)) {
1933 if (num >= dn->comp_num) return NULL;
1934 return dn->components[num].name;
1937 const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn,
1940 if ( ! ldb_dn_validate(dn)) {
1943 if (num >= dn->comp_num) return NULL;
1944 return &dn->components[num].value;
1947 const char *ldb_dn_get_rdn_name(struct ldb_dn *dn)
1949 if ( ! ldb_dn_validate(dn)) {
1952 if (dn->comp_num == 0) return NULL;
1953 return dn->components[0].name;
1956 const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn)
1958 if ( ! ldb_dn_validate(dn)) {
1961 if (dn->comp_num == 0) return NULL;
1962 return &dn->components[0].value;
1965 int ldb_dn_set_component(struct ldb_dn *dn, int num,
1966 const char *name, const struct ldb_val val)
1971 if ( ! ldb_dn_validate(dn)) {
1972 return LDB_ERR_OTHER;
1975 if (num >= dn->comp_num) {
1976 return LDB_ERR_OTHER;
1979 n = talloc_strdup(dn, name);
1981 return LDB_ERR_OTHER;
1984 v.length = val.length;
1985 v.data = (uint8_t *)talloc_memdup(dn, val.data, v.length+1);
1988 return LDB_ERR_OTHER;
1991 talloc_free(dn->components[num].name);
1992 talloc_free(dn->components[num].value.data);
1993 dn->components[num].name = n;
1994 dn->components[num].value = v;
1996 if (dn->valid_case) {
1998 for (i = 0; i < dn->comp_num; i++) {
1999 LDB_FREE(dn->components[i].cf_name);
2000 LDB_FREE(dn->components[i].cf_value.data);
2002 dn->valid_case = false;
2004 LDB_FREE(dn->casefold);
2005 LDB_FREE(dn->linearized);
2007 /* Wipe the ext_linearized DN,
2008 * the GUID and SID are almost certainly no longer valid */
2009 LDB_FREE(dn->ext_linearized);
2011 dn->ext_comp_num = 0;
2012 LDB_FREE(dn->ext_components);
2016 const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn,
2020 if ( ! ldb_dn_validate(dn)) {
2023 for (i=0; i < dn->ext_comp_num; i++) {
2024 if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) {
2025 return &dn->ext_components[i].value;
2031 int ldb_dn_set_extended_component(struct ldb_dn *dn,
2032 const char *name, const struct ldb_val *val)
2034 struct ldb_dn_ext_component *p;
2037 if ( ! ldb_dn_validate(dn)) {
2038 return LDB_ERR_OTHER;
2041 for (i=0; i < dn->ext_comp_num; i++) {
2042 if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) {
2044 dn->ext_components[i].value =
2045 ldb_val_dup(dn->ext_components, val);
2047 dn->ext_components[i].name =
2048 talloc_strdup(dn->ext_components, name);
2049 if (!dn->ext_components[i].name ||
2050 !dn->ext_components[i].value.data) {
2051 ldb_dn_mark_invalid(dn);
2052 return LDB_ERR_OPERATIONS_ERROR;
2056 if (i != (dn->ext_comp_num - 1)) {
2057 memmove(&dn->ext_components[i],
2058 &dn->ext_components[i+1],
2059 ((dn->ext_comp_num-1) - i) *
2060 sizeof(*dn->ext_components));
2064 dn->ext_components = talloc_realloc(dn,
2066 struct ldb_dn_ext_component,
2068 if (!dn->ext_components) {
2069 ldb_dn_mark_invalid(dn);
2070 return LDB_ERR_OPERATIONS_ERROR;
2077 p = dn->ext_components
2078 = talloc_realloc(dn,
2080 struct ldb_dn_ext_component,
2081 dn->ext_comp_num + 1);
2082 if (!dn->ext_components) {
2083 ldb_dn_mark_invalid(dn);
2084 return LDB_ERR_OPERATIONS_ERROR;
2087 p[dn->ext_comp_num].value = ldb_val_dup(dn->ext_components, val);
2088 p[dn->ext_comp_num].name = talloc_strdup(p, name);
2090 if (!dn->ext_components[i].name || !dn->ext_components[i].value.data) {
2091 ldb_dn_mark_invalid(dn);
2092 return LDB_ERR_OPERATIONS_ERROR;
2094 dn->ext_components = p;
2100 void ldb_dn_remove_extended_components(struct ldb_dn *dn)
2102 dn->ext_comp_num = 0;
2103 LDB_FREE(dn->ext_components);
2106 bool ldb_dn_is_valid(struct ldb_dn *dn)
2108 if ( ! dn) return false;
2109 return ! dn->invalid;
2112 bool ldb_dn_is_special(struct ldb_dn *dn)
2114 if ( ! dn || dn->invalid) return false;
2118 bool ldb_dn_has_extended(struct ldb_dn *dn)
2120 if ( ! dn || dn->invalid) return false;
2121 if (dn->ext_linearized && strchr(dn->ext_linearized,'<')) return true;
2122 return dn->ext_comp_num != 0;
2125 bool ldb_dn_check_special(struct ldb_dn *dn, const char *check)
2127 if ( ! dn || dn->invalid) return false;
2128 return ! strcmp(dn->linearized, check);
2131 bool ldb_dn_is_null(struct ldb_dn *dn)
2133 if ( ! dn || dn->invalid) return false;
2134 if (ldb_dn_has_extended(dn)) return false;
2135 if (dn->linearized && (dn->linearized[0] == '\0')) return true;
2139 int ldb_dn_get_binary(struct ldb_dn *dn, struct ldb_val *val)
2142 if (dn->extra_type != 'B') {
2145 *val = dn->extra_val;
2149 int ldb_dn_set_binary(struct ldb_dn *dn, struct ldb_val *val)
2151 dn->extra_type = 'B';
2152 dn->extra_val.data = talloc_memdup(dn, val->data, val->length);
2153 dn->extra_val.length = val->length;
2155 talloc_free(dn->linearized);
2156 talloc_free(dn->ext_linearized);
2157 dn->linearized = NULL;
2158 dn->ext_linearized = NULL;