s4:ldb_dn: fix an uninitialized variable (found by make valgrindtest)
[Samba/cd1.git] / source4 / lib / ldb / common / ldb_dn.c
blob04e769f031da5e29dc452016ac35a8e03af687e7
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 = talloc_get_type(ldb, struct ldb_context);
107 if (dn->ldb == NULL) {
108 /* the caller probably got the arguments to
109 ldb_dn_new() mixed up */
110 talloc_free(dn);
111 return NULL;
114 if (strdn->data && strdn->length) {
115 const char *data = (const char *)strdn->data;
116 size_t length = strdn->length;
118 if (data[0] == '@') {
119 dn->special = true;
121 dn->ext_linearized = talloc_strndup(dn, data, length);
122 LDB_DN_NULL_FAILED(dn->ext_linearized);
124 if (data[0] == '<') {
125 const char *p_save, *p = dn->ext_linearized;
126 do {
127 p_save = p;
128 p = strstr(p, ">;");
129 if (p) {
130 p = p + 2;
132 } while (p);
134 if (p_save == dn->ext_linearized) {
135 dn->linearized = talloc_strdup(dn, "");
136 } else {
137 dn->linearized = talloc_strdup(dn, p_save);
139 LDB_DN_NULL_FAILED(dn->linearized);
140 } else {
141 dn->linearized = dn->ext_linearized;
142 dn->ext_linearized = NULL;
144 } else {
145 dn->linearized = talloc_strdup(dn, "");
146 LDB_DN_NULL_FAILED(dn->linearized);
149 return dn;
151 failed:
152 talloc_free(dn);
153 return NULL;
156 /* strdn may be NULL */
157 struct ldb_dn *ldb_dn_new(void *mem_ctx,
158 struct ldb_context *ldb,
159 const char *strdn)
161 struct ldb_val blob;
162 blob.data = discard_const_p(uint8_t, strdn);
163 blob.length = strdn ? strlen(strdn) : 0;
164 return ldb_dn_from_ldb_val(mem_ctx, ldb, &blob);
167 struct ldb_dn *ldb_dn_new_fmt(void *mem_ctx,
168 struct ldb_context *ldb,
169 const char *new_fmt, ...)
171 char *strdn;
172 va_list ap;
174 if ( (! mem_ctx) || (! ldb)) return NULL;
176 va_start(ap, new_fmt);
177 strdn = talloc_vasprintf(mem_ctx, new_fmt, ap);
178 va_end(ap);
180 if (strdn) {
181 struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb, strdn);
182 talloc_free(strdn);
183 return dn;
186 return NULL;
189 /* see RFC2253 section 2.4 */
190 static int ldb_dn_escape_internal(char *dst, const char *src, int len)
192 const char *p, *s;
193 char *d;
194 int l;
196 p = s = src;
197 d = dst;
199 while (p - src < len) {
200 p += strcspn(p, ",=\n\r+<>#;\\\" ");
202 if (p - src == len) /* found no escapable chars */
203 break;
205 /* copy the part of the string before the stop */
206 memcpy(d, s, p - s);
207 d += (p - s); /* move to current position */
209 switch (*p) {
210 case ' ':
211 if (p == src || (p-src)==(len-1)) {
212 /* if at the beginning or end
213 * of the string then escape */
214 *d++ = '\\';
215 *d++ = *p++;
216 } else {
217 /* otherwise don't escape */
218 *d++ = *p++;
220 break;
222 case '#':
223 /* despite the RFC, windows escapes a #
224 anywhere in the string */
225 case ',':
226 case '+':
227 case '"':
228 case '\\':
229 case '<':
230 case '>':
231 case '?':
232 /* these must be escaped using \c form */
233 *d++ = '\\';
234 *d++ = *p++;
235 break;
237 default: {
238 /* any others get \XX form */
239 unsigned char v;
240 const char *hexbytes = "0123456789ABCDEF";
241 v = *(const unsigned char *)p;
242 *d++ = '\\';
243 *d++ = hexbytes[v>>4];
244 *d++ = hexbytes[v&0xF];
245 p++;
246 break;
249 s = p; /* move forward */
252 /* copy the last part (with zero) and return */
253 l = len - (s - src);
254 memcpy(d, s, l + 1);
256 /* return the length of the resulting string */
257 return (l + (d - dst));
260 char *ldb_dn_escape_value(void *mem_ctx, struct ldb_val value)
262 char *dst;
264 if (!value.length)
265 return NULL;
267 /* allocate destination string, it will be at most 3 times the source */
268 dst = talloc_array(mem_ctx, char, value.length * 3 + 1);
269 if ( ! dst) {
270 talloc_free(dst);
271 return NULL;
274 ldb_dn_escape_internal(dst, (const char *)value.data, value.length);
276 dst = talloc_realloc(mem_ctx, dst, char, strlen(dst) + 1);
278 return dst;
282 explode a DN string into a ldb_dn structure
283 based on RFC4514 except that we don't support multiple valued RDNs
285 TODO: according to MS-ADTS:3.1.1.5.2 Naming Constraints
286 DN must be compliant with RFC2253
288 static bool ldb_dn_explode(struct ldb_dn *dn)
290 char *p, *ex_name, *ex_value, *data, *d, *dt, *t;
291 bool trim = false;
292 bool in_extended = false;
293 bool in_ex_name = false;
294 bool in_ex_value = false;
295 bool in_attr = false;
296 bool in_value = false;
297 bool in_quote = false;
298 bool is_oid = false;
299 bool escape = false;
300 unsigned x;
301 int l, ret;
302 char *parse_dn;
303 bool is_index;
305 if ( ! dn || dn->invalid) return false;
307 if (dn->components) {
308 return true;
311 if (dn->ext_linearized) {
312 parse_dn = dn->ext_linearized;
313 } else {
314 parse_dn = dn->linearized;
317 if ( ! parse_dn ) {
318 return false;
321 is_index = (strncmp(parse_dn, "DN=@INDEX:", 10) == 0);
323 /* Empty DNs */
324 if (parse_dn[0] == '\0') {
325 return true;
328 /* Special DNs case */
329 if (dn->special) {
330 return true;
333 /* make sure we free this if alloced previously before replacing */
334 talloc_free(dn->components);
336 LDB_FREE(dn->ext_components);
337 dn->ext_comp_num = 0;
339 /* in the common case we have 3 or more components */
340 /* make sure all components are zeroed, other functions depend on it */
341 dn->components = talloc_zero_array(dn, struct ldb_dn_component, 3);
342 if ( ! dn->components) {
343 return false;
345 dn->comp_num = 0;
347 /* Components data space is allocated here once */
348 data = talloc_array(dn->components, char, strlen(parse_dn) + 1);
349 if (!data) {
350 return false;
353 p = parse_dn;
354 in_extended = true;
355 in_ex_name = false;
356 in_ex_value = false;
357 trim = true;
358 t = NULL;
359 d = dt = data;
361 while (*p) {
362 if (in_extended) {
364 if (!in_ex_name && !in_ex_value) {
366 if (p[0] == '<') {
367 p++;
368 ex_name = d;
369 in_ex_name = true;
370 continue;
371 } else if (p[0] == '\0') {
372 p++;
373 continue;
374 } else {
375 in_extended = false;
376 in_attr = true;
377 dt = d;
379 continue;
383 if (in_ex_name && *p == '=') {
384 *d++ = '\0';
385 p++;
386 ex_value = d;
387 in_ex_name = false;
388 in_ex_value = true;
389 continue;
392 if (in_ex_value && *p == '>') {
393 const struct ldb_dn_extended_syntax *ext_syntax;
394 struct ldb_val ex_val = {
395 .data = (uint8_t *)ex_value,
396 .length = d - ex_value
399 *d++ = '\0';
400 p++;
401 in_ex_value = false;
403 /* Process name and ex_value */
405 dn->ext_components = talloc_realloc(dn,
406 dn->ext_components,
407 struct ldb_dn_ext_component,
408 dn->ext_comp_num + 1);
409 if ( ! dn->ext_components) {
410 /* ouch ! */
411 goto failed;
414 ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, ex_name);
415 if (!ext_syntax) {
416 /* We don't know about this type of extended DN */
417 goto failed;
420 dn->ext_components[dn->ext_comp_num].name = talloc_strdup(dn->ext_components, ex_name);
421 if (!dn->ext_components[dn->ext_comp_num].name) {
422 /* ouch */
423 goto failed;
425 ret = ext_syntax->read_fn(dn->ldb, dn->ext_components,
426 &ex_val, &dn->ext_components[dn->ext_comp_num].value);
427 if (ret != LDB_SUCCESS) {
428 ldb_dn_mark_invalid(dn);
429 goto failed;
432 dn->ext_comp_num++;
434 if (*p == '\0') {
435 /* We have reached the end (extended component only)! */
436 talloc_free(data);
437 return true;
439 } else if (*p == ';') {
440 p++;
441 continue;
442 } else {
443 ldb_dn_mark_invalid(dn);
444 goto failed;
448 *d++ = *p++;
449 continue;
451 if (in_attr) {
452 if (trim) {
453 if (*p == ' ') {
454 p++;
455 continue;
458 /* first char */
459 trim = false;
461 if (!isascii(*p)) {
462 /* attr names must be ascii only */
463 ldb_dn_mark_invalid(dn);
464 goto failed;
467 if (isdigit(*p)) {
468 is_oid = true;
469 } else
470 if ( ! isalpha(*p)) {
471 /* not a digit nor an alpha,
472 * invalid attribute name */
473 ldb_dn_mark_invalid(dn);
474 goto failed;
477 /* Copy this character across from parse_dn,
478 * now we have trimmed out spaces */
479 *d++ = *p++;
480 continue;
483 if (*p == ' ') {
484 p++;
485 /* valid only if we are at the end */
486 trim = true;
487 continue;
490 if (trim && (*p != '=')) {
491 /* spaces/tabs are not allowed */
492 ldb_dn_mark_invalid(dn);
493 goto failed;
496 if (*p == '=') {
497 /* attribute terminated */
498 in_attr = false;
499 in_value = true;
500 trim = true;
501 l = 0;
503 /* Terminate this string in d
504 * (which is a copy of parse_dn
505 * with spaces trimmed) */
506 *d++ = '\0';
507 dn->components[dn->comp_num].name = talloc_strdup(dn->components, dt);
508 if ( ! dn->components[dn->comp_num].name) {
509 /* ouch */
510 goto failed;
513 dt = d;
515 p++;
516 continue;
519 if (!isascii(*p)) {
520 /* attr names must be ascii only */
521 ldb_dn_mark_invalid(dn);
522 goto failed;
525 if (is_oid && ( ! (isdigit(*p) || (*p == '.')))) {
526 /* not a digit nor a dot,
527 * invalid attribute oid */
528 ldb_dn_mark_invalid(dn);
529 goto failed;
530 } else
531 if ( ! (isalpha(*p) || isdigit(*p) || (*p == '-'))) {
532 /* not ALPHA, DIGIT or HYPHEN */
533 ldb_dn_mark_invalid(dn);
534 goto failed;
537 *d++ = *p++;
538 continue;
541 if (in_value) {
542 if (in_quote) {
543 if (*p == '\"') {
544 if (p[-1] != '\\') {
545 p++;
546 in_quote = false;
547 continue;
550 *d++ = *p++;
551 l++;
552 continue;
555 if (trim) {
556 if (*p == ' ') {
557 p++;
558 continue;
561 /* first char */
562 trim = false;
564 if (*p == '\"') {
565 in_quote = true;
566 p++;
567 continue;
571 switch (*p) {
573 /* TODO: support ber encoded values
574 case '#':
577 case ',':
578 if (escape) {
579 *d++ = *p++;
580 l++;
581 escape = false;
582 continue;
584 /* ok found value terminator */
586 if ( t ) {
587 /* trim back */
588 d -= (p - t);
589 l -= (p - t);
592 in_attr = true;
593 in_value = false;
594 trim = true;
596 p++;
597 *d++ = '\0';
598 dn->components[dn->comp_num].value.data = (uint8_t *)talloc_strdup(dn->components, dt);
599 dn->components[dn->comp_num].value.length = l;
600 if ( ! dn->components[dn->comp_num].value.data) {
601 /* ouch ! */
602 goto failed;
605 dt = d;
607 dn->comp_num++;
608 if (dn->comp_num > 2) {
609 dn->components = talloc_realloc(dn,
610 dn->components,
611 struct ldb_dn_component,
612 dn->comp_num + 1);
613 if ( ! dn->components) {
614 /* ouch ! */
615 goto failed;
617 /* make sure all components are zeroed, other functions depend on this */
618 memset(&dn->components[dn->comp_num], '\0', sizeof(struct ldb_dn_component));
621 continue;
623 case '+':
624 case '=':
625 /* to main compatibility with earlier
626 versions of ldb indexing, we have to
627 accept the base64 encoded binary index
628 values, which contain a '+' or '='
629 which should normally be escaped */
630 if (is_index) {
631 if ( t ) t = NULL;
632 *d++ = *p++;
633 l++;
634 break;
636 /* fall through */
637 case '\"':
638 case '<':
639 case '>':
640 case ';':
641 /* a string with not escaped specials is invalid (tested) */
642 if ( ! escape) {
643 ldb_dn_mark_invalid(dn);
644 goto failed;
646 escape = false;
648 *d++ = *p++;
649 l++;
651 if ( t ) t = NULL;
652 break;
654 case '\\':
655 if ( ! escape) {
656 escape = true;
657 p++;
658 continue;
660 escape = false;
662 *d++ = *p++;
663 l++;
665 if ( t ) t = NULL;
666 break;
668 default:
669 if (escape) {
670 if (isxdigit(p[0]) && isxdigit(p[1])) {
671 if (sscanf(p, "%02x", &x) != 1) {
672 /* invalid escaping sequence */
673 ldb_dn_mark_invalid(dn);
674 goto failed;
676 p += 2;
677 *d++ = (unsigned char)x;
678 } else {
679 *d++ = *p++;
682 escape = false;
683 l++;
684 if ( t ) t = NULL;
685 break;
688 if (*p == ' ') {
689 if ( ! t) t = p;
690 } else {
691 if ( t ) t = NULL;
694 *d++ = *p++;
695 l++;
697 break;
703 if (in_attr || in_quote) {
704 /* invalid dn */
705 ldb_dn_mark_invalid(dn);
706 goto failed;
709 /* save last element */
710 if ( t ) {
711 /* trim back */
712 d -= (p - t);
713 l -= (p - t);
716 *d++ = '\0';
717 dn->components[dn->comp_num].value.length = l;
718 dn->components[dn->comp_num].value.data =
719 (uint8_t *)talloc_strdup(dn->components, dt);
720 if ( ! dn->components[dn->comp_num].value.data) {
721 /* ouch */
722 goto failed;
725 dn->comp_num++;
727 talloc_free(data);
728 return true;
730 failed:
731 dn->comp_num = 0;
732 talloc_free(dn->components);
733 return false;
736 bool ldb_dn_validate(struct ldb_dn *dn)
738 return ldb_dn_explode(dn);
741 const char *ldb_dn_get_linearized(struct ldb_dn *dn)
743 int i, len;
744 char *d, *n;
746 if ( ! dn || ( dn->invalid)) return NULL;
748 if (dn->linearized) return dn->linearized;
750 if ( ! dn->components) {
751 ldb_dn_mark_invalid(dn);
752 return NULL;
755 if (dn->comp_num == 0) {
756 dn->linearized = talloc_strdup(dn, "");
757 if ( ! dn->linearized) return NULL;
758 return dn->linearized;
761 /* calculate maximum possible length of DN */
762 for (len = 0, i = 0; i < dn->comp_num; i++) {
763 /* name len */
764 len += strlen(dn->components[i].name);
765 /* max escaped data len */
766 len += (dn->components[i].value.length * 3);
767 len += 2; /* '=' and ',' */
769 dn->linearized = talloc_array(dn, char, len);
770 if ( ! dn->linearized) return NULL;
772 d = dn->linearized;
774 for (i = 0; i < dn->comp_num; i++) {
776 /* copy the name */
777 n = dn->components[i].name;
778 while (*n) *d++ = *n++;
780 *d++ = '=';
782 /* and the value */
783 d += ldb_dn_escape_internal( d,
784 (char *)dn->components[i].value.data,
785 dn->components[i].value.length);
786 *d++ = ',';
789 *(--d) = '\0';
791 /* don't waste more memory than necessary */
792 dn->linearized = talloc_realloc(dn, dn->linearized,
793 char, (d - dn->linearized + 1));
795 return dn->linearized;
798 static int ldb_dn_extended_component_compare(const void *p1, const void *p2)
800 const struct ldb_dn_ext_component *ec1 = (const struct ldb_dn_ext_component *)p1;
801 const struct ldb_dn_ext_component *ec2 = (const struct ldb_dn_ext_component *)p2;
802 return strcmp(ec1->name, ec2->name);
805 char *ldb_dn_get_extended_linearized(void *mem_ctx, struct ldb_dn *dn, int mode)
807 const char *linearized = ldb_dn_get_linearized(dn);
808 char *p = NULL;
809 int i;
811 if (!linearized) {
812 return NULL;
815 if (!ldb_dn_has_extended(dn)) {
816 return talloc_strdup(mem_ctx, linearized);
819 if (!ldb_dn_validate(dn)) {
820 return NULL;
823 /* sort the extended components by name. The idea is to make
824 * the resulting DNs consistent, plus to ensure that we put
825 * 'DELETED' first, so it can be very quickly recognised
827 TYPESAFE_QSORT(dn->ext_components, dn->ext_comp_num,
828 ldb_dn_extended_component_compare);
830 for (i = 0; i < dn->ext_comp_num; i++) {
831 const struct ldb_dn_extended_syntax *ext_syntax;
832 const char *name = dn->ext_components[i].name;
833 struct ldb_val ec_val = dn->ext_components[i].value;
834 struct ldb_val val;
835 int ret;
837 ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name);
838 if (!ext_syntax) {
839 return NULL;
842 if (mode == 1) {
843 ret = ext_syntax->write_clear_fn(dn->ldb, mem_ctx,
844 &ec_val, &val);
845 } else if (mode == 0) {
846 ret = ext_syntax->write_hex_fn(dn->ldb, mem_ctx,
847 &ec_val, &val);
848 } else {
849 ret = -1;
852 if (ret != LDB_SUCCESS) {
853 return NULL;
856 if (i == 0) {
857 p = talloc_asprintf(mem_ctx, "<%s=%s>",
858 name, val.data);
859 } else {
860 p = talloc_asprintf_append_buffer(p, ";<%s=%s>",
861 name, val.data);
864 talloc_free(val.data);
866 if (!p) {
867 return NULL;
871 if (dn->ext_comp_num && *linearized) {
872 p = talloc_asprintf_append_buffer(p, ";%s", linearized);
875 if (!p) {
876 return NULL;
879 return p;
883 filter out all but an acceptable list of extended DN components
885 void ldb_dn_extended_filter(struct ldb_dn *dn, const char * const *accept)
887 int i;
888 for (i=0; i<dn->ext_comp_num; i++) {
889 if (!ldb_attr_in_list(accept, dn->ext_components[i].name)) {
890 memmove(&dn->ext_components[i],
891 &dn->ext_components[i+1],
892 (dn->ext_comp_num-(i+1))*sizeof(dn->ext_components[0]));
893 dn->ext_comp_num--;
894 i--;
897 LDB_FREE(dn->ext_linearized);
901 char *ldb_dn_alloc_linearized(void *mem_ctx, struct ldb_dn *dn)
903 return talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn));
907 casefold a dn. We need to casefold the attribute names, and canonicalize
908 attribute values of case insensitive attributes.
911 static bool ldb_dn_casefold_internal(struct ldb_dn *dn)
913 int i, ret;
915 if ( ! dn || dn->invalid) return false;
917 if (dn->valid_case) return true;
919 if (( ! dn->components) && ( ! ldb_dn_explode(dn))) {
920 return false;
923 for (i = 0; i < dn->comp_num; i++) {
924 const struct ldb_schema_attribute *a;
926 dn->components[i].cf_name =
927 ldb_attr_casefold(dn->components,
928 dn->components[i].name);
929 if (!dn->components[i].cf_name) {
930 goto failed;
933 a = ldb_schema_attribute_by_name(dn->ldb,
934 dn->components[i].cf_name);
936 ret = a->syntax->canonicalise_fn(dn->ldb, dn->components,
937 &(dn->components[i].value),
938 &(dn->components[i].cf_value));
939 if (ret != 0) {
940 goto failed;
944 dn->valid_case = true;
946 return true;
948 failed:
949 for (i = 0; i < dn->comp_num; i++) {
950 LDB_FREE(dn->components[i].cf_name);
951 LDB_FREE(dn->components[i].cf_value.data);
953 return false;
956 const char *ldb_dn_get_casefold(struct ldb_dn *dn)
958 int i, len;
959 char *d, *n;
961 if (dn->casefold) return dn->casefold;
963 if (dn->special) {
964 dn->casefold = talloc_strdup(dn, dn->linearized);
965 if (!dn->casefold) return NULL;
966 dn->valid_case = true;
967 return dn->casefold;
970 if ( ! ldb_dn_casefold_internal(dn)) {
971 return NULL;
974 if (dn->comp_num == 0) {
975 dn->casefold = talloc_strdup(dn, "");
976 return dn->casefold;
979 /* calculate maximum possible length of DN */
980 for (len = 0, i = 0; i < dn->comp_num; i++) {
981 /* name len */
982 len += strlen(dn->components[i].cf_name);
983 /* max escaped data len */
984 len += (dn->components[i].cf_value.length * 3);
985 len += 2; /* '=' and ',' */
987 dn->casefold = talloc_array(dn, char, len);
988 if ( ! dn->casefold) return NULL;
990 d = dn->casefold;
992 for (i = 0; i < dn->comp_num; i++) {
994 /* copy the name */
995 n = dn->components[i].cf_name;
996 while (*n) *d++ = *n++;
998 *d++ = '=';
1000 /* and the value */
1001 d += ldb_dn_escape_internal( d,
1002 (char *)dn->components[i].cf_value.data,
1003 dn->components[i].cf_value.length);
1004 *d++ = ',';
1006 *(--d) = '\0';
1008 /* don't waste more memory than necessary */
1009 dn->casefold = talloc_realloc(dn, dn->casefold,
1010 char, strlen(dn->casefold) + 1);
1012 return dn->casefold;
1015 char *ldb_dn_alloc_casefold(void *mem_ctx, struct ldb_dn *dn)
1017 return talloc_strdup(mem_ctx, ldb_dn_get_casefold(dn));
1020 /* Determine if dn is below base, in the ldap tree. Used for
1021 * evaluating a subtree search.
1022 * 0 if they match, otherwise non-zero
1025 int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn)
1027 int ret;
1028 int n_base, n_dn;
1030 if ( ! base || base->invalid) return 1;
1031 if ( ! dn || dn->invalid) return -1;
1033 if (( ! base->valid_case) || ( ! dn->valid_case)) {
1034 if (base->linearized && dn->linearized) {
1035 /* try with a normal compare first, if we are lucky
1036 * we will avoid exploding and casfolding */
1037 int dif;
1038 dif = strlen(dn->linearized) - strlen(base->linearized);
1039 if (dif < 0) {
1040 return dif;
1042 if (strcmp(base->linearized,
1043 &dn->linearized[dif]) == 0) {
1044 return 0;
1048 if ( ! ldb_dn_casefold_internal(base)) {
1049 return 1;
1052 if ( ! ldb_dn_casefold_internal(dn)) {
1053 return -1;
1058 /* if base has more components,
1059 * they don't have the same base */
1060 if (base->comp_num > dn->comp_num) {
1061 return (dn->comp_num - base->comp_num);
1064 if (dn->comp_num == 0) {
1065 if (dn->special && base->special) {
1066 return strcmp(base->linearized, dn->linearized);
1067 } else if (dn->special) {
1068 return -1;
1069 } else if (base->special) {
1070 return 1;
1071 } else {
1072 return 0;
1076 n_base = base->comp_num - 1;
1077 n_dn = dn->comp_num - 1;
1079 while (n_base >= 0) {
1080 char *b_name = base->components[n_base].cf_name;
1081 char *dn_name = dn->components[n_dn].cf_name;
1083 char *b_vdata = (char *)base->components[n_base].cf_value.data;
1084 char *dn_vdata = (char *)dn->components[n_dn].cf_value.data;
1086 size_t b_vlen = base->components[n_base].cf_value.length;
1087 size_t dn_vlen = dn->components[n_dn].cf_value.length;
1089 /* compare attr names */
1090 ret = strcmp(b_name, dn_name);
1091 if (ret != 0) return ret;
1093 /* compare attr.cf_value. */
1094 if (b_vlen != dn_vlen) {
1095 return b_vlen - dn_vlen;
1097 ret = strcmp(b_vdata, dn_vdata);
1098 if (ret != 0) return ret;
1100 n_base--;
1101 n_dn--;
1104 return 0;
1107 /* compare DNs using casefolding compare functions.
1109 If they match, then return 0
1112 int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1)
1114 int i, ret;
1116 if (( ! dn0) || dn0->invalid || ! dn1 || dn1->invalid) {
1117 return -1;
1120 if (( ! dn0->valid_case) || ( ! dn1->valid_case)) {
1121 if (dn0->linearized && dn1->linearized) {
1122 /* try with a normal compare first, if we are lucky
1123 * we will avoid exploding and casfolding */
1124 if (strcmp(dn0->linearized, dn1->linearized) == 0) {
1125 return 0;
1129 if ( ! ldb_dn_casefold_internal(dn0)) {
1130 return 1;
1133 if ( ! ldb_dn_casefold_internal(dn1)) {
1134 return -1;
1139 if (dn0->comp_num != dn1->comp_num) {
1140 return (dn1->comp_num - dn0->comp_num);
1143 if (dn0->comp_num == 0) {
1144 if (dn0->special && dn1->special) {
1145 return strcmp(dn0->linearized, dn1->linearized);
1146 } else if (dn0->special) {
1147 return 1;
1148 } else if (dn1->special) {
1149 return -1;
1150 } else {
1151 return 0;
1155 for (i = 0; i < dn0->comp_num; i++) {
1156 char *dn0_name = dn0->components[i].cf_name;
1157 char *dn1_name = dn1->components[i].cf_name;
1159 char *dn0_vdata = (char *)dn0->components[i].cf_value.data;
1160 char *dn1_vdata = (char *)dn1->components[i].cf_value.data;
1162 size_t dn0_vlen = dn0->components[i].cf_value.length;
1163 size_t dn1_vlen = dn1->components[i].cf_value.length;
1165 /* compare attr names */
1166 ret = strcmp(dn0_name, dn1_name);
1167 if (ret != 0) {
1168 return ret;
1171 /* compare attr.cf_value. */
1172 if (dn0_vlen != dn1_vlen) {
1173 return dn0_vlen - dn1_vlen;
1175 ret = strcmp(dn0_vdata, dn1_vdata);
1176 if (ret != 0) {
1177 return ret;
1181 return 0;
1184 static struct ldb_dn_component ldb_dn_copy_component(
1185 void *mem_ctx,
1186 struct ldb_dn_component *src)
1188 struct ldb_dn_component dst;
1190 memset(&dst, 0, sizeof(dst));
1192 if (src == NULL) {
1193 return dst;
1196 dst.value = ldb_val_dup(mem_ctx, &(src->value));
1197 if (dst.value.data == NULL) {
1198 return dst;
1201 dst.name = talloc_strdup(mem_ctx, src->name);
1202 if (dst.name == NULL) {
1203 LDB_FREE(dst.value.data);
1204 return dst;
1207 if (src->cf_value.data) {
1208 dst.cf_value = ldb_val_dup(mem_ctx, &(src->cf_value));
1209 if (dst.cf_value.data == NULL) {
1210 LDB_FREE(dst.value.data);
1211 LDB_FREE(dst.name);
1212 return dst;
1215 dst.cf_name = talloc_strdup(mem_ctx, src->cf_name);
1216 if (dst.cf_name == NULL) {
1217 LDB_FREE(dst.cf_name);
1218 LDB_FREE(dst.value.data);
1219 LDB_FREE(dst.name);
1220 return dst;
1222 } else {
1223 dst.cf_value.data = NULL;
1224 dst.cf_name = NULL;
1227 return dst;
1230 static struct ldb_dn_ext_component ldb_dn_ext_copy_component(
1231 void *mem_ctx,
1232 struct ldb_dn_ext_component *src)
1234 struct ldb_dn_ext_component dst;
1236 memset(&dst, 0, sizeof(dst));
1238 if (src == NULL) {
1239 return dst;
1242 dst.value = ldb_val_dup(mem_ctx, &(src->value));
1243 if (dst.value.data == NULL) {
1244 return dst;
1247 dst.name = talloc_strdup(mem_ctx, src->name);
1248 if (dst.name == NULL) {
1249 LDB_FREE(dst.value.data);
1250 return dst;
1253 return dst;
1256 struct ldb_dn *ldb_dn_copy(void *mem_ctx, struct ldb_dn *dn)
1258 struct ldb_dn *new_dn;
1260 if (!dn || dn->invalid) {
1261 return NULL;
1264 new_dn = talloc_zero(mem_ctx, struct ldb_dn);
1265 if ( !new_dn) {
1266 return NULL;
1269 *new_dn = *dn;
1271 if (dn->components) {
1272 int i;
1274 new_dn->components =
1275 talloc_zero_array(new_dn,
1276 struct ldb_dn_component,
1277 dn->comp_num);
1278 if ( ! new_dn->components) {
1279 talloc_free(new_dn);
1280 return NULL;
1283 for (i = 0; i < dn->comp_num; i++) {
1284 new_dn->components[i] =
1285 ldb_dn_copy_component(new_dn->components,
1286 &dn->components[i]);
1287 if ( ! new_dn->components[i].value.data) {
1288 talloc_free(new_dn);
1289 return NULL;
1294 if (dn->ext_components) {
1295 int i;
1297 new_dn->ext_components =
1298 talloc_zero_array(new_dn,
1299 struct ldb_dn_ext_component,
1300 dn->ext_comp_num);
1301 if ( ! new_dn->ext_components) {
1302 talloc_free(new_dn);
1303 return NULL;
1306 for (i = 0; i < dn->ext_comp_num; i++) {
1307 new_dn->ext_components[i] =
1308 ldb_dn_ext_copy_component(
1309 new_dn->ext_components,
1310 &dn->ext_components[i]);
1311 if ( ! new_dn->ext_components[i].value.data) {
1312 talloc_free(new_dn);
1313 return NULL;
1318 if (dn->casefold) {
1319 new_dn->casefold = talloc_strdup(new_dn, dn->casefold);
1320 if ( ! new_dn->casefold) {
1321 talloc_free(new_dn);
1322 return NULL;
1326 if (dn->linearized) {
1327 new_dn->linearized = talloc_strdup(new_dn, dn->linearized);
1328 if ( ! new_dn->linearized) {
1329 talloc_free(new_dn);
1330 return NULL;
1334 if (dn->ext_linearized) {
1335 new_dn->ext_linearized = talloc_strdup(new_dn,
1336 dn->ext_linearized);
1337 if ( ! new_dn->ext_linearized) {
1338 talloc_free(new_dn);
1339 return NULL;
1343 return new_dn;
1346 /* modify the given dn by adding a base.
1348 * return true if successful and false if not
1349 * if false is returned the dn may be marked invalid
1351 bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base)
1353 const char *s;
1354 char *t;
1356 if ( !base || base->invalid || !dn || dn->invalid) {
1357 return false;
1360 if (dn->components) {
1361 int i;
1363 if ( ! ldb_dn_validate(base)) {
1364 return false;
1367 s = NULL;
1368 if (dn->valid_case) {
1369 if ( ! (s = ldb_dn_get_casefold(base))) {
1370 return false;
1374 dn->components = talloc_realloc(dn,
1375 dn->components,
1376 struct ldb_dn_component,
1377 dn->comp_num + base->comp_num);
1378 if ( ! dn->components) {
1379 ldb_dn_mark_invalid(dn);
1380 return false;
1383 for (i = 0; i < base->comp_num; dn->comp_num++, i++) {
1384 dn->components[dn->comp_num] =
1385 ldb_dn_copy_component(dn->components,
1386 &base->components[i]);
1387 if (dn->components[dn->comp_num].value.data == NULL) {
1388 ldb_dn_mark_invalid(dn);
1389 return false;
1393 if (dn->casefold && s) {
1394 if (*dn->casefold) {
1395 t = talloc_asprintf(dn, "%s,%s",
1396 dn->casefold, s);
1397 } else {
1398 t = talloc_strdup(dn, s);
1400 LDB_FREE(dn->casefold);
1401 dn->casefold = t;
1405 if (dn->linearized) {
1407 s = ldb_dn_get_linearized(base);
1408 if ( ! s) {
1409 return false;
1412 if (*dn->linearized) {
1413 t = talloc_asprintf(dn, "%s,%s",
1414 dn->linearized, s);
1415 } else {
1416 t = talloc_strdup(dn, s);
1418 if ( ! t) {
1419 ldb_dn_mark_invalid(dn);
1420 return false;
1422 LDB_FREE(dn->linearized);
1423 dn->linearized = t;
1426 /* Wipe the ext_linearized DN,
1427 * the GUID and SID are almost certainly no longer valid */
1428 LDB_FREE(dn->ext_linearized);
1430 LDB_FREE(dn->ext_components);
1431 dn->ext_comp_num = 0;
1432 return true;
1435 /* modify the given dn by adding a base.
1437 * return true if successful and false if not
1438 * if false is returned the dn may be marked invalid
1440 bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...)
1442 struct ldb_dn *base;
1443 char *base_str;
1444 va_list ap;
1445 bool ret;
1447 if ( !dn || dn->invalid) {
1448 return false;
1451 va_start(ap, base_fmt);
1452 base_str = talloc_vasprintf(dn, base_fmt, ap);
1453 va_end(ap);
1455 if (base_str == NULL) {
1456 return false;
1459 base = ldb_dn_new(base_str, dn->ldb, base_str);
1461 ret = ldb_dn_add_base(dn, base);
1463 talloc_free(base_str);
1465 return ret;
1468 /* modify the given dn by adding children elements.
1470 * return true if successful and false if not
1471 * if false is returned the dn may be marked invalid
1473 bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child)
1475 const char *s;
1476 char *t;
1478 if ( !child || child->invalid || !dn || dn->invalid) {
1479 return false;
1482 if (dn->components) {
1483 int n, i, j;
1485 if ( ! ldb_dn_validate(child)) {
1486 return false;
1489 s = NULL;
1490 if (dn->valid_case) {
1491 if ( ! (s = ldb_dn_get_casefold(child))) {
1492 return false;
1496 n = dn->comp_num + child->comp_num;
1498 dn->components = talloc_realloc(dn,
1499 dn->components,
1500 struct ldb_dn_component,
1502 if ( ! dn->components) {
1503 ldb_dn_mark_invalid(dn);
1504 return false;
1507 for (i = dn->comp_num - 1, j = n - 1; i >= 0; i--, j--) {
1508 dn->components[j] = dn->components[i];
1511 for (i = 0; i < child->comp_num; i++) {
1512 dn->components[i] =
1513 ldb_dn_copy_component(dn->components,
1514 &child->components[i]);
1515 if (dn->components[i].value.data == NULL) {
1516 ldb_dn_mark_invalid(dn);
1517 return false;
1521 dn->comp_num = n;
1523 if (dn->casefold && s) {
1524 t = talloc_asprintf(dn, "%s,%s", s, dn->casefold);
1525 LDB_FREE(dn->casefold);
1526 dn->casefold = t;
1530 if (dn->linearized) {
1532 s = ldb_dn_get_linearized(child);
1533 if ( ! s) {
1534 return false;
1537 t = talloc_asprintf(dn, "%s,%s", s, dn->linearized);
1538 if ( ! t) {
1539 ldb_dn_mark_invalid(dn);
1540 return false;
1542 LDB_FREE(dn->linearized);
1543 dn->linearized = t;
1546 /* Wipe the ext_linearized DN,
1547 * the GUID and SID are almost certainly no longer valid */
1548 LDB_FREE(dn->ext_linearized);
1550 LDB_FREE(dn->ext_components);
1551 dn->ext_comp_num = 0;
1553 return true;
1556 /* modify the given dn by adding children elements.
1558 * return true if successful and false if not
1559 * if false is returned the dn may be marked invalid
1561 bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...)
1563 struct ldb_dn *child;
1564 char *child_str;
1565 va_list ap;
1566 bool ret;
1568 if ( !dn || dn->invalid) {
1569 return false;
1572 va_start(ap, child_fmt);
1573 child_str = talloc_vasprintf(dn, child_fmt, ap);
1574 va_end(ap);
1576 if (child_str == NULL) {
1577 return false;
1580 child = ldb_dn_new(child_str, dn->ldb, child_str);
1582 ret = ldb_dn_add_child(dn, child);
1584 talloc_free(child_str);
1586 return ret;
1589 bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num)
1591 int i;
1593 if ( ! ldb_dn_validate(dn)) {
1594 return false;
1597 if (dn->comp_num < num) {
1598 return false;
1601 /* free components */
1602 for (i = num; i > 0; i--) {
1603 LDB_FREE(dn->components[dn->comp_num - i].name);
1604 LDB_FREE(dn->components[dn->comp_num - i].value.data);
1605 LDB_FREE(dn->components[dn->comp_num - i].cf_name);
1606 LDB_FREE(dn->components[dn->comp_num - i].cf_value.data);
1609 dn->comp_num -= num;
1611 if (dn->valid_case) {
1612 for (i = 0; i < dn->comp_num; i++) {
1613 LDB_FREE(dn->components[i].cf_name);
1614 LDB_FREE(dn->components[i].cf_value.data);
1616 dn->valid_case = false;
1619 LDB_FREE(dn->casefold);
1620 LDB_FREE(dn->linearized);
1622 /* Wipe the ext_linearized DN,
1623 * the GUID and SID are almost certainly no longer valid */
1624 LDB_FREE(dn->ext_linearized);
1626 LDB_FREE(dn->ext_components);
1627 dn->ext_comp_num = 0;
1629 return true;
1632 bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num)
1634 int i, j;
1636 if ( ! ldb_dn_validate(dn)) {
1637 return false;
1640 if (dn->comp_num < num) {
1641 return false;
1644 for (i = 0, j = num; j < dn->comp_num; i++, j++) {
1645 if (i < num) {
1646 LDB_FREE(dn->components[i].name);
1647 LDB_FREE(dn->components[i].value.data);
1648 LDB_FREE(dn->components[i].cf_name);
1649 LDB_FREE(dn->components[i].cf_value.data);
1651 dn->components[i] = dn->components[j];
1654 dn->comp_num -= num;
1656 if (dn->valid_case) {
1657 for (i = 0; i < dn->comp_num; i++) {
1658 LDB_FREE(dn->components[i].cf_name);
1659 LDB_FREE(dn->components[i].cf_value.data);
1661 dn->valid_case = false;
1664 LDB_FREE(dn->casefold);
1665 LDB_FREE(dn->linearized);
1667 /* Wipe the ext_linearized DN,
1668 * the GUID and SID are almost certainly no longer valid */
1669 LDB_FREE(dn->ext_linearized);
1671 LDB_FREE(dn->ext_components);
1672 dn->ext_comp_num = 0;
1673 return true;
1676 struct ldb_dn *ldb_dn_get_parent(void *mem_ctx, struct ldb_dn *dn)
1678 struct ldb_dn *new_dn;
1680 new_dn = ldb_dn_copy(mem_ctx, dn);
1681 if ( !new_dn ) {
1682 return NULL;
1685 if ( ! ldb_dn_remove_child_components(new_dn, 1)) {
1686 talloc_free(new_dn);
1687 return NULL;
1690 /* Wipe the ext_linearized DN,
1691 * the GUID and SID are almost certainly no longer valid */
1692 LDB_FREE(dn->ext_linearized);
1694 LDB_FREE(dn->ext_components);
1695 dn->ext_comp_num = 0;
1696 return new_dn;
1699 /* Create a 'canonical name' string from a DN:
1701 ie dc=samba,dc=org -> samba.org/
1702 uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator
1704 There are two formats,
1705 the EX format has the last '/' replaced with a newline (\n).
1708 static char *ldb_dn_canonical(void *mem_ctx, struct ldb_dn *dn, int ex_format) {
1709 int i;
1710 TALLOC_CTX *tmpctx;
1711 char *cracked = NULL;
1712 const char *format = (ex_format ? "\n" : "/" );
1714 if ( ! ldb_dn_validate(dn)) {
1715 return NULL;
1718 tmpctx = talloc_new(mem_ctx);
1720 /* Walk backwards down the DN, grabbing 'dc' components at first */
1721 for (i = dn->comp_num - 1 ; i >= 0; i--) {
1722 if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) {
1723 break;
1725 if (cracked) {
1726 cracked = talloc_asprintf(tmpctx, "%s.%s",
1727 ldb_dn_escape_value(tmpctx,
1728 dn->components[i].value),
1729 cracked);
1730 } else {
1731 cracked = ldb_dn_escape_value(tmpctx,
1732 dn->components[i].value);
1734 if (!cracked) {
1735 goto done;
1739 /* Only domain components? Finish here */
1740 if (i < 0) {
1741 cracked = talloc_strdup_append_buffer(cracked, format);
1742 talloc_steal(mem_ctx, cracked);
1743 goto done;
1746 /* Now walk backwards appending remaining components */
1747 for (; i > 0; i--) {
1748 cracked = talloc_asprintf_append_buffer(cracked, "/%s",
1749 ldb_dn_escape_value(tmpctx,
1750 dn->components[i].value));
1751 if (!cracked) {
1752 goto done;
1756 /* Last one, possibly a newline for the 'ex' format */
1757 cracked = talloc_asprintf_append_buffer(cracked, "%s%s", format,
1758 ldb_dn_escape_value(tmpctx,
1759 dn->components[i].value));
1761 talloc_steal(mem_ctx, cracked);
1762 done:
1763 talloc_free(tmpctx);
1764 return cracked;
1767 /* Wrapper functions for the above, for the two different string formats */
1768 char *ldb_dn_canonical_string(void *mem_ctx, struct ldb_dn *dn) {
1769 return ldb_dn_canonical(mem_ctx, dn, 0);
1773 char *ldb_dn_canonical_ex_string(void *mem_ctx, struct ldb_dn *dn) {
1774 return ldb_dn_canonical(mem_ctx, dn, 1);
1777 int ldb_dn_get_comp_num(struct ldb_dn *dn)
1779 if ( ! ldb_dn_validate(dn)) {
1780 return -1;
1782 return dn->comp_num;
1785 const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num)
1787 if ( ! ldb_dn_validate(dn)) {
1788 return NULL;
1790 if (num >= dn->comp_num) return NULL;
1791 return dn->components[num].name;
1794 const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn,
1795 unsigned int num)
1797 if ( ! ldb_dn_validate(dn)) {
1798 return NULL;
1800 if (num >= dn->comp_num) return NULL;
1801 return &dn->components[num].value;
1804 const char *ldb_dn_get_rdn_name(struct ldb_dn *dn)
1806 if ( ! ldb_dn_validate(dn)) {
1807 return NULL;
1809 if (dn->comp_num == 0) return NULL;
1810 return dn->components[0].name;
1813 const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn)
1815 if ( ! ldb_dn_validate(dn)) {
1816 return NULL;
1818 if (dn->comp_num == 0) return NULL;
1819 return &dn->components[0].value;
1822 int ldb_dn_set_component(struct ldb_dn *dn, int num,
1823 const char *name, const struct ldb_val val)
1825 char *n;
1826 struct ldb_val v;
1828 if ( ! ldb_dn_validate(dn)) {
1829 return LDB_ERR_OTHER;
1832 if (num >= dn->comp_num) {
1833 return LDB_ERR_OTHER;
1836 n = talloc_strdup(dn, name);
1837 if ( ! n) {
1838 return LDB_ERR_OTHER;
1841 v.length = val.length;
1842 v.data = (uint8_t *)talloc_memdup(dn, val.data, v.length+1);
1843 if ( ! v.data) {
1844 talloc_free(n);
1845 return LDB_ERR_OTHER;
1848 talloc_free(dn->components[num].name);
1849 talloc_free(dn->components[num].value.data);
1850 dn->components[num].name = n;
1851 dn->components[num].value = v;
1853 if (dn->valid_case) {
1854 int i;
1855 for (i = 0; i < dn->comp_num; i++) {
1856 LDB_FREE(dn->components[i].cf_name);
1857 LDB_FREE(dn->components[i].cf_value.data);
1859 dn->valid_case = false;
1861 LDB_FREE(dn->casefold);
1862 LDB_FREE(dn->linearized);
1864 /* Wipe the ext_linearized DN,
1865 * the GUID and SID are almost certainly no longer valid */
1866 LDB_FREE(dn->ext_linearized);
1868 dn->ext_comp_num = 0;
1869 LDB_FREE(dn->ext_components);
1870 return LDB_SUCCESS;
1873 const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn,
1874 const char *name)
1876 int i;
1877 if ( ! ldb_dn_validate(dn)) {
1878 return NULL;
1880 for (i=0; i < dn->ext_comp_num; i++) {
1881 if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) {
1882 return &dn->ext_components[i].value;
1885 return NULL;
1888 int ldb_dn_set_extended_component(struct ldb_dn *dn,
1889 const char *name, const struct ldb_val *val)
1891 struct ldb_dn_ext_component *p;
1892 int i;
1893 struct ldb_val v2;
1895 if ( ! ldb_dn_validate(dn)) {
1896 return LDB_ERR_OTHER;
1899 if (!ldb_dn_extended_syntax_by_name(dn->ldb, name)) {
1900 /* We don't know how to handle this type of thing */
1901 return LDB_ERR_INVALID_DN_SYNTAX;
1904 for (i=0; i < dn->ext_comp_num; i++) {
1905 if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) {
1906 if (val) {
1907 dn->ext_components[i].value =
1908 ldb_val_dup(dn->ext_components, val);
1910 dn->ext_components[i].name =
1911 talloc_strdup(dn->ext_components, name);
1912 if (!dn->ext_components[i].name ||
1913 !dn->ext_components[i].value.data) {
1914 ldb_dn_mark_invalid(dn);
1915 return LDB_ERR_OPERATIONS_ERROR;
1917 return LDB_SUCCESS;
1918 } else {
1919 if (i != (dn->ext_comp_num - 1)) {
1920 memmove(&dn->ext_components[i],
1921 &dn->ext_components[i+1],
1922 ((dn->ext_comp_num-1) - i) *
1923 sizeof(*dn->ext_components));
1925 dn->ext_comp_num--;
1927 dn->ext_components = talloc_realloc(dn,
1928 dn->ext_components,
1929 struct ldb_dn_ext_component,
1930 dn->ext_comp_num);
1931 if (!dn->ext_components) {
1932 ldb_dn_mark_invalid(dn);
1933 return LDB_ERR_OPERATIONS_ERROR;
1935 return LDB_SUCCESS;
1937 LDB_FREE(dn->ext_linearized);
1941 if (val == NULL) {
1942 /* removing a value that doesn't exist is not an error */
1943 return LDB_SUCCESS;
1946 v2 = *val;
1948 p = dn->ext_components
1949 = talloc_realloc(dn,
1950 dn->ext_components,
1951 struct ldb_dn_ext_component,
1952 dn->ext_comp_num + 1);
1953 if (!dn->ext_components) {
1954 ldb_dn_mark_invalid(dn);
1955 return LDB_ERR_OPERATIONS_ERROR;
1958 p[dn->ext_comp_num].value = ldb_val_dup(dn->ext_components, &v2);
1959 p[dn->ext_comp_num].name = talloc_strdup(p, name);
1961 if (!dn->ext_components[i].name || !dn->ext_components[i].value.data) {
1962 ldb_dn_mark_invalid(dn);
1963 return LDB_ERR_OPERATIONS_ERROR;
1965 dn->ext_components = p;
1966 dn->ext_comp_num++;
1968 return LDB_SUCCESS;
1971 void ldb_dn_remove_extended_components(struct ldb_dn *dn)
1973 dn->ext_comp_num = 0;
1974 LDB_FREE(dn->ext_components);
1975 LDB_FREE(dn->ext_linearized);
1978 bool ldb_dn_is_valid(struct ldb_dn *dn)
1980 if ( ! dn) return false;
1981 return ! dn->invalid;
1984 bool ldb_dn_is_special(struct ldb_dn *dn)
1986 if ( ! dn || dn->invalid) return false;
1987 return dn->special;
1990 bool ldb_dn_has_extended(struct ldb_dn *dn)
1992 if ( ! dn || dn->invalid) return false;
1993 if (dn->ext_linearized && (dn->ext_linearized[0] == '<')) return true;
1994 return dn->ext_comp_num != 0;
1997 bool ldb_dn_check_special(struct ldb_dn *dn, const char *check)
1999 if ( ! dn || dn->invalid) return false;
2000 return ! strcmp(dn->linearized, check);
2003 bool ldb_dn_is_null(struct ldb_dn *dn)
2005 if ( ! dn || dn->invalid) return false;
2006 if (ldb_dn_has_extended(dn)) return false;
2007 if (dn->linearized && (dn->linearized[0] == '\0')) return true;
2008 return false;
2012 this updates dn->components, taking the components from ref_dn.
2013 This is used by code that wants to update the DN path of a DN
2014 while not impacting on the extended DN components
2016 int ldb_dn_update_components(struct ldb_dn *dn, const struct ldb_dn *ref_dn)
2018 dn->components = talloc_realloc(dn, dn->components,
2019 struct ldb_dn_component, ref_dn->comp_num);
2020 if (!dn->components) {
2021 return LDB_ERR_OPERATIONS_ERROR;
2023 memcpy(dn->components, ref_dn->components,
2024 sizeof(struct ldb_dn_component)*ref_dn->comp_num);
2025 dn->comp_num = ref_dn->comp_num;
2027 talloc_free(dn->linearized);
2028 talloc_free(dn->ext_linearized);
2029 dn->ext_linearized = NULL;
2030 dn->linearized = NULL;
2032 return LDB_SUCCESS;