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 2 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, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 * Component: ldb dn creation and manipulation utility functions
30 * Description: - explode a dn into it's own basic elements
31 * and put them in a structure (only if necessary)
32 * - manipulate ldb_dn structures
39 #include "ldb/include/includes.h"
41 #define LDB_DN_NULL_FAILED(x) if (!(x)) goto failed
43 #define LDB_FREE(x) do { talloc_free(x); x = NULL; } while(0)
46 internal ldb exploded dn structures
48 struct ldb_dn_component
{
54 struct ldb_val cf_value
;
59 struct ldb_context
*ldb
;
61 /* Special DNs are always linearized */
70 unsigned int comp_num
;
71 struct ldb_dn_component
*components
;
75 /* strdn may be NULL */
76 struct ldb_dn
*ldb_dn_new(void *mem_ctx
, struct ldb_context
*ldb
, const char *strdn
)
80 if ( (! mem_ctx
) || (! ldb
)) return NULL
;
82 dn
= talloc_zero(mem_ctx
, struct ldb_dn
);
83 LDB_DN_NULL_FAILED(dn
);
88 if (strdn
[0] == '@') {
91 if (strncasecmp(strdn
, "<GUID=", 6) == 0) {
92 /* this is special DN returned when the
93 * exploded_dn control is used */
95 /* FIXME: add a GUID string to ldb_dn structure */
96 } else if (strncasecmp(strdn
, "<SID=", 8) == 0) {
97 /* this is special DN returned when the
98 * exploded_dn control is used */
100 /* FIXME: add a SID string to ldb_dn structure */
101 } else if (strncasecmp(strdn
, "<WKGUID=", 8) == 0) {
102 /* this is special DN returned when the
103 * exploded_dn control is used */
105 /* FIXME: add a WKGUID string to ldb_dn structure */
107 dn
->linearized
= talloc_strdup(dn
, strdn
);
109 dn
->linearized
= talloc_strdup(dn
, "");
111 LDB_DN_NULL_FAILED(dn
->linearized
);
120 struct ldb_dn
*ldb_dn_new_fmt(void *mem_ctx
, struct ldb_context
*ldb
, const char *new_fmt
, ...)
126 if ( (! mem_ctx
) || (! ldb
)) return NULL
;
128 dn
= talloc_zero(mem_ctx
, struct ldb_dn
);
129 LDB_DN_NULL_FAILED(dn
);
133 va_start(ap
, new_fmt
);
134 strdn
= talloc_vasprintf(dn
, new_fmt
, ap
);
136 LDB_DN_NULL_FAILED(strdn
);
138 if (strdn
[0] == '@') {
141 if (strncasecmp(strdn
, "<GUID=", 6) == 0) {
142 /* this is special DN returned when the
143 * exploded_dn control is used */
145 /* FIXME: add a GUID string to ldb_dn structure */
146 } else if (strncasecmp(strdn
, "<SID=", 8) == 0) {
147 /* this is special DN returned when the
148 * exploded_dn control is used */
150 /* FIXME: add a SID string to ldb_dn structure */
151 } else if (strncasecmp(strdn
, "<WKGUID=", 8) == 0) {
152 /* this is special DN returned when the
153 * exploded_dn control is used */
155 /* FIXME: add a WKGUID string to ldb_dn structure */
157 dn
->linearized
= strdn
;
166 static int ldb_dn_escape_internal(char *dst
, const char *src
, int len
)
175 while (p
- src
< len
) {
177 p
+= strcspn(p
, ",=\n+<>#;\\\"");
179 if (p
- src
== len
) /* found no escapable chars */
182 memcpy(d
, s
, p
- s
); /* copy the part of the string before the stop */
183 d
+= (p
- s
); /* move to current position */
185 if (*p
) { /* it is a normal escapable character */
188 } else { /* we have a zero byte in the string */
189 strncpy(d
, "\00", 3); /* escape the zero */
191 p
++; /* skip the zero */
193 s
= p
; /* move forward */
196 /* copy the last part (with zero) and return */
200 /* return the length of the resulting string */
201 return (l
+ (d
- dst
));
204 char *ldb_dn_escape_value(void *mem_ctx
, struct ldb_val value
)
211 /* allocate destination string, it will be at most 3 times the source */
212 dst
= talloc_array(mem_ctx
, char, value
.length
* 3 + 1);
218 ldb_dn_escape_internal(dst
, (const char *)value
.data
, value
.length
);
220 dst
= talloc_realloc(mem_ctx
, dst
, char, strlen(dst
) + 1);
226 explode a DN string into a ldb_dn structure
227 based on RFC4514 except that we don't support multiple valued RDNs
229 static bool ldb_dn_explode(struct ldb_dn
*dn
)
231 char *p
, *data
, *d
, *dt
, *t
;
233 bool in_attr
= false;
234 bool in_value
= false;
235 bool in_quote
= false;
241 if ( ! dn
|| dn
->invalid
) return false;
243 if (dn
->components
) {
247 if ( ! dn
->linearized
) {
252 if (dn
->linearized
[0] == '\0') {
256 /* Special DNs case */
261 /* make sure we free this if alloced previously before replacing */
262 talloc_free(dn
->components
);
264 /* in the common case we have 3 or more components */
265 /* make sure all components are zeroed, other functions depend on this */
266 dn
->components
= talloc_zero_array(dn
, struct ldb_dn_component
, 3);
267 if ( ! dn
->components
) {
272 /* Components data space is allocated here once */
273 data
= talloc_array(dn
->components
, char, strlen(dn
->linearized
) + 1);
299 if ( ! isalpha(*p
)) {
300 /* not a digit nor an alpha, invalid attribute name */
311 /* valid only if we are at the end */
316 if (trim
&& (*p
!= '=')) {
317 /* spaces/tabs are not allowed in attribute names */
323 /* attribute terminated */
330 dn
->components
[dn
->comp_num
].name
= talloc_strdup(dn
->components
, dt
);
331 if ( ! dn
->components
[dn
->comp_num
].name
) {
342 if (is_oid
&& ( ! (isdigit(*p
) || (*p
== '.')))) {
343 /* not a digit nor a dot, invalid attribute oid */
347 if ( ! (isalpha(*p
) || isdigit(*p
) || (*p
== '-'))) {
348 /* not ALPHA, DIGIT or HYPHEN */
389 /* TODO: support ber encoded values
400 /* ok found value terminator */
414 dn
->components
[dn
->comp_num
].value
.data
= (uint8_t *)talloc_strdup(dn
->components
, dt
);
415 dn
->components
[dn
->comp_num
].value
.length
= l
;
416 if ( ! dn
->components
[dn
->comp_num
].value
.data
) {
424 if (dn
->comp_num
> 2) {
425 dn
->components
= talloc_realloc(dn
,
427 struct ldb_dn_component
,
429 if ( ! dn
->components
) {
433 /* make sure all components are zeroed, other functions depend on this */
434 memset(&dn
->components
[dn
->comp_num
], '\0', sizeof(struct ldb_dn_component
));
447 /* a string with not escaped specials is invalid (tested) */
476 if (sscanf(p
, "%02x", &x
) != 1) {
477 /* invalid escaping sequence */
484 *d
++ = (unsigned char)x
;
506 if (in_attr
|| in_quote
) {
512 /* save last element */
520 dn
->components
[dn
->comp_num
].value
.data
= (uint8_t *)talloc_strdup(dn
->components
, dt
);
521 dn
->components
[dn
->comp_num
].value
.length
= l
;
523 if ( ! dn
->components
[dn
->comp_num
].value
.data
) {
535 talloc_free(dn
->components
);
539 bool ldb_dn_validate(struct ldb_dn
*dn
)
541 return ldb_dn_explode(dn
);
544 const char *ldb_dn_get_linearized(struct ldb_dn
*dn
)
549 if ( ! dn
|| ( dn
->invalid
)) return NULL
;
551 if (dn
->linearized
) return dn
->linearized
;
553 if ( ! dn
->components
) {
558 if (dn
->comp_num
== 0) {
559 dn
->linearized
= talloc_strdup(dn
, "");
560 if ( ! dn
->linearized
) return NULL
;
561 return dn
->linearized
;
564 /* calculate maximum possible length of DN */
565 for (len
= 0, i
= 0; i
< dn
->comp_num
; i
++) {
566 len
+= strlen(dn
->components
[i
].name
); /* name len */
567 len
+= (dn
->components
[i
].value
.length
* 3); /* max escaped data len */
568 len
+= 2; /* '=' and ',' */
570 dn
->linearized
= talloc_array(dn
, char, len
);
571 if ( ! dn
->linearized
) return NULL
;
575 for (i
= 0; i
< dn
->comp_num
; i
++) {
578 n
= dn
->components
[i
].name
;
579 while (*n
) *d
++ = *n
++;
584 d
+= ldb_dn_escape_internal( d
,
585 (char *)dn
->components
[i
].value
.data
,
586 dn
->components
[i
].value
.length
);
592 /* don't waste more memory than necessary */
593 dn
->linearized
= talloc_realloc(dn
, dn
->linearized
, char, (d
- dn
->linearized
+ 1));
595 return dn
->linearized
;
598 char *ldb_dn_alloc_linearized(void *mem_ctx
, struct ldb_dn
*dn
)
600 return talloc_strdup(mem_ctx
, ldb_dn_get_linearized(dn
));
604 casefold a dn. We need to casefold the attribute names, and canonicalize
605 attribute values of case insensitive attributes.
608 static bool ldb_dn_casefold_internal(struct ldb_dn
*dn
)
612 if ( ! dn
|| dn
->invalid
) return false;
614 if (dn
->valid_case
) return true;
616 if (( ! dn
->components
) && ( ! ldb_dn_explode(dn
))) {
620 for (i
= 0; i
< dn
->comp_num
; i
++) {
621 const struct ldb_schema_attribute
*a
;
623 dn
->components
[i
].cf_name
= ldb_attr_casefold(dn
->components
, dn
->components
[i
].name
);
624 if (!dn
->components
[i
].cf_name
) {
628 a
= ldb_schema_attribute_by_name(dn
->ldb
, dn
->components
[i
].cf_name
);
629 ret
= a
->syntax
->canonicalise_fn(dn
->ldb
, dn
->components
,
630 &(dn
->components
[i
].value
),
631 &(dn
->components
[i
].cf_value
));
637 dn
->valid_case
= true;
642 for (i
= 0; i
< dn
->comp_num
; i
++) {
643 LDB_FREE(dn
->components
[i
].cf_name
);
644 LDB_FREE(dn
->components
[i
].cf_value
.data
);
649 const char *ldb_dn_get_casefold(struct ldb_dn
*dn
)
654 if (dn
->casefold
) return dn
->casefold
;
657 dn
->casefold
= talloc_strdup(dn
, dn
->linearized
);
658 if (!dn
->casefold
) return NULL
;
659 dn
->valid_case
= true;
663 if ( ! ldb_dn_casefold_internal(dn
)) {
667 if (dn
->comp_num
== 0) {
668 if (dn
->linearized
&& dn
->linearized
[0] == '\0') {
669 /* hmm a NULL dn, should we faild casefolding ? */
670 dn
->casefold
= talloc_strdup(dn
, "");
673 /* A DN must be NULL, special, or have components */
678 /* calculate maximum possible length of DN */
679 for (len
= 0, i
= 0; i
< dn
->comp_num
; i
++) {
680 len
+= strlen(dn
->components
[i
].cf_name
); /* name len */
681 len
+= (dn
->components
[i
].cf_value
.length
* 3); /* max escaped data len */
682 len
+= 2; /* '=' and ',' */
684 dn
->casefold
= talloc_array(dn
, char, len
);
685 if ( ! dn
->casefold
) return NULL
;
689 for (i
= 0; i
< dn
->comp_num
; i
++) {
692 n
= dn
->components
[i
].cf_name
;
693 while (*n
) *d
++ = *n
++;
698 d
+= ldb_dn_escape_internal( d
,
699 (char *)dn
->components
[i
].cf_value
.data
,
700 dn
->components
[i
].cf_value
.length
);
705 /* don't waste more memory than necessary */
706 dn
->casefold
= talloc_realloc(dn
, dn
->casefold
, char, strlen(dn
->casefold
) + 1);
711 char *ldb_dn_alloc_casefold(void *mem_ctx
, struct ldb_dn
*dn
)
713 return talloc_strdup(mem_ctx
, ldb_dn_get_casefold(dn
));
716 /* Determine if dn is below base, in the ldap tree. Used for
717 * evaluating a subtree search.
718 * 0 if they match, otherwise non-zero
721 int ldb_dn_compare_base(struct ldb_dn
*base
, struct ldb_dn
*dn
)
726 if ( ! base
|| base
->invalid
) return 1;
727 if ( ! dn
|| dn
->invalid
) return -1;
729 if (( ! base
->valid_case
) || ( ! dn
->valid_case
)) {
730 if (base
->linearized
&& dn
->linearized
) {
731 /* try with a normal compare first, if we are lucky
732 * we will avoid exploding and casfolding */
734 dif
= strlen(dn
->linearized
) - strlen(base
->linearized
);
735 if (dif
< 0) return dif
;
736 if (strcmp(base
->linearized
, &dn
->linearized
[dif
]) == 0) return 0;
739 if ( ! ldb_dn_casefold_internal(base
)) {
743 if ( ! ldb_dn_casefold_internal(dn
)) {
749 /* if base has more components,
750 * they don't have the same base */
751 if (base
->comp_num
> dn
->comp_num
) {
752 return (dn
->comp_num
- base
->comp_num
);
755 if (dn
->comp_num
== 0) {
756 if (dn
->special
&& base
->special
) {
757 return strcmp(base
->linearized
, dn
->linearized
);
758 } else if (dn
->special
) {
760 } else if (base
->special
) {
767 n_base
= base
->comp_num
- 1;
768 n_dn
= dn
->comp_num
- 1;
770 while (n_base
>= 0) {
771 /* compare attr names */
772 ret
= strcmp(base
->components
[n_base
].cf_name
, dn
->components
[n_dn
].cf_name
);
773 if (ret
!= 0) return ret
;
775 /* compare attr.cf_value. */
776 if (base
->components
[n_base
].cf_value
.length
!= dn
->components
[n_dn
].cf_value
.length
) {
777 return base
->components
[n_base
].cf_value
.length
- dn
->components
[n_dn
].cf_value
.length
;
779 ret
= strcmp((char *)base
->components
[n_base
].cf_value
.data
, (char *)dn
->components
[n_dn
].cf_value
.data
);
780 if (ret
!= 0) return ret
;
789 /* compare DNs using casefolding compare functions.
791 If they match, then return 0
794 int ldb_dn_compare(struct ldb_dn
*dn0
, struct ldb_dn
*dn1
)
798 if (( ! dn0
) || dn0
->invalid
|| ! dn1
|| dn1
->invalid
) return -1;
800 if (( ! dn0
->valid_case
) || ( ! dn1
->valid_case
)) {
801 if (dn0
->linearized
&& dn1
->linearized
) {
802 /* try with a normal compare first, if we are lucky
803 * we will avoid exploding and casfolding */
804 if (strcmp(dn0
->linearized
, dn1
->linearized
) == 0) return 0;
807 if ( ! ldb_dn_casefold_internal(dn0
)) {
811 if ( ! ldb_dn_casefold_internal(dn1
)) {
817 if (dn0
->comp_num
!= dn1
->comp_num
) {
818 return (dn1
->comp_num
- dn0
->comp_num
);
821 if (dn0
->comp_num
== 0) {
822 if (dn0
->special
&& dn1
->special
) {
823 return strcmp(dn0
->linearized
, dn1
->linearized
);
824 } else if (dn0
->special
) {
826 } else if (dn1
->special
) {
833 for (i
= 0; i
< dn0
->comp_num
; i
++) {
834 /* compare attr names */
835 ret
= strcmp(dn0
->components
[i
].cf_name
, dn1
->components
[i
].cf_name
);
836 if (ret
!= 0) return ret
;
838 /* compare attr.cf_value. */
839 if (dn0
->components
[i
].cf_value
.length
!= dn1
->components
[i
].cf_value
.length
) {
840 return dn0
->components
[i
].cf_value
.length
- dn1
->components
[i
].cf_value
.length
;
842 ret
= strcmp((char *)dn0
->components
[i
].cf_value
.data
, (char *)dn1
->components
[i
].cf_value
.data
);
843 if (ret
!= 0) return ret
;
849 static struct ldb_dn_component
ldb_dn_copy_component(void *mem_ctx
, struct ldb_dn_component
*src
)
851 struct ldb_dn_component dst
;
853 memset(&dst
, 0, sizeof(dst
));
859 dst
.value
= ldb_val_dup(mem_ctx
, &(src
->value
));
860 if (dst
.value
.data
== NULL
) {
864 dst
.name
= talloc_strdup(mem_ctx
, src
->name
);
865 if (dst
.name
== NULL
) {
866 LDB_FREE(dst
.value
.data
);
870 if (src
->cf_value
.data
) {
871 dst
.cf_value
= ldb_val_dup(mem_ctx
, &(src
->cf_value
));
872 if (dst
.cf_value
.data
== NULL
) {
873 LDB_FREE(dst
.value
.data
);
878 dst
.cf_name
= talloc_strdup(mem_ctx
, src
->cf_name
);
879 if (dst
.cf_name
== NULL
) {
880 LDB_FREE(dst
.cf_name
);
881 LDB_FREE(dst
.value
.data
);
886 dst
.cf_value
.data
= NULL
;
893 struct ldb_dn
*ldb_dn_copy(void *mem_ctx
, struct ldb_dn
*dn
)
895 struct ldb_dn
*new_dn
;
897 if (!dn
|| dn
->invalid
) {
901 new_dn
= talloc_zero(mem_ctx
, struct ldb_dn
);
908 if (dn
->components
) {
911 new_dn
->components
= talloc_zero_array(new_dn
, struct ldb_dn_component
, dn
->comp_num
);
912 if ( ! new_dn
->components
) {
917 for (i
= 0; i
< dn
->comp_num
; i
++) {
918 new_dn
->components
[i
] = ldb_dn_copy_component(new_dn
->components
, &dn
->components
[i
]);
919 if ( ! new_dn
->components
[i
].value
.data
) {
927 new_dn
->casefold
= talloc_strdup(new_dn
, dn
->casefold
);
928 if ( ! new_dn
->casefold
) {
934 if (dn
->linearized
) {
935 new_dn
->linearized
= talloc_strdup(new_dn
, dn
->linearized
);
936 if ( ! new_dn
->linearized
) {
945 /* modify the given dn by adding a base.
947 * return true if successful and false if not
948 * if false is returned the dn may be marked invalid
950 bool ldb_dn_add_base(struct ldb_dn
*dn
, struct ldb_dn
*base
)
955 if ( !base
|| base
->invalid
|| !dn
|| dn
->invalid
) {
959 if (dn
->components
) {
962 if ( ! ldb_dn_validate(base
)) {
967 if (dn
->valid_case
) {
968 if ( ! (s
= ldb_dn_get_casefold(base
))) {
973 dn
->components
= talloc_realloc(dn
,
975 struct ldb_dn_component
,
976 dn
->comp_num
+ base
->comp_num
);
977 if ( ! dn
->components
) {
982 for (i
= 0; i
< base
->comp_num
; dn
->comp_num
++, i
++) {
983 dn
->components
[dn
->comp_num
] = ldb_dn_copy_component(dn
->components
, &base
->components
[i
]);
984 if (dn
->components
[dn
->comp_num
].value
.data
== NULL
) {
990 if (dn
->casefold
&& s
) {
991 t
= talloc_asprintf(dn
, "%s,%s", dn
->casefold
, s
);
992 LDB_FREE(dn
->casefold
);
997 if (dn
->linearized
) {
999 s
= ldb_dn_get_linearized(base
);
1004 t
= talloc_asprintf(dn
, "%s,%s", dn
->linearized
, s
);
1009 LDB_FREE(dn
->linearized
);
1016 /* modify the given dn by adding a base.
1018 * return true if successful and false if not
1019 * if false is returned the dn may be marked invalid
1021 bool ldb_dn_add_base_fmt(struct ldb_dn
*dn
, const char *base_fmt
, ...)
1023 struct ldb_dn
*base
;
1028 if ( !dn
|| dn
->invalid
) {
1032 va_start(ap
, base_fmt
);
1033 base_str
= talloc_vasprintf(dn
, base_fmt
, ap
);
1036 if (base_str
== NULL
) {
1040 base
= ldb_dn_new(base_str
, dn
->ldb
, base_str
);
1042 ret
= ldb_dn_add_base(dn
, base
);
1044 talloc_free(base_str
);
1049 /* modify the given dn by adding children elements.
1051 * return true if successful and false if not
1052 * if false is returned the dn may be marked invalid
1054 bool ldb_dn_add_child(struct ldb_dn
*dn
, struct ldb_dn
*child
)
1059 if ( !child
|| child
->invalid
|| !dn
|| dn
->invalid
) {
1063 if (dn
->components
) {
1066 if ( ! ldb_dn_validate(child
)) {
1071 if (dn
->valid_case
) {
1072 if ( ! (s
= ldb_dn_get_casefold(child
))) {
1077 n
= dn
->comp_num
+ child
->comp_num
;
1079 dn
->components
= talloc_realloc(dn
,
1081 struct ldb_dn_component
,
1083 if ( ! dn
->components
) {
1088 for (i
= dn
->comp_num
- 1, j
= n
- 1; i
>= 0; i
--, j
--) {
1089 dn
->components
[j
] = dn
->components
[i
];
1092 for (i
= 0; i
< child
->comp_num
; i
++) {
1093 dn
->components
[i
] = ldb_dn_copy_component(dn
->components
, &child
->components
[i
]);
1094 if (dn
->components
[i
].value
.data
== NULL
) {
1102 if (dn
->casefold
&& s
) {
1103 t
= talloc_asprintf(dn
, "%s,%s", s
, dn
->casefold
);
1104 LDB_FREE(dn
->casefold
);
1109 if (dn
->linearized
) {
1111 s
= ldb_dn_get_linearized(child
);
1116 t
= talloc_asprintf(dn
, "%s,%s", s
, dn
->linearized
);
1121 LDB_FREE(dn
->linearized
);
1128 /* modify the given dn by adding children elements.
1130 * return true if successful and false if not
1131 * if false is returned the dn may be marked invalid
1133 bool ldb_dn_add_child_fmt(struct ldb_dn
*dn
, const char *child_fmt
, ...)
1135 struct ldb_dn
*child
;
1140 if ( !dn
|| dn
->invalid
) {
1144 va_start(ap
, child_fmt
);
1145 child_str
= talloc_vasprintf(dn
, child_fmt
, ap
);
1148 if (child_str
== NULL
) {
1152 child
= ldb_dn_new(child_str
, dn
->ldb
, child_str
);
1154 ret
= ldb_dn_add_child(dn
, child
);
1156 talloc_free(child_str
);
1161 bool ldb_dn_remove_base_components(struct ldb_dn
*dn
, unsigned int num
)
1165 if ( ! ldb_dn_validate(dn
)) {
1169 if (dn
->comp_num
< num
) {
1173 /* free components */
1174 for (i
= num
; i
> 0; i
--) {
1175 LDB_FREE(dn
->components
[dn
->comp_num
- i
].name
);
1176 LDB_FREE(dn
->components
[dn
->comp_num
- i
].value
.data
);
1177 LDB_FREE(dn
->components
[dn
->comp_num
- i
].cf_name
);
1178 LDB_FREE(dn
->components
[dn
->comp_num
- i
].cf_value
.data
);
1181 dn
->comp_num
-= num
;
1183 if (dn
->valid_case
) {
1184 for (i
= 0; i
< dn
->comp_num
; i
++) {
1185 LDB_FREE(dn
->components
[i
].cf_name
);
1186 LDB_FREE(dn
->components
[i
].cf_value
.data
);
1188 dn
->valid_case
= false;
1191 LDB_FREE(dn
->casefold
);
1192 LDB_FREE(dn
->linearized
);
1197 bool ldb_dn_remove_child_components(struct ldb_dn
*dn
, unsigned int num
)
1201 if ( ! ldb_dn_validate(dn
)) {
1205 if (dn
->comp_num
< num
) {
1209 for (i
= 0, j
= num
; j
< dn
->comp_num
; i
++, j
++) {
1211 LDB_FREE(dn
->components
[i
].name
);
1212 LDB_FREE(dn
->components
[i
].value
.data
);
1213 LDB_FREE(dn
->components
[i
].cf_name
);
1214 LDB_FREE(dn
->components
[i
].cf_value
.data
);
1216 dn
->components
[i
] = dn
->components
[j
];
1219 dn
->comp_num
-= num
;
1221 if (dn
->valid_case
) {
1222 for (i
= 0; i
< dn
->comp_num
; i
++) {
1223 LDB_FREE(dn
->components
[i
].cf_name
);
1224 LDB_FREE(dn
->components
[i
].cf_value
.data
);
1226 dn
->valid_case
= false;
1229 LDB_FREE(dn
->casefold
);
1230 LDB_FREE(dn
->linearized
);
1235 struct ldb_dn
*ldb_dn_get_parent(void *mem_ctx
, struct ldb_dn
*dn
)
1237 struct ldb_dn
*new_dn
;
1239 new_dn
= ldb_dn_copy(mem_ctx
, dn
);
1244 if ( ! ldb_dn_remove_child_components(new_dn
, 1)) {
1245 talloc_free(new_dn
);
1252 /* Create a 'canonical name' string from a DN:
1254 ie dc=samba,dc=org -> samba.org/
1255 uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator
1257 There are two formats, the EX format has the last / replaced with a newline (\n).
1260 static char *ldb_dn_canonical(void *mem_ctx
, struct ldb_dn
*dn
, int ex_format
) {
1263 char *cracked
= NULL
;
1265 if ( ! ldb_dn_validate(dn
)) {
1269 tmpctx
= talloc_new(mem_ctx
);
1271 /* Walk backwards down the DN, grabbing 'dc' components at first */
1272 for (i
= dn
->comp_num
- 1 ; i
>= 0; i
--) {
1273 if (ldb_attr_cmp(dn
->components
[i
].name
, "dc") != 0) {
1277 cracked
= talloc_asprintf(tmpctx
, "%s.%s",
1278 ldb_dn_escape_value(tmpctx
, dn
->components
[i
].value
),
1281 cracked
= ldb_dn_escape_value(tmpctx
, dn
->components
[i
].value
);
1288 /* Only domain components? Finish here */
1291 cracked
= talloc_append_string(tmpctx
, cracked
, "\n");
1293 cracked
= talloc_append_string(tmpctx
, cracked
, "/");
1295 talloc_steal(mem_ctx
, cracked
);
1299 /* Now walk backwards appending remaining components */
1300 for (; i
> 0; i
--) {
1301 cracked
= talloc_asprintf_append(cracked
, "/%s",
1302 ldb_dn_escape_value(tmpctx
, dn
->components
[i
].value
));
1308 /* Last one, possibly a newline for the 'ex' format */
1310 cracked
= talloc_asprintf_append(cracked
, "\n%s",
1311 ldb_dn_escape_value(tmpctx
, dn
->components
[i
].value
));
1313 cracked
= talloc_asprintf_append(cracked
, "/%s",
1314 ldb_dn_escape_value(tmpctx
, dn
->components
[i
].value
));
1317 talloc_steal(mem_ctx
, cracked
);
1319 talloc_free(tmpctx
);
1323 /* Wrapper functions for the above, for the two different string formats */
1324 char *ldb_dn_canonical_string(void *mem_ctx
, struct ldb_dn
*dn
) {
1325 return ldb_dn_canonical(mem_ctx
, dn
, 0);
1329 char *ldb_dn_canonical_ex_string(void *mem_ctx
, struct ldb_dn
*dn
) {
1330 return ldb_dn_canonical(mem_ctx
, dn
, 1);
1333 int ldb_dn_get_comp_num(struct ldb_dn
*dn
)
1335 if ( ! ldb_dn_validate(dn
)) {
1338 return dn
->comp_num
;
1341 const char *ldb_dn_get_component_name(struct ldb_dn
*dn
, unsigned int num
)
1343 if ( ! ldb_dn_validate(dn
)) {
1346 if (num
>= dn
->comp_num
) return NULL
;
1347 return dn
->components
[num
].name
;
1350 const struct ldb_val
*ldb_dn_get_component_val(struct ldb_dn
*dn
, unsigned int num
)
1352 if ( ! ldb_dn_validate(dn
)) {
1355 if (num
>= dn
->comp_num
) return NULL
;
1356 return &dn
->components
[num
].value
;
1359 const char *ldb_dn_get_rdn_name(struct ldb_dn
*dn
)
1361 if ( ! ldb_dn_validate(dn
)) {
1364 if (dn
->comp_num
== 0) return NULL
;
1365 return dn
->components
[0].name
;
1368 const struct ldb_val
*ldb_dn_get_rdn_val(struct ldb_dn
*dn
)
1370 if ( ! ldb_dn_validate(dn
)) {
1373 if (dn
->comp_num
== 0) return NULL
;
1374 return &dn
->components
[0].value
;
1377 int ldb_dn_set_component(struct ldb_dn
*dn
, int num
, const char *name
, const struct ldb_val val
)
1382 if ( ! ldb_dn_validate(dn
)) {
1383 return LDB_ERR_OTHER
;
1386 if (num
>= dn
->comp_num
) {
1387 return LDB_ERR_OTHER
;
1390 n
= talloc_strdup(dn
, name
);
1392 return LDB_ERR_OTHER
;
1395 v
.length
= val
.length
;
1396 v
.data
= (uint8_t *)talloc_memdup(dn
, val
.data
, v
.length
+1);
1399 return LDB_ERR_OTHER
;
1402 talloc_free(dn
->components
[num
].name
);
1403 talloc_free(dn
->components
[num
].value
.data
);
1404 dn
->components
[num
].name
= n
;
1405 dn
->components
[num
].value
= v
;
1407 if (dn
->valid_case
) {
1409 for (i
= 0; i
< dn
->comp_num
; i
++) {
1410 LDB_FREE(dn
->components
[i
].cf_name
);
1411 LDB_FREE(dn
->components
[i
].cf_value
.data
);
1413 dn
->valid_case
= false;
1415 LDB_FREE(dn
->casefold
);
1420 bool ldb_dn_is_valid(struct ldb_dn
*dn
)
1422 if ( ! dn
) return false;
1423 return ! dn
->invalid
;
1426 bool ldb_dn_is_special(struct ldb_dn
*dn
)
1428 if ( ! dn
|| dn
->invalid
) return false;
1432 bool ldb_dn_check_special(struct ldb_dn
*dn
, const char *check
)
1434 if ( ! dn
|| dn
->invalid
) return false;
1435 return ! strcmp(dn
->linearized
, check
);
1438 bool ldb_dn_is_null(struct ldb_dn
*dn
)
1440 if ( ! dn
|| dn
->invalid
) return false;
1441 if (dn
->linearized
&& (dn
->linearized
[0] == '\0')) return true;