Fix the mess with ldb includes.
[Samba/ekacnet.git] / source4 / lib / ldb / common / ldb_dn.c
blob402d6295015d141de84211692b1131f7a0a6ff70
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_extended_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 *extended_linearized;
73 char *casefold;
75 unsigned int comp_num;
76 struct ldb_dn_component *components;
78 unsigned int extended_comp_num;
79 struct ldb_dn_extended_component *extended_components;
82 /* strdn may be NULL */
83 struct ldb_dn *ldb_dn_from_ldb_val(void *mem_ctx, struct ldb_context *ldb, const struct ldb_val *strdn)
85 struct ldb_dn *dn;
87 if (! ldb) return NULL;
89 dn = talloc_zero(mem_ctx, struct ldb_dn);
90 LDB_DN_NULL_FAILED(dn);
92 dn->ldb = ldb;
94 if (strdn->data && strdn->length) {
95 if (strdn->data[0] == '@') {
96 dn->special = true;
98 dn->extended_linearized = talloc_strndup(dn, (const char *)strdn->data, strdn->length);
99 LDB_DN_NULL_FAILED(dn->extended_linearized);
101 if (strdn->data[0] == '<') {
102 const char *p_save, *p = dn->extended_linearized;
103 do {
104 p_save = p;
105 p = strstr(p, ">;");
106 if (p) {
107 p = p + 2;
109 } while (p);
111 if (p_save == dn->extended_linearized) {
112 dn->linearized = talloc_strdup(dn, "");
113 } else {
114 dn->linearized = talloc_strdup(dn, p_save);
116 LDB_DN_NULL_FAILED(dn->linearized);
117 } else {
118 dn->linearized = dn->extended_linearized;
119 dn->extended_linearized = NULL;
121 } else {
122 dn->linearized = talloc_strdup(dn, "");
123 LDB_DN_NULL_FAILED(dn->linearized);
126 return dn;
128 failed:
129 talloc_free(dn);
130 return NULL;
133 /* strdn may be NULL */
134 struct ldb_dn *ldb_dn_new(void *mem_ctx, struct ldb_context *ldb, const char *strdn)
136 struct ldb_val blob;
137 blob.data = strdn;
138 blob.length = strdn ? strlen(strdn) : 0;
139 return ldb_dn_from_ldb_val(mem_ctx, ldb, &blob);
142 struct ldb_dn *ldb_dn_new_fmt(void *mem_ctx, struct ldb_context *ldb, const char *new_fmt, ...)
144 char *strdn;
145 va_list ap;
147 if ( (! mem_ctx) || (! ldb)) return NULL;
149 va_start(ap, new_fmt);
150 strdn = talloc_vasprintf(mem_ctx, new_fmt, ap);
151 va_end(ap);
153 if (strdn) {
154 struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb, strdn);
155 talloc_free(strdn);
156 return dn;
159 return NULL;
162 static int ldb_dn_escape_internal(char *dst, const char *src, int len)
164 const char *p, *s;
165 char *d;
166 int l;
168 p = s = src;
169 d = dst;
171 while (p - src < len) {
173 p += strcspn(p, ",=\n+<>#;\\\"");
175 if (p - src == len) /* found no escapable chars */
176 break;
178 memcpy(d, s, p - s); /* copy the part of the string before the stop */
179 d += (p - s); /* move to current position */
181 if (*p) { /* it is a normal escapable character */
182 *d++ = '\\';
183 *d++ = *p++;
184 } else { /* we have a zero byte in the string */
185 strncpy(d, "\00", 3); /* escape the zero */
186 d += 3;
187 p++; /* skip the zero */
189 s = p; /* move forward */
192 /* copy the last part (with zero) and return */
193 l = len - (s - src);
194 memcpy(d, s, l + 1);
196 /* return the length of the resulting string */
197 return (l + (d - dst));
200 char *ldb_dn_escape_value(void *mem_ctx, struct ldb_val value)
202 char *dst;
204 if (!value.length)
205 return NULL;
207 /* allocate destination string, it will be at most 3 times the source */
208 dst = talloc_array(mem_ctx, char, value.length * 3 + 1);
209 if ( ! dst) {
210 talloc_free(dst);
211 return NULL;
214 ldb_dn_escape_internal(dst, (const char *)value.data, value.length);
216 dst = talloc_realloc(mem_ctx, dst, char, strlen(dst) + 1);
218 return dst;
222 explode a DN string into a ldb_dn structure
223 based on RFC4514 except that we don't support multiple valued RDNs
225 static bool ldb_dn_explode(struct ldb_dn *dn)
227 char *p, *ex_name, *ex_value, *data, *d, *dt, *t;
228 bool trim = false;
229 bool in_extended = false;
230 bool in_ex_name = false;
231 bool in_ex_value = false;
232 bool in_attr = false;
233 bool in_value = false;
234 bool in_quote = false;
235 bool is_oid = false;
236 bool escape = false;
237 unsigned x;
238 int l, ret;
239 char *parse_dn;
241 if ( ! dn || dn->invalid) return false;
243 if (dn->components) {
244 return true;
247 if (dn->extended_linearized) {
248 parse_dn = dn->extended_linearized;
249 } else {
250 parse_dn = dn->linearized;
253 if ( ! parse_dn ) {
254 return false;
257 /* Empty DNs */
258 if (parse_dn[0] == '\0') {
259 return true;
262 /* Special DNs case */
263 if (dn->special) {
264 return true;
267 /* make sure we free this if alloced previously before replacing */
268 talloc_free(dn->components);
270 talloc_free(dn->extended_components);
271 dn->extended_components = NULL;
273 /* in the common case we have 3 or more components */
274 /* make sure all components are zeroed, other functions depend on this */
275 dn->components = talloc_zero_array(dn, struct ldb_dn_component, 3);
276 if ( ! dn->components) {
277 return false;
279 dn->comp_num = 0;
281 /* Components data space is allocated here once */
282 data = talloc_array(dn->components, char, strlen(parse_dn) + 1);
283 if (!data) {
284 return false;
287 p = parse_dn;
288 in_extended = true;
289 in_ex_name = false;
290 in_ex_value = false;
291 trim = true;
292 t = NULL;
293 d = dt = data;
295 while (*p) {
296 if (in_extended) {
298 if (!in_ex_name && !in_ex_value) {
300 if (p[0] == '<') {
301 p++;
302 ex_name = d;
303 in_ex_name = true;
304 continue;
305 } else if (p[0] == '\0') {
306 p++;
307 continue;
308 } else {
309 in_extended = false;
310 in_attr = true;
311 dt = d;
313 continue;
317 if (in_ex_name && *p == '=') {
318 *d++ = '\0';
319 p++;
320 ex_value = d;
321 in_ex_name = false;
322 in_ex_value = true;
323 continue;
326 if (in_ex_value && *p == '>') {
327 const struct ldb_dn_extended_syntax *extended_syntax;
328 struct ldb_val ex_val = {
329 .data = ex_value,
330 .length = d - ex_value
333 *d++ = '\0';
334 p++;
335 in_ex_value = false;
337 /* Process name and ex_value */
339 dn->extended_components = talloc_realloc(dn,
340 dn->extended_components,
341 struct ldb_dn_extended_component,
342 dn->extended_comp_num + 1);
343 if ( ! dn->extended_components) {
344 /* ouch ! */
345 goto failed;
348 extended_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, ex_name);
349 if (!extended_syntax) {
350 /* We don't know about this type of extended DN */
351 goto failed;
354 dn->extended_components[dn->extended_comp_num].name = talloc_strdup(dn->extended_components, ex_name);
355 if (!dn->extended_components[dn->extended_comp_num].name) {
356 /* ouch */
357 goto failed;
359 ret = extended_syntax->read_fn(dn->ldb, dn->extended_components,
360 &ex_val, &dn->extended_components[dn->extended_comp_num].value);
361 if (ret != LDB_SUCCESS) {
362 dn->invalid = true;
363 goto failed;
366 dn->extended_comp_num++;
368 if (*p == '\0') {
369 /* We have reached the end (extended component only)! */
370 talloc_free(data);
371 return true;
373 } else if (*p == ';') {
374 p++;
375 continue;
376 } else {
377 dn->invalid = true;
378 goto failed;
382 *d++ = *p++;
383 continue;
385 if (in_attr) {
386 if (trim) {
387 if (*p == ' ') {
388 p++;
389 continue;
392 /* first char */
393 trim = false;
395 if (!isascii(*p)) {
396 /* attr names must be ascii only */
397 dn->invalid = true;
398 goto failed;
401 if (isdigit(*p)) {
402 is_oid = true;
403 } else
404 if ( ! isalpha(*p)) {
405 /* not a digit nor an alpha, invalid attribute name */
406 dn->invalid = true;
407 goto failed;
410 /* Copy this character across from parse_dn, now we have trimmed out spaces */
411 *d++ = *p++;
412 continue;
415 if (*p == ' ') {
416 p++;
417 /* valid only if we are at the end */
418 trim = true;
419 continue;
422 if (trim && (*p != '=')) {
423 /* spaces/tabs are not allowed in attribute names */
424 dn->invalid = true;
425 goto failed;
428 if (*p == '=') {
429 /* attribute terminated */
430 in_attr = false;
431 in_value = true;
432 trim = true;
433 l = 0;
435 /* Terminate this string in d (which is a copy of parse_dn with spaces trimmed) */
436 *d++ = '\0';
437 dn->components[dn->comp_num].name = talloc_strdup(dn->components, dt);
438 if ( ! dn->components[dn->comp_num].name) {
439 /* ouch */
440 goto failed;
443 dt = d;
445 p++;
446 continue;
449 if (!isascii(*p)) {
450 /* attr names must be ascii only */
451 dn->invalid = true;
452 goto failed;
455 if (is_oid && ( ! (isdigit(*p) || (*p == '.')))) {
456 /* not a digit nor a dot, invalid attribute oid */
457 dn->invalid = true;
458 goto failed;
459 } else
460 if ( ! (isalpha(*p) || isdigit(*p) || (*p == '-'))) {
461 /* not ALPHA, DIGIT or HYPHEN */
462 dn->invalid = true;
463 goto failed;
466 *d++ = *p++;
467 continue;
470 if (in_value) {
471 if (in_quote) {
472 if (*p == '\"') {
473 if (p[-1] != '\\') {
474 p++;
475 in_quote = false;
476 continue;
479 *d++ = *p++;
480 l++;
481 continue;
484 if (trim) {
485 if (*p == ' ') {
486 p++;
487 continue;
490 /* first char */
491 trim = false;
493 if (*p == '\"') {
494 in_quote = true;
495 p++;
496 continue;
500 switch (*p) {
502 /* TODO: support ber encoded values
503 case '#':
506 case ',':
507 if (escape) {
508 *d++ = *p++;
509 l++;
510 escape = false;
511 continue;
513 /* ok found value terminator */
515 if ( t ) {
516 /* trim back */
517 d -= (p - t);
518 l -= (p - t);
521 in_attr = true;
522 in_value = false;
523 trim = true;
525 p++;
526 *d++ = '\0';
527 dn->components[dn->comp_num].value.data = (uint8_t *)talloc_strdup(dn->components, dt);
528 dn->components[dn->comp_num].value.length = l;
529 if ( ! dn->components[dn->comp_num].value.data) {
530 /* ouch ! */
531 goto failed;
534 dt = d;
536 dn->comp_num++;
537 if (dn->comp_num > 2) {
538 dn->components = talloc_realloc(dn,
539 dn->components,
540 struct ldb_dn_component,
541 dn->comp_num + 1);
542 if ( ! dn->components) {
543 /* ouch ! */
544 goto failed;
546 /* make sure all components are zeroed, other functions depend on this */
547 memset(&dn->components[dn->comp_num], '\0', sizeof(struct ldb_dn_component));
550 continue;
552 case '=':
553 case '\n':
554 case '+':
555 case '<':
556 case '>':
557 case '#':
558 case ';':
559 case '\"':
560 /* a string with not escaped specials is invalid (tested) */
561 if ( ! escape) {
562 dn->invalid = true;
563 goto failed;
565 escape = false;
567 *d++ = *p++;
568 l++;
570 if ( t ) t = NULL;
571 break;
573 case '\\':
574 if ( ! escape) {
575 escape = true;
576 p++;
577 continue;
579 escape = false;
581 *d++ = *p++;
582 l++;
584 if ( t ) t = NULL;
585 break;
587 default:
588 if (escape) {
589 if (sscanf(p, "%02x", &x) != 1) {
590 /* invalid escaping sequence */
591 dn->invalid = true;
592 goto failed;
594 escape = false;
596 p += 2;
597 *d++ = (unsigned char)x;
598 l++;
600 if ( t ) t = NULL;
601 break;
604 if (*p == ' ') {
605 if ( ! t) t = p;
606 } else {
607 if ( t ) t = NULL;
610 *d++ = *p++;
611 l++;
613 break;
619 if (in_attr || in_quote) {
620 /* invalid dn */
621 dn->invalid = true;
622 goto failed;
625 /* save last element */
626 if ( t ) {
627 /* trim back */
628 d -= (p - t);
629 l -= (p - t);
632 *d++ = '\0';
633 dn->components[dn->comp_num].value.data = (uint8_t *)talloc_strdup(dn->components, dt);
634 dn->components[dn->comp_num].value.length = l;
636 if ( ! dn->components[dn->comp_num].value.data) {
637 /* ouch */
638 goto failed;
641 dn->comp_num++;
643 talloc_free(data);
644 return true;
646 failed:
647 dn->comp_num = 0;
648 talloc_free(dn->components);
649 return false;
652 bool ldb_dn_validate(struct ldb_dn *dn)
654 return ldb_dn_explode(dn);
657 const char *ldb_dn_get_linearized(struct ldb_dn *dn)
659 int i, len;
660 char *d, *n;
662 if ( ! dn || ( dn->invalid)) return NULL;
664 if (dn->linearized) return dn->linearized;
666 if ( ! dn->components) {
667 dn->invalid = true;
668 return NULL;
671 if (dn->comp_num == 0) {
672 dn->linearized = talloc_strdup(dn, "");
673 if ( ! dn->linearized) return NULL;
674 return dn->linearized;
677 /* calculate maximum possible length of DN */
678 for (len = 0, i = 0; i < dn->comp_num; i++) {
679 len += strlen(dn->components[i].name); /* name len */
680 len += (dn->components[i].value.length * 3); /* max escaped data len */
681 len += 2; /* '=' and ',' */
683 dn->linearized = talloc_array(dn, char, len);
684 if ( ! dn->linearized) return NULL;
686 d = dn->linearized;
688 for (i = 0; i < dn->comp_num; i++) {
690 /* copy the name */
691 n = dn->components[i].name;
692 while (*n) *d++ = *n++;
694 *d++ = '=';
696 /* and the value */
697 d += ldb_dn_escape_internal( d,
698 (char *)dn->components[i].value.data,
699 dn->components[i].value.length);
700 *d++ = ',';
703 *(--d) = '\0';
705 /* don't waste more memory than necessary */
706 dn->linearized = talloc_realloc(dn, dn->linearized, char, (d - dn->linearized + 1));
708 return dn->linearized;
711 char *ldb_dn_get_extended_linearized(void *mem_ctx, struct ldb_dn *dn, int mode)
713 const char *linearized = ldb_dn_get_linearized(dn);
714 char *p;
715 int i;
717 if (!linearized) {
718 return NULL;
721 if (!ldb_dn_has_extended(dn)) {
722 return talloc_strdup(mem_ctx, linearized);
725 if (!ldb_dn_validate(dn)) {
726 return NULL;
729 for (i=0; i < dn->extended_comp_num; i++) {
730 struct ldb_val val;
731 int ret;
732 const struct ldb_dn_extended_syntax *extended_syntax;
733 const char *name = dn->extended_components[i].name;
735 extended_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name);
737 if (mode == 1) {
738 ret = extended_syntax->write_clear_fn(dn->ldb, mem_ctx,
739 &dn->extended_components[i].value,
740 &val);
741 } else if (mode == 0) {
742 ret = extended_syntax->write_hex_fn(dn->ldb, mem_ctx,
743 &dn->extended_components[i].value,
744 &val);
745 } else {
746 ret = -1;
749 if (ret != LDB_SUCCESS) {
750 return NULL;
753 if (i == 0) {
754 p = talloc_asprintf(mem_ctx, "<%s=%s>", dn->extended_components[i].name, val.data);
755 } else {
756 p = talloc_asprintf_append(p, ";<%s=%s>", dn->extended_components[i].name, val.data);
759 talloc_free(val.data);
761 if (!p) {
762 return NULL;
766 if (dn->extended_comp_num && *linearized) {
767 p = talloc_asprintf_append(p, ";%s", linearized);
770 if (!p) {
771 return NULL;
774 return p;
779 char *ldb_dn_alloc_linearized(void *mem_ctx, struct ldb_dn *dn)
781 return talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn));
785 casefold a dn. We need to casefold the attribute names, and canonicalize
786 attribute values of case insensitive attributes.
789 static bool ldb_dn_casefold_internal(struct ldb_dn *dn)
791 int i, ret;
793 if ( ! dn || dn->invalid) return false;
795 if (dn->valid_case) return true;
797 if (( ! dn->components) && ( ! ldb_dn_explode(dn))) {
798 return false;
801 for (i = 0; i < dn->comp_num; i++) {
802 const struct ldb_schema_attribute *a;
804 dn->components[i].cf_name = ldb_attr_casefold(dn->components, dn->components[i].name);
805 if (!dn->components[i].cf_name) {
806 goto failed;
809 a = ldb_schema_attribute_by_name(dn->ldb, dn->components[i].cf_name);
810 ret = a->syntax->canonicalise_fn(dn->ldb, dn->components,
811 &(dn->components[i].value),
812 &(dn->components[i].cf_value));
813 if (ret != 0) {
814 goto failed;
818 dn->valid_case = true;
820 return true;
822 failed:
823 for (i = 0; i < dn->comp_num; i++) {
824 LDB_FREE(dn->components[i].cf_name);
825 LDB_FREE(dn->components[i].cf_value.data);
827 return false;
830 const char *ldb_dn_get_casefold(struct ldb_dn *dn)
832 int i, len;
833 char *d, *n;
835 if (dn->casefold) return dn->casefold;
837 if (dn->special) {
838 dn->casefold = talloc_strdup(dn, dn->linearized);
839 if (!dn->casefold) return NULL;
840 dn->valid_case = true;
841 return dn->casefold;
844 if ( ! ldb_dn_casefold_internal(dn)) {
845 return NULL;
848 if (dn->comp_num == 0) {
849 if (dn->linearized && dn->linearized[0] == '\0') {
850 /* hmm a NULL dn, should we faild casefolding ? */
851 dn->casefold = talloc_strdup(dn, "");
852 return dn->casefold;
854 /* A DN must be NULL, special, or have components */
855 dn->invalid = true;
856 return NULL;
859 /* calculate maximum possible length of DN */
860 for (len = 0, i = 0; i < dn->comp_num; i++) {
861 len += strlen(dn->components[i].cf_name); /* name len */
862 len += (dn->components[i].cf_value.length * 3); /* max escaped data len */
863 len += 2; /* '=' and ',' */
865 dn->casefold = talloc_array(dn, char, len);
866 if ( ! dn->casefold) return NULL;
868 d = dn->casefold;
870 for (i = 0; i < dn->comp_num; i++) {
872 /* copy the name */
873 n = dn->components[i].cf_name;
874 while (*n) *d++ = *n++;
876 *d++ = '=';
878 /* and the value */
879 d += ldb_dn_escape_internal( d,
880 (char *)dn->components[i].cf_value.data,
881 dn->components[i].cf_value.length);
882 *d++ = ',';
884 *(--d) = '\0';
886 /* don't waste more memory than necessary */
887 dn->casefold = talloc_realloc(dn, dn->casefold, char, strlen(dn->casefold) + 1);
889 return dn->casefold;
892 char *ldb_dn_alloc_casefold(void *mem_ctx, struct ldb_dn *dn)
894 return talloc_strdup(mem_ctx, ldb_dn_get_casefold(dn));
897 /* Determine if dn is below base, in the ldap tree. Used for
898 * evaluating a subtree search.
899 * 0 if they match, otherwise non-zero
902 int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn)
904 int ret;
905 int n_base, n_dn;
907 if ( ! base || base->invalid) return 1;
908 if ( ! dn || dn->invalid) return -1;
910 if (( ! base->valid_case) || ( ! dn->valid_case)) {
911 if (base->linearized && dn->linearized) {
912 /* try with a normal compare first, if we are lucky
913 * we will avoid exploding and casfolding */
914 int dif;
915 dif = strlen(dn->linearized) - strlen(base->linearized);
916 if (dif < 0) return dif;
917 if (strcmp(base->linearized, &dn->linearized[dif]) == 0) return 0;
920 if ( ! ldb_dn_casefold_internal(base)) {
921 return 1;
924 if ( ! ldb_dn_casefold_internal(dn)) {
925 return -1;
930 /* if base has more components,
931 * they don't have the same base */
932 if (base->comp_num > dn->comp_num) {
933 return (dn->comp_num - base->comp_num);
936 if (dn->comp_num == 0) {
937 if (dn->special && base->special) {
938 return strcmp(base->linearized, dn->linearized);
939 } else if (dn->special) {
940 return -1;
941 } else if (base->special) {
942 return 1;
943 } else {
944 return 0;
948 n_base = base->comp_num - 1;
949 n_dn = dn->comp_num - 1;
951 while (n_base >= 0) {
952 /* compare attr names */
953 ret = strcmp(base->components[n_base].cf_name, dn->components[n_dn].cf_name);
954 if (ret != 0) return ret;
956 /* compare attr.cf_value. */
957 if (base->components[n_base].cf_value.length != dn->components[n_dn].cf_value.length) {
958 return base->components[n_base].cf_value.length - dn->components[n_dn].cf_value.length;
960 ret = strcmp((char *)base->components[n_base].cf_value.data, (char *)dn->components[n_dn].cf_value.data);
961 if (ret != 0) return ret;
963 n_base--;
964 n_dn--;
967 return 0;
970 /* compare DNs using casefolding compare functions.
972 If they match, then return 0
975 int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1)
977 int i, ret;
979 if (( ! dn0) || dn0->invalid || ! dn1 || dn1->invalid) return -1;
981 if (( ! dn0->valid_case) || ( ! dn1->valid_case)) {
982 if (dn0->linearized && dn1->linearized) {
983 /* try with a normal compare first, if we are lucky
984 * we will avoid exploding and casfolding */
985 if (strcmp(dn0->linearized, dn1->linearized) == 0) return 0;
988 if ( ! ldb_dn_casefold_internal(dn0)) {
989 return 1;
992 if ( ! ldb_dn_casefold_internal(dn1)) {
993 return -1;
998 if (dn0->comp_num != dn1->comp_num) {
999 return (dn1->comp_num - dn0->comp_num);
1002 if (dn0->comp_num == 0) {
1003 if (dn0->special && dn1->special) {
1004 return strcmp(dn0->linearized, dn1->linearized);
1005 } else if (dn0->special) {
1006 return 1;
1007 } else if (dn1->special) {
1008 return -1;
1009 } else {
1010 return 0;
1014 for (i = 0; i < dn0->comp_num; i++) {
1015 /* compare attr names */
1016 ret = strcmp(dn0->components[i].cf_name, dn1->components[i].cf_name);
1017 if (ret != 0) return ret;
1019 /* compare attr.cf_value. */
1020 if (dn0->components[i].cf_value.length != dn1->components[i].cf_value.length) {
1021 return dn0->components[i].cf_value.length - dn1->components[i].cf_value.length;
1023 ret = strcmp((char *)dn0->components[i].cf_value.data, (char *)dn1->components[i].cf_value.data);
1024 if (ret != 0) return ret;
1027 return 0;
1030 static struct ldb_dn_component ldb_dn_copy_component(void *mem_ctx, struct ldb_dn_component *src)
1032 struct ldb_dn_component dst;
1034 memset(&dst, 0, sizeof(dst));
1036 if (src == NULL) {
1037 return dst;
1040 dst.value = ldb_val_dup(mem_ctx, &(src->value));
1041 if (dst.value.data == NULL) {
1042 return dst;
1045 dst.name = talloc_strdup(mem_ctx, src->name);
1046 if (dst.name == NULL) {
1047 LDB_FREE(dst.value.data);
1048 return dst;
1051 if (src->cf_value.data) {
1052 dst.cf_value = ldb_val_dup(mem_ctx, &(src->cf_value));
1053 if (dst.cf_value.data == NULL) {
1054 LDB_FREE(dst.value.data);
1055 LDB_FREE(dst.name);
1056 return dst;
1059 dst.cf_name = talloc_strdup(mem_ctx, src->cf_name);
1060 if (dst.cf_name == NULL) {
1061 LDB_FREE(dst.cf_name);
1062 LDB_FREE(dst.value.data);
1063 LDB_FREE(dst.name);
1064 return dst;
1066 } else {
1067 dst.cf_value.data = NULL;
1068 dst.cf_name = NULL;
1071 return dst;
1074 static struct ldb_dn_extended_component ldb_dn_extended_copy_component(void *mem_ctx, struct ldb_dn_extended_component *src)
1076 struct ldb_dn_extended_component dst;
1078 memset(&dst, 0, sizeof(dst));
1080 if (src == NULL) {
1081 return dst;
1084 dst.value = ldb_val_dup(mem_ctx, &(src->value));
1085 if (dst.value.data == NULL) {
1086 return dst;
1089 dst.name = talloc_strdup(mem_ctx, src->name);
1090 if (dst.name == NULL) {
1091 LDB_FREE(dst.value.data);
1092 return dst;
1095 return dst;
1098 struct ldb_dn *ldb_dn_copy(void *mem_ctx, struct ldb_dn *dn)
1100 struct ldb_dn *new_dn;
1102 if (!dn || dn->invalid) {
1103 return NULL;
1106 new_dn = talloc_zero(mem_ctx, struct ldb_dn);
1107 if ( !new_dn) {
1108 return NULL;
1111 *new_dn = *dn;
1113 if (dn->components) {
1114 int i;
1116 new_dn->components = talloc_zero_array(new_dn, struct ldb_dn_component, dn->comp_num);
1117 if ( ! new_dn->components) {
1118 talloc_free(new_dn);
1119 return NULL;
1122 for (i = 0; i < dn->comp_num; i++) {
1123 new_dn->components[i] = ldb_dn_copy_component(new_dn->components, &dn->components[i]);
1124 if ( ! new_dn->components[i].value.data) {
1125 talloc_free(new_dn);
1126 return NULL;
1131 if (dn->extended_components) {
1132 int i;
1134 new_dn->extended_components = talloc_zero_array(new_dn, struct ldb_dn_extended_component, dn->extended_comp_num);
1135 if ( ! new_dn->extended_components) {
1136 talloc_free(new_dn);
1137 return NULL;
1140 for (i = 0; i < dn->extended_comp_num; i++) {
1141 new_dn->extended_components[i] = ldb_dn_extended_copy_component(new_dn->extended_components, &dn->extended_components[i]);
1142 if ( ! new_dn->extended_components[i].value.data) {
1143 talloc_free(new_dn);
1144 return NULL;
1149 if (dn->casefold) {
1150 new_dn->casefold = talloc_strdup(new_dn, dn->casefold);
1151 if ( ! new_dn->casefold) {
1152 talloc_free(new_dn);
1153 return NULL;
1157 if (dn->linearized) {
1158 new_dn->linearized = talloc_strdup(new_dn, dn->linearized);
1159 if ( ! new_dn->linearized) {
1160 talloc_free(new_dn);
1161 return NULL;
1165 if (dn->extended_linearized) {
1166 new_dn->extended_linearized = talloc_strdup(new_dn, dn->extended_linearized);
1167 if ( ! new_dn->extended_linearized) {
1168 talloc_free(new_dn);
1169 return NULL;
1173 return new_dn;
1176 /* modify the given dn by adding a base.
1178 * return true if successful and false if not
1179 * if false is returned the dn may be marked invalid
1181 bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base)
1183 const char *s;
1184 char *t;
1186 if ( !base || base->invalid || !dn || dn->invalid) {
1187 return false;
1190 if (dn->components) {
1191 int i;
1193 if ( ! ldb_dn_validate(base)) {
1194 return false;
1197 s = NULL;
1198 if (dn->valid_case) {
1199 if ( ! (s = ldb_dn_get_casefold(base))) {
1200 return false;
1204 dn->components = talloc_realloc(dn,
1205 dn->components,
1206 struct ldb_dn_component,
1207 dn->comp_num + base->comp_num);
1208 if ( ! dn->components) {
1209 dn->invalid = true;
1210 return false;
1213 for (i = 0; i < base->comp_num; dn->comp_num++, i++) {
1214 dn->components[dn->comp_num] = ldb_dn_copy_component(dn->components, &base->components[i]);
1215 if (dn->components[dn->comp_num].value.data == NULL) {
1216 dn->invalid = true;
1217 return false;
1221 if (dn->casefold && s) {
1222 if (*dn->casefold) {
1223 t = talloc_asprintf(dn, "%s,%s", dn->casefold, s);
1224 } else {
1225 t = talloc_strdup(dn, s);
1227 LDB_FREE(dn->casefold);
1228 dn->casefold = t;
1232 if (dn->linearized) {
1234 s = ldb_dn_get_linearized(base);
1235 if ( ! s) {
1236 return false;
1239 if (*dn->linearized) {
1240 t = talloc_asprintf(dn, "%s,%s", dn->linearized, s);
1241 } else {
1242 t = talloc_strdup(dn, s);
1244 if ( ! t) {
1245 dn->invalid = true;
1246 return false;
1248 LDB_FREE(dn->linearized);
1249 dn->linearized = t;
1252 /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
1253 if (dn->extended_linearized) {
1254 LDB_FREE(dn->extended_linearized);
1257 LDB_FREE(dn->extended_components);
1258 dn->extended_comp_num = 0;
1259 return true;
1262 /* modify the given dn by adding a base.
1264 * return true if successful and false if not
1265 * if false is returned the dn may be marked invalid
1267 bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...)
1269 struct ldb_dn *base;
1270 char *base_str;
1271 va_list ap;
1272 bool ret;
1274 if ( !dn || dn->invalid) {
1275 return false;
1278 va_start(ap, base_fmt);
1279 base_str = talloc_vasprintf(dn, base_fmt, ap);
1280 va_end(ap);
1282 if (base_str == NULL) {
1283 return false;
1286 base = ldb_dn_new(base_str, dn->ldb, base_str);
1288 ret = ldb_dn_add_base(dn, base);
1290 talloc_free(base_str);
1292 return ret;
1295 /* modify the given dn by adding children elements.
1297 * return true if successful and false if not
1298 * if false is returned the dn may be marked invalid
1300 bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child)
1302 const char *s;
1303 char *t;
1305 if ( !child || child->invalid || !dn || dn->invalid) {
1306 return false;
1309 if (dn->components) {
1310 int n, i, j;
1312 if ( ! ldb_dn_validate(child)) {
1313 return false;
1316 s = NULL;
1317 if (dn->valid_case) {
1318 if ( ! (s = ldb_dn_get_casefold(child))) {
1319 return false;
1323 n = dn->comp_num + child->comp_num;
1325 dn->components = talloc_realloc(dn,
1326 dn->components,
1327 struct ldb_dn_component,
1329 if ( ! dn->components) {
1330 dn->invalid = true;
1331 return false;
1334 for (i = dn->comp_num - 1, j = n - 1; i >= 0; i--, j--) {
1335 dn->components[j] = dn->components[i];
1338 for (i = 0; i < child->comp_num; i++) {
1339 dn->components[i] = ldb_dn_copy_component(dn->components, &child->components[i]);
1340 if (dn->components[i].value.data == NULL) {
1341 dn->invalid = true;
1342 return false;
1346 dn->comp_num = n;
1348 if (dn->casefold && s) {
1349 t = talloc_asprintf(dn, "%s,%s", s, dn->casefold);
1350 LDB_FREE(dn->casefold);
1351 dn->casefold = t;
1355 if (dn->linearized) {
1357 s = ldb_dn_get_linearized(child);
1358 if ( ! s) {
1359 return false;
1362 t = talloc_asprintf(dn, "%s,%s", s, dn->linearized);
1363 if ( ! t) {
1364 dn->invalid = true;
1365 return false;
1367 LDB_FREE(dn->linearized);
1368 dn->linearized = t;
1371 /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
1372 LDB_FREE(dn->extended_linearized);
1374 LDB_FREE(dn->extended_components);
1375 dn->extended_comp_num = 0;
1377 return true;
1380 /* modify the given dn by adding children elements.
1382 * return true if successful and false if not
1383 * if false is returned the dn may be marked invalid
1385 bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...)
1387 struct ldb_dn *child;
1388 char *child_str;
1389 va_list ap;
1390 bool ret;
1392 if ( !dn || dn->invalid) {
1393 return false;
1396 va_start(ap, child_fmt);
1397 child_str = talloc_vasprintf(dn, child_fmt, ap);
1398 va_end(ap);
1400 if (child_str == NULL) {
1401 return false;
1404 child = ldb_dn_new(child_str, dn->ldb, child_str);
1406 ret = ldb_dn_add_child(dn, child);
1408 talloc_free(child_str);
1410 return ret;
1413 bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num)
1415 int i;
1417 if ( ! ldb_dn_validate(dn)) {
1418 return false;
1421 if (dn->comp_num < num) {
1422 return false;
1425 /* free components */
1426 for (i = num; i > 0; i--) {
1427 LDB_FREE(dn->components[dn->comp_num - i].name);
1428 LDB_FREE(dn->components[dn->comp_num - i].value.data);
1429 LDB_FREE(dn->components[dn->comp_num - i].cf_name);
1430 LDB_FREE(dn->components[dn->comp_num - i].cf_value.data);
1433 dn->comp_num -= num;
1435 if (dn->valid_case) {
1436 for (i = 0; i < dn->comp_num; i++) {
1437 LDB_FREE(dn->components[i].cf_name);
1438 LDB_FREE(dn->components[i].cf_value.data);
1440 dn->valid_case = false;
1443 LDB_FREE(dn->casefold);
1444 LDB_FREE(dn->linearized);
1446 /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
1447 LDB_FREE(dn->extended_linearized);
1449 LDB_FREE(dn->extended_components);
1450 dn->extended_comp_num = 0;
1452 return true;
1455 bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num)
1457 int i, j;
1459 if ( ! ldb_dn_validate(dn)) {
1460 return false;
1463 if (dn->comp_num < num) {
1464 return false;
1467 for (i = 0, j = num; j < dn->comp_num; i++, j++) {
1468 if (i < num) {
1469 LDB_FREE(dn->components[i].name);
1470 LDB_FREE(dn->components[i].value.data);
1471 LDB_FREE(dn->components[i].cf_name);
1472 LDB_FREE(dn->components[i].cf_value.data);
1474 dn->components[i] = dn->components[j];
1477 dn->comp_num -= num;
1479 if (dn->valid_case) {
1480 for (i = 0; i < dn->comp_num; i++) {
1481 LDB_FREE(dn->components[i].cf_name);
1482 LDB_FREE(dn->components[i].cf_value.data);
1484 dn->valid_case = false;
1487 LDB_FREE(dn->casefold);
1488 LDB_FREE(dn->linearized);
1490 /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
1491 LDB_FREE(dn->extended_linearized);
1493 LDB_FREE(dn->extended_components);
1494 dn->extended_comp_num = 0;
1495 return true;
1498 struct ldb_dn *ldb_dn_get_parent(void *mem_ctx, struct ldb_dn *dn)
1500 struct ldb_dn *new_dn;
1502 new_dn = ldb_dn_copy(mem_ctx, dn);
1503 if ( !new_dn ) {
1504 return NULL;
1507 if ( ! ldb_dn_remove_child_components(new_dn, 1)) {
1508 talloc_free(new_dn);
1509 return NULL;
1512 /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
1513 LDB_FREE(dn->extended_linearized);
1515 LDB_FREE(dn->extended_components);
1516 dn->extended_comp_num = 0;
1517 return new_dn;
1520 /* Create a 'canonical name' string from a DN:
1522 ie dc=samba,dc=org -> samba.org/
1523 uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator
1525 There are two formats, the EX format has the last / replaced with a newline (\n).
1528 static char *ldb_dn_canonical(void *mem_ctx, struct ldb_dn *dn, int ex_format) {
1529 int i;
1530 TALLOC_CTX *tmpctx;
1531 char *cracked = NULL;
1532 const char *format = (ex_format ? "\n" : "/" );
1534 if ( ! ldb_dn_validate(dn)) {
1535 return NULL;
1538 tmpctx = talloc_new(mem_ctx);
1540 /* Walk backwards down the DN, grabbing 'dc' components at first */
1541 for (i = dn->comp_num - 1 ; i >= 0; i--) {
1542 if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) {
1543 break;
1545 if (cracked) {
1546 cracked = talloc_asprintf(tmpctx, "%s.%s",
1547 ldb_dn_escape_value(tmpctx, dn->components[i].value),
1548 cracked);
1549 } else {
1550 cracked = ldb_dn_escape_value(tmpctx, dn->components[i].value);
1552 if (!cracked) {
1553 goto done;
1557 /* Only domain components? Finish here */
1558 if (i < 0) {
1559 cracked = talloc_strdup_append_buffer(cracked, format);
1560 talloc_steal(mem_ctx, cracked);
1561 goto done;
1564 /* Now walk backwards appending remaining components */
1565 for (; i > 0; i--) {
1566 cracked = talloc_asprintf_append_buffer(cracked, "/%s",
1567 ldb_dn_escape_value(tmpctx, dn->components[i].value));
1568 if (!cracked) {
1569 goto done;
1573 /* Last one, possibly a newline for the 'ex' format */
1574 cracked = talloc_asprintf_append_buffer(cracked, "%s%s", format,
1575 ldb_dn_escape_value(tmpctx, dn->components[i].value));
1577 talloc_steal(mem_ctx, cracked);
1578 done:
1579 talloc_free(tmpctx);
1580 return cracked;
1583 /* Wrapper functions for the above, for the two different string formats */
1584 char *ldb_dn_canonical_string(void *mem_ctx, struct ldb_dn *dn) {
1585 return ldb_dn_canonical(mem_ctx, dn, 0);
1589 char *ldb_dn_canonical_ex_string(void *mem_ctx, struct ldb_dn *dn) {
1590 return ldb_dn_canonical(mem_ctx, dn, 1);
1593 int ldb_dn_get_comp_num(struct ldb_dn *dn)
1595 if ( ! ldb_dn_validate(dn)) {
1596 return -1;
1598 return dn->comp_num;
1601 const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num)
1603 if ( ! ldb_dn_validate(dn)) {
1604 return NULL;
1606 if (num >= dn->comp_num) return NULL;
1607 return dn->components[num].name;
1610 const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn, unsigned int num)
1612 if ( ! ldb_dn_validate(dn)) {
1613 return NULL;
1615 if (num >= dn->comp_num) return NULL;
1616 return &dn->components[num].value;
1619 const char *ldb_dn_get_rdn_name(struct ldb_dn *dn)
1621 if ( ! ldb_dn_validate(dn)) {
1622 return NULL;
1624 if (dn->comp_num == 0) return NULL;
1625 return dn->components[0].name;
1628 const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn)
1630 if ( ! ldb_dn_validate(dn)) {
1631 return NULL;
1633 if (dn->comp_num == 0) return NULL;
1634 return &dn->components[0].value;
1637 int ldb_dn_set_component(struct ldb_dn *dn, int num, const char *name, const struct ldb_val val)
1639 char *n;
1640 struct ldb_val v;
1642 if ( ! ldb_dn_validate(dn)) {
1643 return LDB_ERR_OTHER;
1646 if (num >= dn->comp_num) {
1647 return LDB_ERR_OTHER;
1650 n = talloc_strdup(dn, name);
1651 if ( ! n) {
1652 return LDB_ERR_OTHER;
1655 v.length = val.length;
1656 v.data = (uint8_t *)talloc_memdup(dn, val.data, v.length+1);
1657 if ( ! v.data) {
1658 talloc_free(n);
1659 return LDB_ERR_OTHER;
1662 talloc_free(dn->components[num].name);
1663 talloc_free(dn->components[num].value.data);
1664 dn->components[num].name = n;
1665 dn->components[num].value = v;
1667 if (dn->valid_case) {
1668 int i;
1669 for (i = 0; i < dn->comp_num; i++) {
1670 LDB_FREE(dn->components[i].cf_name);
1671 LDB_FREE(dn->components[i].cf_value.data);
1673 dn->valid_case = false;
1675 LDB_FREE(dn->casefold);
1676 LDB_FREE(dn->linearized);
1678 /* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
1679 LDB_FREE(dn->extended_linearized);
1681 dn->extended_comp_num = 0;
1682 LDB_FREE(dn->extended_components);
1683 return LDB_SUCCESS;
1686 const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn, const char *name)
1688 int i;
1689 if ( ! ldb_dn_validate(dn)) {
1690 return NULL;
1692 for (i=0; i < dn->extended_comp_num; i++) {
1693 if (ldb_attr_cmp(dn->extended_components[i].name, name) == 0) {
1694 return &dn->extended_components[i].value;
1697 return NULL;
1700 int ldb_dn_set_extended_component(struct ldb_dn *dn, const char *name, const struct ldb_val *val)
1702 struct ldb_dn_extended_component *p;
1703 int i;
1705 if ( ! ldb_dn_validate(dn)) {
1706 return LDB_ERR_OTHER;
1709 for (i=0; i < dn->extended_comp_num; i++) {
1710 if (ldb_attr_cmp(dn->extended_components[i].name, name) == 0) {
1711 if (val) {
1712 dn->extended_components[i].value = ldb_val_dup(dn->extended_components, val);
1714 dn->extended_components[i].name = talloc_strdup(dn->extended_components, name);
1715 if (!dn->extended_components[i].name || !dn->extended_components[i].value.data) {
1716 dn->invalid = true;
1717 return LDB_ERR_OPERATIONS_ERROR;
1720 } else {
1721 if (i != (dn->extended_comp_num - 1)) {
1722 memmove(&dn->extended_components[i], &dn->extended_components[i+1],
1723 ((dn->extended_comp_num-1) - i)*sizeof(*dn->extended_components));
1725 dn->extended_comp_num--;
1727 dn->extended_components = talloc_realloc(dn,
1728 dn->extended_components,
1729 struct ldb_dn_extended_component,
1730 dn->extended_comp_num);
1731 if (!dn->extended_components) {
1732 dn->invalid = true;
1733 return LDB_ERR_OPERATIONS_ERROR;
1735 return LDB_SUCCESS;
1740 p = dn->extended_components
1741 = talloc_realloc(dn,
1742 dn->extended_components,
1743 struct ldb_dn_extended_component,
1744 dn->extended_comp_num + 1);
1745 if (!dn->extended_components) {
1746 dn->invalid = true;
1747 return LDB_ERR_OPERATIONS_ERROR;
1750 p[dn->extended_comp_num].value = ldb_val_dup(dn->extended_components, val);
1751 p[dn->extended_comp_num].name = talloc_strdup(p, name);
1753 if (!dn->extended_components[i].name || !dn->extended_components[i].value.data) {
1754 dn->invalid = true;
1755 return LDB_ERR_OPERATIONS_ERROR;
1757 dn->extended_components = p;
1758 dn->extended_comp_num++;
1760 return LDB_SUCCESS;
1763 void ldb_dn_remove_extended_components(struct ldb_dn *dn)
1765 dn->extended_comp_num = 0;
1766 LDB_FREE(dn->extended_components);
1769 bool ldb_dn_is_valid(struct ldb_dn *dn)
1771 if ( ! dn) return false;
1772 return ! dn->invalid;
1775 bool ldb_dn_is_special(struct ldb_dn *dn)
1777 if ( ! dn || dn->invalid) return false;
1778 return dn->special;
1781 bool ldb_dn_has_extended(struct ldb_dn *dn)
1783 if ( ! dn || dn->invalid) return false;
1784 if (dn->extended_linearized && (dn->extended_linearized[0] == '<')) return true;
1785 return dn->extended_comp_num != 0;
1788 bool ldb_dn_check_special(struct ldb_dn *dn, const char *check)
1790 if ( ! dn || dn->invalid) return false;
1791 return ! strcmp(dn->linearized, check);
1794 bool ldb_dn_is_null(struct ldb_dn *dn)
1796 if ( ! dn || dn->invalid) return false;
1797 if (ldb_dn_has_extended(dn)) return false;
1798 if (dn->linearized && (dn->linearized[0] == '\0')) return true;
1799 return false;