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
);
106 dn
->ldb
= talloc_get_type(ldb
, struct ldb_context
);
107 if (dn
->ldb
== NULL
) {
108 /* the caller probably got the arguments to
109 ldb_dn_new() mixed up */
114 if (strdn
->data
&& strdn
->length
) {
115 const char *data
= (const char *)strdn
->data
;
116 size_t length
= strdn
->length
;
118 if (data
[0] == '@') {
121 dn
->ext_linearized
= talloc_strndup(dn
, data
, length
);
122 LDB_DN_NULL_FAILED(dn
->ext_linearized
);
124 if (data
[0] == '<') {
125 const char *p_save
, *p
= dn
->ext_linearized
;
134 if (p_save
== dn
->ext_linearized
) {
135 dn
->linearized
= talloc_strdup(dn
, "");
137 dn
->linearized
= talloc_strdup(dn
, p_save
);
139 LDB_DN_NULL_FAILED(dn
->linearized
);
141 dn
->linearized
= dn
->ext_linearized
;
142 dn
->ext_linearized
= NULL
;
145 dn
->linearized
= talloc_strdup(dn
, "");
146 LDB_DN_NULL_FAILED(dn
->linearized
);
156 /* strdn may be NULL */
157 struct ldb_dn
*ldb_dn_new(void *mem_ctx
,
158 struct ldb_context
*ldb
,
162 blob
.data
= discard_const_p(uint8_t, strdn
);
163 blob
.length
= strdn
? strlen(strdn
) : 0;
164 return ldb_dn_from_ldb_val(mem_ctx
, ldb
, &blob
);
167 struct ldb_dn
*ldb_dn_new_fmt(void *mem_ctx
,
168 struct ldb_context
*ldb
,
169 const char *new_fmt
, ...)
174 if ( (! mem_ctx
) || (! ldb
)) return NULL
;
176 va_start(ap
, new_fmt
);
177 strdn
= talloc_vasprintf(mem_ctx
, new_fmt
, ap
);
181 struct ldb_dn
*dn
= ldb_dn_new(mem_ctx
, ldb
, strdn
);
189 /* see RFC2253 section 2.4 */
190 static int ldb_dn_escape_internal(char *dst
, const char *src
, int len
)
199 while (p
- src
< len
) {
200 p
+= strcspn(p
, ",=\n\r+<>#;\\\" ");
202 if (p
- src
== len
) /* found no escapable chars */
205 /* copy the part of the string before the stop */
207 d
+= (p
- s
); /* move to current position */
211 if (p
== src
|| (p
-src
)==(len
-1)) {
212 /* if at the beginning or end
213 * of the string then escape */
217 /* otherwise don't escape */
223 /* despite the RFC, windows escapes a #
224 anywhere in the string */
232 /* these must be escaped using \c form */
238 /* any others get \XX form */
240 const char *hexbytes
= "0123456789ABCDEF";
241 v
= *(const unsigned char *)p
;
243 *d
++ = hexbytes
[v
>>4];
244 *d
++ = hexbytes
[v
&0xF];
249 s
= p
; /* move forward */
252 /* copy the last part (with zero) and return */
256 /* return the length of the resulting string */
257 return (l
+ (d
- dst
));
260 char *ldb_dn_escape_value(void *mem_ctx
, struct ldb_val value
)
267 /* allocate destination string, it will be at most 3 times the source */
268 dst
= talloc_array(mem_ctx
, char, value
.length
* 3 + 1);
274 ldb_dn_escape_internal(dst
, (const char *)value
.data
, value
.length
);
276 dst
= talloc_realloc(mem_ctx
, dst
, char, strlen(dst
) + 1);
282 explode a DN string into a ldb_dn structure
283 based on RFC4514 except that we don't support multiple valued RDNs
285 TODO: according to MS-ADTS:3.1.1.5.2 Naming Constraints
286 DN must be compliant with RFC2253
288 static bool ldb_dn_explode(struct ldb_dn
*dn
)
290 char *p
, *ex_name
, *ex_value
, *data
, *d
, *dt
, *t
;
292 bool in_extended
= false;
293 bool in_ex_name
= false;
294 bool in_ex_value
= false;
295 bool in_attr
= false;
296 bool in_value
= false;
297 bool in_quote
= false;
305 if ( ! dn
|| dn
->invalid
) return false;
307 if (dn
->components
) {
311 if (dn
->ext_linearized
) {
312 parse_dn
= dn
->ext_linearized
;
314 parse_dn
= dn
->linearized
;
321 is_index
= (strncmp(parse_dn
, "DN=@INDEX:", 10) == 0);
324 if (parse_dn
[0] == '\0') {
328 /* Special DNs case */
333 /* make sure we free this if alloced previously before replacing */
334 talloc_free(dn
->components
);
336 LDB_FREE(dn
->ext_components
);
337 dn
->ext_comp_num
= 0;
339 /* in the common case we have 3 or more components */
340 /* make sure all components are zeroed, other functions depend on it */
341 dn
->components
= talloc_zero_array(dn
, struct ldb_dn_component
, 3);
342 if ( ! dn
->components
) {
347 /* Components data space is allocated here once */
348 data
= talloc_array(dn
->components
, char, strlen(parse_dn
) + 1);
364 if (!in_ex_name
&& !in_ex_value
) {
371 } else if (p
[0] == '\0') {
383 if (in_ex_name
&& *p
== '=') {
392 if (in_ex_value
&& *p
== '>') {
393 const struct ldb_dn_extended_syntax
*ext_syntax
;
394 struct ldb_val ex_val
= {
395 .data
= (uint8_t *)ex_value
,
396 .length
= d
- ex_value
403 /* Process name and ex_value */
405 dn
->ext_components
= talloc_realloc(dn
,
407 struct ldb_dn_ext_component
,
408 dn
->ext_comp_num
+ 1);
409 if ( ! dn
->ext_components
) {
414 ext_syntax
= ldb_dn_extended_syntax_by_name(dn
->ldb
, ex_name
);
416 /* We don't know about this type of extended DN */
420 dn
->ext_components
[dn
->ext_comp_num
].name
= talloc_strdup(dn
->ext_components
, ex_name
);
421 if (!dn
->ext_components
[dn
->ext_comp_num
].name
) {
425 ret
= ext_syntax
->read_fn(dn
->ldb
, dn
->ext_components
,
426 &ex_val
, &dn
->ext_components
[dn
->ext_comp_num
].value
);
427 if (ret
!= LDB_SUCCESS
) {
428 ldb_dn_mark_invalid(dn
);
435 /* We have reached the end (extended component only)! */
439 } else if (*p
== ';') {
443 ldb_dn_mark_invalid(dn
);
462 /* attr names must be ascii only */
463 ldb_dn_mark_invalid(dn
);
470 if ( ! isalpha(*p
)) {
471 /* not a digit nor an alpha,
472 * invalid attribute name */
473 ldb_dn_mark_invalid(dn
);
477 /* Copy this character across from parse_dn,
478 * now we have trimmed out spaces */
485 /* valid only if we are at the end */
490 if (trim
&& (*p
!= '=')) {
491 /* spaces/tabs are not allowed */
492 ldb_dn_mark_invalid(dn
);
497 /* attribute terminated */
503 /* Terminate this string in d
504 * (which is a copy of parse_dn
505 * with spaces trimmed) */
507 dn
->components
[dn
->comp_num
].name
= talloc_strdup(dn
->components
, dt
);
508 if ( ! dn
->components
[dn
->comp_num
].name
) {
520 /* attr names must be ascii only */
521 ldb_dn_mark_invalid(dn
);
525 if (is_oid
&& ( ! (isdigit(*p
) || (*p
== '.')))) {
526 /* not a digit nor a dot,
527 * invalid attribute oid */
528 ldb_dn_mark_invalid(dn
);
531 if ( ! (isalpha(*p
) || isdigit(*p
) || (*p
== '-'))) {
532 /* not ALPHA, DIGIT or HYPHEN */
533 ldb_dn_mark_invalid(dn
);
573 /* TODO: support ber encoded values
584 /* ok found value terminator */
598 dn
->components
[dn
->comp_num
].value
.data
= (uint8_t *)talloc_strdup(dn
->components
, dt
);
599 dn
->components
[dn
->comp_num
].value
.length
= l
;
600 if ( ! dn
->components
[dn
->comp_num
].value
.data
) {
608 if (dn
->comp_num
> 2) {
609 dn
->components
= talloc_realloc(dn
,
611 struct ldb_dn_component
,
613 if ( ! dn
->components
) {
617 /* make sure all components are zeroed, other functions depend on this */
618 memset(&dn
->components
[dn
->comp_num
], '\0', sizeof(struct ldb_dn_component
));
625 /* to main compatibility with earlier
626 versions of ldb indexing, we have to
627 accept the base64 encoded binary index
628 values, which contain a '+' or '='
629 which should normally be escaped */
641 /* a string with not escaped specials is invalid (tested) */
643 ldb_dn_mark_invalid(dn
);
670 if (isxdigit(p
[0]) && isxdigit(p
[1])) {
671 if (sscanf(p
, "%02x", &x
) != 1) {
672 /* invalid escaping sequence */
673 ldb_dn_mark_invalid(dn
);
677 *d
++ = (unsigned char)x
;
703 if (in_attr
|| in_quote
) {
705 ldb_dn_mark_invalid(dn
);
709 /* save last element */
717 dn
->components
[dn
->comp_num
].value
.length
= l
;
718 dn
->components
[dn
->comp_num
].value
.data
=
719 (uint8_t *)talloc_strdup(dn
->components
, dt
);
720 if ( ! dn
->components
[dn
->comp_num
].value
.data
) {
732 talloc_free(dn
->components
);
736 bool ldb_dn_validate(struct ldb_dn
*dn
)
738 return ldb_dn_explode(dn
);
741 const char *ldb_dn_get_linearized(struct ldb_dn
*dn
)
746 if ( ! dn
|| ( dn
->invalid
)) return NULL
;
748 if (dn
->linearized
) return dn
->linearized
;
750 if ( ! dn
->components
) {
751 ldb_dn_mark_invalid(dn
);
755 if (dn
->comp_num
== 0) {
756 dn
->linearized
= talloc_strdup(dn
, "");
757 if ( ! dn
->linearized
) return NULL
;
758 return dn
->linearized
;
761 /* calculate maximum possible length of DN */
762 for (len
= 0, i
= 0; i
< dn
->comp_num
; i
++) {
764 len
+= strlen(dn
->components
[i
].name
);
765 /* max escaped data len */
766 len
+= (dn
->components
[i
].value
.length
* 3);
767 len
+= 2; /* '=' and ',' */
769 dn
->linearized
= talloc_array(dn
, char, len
);
770 if ( ! dn
->linearized
) return NULL
;
774 for (i
= 0; i
< dn
->comp_num
; i
++) {
777 n
= dn
->components
[i
].name
;
778 while (*n
) *d
++ = *n
++;
783 d
+= ldb_dn_escape_internal( d
,
784 (char *)dn
->components
[i
].value
.data
,
785 dn
->components
[i
].value
.length
);
791 /* don't waste more memory than necessary */
792 dn
->linearized
= talloc_realloc(dn
, dn
->linearized
,
793 char, (d
- dn
->linearized
+ 1));
795 return dn
->linearized
;
798 static int ldb_dn_extended_component_compare(const void *p1
, const void *p2
)
800 const struct ldb_dn_ext_component
*ec1
= (const struct ldb_dn_ext_component
*)p1
;
801 const struct ldb_dn_ext_component
*ec2
= (const struct ldb_dn_ext_component
*)p2
;
802 return strcmp(ec1
->name
, ec2
->name
);
805 char *ldb_dn_get_extended_linearized(void *mem_ctx
, struct ldb_dn
*dn
, int mode
)
807 const char *linearized
= ldb_dn_get_linearized(dn
);
815 if (!ldb_dn_has_extended(dn
)) {
816 return talloc_strdup(mem_ctx
, linearized
);
819 if (!ldb_dn_validate(dn
)) {
823 /* sort the extended components by name. The idea is to make
824 * the resulting DNs consistent, plus to ensure that we put
825 * 'DELETED' first, so it can be very quickly recognised
827 TYPESAFE_QSORT(dn
->ext_components
, dn
->ext_comp_num
,
828 ldb_dn_extended_component_compare
);
830 for (i
= 0; i
< dn
->ext_comp_num
; i
++) {
831 const struct ldb_dn_extended_syntax
*ext_syntax
;
832 const char *name
= dn
->ext_components
[i
].name
;
833 struct ldb_val ec_val
= dn
->ext_components
[i
].value
;
837 ext_syntax
= ldb_dn_extended_syntax_by_name(dn
->ldb
, name
);
843 ret
= ext_syntax
->write_clear_fn(dn
->ldb
, mem_ctx
,
845 } else if (mode
== 0) {
846 ret
= ext_syntax
->write_hex_fn(dn
->ldb
, mem_ctx
,
852 if (ret
!= LDB_SUCCESS
) {
857 p
= talloc_asprintf(mem_ctx
, "<%s=%s>",
860 p
= talloc_asprintf_append_buffer(p
, ";<%s=%s>",
864 talloc_free(val
.data
);
871 if (dn
->ext_comp_num
&& *linearized
) {
872 p
= talloc_asprintf_append_buffer(p
, ";%s", linearized
);
883 filter out all but an acceptable list of extended DN components
885 void ldb_dn_extended_filter(struct ldb_dn
*dn
, const char * const *accept
)
888 for (i
=0; i
<dn
->ext_comp_num
; i
++) {
889 if (!ldb_attr_in_list(accept
, dn
->ext_components
[i
].name
)) {
890 memmove(&dn
->ext_components
[i
],
891 &dn
->ext_components
[i
+1],
892 (dn
->ext_comp_num
-(i
+1))*sizeof(dn
->ext_components
[0]));
897 LDB_FREE(dn
->ext_linearized
);
901 char *ldb_dn_alloc_linearized(void *mem_ctx
, struct ldb_dn
*dn
)
903 return talloc_strdup(mem_ctx
, ldb_dn_get_linearized(dn
));
907 casefold a dn. We need to casefold the attribute names, and canonicalize
908 attribute values of case insensitive attributes.
911 static bool ldb_dn_casefold_internal(struct ldb_dn
*dn
)
915 if ( ! dn
|| dn
->invalid
) return false;
917 if (dn
->valid_case
) return true;
919 if (( ! dn
->components
) && ( ! ldb_dn_explode(dn
))) {
923 for (i
= 0; i
< dn
->comp_num
; i
++) {
924 const struct ldb_schema_attribute
*a
;
926 dn
->components
[i
].cf_name
=
927 ldb_attr_casefold(dn
->components
,
928 dn
->components
[i
].name
);
929 if (!dn
->components
[i
].cf_name
) {
933 a
= ldb_schema_attribute_by_name(dn
->ldb
,
934 dn
->components
[i
].cf_name
);
936 ret
= a
->syntax
->canonicalise_fn(dn
->ldb
, dn
->components
,
937 &(dn
->components
[i
].value
),
938 &(dn
->components
[i
].cf_value
));
944 dn
->valid_case
= true;
949 for (i
= 0; i
< dn
->comp_num
; i
++) {
950 LDB_FREE(dn
->components
[i
].cf_name
);
951 LDB_FREE(dn
->components
[i
].cf_value
.data
);
956 const char *ldb_dn_get_casefold(struct ldb_dn
*dn
)
961 if (dn
->casefold
) return dn
->casefold
;
964 dn
->casefold
= talloc_strdup(dn
, dn
->linearized
);
965 if (!dn
->casefold
) return NULL
;
966 dn
->valid_case
= true;
970 if ( ! ldb_dn_casefold_internal(dn
)) {
974 if (dn
->comp_num
== 0) {
975 dn
->casefold
= talloc_strdup(dn
, "");
979 /* calculate maximum possible length of DN */
980 for (len
= 0, i
= 0; i
< dn
->comp_num
; i
++) {
982 len
+= strlen(dn
->components
[i
].cf_name
);
983 /* max escaped data len */
984 len
+= (dn
->components
[i
].cf_value
.length
* 3);
985 len
+= 2; /* '=' and ',' */
987 dn
->casefold
= talloc_array(dn
, char, len
);
988 if ( ! dn
->casefold
) return NULL
;
992 for (i
= 0; i
< dn
->comp_num
; i
++) {
995 n
= dn
->components
[i
].cf_name
;
996 while (*n
) *d
++ = *n
++;
1001 d
+= ldb_dn_escape_internal( d
,
1002 (char *)dn
->components
[i
].cf_value
.data
,
1003 dn
->components
[i
].cf_value
.length
);
1008 /* don't waste more memory than necessary */
1009 dn
->casefold
= talloc_realloc(dn
, dn
->casefold
,
1010 char, strlen(dn
->casefold
) + 1);
1012 return dn
->casefold
;
1015 char *ldb_dn_alloc_casefold(void *mem_ctx
, struct ldb_dn
*dn
)
1017 return talloc_strdup(mem_ctx
, ldb_dn_get_casefold(dn
));
1020 /* Determine if dn is below base, in the ldap tree. Used for
1021 * evaluating a subtree search.
1022 * 0 if they match, otherwise non-zero
1025 int ldb_dn_compare_base(struct ldb_dn
*base
, struct ldb_dn
*dn
)
1030 if ( ! base
|| base
->invalid
) return 1;
1031 if ( ! dn
|| dn
->invalid
) return -1;
1033 if (( ! base
->valid_case
) || ( ! dn
->valid_case
)) {
1034 if (base
->linearized
&& dn
->linearized
) {
1035 /* try with a normal compare first, if we are lucky
1036 * we will avoid exploding and casfolding */
1038 dif
= strlen(dn
->linearized
) - strlen(base
->linearized
);
1042 if (strcmp(base
->linearized
,
1043 &dn
->linearized
[dif
]) == 0) {
1048 if ( ! ldb_dn_casefold_internal(base
)) {
1052 if ( ! ldb_dn_casefold_internal(dn
)) {
1058 /* if base has more components,
1059 * they don't have the same base */
1060 if (base
->comp_num
> dn
->comp_num
) {
1061 return (dn
->comp_num
- base
->comp_num
);
1064 if (dn
->comp_num
== 0) {
1065 if (dn
->special
&& base
->special
) {
1066 return strcmp(base
->linearized
, dn
->linearized
);
1067 } else if (dn
->special
) {
1069 } else if (base
->special
) {
1076 n_base
= base
->comp_num
- 1;
1077 n_dn
= dn
->comp_num
- 1;
1079 while (n_base
>= 0) {
1080 char *b_name
= base
->components
[n_base
].cf_name
;
1081 char *dn_name
= dn
->components
[n_dn
].cf_name
;
1083 char *b_vdata
= (char *)base
->components
[n_base
].cf_value
.data
;
1084 char *dn_vdata
= (char *)dn
->components
[n_dn
].cf_value
.data
;
1086 size_t b_vlen
= base
->components
[n_base
].cf_value
.length
;
1087 size_t dn_vlen
= dn
->components
[n_dn
].cf_value
.length
;
1089 /* compare attr names */
1090 ret
= strcmp(b_name
, dn_name
);
1091 if (ret
!= 0) return ret
;
1093 /* compare attr.cf_value. */
1094 if (b_vlen
!= dn_vlen
) {
1095 return b_vlen
- dn_vlen
;
1097 ret
= strcmp(b_vdata
, dn_vdata
);
1098 if (ret
!= 0) return ret
;
1107 /* compare DNs using casefolding compare functions.
1109 If they match, then return 0
1112 int ldb_dn_compare(struct ldb_dn
*dn0
, struct ldb_dn
*dn1
)
1116 if (( ! dn0
) || dn0
->invalid
|| ! dn1
|| dn1
->invalid
) {
1120 if (( ! dn0
->valid_case
) || ( ! dn1
->valid_case
)) {
1121 if (dn0
->linearized
&& dn1
->linearized
) {
1122 /* try with a normal compare first, if we are lucky
1123 * we will avoid exploding and casfolding */
1124 if (strcmp(dn0
->linearized
, dn1
->linearized
) == 0) {
1129 if ( ! ldb_dn_casefold_internal(dn0
)) {
1133 if ( ! ldb_dn_casefold_internal(dn1
)) {
1139 if (dn0
->comp_num
!= dn1
->comp_num
) {
1140 return (dn1
->comp_num
- dn0
->comp_num
);
1143 if (dn0
->comp_num
== 0) {
1144 if (dn0
->special
&& dn1
->special
) {
1145 return strcmp(dn0
->linearized
, dn1
->linearized
);
1146 } else if (dn0
->special
) {
1148 } else if (dn1
->special
) {
1155 for (i
= 0; i
< dn0
->comp_num
; i
++) {
1156 char *dn0_name
= dn0
->components
[i
].cf_name
;
1157 char *dn1_name
= dn1
->components
[i
].cf_name
;
1159 char *dn0_vdata
= (char *)dn0
->components
[i
].cf_value
.data
;
1160 char *dn1_vdata
= (char *)dn1
->components
[i
].cf_value
.data
;
1162 size_t dn0_vlen
= dn0
->components
[i
].cf_value
.length
;
1163 size_t dn1_vlen
= dn1
->components
[i
].cf_value
.length
;
1165 /* compare attr names */
1166 ret
= strcmp(dn0_name
, dn1_name
);
1171 /* compare attr.cf_value. */
1172 if (dn0_vlen
!= dn1_vlen
) {
1173 return dn0_vlen
- dn1_vlen
;
1175 ret
= strcmp(dn0_vdata
, dn1_vdata
);
1184 static struct ldb_dn_component
ldb_dn_copy_component(
1186 struct ldb_dn_component
*src
)
1188 struct ldb_dn_component dst
;
1190 memset(&dst
, 0, sizeof(dst
));
1196 dst
.value
= ldb_val_dup(mem_ctx
, &(src
->value
));
1197 if (dst
.value
.data
== NULL
) {
1201 dst
.name
= talloc_strdup(mem_ctx
, src
->name
);
1202 if (dst
.name
== NULL
) {
1203 LDB_FREE(dst
.value
.data
);
1207 if (src
->cf_value
.data
) {
1208 dst
.cf_value
= ldb_val_dup(mem_ctx
, &(src
->cf_value
));
1209 if (dst
.cf_value
.data
== NULL
) {
1210 LDB_FREE(dst
.value
.data
);
1215 dst
.cf_name
= talloc_strdup(mem_ctx
, src
->cf_name
);
1216 if (dst
.cf_name
== NULL
) {
1217 LDB_FREE(dst
.cf_name
);
1218 LDB_FREE(dst
.value
.data
);
1223 dst
.cf_value
.data
= NULL
;
1230 static struct ldb_dn_ext_component
ldb_dn_ext_copy_component(
1232 struct ldb_dn_ext_component
*src
)
1234 struct ldb_dn_ext_component dst
;
1236 memset(&dst
, 0, sizeof(dst
));
1242 dst
.value
= ldb_val_dup(mem_ctx
, &(src
->value
));
1243 if (dst
.value
.data
== NULL
) {
1247 dst
.name
= talloc_strdup(mem_ctx
, src
->name
);
1248 if (dst
.name
== NULL
) {
1249 LDB_FREE(dst
.value
.data
);
1256 struct ldb_dn
*ldb_dn_copy(void *mem_ctx
, struct ldb_dn
*dn
)
1258 struct ldb_dn
*new_dn
;
1260 if (!dn
|| dn
->invalid
) {
1264 new_dn
= talloc_zero(mem_ctx
, struct ldb_dn
);
1271 if (dn
->components
) {
1274 new_dn
->components
=
1275 talloc_zero_array(new_dn
,
1276 struct ldb_dn_component
,
1278 if ( ! new_dn
->components
) {
1279 talloc_free(new_dn
);
1283 for (i
= 0; i
< dn
->comp_num
; i
++) {
1284 new_dn
->components
[i
] =
1285 ldb_dn_copy_component(new_dn
->components
,
1286 &dn
->components
[i
]);
1287 if ( ! new_dn
->components
[i
].value
.data
) {
1288 talloc_free(new_dn
);
1294 if (dn
->ext_components
) {
1297 new_dn
->ext_components
=
1298 talloc_zero_array(new_dn
,
1299 struct ldb_dn_ext_component
,
1301 if ( ! new_dn
->ext_components
) {
1302 talloc_free(new_dn
);
1306 for (i
= 0; i
< dn
->ext_comp_num
; i
++) {
1307 new_dn
->ext_components
[i
] =
1308 ldb_dn_ext_copy_component(
1309 new_dn
->ext_components
,
1310 &dn
->ext_components
[i
]);
1311 if ( ! new_dn
->ext_components
[i
].value
.data
) {
1312 talloc_free(new_dn
);
1319 new_dn
->casefold
= talloc_strdup(new_dn
, dn
->casefold
);
1320 if ( ! new_dn
->casefold
) {
1321 talloc_free(new_dn
);
1326 if (dn
->linearized
) {
1327 new_dn
->linearized
= talloc_strdup(new_dn
, dn
->linearized
);
1328 if ( ! new_dn
->linearized
) {
1329 talloc_free(new_dn
);
1334 if (dn
->ext_linearized
) {
1335 new_dn
->ext_linearized
= talloc_strdup(new_dn
,
1336 dn
->ext_linearized
);
1337 if ( ! new_dn
->ext_linearized
) {
1338 talloc_free(new_dn
);
1346 /* modify the given dn by adding a base.
1348 * return true if successful and false if not
1349 * if false is returned the dn may be marked invalid
1351 bool ldb_dn_add_base(struct ldb_dn
*dn
, struct ldb_dn
*base
)
1356 if ( !base
|| base
->invalid
|| !dn
|| dn
->invalid
) {
1360 if (dn
->components
) {
1363 if ( ! ldb_dn_validate(base
)) {
1368 if (dn
->valid_case
) {
1369 if ( ! (s
= ldb_dn_get_casefold(base
))) {
1374 dn
->components
= talloc_realloc(dn
,
1376 struct ldb_dn_component
,
1377 dn
->comp_num
+ base
->comp_num
);
1378 if ( ! dn
->components
) {
1379 ldb_dn_mark_invalid(dn
);
1383 for (i
= 0; i
< base
->comp_num
; dn
->comp_num
++, i
++) {
1384 dn
->components
[dn
->comp_num
] =
1385 ldb_dn_copy_component(dn
->components
,
1386 &base
->components
[i
]);
1387 if (dn
->components
[dn
->comp_num
].value
.data
== NULL
) {
1388 ldb_dn_mark_invalid(dn
);
1393 if (dn
->casefold
&& s
) {
1394 if (*dn
->casefold
) {
1395 t
= talloc_asprintf(dn
, "%s,%s",
1398 t
= talloc_strdup(dn
, s
);
1400 LDB_FREE(dn
->casefold
);
1405 if (dn
->linearized
) {
1407 s
= ldb_dn_get_linearized(base
);
1412 if (*dn
->linearized
) {
1413 t
= talloc_asprintf(dn
, "%s,%s",
1416 t
= talloc_strdup(dn
, s
);
1419 ldb_dn_mark_invalid(dn
);
1422 LDB_FREE(dn
->linearized
);
1426 /* Wipe the ext_linearized DN,
1427 * the GUID and SID are almost certainly no longer valid */
1428 LDB_FREE(dn
->ext_linearized
);
1430 LDB_FREE(dn
->ext_components
);
1431 dn
->ext_comp_num
= 0;
1435 /* modify the given dn by adding a base.
1437 * return true if successful and false if not
1438 * if false is returned the dn may be marked invalid
1440 bool ldb_dn_add_base_fmt(struct ldb_dn
*dn
, const char *base_fmt
, ...)
1442 struct ldb_dn
*base
;
1447 if ( !dn
|| dn
->invalid
) {
1451 va_start(ap
, base_fmt
);
1452 base_str
= talloc_vasprintf(dn
, base_fmt
, ap
);
1455 if (base_str
== NULL
) {
1459 base
= ldb_dn_new(base_str
, dn
->ldb
, base_str
);
1461 ret
= ldb_dn_add_base(dn
, base
);
1463 talloc_free(base_str
);
1468 /* modify the given dn by adding children elements.
1470 * return true if successful and false if not
1471 * if false is returned the dn may be marked invalid
1473 bool ldb_dn_add_child(struct ldb_dn
*dn
, struct ldb_dn
*child
)
1478 if ( !child
|| child
->invalid
|| !dn
|| dn
->invalid
) {
1482 if (dn
->components
) {
1485 if ( ! ldb_dn_validate(child
)) {
1490 if (dn
->valid_case
) {
1491 if ( ! (s
= ldb_dn_get_casefold(child
))) {
1496 n
= dn
->comp_num
+ child
->comp_num
;
1498 dn
->components
= talloc_realloc(dn
,
1500 struct ldb_dn_component
,
1502 if ( ! dn
->components
) {
1503 ldb_dn_mark_invalid(dn
);
1507 for (i
= dn
->comp_num
- 1, j
= n
- 1; i
>= 0; i
--, j
--) {
1508 dn
->components
[j
] = dn
->components
[i
];
1511 for (i
= 0; i
< child
->comp_num
; i
++) {
1513 ldb_dn_copy_component(dn
->components
,
1514 &child
->components
[i
]);
1515 if (dn
->components
[i
].value
.data
== NULL
) {
1516 ldb_dn_mark_invalid(dn
);
1523 if (dn
->casefold
&& s
) {
1524 t
= talloc_asprintf(dn
, "%s,%s", s
, dn
->casefold
);
1525 LDB_FREE(dn
->casefold
);
1530 if (dn
->linearized
) {
1532 s
= ldb_dn_get_linearized(child
);
1537 t
= talloc_asprintf(dn
, "%s,%s", s
, dn
->linearized
);
1539 ldb_dn_mark_invalid(dn
);
1542 LDB_FREE(dn
->linearized
);
1546 /* Wipe the ext_linearized DN,
1547 * the GUID and SID are almost certainly no longer valid */
1548 LDB_FREE(dn
->ext_linearized
);
1550 LDB_FREE(dn
->ext_components
);
1551 dn
->ext_comp_num
= 0;
1556 /* modify the given dn by adding children elements.
1558 * return true if successful and false if not
1559 * if false is returned the dn may be marked invalid
1561 bool ldb_dn_add_child_fmt(struct ldb_dn
*dn
, const char *child_fmt
, ...)
1563 struct ldb_dn
*child
;
1568 if ( !dn
|| dn
->invalid
) {
1572 va_start(ap
, child_fmt
);
1573 child_str
= talloc_vasprintf(dn
, child_fmt
, ap
);
1576 if (child_str
== NULL
) {
1580 child
= ldb_dn_new(child_str
, dn
->ldb
, child_str
);
1582 ret
= ldb_dn_add_child(dn
, child
);
1584 talloc_free(child_str
);
1589 bool ldb_dn_remove_base_components(struct ldb_dn
*dn
, unsigned int num
)
1593 if ( ! ldb_dn_validate(dn
)) {
1597 if (dn
->comp_num
< num
) {
1601 /* free components */
1602 for (i
= num
; i
> 0; i
--) {
1603 LDB_FREE(dn
->components
[dn
->comp_num
- i
].name
);
1604 LDB_FREE(dn
->components
[dn
->comp_num
- i
].value
.data
);
1605 LDB_FREE(dn
->components
[dn
->comp_num
- i
].cf_name
);
1606 LDB_FREE(dn
->components
[dn
->comp_num
- i
].cf_value
.data
);
1609 dn
->comp_num
-= num
;
1611 if (dn
->valid_case
) {
1612 for (i
= 0; i
< dn
->comp_num
; i
++) {
1613 LDB_FREE(dn
->components
[i
].cf_name
);
1614 LDB_FREE(dn
->components
[i
].cf_value
.data
);
1616 dn
->valid_case
= false;
1619 LDB_FREE(dn
->casefold
);
1620 LDB_FREE(dn
->linearized
);
1622 /* Wipe the ext_linearized DN,
1623 * the GUID and SID are almost certainly no longer valid */
1624 LDB_FREE(dn
->ext_linearized
);
1626 LDB_FREE(dn
->ext_components
);
1627 dn
->ext_comp_num
= 0;
1632 bool ldb_dn_remove_child_components(struct ldb_dn
*dn
, unsigned int num
)
1636 if ( ! ldb_dn_validate(dn
)) {
1640 if (dn
->comp_num
< num
) {
1644 for (i
= 0, j
= num
; j
< dn
->comp_num
; i
++, j
++) {
1646 LDB_FREE(dn
->components
[i
].name
);
1647 LDB_FREE(dn
->components
[i
].value
.data
);
1648 LDB_FREE(dn
->components
[i
].cf_name
);
1649 LDB_FREE(dn
->components
[i
].cf_value
.data
);
1651 dn
->components
[i
] = dn
->components
[j
];
1654 dn
->comp_num
-= num
;
1656 if (dn
->valid_case
) {
1657 for (i
= 0; i
< dn
->comp_num
; i
++) {
1658 LDB_FREE(dn
->components
[i
].cf_name
);
1659 LDB_FREE(dn
->components
[i
].cf_value
.data
);
1661 dn
->valid_case
= false;
1664 LDB_FREE(dn
->casefold
);
1665 LDB_FREE(dn
->linearized
);
1667 /* Wipe the ext_linearized DN,
1668 * the GUID and SID are almost certainly no longer valid */
1669 LDB_FREE(dn
->ext_linearized
);
1671 LDB_FREE(dn
->ext_components
);
1672 dn
->ext_comp_num
= 0;
1676 struct ldb_dn
*ldb_dn_get_parent(void *mem_ctx
, struct ldb_dn
*dn
)
1678 struct ldb_dn
*new_dn
;
1680 new_dn
= ldb_dn_copy(mem_ctx
, dn
);
1685 if ( ! ldb_dn_remove_child_components(new_dn
, 1)) {
1686 talloc_free(new_dn
);
1690 /* Wipe the ext_linearized DN,
1691 * the GUID and SID are almost certainly no longer valid */
1692 LDB_FREE(dn
->ext_linearized
);
1694 LDB_FREE(dn
->ext_components
);
1695 dn
->ext_comp_num
= 0;
1699 /* Create a 'canonical name' string from a DN:
1701 ie dc=samba,dc=org -> samba.org/
1702 uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator
1704 There are two formats,
1705 the EX format has the last '/' replaced with a newline (\n).
1708 static char *ldb_dn_canonical(void *mem_ctx
, struct ldb_dn
*dn
, int ex_format
) {
1711 char *cracked
= NULL
;
1712 const char *format
= (ex_format
? "\n" : "/" );
1714 if ( ! ldb_dn_validate(dn
)) {
1718 tmpctx
= talloc_new(mem_ctx
);
1720 /* Walk backwards down the DN, grabbing 'dc' components at first */
1721 for (i
= dn
->comp_num
- 1 ; i
>= 0; i
--) {
1722 if (ldb_attr_cmp(dn
->components
[i
].name
, "dc") != 0) {
1726 cracked
= talloc_asprintf(tmpctx
, "%s.%s",
1727 ldb_dn_escape_value(tmpctx
,
1728 dn
->components
[i
].value
),
1731 cracked
= ldb_dn_escape_value(tmpctx
,
1732 dn
->components
[i
].value
);
1739 /* Only domain components? Finish here */
1741 cracked
= talloc_strdup_append_buffer(cracked
, format
);
1742 talloc_steal(mem_ctx
, cracked
);
1746 /* Now walk backwards appending remaining components */
1747 for (; i
> 0; i
--) {
1748 cracked
= talloc_asprintf_append_buffer(cracked
, "/%s",
1749 ldb_dn_escape_value(tmpctx
,
1750 dn
->components
[i
].value
));
1756 /* Last one, possibly a newline for the 'ex' format */
1757 cracked
= talloc_asprintf_append_buffer(cracked
, "%s%s", format
,
1758 ldb_dn_escape_value(tmpctx
,
1759 dn
->components
[i
].value
));
1761 talloc_steal(mem_ctx
, cracked
);
1763 talloc_free(tmpctx
);
1767 /* Wrapper functions for the above, for the two different string formats */
1768 char *ldb_dn_canonical_string(void *mem_ctx
, struct ldb_dn
*dn
) {
1769 return ldb_dn_canonical(mem_ctx
, dn
, 0);
1773 char *ldb_dn_canonical_ex_string(void *mem_ctx
, struct ldb_dn
*dn
) {
1774 return ldb_dn_canonical(mem_ctx
, dn
, 1);
1777 int ldb_dn_get_comp_num(struct ldb_dn
*dn
)
1779 if ( ! ldb_dn_validate(dn
)) {
1782 return dn
->comp_num
;
1785 const char *ldb_dn_get_component_name(struct ldb_dn
*dn
, unsigned int num
)
1787 if ( ! ldb_dn_validate(dn
)) {
1790 if (num
>= dn
->comp_num
) return NULL
;
1791 return dn
->components
[num
].name
;
1794 const struct ldb_val
*ldb_dn_get_component_val(struct ldb_dn
*dn
,
1797 if ( ! ldb_dn_validate(dn
)) {
1800 if (num
>= dn
->comp_num
) return NULL
;
1801 return &dn
->components
[num
].value
;
1804 const char *ldb_dn_get_rdn_name(struct ldb_dn
*dn
)
1806 if ( ! ldb_dn_validate(dn
)) {
1809 if (dn
->comp_num
== 0) return NULL
;
1810 return dn
->components
[0].name
;
1813 const struct ldb_val
*ldb_dn_get_rdn_val(struct ldb_dn
*dn
)
1815 if ( ! ldb_dn_validate(dn
)) {
1818 if (dn
->comp_num
== 0) return NULL
;
1819 return &dn
->components
[0].value
;
1822 int ldb_dn_set_component(struct ldb_dn
*dn
, int num
,
1823 const char *name
, const struct ldb_val val
)
1828 if ( ! ldb_dn_validate(dn
)) {
1829 return LDB_ERR_OTHER
;
1832 if (num
>= dn
->comp_num
) {
1833 return LDB_ERR_OTHER
;
1836 n
= talloc_strdup(dn
, name
);
1838 return LDB_ERR_OTHER
;
1841 v
.length
= val
.length
;
1842 v
.data
= (uint8_t *)talloc_memdup(dn
, val
.data
, v
.length
+1);
1845 return LDB_ERR_OTHER
;
1848 talloc_free(dn
->components
[num
].name
);
1849 talloc_free(dn
->components
[num
].value
.data
);
1850 dn
->components
[num
].name
= n
;
1851 dn
->components
[num
].value
= v
;
1853 if (dn
->valid_case
) {
1855 for (i
= 0; i
< dn
->comp_num
; i
++) {
1856 LDB_FREE(dn
->components
[i
].cf_name
);
1857 LDB_FREE(dn
->components
[i
].cf_value
.data
);
1859 dn
->valid_case
= false;
1861 LDB_FREE(dn
->casefold
);
1862 LDB_FREE(dn
->linearized
);
1864 /* Wipe the ext_linearized DN,
1865 * the GUID and SID are almost certainly no longer valid */
1866 LDB_FREE(dn
->ext_linearized
);
1868 dn
->ext_comp_num
= 0;
1869 LDB_FREE(dn
->ext_components
);
1873 const struct ldb_val
*ldb_dn_get_extended_component(struct ldb_dn
*dn
,
1877 if ( ! ldb_dn_validate(dn
)) {
1880 for (i
=0; i
< dn
->ext_comp_num
; i
++) {
1881 if (ldb_attr_cmp(dn
->ext_components
[i
].name
, name
) == 0) {
1882 return &dn
->ext_components
[i
].value
;
1888 int ldb_dn_set_extended_component(struct ldb_dn
*dn
,
1889 const char *name
, const struct ldb_val
*val
)
1891 struct ldb_dn_ext_component
*p
;
1895 if ( ! ldb_dn_validate(dn
)) {
1896 return LDB_ERR_OTHER
;
1899 if (!ldb_dn_extended_syntax_by_name(dn
->ldb
, name
)) {
1900 /* We don't know how to handle this type of thing */
1901 return LDB_ERR_INVALID_DN_SYNTAX
;
1904 for (i
=0; i
< dn
->ext_comp_num
; i
++) {
1905 if (ldb_attr_cmp(dn
->ext_components
[i
].name
, name
) == 0) {
1907 dn
->ext_components
[i
].value
=
1908 ldb_val_dup(dn
->ext_components
, val
);
1910 dn
->ext_components
[i
].name
=
1911 talloc_strdup(dn
->ext_components
, name
);
1912 if (!dn
->ext_components
[i
].name
||
1913 !dn
->ext_components
[i
].value
.data
) {
1914 ldb_dn_mark_invalid(dn
);
1915 return LDB_ERR_OPERATIONS_ERROR
;
1919 if (i
!= (dn
->ext_comp_num
- 1)) {
1920 memmove(&dn
->ext_components
[i
],
1921 &dn
->ext_components
[i
+1],
1922 ((dn
->ext_comp_num
-1) - i
) *
1923 sizeof(*dn
->ext_components
));
1927 dn
->ext_components
= talloc_realloc(dn
,
1929 struct ldb_dn_ext_component
,
1931 if (!dn
->ext_components
) {
1932 ldb_dn_mark_invalid(dn
);
1933 return LDB_ERR_OPERATIONS_ERROR
;
1937 LDB_FREE(dn
->ext_linearized
);
1942 /* removing a value that doesn't exist is not an error */
1948 p
= dn
->ext_components
1949 = talloc_realloc(dn
,
1951 struct ldb_dn_ext_component
,
1952 dn
->ext_comp_num
+ 1);
1953 if (!dn
->ext_components
) {
1954 ldb_dn_mark_invalid(dn
);
1955 return LDB_ERR_OPERATIONS_ERROR
;
1958 p
[dn
->ext_comp_num
].value
= ldb_val_dup(dn
->ext_components
, &v2
);
1959 p
[dn
->ext_comp_num
].name
= talloc_strdup(p
, name
);
1961 if (!dn
->ext_components
[i
].name
|| !dn
->ext_components
[i
].value
.data
) {
1962 ldb_dn_mark_invalid(dn
);
1963 return LDB_ERR_OPERATIONS_ERROR
;
1965 dn
->ext_components
= p
;
1971 void ldb_dn_remove_extended_components(struct ldb_dn
*dn
)
1973 dn
->ext_comp_num
= 0;
1974 LDB_FREE(dn
->ext_components
);
1975 LDB_FREE(dn
->ext_linearized
);
1978 bool ldb_dn_is_valid(struct ldb_dn
*dn
)
1980 if ( ! dn
) return false;
1981 return ! dn
->invalid
;
1984 bool ldb_dn_is_special(struct ldb_dn
*dn
)
1986 if ( ! dn
|| dn
->invalid
) return false;
1990 bool ldb_dn_has_extended(struct ldb_dn
*dn
)
1992 if ( ! dn
|| dn
->invalid
) return false;
1993 if (dn
->ext_linearized
&& (dn
->ext_linearized
[0] == '<')) return true;
1994 return dn
->ext_comp_num
!= 0;
1997 bool ldb_dn_check_special(struct ldb_dn
*dn
, const char *check
)
1999 if ( ! dn
|| dn
->invalid
) return false;
2000 return ! strcmp(dn
->linearized
, check
);
2003 bool ldb_dn_is_null(struct ldb_dn
*dn
)
2005 if ( ! dn
|| dn
->invalid
) return false;
2006 if (ldb_dn_has_extended(dn
)) return false;
2007 if (dn
->linearized
&& (dn
->linearized
[0] == '\0')) return true;
2012 this updates dn->components, taking the components from ref_dn.
2013 This is used by code that wants to update the DN path of a DN
2014 while not impacting on the extended DN components
2016 int ldb_dn_update_components(struct ldb_dn
*dn
, const struct ldb_dn
*ref_dn
)
2018 dn
->components
= talloc_realloc(dn
, dn
->components
,
2019 struct ldb_dn_component
, ref_dn
->comp_num
);
2020 if (!dn
->components
) {
2021 return LDB_ERR_OPERATIONS_ERROR
;
2023 memcpy(dn
->components
, ref_dn
->components
,
2024 sizeof(struct ldb_dn_component
)*ref_dn
->comp_num
);
2025 dn
->comp_num
= ref_dn
->comp_num
;
2027 talloc_free(dn
->linearized
);
2028 talloc_free(dn
->ext_linearized
);
2029 dn
->ext_linearized
= NULL
;
2030 dn
->linearized
= NULL
;