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_extended_component
{
63 struct ldb_context
*ldb
;
65 /* Special DNs are always linearized */
72 char *extended_linearized
;
75 unsigned int comp_num
;
76 struct ldb_dn_component
*components
;
78 unsigned int extended_comp_num
;
79 struct ldb_dn_extended_component
*extended_components
;
82 /* strdn may be NULL */
83 struct ldb_dn
*ldb_dn_from_ldb_val(void *mem_ctx
, struct ldb_context
*ldb
, const struct ldb_val
*strdn
)
87 if (! ldb
) return NULL
;
89 dn
= talloc_zero(mem_ctx
, struct ldb_dn
);
90 LDB_DN_NULL_FAILED(dn
);
94 if (strdn
->data
&& strdn
->length
) {
95 if (strdn
->data
[0] == '@') {
98 dn
->extended_linearized
= talloc_strndup(dn
, (const char *)strdn
->data
, strdn
->length
);
99 LDB_DN_NULL_FAILED(dn
->extended_linearized
);
101 if (strdn
->data
[0] == '<') {
102 const char *p_save
, *p
= dn
->extended_linearized
;
111 if (p_save
== dn
->extended_linearized
) {
112 dn
->linearized
= talloc_strdup(dn
, "");
114 dn
->linearized
= talloc_strdup(dn
, p_save
);
116 LDB_DN_NULL_FAILED(dn
->linearized
);
118 dn
->linearized
= dn
->extended_linearized
;
119 dn
->extended_linearized
= NULL
;
122 dn
->linearized
= talloc_strdup(dn
, "");
123 LDB_DN_NULL_FAILED(dn
->linearized
);
133 /* strdn may be NULL */
134 struct ldb_dn
*ldb_dn_new(void *mem_ctx
, struct ldb_context
*ldb
, const char *strdn
)
138 blob
.length
= strdn
? strlen(strdn
) : 0;
139 return ldb_dn_from_ldb_val(mem_ctx
, ldb
, &blob
);
142 struct ldb_dn
*ldb_dn_new_fmt(void *mem_ctx
, struct ldb_context
*ldb
, const char *new_fmt
, ...)
147 if ( (! mem_ctx
) || (! ldb
)) return NULL
;
149 va_start(ap
, new_fmt
);
150 strdn
= talloc_vasprintf(mem_ctx
, new_fmt
, ap
);
154 struct ldb_dn
*dn
= ldb_dn_new(mem_ctx
, ldb
, strdn
);
162 static int ldb_dn_escape_internal(char *dst
, const char *src
, int len
)
171 while (p
- src
< len
) {
173 p
+= strcspn(p
, ",=\n+<>#;\\\"");
175 if (p
- src
== len
) /* found no escapable chars */
178 memcpy(d
, s
, p
- s
); /* copy the part of the string before the stop */
179 d
+= (p
- s
); /* move to current position */
181 if (*p
) { /* it is a normal escapable character */
184 } else { /* we have a zero byte in the string */
185 strncpy(d
, "\00", 3); /* escape the zero */
187 p
++; /* skip the zero */
189 s
= p
; /* move forward */
192 /* copy the last part (with zero) and return */
196 /* return the length of the resulting string */
197 return (l
+ (d
- dst
));
200 char *ldb_dn_escape_value(void *mem_ctx
, struct ldb_val value
)
207 /* allocate destination string, it will be at most 3 times the source */
208 dst
= talloc_array(mem_ctx
, char, value
.length
* 3 + 1);
214 ldb_dn_escape_internal(dst
, (const char *)value
.data
, value
.length
);
216 dst
= talloc_realloc(mem_ctx
, dst
, char, strlen(dst
) + 1);
222 explode a DN string into a ldb_dn structure
223 based on RFC4514 except that we don't support multiple valued RDNs
225 static bool ldb_dn_explode(struct ldb_dn
*dn
)
227 char *p
, *ex_name
, *ex_value
, *data
, *d
, *dt
, *t
;
229 bool in_extended
= false;
230 bool in_ex_name
= false;
231 bool in_ex_value
= false;
232 bool in_attr
= false;
233 bool in_value
= false;
234 bool in_quote
= false;
241 if ( ! dn
|| dn
->invalid
) return false;
243 if (dn
->components
) {
247 if (dn
->extended_linearized
) {
248 parse_dn
= dn
->extended_linearized
;
250 parse_dn
= dn
->linearized
;
258 if (parse_dn
[0] == '\0') {
262 /* Special DNs case */
267 /* make sure we free this if alloced previously before replacing */
268 talloc_free(dn
->components
);
270 talloc_free(dn
->extended_components
);
271 dn
->extended_components
= NULL
;
273 /* in the common case we have 3 or more components */
274 /* make sure all components are zeroed, other functions depend on this */
275 dn
->components
= talloc_zero_array(dn
, struct ldb_dn_component
, 3);
276 if ( ! dn
->components
) {
281 /* Components data space is allocated here once */
282 data
= talloc_array(dn
->components
, char, strlen(parse_dn
) + 1);
298 if (!in_ex_name
&& !in_ex_value
) {
305 } else if (p
[0] == '\0') {
317 if (in_ex_name
&& *p
== '=') {
326 if (in_ex_value
&& *p
== '>') {
327 const struct ldb_dn_extended_syntax
*extended_syntax
;
328 struct ldb_val ex_val
= {
330 .length
= d
- ex_value
337 /* Process name and ex_value */
339 dn
->extended_components
= talloc_realloc(dn
,
340 dn
->extended_components
,
341 struct ldb_dn_extended_component
,
342 dn
->extended_comp_num
+ 1);
343 if ( ! dn
->extended_components
) {
348 extended_syntax
= ldb_dn_extended_syntax_by_name(dn
->ldb
, ex_name
);
349 if (!extended_syntax
) {
350 /* We don't know about this type of extended DN */
354 dn
->extended_components
[dn
->extended_comp_num
].name
= talloc_strdup(dn
->extended_components
, ex_name
);
355 if (!dn
->extended_components
[dn
->extended_comp_num
].name
) {
359 ret
= extended_syntax
->read_fn(dn
->ldb
, dn
->extended_components
,
360 &ex_val
, &dn
->extended_components
[dn
->extended_comp_num
].value
);
361 if (ret
!= LDB_SUCCESS
) {
366 dn
->extended_comp_num
++;
369 /* We have reached the end (extended component only)! */
373 } else if (*p
== ';') {
396 /* attr names must be ascii only */
404 if ( ! isalpha(*p
)) {
405 /* not a digit nor an alpha, invalid attribute name */
410 /* Copy this character across from parse_dn, now we have trimmed out spaces */
417 /* valid only if we are at the end */
422 if (trim
&& (*p
!= '=')) {
423 /* spaces/tabs are not allowed in attribute names */
429 /* attribute terminated */
435 /* Terminate this string in d (which is a copy of parse_dn with spaces trimmed) */
437 dn
->components
[dn
->comp_num
].name
= talloc_strdup(dn
->components
, dt
);
438 if ( ! dn
->components
[dn
->comp_num
].name
) {
450 /* attr names must be ascii only */
455 if (is_oid
&& ( ! (isdigit(*p
) || (*p
== '.')))) {
456 /* not a digit nor a dot, invalid attribute oid */
460 if ( ! (isalpha(*p
) || isdigit(*p
) || (*p
== '-'))) {
461 /* not ALPHA, DIGIT or HYPHEN */
502 /* TODO: support ber encoded values
513 /* ok found value terminator */
527 dn
->components
[dn
->comp_num
].value
.data
= (uint8_t *)talloc_strdup(dn
->components
, dt
);
528 dn
->components
[dn
->comp_num
].value
.length
= l
;
529 if ( ! dn
->components
[dn
->comp_num
].value
.data
) {
537 if (dn
->comp_num
> 2) {
538 dn
->components
= talloc_realloc(dn
,
540 struct ldb_dn_component
,
542 if ( ! dn
->components
) {
546 /* make sure all components are zeroed, other functions depend on this */
547 memset(&dn
->components
[dn
->comp_num
], '\0', sizeof(struct ldb_dn_component
));
560 /* a string with not escaped specials is invalid (tested) */
589 if (sscanf(p
, "%02x", &x
) != 1) {
590 /* invalid escaping sequence */
597 *d
++ = (unsigned char)x
;
619 if (in_attr
|| in_quote
) {
625 /* save last element */
633 dn
->components
[dn
->comp_num
].value
.data
= (uint8_t *)talloc_strdup(dn
->components
, dt
);
634 dn
->components
[dn
->comp_num
].value
.length
= l
;
636 if ( ! dn
->components
[dn
->comp_num
].value
.data
) {
648 talloc_free(dn
->components
);
652 bool ldb_dn_validate(struct ldb_dn
*dn
)
654 return ldb_dn_explode(dn
);
657 const char *ldb_dn_get_linearized(struct ldb_dn
*dn
)
662 if ( ! dn
|| ( dn
->invalid
)) return NULL
;
664 if (dn
->linearized
) return dn
->linearized
;
666 if ( ! dn
->components
) {
671 if (dn
->comp_num
== 0) {
672 dn
->linearized
= talloc_strdup(dn
, "");
673 if ( ! dn
->linearized
) return NULL
;
674 return dn
->linearized
;
677 /* calculate maximum possible length of DN */
678 for (len
= 0, i
= 0; i
< dn
->comp_num
; i
++) {
679 len
+= strlen(dn
->components
[i
].name
); /* name len */
680 len
+= (dn
->components
[i
].value
.length
* 3); /* max escaped data len */
681 len
+= 2; /* '=' and ',' */
683 dn
->linearized
= talloc_array(dn
, char, len
);
684 if ( ! dn
->linearized
) return NULL
;
688 for (i
= 0; i
< dn
->comp_num
; i
++) {
691 n
= dn
->components
[i
].name
;
692 while (*n
) *d
++ = *n
++;
697 d
+= ldb_dn_escape_internal( d
,
698 (char *)dn
->components
[i
].value
.data
,
699 dn
->components
[i
].value
.length
);
705 /* don't waste more memory than necessary */
706 dn
->linearized
= talloc_realloc(dn
, dn
->linearized
, char, (d
- dn
->linearized
+ 1));
708 return dn
->linearized
;
711 char *ldb_dn_get_extended_linearized(void *mem_ctx
, struct ldb_dn
*dn
, int mode
)
713 const char *linearized
= ldb_dn_get_linearized(dn
);
721 if (!ldb_dn_has_extended(dn
)) {
722 return talloc_strdup(mem_ctx
, linearized
);
725 if (!ldb_dn_validate(dn
)) {
729 for (i
=0; i
< dn
->extended_comp_num
; i
++) {
732 const struct ldb_dn_extended_syntax
*extended_syntax
;
733 const char *name
= dn
->extended_components
[i
].name
;
735 extended_syntax
= ldb_dn_extended_syntax_by_name(dn
->ldb
, name
);
738 ret
= extended_syntax
->write_clear_fn(dn
->ldb
, mem_ctx
,
739 &dn
->extended_components
[i
].value
,
741 } else if (mode
== 0) {
742 ret
= extended_syntax
->write_hex_fn(dn
->ldb
, mem_ctx
,
743 &dn
->extended_components
[i
].value
,
749 if (ret
!= LDB_SUCCESS
) {
754 p
= talloc_asprintf(mem_ctx
, "<%s=%s>", dn
->extended_components
[i
].name
, val
.data
);
756 p
= talloc_asprintf_append(p
, ";<%s=%s>", dn
->extended_components
[i
].name
, val
.data
);
759 talloc_free(val
.data
);
766 if (dn
->extended_comp_num
&& *linearized
) {
767 p
= talloc_asprintf_append(p
, ";%s", linearized
);
779 char *ldb_dn_alloc_linearized(void *mem_ctx
, struct ldb_dn
*dn
)
781 return talloc_strdup(mem_ctx
, ldb_dn_get_linearized(dn
));
785 casefold a dn. We need to casefold the attribute names, and canonicalize
786 attribute values of case insensitive attributes.
789 static bool ldb_dn_casefold_internal(struct ldb_dn
*dn
)
793 if ( ! dn
|| dn
->invalid
) return false;
795 if (dn
->valid_case
) return true;
797 if (( ! dn
->components
) && ( ! ldb_dn_explode(dn
))) {
801 for (i
= 0; i
< dn
->comp_num
; i
++) {
802 const struct ldb_schema_attribute
*a
;
804 dn
->components
[i
].cf_name
= ldb_attr_casefold(dn
->components
, dn
->components
[i
].name
);
805 if (!dn
->components
[i
].cf_name
) {
809 a
= ldb_schema_attribute_by_name(dn
->ldb
, dn
->components
[i
].cf_name
);
810 ret
= a
->syntax
->canonicalise_fn(dn
->ldb
, dn
->components
,
811 &(dn
->components
[i
].value
),
812 &(dn
->components
[i
].cf_value
));
818 dn
->valid_case
= true;
823 for (i
= 0; i
< dn
->comp_num
; i
++) {
824 LDB_FREE(dn
->components
[i
].cf_name
);
825 LDB_FREE(dn
->components
[i
].cf_value
.data
);
830 const char *ldb_dn_get_casefold(struct ldb_dn
*dn
)
835 if (dn
->casefold
) return dn
->casefold
;
838 dn
->casefold
= talloc_strdup(dn
, dn
->linearized
);
839 if (!dn
->casefold
) return NULL
;
840 dn
->valid_case
= true;
844 if ( ! ldb_dn_casefold_internal(dn
)) {
848 if (dn
->comp_num
== 0) {
849 if (dn
->linearized
&& dn
->linearized
[0] == '\0') {
850 /* hmm a NULL dn, should we faild casefolding ? */
851 dn
->casefold
= talloc_strdup(dn
, "");
854 /* A DN must be NULL, special, or have components */
859 /* calculate maximum possible length of DN */
860 for (len
= 0, i
= 0; i
< dn
->comp_num
; i
++) {
861 len
+= strlen(dn
->components
[i
].cf_name
); /* name len */
862 len
+= (dn
->components
[i
].cf_value
.length
* 3); /* max escaped data len */
863 len
+= 2; /* '=' and ',' */
865 dn
->casefold
= talloc_array(dn
, char, len
);
866 if ( ! dn
->casefold
) return NULL
;
870 for (i
= 0; i
< dn
->comp_num
; i
++) {
873 n
= dn
->components
[i
].cf_name
;
874 while (*n
) *d
++ = *n
++;
879 d
+= ldb_dn_escape_internal( d
,
880 (char *)dn
->components
[i
].cf_value
.data
,
881 dn
->components
[i
].cf_value
.length
);
886 /* don't waste more memory than necessary */
887 dn
->casefold
= talloc_realloc(dn
, dn
->casefold
, char, strlen(dn
->casefold
) + 1);
892 char *ldb_dn_alloc_casefold(void *mem_ctx
, struct ldb_dn
*dn
)
894 return talloc_strdup(mem_ctx
, ldb_dn_get_casefold(dn
));
897 /* Determine if dn is below base, in the ldap tree. Used for
898 * evaluating a subtree search.
899 * 0 if they match, otherwise non-zero
902 int ldb_dn_compare_base(struct ldb_dn
*base
, struct ldb_dn
*dn
)
907 if ( ! base
|| base
->invalid
) return 1;
908 if ( ! dn
|| dn
->invalid
) return -1;
910 if (( ! base
->valid_case
) || ( ! dn
->valid_case
)) {
911 if (base
->linearized
&& dn
->linearized
) {
912 /* try with a normal compare first, if we are lucky
913 * we will avoid exploding and casfolding */
915 dif
= strlen(dn
->linearized
) - strlen(base
->linearized
);
916 if (dif
< 0) return dif
;
917 if (strcmp(base
->linearized
, &dn
->linearized
[dif
]) == 0) return 0;
920 if ( ! ldb_dn_casefold_internal(base
)) {
924 if ( ! ldb_dn_casefold_internal(dn
)) {
930 /* if base has more components,
931 * they don't have the same base */
932 if (base
->comp_num
> dn
->comp_num
) {
933 return (dn
->comp_num
- base
->comp_num
);
936 if (dn
->comp_num
== 0) {
937 if (dn
->special
&& base
->special
) {
938 return strcmp(base
->linearized
, dn
->linearized
);
939 } else if (dn
->special
) {
941 } else if (base
->special
) {
948 n_base
= base
->comp_num
- 1;
949 n_dn
= dn
->comp_num
- 1;
951 while (n_base
>= 0) {
952 /* compare attr names */
953 ret
= strcmp(base
->components
[n_base
].cf_name
, dn
->components
[n_dn
].cf_name
);
954 if (ret
!= 0) return ret
;
956 /* compare attr.cf_value. */
957 if (base
->components
[n_base
].cf_value
.length
!= dn
->components
[n_dn
].cf_value
.length
) {
958 return base
->components
[n_base
].cf_value
.length
- dn
->components
[n_dn
].cf_value
.length
;
960 ret
= strcmp((char *)base
->components
[n_base
].cf_value
.data
, (char *)dn
->components
[n_dn
].cf_value
.data
);
961 if (ret
!= 0) return ret
;
970 /* compare DNs using casefolding compare functions.
972 If they match, then return 0
975 int ldb_dn_compare(struct ldb_dn
*dn0
, struct ldb_dn
*dn1
)
979 if (( ! dn0
) || dn0
->invalid
|| ! dn1
|| dn1
->invalid
) return -1;
981 if (( ! dn0
->valid_case
) || ( ! dn1
->valid_case
)) {
982 if (dn0
->linearized
&& dn1
->linearized
) {
983 /* try with a normal compare first, if we are lucky
984 * we will avoid exploding and casfolding */
985 if (strcmp(dn0
->linearized
, dn1
->linearized
) == 0) return 0;
988 if ( ! ldb_dn_casefold_internal(dn0
)) {
992 if ( ! ldb_dn_casefold_internal(dn1
)) {
998 if (dn0
->comp_num
!= dn1
->comp_num
) {
999 return (dn1
->comp_num
- dn0
->comp_num
);
1002 if (dn0
->comp_num
== 0) {
1003 if (dn0
->special
&& dn1
->special
) {
1004 return strcmp(dn0
->linearized
, dn1
->linearized
);
1005 } else if (dn0
->special
) {
1007 } else if (dn1
->special
) {
1014 for (i
= 0; i
< dn0
->comp_num
; i
++) {
1015 /* compare attr names */
1016 ret
= strcmp(dn0
->components
[i
].cf_name
, dn1
->components
[i
].cf_name
);
1017 if (ret
!= 0) return ret
;
1019 /* compare attr.cf_value. */
1020 if (dn0
->components
[i
].cf_value
.length
!= dn1
->components
[i
].cf_value
.length
) {
1021 return dn0
->components
[i
].cf_value
.length
- dn1
->components
[i
].cf_value
.length
;
1023 ret
= strcmp((char *)dn0
->components
[i
].cf_value
.data
, (char *)dn1
->components
[i
].cf_value
.data
);
1024 if (ret
!= 0) return ret
;
1030 static struct ldb_dn_component
ldb_dn_copy_component(void *mem_ctx
, struct ldb_dn_component
*src
)
1032 struct ldb_dn_component dst
;
1034 memset(&dst
, 0, sizeof(dst
));
1040 dst
.value
= ldb_val_dup(mem_ctx
, &(src
->value
));
1041 if (dst
.value
.data
== NULL
) {
1045 dst
.name
= talloc_strdup(mem_ctx
, src
->name
);
1046 if (dst
.name
== NULL
) {
1047 LDB_FREE(dst
.value
.data
);
1051 if (src
->cf_value
.data
) {
1052 dst
.cf_value
= ldb_val_dup(mem_ctx
, &(src
->cf_value
));
1053 if (dst
.cf_value
.data
== NULL
) {
1054 LDB_FREE(dst
.value
.data
);
1059 dst
.cf_name
= talloc_strdup(mem_ctx
, src
->cf_name
);
1060 if (dst
.cf_name
== NULL
) {
1061 LDB_FREE(dst
.cf_name
);
1062 LDB_FREE(dst
.value
.data
);
1067 dst
.cf_value
.data
= NULL
;
1074 static struct ldb_dn_extended_component
ldb_dn_extended_copy_component(void *mem_ctx
, struct ldb_dn_extended_component
*src
)
1076 struct ldb_dn_extended_component dst
;
1078 memset(&dst
, 0, sizeof(dst
));
1084 dst
.value
= ldb_val_dup(mem_ctx
, &(src
->value
));
1085 if (dst
.value
.data
== NULL
) {
1089 dst
.name
= talloc_strdup(mem_ctx
, src
->name
);
1090 if (dst
.name
== NULL
) {
1091 LDB_FREE(dst
.value
.data
);
1098 struct ldb_dn
*ldb_dn_copy(void *mem_ctx
, struct ldb_dn
*dn
)
1100 struct ldb_dn
*new_dn
;
1102 if (!dn
|| dn
->invalid
) {
1106 new_dn
= talloc_zero(mem_ctx
, struct ldb_dn
);
1113 if (dn
->components
) {
1116 new_dn
->components
= talloc_zero_array(new_dn
, struct ldb_dn_component
, dn
->comp_num
);
1117 if ( ! new_dn
->components
) {
1118 talloc_free(new_dn
);
1122 for (i
= 0; i
< dn
->comp_num
; i
++) {
1123 new_dn
->components
[i
] = ldb_dn_copy_component(new_dn
->components
, &dn
->components
[i
]);
1124 if ( ! new_dn
->components
[i
].value
.data
) {
1125 talloc_free(new_dn
);
1131 if (dn
->extended_components
) {
1134 new_dn
->extended_components
= talloc_zero_array(new_dn
, struct ldb_dn_extended_component
, dn
->extended_comp_num
);
1135 if ( ! new_dn
->extended_components
) {
1136 talloc_free(new_dn
);
1140 for (i
= 0; i
< dn
->extended_comp_num
; i
++) {
1141 new_dn
->extended_components
[i
] = ldb_dn_extended_copy_component(new_dn
->extended_components
, &dn
->extended_components
[i
]);
1142 if ( ! new_dn
->extended_components
[i
].value
.data
) {
1143 talloc_free(new_dn
);
1150 new_dn
->casefold
= talloc_strdup(new_dn
, dn
->casefold
);
1151 if ( ! new_dn
->casefold
) {
1152 talloc_free(new_dn
);
1157 if (dn
->linearized
) {
1158 new_dn
->linearized
= talloc_strdup(new_dn
, dn
->linearized
);
1159 if ( ! new_dn
->linearized
) {
1160 talloc_free(new_dn
);
1165 if (dn
->extended_linearized
) {
1166 new_dn
->extended_linearized
= talloc_strdup(new_dn
, dn
->extended_linearized
);
1167 if ( ! new_dn
->extended_linearized
) {
1168 talloc_free(new_dn
);
1176 /* modify the given dn by adding a base.
1178 * return true if successful and false if not
1179 * if false is returned the dn may be marked invalid
1181 bool ldb_dn_add_base(struct ldb_dn
*dn
, struct ldb_dn
*base
)
1186 if ( !base
|| base
->invalid
|| !dn
|| dn
->invalid
) {
1190 if (dn
->components
) {
1193 if ( ! ldb_dn_validate(base
)) {
1198 if (dn
->valid_case
) {
1199 if ( ! (s
= ldb_dn_get_casefold(base
))) {
1204 dn
->components
= talloc_realloc(dn
,
1206 struct ldb_dn_component
,
1207 dn
->comp_num
+ base
->comp_num
);
1208 if ( ! dn
->components
) {
1213 for (i
= 0; i
< base
->comp_num
; dn
->comp_num
++, i
++) {
1214 dn
->components
[dn
->comp_num
] = ldb_dn_copy_component(dn
->components
, &base
->components
[i
]);
1215 if (dn
->components
[dn
->comp_num
].value
.data
== NULL
) {
1221 if (dn
->casefold
&& s
) {
1222 if (*dn
->casefold
) {
1223 t
= talloc_asprintf(dn
, "%s,%s", dn
->casefold
, s
);
1225 t
= talloc_strdup(dn
, s
);
1227 LDB_FREE(dn
->casefold
);
1232 if (dn
->linearized
) {
1234 s
= ldb_dn_get_linearized(base
);
1239 if (*dn
->linearized
) {
1240 t
= talloc_asprintf(dn
, "%s,%s", dn
->linearized
, s
);
1242 t
= talloc_strdup(dn
, s
);
1248 LDB_FREE(dn
->linearized
);
1252 /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
1253 if (dn
->extended_linearized
) {
1254 LDB_FREE(dn
->extended_linearized
);
1257 LDB_FREE(dn
->extended_components
);
1258 dn
->extended_comp_num
= 0;
1262 /* modify the given dn by adding a base.
1264 * return true if successful and false if not
1265 * if false is returned the dn may be marked invalid
1267 bool ldb_dn_add_base_fmt(struct ldb_dn
*dn
, const char *base_fmt
, ...)
1269 struct ldb_dn
*base
;
1274 if ( !dn
|| dn
->invalid
) {
1278 va_start(ap
, base_fmt
);
1279 base_str
= talloc_vasprintf(dn
, base_fmt
, ap
);
1282 if (base_str
== NULL
) {
1286 base
= ldb_dn_new(base_str
, dn
->ldb
, base_str
);
1288 ret
= ldb_dn_add_base(dn
, base
);
1290 talloc_free(base_str
);
1295 /* modify the given dn by adding children elements.
1297 * return true if successful and false if not
1298 * if false is returned the dn may be marked invalid
1300 bool ldb_dn_add_child(struct ldb_dn
*dn
, struct ldb_dn
*child
)
1305 if ( !child
|| child
->invalid
|| !dn
|| dn
->invalid
) {
1309 if (dn
->components
) {
1312 if ( ! ldb_dn_validate(child
)) {
1317 if (dn
->valid_case
) {
1318 if ( ! (s
= ldb_dn_get_casefold(child
))) {
1323 n
= dn
->comp_num
+ child
->comp_num
;
1325 dn
->components
= talloc_realloc(dn
,
1327 struct ldb_dn_component
,
1329 if ( ! dn
->components
) {
1334 for (i
= dn
->comp_num
- 1, j
= n
- 1; i
>= 0; i
--, j
--) {
1335 dn
->components
[j
] = dn
->components
[i
];
1338 for (i
= 0; i
< child
->comp_num
; i
++) {
1339 dn
->components
[i
] = ldb_dn_copy_component(dn
->components
, &child
->components
[i
]);
1340 if (dn
->components
[i
].value
.data
== NULL
) {
1348 if (dn
->casefold
&& s
) {
1349 t
= talloc_asprintf(dn
, "%s,%s", s
, dn
->casefold
);
1350 LDB_FREE(dn
->casefold
);
1355 if (dn
->linearized
) {
1357 s
= ldb_dn_get_linearized(child
);
1362 t
= talloc_asprintf(dn
, "%s,%s", s
, dn
->linearized
);
1367 LDB_FREE(dn
->linearized
);
1371 /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
1372 LDB_FREE(dn
->extended_linearized
);
1374 LDB_FREE(dn
->extended_components
);
1375 dn
->extended_comp_num
= 0;
1380 /* modify the given dn by adding children elements.
1382 * return true if successful and false if not
1383 * if false is returned the dn may be marked invalid
1385 bool ldb_dn_add_child_fmt(struct ldb_dn
*dn
, const char *child_fmt
, ...)
1387 struct ldb_dn
*child
;
1392 if ( !dn
|| dn
->invalid
) {
1396 va_start(ap
, child_fmt
);
1397 child_str
= talloc_vasprintf(dn
, child_fmt
, ap
);
1400 if (child_str
== NULL
) {
1404 child
= ldb_dn_new(child_str
, dn
->ldb
, child_str
);
1406 ret
= ldb_dn_add_child(dn
, child
);
1408 talloc_free(child_str
);
1413 bool ldb_dn_remove_base_components(struct ldb_dn
*dn
, unsigned int num
)
1417 if ( ! ldb_dn_validate(dn
)) {
1421 if (dn
->comp_num
< num
) {
1425 /* free components */
1426 for (i
= num
; i
> 0; i
--) {
1427 LDB_FREE(dn
->components
[dn
->comp_num
- i
].name
);
1428 LDB_FREE(dn
->components
[dn
->comp_num
- i
].value
.data
);
1429 LDB_FREE(dn
->components
[dn
->comp_num
- i
].cf_name
);
1430 LDB_FREE(dn
->components
[dn
->comp_num
- i
].cf_value
.data
);
1433 dn
->comp_num
-= num
;
1435 if (dn
->valid_case
) {
1436 for (i
= 0; i
< dn
->comp_num
; i
++) {
1437 LDB_FREE(dn
->components
[i
].cf_name
);
1438 LDB_FREE(dn
->components
[i
].cf_value
.data
);
1440 dn
->valid_case
= false;
1443 LDB_FREE(dn
->casefold
);
1444 LDB_FREE(dn
->linearized
);
1446 /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
1447 LDB_FREE(dn
->extended_linearized
);
1449 LDB_FREE(dn
->extended_components
);
1450 dn
->extended_comp_num
= 0;
1455 bool ldb_dn_remove_child_components(struct ldb_dn
*dn
, unsigned int num
)
1459 if ( ! ldb_dn_validate(dn
)) {
1463 if (dn
->comp_num
< num
) {
1467 for (i
= 0, j
= num
; j
< dn
->comp_num
; i
++, j
++) {
1469 LDB_FREE(dn
->components
[i
].name
);
1470 LDB_FREE(dn
->components
[i
].value
.data
);
1471 LDB_FREE(dn
->components
[i
].cf_name
);
1472 LDB_FREE(dn
->components
[i
].cf_value
.data
);
1474 dn
->components
[i
] = dn
->components
[j
];
1477 dn
->comp_num
-= num
;
1479 if (dn
->valid_case
) {
1480 for (i
= 0; i
< dn
->comp_num
; i
++) {
1481 LDB_FREE(dn
->components
[i
].cf_name
);
1482 LDB_FREE(dn
->components
[i
].cf_value
.data
);
1484 dn
->valid_case
= false;
1487 LDB_FREE(dn
->casefold
);
1488 LDB_FREE(dn
->linearized
);
1490 /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
1491 LDB_FREE(dn
->extended_linearized
);
1493 LDB_FREE(dn
->extended_components
);
1494 dn
->extended_comp_num
= 0;
1498 struct ldb_dn
*ldb_dn_get_parent(void *mem_ctx
, struct ldb_dn
*dn
)
1500 struct ldb_dn
*new_dn
;
1502 new_dn
= ldb_dn_copy(mem_ctx
, dn
);
1507 if ( ! ldb_dn_remove_child_components(new_dn
, 1)) {
1508 talloc_free(new_dn
);
1512 /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
1513 LDB_FREE(dn
->extended_linearized
);
1515 LDB_FREE(dn
->extended_components
);
1516 dn
->extended_comp_num
= 0;
1520 /* Create a 'canonical name' string from a DN:
1522 ie dc=samba,dc=org -> samba.org/
1523 uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator
1525 There are two formats, the EX format has the last / replaced with a newline (\n).
1528 static char *ldb_dn_canonical(void *mem_ctx
, struct ldb_dn
*dn
, int ex_format
) {
1531 char *cracked
= NULL
;
1532 const char *format
= (ex_format
? "\n" : "/" );
1534 if ( ! ldb_dn_validate(dn
)) {
1538 tmpctx
= talloc_new(mem_ctx
);
1540 /* Walk backwards down the DN, grabbing 'dc' components at first */
1541 for (i
= dn
->comp_num
- 1 ; i
>= 0; i
--) {
1542 if (ldb_attr_cmp(dn
->components
[i
].name
, "dc") != 0) {
1546 cracked
= talloc_asprintf(tmpctx
, "%s.%s",
1547 ldb_dn_escape_value(tmpctx
, dn
->components
[i
].value
),
1550 cracked
= ldb_dn_escape_value(tmpctx
, dn
->components
[i
].value
);
1557 /* Only domain components? Finish here */
1559 cracked
= talloc_strdup_append_buffer(cracked
, format
);
1560 talloc_steal(mem_ctx
, cracked
);
1564 /* Now walk backwards appending remaining components */
1565 for (; i
> 0; i
--) {
1566 cracked
= talloc_asprintf_append_buffer(cracked
, "/%s",
1567 ldb_dn_escape_value(tmpctx
, dn
->components
[i
].value
));
1573 /* Last one, possibly a newline for the 'ex' format */
1574 cracked
= talloc_asprintf_append_buffer(cracked
, "%s%s", format
,
1575 ldb_dn_escape_value(tmpctx
, dn
->components
[i
].value
));
1577 talloc_steal(mem_ctx
, cracked
);
1579 talloc_free(tmpctx
);
1583 /* Wrapper functions for the above, for the two different string formats */
1584 char *ldb_dn_canonical_string(void *mem_ctx
, struct ldb_dn
*dn
) {
1585 return ldb_dn_canonical(mem_ctx
, dn
, 0);
1589 char *ldb_dn_canonical_ex_string(void *mem_ctx
, struct ldb_dn
*dn
) {
1590 return ldb_dn_canonical(mem_ctx
, dn
, 1);
1593 int ldb_dn_get_comp_num(struct ldb_dn
*dn
)
1595 if ( ! ldb_dn_validate(dn
)) {
1598 return dn
->comp_num
;
1601 const char *ldb_dn_get_component_name(struct ldb_dn
*dn
, unsigned int num
)
1603 if ( ! ldb_dn_validate(dn
)) {
1606 if (num
>= dn
->comp_num
) return NULL
;
1607 return dn
->components
[num
].name
;
1610 const struct ldb_val
*ldb_dn_get_component_val(struct ldb_dn
*dn
, unsigned int num
)
1612 if ( ! ldb_dn_validate(dn
)) {
1615 if (num
>= dn
->comp_num
) return NULL
;
1616 return &dn
->components
[num
].value
;
1619 const char *ldb_dn_get_rdn_name(struct ldb_dn
*dn
)
1621 if ( ! ldb_dn_validate(dn
)) {
1624 if (dn
->comp_num
== 0) return NULL
;
1625 return dn
->components
[0].name
;
1628 const struct ldb_val
*ldb_dn_get_rdn_val(struct ldb_dn
*dn
)
1630 if ( ! ldb_dn_validate(dn
)) {
1633 if (dn
->comp_num
== 0) return NULL
;
1634 return &dn
->components
[0].value
;
1637 int ldb_dn_set_component(struct ldb_dn
*dn
, int num
, const char *name
, const struct ldb_val val
)
1642 if ( ! ldb_dn_validate(dn
)) {
1643 return LDB_ERR_OTHER
;
1646 if (num
>= dn
->comp_num
) {
1647 return LDB_ERR_OTHER
;
1650 n
= talloc_strdup(dn
, name
);
1652 return LDB_ERR_OTHER
;
1655 v
.length
= val
.length
;
1656 v
.data
= (uint8_t *)talloc_memdup(dn
, val
.data
, v
.length
+1);
1659 return LDB_ERR_OTHER
;
1662 talloc_free(dn
->components
[num
].name
);
1663 talloc_free(dn
->components
[num
].value
.data
);
1664 dn
->components
[num
].name
= n
;
1665 dn
->components
[num
].value
= v
;
1667 if (dn
->valid_case
) {
1669 for (i
= 0; i
< dn
->comp_num
; i
++) {
1670 LDB_FREE(dn
->components
[i
].cf_name
);
1671 LDB_FREE(dn
->components
[i
].cf_value
.data
);
1673 dn
->valid_case
= false;
1675 LDB_FREE(dn
->casefold
);
1676 LDB_FREE(dn
->linearized
);
1678 /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
1679 LDB_FREE(dn
->extended_linearized
);
1681 dn
->extended_comp_num
= 0;
1682 LDB_FREE(dn
->extended_components
);
1686 const struct ldb_val
*ldb_dn_get_extended_component(struct ldb_dn
*dn
, const char *name
)
1689 if ( ! ldb_dn_validate(dn
)) {
1692 for (i
=0; i
< dn
->extended_comp_num
; i
++) {
1693 if (ldb_attr_cmp(dn
->extended_components
[i
].name
, name
) == 0) {
1694 return &dn
->extended_components
[i
].value
;
1700 int ldb_dn_set_extended_component(struct ldb_dn
*dn
, const char *name
, const struct ldb_val
*val
)
1702 struct ldb_dn_extended_component
*p
;
1705 if ( ! ldb_dn_validate(dn
)) {
1706 return LDB_ERR_OTHER
;
1709 for (i
=0; i
< dn
->extended_comp_num
; i
++) {
1710 if (ldb_attr_cmp(dn
->extended_components
[i
].name
, name
) == 0) {
1712 dn
->extended_components
[i
].value
= ldb_val_dup(dn
->extended_components
, val
);
1714 dn
->extended_components
[i
].name
= talloc_strdup(dn
->extended_components
, name
);
1715 if (!dn
->extended_components
[i
].name
|| !dn
->extended_components
[i
].value
.data
) {
1717 return LDB_ERR_OPERATIONS_ERROR
;
1721 if (i
!= (dn
->extended_comp_num
- 1)) {
1722 memmove(&dn
->extended_components
[i
], &dn
->extended_components
[i
+1],
1723 ((dn
->extended_comp_num
-1) - i
)*sizeof(*dn
->extended_components
));
1725 dn
->extended_comp_num
--;
1727 dn
->extended_components
= talloc_realloc(dn
,
1728 dn
->extended_components
,
1729 struct ldb_dn_extended_component
,
1730 dn
->extended_comp_num
);
1731 if (!dn
->extended_components
) {
1733 return LDB_ERR_OPERATIONS_ERROR
;
1740 p
= dn
->extended_components
1741 = talloc_realloc(dn
,
1742 dn
->extended_components
,
1743 struct ldb_dn_extended_component
,
1744 dn
->extended_comp_num
+ 1);
1745 if (!dn
->extended_components
) {
1747 return LDB_ERR_OPERATIONS_ERROR
;
1750 p
[dn
->extended_comp_num
].value
= ldb_val_dup(dn
->extended_components
, val
);
1751 p
[dn
->extended_comp_num
].name
= talloc_strdup(p
, name
);
1753 if (!dn
->extended_components
[i
].name
|| !dn
->extended_components
[i
].value
.data
) {
1755 return LDB_ERR_OPERATIONS_ERROR
;
1757 dn
->extended_components
= p
;
1758 dn
->extended_comp_num
++;
1763 void ldb_dn_remove_extended_components(struct ldb_dn
*dn
)
1765 dn
->extended_comp_num
= 0;
1766 LDB_FREE(dn
->extended_components
);
1769 bool ldb_dn_is_valid(struct ldb_dn
*dn
)
1771 if ( ! dn
) return false;
1772 return ! dn
->invalid
;
1775 bool ldb_dn_is_special(struct ldb_dn
*dn
)
1777 if ( ! dn
|| dn
->invalid
) return false;
1781 bool ldb_dn_has_extended(struct ldb_dn
*dn
)
1783 if ( ! dn
|| dn
->invalid
) return false;
1784 if (dn
->extended_linearized
&& (dn
->extended_linearized
[0] == '<')) return true;
1785 return dn
->extended_comp_num
!= 0;
1788 bool ldb_dn_check_special(struct ldb_dn
*dn
, const char *check
)
1790 if ( ! dn
|| dn
->invalid
) return false;
1791 return ! strcmp(dn
->linearized
, check
);
1794 bool ldb_dn_is_null(struct ldb_dn
*dn
)
1796 if ( ! dn
|| dn
->invalid
) return false;
1797 if (ldb_dn_has_extended(dn
)) return false;
1798 if (dn
->linearized
&& (dn
->linearized
[0] == '\0')) return true;