4 Copyright (C) Simo Sorce 2005
6 ** NOTE! The following LGPL license applies to the ldb
7 ** library. This does NOT imply that all of Samba is released
10 This library is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Lesser General Public
12 License as published by the Free Software Foundation; either
13 version 2 of the License, or (at your option) any later version.
15 This library is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Lesser General Public License for more details.
20 You should have received a copy of the GNU Lesser General Public
21 License along with this library; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 * Component: ldb dn explode and utility functions
30 * Description: - explode a dn into it's own basic elements
31 * and put them in a structure
32 * - manipulate ldb_dn structures
38 #include "ldb/include/ldb.h"
39 #include "ldb/include/ldb_private.h"
42 #define LDB_DN_NULL_FAILED(x) if (!(x)) goto failed
44 #define LDB_SPECIAL "@SPECIAL"
46 int ldb_dn_is_special(const struct ldb_dn *dn)
48 if (dn == NULL || dn->comp_num != 1) return 0;
50 return ! strcmp(dn->components[0].name, LDB_SPECIAL);
53 int ldb_dn_check_special(const struct ldb_dn *dn, const char *check)
55 if (dn == NULL || dn->comp_num != 1) return 0;
57 return ! strcmp((char *)dn->components[0].value.data, check);
60 static int ldb_dn_is_valid_attribute_name(const char *name)
62 if (name == NULL) return 0;
65 if (! isascii(*name)) {
68 if (! (isalnum((unsigned char)*name) || *name == '-')) {
77 char *ldb_dn_escape_value(void *mem_ctx, struct ldb_val value)
79 const char *p, *s, *src;
86 p = s = src = (const char *)value.data;
89 /* allocate destination string, it will be at most 3 times the source */
90 dst = d = talloc_array(mem_ctx, char, len * 3 + 1);
91 LDB_DN_NULL_FAILED(dst);
93 while (p - src < len) {
95 p += strcspn(p, ",=\n+<>#;\\\"");
97 if (p - src == len) /* found no escapable chars */
100 memcpy(d, s, p - s); /* copy the part of the string before the stop */
101 d += (p - s); /* move to current position */
103 if (*p) { /* it is a normal escapable character */
106 } else { /* we have a zero byte in the string */
107 strncpy(d, "\00", 3); /* escape the zero */
109 p++; /* skip the zero */
111 s = p; /* move forward */
114 /* copy the last part (with zero) and return */
115 memcpy(d, s, &src[len] - s + 1);
124 static struct ldb_val ldb_dn_unescape_value(void *mem_ctx, const char *src)
126 struct ldb_val value;
128 char *p, *dst = NULL, *end;
132 LDB_DN_NULL_FAILED(src);
134 dst = p = talloc_memdup(mem_ctx, src, strlen(src) + 1);
135 LDB_DN_NULL_FAILED(dst);
137 end = &dst[strlen(dst)];
140 p += strcspn(p, ",=\n+<>#;\\\"");
143 if (strchr(",=\n+<>#;\\\"", p[1])) {
144 memmove(p, p + 1, end - (p + 1) + 1);
150 if (sscanf(p + 1, "%02x", &x) == 1) {
151 *p = (unsigned char)x;
152 memmove(p + 1, p + 3, end - (p + 3) + 1);
159 /* a string with not escaped specials is invalid (tested) */
165 value.length = end - dst;
166 value.data = (uint8_t *)dst;
174 /* check if the string contains quotes
175 * skips leading and trailing spaces
176 * - returns 0 if no quotes found
177 * - returns 1 if quotes are found and put their position
178 * in *quote_start and *quote_end parameters
179 * - return -1 if there are open quotes
182 static int get_quotes_position(const char *source, int *quote_start, int *quote_end)
186 if (source == NULL || quote_start == NULL || quote_end == NULL) return -1;
190 /* check if there are quotes surrounding the value */
191 p += strspn(p, " \n"); /* skip white spaces */
194 *quote_start = p - source;
199 LDB_DN_NULL_FAILED(p);
201 if (*(p - 1) == '\\')
205 *quote_end = p - source;
215 static char *seek_to_separator(char *string, const char *separators)
220 if (string == NULL || separators == NULL) return NULL;
222 p = strchr(string, '=');
223 LDB_DN_NULL_FAILED(p);
227 /* check if there are quotes surrounding the value */
229 ret = get_quotes_position(p, &qs, &qe);
233 if (ret == 1) { /* quotes found */
235 p += qe; /* positioning after quotes */
236 p += strspn(p, " \n"); /* skip white spaces after the quote */
238 if (strcspn(p, separators) != 0) /* if there are characters between quotes */
239 return NULL; /* and separators, the dn is invalid */
241 return p; /* return on the separator */
244 /* no quotes found seek to separators */
245 ret = strcspn(p, separators);
246 if (ret == 0) /* no separators ?! bail out */
255 static char *ldb_dn_trim_string(char *string, const char *edge)
259 /* seek out edge from start of string */
260 s = string + strspn(string, edge);
262 /* backwards skip from end of string */
263 p = &s[strlen(s) - 1];
264 while (p > s && strchr(edge, *p)) {
272 /* we choosed to not support multpile valued components */
273 static struct ldb_dn_component ldb_dn_explode_component(void *mem_ctx, char *raw_component)
275 struct ldb_dn_component dc;
279 if (raw_component == NULL) {
284 /* find attribute type/value separator */
285 p = strchr(raw_component, '=');
286 LDB_DN_NULL_FAILED(p);
288 *p++ = '\0'; /* terminate name and point to value */
290 /* copy and trim name in the component */
291 dc.name = talloc_strdup(mem_ctx, ldb_dn_trim_string(raw_component, " \n"));
295 if (! ldb_dn_is_valid_attribute_name(dc.name)) {
299 ret = get_quotes_position(p, &qs, &qe);
302 case 0: /* no quotes trim the string */
303 p = ldb_dn_trim_string(p, " \n");
304 dc.value = ldb_dn_unescape_value(mem_ctx, p);
307 case 1: /* quotes found get the unquoted string */
310 dc.value.length = strlen(p);
311 dc.value.data = talloc_memdup(mem_ctx, p, dc.value.length + 1);
314 default: /* mismatched quotes ot other error, bail out */
318 if (dc.value.length == 0) {
325 talloc_free(dc.name);
330 struct ldb_dn *ldb_dn_new(void *mem_ctx)
334 edn = talloc(mem_ctx, struct ldb_dn);
335 LDB_DN_NULL_FAILED(edn);
337 /* Initially there are no components */
339 edn->components = NULL;
347 struct ldb_dn *ldb_dn_explode(void *mem_ctx, const char *dn)
349 struct ldb_dn *edn; /* the exploded dn */
352 if (dn == NULL) return NULL;
354 /* Allocate a structure to hold the exploded DN */
355 edn = ldb_dn_new(mem_ctx);
363 /* Special DNs case */
366 edn->components = talloc(edn, struct ldb_dn_component);
367 if (edn->components == NULL) goto failed;
368 edn->components[0].name = talloc_strdup(edn->components, LDB_SPECIAL);
369 if (edn->components[0].name == NULL) goto failed;
370 edn->components[0].value.data = (uint8_t *)talloc_strdup(edn->components, dn);
371 if (edn->components[0].value.data== NULL) goto failed;
372 edn->components[0].value.length = strlen(dn);
376 pdn = p = talloc_strdup(edn, dn);
377 LDB_DN_NULL_FAILED(pdn);
379 /* get the components */
383 /* terminate the current component and return pointer to the next one */
384 t = seek_to_separator(p, ",;");
385 LDB_DN_NULL_FAILED(t);
387 if (*t) { /* here there is a separator */
388 *t = '\0'; /*terminate */
389 t++; /* a separtor means another component follows */
392 /* allocate space to hold the dn component */
393 edn->components = talloc_realloc(edn, edn->components,
394 struct ldb_dn_component,
396 if (edn->components == NULL)
399 /* store the exploded component in the main structure */
400 edn->components[edn->comp_num] = ldb_dn_explode_component(edn, p);
401 LDB_DN_NULL_FAILED(edn->components[edn->comp_num].name);
405 /* jump to the next component if any */
419 char *ldb_dn_linearize(void *mem_ctx, const struct ldb_dn *edn)
424 if (edn == NULL) return NULL;
427 if (ldb_dn_is_special(edn)) {
428 dn = talloc_strdup(mem_ctx, (char *)edn->components[0].value.data);
432 dn = talloc_strdup(mem_ctx, "");
433 LDB_DN_NULL_FAILED(dn);
435 for (i = 0; i < edn->comp_num; i++) {
436 value = ldb_dn_escape_value(dn, edn->components[i].value);
437 LDB_DN_NULL_FAILED(value);
440 dn = talloc_asprintf_append(dn, "%s=%s", edn->components[i].name, value);
442 dn = talloc_asprintf_append(dn, ",%s=%s", edn->components[i].name, value);
444 LDB_DN_NULL_FAILED(dn);
456 /* compare DNs using casefolding compare functions */
458 int ldb_dn_compare_base(struct ldb_context *ldb,
459 const struct ldb_dn *base,
460 const struct ldb_dn *dn)
465 if (base->comp_num > dn->comp_num) {
466 return (dn->comp_num - base->comp_num);
469 if (base == NULL || base->comp_num == 0) return 0;
470 if (dn == NULL || dn->comp_num == 0) return -1;
471 if (base->comp_num > dn->comp_num) return -1;
473 /* if the number of components doesn't match they differ */
474 n0 = base->comp_num - 1;
475 n1 = dn->comp_num - 1;
476 while (n0 >= 0 && n1 >= 0) {
477 const struct ldb_attrib_handler *h;
479 /* compare names (attribute names are guaranteed to be ASCII only) */
480 ret = ldb_caseless_cmp(base->components[n0].name,
481 dn->components[n1].name);
486 /* names match, compare values */
487 h = ldb_attrib_handler(ldb, base->components[n0].name);
488 ret = h->comparison_fn(ldb, ldb, &(base->components[n0].value),
489 &(dn->components[n1].value));
500 int ldb_dn_compare(struct ldb_context *ldb,
501 const struct ldb_dn *edn0,
502 const struct ldb_dn *edn1)
504 if (edn0 == NULL || edn1 == NULL) return edn1 - edn0;
506 if (edn0->comp_num != edn1->comp_num)
507 return (edn1->comp_num - edn0->comp_num);
509 return ldb_dn_compare_base(ldb, edn0, edn1);
512 int ldb_dn_cmp(struct ldb_context *ldb, const char *dn0, const char *dn1)
518 if (dn0 == NULL || dn1 == NULL) return dn1 - dn0;
520 edn0 = ldb_dn_explode_casefold(ldb, dn0);
521 if (edn0 == NULL) return 1;
523 edn1 = ldb_dn_explode_casefold(ldb, dn1);
529 ret = ldb_dn_compare(ldb, edn0, edn1);
538 casefold a dn. We need to casefold the attribute names, and canonicalize
539 attribute values of case insensitive attributes.
541 struct ldb_dn *ldb_dn_casefold(struct ldb_context *ldb, const struct ldb_dn *edn)
546 if (edn == NULL) return NULL;
548 cedn = ldb_dn_new(ldb);
549 LDB_DN_NULL_FAILED(cedn);
551 cedn->comp_num = edn->comp_num;
552 cedn->components = talloc_array(cedn, struct ldb_dn_component, edn->comp_num);
553 LDB_DN_NULL_FAILED(cedn->components);
555 for (i = 0; i < edn->comp_num; i++) {
556 struct ldb_dn_component dc;
557 const struct ldb_attrib_handler *h;
559 dc.name = ldb_casefold(cedn, edn->components[i].name);
560 LDB_DN_NULL_FAILED(dc.name);
562 h = ldb_attrib_handler(ldb, dc.name);
563 if (h->canonicalise_fn(ldb, cedn, &(edn->components[i].value), &(dc.value)) != 0) {
567 cedn->components[i] = dc;
577 struct ldb_dn *ldb_dn_explode_casefold(struct ldb_context *ldb, const char *dn)
579 struct ldb_dn *edn, *cdn;
581 if (dn == NULL) return NULL;
583 edn = ldb_dn_explode(ldb, dn);
584 if (edn == NULL) return NULL;
586 cdn = ldb_dn_casefold(ldb, edn);
592 char *ldb_dn_linearize_casefold(struct ldb_context *ldb, const struct ldb_dn *edn)
597 if (edn == NULL) return NULL;
600 if (ldb_dn_is_special(edn)) {
601 dn = talloc_strdup(ldb, (char *)edn->components[0].value.data);
605 cdn = ldb_dn_casefold(ldb, edn);
606 if (cdn == NULL) return NULL;
608 dn = ldb_dn_linearize(ldb, cdn);
618 static struct ldb_dn_component ldb_dn_copy_component(void *mem_ctx, struct ldb_dn_component *src)
620 struct ldb_dn_component dst;
628 dst.value = ldb_val_dup(mem_ctx, &(src->value));
629 if (dst.value.data == NULL) {
633 dst.name = talloc_strdup(mem_ctx, src->name);
634 if (dst.name == NULL) {
635 talloc_free(dst.value.data);
641 /* copy specified number of elements of a dn into a new one
642 element are copied from top level up to the unique rdn
643 num_el may be greater then dn->comp_num (see ldb_dn_make_child)
645 struct ldb_dn *ldb_dn_copy_partial(void *mem_ctx, const struct ldb_dn *dn, int num_el)
650 if (dn == NULL) return NULL;
651 if (num_el <= 0) return NULL;
653 new = ldb_dn_new(mem_ctx);
654 LDB_DN_NULL_FAILED(new);
656 new->comp_num = num_el;
657 n = new->comp_num - 1;
658 new->components = talloc_array(new, struct ldb_dn_component, new->comp_num);
660 if (dn->comp_num == 0) return new;
661 e = dn->comp_num - 1;
663 for (i = 0; i < new->comp_num; i++) {
664 new->components[n - i] = ldb_dn_copy_component(new->components,
665 &(dn->components[e - i]));
678 struct ldb_dn *ldb_dn_copy(void *mem_ctx, const struct ldb_dn *dn)
680 if (dn == NULL) return NULL;
681 return ldb_dn_copy_partial(mem_ctx, dn, dn->comp_num);
684 struct ldb_dn *ldb_dn_get_parent(void *mem_ctx, const struct ldb_dn *dn)
686 if (dn == NULL) return NULL;
687 return ldb_dn_copy_partial(mem_ctx, dn, dn->comp_num - 1);
690 struct ldb_dn_component *ldb_dn_build_component(void *mem_ctx, const char *attr,
693 struct ldb_dn_component *dc;
695 if (attr == NULL || val == NULL) return NULL;
697 dc = talloc(mem_ctx, struct ldb_dn_component);
698 if (dc == NULL) return NULL;
700 dc->name = talloc_strdup(dc, attr);
701 if (dc->name == NULL) {
706 dc->value.data = (uint8_t *)talloc_strdup(dc, val);
707 if (dc->value.data == NULL) {
712 dc->value.length = strlen(val);
717 struct ldb_dn *ldb_dn_build_child(void *mem_ctx, const char *attr,
719 const struct ldb_dn *base)
722 if (! ldb_dn_is_valid_attribute_name(attr)) return NULL;
723 if (value == NULL || value == '\0') return NULL;
726 new = ldb_dn_copy_partial(mem_ctx, base, base->comp_num + 1);
727 LDB_DN_NULL_FAILED(new);
729 new = ldb_dn_new(mem_ctx);
730 LDB_DN_NULL_FAILED(new);
733 new->components = talloc_array(new, struct ldb_dn_component, new->comp_num);
736 new->components[0].name = talloc_strdup(new->components, attr);
737 LDB_DN_NULL_FAILED(new->components[0].name);
739 new->components[0].value.data = (uint8_t *)talloc_strdup(new->components, value);
740 LDB_DN_NULL_FAILED(new->components[0].value.data);
741 new->components[0].value.length = strlen((char *)new->components[0].value.data);
751 struct ldb_dn *ldb_dn_make_child(void *mem_ctx, const struct ldb_dn_component *component,
752 const struct ldb_dn *base)
754 if (component == NULL) return NULL;
756 return ldb_dn_build_child(mem_ctx, component->name,
757 (char *)component->value.data, base);
760 struct ldb_dn *ldb_dn_compose(void *mem_ctx, const struct ldb_dn *dn1, const struct ldb_dn *dn2)
765 if (dn2 == NULL && dn1 == NULL) {
770 new = ldb_dn_new(mem_ctx);
771 LDB_DN_NULL_FAILED(new);
773 new->comp_num = dn1->comp_num;
774 new->components = talloc_array(new, struct ldb_dn_component, new->comp_num);
776 int comp_num = dn2->comp_num;
777 if (dn1 != NULL) comp_num += dn1->comp_num;
778 new = ldb_dn_copy_partial(mem_ctx, dn2, comp_num);
785 for (i = 0; i < dn1->comp_num; i++) {
786 new->components[i] = ldb_dn_copy_component(new->components,
787 &(dn1->components[i]));
797 struct ldb_dn *ldb_dn_string_compose(void *mem_ctx, const struct ldb_dn *base, const char *child_fmt, ...)
804 if (child_fmt == NULL) return NULL;
806 va_start(ap, child_fmt);
807 ret = vasprintf(&child_str, child_fmt, ap);
810 if (ret <= 0) return NULL;
812 dn = ldb_dn_compose(mem_ctx, ldb_dn_explode(mem_ctx, child_str), base);
819 struct ldb_dn_component *ldb_dn_get_rdn(void *mem_ctx, const struct ldb_dn *dn)
821 struct ldb_dn_component *rdn;
823 if (dn == NULL) return NULL;
825 if (dn->comp_num < 1) {
829 rdn = talloc(mem_ctx, struct ldb_dn_component);
830 if (rdn == NULL) return NULL;
832 *rdn = ldb_dn_copy_component(mem_ctx, &dn->components[0]);
833 if (rdn->name == NULL) {