added new function "ldb_msg_add_dn"
[Samba/cd1.git] / source4 / lib / ldb / common / ldb_dn.c
blob3721fa733352de3e7c7009271591d3bfd6686d9f
1 /*
2 ldb database library
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
8 ** under the LGPL
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/>.
25 * Name: ldb
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
33 * Author: Simo Sorce
36 #include "ldb_private.h"
37 #include <ctype.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)
43 /**
44 internal ldb exploded dn structures
46 struct ldb_dn_component {
48 char *name;
49 struct ldb_val value;
51 char *cf_name;
52 struct ldb_val cf_value;
55 struct ldb_dn_ext_component {
57 char *name;
58 struct ldb_val value;
61 struct ldb_dn {
63 struct ldb_context *ldb;
65 /* Special DNs are always linearized */
66 bool special;
67 bool invalid;
69 bool valid_case;
71 char *linearized;
72 char *ext_linearized;
73 char *casefold;
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)
85 dn->invalid = true;
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)
93 struct ldb_dn *dn;
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 */
100 return NULL;
103 dn = talloc_zero(mem_ctx, struct ldb_dn);
104 LDB_DN_NULL_FAILED(dn);
106 dn->ldb = ldb;
108 if (strdn->data && strdn->length) {
109 const char *data = (const char *)strdn->data;
110 size_t length = strdn->length;
112 if (data[0] == '@') {
113 dn->special = true;
115 dn->ext_linearized = talloc_strndup(dn, data, length);
116 LDB_DN_NULL_FAILED(dn->ext_linearized);
118 if (data[0] == '<') {
119 const char *p_save, *p = dn->ext_linearized;
120 do {
121 p_save = p;
122 p = strstr(p, ">;");
123 if (p) {
124 p = p + 2;
126 } while (p);
128 if (p_save == dn->ext_linearized) {
129 dn->linearized = talloc_strdup(dn, "");
130 } else {
131 dn->linearized = talloc_strdup(dn, p_save);
133 LDB_DN_NULL_FAILED(dn->linearized);
134 } else {
135 dn->linearized = dn->ext_linearized;
136 dn->ext_linearized = NULL;
138 } else {
139 dn->linearized = talloc_strdup(dn, "");
140 LDB_DN_NULL_FAILED(dn->linearized);
143 return dn;
145 failed:
146 talloc_free(dn);
147 return NULL;
150 /* strdn may be NULL */
151 struct ldb_dn *ldb_dn_new(void *mem_ctx,
152 struct ldb_context *ldb,
153 const char *strdn)
155 struct ldb_val blob;
156 blob.data = discard_const_p(uint8_t, strdn);
157 blob.length = strdn ? strlen(strdn) : 0;
158 return ldb_dn_from_ldb_val(mem_ctx, ldb, &blob);
161 struct ldb_dn *ldb_dn_new_fmt(void *mem_ctx,
162 struct ldb_context *ldb,
163 const char *new_fmt, ...)
165 char *strdn;
166 va_list ap;
168 if ( (! mem_ctx) || (! ldb)) return NULL;
170 va_start(ap, new_fmt);
171 strdn = talloc_vasprintf(mem_ctx, new_fmt, ap);
172 va_end(ap);
174 if (strdn) {
175 struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb, strdn);
176 talloc_free(strdn);
177 return dn;
180 return NULL;
183 /* see RFC2253 section 2.4 */
184 static int ldb_dn_escape_internal(char *dst, const char *src, int len)
186 const char *p, *s;
187 char *d;
188 int l;
190 p = s = src;
191 d = dst;
193 while (p - src < len) {
194 p += strcspn(p, ",=\n\r+<>#;\\\" ");
196 if (p - src == len) /* found no escapable chars */
197 break;
199 /* copy the part of the string before the stop */
200 memcpy(d, s, p - s);
201 d += (p - s); /* move to current position */
203 switch (*p) {
204 case ' ':
205 if (p == src || (p-src)==(len-1)) {
206 /* if at the beginning or end
207 * of the string then escape */
208 *d++ = '\\';
209 *d++ = *p++;
210 } else {
211 /* otherwise don't escape */
212 *d++ = *p++;
214 break;
216 case '#':
217 /* despite the RFC, windows escapes a #
218 anywhere in the string */
219 case ',':
220 case '+':
221 case '"':
222 case '\\':
223 case '<':
224 case '>':
225 case '?':
226 /* these must be escaped using \c form */
227 *d++ = '\\';
228 *d++ = *p++;
229 break;
231 default: {
232 /* any others get \XX form */
233 unsigned char v;
234 const char *hexbytes = "0123456789ABCDEF";
235 v = *(unsigned char *)p;
236 *d++ = '\\';
237 *d++ = hexbytes[v>>4];
238 *d++ = hexbytes[v&0xF];
239 p++;
240 break;
243 s = p; /* move forward */
246 /* copy the last part (with zero) and return */
247 l = len - (s - src);
248 memcpy(d, s, l + 1);
250 /* return the length of the resulting string */
251 return (l + (d - dst));
254 char *ldb_dn_escape_value(void *mem_ctx, struct ldb_val value)
256 char *dst;
258 if (!value.length)
259 return NULL;
261 /* allocate destination string, it will be at most 3 times the source */
262 dst = talloc_array(mem_ctx, char, value.length * 3 + 1);
263 if ( ! dst) {
264 talloc_free(dst);
265 return NULL;
268 ldb_dn_escape_internal(dst, (const char *)value.data, value.length);
270 dst = talloc_realloc(mem_ctx, dst, char, strlen(dst) + 1);
272 return dst;
276 explode a DN string into a ldb_dn structure
277 based on RFC4514 except that we don't support multiple valued RDNs
279 TODO: according to MS-ADTS:3.1.1.5.2 Naming Constraints
280 DN must be compliant with RFC2253
282 static bool ldb_dn_explode(struct ldb_dn *dn)
284 char *p, *ex_name, *ex_value, *data, *d, *dt, *t;
285 bool trim = false;
286 bool in_extended = false;
287 bool in_ex_name = false;
288 bool in_ex_value = false;
289 bool in_attr = false;
290 bool in_value = false;
291 bool in_quote = false;
292 bool is_oid = false;
293 bool escape = false;
294 unsigned x;
295 int l, ret;
296 char *parse_dn;
297 bool is_index;
299 if ( ! dn || dn->invalid) return false;
301 if (dn->components) {
302 return true;
305 if (dn->ext_linearized) {
306 parse_dn = dn->ext_linearized;
307 } else {
308 parse_dn = dn->linearized;
311 if ( ! parse_dn ) {
312 return false;
315 is_index = (strncmp(parse_dn, "DN=@INDEX:", 10) == 0);
317 /* Empty DNs */
318 if (parse_dn[0] == '\0') {
319 return true;
322 /* Special DNs case */
323 if (dn->special) {
324 return true;
327 /* make sure we free this if alloced previously before replacing */
328 talloc_free(dn->components);
330 talloc_free(dn->ext_components);
331 dn->ext_components = NULL;
333 /* in the common case we have 3 or more components */
334 /* make sure all components are zeroed, other functions depend on it */
335 dn->components = talloc_zero_array(dn, struct ldb_dn_component, 3);
336 if ( ! dn->components) {
337 return false;
339 dn->comp_num = 0;
341 /* Components data space is allocated here once */
342 data = talloc_array(dn->components, char, strlen(parse_dn) + 1);
343 if (!data) {
344 return false;
347 p = parse_dn;
348 in_extended = true;
349 in_ex_name = false;
350 in_ex_value = false;
351 trim = true;
352 t = NULL;
353 d = dt = data;
355 while (*p) {
356 if (in_extended) {
358 if (!in_ex_name && !in_ex_value) {
360 if (p[0] == '<') {
361 p++;
362 ex_name = d;
363 in_ex_name = true;
364 continue;
365 } else if (p[0] == '\0') {
366 p++;
367 continue;
368 } else {
369 in_extended = false;
370 in_attr = true;
371 dt = d;
373 continue;
377 if (in_ex_name && *p == '=') {
378 *d++ = '\0';
379 p++;
380 ex_value = d;
381 in_ex_name = false;
382 in_ex_value = true;
383 continue;
386 if (in_ex_value && *p == '>') {
387 const struct ldb_dn_extended_syntax *ext_syntax;
388 struct ldb_val ex_val = {
389 .data = (uint8_t *)ex_value,
390 .length = d - ex_value
393 *d++ = '\0';
394 p++;
395 in_ex_value = false;
397 /* Process name and ex_value */
399 dn->ext_components = talloc_realloc(dn,
400 dn->ext_components,
401 struct ldb_dn_ext_component,
402 dn->ext_comp_num + 1);
403 if ( ! dn->ext_components) {
404 /* ouch ! */
405 goto failed;
408 ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, ex_name);
409 if (!ext_syntax) {
410 /* We don't know about this type of extended DN */
411 goto failed;
414 dn->ext_components[dn->ext_comp_num].name = talloc_strdup(dn->ext_components, ex_name);
415 if (!dn->ext_components[dn->ext_comp_num].name) {
416 /* ouch */
417 goto failed;
419 ret = ext_syntax->read_fn(dn->ldb, dn->ext_components,
420 &ex_val, &dn->ext_components[dn->ext_comp_num].value);
421 if (ret != LDB_SUCCESS) {
422 ldb_dn_mark_invalid(dn);
423 goto failed;
426 dn->ext_comp_num++;
428 if (*p == '\0') {
429 /* We have reached the end (extended component only)! */
430 talloc_free(data);
431 return true;
433 } else if (*p == ';') {
434 p++;
435 continue;
436 } else {
437 ldb_dn_mark_invalid(dn);
438 goto failed;
442 *d++ = *p++;
443 continue;
445 if (in_attr) {
446 if (trim) {
447 if (*p == ' ') {
448 p++;
449 continue;
452 /* first char */
453 trim = false;
455 if (!isascii(*p)) {
456 /* attr names must be ascii only */
457 ldb_dn_mark_invalid(dn);
458 goto failed;
461 if (isdigit(*p)) {
462 is_oid = true;
463 } else
464 if ( ! isalpha(*p)) {
465 /* not a digit nor an alpha,
466 * invalid attribute name */
467 ldb_dn_mark_invalid(dn);
468 goto failed;
471 /* Copy this character across from parse_dn,
472 * now we have trimmed out spaces */
473 *d++ = *p++;
474 continue;
477 if (*p == ' ') {
478 p++;
479 /* valid only if we are at the end */
480 trim = true;
481 continue;
484 if (trim && (*p != '=')) {
485 /* spaces/tabs are not allowed */
486 ldb_dn_mark_invalid(dn);
487 goto failed;
490 if (*p == '=') {
491 /* attribute terminated */
492 in_attr = false;
493 in_value = true;
494 trim = true;
495 l = 0;
497 /* Terminate this string in d
498 * (which is a copy of parse_dn
499 * with spaces trimmed) */
500 *d++ = '\0';
501 dn->components[dn->comp_num].name = talloc_strdup(dn->components, dt);
502 if ( ! dn->components[dn->comp_num].name) {
503 /* ouch */
504 goto failed;
507 dt = d;
509 p++;
510 continue;
513 if (!isascii(*p)) {
514 /* attr names must be ascii only */
515 ldb_dn_mark_invalid(dn);
516 goto failed;
519 if (is_oid && ( ! (isdigit(*p) || (*p == '.')))) {
520 /* not a digit nor a dot,
521 * invalid attribute oid */
522 ldb_dn_mark_invalid(dn);
523 goto failed;
524 } else
525 if ( ! (isalpha(*p) || isdigit(*p) || (*p == '-'))) {
526 /* not ALPHA, DIGIT or HYPHEN */
527 ldb_dn_mark_invalid(dn);
528 goto failed;
531 *d++ = *p++;
532 continue;
535 if (in_value) {
536 if (in_quote) {
537 if (*p == '\"') {
538 if (p[-1] != '\\') {
539 p++;
540 in_quote = false;
541 continue;
544 *d++ = *p++;
545 l++;
546 continue;
549 if (trim) {
550 if (*p == ' ') {
551 p++;
552 continue;
555 /* first char */
556 trim = false;
558 if (*p == '\"') {
559 in_quote = true;
560 p++;
561 continue;
565 switch (*p) {
567 /* TODO: support ber encoded values
568 case '#':
571 case ',':
572 if (escape) {
573 *d++ = *p++;
574 l++;
575 escape = false;
576 continue;
578 /* ok found value terminator */
580 if ( t ) {
581 /* trim back */
582 d -= (p - t);
583 l -= (p - t);
586 in_attr = true;
587 in_value = false;
588 trim = true;
590 p++;
591 *d++ = '\0';
592 dn->components[dn->comp_num].value.data = (uint8_t *)talloc_strdup(dn->components, dt);
593 dn->components[dn->comp_num].value.length = l;
594 if ( ! dn->components[dn->comp_num].value.data) {
595 /* ouch ! */
596 goto failed;
599 dt = d;
601 dn->comp_num++;
602 if (dn->comp_num > 2) {
603 dn->components = talloc_realloc(dn,
604 dn->components,
605 struct ldb_dn_component,
606 dn->comp_num + 1);
607 if ( ! dn->components) {
608 /* ouch ! */
609 goto failed;
611 /* make sure all components are zeroed, other functions depend on this */
612 memset(&dn->components[dn->comp_num], '\0', sizeof(struct ldb_dn_component));
615 continue;
617 case '+':
618 case '=':
619 /* to main compatibility with earlier
620 versions of ldb indexing, we have to
621 accept the base64 encoded binary index
622 values, which contain a '+' or '='
623 which should normally be escaped */
624 if (is_index) {
625 if ( t ) t = NULL;
626 *d++ = *p++;
627 l++;
628 break;
630 /* fall through */
631 case '\"':
632 case '<':
633 case '>':
634 case ';':
635 /* a string with not escaped specials is invalid (tested) */
636 if ( ! escape) {
637 ldb_dn_mark_invalid(dn);
638 goto failed;
640 escape = false;
642 *d++ = *p++;
643 l++;
645 if ( t ) t = NULL;
646 break;
648 case '\\':
649 if ( ! escape) {
650 escape = true;
651 p++;
652 continue;
654 escape = false;
656 *d++ = *p++;
657 l++;
659 if ( t ) t = NULL;
660 break;
662 default:
663 if (escape) {
664 if (isxdigit(p[0]) && isxdigit(p[1])) {
665 if (sscanf(p, "%02x", &x) != 1) {
666 /* invalid escaping sequence */
667 ldb_dn_mark_invalid(dn);
668 goto failed;
670 p += 2;
671 *d++ = (unsigned char)x;
672 } else {
673 *d++ = *p++;
676 escape = false;
677 l++;
678 if ( t ) t = NULL;
679 break;
682 if (*p == ' ') {
683 if ( ! t) t = p;
684 } else {
685 if ( t ) t = NULL;
688 *d++ = *p++;
689 l++;
691 break;
697 if (in_attr || in_quote) {
698 /* invalid dn */
699 ldb_dn_mark_invalid(dn);
700 goto failed;
703 /* save last element */
704 if ( t ) {
705 /* trim back */
706 d -= (p - t);
707 l -= (p - t);
710 *d++ = '\0';
711 dn->components[dn->comp_num].value.length = l;
712 dn->components[dn->comp_num].value.data =
713 (uint8_t *)talloc_strdup(dn->components, dt);
714 if ( ! dn->components[dn->comp_num].value.data) {
715 /* ouch */
716 goto failed;
719 dn->comp_num++;
721 talloc_free(data);
722 return true;
724 failed:
725 dn->comp_num = 0;
726 talloc_free(dn->components);
727 return false;
730 bool ldb_dn_validate(struct ldb_dn *dn)
732 return ldb_dn_explode(dn);
735 const char *ldb_dn_get_linearized(struct ldb_dn *dn)
737 int i, len;
738 char *d, *n;
740 if ( ! dn || ( dn->invalid)) return NULL;
742 if (dn->linearized) return dn->linearized;
744 if ( ! dn->components) {
745 ldb_dn_mark_invalid(dn);
746 return NULL;
749 if (dn->comp_num == 0) {
750 dn->linearized = talloc_strdup(dn, "");
751 if ( ! dn->linearized) return NULL;
752 return dn->linearized;
755 /* calculate maximum possible length of DN */
756 for (len = 0, i = 0; i < dn->comp_num; i++) {
757 /* name len */
758 len += strlen(dn->components[i].name);
759 /* max escaped data len */
760 len += (dn->components[i].value.length * 3);
761 len += 2; /* '=' and ',' */
763 dn->linearized = talloc_array(dn, char, len);
764 if ( ! dn->linearized) return NULL;
766 d = dn->linearized;
768 for (i = 0; i < dn->comp_num; i++) {
770 /* copy the name */
771 n = dn->components[i].name;
772 while (*n) *d++ = *n++;
774 *d++ = '=';
776 /* and the value */
777 d += ldb_dn_escape_internal( d,
778 (char *)dn->components[i].value.data,
779 dn->components[i].value.length);
780 *d++ = ',';
783 *(--d) = '\0';
785 /* don't waste more memory than necessary */
786 dn->linearized = talloc_realloc(dn, dn->linearized,
787 char, (d - dn->linearized + 1));
789 return dn->linearized;
792 char *ldb_dn_get_extended_linearized(void *mem_ctx, struct ldb_dn *dn, int mode)
794 const char *linearized = ldb_dn_get_linearized(dn);
795 char *p;
796 int i;
798 if (!linearized) {
799 return NULL;
802 if (!ldb_dn_has_extended(dn)) {
803 return talloc_strdup(mem_ctx, linearized);
806 if (!ldb_dn_validate(dn)) {
807 return NULL;
810 for (i = 0; i < dn->ext_comp_num; i++) {
811 const struct ldb_dn_extended_syntax *ext_syntax;
812 const char *name = dn->ext_components[i].name;
813 struct ldb_val ec_val = dn->ext_components[i].value;
814 struct ldb_val val;
815 int ret;
817 ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name);
818 if (!ext_syntax) {
819 return NULL;
822 if (mode == 1) {
823 ret = ext_syntax->write_clear_fn(dn->ldb, mem_ctx,
824 &ec_val, &val);
825 } else if (mode == 0) {
826 ret = ext_syntax->write_hex_fn(dn->ldb, mem_ctx,
827 &ec_val, &val);
828 } else {
829 ret = -1;
832 if (ret != LDB_SUCCESS) {
833 return NULL;
836 if (i == 0) {
837 p = talloc_asprintf(mem_ctx, "<%s=%s>",
838 name, val.data);
839 } else {
840 p = talloc_asprintf_append_buffer(p, ";<%s=%s>",
841 name, val.data);
844 talloc_free(val.data);
846 if (!p) {
847 return NULL;
851 if (dn->ext_comp_num && *linearized) {
852 p = talloc_asprintf_append_buffer(p, ";%s", linearized);
855 if (!p) {
856 return NULL;
859 return p;
864 char *ldb_dn_alloc_linearized(void *mem_ctx, struct ldb_dn *dn)
866 return talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn));
870 casefold a dn. We need to casefold the attribute names, and canonicalize
871 attribute values of case insensitive attributes.
874 static bool ldb_dn_casefold_internal(struct ldb_dn *dn)
876 int i, ret;
878 if ( ! dn || dn->invalid) return false;
880 if (dn->valid_case) return true;
882 if (( ! dn->components) && ( ! ldb_dn_explode(dn))) {
883 return false;
886 for (i = 0; i < dn->comp_num; i++) {
887 const struct ldb_schema_attribute *a;
889 dn->components[i].cf_name =
890 ldb_attr_casefold(dn->components,
891 dn->components[i].name);
892 if (!dn->components[i].cf_name) {
893 goto failed;
896 a = ldb_schema_attribute_by_name(dn->ldb,
897 dn->components[i].cf_name);
899 ret = a->syntax->canonicalise_fn(dn->ldb, dn->components,
900 &(dn->components[i].value),
901 &(dn->components[i].cf_value));
902 if (ret != 0) {
903 goto failed;
907 dn->valid_case = true;
909 return true;
911 failed:
912 for (i = 0; i < dn->comp_num; i++) {
913 LDB_FREE(dn->components[i].cf_name);
914 LDB_FREE(dn->components[i].cf_value.data);
916 return false;
919 const char *ldb_dn_get_casefold(struct ldb_dn *dn)
921 int i, len;
922 char *d, *n;
924 if (dn->casefold) return dn->casefold;
926 if (dn->special) {
927 dn->casefold = talloc_strdup(dn, dn->linearized);
928 if (!dn->casefold) return NULL;
929 dn->valid_case = true;
930 return dn->casefold;
933 if ( ! ldb_dn_casefold_internal(dn)) {
934 return NULL;
937 if (dn->comp_num == 0) {
938 dn->casefold = talloc_strdup(dn, "");
939 return dn->casefold;
942 /* calculate maximum possible length of DN */
943 for (len = 0, i = 0; i < dn->comp_num; i++) {
944 /* name len */
945 len += strlen(dn->components[i].cf_name);
946 /* max escaped data len */
947 len += (dn->components[i].cf_value.length * 3);
948 len += 2; /* '=' and ',' */
950 dn->casefold = talloc_array(dn, char, len);
951 if ( ! dn->casefold) return NULL;
953 d = dn->casefold;
955 for (i = 0; i < dn->comp_num; i++) {
957 /* copy the name */
958 n = dn->components[i].cf_name;
959 while (*n) *d++ = *n++;
961 *d++ = '=';
963 /* and the value */
964 d += ldb_dn_escape_internal( d,
965 (char *)dn->components[i].cf_value.data,
966 dn->components[i].cf_value.length);
967 *d++ = ',';
969 *(--d) = '\0';
971 /* don't waste more memory than necessary */
972 dn->casefold = talloc_realloc(dn, dn->casefold,
973 char, strlen(dn->casefold) + 1);
975 return dn->casefold;
978 char *ldb_dn_alloc_casefold(void *mem_ctx, struct ldb_dn *dn)
980 return talloc_strdup(mem_ctx, ldb_dn_get_casefold(dn));
983 /* Determine if dn is below base, in the ldap tree. Used for
984 * evaluating a subtree search.
985 * 0 if they match, otherwise non-zero
988 int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn)
990 int ret;
991 int n_base, n_dn;
993 if ( ! base || base->invalid) return 1;
994 if ( ! dn || dn->invalid) return -1;
996 if (( ! base->valid_case) || ( ! dn->valid_case)) {
997 if (base->linearized && dn->linearized) {
998 /* try with a normal compare first, if we are lucky
999 * we will avoid exploding and casfolding */
1000 int dif;
1001 dif = strlen(dn->linearized) - strlen(base->linearized);
1002 if (dif < 0) {
1003 return dif;
1005 if (strcmp(base->linearized,
1006 &dn->linearized[dif]) == 0) {
1007 return 0;
1011 if ( ! ldb_dn_casefold_internal(base)) {
1012 return 1;
1015 if ( ! ldb_dn_casefold_internal(dn)) {
1016 return -1;
1021 /* if base has more components,
1022 * they don't have the same base */
1023 if (base->comp_num > dn->comp_num) {
1024 return (dn->comp_num - base->comp_num);
1027 if (dn->comp_num == 0) {
1028 if (dn->special && base->special) {
1029 return strcmp(base->linearized, dn->linearized);
1030 } else if (dn->special) {
1031 return -1;
1032 } else if (base->special) {
1033 return 1;
1034 } else {
1035 return 0;
1039 n_base = base->comp_num - 1;
1040 n_dn = dn->comp_num - 1;
1042 while (n_base >= 0) {
1043 char *b_name = base->components[n_base].cf_name;
1044 char *dn_name = dn->components[n_dn].cf_name;
1046 char *b_vdata = (char *)base->components[n_base].cf_value.data;
1047 char *dn_vdata = (char *)dn->components[n_dn].cf_value.data;
1049 size_t b_vlen = base->components[n_base].cf_value.length;
1050 size_t dn_vlen = dn->components[n_dn].cf_value.length;
1052 /* compare attr names */
1053 ret = strcmp(b_name, dn_name);
1054 if (ret != 0) return ret;
1056 /* compare attr.cf_value. */
1057 if (b_vlen != dn_vlen) {
1058 return b_vlen - dn_vlen;
1060 ret = strcmp(b_vdata, dn_vdata);
1061 if (ret != 0) return ret;
1063 n_base--;
1064 n_dn--;
1067 return 0;
1070 /* compare DNs using casefolding compare functions.
1072 If they match, then return 0
1075 int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1)
1077 int i, ret;
1079 if (( ! dn0) || dn0->invalid || ! dn1 || dn1->invalid) {
1080 return -1;
1083 if (( ! dn0->valid_case) || ( ! dn1->valid_case)) {
1084 if (dn0->linearized && dn1->linearized) {
1085 /* try with a normal compare first, if we are lucky
1086 * we will avoid exploding and casfolding */
1087 if (strcmp(dn0->linearized, dn1->linearized) == 0) {
1088 return 0;
1092 if ( ! ldb_dn_casefold_internal(dn0)) {
1093 return 1;
1096 if ( ! ldb_dn_casefold_internal(dn1)) {
1097 return -1;
1102 if (dn0->comp_num != dn1->comp_num) {
1103 return (dn1->comp_num - dn0->comp_num);
1106 if (dn0->comp_num == 0) {
1107 if (dn0->special && dn1->special) {
1108 return strcmp(dn0->linearized, dn1->linearized);
1109 } else if (dn0->special) {
1110 return 1;
1111 } else if (dn1->special) {
1112 return -1;
1113 } else {
1114 return 0;
1118 for (i = 0; i < dn0->comp_num; i++) {
1119 char *dn0_name = dn0->components[i].cf_name;
1120 char *dn1_name = dn1->components[i].cf_name;
1122 char *dn0_vdata = (char *)dn0->components[i].cf_value.data;
1123 char *dn1_vdata = (char *)dn1->components[i].cf_value.data;
1125 size_t dn0_vlen = dn0->components[i].cf_value.length;
1126 size_t dn1_vlen = dn1->components[i].cf_value.length;
1128 /* compare attr names */
1129 ret = strcmp(dn0_name, dn1_name);
1130 if (ret != 0) {
1131 return ret;
1134 /* compare attr.cf_value. */
1135 if (dn0_vlen != dn1_vlen) {
1136 return dn0_vlen - dn1_vlen;
1138 ret = strcmp(dn0_vdata, dn1_vdata);
1139 if (ret != 0) {
1140 return ret;
1144 return 0;
1147 static struct ldb_dn_component ldb_dn_copy_component(
1148 void *mem_ctx,
1149 struct ldb_dn_component *src)
1151 struct ldb_dn_component dst;
1153 memset(&dst, 0, sizeof(dst));
1155 if (src == NULL) {
1156 return dst;
1159 dst.value = ldb_val_dup(mem_ctx, &(src->value));
1160 if (dst.value.data == NULL) {
1161 return dst;
1164 dst.name = talloc_strdup(mem_ctx, src->name);
1165 if (dst.name == NULL) {
1166 LDB_FREE(dst.value.data);
1167 return dst;
1170 if (src->cf_value.data) {
1171 dst.cf_value = ldb_val_dup(mem_ctx, &(src->cf_value));
1172 if (dst.cf_value.data == NULL) {
1173 LDB_FREE(dst.value.data);
1174 LDB_FREE(dst.name);
1175 return dst;
1178 dst.cf_name = talloc_strdup(mem_ctx, src->cf_name);
1179 if (dst.cf_name == NULL) {
1180 LDB_FREE(dst.cf_name);
1181 LDB_FREE(dst.value.data);
1182 LDB_FREE(dst.name);
1183 return dst;
1185 } else {
1186 dst.cf_value.data = NULL;
1187 dst.cf_name = NULL;
1190 return dst;
1193 static struct ldb_dn_ext_component ldb_dn_ext_copy_component(
1194 void *mem_ctx,
1195 struct ldb_dn_ext_component *src)
1197 struct ldb_dn_ext_component dst;
1199 memset(&dst, 0, sizeof(dst));
1201 if (src == NULL) {
1202 return dst;
1205 dst.value = ldb_val_dup(mem_ctx, &(src->value));
1206 if (dst.value.data == NULL) {
1207 return dst;
1210 dst.name = talloc_strdup(mem_ctx, src->name);
1211 if (dst.name == NULL) {
1212 LDB_FREE(dst.value.data);
1213 return dst;
1216 return dst;
1219 struct ldb_dn *ldb_dn_copy(void *mem_ctx, struct ldb_dn *dn)
1221 struct ldb_dn *new_dn;
1223 if (!dn || dn->invalid) {
1224 return NULL;
1227 new_dn = talloc_zero(mem_ctx, struct ldb_dn);
1228 if ( !new_dn) {
1229 return NULL;
1232 *new_dn = *dn;
1234 if (dn->components) {
1235 int i;
1237 new_dn->components =
1238 talloc_zero_array(new_dn,
1239 struct ldb_dn_component,
1240 dn->comp_num);
1241 if ( ! new_dn->components) {
1242 talloc_free(new_dn);
1243 return NULL;
1246 for (i = 0; i < dn->comp_num; i++) {
1247 new_dn->components[i] =
1248 ldb_dn_copy_component(new_dn->components,
1249 &dn->components[i]);
1250 if ( ! new_dn->components[i].value.data) {
1251 talloc_free(new_dn);
1252 return NULL;
1257 if (dn->ext_components) {
1258 int i;
1260 new_dn->ext_components =
1261 talloc_zero_array(new_dn,
1262 struct ldb_dn_ext_component,
1263 dn->ext_comp_num);
1264 if ( ! new_dn->ext_components) {
1265 talloc_free(new_dn);
1266 return NULL;
1269 for (i = 0; i < dn->ext_comp_num; i++) {
1270 new_dn->ext_components[i] =
1271 ldb_dn_ext_copy_component(
1272 new_dn->ext_components,
1273 &dn->ext_components[i]);
1274 if ( ! new_dn->ext_components[i].value.data) {
1275 talloc_free(new_dn);
1276 return NULL;
1281 if (dn->casefold) {
1282 new_dn->casefold = talloc_strdup(new_dn, dn->casefold);
1283 if ( ! new_dn->casefold) {
1284 talloc_free(new_dn);
1285 return NULL;
1289 if (dn->linearized) {
1290 new_dn->linearized = talloc_strdup(new_dn, dn->linearized);
1291 if ( ! new_dn->linearized) {
1292 talloc_free(new_dn);
1293 return NULL;
1297 if (dn->ext_linearized) {
1298 new_dn->ext_linearized = talloc_strdup(new_dn,
1299 dn->ext_linearized);
1300 if ( ! new_dn->ext_linearized) {
1301 talloc_free(new_dn);
1302 return NULL;
1306 return new_dn;
1309 /* modify the given dn by adding a base.
1311 * return true if successful and false if not
1312 * if false is returned the dn may be marked invalid
1314 bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base)
1316 const char *s;
1317 char *t;
1319 if ( !base || base->invalid || !dn || dn->invalid) {
1320 return false;
1323 if (dn->components) {
1324 int i;
1326 if ( ! ldb_dn_validate(base)) {
1327 return false;
1330 s = NULL;
1331 if (dn->valid_case) {
1332 if ( ! (s = ldb_dn_get_casefold(base))) {
1333 return false;
1337 dn->components = talloc_realloc(dn,
1338 dn->components,
1339 struct ldb_dn_component,
1340 dn->comp_num + base->comp_num);
1341 if ( ! dn->components) {
1342 ldb_dn_mark_invalid(dn);
1343 return false;
1346 for (i = 0; i < base->comp_num; dn->comp_num++, i++) {
1347 dn->components[dn->comp_num] =
1348 ldb_dn_copy_component(dn->components,
1349 &base->components[i]);
1350 if (dn->components[dn->comp_num].value.data == NULL) {
1351 ldb_dn_mark_invalid(dn);
1352 return false;
1356 if (dn->casefold && s) {
1357 if (*dn->casefold) {
1358 t = talloc_asprintf(dn, "%s,%s",
1359 dn->casefold, s);
1360 } else {
1361 t = talloc_strdup(dn, s);
1363 LDB_FREE(dn->casefold);
1364 dn->casefold = t;
1368 if (dn->linearized) {
1370 s = ldb_dn_get_linearized(base);
1371 if ( ! s) {
1372 return false;
1375 if (*dn->linearized) {
1376 t = talloc_asprintf(dn, "%s,%s",
1377 dn->linearized, s);
1378 } else {
1379 t = talloc_strdup(dn, s);
1381 if ( ! t) {
1382 ldb_dn_mark_invalid(dn);
1383 return false;
1385 LDB_FREE(dn->linearized);
1386 dn->linearized = t;
1389 /* Wipe the ext_linearized DN,
1390 * the GUID and SID are almost certainly no longer valid */
1391 if (dn->ext_linearized) {
1392 LDB_FREE(dn->ext_linearized);
1395 LDB_FREE(dn->ext_components);
1396 dn->ext_comp_num = 0;
1397 return true;
1400 /* modify the given dn by adding a base.
1402 * return true if successful and false if not
1403 * if false is returned the dn may be marked invalid
1405 bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...)
1407 struct ldb_dn *base;
1408 char *base_str;
1409 va_list ap;
1410 bool ret;
1412 if ( !dn || dn->invalid) {
1413 return false;
1416 va_start(ap, base_fmt);
1417 base_str = talloc_vasprintf(dn, base_fmt, ap);
1418 va_end(ap);
1420 if (base_str == NULL) {
1421 return false;
1424 base = ldb_dn_new(base_str, dn->ldb, base_str);
1426 ret = ldb_dn_add_base(dn, base);
1428 talloc_free(base_str);
1430 return ret;
1433 /* modify the given dn by adding children elements.
1435 * return true if successful and false if not
1436 * if false is returned the dn may be marked invalid
1438 bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child)
1440 const char *s;
1441 char *t;
1443 if ( !child || child->invalid || !dn || dn->invalid) {
1444 return false;
1447 if (dn->components) {
1448 int n, i, j;
1450 if ( ! ldb_dn_validate(child)) {
1451 return false;
1454 s = NULL;
1455 if (dn->valid_case) {
1456 if ( ! (s = ldb_dn_get_casefold(child))) {
1457 return false;
1461 n = dn->comp_num + child->comp_num;
1463 dn->components = talloc_realloc(dn,
1464 dn->components,
1465 struct ldb_dn_component,
1467 if ( ! dn->components) {
1468 ldb_dn_mark_invalid(dn);
1469 return false;
1472 for (i = dn->comp_num - 1, j = n - 1; i >= 0; i--, j--) {
1473 dn->components[j] = dn->components[i];
1476 for (i = 0; i < child->comp_num; i++) {
1477 dn->components[i] =
1478 ldb_dn_copy_component(dn->components,
1479 &child->components[i]);
1480 if (dn->components[i].value.data == NULL) {
1481 ldb_dn_mark_invalid(dn);
1482 return false;
1486 dn->comp_num = n;
1488 if (dn->casefold && s) {
1489 t = talloc_asprintf(dn, "%s,%s", s, dn->casefold);
1490 LDB_FREE(dn->casefold);
1491 dn->casefold = t;
1495 if (dn->linearized) {
1497 s = ldb_dn_get_linearized(child);
1498 if ( ! s) {
1499 return false;
1502 t = talloc_asprintf(dn, "%s,%s", s, dn->linearized);
1503 if ( ! t) {
1504 ldb_dn_mark_invalid(dn);
1505 return false;
1507 LDB_FREE(dn->linearized);
1508 dn->linearized = t;
1511 /* Wipe the ext_linearized DN,
1512 * the GUID and SID are almost certainly no longer valid */
1513 LDB_FREE(dn->ext_linearized);
1515 LDB_FREE(dn->ext_components);
1516 dn->ext_comp_num = 0;
1518 return true;
1521 /* modify the given dn by adding children elements.
1523 * return true if successful and false if not
1524 * if false is returned the dn may be marked invalid
1526 bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...)
1528 struct ldb_dn *child;
1529 char *child_str;
1530 va_list ap;
1531 bool ret;
1533 if ( !dn || dn->invalid) {
1534 return false;
1537 va_start(ap, child_fmt);
1538 child_str = talloc_vasprintf(dn, child_fmt, ap);
1539 va_end(ap);
1541 if (child_str == NULL) {
1542 return false;
1545 child = ldb_dn_new(child_str, dn->ldb, child_str);
1547 ret = ldb_dn_add_child(dn, child);
1549 talloc_free(child_str);
1551 return ret;
1554 bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num)
1556 int i;
1558 if ( ! ldb_dn_validate(dn)) {
1559 return false;
1562 if (dn->comp_num < num) {
1563 return false;
1566 /* free components */
1567 for (i = num; i > 0; i--) {
1568 LDB_FREE(dn->components[dn->comp_num - i].name);
1569 LDB_FREE(dn->components[dn->comp_num - i].value.data);
1570 LDB_FREE(dn->components[dn->comp_num - i].cf_name);
1571 LDB_FREE(dn->components[dn->comp_num - i].cf_value.data);
1574 dn->comp_num -= num;
1576 if (dn->valid_case) {
1577 for (i = 0; i < dn->comp_num; i++) {
1578 LDB_FREE(dn->components[i].cf_name);
1579 LDB_FREE(dn->components[i].cf_value.data);
1581 dn->valid_case = false;
1584 LDB_FREE(dn->casefold);
1585 LDB_FREE(dn->linearized);
1587 /* Wipe the ext_linearized DN,
1588 * the GUID and SID are almost certainly no longer valid */
1589 LDB_FREE(dn->ext_linearized);
1591 LDB_FREE(dn->ext_components);
1592 dn->ext_comp_num = 0;
1594 return true;
1597 bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num)
1599 int i, j;
1601 if ( ! ldb_dn_validate(dn)) {
1602 return false;
1605 if (dn->comp_num < num) {
1606 return false;
1609 for (i = 0, j = num; j < dn->comp_num; i++, j++) {
1610 if (i < num) {
1611 LDB_FREE(dn->components[i].name);
1612 LDB_FREE(dn->components[i].value.data);
1613 LDB_FREE(dn->components[i].cf_name);
1614 LDB_FREE(dn->components[i].cf_value.data);
1616 dn->components[i] = dn->components[j];
1619 dn->comp_num -= num;
1621 if (dn->valid_case) {
1622 for (i = 0; i < dn->comp_num; i++) {
1623 LDB_FREE(dn->components[i].cf_name);
1624 LDB_FREE(dn->components[i].cf_value.data);
1626 dn->valid_case = false;
1629 LDB_FREE(dn->casefold);
1630 LDB_FREE(dn->linearized);
1632 /* Wipe the ext_linearized DN,
1633 * the GUID and SID are almost certainly no longer valid */
1634 LDB_FREE(dn->ext_linearized);
1636 LDB_FREE(dn->ext_components);
1637 dn->ext_comp_num = 0;
1638 return true;
1641 struct ldb_dn *ldb_dn_get_parent(void *mem_ctx, struct ldb_dn *dn)
1643 struct ldb_dn *new_dn;
1645 new_dn = ldb_dn_copy(mem_ctx, dn);
1646 if ( !new_dn ) {
1647 return NULL;
1650 if ( ! ldb_dn_remove_child_components(new_dn, 1)) {
1651 talloc_free(new_dn);
1652 return NULL;
1655 /* Wipe the ext_linearized DN,
1656 * the GUID and SID are almost certainly no longer valid */
1657 LDB_FREE(dn->ext_linearized);
1659 LDB_FREE(dn->ext_components);
1660 dn->ext_comp_num = 0;
1661 return new_dn;
1664 /* Create a 'canonical name' string from a DN:
1666 ie dc=samba,dc=org -> samba.org/
1667 uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator
1669 There are two formats,
1670 the EX format has the last '/' replaced with a newline (\n).
1673 static char *ldb_dn_canonical(void *mem_ctx, struct ldb_dn *dn, int ex_format) {
1674 int i;
1675 TALLOC_CTX *tmpctx;
1676 char *cracked = NULL;
1677 const char *format = (ex_format ? "\n" : "/" );
1679 if ( ! ldb_dn_validate(dn)) {
1680 return NULL;
1683 tmpctx = talloc_new(mem_ctx);
1685 /* Walk backwards down the DN, grabbing 'dc' components at first */
1686 for (i = dn->comp_num - 1 ; i >= 0; i--) {
1687 if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) {
1688 break;
1690 if (cracked) {
1691 cracked = talloc_asprintf(tmpctx, "%s.%s",
1692 ldb_dn_escape_value(tmpctx,
1693 dn->components[i].value),
1694 cracked);
1695 } else {
1696 cracked = ldb_dn_escape_value(tmpctx,
1697 dn->components[i].value);
1699 if (!cracked) {
1700 goto done;
1704 /* Only domain components? Finish here */
1705 if (i < 0) {
1706 cracked = talloc_strdup_append_buffer(cracked, format);
1707 talloc_steal(mem_ctx, cracked);
1708 goto done;
1711 /* Now walk backwards appending remaining components */
1712 for (; i > 0; i--) {
1713 cracked = talloc_asprintf_append_buffer(cracked, "/%s",
1714 ldb_dn_escape_value(tmpctx,
1715 dn->components[i].value));
1716 if (!cracked) {
1717 goto done;
1721 /* Last one, possibly a newline for the 'ex' format */
1722 cracked = talloc_asprintf_append_buffer(cracked, "%s%s", format,
1723 ldb_dn_escape_value(tmpctx,
1724 dn->components[i].value));
1726 talloc_steal(mem_ctx, cracked);
1727 done:
1728 talloc_free(tmpctx);
1729 return cracked;
1732 /* Wrapper functions for the above, for the two different string formats */
1733 char *ldb_dn_canonical_string(void *mem_ctx, struct ldb_dn *dn) {
1734 return ldb_dn_canonical(mem_ctx, dn, 0);
1738 char *ldb_dn_canonical_ex_string(void *mem_ctx, struct ldb_dn *dn) {
1739 return ldb_dn_canonical(mem_ctx, dn, 1);
1742 int ldb_dn_get_comp_num(struct ldb_dn *dn)
1744 if ( ! ldb_dn_validate(dn)) {
1745 return -1;
1747 return dn->comp_num;
1750 const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num)
1752 if ( ! ldb_dn_validate(dn)) {
1753 return NULL;
1755 if (num >= dn->comp_num) return NULL;
1756 return dn->components[num].name;
1759 const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn,
1760 unsigned int num)
1762 if ( ! ldb_dn_validate(dn)) {
1763 return NULL;
1765 if (num >= dn->comp_num) return NULL;
1766 return &dn->components[num].value;
1769 const char *ldb_dn_get_rdn_name(struct ldb_dn *dn)
1771 if ( ! ldb_dn_validate(dn)) {
1772 return NULL;
1774 if (dn->comp_num == 0) return NULL;
1775 return dn->components[0].name;
1778 const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn)
1780 if ( ! ldb_dn_validate(dn)) {
1781 return NULL;
1783 if (dn->comp_num == 0) return NULL;
1784 return &dn->components[0].value;
1787 int ldb_dn_set_component(struct ldb_dn *dn, int num,
1788 const char *name, const struct ldb_val val)
1790 char *n;
1791 struct ldb_val v;
1793 if ( ! ldb_dn_validate(dn)) {
1794 return LDB_ERR_OTHER;
1797 if (num >= dn->comp_num) {
1798 return LDB_ERR_OTHER;
1801 n = talloc_strdup(dn, name);
1802 if ( ! n) {
1803 return LDB_ERR_OTHER;
1806 v.length = val.length;
1807 v.data = (uint8_t *)talloc_memdup(dn, val.data, v.length+1);
1808 if ( ! v.data) {
1809 talloc_free(n);
1810 return LDB_ERR_OTHER;
1813 talloc_free(dn->components[num].name);
1814 talloc_free(dn->components[num].value.data);
1815 dn->components[num].name = n;
1816 dn->components[num].value = v;
1818 if (dn->valid_case) {
1819 int i;
1820 for (i = 0; i < dn->comp_num; i++) {
1821 LDB_FREE(dn->components[i].cf_name);
1822 LDB_FREE(dn->components[i].cf_value.data);
1824 dn->valid_case = false;
1826 LDB_FREE(dn->casefold);
1827 LDB_FREE(dn->linearized);
1829 /* Wipe the ext_linearized DN,
1830 * the GUID and SID are almost certainly no longer valid */
1831 LDB_FREE(dn->ext_linearized);
1833 dn->ext_comp_num = 0;
1834 LDB_FREE(dn->ext_components);
1835 return LDB_SUCCESS;
1838 const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn,
1839 const char *name)
1841 int i;
1842 if ( ! ldb_dn_validate(dn)) {
1843 return NULL;
1845 for (i=0; i < dn->ext_comp_num; i++) {
1846 if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) {
1847 return &dn->ext_components[i].value;
1850 return NULL;
1853 int ldb_dn_set_extended_component(struct ldb_dn *dn,
1854 const char *name, const struct ldb_val *val)
1856 struct ldb_dn_ext_component *p;
1857 int i;
1859 if ( ! ldb_dn_validate(dn)) {
1860 return LDB_ERR_OTHER;
1863 if (!ldb_dn_extended_syntax_by_name(dn->ldb, name)) {
1864 /* We don't know how to handle this type of thing */
1865 return LDB_ERR_INVALID_DN_SYNTAX;
1868 for (i=0; i < dn->ext_comp_num; i++) {
1869 if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) {
1870 if (val) {
1871 dn->ext_components[i].value =
1872 ldb_val_dup(dn->ext_components, val);
1874 dn->ext_components[i].name =
1875 talloc_strdup(dn->ext_components, name);
1876 if (!dn->ext_components[i].name ||
1877 !dn->ext_components[i].value.data) {
1878 ldb_dn_mark_invalid(dn);
1879 return LDB_ERR_OPERATIONS_ERROR;
1882 } else {
1883 if (i != (dn->ext_comp_num - 1)) {
1884 memmove(&dn->ext_components[i],
1885 &dn->ext_components[i+1],
1886 ((dn->ext_comp_num-1) - i) *
1887 sizeof(*dn->ext_components));
1889 dn->ext_comp_num--;
1891 dn->ext_components = talloc_realloc(dn,
1892 dn->ext_components,
1893 struct ldb_dn_ext_component,
1894 dn->ext_comp_num);
1895 if (!dn->ext_components) {
1896 ldb_dn_mark_invalid(dn);
1897 return LDB_ERR_OPERATIONS_ERROR;
1899 return LDB_SUCCESS;
1904 p = dn->ext_components
1905 = talloc_realloc(dn,
1906 dn->ext_components,
1907 struct ldb_dn_ext_component,
1908 dn->ext_comp_num + 1);
1909 if (!dn->ext_components) {
1910 ldb_dn_mark_invalid(dn);
1911 return LDB_ERR_OPERATIONS_ERROR;
1914 p[dn->ext_comp_num].value = ldb_val_dup(dn->ext_components, val);
1915 p[dn->ext_comp_num].name = talloc_strdup(p, name);
1917 if (!dn->ext_components[i].name || !dn->ext_components[i].value.data) {
1918 ldb_dn_mark_invalid(dn);
1919 return LDB_ERR_OPERATIONS_ERROR;
1921 dn->ext_components = p;
1922 dn->ext_comp_num++;
1924 return LDB_SUCCESS;
1927 void ldb_dn_remove_extended_components(struct ldb_dn *dn)
1929 dn->ext_comp_num = 0;
1930 LDB_FREE(dn->ext_components);
1933 bool ldb_dn_is_valid(struct ldb_dn *dn)
1935 if ( ! dn) return false;
1936 return ! dn->invalid;
1939 bool ldb_dn_is_special(struct ldb_dn *dn)
1941 if ( ! dn || dn->invalid) return false;
1942 return dn->special;
1945 bool ldb_dn_has_extended(struct ldb_dn *dn)
1947 if ( ! dn || dn->invalid) return false;
1948 if (dn->ext_linearized && (dn->ext_linearized[0] == '<')) return true;
1949 return dn->ext_comp_num != 0;
1952 bool ldb_dn_check_special(struct ldb_dn *dn, const char *check)
1954 if ( ! dn || dn->invalid) return false;
1955 return ! strcmp(dn->linearized, check);
1958 bool ldb_dn_is_null(struct ldb_dn *dn)
1960 if ( ! dn || dn->invalid) return false;
1961 if (ldb_dn_has_extended(dn)) return false;
1962 if (dn->linearized && (dn->linearized[0] == '\0')) return true;
1963 return false;