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
= *(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 char *ldb_dn_get_extended_linearized(void *mem_ctx
, struct ldb_dn
*dn
, int mode
)
794 const char *linearized
= ldb_dn_get_linearized(dn
);
802 if (!ldb_dn_has_extended(dn
)) {
803 return talloc_strdup(mem_ctx
, linearized
);
806 if (!ldb_dn_validate(dn
)) {
810 for (i
= 0; i
< dn
->ext_comp_num
; i
++) {
811 const struct ldb_dn_extended_syntax
*ext_syntax
;
812 const char *name
= dn
->ext_components
[i
].name
;
813 struct ldb_val ec_val
= dn
->ext_components
[i
].value
;
817 ext_syntax
= ldb_dn_extended_syntax_by_name(dn
->ldb
, name
);
823 ret
= ext_syntax
->write_clear_fn(dn
->ldb
, mem_ctx
,
825 } else if (mode
== 0) {
826 ret
= ext_syntax
->write_hex_fn(dn
->ldb
, mem_ctx
,
832 if (ret
!= LDB_SUCCESS
) {
837 p
= talloc_asprintf(mem_ctx
, "<%s=%s>",
840 p
= talloc_asprintf_append_buffer(p
, ";<%s=%s>",
844 talloc_free(val
.data
);
851 if (dn
->ext_comp_num
&& *linearized
) {
852 p
= talloc_asprintf_append_buffer(p
, ";%s", linearized
);
864 char *ldb_dn_alloc_linearized(void *mem_ctx
, struct ldb_dn
*dn
)
866 return talloc_strdup(mem_ctx
, ldb_dn_get_linearized(dn
));
870 casefold a dn. We need to casefold the attribute names, and canonicalize
871 attribute values of case insensitive attributes.
874 static bool ldb_dn_casefold_internal(struct ldb_dn
*dn
)
878 if ( ! dn
|| dn
->invalid
) return false;
880 if (dn
->valid_case
) return true;
882 if (( ! dn
->components
) && ( ! ldb_dn_explode(dn
))) {
886 for (i
= 0; i
< dn
->comp_num
; i
++) {
887 const struct ldb_schema_attribute
*a
;
889 dn
->components
[i
].cf_name
=
890 ldb_attr_casefold(dn
->components
,
891 dn
->components
[i
].name
);
892 if (!dn
->components
[i
].cf_name
) {
896 a
= ldb_schema_attribute_by_name(dn
->ldb
,
897 dn
->components
[i
].cf_name
);
899 ret
= a
->syntax
->canonicalise_fn(dn
->ldb
, dn
->components
,
900 &(dn
->components
[i
].value
),
901 &(dn
->components
[i
].cf_value
));
907 dn
->valid_case
= true;
912 for (i
= 0; i
< dn
->comp_num
; i
++) {
913 LDB_FREE(dn
->components
[i
].cf_name
);
914 LDB_FREE(dn
->components
[i
].cf_value
.data
);
919 const char *ldb_dn_get_casefold(struct ldb_dn
*dn
)
924 if (dn
->casefold
) return dn
->casefold
;
927 dn
->casefold
= talloc_strdup(dn
, dn
->linearized
);
928 if (!dn
->casefold
) return NULL
;
929 dn
->valid_case
= true;
933 if ( ! ldb_dn_casefold_internal(dn
)) {
937 if (dn
->comp_num
== 0) {
938 dn
->casefold
= talloc_strdup(dn
, "");
942 /* calculate maximum possible length of DN */
943 for (len
= 0, i
= 0; i
< dn
->comp_num
; i
++) {
945 len
+= strlen(dn
->components
[i
].cf_name
);
946 /* max escaped data len */
947 len
+= (dn
->components
[i
].cf_value
.length
* 3);
948 len
+= 2; /* '=' and ',' */
950 dn
->casefold
= talloc_array(dn
, char, len
);
951 if ( ! dn
->casefold
) return NULL
;
955 for (i
= 0; i
< dn
->comp_num
; i
++) {
958 n
= dn
->components
[i
].cf_name
;
959 while (*n
) *d
++ = *n
++;
964 d
+= ldb_dn_escape_internal( d
,
965 (char *)dn
->components
[i
].cf_value
.data
,
966 dn
->components
[i
].cf_value
.length
);
971 /* don't waste more memory than necessary */
972 dn
->casefold
= talloc_realloc(dn
, dn
->casefold
,
973 char, strlen(dn
->casefold
) + 1);
978 char *ldb_dn_alloc_casefold(void *mem_ctx
, struct ldb_dn
*dn
)
980 return talloc_strdup(mem_ctx
, ldb_dn_get_casefold(dn
));
983 /* Determine if dn is below base, in the ldap tree. Used for
984 * evaluating a subtree search.
985 * 0 if they match, otherwise non-zero
988 int ldb_dn_compare_base(struct ldb_dn
*base
, struct ldb_dn
*dn
)
993 if ( ! base
|| base
->invalid
) return 1;
994 if ( ! dn
|| dn
->invalid
) return -1;
996 if (( ! base
->valid_case
) || ( ! dn
->valid_case
)) {
997 if (base
->linearized
&& dn
->linearized
) {
998 /* try with a normal compare first, if we are lucky
999 * we will avoid exploding and casfolding */
1001 dif
= strlen(dn
->linearized
) - strlen(base
->linearized
);
1005 if (strcmp(base
->linearized
,
1006 &dn
->linearized
[dif
]) == 0) {
1011 if ( ! ldb_dn_casefold_internal(base
)) {
1015 if ( ! ldb_dn_casefold_internal(dn
)) {
1021 /* if base has more components,
1022 * they don't have the same base */
1023 if (base
->comp_num
> dn
->comp_num
) {
1024 return (dn
->comp_num
- base
->comp_num
);
1027 if (dn
->comp_num
== 0) {
1028 if (dn
->special
&& base
->special
) {
1029 return strcmp(base
->linearized
, dn
->linearized
);
1030 } else if (dn
->special
) {
1032 } else if (base
->special
) {
1039 n_base
= base
->comp_num
- 1;
1040 n_dn
= dn
->comp_num
- 1;
1042 while (n_base
>= 0) {
1043 char *b_name
= base
->components
[n_base
].cf_name
;
1044 char *dn_name
= dn
->components
[n_dn
].cf_name
;
1046 char *b_vdata
= (char *)base
->components
[n_base
].cf_value
.data
;
1047 char *dn_vdata
= (char *)dn
->components
[n_dn
].cf_value
.data
;
1049 size_t b_vlen
= base
->components
[n_base
].cf_value
.length
;
1050 size_t dn_vlen
= dn
->components
[n_dn
].cf_value
.length
;
1052 /* compare attr names */
1053 ret
= strcmp(b_name
, dn_name
);
1054 if (ret
!= 0) return ret
;
1056 /* compare attr.cf_value. */
1057 if (b_vlen
!= dn_vlen
) {
1058 return b_vlen
- dn_vlen
;
1060 ret
= strcmp(b_vdata
, dn_vdata
);
1061 if (ret
!= 0) return ret
;
1070 /* compare DNs using casefolding compare functions.
1072 If they match, then return 0
1075 int ldb_dn_compare(struct ldb_dn
*dn0
, struct ldb_dn
*dn1
)
1079 if (( ! dn0
) || dn0
->invalid
|| ! dn1
|| dn1
->invalid
) {
1083 if (( ! dn0
->valid_case
) || ( ! dn1
->valid_case
)) {
1084 if (dn0
->linearized
&& dn1
->linearized
) {
1085 /* try with a normal compare first, if we are lucky
1086 * we will avoid exploding and casfolding */
1087 if (strcmp(dn0
->linearized
, dn1
->linearized
) == 0) {
1092 if ( ! ldb_dn_casefold_internal(dn0
)) {
1096 if ( ! ldb_dn_casefold_internal(dn1
)) {
1102 if (dn0
->comp_num
!= dn1
->comp_num
) {
1103 return (dn1
->comp_num
- dn0
->comp_num
);
1106 if (dn0
->comp_num
== 0) {
1107 if (dn0
->special
&& dn1
->special
) {
1108 return strcmp(dn0
->linearized
, dn1
->linearized
);
1109 } else if (dn0
->special
) {
1111 } else if (dn1
->special
) {
1118 for (i
= 0; i
< dn0
->comp_num
; i
++) {
1119 char *dn0_name
= dn0
->components
[i
].cf_name
;
1120 char *dn1_name
= dn1
->components
[i
].cf_name
;
1122 char *dn0_vdata
= (char *)dn0
->components
[i
].cf_value
.data
;
1123 char *dn1_vdata
= (char *)dn1
->components
[i
].cf_value
.data
;
1125 size_t dn0_vlen
= dn0
->components
[i
].cf_value
.length
;
1126 size_t dn1_vlen
= dn1
->components
[i
].cf_value
.length
;
1128 /* compare attr names */
1129 ret
= strcmp(dn0_name
, dn1_name
);
1134 /* compare attr.cf_value. */
1135 if (dn0_vlen
!= dn1_vlen
) {
1136 return dn0_vlen
- dn1_vlen
;
1138 ret
= strcmp(dn0_vdata
, dn1_vdata
);
1147 static struct ldb_dn_component
ldb_dn_copy_component(
1149 struct ldb_dn_component
*src
)
1151 struct ldb_dn_component dst
;
1153 memset(&dst
, 0, sizeof(dst
));
1159 dst
.value
= ldb_val_dup(mem_ctx
, &(src
->value
));
1160 if (dst
.value
.data
== NULL
) {
1164 dst
.name
= talloc_strdup(mem_ctx
, src
->name
);
1165 if (dst
.name
== NULL
) {
1166 LDB_FREE(dst
.value
.data
);
1170 if (src
->cf_value
.data
) {
1171 dst
.cf_value
= ldb_val_dup(mem_ctx
, &(src
->cf_value
));
1172 if (dst
.cf_value
.data
== NULL
) {
1173 LDB_FREE(dst
.value
.data
);
1178 dst
.cf_name
= talloc_strdup(mem_ctx
, src
->cf_name
);
1179 if (dst
.cf_name
== NULL
) {
1180 LDB_FREE(dst
.cf_name
);
1181 LDB_FREE(dst
.value
.data
);
1186 dst
.cf_value
.data
= NULL
;
1193 static struct ldb_dn_ext_component
ldb_dn_ext_copy_component(
1195 struct ldb_dn_ext_component
*src
)
1197 struct ldb_dn_ext_component dst
;
1199 memset(&dst
, 0, sizeof(dst
));
1205 dst
.value
= ldb_val_dup(mem_ctx
, &(src
->value
));
1206 if (dst
.value
.data
== NULL
) {
1210 dst
.name
= talloc_strdup(mem_ctx
, src
->name
);
1211 if (dst
.name
== NULL
) {
1212 LDB_FREE(dst
.value
.data
);
1219 struct ldb_dn
*ldb_dn_copy(void *mem_ctx
, struct ldb_dn
*dn
)
1221 struct ldb_dn
*new_dn
;
1223 if (!dn
|| dn
->invalid
) {
1227 new_dn
= talloc_zero(mem_ctx
, struct ldb_dn
);
1234 if (dn
->components
) {
1237 new_dn
->components
=
1238 talloc_zero_array(new_dn
,
1239 struct ldb_dn_component
,
1241 if ( ! new_dn
->components
) {
1242 talloc_free(new_dn
);
1246 for (i
= 0; i
< dn
->comp_num
; i
++) {
1247 new_dn
->components
[i
] =
1248 ldb_dn_copy_component(new_dn
->components
,
1249 &dn
->components
[i
]);
1250 if ( ! new_dn
->components
[i
].value
.data
) {
1251 talloc_free(new_dn
);
1257 if (dn
->ext_components
) {
1260 new_dn
->ext_components
=
1261 talloc_zero_array(new_dn
,
1262 struct ldb_dn_ext_component
,
1264 if ( ! new_dn
->ext_components
) {
1265 talloc_free(new_dn
);
1269 for (i
= 0; i
< dn
->ext_comp_num
; i
++) {
1270 new_dn
->ext_components
[i
] =
1271 ldb_dn_ext_copy_component(
1272 new_dn
->ext_components
,
1273 &dn
->ext_components
[i
]);
1274 if ( ! new_dn
->ext_components
[i
].value
.data
) {
1275 talloc_free(new_dn
);
1282 new_dn
->casefold
= talloc_strdup(new_dn
, dn
->casefold
);
1283 if ( ! new_dn
->casefold
) {
1284 talloc_free(new_dn
);
1289 if (dn
->linearized
) {
1290 new_dn
->linearized
= talloc_strdup(new_dn
, dn
->linearized
);
1291 if ( ! new_dn
->linearized
) {
1292 talloc_free(new_dn
);
1297 if (dn
->ext_linearized
) {
1298 new_dn
->ext_linearized
= talloc_strdup(new_dn
,
1299 dn
->ext_linearized
);
1300 if ( ! new_dn
->ext_linearized
) {
1301 talloc_free(new_dn
);
1309 /* modify the given dn by adding a base.
1311 * return true if successful and false if not
1312 * if false is returned the dn may be marked invalid
1314 bool ldb_dn_add_base(struct ldb_dn
*dn
, struct ldb_dn
*base
)
1319 if ( !base
|| base
->invalid
|| !dn
|| dn
->invalid
) {
1323 if (dn
->components
) {
1326 if ( ! ldb_dn_validate(base
)) {
1331 if (dn
->valid_case
) {
1332 if ( ! (s
= ldb_dn_get_casefold(base
))) {
1337 dn
->components
= talloc_realloc(dn
,
1339 struct ldb_dn_component
,
1340 dn
->comp_num
+ base
->comp_num
);
1341 if ( ! dn
->components
) {
1342 ldb_dn_mark_invalid(dn
);
1346 for (i
= 0; i
< base
->comp_num
; dn
->comp_num
++, i
++) {
1347 dn
->components
[dn
->comp_num
] =
1348 ldb_dn_copy_component(dn
->components
,
1349 &base
->components
[i
]);
1350 if (dn
->components
[dn
->comp_num
].value
.data
== NULL
) {
1351 ldb_dn_mark_invalid(dn
);
1356 if (dn
->casefold
&& s
) {
1357 if (*dn
->casefold
) {
1358 t
= talloc_asprintf(dn
, "%s,%s",
1361 t
= talloc_strdup(dn
, s
);
1363 LDB_FREE(dn
->casefold
);
1368 if (dn
->linearized
) {
1370 s
= ldb_dn_get_linearized(base
);
1375 if (*dn
->linearized
) {
1376 t
= talloc_asprintf(dn
, "%s,%s",
1379 t
= talloc_strdup(dn
, s
);
1382 ldb_dn_mark_invalid(dn
);
1385 LDB_FREE(dn
->linearized
);
1389 /* Wipe the ext_linearized DN,
1390 * the GUID and SID are almost certainly no longer valid */
1391 if (dn
->ext_linearized
) {
1392 LDB_FREE(dn
->ext_linearized
);
1395 LDB_FREE(dn
->ext_components
);
1396 dn
->ext_comp_num
= 0;
1400 /* modify the given dn by adding a base.
1402 * return true if successful and false if not
1403 * if false is returned the dn may be marked invalid
1405 bool ldb_dn_add_base_fmt(struct ldb_dn
*dn
, const char *base_fmt
, ...)
1407 struct ldb_dn
*base
;
1412 if ( !dn
|| dn
->invalid
) {
1416 va_start(ap
, base_fmt
);
1417 base_str
= talloc_vasprintf(dn
, base_fmt
, ap
);
1420 if (base_str
== NULL
) {
1424 base
= ldb_dn_new(base_str
, dn
->ldb
, base_str
);
1426 ret
= ldb_dn_add_base(dn
, base
);
1428 talloc_free(base_str
);
1433 /* modify the given dn by adding children elements.
1435 * return true if successful and false if not
1436 * if false is returned the dn may be marked invalid
1438 bool ldb_dn_add_child(struct ldb_dn
*dn
, struct ldb_dn
*child
)
1443 if ( !child
|| child
->invalid
|| !dn
|| dn
->invalid
) {
1447 if (dn
->components
) {
1450 if ( ! ldb_dn_validate(child
)) {
1455 if (dn
->valid_case
) {
1456 if ( ! (s
= ldb_dn_get_casefold(child
))) {
1461 n
= dn
->comp_num
+ child
->comp_num
;
1463 dn
->components
= talloc_realloc(dn
,
1465 struct ldb_dn_component
,
1467 if ( ! dn
->components
) {
1468 ldb_dn_mark_invalid(dn
);
1472 for (i
= dn
->comp_num
- 1, j
= n
- 1; i
>= 0; i
--, j
--) {
1473 dn
->components
[j
] = dn
->components
[i
];
1476 for (i
= 0; i
< child
->comp_num
; i
++) {
1478 ldb_dn_copy_component(dn
->components
,
1479 &child
->components
[i
]);
1480 if (dn
->components
[i
].value
.data
== NULL
) {
1481 ldb_dn_mark_invalid(dn
);
1488 if (dn
->casefold
&& s
) {
1489 t
= talloc_asprintf(dn
, "%s,%s", s
, dn
->casefold
);
1490 LDB_FREE(dn
->casefold
);
1495 if (dn
->linearized
) {
1497 s
= ldb_dn_get_linearized(child
);
1502 t
= talloc_asprintf(dn
, "%s,%s", s
, dn
->linearized
);
1504 ldb_dn_mark_invalid(dn
);
1507 LDB_FREE(dn
->linearized
);
1511 /* Wipe the ext_linearized DN,
1512 * the GUID and SID are almost certainly no longer valid */
1513 LDB_FREE(dn
->ext_linearized
);
1515 LDB_FREE(dn
->ext_components
);
1516 dn
->ext_comp_num
= 0;
1521 /* modify the given dn by adding children elements.
1523 * return true if successful and false if not
1524 * if false is returned the dn may be marked invalid
1526 bool ldb_dn_add_child_fmt(struct ldb_dn
*dn
, const char *child_fmt
, ...)
1528 struct ldb_dn
*child
;
1533 if ( !dn
|| dn
->invalid
) {
1537 va_start(ap
, child_fmt
);
1538 child_str
= talloc_vasprintf(dn
, child_fmt
, ap
);
1541 if (child_str
== NULL
) {
1545 child
= ldb_dn_new(child_str
, dn
->ldb
, child_str
);
1547 ret
= ldb_dn_add_child(dn
, child
);
1549 talloc_free(child_str
);
1554 bool ldb_dn_remove_base_components(struct ldb_dn
*dn
, unsigned int num
)
1558 if ( ! ldb_dn_validate(dn
)) {
1562 if (dn
->comp_num
< num
) {
1566 /* free components */
1567 for (i
= num
; i
> 0; i
--) {
1568 LDB_FREE(dn
->components
[dn
->comp_num
- i
].name
);
1569 LDB_FREE(dn
->components
[dn
->comp_num
- i
].value
.data
);
1570 LDB_FREE(dn
->components
[dn
->comp_num
- i
].cf_name
);
1571 LDB_FREE(dn
->components
[dn
->comp_num
- i
].cf_value
.data
);
1574 dn
->comp_num
-= num
;
1576 if (dn
->valid_case
) {
1577 for (i
= 0; i
< dn
->comp_num
; i
++) {
1578 LDB_FREE(dn
->components
[i
].cf_name
);
1579 LDB_FREE(dn
->components
[i
].cf_value
.data
);
1581 dn
->valid_case
= false;
1584 LDB_FREE(dn
->casefold
);
1585 LDB_FREE(dn
->linearized
);
1587 /* Wipe the ext_linearized DN,
1588 * the GUID and SID are almost certainly no longer valid */
1589 LDB_FREE(dn
->ext_linearized
);
1591 LDB_FREE(dn
->ext_components
);
1592 dn
->ext_comp_num
= 0;
1597 bool ldb_dn_remove_child_components(struct ldb_dn
*dn
, unsigned int num
)
1601 if ( ! ldb_dn_validate(dn
)) {
1605 if (dn
->comp_num
< num
) {
1609 for (i
= 0, j
= num
; j
< dn
->comp_num
; i
++, j
++) {
1611 LDB_FREE(dn
->components
[i
].name
);
1612 LDB_FREE(dn
->components
[i
].value
.data
);
1613 LDB_FREE(dn
->components
[i
].cf_name
);
1614 LDB_FREE(dn
->components
[i
].cf_value
.data
);
1616 dn
->components
[i
] = dn
->components
[j
];
1619 dn
->comp_num
-= num
;
1621 if (dn
->valid_case
) {
1622 for (i
= 0; i
< dn
->comp_num
; i
++) {
1623 LDB_FREE(dn
->components
[i
].cf_name
);
1624 LDB_FREE(dn
->components
[i
].cf_value
.data
);
1626 dn
->valid_case
= false;
1629 LDB_FREE(dn
->casefold
);
1630 LDB_FREE(dn
->linearized
);
1632 /* Wipe the ext_linearized DN,
1633 * the GUID and SID are almost certainly no longer valid */
1634 LDB_FREE(dn
->ext_linearized
);
1636 LDB_FREE(dn
->ext_components
);
1637 dn
->ext_comp_num
= 0;
1641 struct ldb_dn
*ldb_dn_get_parent(void *mem_ctx
, struct ldb_dn
*dn
)
1643 struct ldb_dn
*new_dn
;
1645 new_dn
= ldb_dn_copy(mem_ctx
, dn
);
1650 if ( ! ldb_dn_remove_child_components(new_dn
, 1)) {
1651 talloc_free(new_dn
);
1655 /* Wipe the ext_linearized DN,
1656 * the GUID and SID are almost certainly no longer valid */
1657 LDB_FREE(dn
->ext_linearized
);
1659 LDB_FREE(dn
->ext_components
);
1660 dn
->ext_comp_num
= 0;
1664 /* Create a 'canonical name' string from a DN:
1666 ie dc=samba,dc=org -> samba.org/
1667 uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator
1669 There are two formats,
1670 the EX format has the last '/' replaced with a newline (\n).
1673 static char *ldb_dn_canonical(void *mem_ctx
, struct ldb_dn
*dn
, int ex_format
) {
1676 char *cracked
= NULL
;
1677 const char *format
= (ex_format
? "\n" : "/" );
1679 if ( ! ldb_dn_validate(dn
)) {
1683 tmpctx
= talloc_new(mem_ctx
);
1685 /* Walk backwards down the DN, grabbing 'dc' components at first */
1686 for (i
= dn
->comp_num
- 1 ; i
>= 0; i
--) {
1687 if (ldb_attr_cmp(dn
->components
[i
].name
, "dc") != 0) {
1691 cracked
= talloc_asprintf(tmpctx
, "%s.%s",
1692 ldb_dn_escape_value(tmpctx
,
1693 dn
->components
[i
].value
),
1696 cracked
= ldb_dn_escape_value(tmpctx
,
1697 dn
->components
[i
].value
);
1704 /* Only domain components? Finish here */
1706 cracked
= talloc_strdup_append_buffer(cracked
, format
);
1707 talloc_steal(mem_ctx
, cracked
);
1711 /* Now walk backwards appending remaining components */
1712 for (; i
> 0; i
--) {
1713 cracked
= talloc_asprintf_append_buffer(cracked
, "/%s",
1714 ldb_dn_escape_value(tmpctx
,
1715 dn
->components
[i
].value
));
1721 /* Last one, possibly a newline for the 'ex' format */
1722 cracked
= talloc_asprintf_append_buffer(cracked
, "%s%s", format
,
1723 ldb_dn_escape_value(tmpctx
,
1724 dn
->components
[i
].value
));
1726 talloc_steal(mem_ctx
, cracked
);
1728 talloc_free(tmpctx
);
1732 /* Wrapper functions for the above, for the two different string formats */
1733 char *ldb_dn_canonical_string(void *mem_ctx
, struct ldb_dn
*dn
) {
1734 return ldb_dn_canonical(mem_ctx
, dn
, 0);
1738 char *ldb_dn_canonical_ex_string(void *mem_ctx
, struct ldb_dn
*dn
) {
1739 return ldb_dn_canonical(mem_ctx
, dn
, 1);
1742 int ldb_dn_get_comp_num(struct ldb_dn
*dn
)
1744 if ( ! ldb_dn_validate(dn
)) {
1747 return dn
->comp_num
;
1750 const char *ldb_dn_get_component_name(struct ldb_dn
*dn
, unsigned int num
)
1752 if ( ! ldb_dn_validate(dn
)) {
1755 if (num
>= dn
->comp_num
) return NULL
;
1756 return dn
->components
[num
].name
;
1759 const struct ldb_val
*ldb_dn_get_component_val(struct ldb_dn
*dn
,
1762 if ( ! ldb_dn_validate(dn
)) {
1765 if (num
>= dn
->comp_num
) return NULL
;
1766 return &dn
->components
[num
].value
;
1769 const char *ldb_dn_get_rdn_name(struct ldb_dn
*dn
)
1771 if ( ! ldb_dn_validate(dn
)) {
1774 if (dn
->comp_num
== 0) return NULL
;
1775 return dn
->components
[0].name
;
1778 const struct ldb_val
*ldb_dn_get_rdn_val(struct ldb_dn
*dn
)
1780 if ( ! ldb_dn_validate(dn
)) {
1783 if (dn
->comp_num
== 0) return NULL
;
1784 return &dn
->components
[0].value
;
1787 int ldb_dn_set_component(struct ldb_dn
*dn
, int num
,
1788 const char *name
, const struct ldb_val val
)
1793 if ( ! ldb_dn_validate(dn
)) {
1794 return LDB_ERR_OTHER
;
1797 if (num
>= dn
->comp_num
) {
1798 return LDB_ERR_OTHER
;
1801 n
= talloc_strdup(dn
, name
);
1803 return LDB_ERR_OTHER
;
1806 v
.length
= val
.length
;
1807 v
.data
= (uint8_t *)talloc_memdup(dn
, val
.data
, v
.length
+1);
1810 return LDB_ERR_OTHER
;
1813 talloc_free(dn
->components
[num
].name
);
1814 talloc_free(dn
->components
[num
].value
.data
);
1815 dn
->components
[num
].name
= n
;
1816 dn
->components
[num
].value
= v
;
1818 if (dn
->valid_case
) {
1820 for (i
= 0; i
< dn
->comp_num
; i
++) {
1821 LDB_FREE(dn
->components
[i
].cf_name
);
1822 LDB_FREE(dn
->components
[i
].cf_value
.data
);
1824 dn
->valid_case
= false;
1826 LDB_FREE(dn
->casefold
);
1827 LDB_FREE(dn
->linearized
);
1829 /* Wipe the ext_linearized DN,
1830 * the GUID and SID are almost certainly no longer valid */
1831 LDB_FREE(dn
->ext_linearized
);
1833 dn
->ext_comp_num
= 0;
1834 LDB_FREE(dn
->ext_components
);
1838 const struct ldb_val
*ldb_dn_get_extended_component(struct ldb_dn
*dn
,
1842 if ( ! ldb_dn_validate(dn
)) {
1845 for (i
=0; i
< dn
->ext_comp_num
; i
++) {
1846 if (ldb_attr_cmp(dn
->ext_components
[i
].name
, name
) == 0) {
1847 return &dn
->ext_components
[i
].value
;
1853 int ldb_dn_set_extended_component(struct ldb_dn
*dn
,
1854 const char *name
, const struct ldb_val
*val
)
1856 struct ldb_dn_ext_component
*p
;
1859 if ( ! ldb_dn_validate(dn
)) {
1860 return LDB_ERR_OTHER
;
1863 if (!ldb_dn_extended_syntax_by_name(dn
->ldb
, name
)) {
1864 /* We don't know how to handle this type of thing */
1865 return LDB_ERR_INVALID_DN_SYNTAX
;
1868 for (i
=0; i
< dn
->ext_comp_num
; i
++) {
1869 if (ldb_attr_cmp(dn
->ext_components
[i
].name
, name
) == 0) {
1871 dn
->ext_components
[i
].value
=
1872 ldb_val_dup(dn
->ext_components
, val
);
1874 dn
->ext_components
[i
].name
=
1875 talloc_strdup(dn
->ext_components
, name
);
1876 if (!dn
->ext_components
[i
].name
||
1877 !dn
->ext_components
[i
].value
.data
) {
1878 ldb_dn_mark_invalid(dn
);
1879 return LDB_ERR_OPERATIONS_ERROR
;
1883 if (i
!= (dn
->ext_comp_num
- 1)) {
1884 memmove(&dn
->ext_components
[i
],
1885 &dn
->ext_components
[i
+1],
1886 ((dn
->ext_comp_num
-1) - i
) *
1887 sizeof(*dn
->ext_components
));
1891 dn
->ext_components
= talloc_realloc(dn
,
1893 struct ldb_dn_ext_component
,
1895 if (!dn
->ext_components
) {
1896 ldb_dn_mark_invalid(dn
);
1897 return LDB_ERR_OPERATIONS_ERROR
;
1904 p
= dn
->ext_components
1905 = talloc_realloc(dn
,
1907 struct ldb_dn_ext_component
,
1908 dn
->ext_comp_num
+ 1);
1909 if (!dn
->ext_components
) {
1910 ldb_dn_mark_invalid(dn
);
1911 return LDB_ERR_OPERATIONS_ERROR
;
1914 p
[dn
->ext_comp_num
].value
= ldb_val_dup(dn
->ext_components
, val
);
1915 p
[dn
->ext_comp_num
].name
= talloc_strdup(p
, name
);
1917 if (!dn
->ext_components
[i
].name
|| !dn
->ext_components
[i
].value
.data
) {
1918 ldb_dn_mark_invalid(dn
);
1919 return LDB_ERR_OPERATIONS_ERROR
;
1921 dn
->ext_components
= p
;
1927 void ldb_dn_remove_extended_components(struct ldb_dn
*dn
)
1929 dn
->ext_comp_num
= 0;
1930 LDB_FREE(dn
->ext_components
);
1933 bool ldb_dn_is_valid(struct ldb_dn
*dn
)
1935 if ( ! dn
) return false;
1936 return ! dn
->invalid
;
1939 bool ldb_dn_is_special(struct ldb_dn
*dn
)
1941 if ( ! dn
|| dn
->invalid
) return false;
1945 bool ldb_dn_has_extended(struct ldb_dn
*dn
)
1947 if ( ! dn
|| dn
->invalid
) return false;
1948 if (dn
->ext_linearized
&& (dn
->ext_linearized
[0] == '<')) return true;
1949 return dn
->ext_comp_num
!= 0;
1952 bool ldb_dn_check_special(struct ldb_dn
*dn
, const char *check
)
1954 if ( ! dn
|| dn
->invalid
) return false;
1955 return ! strcmp(dn
->linearized
, check
);
1958 bool ldb_dn_is_null(struct ldb_dn
*dn
)
1960 if ( ! dn
|| dn
->invalid
) return false;
1961 if (ldb_dn_has_extended(dn
)) return false;
1962 if (dn
->linearized
&& (dn
->linearized
[0] == '\0')) return true;