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 explode and utility functions
30 * Description: - explode a dn into it's own basic elements
31 * and put them in a structure
32 * - manipulate ldb_dn structures
38 #include "ldb/include/includes.h"
40 #define LDB_DN_NULL_FAILED(x) if (!(x)) goto failed
42 #define LDB_SPECIAL "@SPECIAL"
45 internal ldb exploded dn structures
47 struct ldb_dn_component
{
54 struct ldb_dn_component
*components
;
57 int ldb_dn_is_special(const struct ldb_dn
*dn
)
59 if (dn
== NULL
|| dn
->comp_num
!= 1) return 0;
61 return ! strcmp(dn
->components
[0].name
, LDB_SPECIAL
);
64 int ldb_dn_check_special(const struct ldb_dn
*dn
, const char *check
)
66 if (dn
== NULL
|| dn
->comp_num
!= 1) return 0;
68 return ! strcmp((char *)dn
->components
[0].value
.data
, check
);
71 char *ldb_dn_escape_value(void *mem_ctx
, struct ldb_val value
)
73 const char *p
, *s
, *src
;
80 p
= s
= src
= (const char *)value
.data
;
83 /* allocate destination string, it will be at most 3 times the source */
84 dst
= d
= talloc_array(mem_ctx
, char, len
* 3 + 1);
85 LDB_DN_NULL_FAILED(dst
);
87 while (p
- src
< len
) {
89 p
+= strcspn(p
, ",=\n+<>#;\\\"");
91 if (p
- src
== len
) /* found no escapable chars */
94 memcpy(d
, s
, p
- s
); /* copy the part of the string before the stop */
95 d
+= (p
- s
); /* move to current position */
97 if (*p
) { /* it is a normal escapable character */
100 } else { /* we have a zero byte in the string */
101 strncpy(d
, "\00", 3); /* escape the zero */
103 p
++; /* skip the zero */
105 s
= p
; /* move forward */
108 /* copy the last part (with zero) and return */
109 memcpy(d
, s
, &src
[len
] - s
+ 1);
118 static struct ldb_val
ldb_dn_unescape_value(void *mem_ctx
, const char *src
)
120 struct ldb_val value
;
122 char *p
, *dst
= NULL
, *end
;
124 memset(&value
, 0, sizeof(value
));
126 LDB_DN_NULL_FAILED(src
);
128 dst
= p
= (char *)talloc_memdup(mem_ctx
, src
, strlen(src
) + 1);
129 LDB_DN_NULL_FAILED(dst
);
131 end
= &dst
[strlen(dst
)];
134 p
+= strcspn(p
, ",=\n+<>#;\\\"");
137 if (strchr(",=\n+<>#;\\\"", p
[1])) {
138 memmove(p
, p
+ 1, end
- (p
+ 1) + 1);
144 if (sscanf(p
+ 1, "%02x", &x
) == 1) {
145 *p
= (unsigned char)x
;
146 memmove(p
+ 1, p
+ 3, end
- (p
+ 3) + 1);
153 /* a string with not escaped specials is invalid (tested) */
159 value
.length
= end
- dst
;
160 value
.data
= (uint8_t *)dst
;
168 /* check if the string contains quotes
169 * skips leading and trailing spaces
170 * - returns 0 if no quotes found
171 * - returns 1 if quotes are found and put their position
172 * in *quote_start and *quote_end parameters
173 * - return -1 if there are open quotes
176 static int get_quotes_position(const char *source
, int *quote_start
, int *quote_end
)
180 if (source
== NULL
|| quote_start
== NULL
|| quote_end
== NULL
) return -1;
184 /* check if there are quotes surrounding the value */
185 p
+= strspn(p
, " \n"); /* skip white spaces */
188 *quote_start
= p
- source
;
193 LDB_DN_NULL_FAILED(p
);
195 if (*(p
- 1) == '\\')
199 *quote_end
= p
- source
;
209 static char *seek_to_separator(char *string
, const char *separators
)
212 int ret
, qs
, qe
, escaped
;
214 if (string
== NULL
|| separators
== NULL
) return NULL
;
216 p
= strchr(string
, '=');
217 LDB_DN_NULL_FAILED(p
);
221 /* check if there are quotes surrounding the value */
223 ret
= get_quotes_position(p
, &qs
, &qe
);
227 if (ret
== 1) { /* quotes found */
229 p
+= qe
; /* positioning after quotes */
230 p
+= strspn(p
, " \n"); /* skip white spaces after the quote */
232 if (strcspn(p
, separators
) != 0) /* if there are characters between quotes */
233 return NULL
; /* and separators, the dn is invalid */
235 return p
; /* return on the separator */
238 /* no quotes found seek to separators */
242 ret
= strcspn(q
, separators
);
244 if (q
[ret
- 1] == '\\') {
250 if (ret
== 0 && p
== q
) /* no separators ?! bail out */
259 static char *ldb_dn_trim_string(char *string
, const char *edge
)
263 /* seek out edge from start of string */
264 s
= string
+ strspn(string
, edge
);
266 /* backwards skip from end of string */
267 p
= &s
[strlen(s
) - 1];
268 while (p
> s
&& strchr(edge
, *p
)) {
276 /* we choosed to not support multpile valued components */
277 static struct ldb_dn_component
ldb_dn_explode_component(void *mem_ctx
, char *raw_component
)
279 struct ldb_dn_component dc
;
283 memset(&dc
, 0, sizeof(dc
));
285 if (raw_component
== NULL
) {
289 /* find attribute type/value separator */
290 p
= strchr(raw_component
, '=');
291 LDB_DN_NULL_FAILED(p
);
293 *p
++ = '\0'; /* terminate name and point to value */
295 /* copy and trim name in the component */
296 dc
.name
= talloc_strdup(mem_ctx
, ldb_dn_trim_string(raw_component
, " \n"));
300 if (! ldb_valid_attr_name(dc
.name
)) {
304 ret
= get_quotes_position(p
, &qs
, &qe
);
307 case 0: /* no quotes trim the string */
308 p
= ldb_dn_trim_string(p
, " \n");
309 dc
.value
= ldb_dn_unescape_value(mem_ctx
, p
);
312 case 1: /* quotes found get the unquoted string */
315 dc
.value
.length
= strlen(p
);
316 dc
.value
.data
= (uint8_t *)talloc_memdup(mem_ctx
, p
,
317 dc
.value
.length
+ 1);
320 default: /* mismatched quotes ot other error, bail out */
324 if (dc
.value
.length
== 0) {
331 talloc_free(dc
.name
);
336 struct ldb_dn
*ldb_dn_new(void *mem_ctx
)
340 edn
= talloc(mem_ctx
, struct ldb_dn
);
341 LDB_DN_NULL_FAILED(edn
);
343 /* Initially there are no components */
345 edn
->components
= NULL
;
354 explode a DN string into a ldb_dn structure
356 struct ldb_dn
*ldb_dn_explode(void *mem_ctx
, const char *dn
)
358 struct ldb_dn
*edn
; /* the exploded dn */
361 if (dn
== NULL
) return NULL
;
363 /* Allocate a structure to hold the exploded DN */
364 edn
= ldb_dn_new(mem_ctx
);
376 /* Special DNs case */
379 edn
->components
= talloc(edn
, struct ldb_dn_component
);
380 if (edn
->components
== NULL
) goto failed
;
381 edn
->components
[0].name
= talloc_strdup(edn
->components
, LDB_SPECIAL
);
382 if (edn
->components
[0].name
== NULL
) goto failed
;
383 edn
->components
[0].value
.data
= (uint8_t *)talloc_strdup(edn
->components
, dn
);
384 if (edn
->components
[0].value
.data
== NULL
) goto failed
;
385 edn
->components
[0].value
.length
= strlen(dn
);
389 pdn
= p
= talloc_strdup(edn
, dn
);
390 LDB_DN_NULL_FAILED(pdn
);
392 /* get the components */
396 /* terminate the current component and return pointer to the next one */
397 t
= seek_to_separator(p
, ",;");
398 LDB_DN_NULL_FAILED(t
);
400 if (*t
) { /* here there is a separator */
401 *t
= '\0'; /*terminate */
402 t
++; /* a separtor means another component follows */
405 /* allocate space to hold the dn component */
406 edn
->components
= talloc_realloc(edn
, edn
->components
,
407 struct ldb_dn_component
,
409 if (edn
->components
== NULL
)
412 /* store the exploded component in the main structure */
413 edn
->components
[edn
->comp_num
] = ldb_dn_explode_component(edn
, p
);
414 LDB_DN_NULL_FAILED(edn
->components
[edn
->comp_num
].name
);
418 /* jump to the next component if any */
432 struct ldb_dn
*ldb_dn_explode_or_special(void *mem_ctx
, const char *dn
)
434 struct ldb_dn
*edn
; /* the exploded dn */
436 if (dn
== NULL
) return NULL
;
438 if (strncasecmp(dn
, "<GUID=", 6) == 0) {
439 /* this is special DN returned when the
440 * exploded_dn control is used
443 /* Allocate a structure to hold the exploded DN */
444 if (!(edn
= ldb_dn_new(mem_ctx
))) {
449 edn
->components
= talloc(edn
, struct ldb_dn_component
);
450 if (edn
->components
== NULL
) goto failed
;
451 edn
->components
[0].name
= talloc_strdup(edn
->components
, LDB_SPECIAL
);
452 if (edn
->components
[0].name
== NULL
) goto failed
;
453 edn
->components
[0].value
.data
= (uint8_t *)talloc_strdup(edn
->components
, dn
);
454 if (edn
->components
[0].value
.data
== NULL
) goto failed
;
455 edn
->components
[0].value
.length
= strlen(dn
);
460 return ldb_dn_explode(mem_ctx
, dn
);
467 char *ldb_dn_linearize(void *mem_ctx
, const struct ldb_dn
*edn
)
472 if (edn
== NULL
) return NULL
;
475 if (ldb_dn_is_special(edn
)) {
476 dn
= talloc_strdup(mem_ctx
, (char *)edn
->components
[0].value
.data
);
480 dn
= talloc_strdup(mem_ctx
, "");
481 LDB_DN_NULL_FAILED(dn
);
483 for (i
= 0; i
< edn
->comp_num
; i
++) {
484 value
= ldb_dn_escape_value(dn
, edn
->components
[i
].value
);
485 LDB_DN_NULL_FAILED(value
);
488 dn
= talloc_asprintf_append(dn
, "%s=%s", edn
->components
[i
].name
, value
);
490 dn
= talloc_asprintf_append(dn
, ",%s=%s", edn
->components
[i
].name
, value
);
492 LDB_DN_NULL_FAILED(dn
);
504 /* Determine if dn is below base, in the ldap tree. Used for
505 * evaluating a subtree search.
506 * 0 if they match, otherwise non-zero
509 int ldb_dn_compare_base(struct ldb_context
*ldb
,
510 const struct ldb_dn
*base
,
511 const struct ldb_dn
*dn
)
516 if (base
== NULL
|| base
->comp_num
== 0) return 0;
517 if (dn
== NULL
|| dn
->comp_num
== 0) return -1;
519 /* if the base has more componts than the dn, then they differ */
520 if (base
->comp_num
> dn
->comp_num
) {
521 return (dn
->comp_num
- base
->comp_num
);
524 n0
= base
->comp_num
- 1;
525 n1
= dn
->comp_num
- 1;
526 while (n0
>= 0 && n1
>= 0) {
527 const struct ldb_attrib_handler
*h
;
529 /* compare names (attribute names are guaranteed to be ASCII only) */
530 ret
= ldb_attr_cmp(base
->components
[n0
].name
,
531 dn
->components
[n1
].name
);
536 /* names match, compare values */
537 h
= ldb_attrib_handler(ldb
, base
->components
[n0
].name
);
538 ret
= h
->comparison_fn(ldb
, ldb
, &(base
->components
[n0
].value
),
539 &(dn
->components
[n1
].value
));
550 /* compare DNs using casefolding compare functions.
552 If they match, then return 0
555 int ldb_dn_compare(struct ldb_context
*ldb
,
556 const struct ldb_dn
*edn0
,
557 const struct ldb_dn
*edn1
)
559 if (edn0
== NULL
|| edn1
== NULL
) return edn1
- edn0
;
561 if (edn0
->comp_num
!= edn1
->comp_num
)
562 return (edn1
->comp_num
- edn0
->comp_num
);
564 return ldb_dn_compare_base(ldb
, edn0
, edn1
);
567 int ldb_dn_cmp(struct ldb_context
*ldb
, const char *dn0
, const char *dn1
)
573 if (dn0
== NULL
|| dn1
== NULL
) return dn1
- dn0
;
575 edn0
= ldb_dn_explode_casefold(ldb
, ldb
, dn0
);
576 if (edn0
== NULL
) return 1;
578 edn1
= ldb_dn_explode_casefold(ldb
, ldb
, dn1
);
584 ret
= ldb_dn_compare(ldb
, edn0
, edn1
);
593 casefold a dn. We need to casefold the attribute names, and canonicalize
594 attribute values of case insensitive attributes.
596 struct ldb_dn
*ldb_dn_casefold(struct ldb_context
*ldb
, void *mem_ctx
, const struct ldb_dn
*edn
)
601 if (edn
== NULL
) return NULL
;
603 cedn
= ldb_dn_new(mem_ctx
);
608 cedn
->comp_num
= edn
->comp_num
;
609 cedn
->components
= talloc_array(cedn
, struct ldb_dn_component
, edn
->comp_num
);
610 if (!cedn
->components
) {
615 for (i
= 0; i
< edn
->comp_num
; i
++) {
616 struct ldb_dn_component dc
;
617 const struct ldb_attrib_handler
*h
;
619 memset(&dc
, 0, sizeof(dc
));
620 dc
.name
= ldb_attr_casefold(cedn
->components
, edn
->components
[i
].name
);
626 h
= ldb_attrib_handler(ldb
, dc
.name
);
627 ret
= h
->canonicalise_fn(ldb
, cedn
->components
,
628 &(edn
->components
[i
].value
),
635 cedn
->components
[i
] = dc
;
641 struct ldb_dn
*ldb_dn_explode_casefold(struct ldb_context
*ldb
, void *mem_ctx
, const char *dn
)
643 struct ldb_dn
*edn
, *cdn
;
645 if (dn
== NULL
) return NULL
;
647 edn
= ldb_dn_explode(ldb
, dn
);
648 if (edn
== NULL
) return NULL
;
650 cdn
= ldb_dn_casefold(ldb
, mem_ctx
, edn
);
656 char *ldb_dn_linearize_casefold(struct ldb_context
*ldb
, void *mem_ctx
, const struct ldb_dn
*edn
)
661 if (edn
== NULL
) return NULL
;
664 if (ldb_dn_is_special(edn
)) {
665 dn
= talloc_strdup(mem_ctx
, (char *)edn
->components
[0].value
.data
);
669 cdn
= ldb_dn_casefold(ldb
, mem_ctx
, edn
);
670 if (cdn
== NULL
) return NULL
;
672 dn
= ldb_dn_linearize(ldb
, cdn
);
682 static struct ldb_dn_component
ldb_dn_copy_component(void *mem_ctx
, struct ldb_dn_component
*src
)
684 struct ldb_dn_component dst
;
686 memset(&dst
, 0, sizeof(dst
));
692 dst
.value
= ldb_val_dup(mem_ctx
, &(src
->value
));
693 if (dst
.value
.data
== NULL
) {
697 dst
.name
= talloc_strdup(mem_ctx
, src
->name
);
698 if (dst
.name
== NULL
) {
699 talloc_free(dst
.value
.data
);
700 dst
.value
.data
= NULL
;
706 /* Copy a DN but replace the old with the new base DN. */
707 struct ldb_dn
*ldb_dn_copy_rebase(void *mem_ctx
, const struct ldb_dn
*old
, const struct ldb_dn
*old_base
, const struct ldb_dn
*new_base
)
709 struct ldb_dn
*new_dn
;
712 /* Perhaps we don't need to rebase at all? */
713 if (!old_base
|| !new_base
) {
714 return ldb_dn_copy(mem_ctx
, old
);
717 offset
= old
->comp_num
- old_base
->comp_num
;
718 if (!(new_dn
= ldb_dn_copy_partial(mem_ctx
, new_base
,
719 offset
+ new_base
->comp_num
))) {
722 for (i
= 0; i
< offset
; i
++) {
723 new_dn
->components
[i
] = ldb_dn_copy_component(new_dn
->components
, &(old
->components
[i
]));
729 /* copy specified number of elements of a dn into a new one
730 element are copied from top level up to the unique rdn
731 num_el may be greater than dn->comp_num (see ldb_dn_make_child)
733 struct ldb_dn
*ldb_dn_copy_partial(void *mem_ctx
, const struct ldb_dn
*dn
, int num_el
)
735 struct ldb_dn
*newdn
;
738 if (dn
== NULL
) return NULL
;
739 if (num_el
<= 0) return NULL
;
741 newdn
= ldb_dn_new(mem_ctx
);
742 LDB_DN_NULL_FAILED(newdn
);
744 newdn
->comp_num
= num_el
;
745 n
= newdn
->comp_num
- 1;
746 newdn
->components
= talloc_array(newdn
, struct ldb_dn_component
, newdn
->comp_num
);
747 if (newdn
->components
== NULL
) goto failed
;
749 if (dn
->comp_num
== 0) return newdn
;
750 e
= dn
->comp_num
- 1;
752 for (i
= 0; i
< newdn
->comp_num
; i
++) {
753 newdn
->components
[n
- i
] = ldb_dn_copy_component(newdn
->components
,
754 &(dn
->components
[e
- i
]));
767 struct ldb_dn
*ldb_dn_copy(void *mem_ctx
, const struct ldb_dn
*dn
)
769 if (dn
== NULL
) return NULL
;
770 return ldb_dn_copy_partial(mem_ctx
, dn
, dn
->comp_num
);
773 struct ldb_dn
*ldb_dn_get_parent(void *mem_ctx
, const struct ldb_dn
*dn
)
775 if (dn
== NULL
) return NULL
;
776 return ldb_dn_copy_partial(mem_ctx
, dn
, dn
->comp_num
- 1);
779 struct ldb_dn_component
*ldb_dn_build_component(void *mem_ctx
, const char *attr
,
782 struct ldb_dn_component
*dc
;
784 if (attr
== NULL
|| val
== NULL
) return NULL
;
786 dc
= talloc(mem_ctx
, struct ldb_dn_component
);
787 if (dc
== NULL
) return NULL
;
789 dc
->name
= talloc_strdup(dc
, attr
);
790 if (dc
->name
== NULL
) {
795 dc
->value
.data
= (uint8_t *)talloc_strdup(dc
, val
);
796 if (dc
->value
.data
== NULL
) {
801 dc
->value
.length
= strlen(val
);
806 struct ldb_dn
*ldb_dn_build_child(void *mem_ctx
, const char *attr
,
808 const struct ldb_dn
*base
)
810 struct ldb_dn
*newdn
;
811 if (! ldb_valid_attr_name(attr
)) return NULL
;
812 if (value
== NULL
|| value
== '\0') return NULL
;
815 newdn
= ldb_dn_copy_partial(mem_ctx
, base
, base
->comp_num
+ 1);
816 LDB_DN_NULL_FAILED(newdn
);
818 newdn
= ldb_dn_new(mem_ctx
);
819 LDB_DN_NULL_FAILED(newdn
);
822 newdn
->components
= talloc_array(newdn
, struct ldb_dn_component
, newdn
->comp_num
);
823 LDB_DN_NULL_FAILED(newdn
->components
);
826 newdn
->components
[0].name
= talloc_strdup(newdn
->components
, attr
);
827 LDB_DN_NULL_FAILED(newdn
->components
[0].name
);
829 newdn
->components
[0].value
.data
= (uint8_t *)talloc_strdup(newdn
->components
, value
);
830 LDB_DN_NULL_FAILED(newdn
->components
[0].value
.data
);
831 newdn
->components
[0].value
.length
= strlen((char *)newdn
->components
[0].value
.data
);
841 struct ldb_dn
*ldb_dn_compose(void *mem_ctx
, const struct ldb_dn
*dn1
, const struct ldb_dn
*dn2
)
844 struct ldb_dn
*newdn
;
846 if (dn2
== NULL
&& dn1
== NULL
) {
851 newdn
= ldb_dn_new(mem_ctx
);
852 LDB_DN_NULL_FAILED(newdn
);
854 newdn
->comp_num
= dn1
->comp_num
;
855 newdn
->components
= talloc_array(newdn
, struct ldb_dn_component
, newdn
->comp_num
);
856 LDB_DN_NULL_FAILED(newdn
->components
);
858 int comp_num
= dn2
->comp_num
;
859 if (dn1
!= NULL
) comp_num
+= dn1
->comp_num
;
860 newdn
= ldb_dn_copy_partial(mem_ctx
, dn2
, comp_num
);
861 LDB_DN_NULL_FAILED(newdn
);
868 for (i
= 0; i
< dn1
->comp_num
; i
++) {
869 newdn
->components
[i
] = ldb_dn_copy_component(newdn
->components
,
870 &(dn1
->components
[i
]));
871 if (newdn
->components
[i
].value
.data
== NULL
) {
883 struct ldb_dn
*ldb_dn_string_compose(void *mem_ctx
, const struct ldb_dn
*base
, const char *child_fmt
, ...)
885 struct ldb_dn
*dn
, *dn1
;
889 if (child_fmt
== NULL
) return NULL
;
891 va_start(ap
, child_fmt
);
892 child_str
= talloc_vasprintf(mem_ctx
, child_fmt
, ap
);
895 if (child_str
== NULL
) return NULL
;
897 dn1
= ldb_dn_explode(mem_ctx
, child_str
);
898 dn
= ldb_dn_compose(mem_ctx
, dn1
, base
);
900 talloc_free(child_str
);
906 /* Create a 'canonical name' string from a DN:
908 ie dc=samba,dc=org -> samba.org/
909 uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator
911 There are two formats, the EX format has the last / replaced with a newline (\n).
914 static char *ldb_dn_canonical(void *mem_ctx
, const struct ldb_dn
*dn
, int ex_format
) {
916 char *cracked
= NULL
;
918 /* Walk backwards down the DN, grabbing 'dc' components at first */
919 for (i
= dn
->comp_num
- 1 ; i
>= 0; i
--) {
920 if (ldb_attr_cmp(dn
->components
[i
].name
, "dc") != 0) {
924 cracked
= talloc_asprintf(mem_ctx
, "%s.%s",
925 ldb_dn_escape_value(mem_ctx
, dn
->components
[i
].value
),
928 cracked
= ldb_dn_escape_value(mem_ctx
, dn
->components
[i
].value
);
935 /* Only domain components? Finish here */
938 cracked
= talloc_asprintf(mem_ctx
, "%s\n", cracked
);
940 cracked
= talloc_asprintf(mem_ctx
, "%s/", cracked
);
945 /* Now walk backwards appending remaining components */
947 cracked
= talloc_asprintf(mem_ctx
, "%s/%s", cracked
,
948 ldb_dn_escape_value(mem_ctx
, dn
->components
[i
].value
));
954 /* Last one, possibly a newline for the 'ex' format */
956 cracked
= talloc_asprintf(mem_ctx
, "%s\n%s", cracked
,
957 ldb_dn_escape_value(mem_ctx
, dn
->components
[i
].value
));
959 cracked
= talloc_asprintf(mem_ctx
, "%s/%s", cracked
,
960 ldb_dn_escape_value(mem_ctx
, dn
->components
[i
].value
));
965 /* Wrapper functions for the above, for the two different string formats */
966 char *ldb_dn_canonical_string(void *mem_ctx
, const struct ldb_dn
*dn
) {
967 return ldb_dn_canonical(mem_ctx
, dn
, 0);
971 char *ldb_dn_canonical_ex_string(void *mem_ctx
, const struct ldb_dn
*dn
) {
972 return ldb_dn_canonical(mem_ctx
, dn
, 1);
975 int ldb_dn_get_comp_num(const struct ldb_dn
*dn
)
980 const char *ldb_dn_get_component_name(const struct ldb_dn
*dn
, unsigned int num
)
982 if (num
>= dn
->comp_num
) return NULL
;
983 return dn
->components
[num
].name
;
986 const struct ldb_val
*ldb_dn_get_component_val(const struct ldb_dn
*dn
, unsigned int num
)
988 if (num
>= dn
->comp_num
) return NULL
;
989 return &dn
->components
[num
].value
;
992 const char *ldb_dn_get_rdn_name(const struct ldb_dn
*dn
) {
993 if (dn
->comp_num
== 0) return NULL
;
994 return dn
->components
[0].name
;
997 const struct ldb_val
*ldb_dn_get_rdn_val(const struct ldb_dn
*dn
) {
998 if (dn
->comp_num
== 0) return NULL
;
999 return &dn
->components
[0].value
;
1002 int ldb_dn_set_component(struct ldb_dn
*dn
, int num
, const char *name
, const struct ldb_val val
)
1007 if (num
>= dn
->comp_num
) {
1008 return LDB_ERR_OTHER
;
1011 n
= talloc_strdup(dn
, name
);
1013 return LDB_ERR_OTHER
;
1016 v
.length
= val
.length
;
1017 v
.data
= (uint8_t *)talloc_memdup(dn
, val
.data
, v
.length
+1);
1019 return LDB_ERR_OTHER
;
1022 talloc_free(dn
->components
[num
].name
);
1023 talloc_free(dn
->components
[num
].value
.data
);
1024 dn
->components
[num
].name
= n
;
1025 dn
->components
[num
].value
= v
;