ldb: cosmetic changes in ldb_dn
[Samba.git] / source4 / lib / ldb / common / ldb_dn.c
blobd905f47040b4e42dfce4214bf87903acbc49d323
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 /* strdn may be NULL */
83 struct ldb_dn *ldb_dn_from_ldb_val(void *mem_ctx,
84 struct ldb_context *ldb,
85 const struct ldb_val *strdn)
87 struct ldb_dn *dn;
89 if (! ldb) return NULL;
91 dn = talloc_zero(mem_ctx, struct ldb_dn);
92 LDB_DN_NULL_FAILED(dn);
94 dn->ldb = ldb;
96 if (strdn->data && strdn->length) {
97 const char *data = (const char *)strdn->data;
98 size_t length = strdn->length;
100 if (data[0] == '@') {
101 dn->special = true;
103 dn->ext_linearized = talloc_strndup(dn, data, length);
104 LDB_DN_NULL_FAILED(dn->ext_linearized);
106 if (data[0] == '<') {
107 const char *p_save, *p = dn->ext_linearized;
108 do {
109 p_save = p;
110 p = strstr(p, ">;");
111 if (p) {
112 p = p + 2;
114 } while (p);
116 if (p_save == dn->ext_linearized) {
117 dn->linearized = talloc_strdup(dn, "");
118 } else {
119 dn->linearized = talloc_strdup(dn, p_save);
121 LDB_DN_NULL_FAILED(dn->linearized);
122 } else {
123 dn->linearized = dn->ext_linearized;
124 dn->ext_linearized = NULL;
126 } else {
127 dn->linearized = talloc_strdup(dn, "");
128 LDB_DN_NULL_FAILED(dn->linearized);
131 return dn;
133 failed:
134 talloc_free(dn);
135 return NULL;
138 /* strdn may be NULL */
139 struct ldb_dn *ldb_dn_new(void *mem_ctx,
140 struct ldb_context *ldb,
141 const char *strdn)
143 struct ldb_val blob;
144 blob.data = strdn;
145 blob.length = strdn ? strlen(strdn) : 0;
146 return ldb_dn_from_ldb_val(mem_ctx, ldb, &blob);
149 struct ldb_dn *ldb_dn_new_fmt(void *mem_ctx,
150 struct ldb_context *ldb,
151 const char *new_fmt, ...)
153 char *strdn;
154 va_list ap;
156 if ( (! mem_ctx) || (! ldb)) return NULL;
158 va_start(ap, new_fmt);
159 strdn = talloc_vasprintf(mem_ctx, new_fmt, ap);
160 va_end(ap);
162 if (strdn) {
163 struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb, strdn);
164 talloc_free(strdn);
165 return dn;
168 return NULL;
171 static int ldb_dn_escape_internal(char *dst, const char *src, int len)
173 const char *p, *s;
174 char *d;
175 int l;
177 p = s = src;
178 d = dst;
180 while (p - src < len) {
182 p += strcspn(p, ",=\n+<>#;\\\"");
184 if (p - src == len) /* found no escapable chars */
185 break;
187 /* copy the part of the string before the stop */
188 memcpy(d, s, p - s);
189 d += (p - s); /* move to current position */
191 if (*p) { /* it is a normal escapable character */
192 *d++ = '\\';
193 *d++ = *p++;
194 } else { /* we have a zero byte in the string */
195 strncpy(d, "\00", 3); /* escape the zero */
196 d += 3;
197 p++; /* skip the zero */
199 s = p; /* move forward */
202 /* copy the last part (with zero) and return */
203 l = len - (s - src);
204 memcpy(d, s, l + 1);
206 /* return the length of the resulting string */
207 return (l + (d - dst));
210 char *ldb_dn_escape_value(void *mem_ctx, struct ldb_val value)
212 char *dst;
214 if (!value.length)
215 return NULL;
217 /* allocate destination string, it will be at most 3 times the source */
218 dst = talloc_array(mem_ctx, char, value.length * 3 + 1);
219 if ( ! dst) {
220 talloc_free(dst);
221 return NULL;
224 ldb_dn_escape_internal(dst, (const char *)value.data, value.length);
226 dst = talloc_realloc(mem_ctx, dst, char, strlen(dst) + 1);
228 return dst;
232 explode a DN string into a ldb_dn structure
233 based on RFC4514 except that we don't support multiple valued RDNs
235 static bool ldb_dn_explode(struct ldb_dn *dn)
237 char *p, *ex_name, *ex_value, *data, *d, *dt, *t;
238 bool trim = false;
239 bool in_extended = false;
240 bool in_ex_name = false;
241 bool in_ex_value = false;
242 bool in_attr = false;
243 bool in_value = false;
244 bool in_quote = false;
245 bool is_oid = false;
246 bool escape = false;
247 unsigned x;
248 int l, ret;
249 char *parse_dn;
251 if ( ! dn || dn->invalid) return false;
253 if (dn->components) {
254 return true;
257 if (dn->ext_linearized) {
258 parse_dn = dn->ext_linearized;
259 } else {
260 parse_dn = dn->linearized;
263 if ( ! parse_dn ) {
264 return false;
267 /* Empty DNs */
268 if (parse_dn[0] == '\0') {
269 return true;
272 /* Special DNs case */
273 if (dn->special) {
274 return true;
277 /* make sure we free this if alloced previously before replacing */
278 talloc_free(dn->components);
280 talloc_free(dn->ext_components);
281 dn->ext_components = NULL;
283 /* in the common case we have 3 or more components */
284 /* make sure all components are zeroed, other functions depend on it */
285 dn->components = talloc_zero_array(dn, struct ldb_dn_component, 3);
286 if ( ! dn->components) {
287 return false;
289 dn->comp_num = 0;
291 /* Components data space is allocated here once */
292 data = talloc_array(dn->components, char, strlen(parse_dn) + 1);
293 if (!data) {
294 return false;
297 p = parse_dn;
298 in_extended = true;
299 in_ex_name = false;
300 in_ex_value = false;
301 trim = true;
302 t = NULL;
303 d = dt = data;
305 while (*p) {
306 if (in_extended) {
308 if (!in_ex_name && !in_ex_value) {
310 if (p[0] == '<') {
311 p++;
312 ex_name = d;
313 in_ex_name = true;
314 continue;
315 } else if (p[0] == '\0') {
316 p++;
317 continue;
318 } else {
319 in_extended = false;
320 in_attr = true;
321 dt = d;
323 continue;
327 if (in_ex_name && *p == '=') {
328 *d++ = '\0';
329 p++;
330 ex_value = d;
331 in_ex_name = false;
332 in_ex_value = true;
333 continue;
336 if (in_ex_value && *p == '>') {
337 const struct ldb_dn_extended_syntax *ext_syntax;
338 struct ldb_val ex_val = {
339 .data = (uint8_t *)ex_value,
340 .length = d - ex_value
343 *d++ = '\0';
344 p++;
345 in_ex_value = false;
347 /* Process name and ex_value */
349 dn->ext_components = talloc_realloc(dn,
350 dn->ext_components,
351 struct ldb_dn_ext_component,
352 dn->ext_comp_num + 1);
353 if ( ! dn->ext_components) {
354 /* ouch ! */
355 goto failed;
358 ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, ex_name);
359 if (!ext_syntax) {
360 /* We don't know about this type of extended DN */
361 goto failed;
364 dn->ext_components[dn->ext_comp_num].name = talloc_strdup(dn->ext_components, ex_name);
365 if (!dn->ext_components[dn->ext_comp_num].name) {
366 /* ouch */
367 goto failed;
369 ret = ext_syntax->read_fn(dn->ldb, dn->ext_components,
370 &ex_val, &dn->ext_components[dn->ext_comp_num].value);
371 if (ret != LDB_SUCCESS) {
372 dn->invalid = true;
373 goto failed;
376 dn->ext_comp_num++;
378 if (*p == '\0') {
379 /* We have reached the end (extended component only)! */
380 talloc_free(data);
381 return true;
383 } else if (*p == ';') {
384 p++;
385 continue;
386 } else {
387 dn->invalid = true;
388 goto failed;
392 *d++ = *p++;
393 continue;
395 if (in_attr) {
396 if (trim) {
397 if (*p == ' ') {
398 p++;
399 continue;
402 /* first char */
403 trim = false;
405 if (!isascii(*p)) {
406 /* attr names must be ascii only */
407 dn->invalid = true;
408 goto failed;
411 if (isdigit(*p)) {
412 is_oid = true;
413 } else
414 if ( ! isalpha(*p)) {
415 /* not a digit nor an alpha,
416 * invalid attribute name */
417 dn->invalid = true;
418 goto failed;
421 /* Copy this character across from parse_dn,
422 * now we have trimmed out spaces */
423 *d++ = *p++;
424 continue;
427 if (*p == ' ') {
428 p++;
429 /* valid only if we are at the end */
430 trim = true;
431 continue;
434 if (trim && (*p != '=')) {
435 /* spaces/tabs are not allowed */
436 dn->invalid = true;
437 goto failed;
440 if (*p == '=') {
441 /* attribute terminated */
442 in_attr = false;
443 in_value = true;
444 trim = true;
445 l = 0;
447 /* Terminate this string in d
448 * (which is a copy of parse_dn
449 * with spaces trimmed) */
450 *d++ = '\0';
451 dn->components[dn->comp_num].name = talloc_strdup(dn->components, dt);
452 if ( ! dn->components[dn->comp_num].name) {
453 /* ouch */
454 goto failed;
457 dt = d;
459 p++;
460 continue;
463 if (!isascii(*p)) {
464 /* attr names must be ascii only */
465 dn->invalid = true;
466 goto failed;
469 if (is_oid && ( ! (isdigit(*p) || (*p == '.')))) {
470 /* not a digit nor a dot,
471 * invalid attribute oid */
472 dn->invalid = true;
473 goto failed;
474 } else
475 if ( ! (isalpha(*p) || isdigit(*p) || (*p == '-'))) {
476 /* not ALPHA, DIGIT or HYPHEN */
477 dn->invalid = true;
478 goto failed;
481 *d++ = *p++;
482 continue;
485 if (in_value) {
486 if (in_quote) {
487 if (*p == '\"') {
488 if (p[-1] != '\\') {
489 p++;
490 in_quote = false;
491 continue;
494 *d++ = *p++;
495 l++;
496 continue;
499 if (trim) {
500 if (*p == ' ') {
501 p++;
502 continue;
505 /* first char */
506 trim = false;
508 if (*p == '\"') {
509 in_quote = true;
510 p++;
511 continue;
515 switch (*p) {
517 /* TODO: support ber encoded values
518 case '#':
521 case ',':
522 if (escape) {
523 *d++ = *p++;
524 l++;
525 escape = false;
526 continue;
528 /* ok found value terminator */
530 if ( t ) {
531 /* trim back */
532 d -= (p - t);
533 l -= (p - t);
536 in_attr = true;
537 in_value = false;
538 trim = true;
540 p++;
541 *d++ = '\0';
542 dn->components[dn->comp_num].value.data = (uint8_t *)talloc_strdup(dn->components, dt);
543 dn->components[dn->comp_num].value.length = l;
544 if ( ! dn->components[dn->comp_num].value.data) {
545 /* ouch ! */
546 goto failed;
549 dt = d;
551 dn->comp_num++;
552 if (dn->comp_num > 2) {
553 dn->components = talloc_realloc(dn,
554 dn->components,
555 struct ldb_dn_component,
556 dn->comp_num + 1);
557 if ( ! dn->components) {
558 /* ouch ! */
559 goto failed;
561 /* make sure all components are zeroed, other functions depend on this */
562 memset(&dn->components[dn->comp_num], '\0', sizeof(struct ldb_dn_component));
565 continue;
567 case '=':
568 case '\n':
569 case '+':
570 case '<':
571 case '>':
572 case '#':
573 case ';':
574 case '\"':
575 /* a string with not escaped specials is invalid (tested) */
576 if ( ! escape) {
577 dn->invalid = true;
578 goto failed;
580 escape = false;
582 *d++ = *p++;
583 l++;
585 if ( t ) t = NULL;
586 break;
588 case '\\':
589 if ( ! escape) {
590 escape = true;
591 p++;
592 continue;
594 escape = false;
596 *d++ = *p++;
597 l++;
599 if ( t ) t = NULL;
600 break;
602 default:
603 if (escape) {
604 if (sscanf(p, "%02x", &x) != 1) {
605 /* invalid escaping sequence */
606 dn->invalid = true;
607 goto failed;
609 escape = false;
611 p += 2;
612 *d++ = (unsigned char)x;
613 l++;
615 if ( t ) t = NULL;
616 break;
619 if (*p == ' ') {
620 if ( ! t) t = p;
621 } else {
622 if ( t ) t = NULL;
625 *d++ = *p++;
626 l++;
628 break;
634 if (in_attr || in_quote) {
635 /* invalid dn */
636 dn->invalid = true;
637 goto failed;
640 /* save last element */
641 if ( t ) {
642 /* trim back */
643 d -= (p - t);
644 l -= (p - t);
647 *d++ = '\0';
648 dn->components[dn->comp_num].value.length = l;
649 dn->components[dn->comp_num].value.data =
650 (uint8_t *)talloc_strdup(dn->components, dt);
651 if ( ! dn->components[dn->comp_num].value.data) {
652 /* ouch */
653 goto failed;
656 dn->comp_num++;
658 talloc_free(data);
659 return true;
661 failed:
662 dn->comp_num = 0;
663 talloc_free(dn->components);
664 return false;
667 bool ldb_dn_validate(struct ldb_dn *dn)
669 return ldb_dn_explode(dn);
672 const char *ldb_dn_get_linearized(struct ldb_dn *dn)
674 int i, len;
675 char *d, *n;
677 if ( ! dn || ( dn->invalid)) return NULL;
679 if (dn->linearized) return dn->linearized;
681 if ( ! dn->components) {
682 dn->invalid = true;
683 return NULL;
686 if (dn->comp_num == 0) {
687 dn->linearized = talloc_strdup(dn, "");
688 if ( ! dn->linearized) return NULL;
689 return dn->linearized;
692 /* calculate maximum possible length of DN */
693 for (len = 0, i = 0; i < dn->comp_num; i++) {
694 /* name len */
695 len += strlen(dn->components[i].name);
696 /* max escaped data len */
697 len += (dn->components[i].value.length * 3);
698 len += 2; /* '=' and ',' */
700 dn->linearized = talloc_array(dn, char, len);
701 if ( ! dn->linearized) return NULL;
703 d = dn->linearized;
705 for (i = 0; i < dn->comp_num; i++) {
707 /* copy the name */
708 n = dn->components[i].name;
709 while (*n) *d++ = *n++;
711 *d++ = '=';
713 /* and the value */
714 d += ldb_dn_escape_internal( d,
715 (char *)dn->components[i].value.data,
716 dn->components[i].value.length);
717 *d++ = ',';
720 *(--d) = '\0';
722 /* don't waste more memory than necessary */
723 dn->linearized = talloc_realloc(dn, dn->linearized,
724 char, (d - dn->linearized + 1));
726 return dn->linearized;
729 char *ldb_dn_get_extended_linearized(void *mem_ctx, struct ldb_dn *dn, int mode)
731 const char *linearized = ldb_dn_get_linearized(dn);
732 char *p;
733 int i;
735 if (!linearized) {
736 return NULL;
739 if (!ldb_dn_has_extended(dn)) {
740 return talloc_strdup(mem_ctx, linearized);
743 if (!ldb_dn_validate(dn)) {
744 return NULL;
747 for (i = 0; i < dn->ext_comp_num; i++) {
748 const struct ldb_dn_extended_syntax *ext_syntax;
749 const char *name = dn->ext_components[i].name;
750 struct ldb_val ec_val = dn->ext_components[i].value;
751 struct ldb_val val;
752 int ret;
754 ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name);
756 if (mode == 1) {
757 ret = ext_syntax->write_clear_fn(dn->ldb, mem_ctx,
758 &ec_val, &val);
759 } else if (mode == 0) {
760 ret = ext_syntax->write_hex_fn(dn->ldb, mem_ctx,
761 &ec_val, &val);
762 } else {
763 ret = -1;
766 if (ret != LDB_SUCCESS) {
767 return NULL;
770 if (i == 0) {
771 p = talloc_asprintf(mem_ctx, "<%s=%s>",
772 name, val.data);
773 } else {
774 p = talloc_asprintf_append(p, ";<%s=%s>",
775 name, val.data);
778 talloc_free(val.data);
780 if (!p) {
781 return NULL;
785 if (dn->ext_comp_num && *linearized) {
786 p = talloc_asprintf_append(p, ";%s", linearized);
789 if (!p) {
790 return NULL;
793 return p;
798 char *ldb_dn_alloc_linearized(void *mem_ctx, struct ldb_dn *dn)
800 return talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn));
804 casefold a dn. We need to casefold the attribute names, and canonicalize
805 attribute values of case insensitive attributes.
808 static bool ldb_dn_casefold_internal(struct ldb_dn *dn)
810 int i, ret;
812 if ( ! dn || dn->invalid) return false;
814 if (dn->valid_case) return true;
816 if (( ! dn->components) && ( ! ldb_dn_explode(dn))) {
817 return false;
820 for (i = 0; i < dn->comp_num; i++) {
821 const struct ldb_schema_attribute *a;
823 dn->components[i].cf_name =
824 ldb_attr_casefold(dn->components,
825 dn->components[i].name);
826 if (!dn->components[i].cf_name) {
827 goto failed;
830 a = ldb_schema_attribute_by_name(dn->ldb,
831 dn->components[i].cf_name);
833 ret = a->syntax->canonicalise_fn(dn->ldb, dn->components,
834 &(dn->components[i].value),
835 &(dn->components[i].cf_value));
836 if (ret != 0) {
837 goto failed;
841 dn->valid_case = true;
843 return true;
845 failed:
846 for (i = 0; i < dn->comp_num; i++) {
847 LDB_FREE(dn->components[i].cf_name);
848 LDB_FREE(dn->components[i].cf_value.data);
850 return false;
853 const char *ldb_dn_get_casefold(struct ldb_dn *dn)
855 int i, len;
856 char *d, *n;
858 if (dn->casefold) return dn->casefold;
860 if (dn->special) {
861 dn->casefold = talloc_strdup(dn, dn->linearized);
862 if (!dn->casefold) return NULL;
863 dn->valid_case = true;
864 return dn->casefold;
867 if ( ! ldb_dn_casefold_internal(dn)) {
868 return NULL;
871 if (dn->comp_num == 0) {
872 dn->casefold = talloc_strdup(dn, "");
873 return dn->casefold;
876 /* calculate maximum possible length of DN */
877 for (len = 0, i = 0; i < dn->comp_num; i++) {
878 /* name len */
879 len += strlen(dn->components[i].cf_name);
880 /* max escaped data len */
881 len += (dn->components[i].cf_value.length * 3);
882 len += 2; /* '=' and ',' */
884 dn->casefold = talloc_array(dn, char, len);
885 if ( ! dn->casefold) return NULL;
887 d = dn->casefold;
889 for (i = 0; i < dn->comp_num; i++) {
891 /* copy the name */
892 n = dn->components[i].cf_name;
893 while (*n) *d++ = *n++;
895 *d++ = '=';
897 /* and the value */
898 d += ldb_dn_escape_internal( d,
899 (char *)dn->components[i].cf_value.data,
900 dn->components[i].cf_value.length);
901 *d++ = ',';
903 *(--d) = '\0';
905 /* don't waste more memory than necessary */
906 dn->casefold = talloc_realloc(dn, dn->casefold,
907 char, strlen(dn->casefold) + 1);
909 return dn->casefold;
912 char *ldb_dn_alloc_casefold(void *mem_ctx, struct ldb_dn *dn)
914 return talloc_strdup(mem_ctx, ldb_dn_get_casefold(dn));
917 /* Determine if dn is below base, in the ldap tree. Used for
918 * evaluating a subtree search.
919 * 0 if they match, otherwise non-zero
922 int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn)
924 int ret;
925 int n_base, n_dn;
927 if ( ! base || base->invalid) return 1;
928 if ( ! dn || dn->invalid) return -1;
930 if (( ! base->valid_case) || ( ! dn->valid_case)) {
931 if (base->linearized && dn->linearized) {
932 /* try with a normal compare first, if we are lucky
933 * we will avoid exploding and casfolding */
934 int dif;
935 dif = strlen(dn->linearized) - strlen(base->linearized);
936 if (dif < 0) {
937 return dif;
939 if (strcmp(base->linearized,
940 &dn->linearized[dif]) == 0) {
941 return 0;
945 if ( ! ldb_dn_casefold_internal(base)) {
946 return 1;
949 if ( ! ldb_dn_casefold_internal(dn)) {
950 return -1;
955 /* if base has more components,
956 * they don't have the same base */
957 if (base->comp_num > dn->comp_num) {
958 return (dn->comp_num - base->comp_num);
961 if (dn->comp_num == 0) {
962 if (dn->special && base->special) {
963 return strcmp(base->linearized, dn->linearized);
964 } else if (dn->special) {
965 return -1;
966 } else if (base->special) {
967 return 1;
968 } else {
969 return 0;
973 n_base = base->comp_num - 1;
974 n_dn = dn->comp_num - 1;
976 while (n_base >= 0) {
977 char *b_name = base->components[n_base].cf_name;
978 char *dn_name = dn->components[n_dn].cf_name;
980 char *b_vdata = (char *)base->components[n_base].cf_value.data;
981 char *dn_vdata = (char *)dn->components[n_dn].cf_value.data;
983 size_t b_vlen = base->components[n_base].cf_value.length;
984 size_t dn_vlen = dn->components[n_dn].cf_value.length;
986 /* compare attr names */
987 ret = strcmp(b_name, dn_name);
988 if (ret != 0) return ret;
990 /* compare attr.cf_value. */
991 if (b_vlen != dn_vlen) {
992 return b_vlen - dn_vlen;
994 ret = strcmp(b_vdata, dn_vdata);
995 if (ret != 0) return ret;
997 n_base--;
998 n_dn--;
1001 return 0;
1004 /* compare DNs using casefolding compare functions.
1006 If they match, then return 0
1009 int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1)
1011 int i, ret;
1013 if (( ! dn0) || dn0->invalid || ! dn1 || dn1->invalid) {
1014 return -1;
1017 if (( ! dn0->valid_case) || ( ! dn1->valid_case)) {
1018 if (dn0->linearized && dn1->linearized) {
1019 /* try with a normal compare first, if we are lucky
1020 * we will avoid exploding and casfolding */
1021 if (strcmp(dn0->linearized, dn1->linearized) == 0) {
1022 return 0;
1026 if ( ! ldb_dn_casefold_internal(dn0)) {
1027 return 1;
1030 if ( ! ldb_dn_casefold_internal(dn1)) {
1031 return -1;
1036 if (dn0->comp_num != dn1->comp_num) {
1037 return (dn1->comp_num - dn0->comp_num);
1040 if (dn0->comp_num == 0) {
1041 if (dn0->special && dn1->special) {
1042 return strcmp(dn0->linearized, dn1->linearized);
1043 } else if (dn0->special) {
1044 return 1;
1045 } else if (dn1->special) {
1046 return -1;
1047 } else {
1048 return 0;
1052 for (i = 0; i < dn0->comp_num; i++) {
1053 char *dn0_name = dn0->components[i].cf_name;
1054 char *dn1_name = dn1->components[i].cf_name;
1056 char *dn0_vdata = (char *)dn0->components[i].cf_value.data;
1057 char *dn1_vdata = (char *)dn1->components[i].cf_value.data;
1059 size_t dn0_vlen = dn0->components[i].cf_value.length;
1060 size_t dn1_vlen = dn1->components[i].cf_value.length;
1062 /* compare attr names */
1063 ret = strcmp(dn0_name, dn1_name);
1064 if (ret != 0) {
1065 return ret;
1068 /* compare attr.cf_value. */
1069 if (dn0_vlen != dn1_vlen) {
1070 return dn0_vlen - dn1_vlen;
1072 ret = strcmp(dn0_vdata, dn1_vdata);
1073 if (ret != 0) {
1074 return ret;
1078 return 0;
1081 static struct ldb_dn_component ldb_dn_copy_component(
1082 void *mem_ctx,
1083 struct ldb_dn_component *src)
1085 struct ldb_dn_component dst;
1087 memset(&dst, 0, sizeof(dst));
1089 if (src == NULL) {
1090 return dst;
1093 dst.value = ldb_val_dup(mem_ctx, &(src->value));
1094 if (dst.value.data == NULL) {
1095 return dst;
1098 dst.name = talloc_strdup(mem_ctx, src->name);
1099 if (dst.name == NULL) {
1100 LDB_FREE(dst.value.data);
1101 return dst;
1104 if (src->cf_value.data) {
1105 dst.cf_value = ldb_val_dup(mem_ctx, &(src->cf_value));
1106 if (dst.cf_value.data == NULL) {
1107 LDB_FREE(dst.value.data);
1108 LDB_FREE(dst.name);
1109 return dst;
1112 dst.cf_name = talloc_strdup(mem_ctx, src->cf_name);
1113 if (dst.cf_name == NULL) {
1114 LDB_FREE(dst.cf_name);
1115 LDB_FREE(dst.value.data);
1116 LDB_FREE(dst.name);
1117 return dst;
1119 } else {
1120 dst.cf_value.data = NULL;
1121 dst.cf_name = NULL;
1124 return dst;
1127 static struct ldb_dn_ext_component ldb_dn_ext_copy_component(
1128 void *mem_ctx,
1129 struct ldb_dn_ext_component *src)
1131 struct ldb_dn_ext_component dst;
1133 memset(&dst, 0, sizeof(dst));
1135 if (src == NULL) {
1136 return dst;
1139 dst.value = ldb_val_dup(mem_ctx, &(src->value));
1140 if (dst.value.data == NULL) {
1141 return dst;
1144 dst.name = talloc_strdup(mem_ctx, src->name);
1145 if (dst.name == NULL) {
1146 LDB_FREE(dst.value.data);
1147 return dst;
1150 return dst;
1153 struct ldb_dn *ldb_dn_copy(void *mem_ctx, struct ldb_dn *dn)
1155 struct ldb_dn *new_dn;
1157 if (!dn || dn->invalid) {
1158 return NULL;
1161 new_dn = talloc_zero(mem_ctx, struct ldb_dn);
1162 if ( !new_dn) {
1163 return NULL;
1166 *new_dn = *dn;
1168 if (dn->components) {
1169 int i;
1171 new_dn->components =
1172 talloc_zero_array(new_dn,
1173 struct ldb_dn_component,
1174 dn->comp_num);
1175 if ( ! new_dn->components) {
1176 talloc_free(new_dn);
1177 return NULL;
1180 for (i = 0; i < dn->comp_num; i++) {
1181 new_dn->components[i] =
1182 ldb_dn_copy_component(new_dn->components,
1183 &dn->components[i]);
1184 if ( ! new_dn->components[i].value.data) {
1185 talloc_free(new_dn);
1186 return NULL;
1191 if (dn->ext_components) {
1192 int i;
1194 new_dn->ext_components =
1195 talloc_zero_array(new_dn,
1196 struct ldb_dn_ext_component,
1197 dn->ext_comp_num);
1198 if ( ! new_dn->ext_components) {
1199 talloc_free(new_dn);
1200 return NULL;
1203 for (i = 0; i < dn->ext_comp_num; i++) {
1204 new_dn->ext_components[i] =
1205 ldb_dn_ext_copy_component(
1206 new_dn->ext_components,
1207 &dn->ext_components[i]);
1208 if ( ! new_dn->ext_components[i].value.data) {
1209 talloc_free(new_dn);
1210 return NULL;
1215 if (dn->casefold) {
1216 new_dn->casefold = talloc_strdup(new_dn, dn->casefold);
1217 if ( ! new_dn->casefold) {
1218 talloc_free(new_dn);
1219 return NULL;
1223 if (dn->linearized) {
1224 new_dn->linearized = talloc_strdup(new_dn, dn->linearized);
1225 if ( ! new_dn->linearized) {
1226 talloc_free(new_dn);
1227 return NULL;
1231 if (dn->ext_linearized) {
1232 new_dn->ext_linearized = talloc_strdup(new_dn,
1233 dn->ext_linearized);
1234 if ( ! new_dn->ext_linearized) {
1235 talloc_free(new_dn);
1236 return NULL;
1240 return new_dn;
1243 /* modify the given dn by adding a base.
1245 * return true if successful and false if not
1246 * if false is returned the dn may be marked invalid
1248 bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base)
1250 const char *s;
1251 char *t;
1253 if ( !base || base->invalid || !dn || dn->invalid) {
1254 return false;
1257 if (dn->components) {
1258 int i;
1260 if ( ! ldb_dn_validate(base)) {
1261 return false;
1264 s = NULL;
1265 if (dn->valid_case) {
1266 if ( ! (s = ldb_dn_get_casefold(base))) {
1267 return false;
1271 dn->components = talloc_realloc(dn,
1272 dn->components,
1273 struct ldb_dn_component,
1274 dn->comp_num + base->comp_num);
1275 if ( ! dn->components) {
1276 dn->invalid = true;
1277 return false;
1280 for (i = 0; i < base->comp_num; dn->comp_num++, i++) {
1281 dn->components[dn->comp_num] =
1282 ldb_dn_copy_component(dn->components,
1283 &base->components[i]);
1284 if (dn->components[dn->comp_num].value.data == NULL) {
1285 dn->invalid = true;
1286 return false;
1290 if (dn->casefold && s) {
1291 if (*dn->casefold) {
1292 t = talloc_asprintf(dn, "%s,%s",
1293 dn->casefold, s);
1294 } else {
1295 t = talloc_strdup(dn, s);
1297 LDB_FREE(dn->casefold);
1298 dn->casefold = t;
1302 if (dn->linearized) {
1304 s = ldb_dn_get_linearized(base);
1305 if ( ! s) {
1306 return false;
1309 if (*dn->linearized) {
1310 t = talloc_asprintf(dn, "%s,%s",
1311 dn->linearized, s);
1312 } else {
1313 t = talloc_strdup(dn, s);
1315 if ( ! t) {
1316 dn->invalid = true;
1317 return false;
1319 LDB_FREE(dn->linearized);
1320 dn->linearized = t;
1323 /* Wipe the ext_linearized DN,
1324 * the GUID and SID are almost certainly no longer valid */
1325 if (dn->ext_linearized) {
1326 LDB_FREE(dn->ext_linearized);
1329 LDB_FREE(dn->ext_components);
1330 dn->ext_comp_num = 0;
1331 return true;
1334 /* modify the given dn by adding a base.
1336 * return true if successful and false if not
1337 * if false is returned the dn may be marked invalid
1339 bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...)
1341 struct ldb_dn *base;
1342 char *base_str;
1343 va_list ap;
1344 bool ret;
1346 if ( !dn || dn->invalid) {
1347 return false;
1350 va_start(ap, base_fmt);
1351 base_str = talloc_vasprintf(dn, base_fmt, ap);
1352 va_end(ap);
1354 if (base_str == NULL) {
1355 return false;
1358 base = ldb_dn_new(base_str, dn->ldb, base_str);
1360 ret = ldb_dn_add_base(dn, base);
1362 talloc_free(base_str);
1364 return ret;
1367 /* modify the given dn by adding children elements.
1369 * return true if successful and false if not
1370 * if false is returned the dn may be marked invalid
1372 bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child)
1374 const char *s;
1375 char *t;
1377 if ( !child || child->invalid || !dn || dn->invalid) {
1378 return false;
1381 if (dn->components) {
1382 int n, i, j;
1384 if ( ! ldb_dn_validate(child)) {
1385 return false;
1388 s = NULL;
1389 if (dn->valid_case) {
1390 if ( ! (s = ldb_dn_get_casefold(child))) {
1391 return false;
1395 n = dn->comp_num + child->comp_num;
1397 dn->components = talloc_realloc(dn,
1398 dn->components,
1399 struct ldb_dn_component,
1401 if ( ! dn->components) {
1402 dn->invalid = true;
1403 return false;
1406 for (i = dn->comp_num - 1, j = n - 1; i >= 0; i--, j--) {
1407 dn->components[j] = dn->components[i];
1410 for (i = 0; i < child->comp_num; i++) {
1411 dn->components[i] =
1412 ldb_dn_copy_component(dn->components,
1413 &child->components[i]);
1414 if (dn->components[i].value.data == NULL) {
1415 dn->invalid = true;
1416 return false;
1420 dn->comp_num = n;
1422 if (dn->casefold && s) {
1423 t = talloc_asprintf(dn, "%s,%s", s, dn->casefold);
1424 LDB_FREE(dn->casefold);
1425 dn->casefold = t;
1429 if (dn->linearized) {
1431 s = ldb_dn_get_linearized(child);
1432 if ( ! s) {
1433 return false;
1436 t = talloc_asprintf(dn, "%s,%s", s, dn->linearized);
1437 if ( ! t) {
1438 dn->invalid = true;
1439 return false;
1441 LDB_FREE(dn->linearized);
1442 dn->linearized = t;
1445 /* Wipe the ext_linearized DN,
1446 * the GUID and SID are almost certainly no longer valid */
1447 LDB_FREE(dn->ext_linearized);
1449 LDB_FREE(dn->ext_components);
1450 dn->ext_comp_num = 0;
1452 return true;
1455 /* modify the given dn by adding children elements.
1457 * return true if successful and false if not
1458 * if false is returned the dn may be marked invalid
1460 bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...)
1462 struct ldb_dn *child;
1463 char *child_str;
1464 va_list ap;
1465 bool ret;
1467 if ( !dn || dn->invalid) {
1468 return false;
1471 va_start(ap, child_fmt);
1472 child_str = talloc_vasprintf(dn, child_fmt, ap);
1473 va_end(ap);
1475 if (child_str == NULL) {
1476 return false;
1479 child = ldb_dn_new(child_str, dn->ldb, child_str);
1481 ret = ldb_dn_add_child(dn, child);
1483 talloc_free(child_str);
1485 return ret;
1488 bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num)
1490 int i;
1492 if ( ! ldb_dn_validate(dn)) {
1493 return false;
1496 if (dn->comp_num < num) {
1497 return false;
1500 /* free components */
1501 for (i = num; i > 0; i--) {
1502 LDB_FREE(dn->components[dn->comp_num - i].name);
1503 LDB_FREE(dn->components[dn->comp_num - i].value.data);
1504 LDB_FREE(dn->components[dn->comp_num - i].cf_name);
1505 LDB_FREE(dn->components[dn->comp_num - i].cf_value.data);
1508 dn->comp_num -= num;
1510 if (dn->valid_case) {
1511 for (i = 0; i < dn->comp_num; i++) {
1512 LDB_FREE(dn->components[i].cf_name);
1513 LDB_FREE(dn->components[i].cf_value.data);
1515 dn->valid_case = false;
1518 LDB_FREE(dn->casefold);
1519 LDB_FREE(dn->linearized);
1521 /* Wipe the ext_linearized DN,
1522 * the GUID and SID are almost certainly no longer valid */
1523 LDB_FREE(dn->ext_linearized);
1525 LDB_FREE(dn->ext_components);
1526 dn->ext_comp_num = 0;
1528 return true;
1531 bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num)
1533 int i, j;
1535 if ( ! ldb_dn_validate(dn)) {
1536 return false;
1539 if (dn->comp_num < num) {
1540 return false;
1543 for (i = 0, j = num; j < dn->comp_num; i++, j++) {
1544 if (i < num) {
1545 LDB_FREE(dn->components[i].name);
1546 LDB_FREE(dn->components[i].value.data);
1547 LDB_FREE(dn->components[i].cf_name);
1548 LDB_FREE(dn->components[i].cf_value.data);
1550 dn->components[i] = dn->components[j];
1553 dn->comp_num -= num;
1555 if (dn->valid_case) {
1556 for (i = 0; i < dn->comp_num; i++) {
1557 LDB_FREE(dn->components[i].cf_name);
1558 LDB_FREE(dn->components[i].cf_value.data);
1560 dn->valid_case = false;
1563 LDB_FREE(dn->casefold);
1564 LDB_FREE(dn->linearized);
1566 /* Wipe the ext_linearized DN,
1567 * the GUID and SID are almost certainly no longer valid */
1568 LDB_FREE(dn->ext_linearized);
1570 LDB_FREE(dn->ext_components);
1571 dn->ext_comp_num = 0;
1572 return true;
1575 struct ldb_dn *ldb_dn_get_parent(void *mem_ctx, struct ldb_dn *dn)
1577 struct ldb_dn *new_dn;
1579 new_dn = ldb_dn_copy(mem_ctx, dn);
1580 if ( !new_dn ) {
1581 return NULL;
1584 if ( ! ldb_dn_remove_child_components(new_dn, 1)) {
1585 talloc_free(new_dn);
1586 return NULL;
1589 /* Wipe the ext_linearized DN,
1590 * the GUID and SID are almost certainly no longer valid */
1591 LDB_FREE(dn->ext_linearized);
1593 LDB_FREE(dn->ext_components);
1594 dn->ext_comp_num = 0;
1595 return new_dn;
1598 /* Create a 'canonical name' string from a DN:
1600 ie dc=samba,dc=org -> samba.org/
1601 uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator
1603 There are two formats,
1604 the EX format has the last '/' replaced with a newline (\n).
1607 static char *ldb_dn_canonical(void *mem_ctx, struct ldb_dn *dn, int ex_format) {
1608 int i;
1609 TALLOC_CTX *tmpctx;
1610 char *cracked = NULL;
1611 const char *format = (ex_format ? "\n" : "/" );
1613 if ( ! ldb_dn_validate(dn)) {
1614 return NULL;
1617 tmpctx = talloc_new(mem_ctx);
1619 /* Walk backwards down the DN, grabbing 'dc' components at first */
1620 for (i = dn->comp_num - 1 ; i >= 0; i--) {
1621 if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) {
1622 break;
1624 if (cracked) {
1625 cracked = talloc_asprintf(tmpctx, "%s.%s",
1626 ldb_dn_escape_value(tmpctx,
1627 dn->components[i].value),
1628 cracked);
1629 } else {
1630 cracked = ldb_dn_escape_value(tmpctx,
1631 dn->components[i].value);
1633 if (!cracked) {
1634 goto done;
1638 /* Only domain components? Finish here */
1639 if (i < 0) {
1640 cracked = talloc_strdup_append_buffer(cracked, format);
1641 talloc_steal(mem_ctx, cracked);
1642 goto done;
1645 /* Now walk backwards appending remaining components */
1646 for (; i > 0; i--) {
1647 cracked = talloc_asprintf_append_buffer(cracked, "/%s",
1648 ldb_dn_escape_value(tmpctx,
1649 dn->components[i].value));
1650 if (!cracked) {
1651 goto done;
1655 /* Last one, possibly a newline for the 'ex' format */
1656 cracked = talloc_asprintf_append_buffer(cracked, "%s%s", format,
1657 ldb_dn_escape_value(tmpctx,
1658 dn->components[i].value));
1660 talloc_steal(mem_ctx, cracked);
1661 done:
1662 talloc_free(tmpctx);
1663 return cracked;
1666 /* Wrapper functions for the above, for the two different string formats */
1667 char *ldb_dn_canonical_string(void *mem_ctx, struct ldb_dn *dn) {
1668 return ldb_dn_canonical(mem_ctx, dn, 0);
1672 char *ldb_dn_canonical_ex_string(void *mem_ctx, struct ldb_dn *dn) {
1673 return ldb_dn_canonical(mem_ctx, dn, 1);
1676 int ldb_dn_get_comp_num(struct ldb_dn *dn)
1678 if ( ! ldb_dn_validate(dn)) {
1679 return -1;
1681 return dn->comp_num;
1684 const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num)
1686 if ( ! ldb_dn_validate(dn)) {
1687 return NULL;
1689 if (num >= dn->comp_num) return NULL;
1690 return dn->components[num].name;
1693 const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn,
1694 unsigned int num)
1696 if ( ! ldb_dn_validate(dn)) {
1697 return NULL;
1699 if (num >= dn->comp_num) return NULL;
1700 return &dn->components[num].value;
1703 const char *ldb_dn_get_rdn_name(struct ldb_dn *dn)
1705 if ( ! ldb_dn_validate(dn)) {
1706 return NULL;
1708 if (dn->comp_num == 0) return NULL;
1709 return dn->components[0].name;
1712 const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn)
1714 if ( ! ldb_dn_validate(dn)) {
1715 return NULL;
1717 if (dn->comp_num == 0) return NULL;
1718 return &dn->components[0].value;
1721 int ldb_dn_set_component(struct ldb_dn *dn, int num,
1722 const char *name, const struct ldb_val val)
1724 char *n;
1725 struct ldb_val v;
1727 if ( ! ldb_dn_validate(dn)) {
1728 return LDB_ERR_OTHER;
1731 if (num >= dn->comp_num) {
1732 return LDB_ERR_OTHER;
1735 n = talloc_strdup(dn, name);
1736 if ( ! n) {
1737 return LDB_ERR_OTHER;
1740 v.length = val.length;
1741 v.data = (uint8_t *)talloc_memdup(dn, val.data, v.length+1);
1742 if ( ! v.data) {
1743 talloc_free(n);
1744 return LDB_ERR_OTHER;
1747 talloc_free(dn->components[num].name);
1748 talloc_free(dn->components[num].value.data);
1749 dn->components[num].name = n;
1750 dn->components[num].value = v;
1752 if (dn->valid_case) {
1753 int i;
1754 for (i = 0; i < dn->comp_num; i++) {
1755 LDB_FREE(dn->components[i].cf_name);
1756 LDB_FREE(dn->components[i].cf_value.data);
1758 dn->valid_case = false;
1760 LDB_FREE(dn->casefold);
1761 LDB_FREE(dn->linearized);
1763 /* Wipe the ext_linearized DN,
1764 * the GUID and SID are almost certainly no longer valid */
1765 LDB_FREE(dn->ext_linearized);
1767 dn->ext_comp_num = 0;
1768 LDB_FREE(dn->ext_components);
1769 return LDB_SUCCESS;
1772 const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn,
1773 const char *name)
1775 int i;
1776 if ( ! ldb_dn_validate(dn)) {
1777 return NULL;
1779 for (i=0; i < dn->ext_comp_num; i++) {
1780 if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) {
1781 return &dn->ext_components[i].value;
1784 return NULL;
1787 int ldb_dn_set_extended_component(struct ldb_dn *dn,
1788 const char *name, const struct ldb_val *val)
1790 struct ldb_dn_ext_component *p;
1791 int i;
1793 if ( ! ldb_dn_validate(dn)) {
1794 return LDB_ERR_OTHER;
1797 for (i=0; i < dn->ext_comp_num; i++) {
1798 if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) {
1799 if (val) {
1800 dn->ext_components[i].value =
1801 ldb_val_dup(dn->ext_components, val);
1803 dn->ext_components[i].name =
1804 talloc_strdup(dn->ext_components, name);
1805 if (!dn->ext_components[i].name ||
1806 !dn->ext_components[i].value.data) {
1807 dn->invalid = true;
1808 return LDB_ERR_OPERATIONS_ERROR;
1811 } else {
1812 if (i != (dn->ext_comp_num - 1)) {
1813 memmove(&dn->ext_components[i],
1814 &dn->ext_components[i+1],
1815 ((dn->ext_comp_num-1) - i) *
1816 sizeof(*dn->ext_components));
1818 dn->ext_comp_num--;
1820 dn->ext_components = talloc_realloc(dn,
1821 dn->ext_components,
1822 struct ldb_dn_ext_component,
1823 dn->ext_comp_num);
1824 if (!dn->ext_components) {
1825 dn->invalid = true;
1826 return LDB_ERR_OPERATIONS_ERROR;
1828 return LDB_SUCCESS;
1833 p = dn->ext_components
1834 = talloc_realloc(dn,
1835 dn->ext_components,
1836 struct ldb_dn_ext_component,
1837 dn->ext_comp_num + 1);
1838 if (!dn->ext_components) {
1839 dn->invalid = true;
1840 return LDB_ERR_OPERATIONS_ERROR;
1843 p[dn->ext_comp_num].value = ldb_val_dup(dn->ext_components, val);
1844 p[dn->ext_comp_num].name = talloc_strdup(p, name);
1846 if (!dn->ext_components[i].name || !dn->ext_components[i].value.data) {
1847 dn->invalid = true;
1848 return LDB_ERR_OPERATIONS_ERROR;
1850 dn->ext_components = p;
1851 dn->ext_comp_num++;
1853 return LDB_SUCCESS;
1856 void ldb_dn_remove_extended_components(struct ldb_dn *dn)
1858 dn->ext_comp_num = 0;
1859 LDB_FREE(dn->ext_components);
1862 bool ldb_dn_is_valid(struct ldb_dn *dn)
1864 if ( ! dn) return false;
1865 return ! dn->invalid;
1868 bool ldb_dn_is_special(struct ldb_dn *dn)
1870 if ( ! dn || dn->invalid) return false;
1871 return dn->special;
1874 bool ldb_dn_has_extended(struct ldb_dn *dn)
1876 if ( ! dn || dn->invalid) return false;
1877 if (dn->ext_linearized && (dn->ext_linearized[0] == '<')) return true;
1878 return dn->ext_comp_num != 0;
1881 bool ldb_dn_check_special(struct ldb_dn *dn, const char *check)
1883 if ( ! dn || dn->invalid) return false;
1884 return ! strcmp(dn->linearized, check);
1887 bool ldb_dn_is_null(struct ldb_dn *dn)
1889 if ( ! dn || dn->invalid) return false;
1890 if (ldb_dn_has_extended(dn)) return false;
1891 if (dn->linearized && (dn->linearized[0] == '\0')) return true;
1892 return false;