/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- ldb_dn_is_special
- ldb_dn_check_special
- ldb_dn_escape_value
- ldb_dn_unescape_value
- get_quotes_position
- seek_to_separator
- ldb_dn_trim_string
- ldb_dn_explode_component
- ldb_dn_new
- ldb_dn_explode
- ldb_dn_explode_or_special
- ldb_dn_linearize
- ldb_dn_compare_base
- ldb_dn_compare
- ldb_dn_cmp
- ldb_dn_casefold
- ldb_dn_explode_casefold
- ldb_dn_linearize_casefold
- ldb_dn_copy_component
- ldb_dn_copy_rebase
- ldb_dn_copy_partial
- ldb_dn_copy
- ldb_dn_get_parent
- ldb_dn_build_component
- ldb_dn_build_child
- ldb_dn_compose
- ldb_dn_string_compose
- ldb_dn_canonical
- ldb_dn_canonical_string
- ldb_dn_canonical_ex_string
- ldb_dn_get_comp_num
- ldb_dn_get_component_name
- ldb_dn_get_component_val
- ldb_dn_get_rdn_name
- ldb_dn_get_rdn_val
- ldb_dn_set_component
1 /*
2 ldb database library
3
4 Copyright (C) Simo Sorce 2005
5
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
9
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.
14
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.
19
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/>.
22 */
23
24 /*
25 * Name: ldb
26 *
27 * Component: ldb dn explode and utility functions
28 *
29 * Description: - explode a dn into its own basic elements
30 * and put them in a structure
31 * - manipulate ldb_dn structures
32 *
33 * Author: Simo Sorce
34 */
35
36 #include "includes.h"
37 #include "ldb/include/includes.h"
38
39 #define LDB_DN_NULL_FAILED(x) if (!(x)) goto failed
40
41 #define LDB_SPECIAL "@SPECIAL"
42
43 /**
44 internal ldb exploded dn structures
45 */
46 struct ldb_dn_component {
47 char *name;
48 struct ldb_val value;
49 };
50
51 struct ldb_dn {
52 int comp_num;
53 struct ldb_dn_component *components;
54 };
55
56 int ldb_dn_is_special(const struct ldb_dn *dn)
/* [<][>][^][v][top][bottom][index][help] */
57 {
58 if (dn == NULL || dn->comp_num != 1) return 0;
59
60 return ! strcmp(dn->components[0].name, LDB_SPECIAL);
61 }
62
63 int ldb_dn_check_special(const struct ldb_dn *dn, const char *check)
/* [<][>][^][v][top][bottom][index][help] */
64 {
65 if (dn == NULL || dn->comp_num != 1) return 0;
66
67 return ! strcmp((char *)dn->components[0].value.data, check);
68 }
69
70 char *ldb_dn_escape_value(void *mem_ctx, struct ldb_val value)
/* [<][>][^][v][top][bottom][index][help] */
71 {
72 const char *p, *s, *src;
73 char *d, *dst;
74 int len;
75
76 if (!value.length)
77 return NULL;
78
79 p = s = src = (const char *)value.data;
80 len = value.length;
81
82 /* allocate destination string, it will be at most 3 times the source */
83 dst = d = talloc_array(mem_ctx, char, len * 3 + 1);
84 LDB_DN_NULL_FAILED(dst);
85
86 while (p - src < len) {
87
88 p += strcspn(p, ",=\n+<>#;\\\"");
89
90 if (p - src == len) /* found no escapable chars */
91 break;
92
93 memcpy(d, s, p - s); /* copy the part of the string before the stop */
94 d += (p - s); /* move to current position */
95
96 if (*p) { /* it is a normal escapable character */
97 *d++ = '\\';
98 *d++ = *p++;
99 } else { /* we have a zero byte in the string */
100 strncpy(d, "\00", 3); /* escape the zero */
101 d = d + 3;
102 p++; /* skip the zero */
103 }
104 s = p; /* move forward */
105 }
106
107 /* copy the last part (with zero) and return */
108 memcpy(d, s, &src[len] - s + 1);
109
110 return dst;
111
112 failed:
113 talloc_free(dst);
114 return NULL;
115 }
116
117 static struct ldb_val ldb_dn_unescape_value(void *mem_ctx, const char *src)
/* [<][>][^][v][top][bottom][index][help] */
118 {
119 struct ldb_val value;
120 unsigned x;
121 char *p, *dst = NULL, *end;
122
123 memset(&value, 0, sizeof(value));
124
125 LDB_DN_NULL_FAILED(src);
126
127 dst = p = (char *)talloc_memdup(mem_ctx, src, strlen(src) + 1);
128 LDB_DN_NULL_FAILED(dst);
129
130 end = &dst[strlen(dst)];
131
132 while (*p) {
133 p += strcspn(p, ",=\n+<>#;\\\"");
134
135 if (*p == '\\') {
136 if (strchr(",=\n+<>#;\\\"", p[1])) {
137 memmove(p, p + 1, end - (p + 1) + 1);
138 end--;
139 p++;
140 continue;
141 }
142
143 if (sscanf(p + 1, "%02x", &x) == 1) {
144 *p = (unsigned char)x;
145 memmove(p + 1, p + 3, end - (p + 3) + 1);
146 end -= 2;
147 p++;
148 continue;
149 }
150 }
151
152 /* a string with not escaped specials is invalid (tested) */
153 if (*p != '\0') {
154 goto failed;
155 }
156 }
157
158 value.length = end - dst;
159 value.data = (uint8_t *)dst;
160 return value;
161
162 failed:
163 talloc_free(dst);
164 return value;
165 }
166
167 /* check if the string contains quotes
168 * skips leading and trailing spaces
169 * - returns 0 if no quotes found
170 * - returns 1 if quotes are found and put their position
171 * in *quote_start and *quote_end parameters
172 * - return -1 if there are open quotes
173 */
174
175 static int get_quotes_position(const char *source, int *quote_start, int *quote_end)
/* [<][>][^][v][top][bottom][index][help] */
176 {
177 const char *p;
178
179 if (source == NULL || quote_start == NULL || quote_end == NULL) return -1;
180
181 p = source;
182
183 /* check if there are quotes surrounding the value */
184 p += strspn(p, " \n"); /* skip white spaces */
185
186 if (*p == '\"') {
187 *quote_start = p - source;
188
189 p++;
190 while (*p != '\"') {
191 p = strchr(p, '\"');
192 LDB_DN_NULL_FAILED(p);
193
194 if (*(p - 1) == '\\')
195 p++;
196 }
197
198 *quote_end = p - source;
199 return 1;
200 }
201
202 return 0;
203
204 failed:
205 return -1;
206 }
207
208 static char *seek_to_separator(char *string, const char *separators)
/* [<][>][^][v][top][bottom][index][help] */
209 {
210 char *p, *q;
211 int ret, qs, qe, escaped;
212
213 if (string == NULL || separators == NULL) return NULL;
214
215 p = strchr(string, '=');
216 LDB_DN_NULL_FAILED(p);
217
218 p++;
219
220 /* check if there are quotes surrounding the value */
221
222 ret = get_quotes_position(p, &qs, &qe);
223 if (ret == -1)
224 return NULL;
225
226 if (ret == 1) { /* quotes found */
227
228 p += qe; /* positioning after quotes */
229 p += strspn(p, " \n"); /* skip white spaces after the quote */
230
231 if (strcspn(p, separators) != 0) /* if there are characters between quotes */
232 return NULL; /* and separators, the dn is invalid */
233
234 return p; /* return on the separator */
235 }
236
237 /* no quotes found seek to separators */
238 q = p;
239 do {
240 escaped = 0;
241 ret = strcspn(q, separators);
242
243 if (q[ret - 1] == '\\') {
244 escaped = 1;
245 q = q + ret + 1;
246 }
247 } while (escaped);
248
249 if (ret == 0 && p == q) /* no separators ?! bail out */
250 return NULL;
251
252 return q + ret;
253
254 failed:
255 return NULL;
256 }
257
258 static char *ldb_dn_trim_string(char *string, const char *edge)
/* [<][>][^][v][top][bottom][index][help] */
259 {
260 char *s, *p;
261
262 /* seek out edge from start of string */
263 s = string + strspn(string, edge);
264
265 /* backwards skip from end of string */
266 p = &s[strlen(s) - 1];
267 while (p > s && strchr(edge, *p)) {
268 *p = '\0';
269 p--;
270 }
271
272 return s;
273 }
274
275 /* we choosed to not support multpile valued components */
276 static struct ldb_dn_component ldb_dn_explode_component(void *mem_ctx, char *raw_component)
/* [<][>][^][v][top][bottom][index][help] */
277 {
278 struct ldb_dn_component dc;
279 char *p;
280 int ret, qs, qe;
281
282 memset(&dc, 0, sizeof(dc));
283
284 if (raw_component == NULL) {
285 return dc;
286 }
287
288 /* find attribute type/value separator */
289 p = strchr(raw_component, '=');
290 LDB_DN_NULL_FAILED(p);
291
292 *p++ = '\0'; /* terminate name and point to value */
293
294 /* copy and trim name in the component */
295 dc.name = talloc_strdup(mem_ctx, ldb_dn_trim_string(raw_component, " \n"));
296 if (!dc.name)
297 return dc;
298
299 if (! ldb_valid_attr_name(dc.name)) {
300 goto failed;
301 }
302
303 ret = get_quotes_position(p, &qs, &qe);
304
305 switch (ret) {
306 case 0: /* no quotes trim the string */
307 p = ldb_dn_trim_string(p, " \n");
308 dc.value = ldb_dn_unescape_value(mem_ctx, p);
309 break;
310
311 case 1: /* quotes found get the unquoted string */
312 p[qe] = '\0';
313 p = p + qs + 1;
314 dc.value.length = strlen(p);
315 dc.value.data = (uint8_t *)talloc_memdup(mem_ctx, p,
316 dc.value.length + 1);
317 break;
318
319 default: /* mismatched quotes ot other error, bail out */
320 goto failed;
321 }
322
323 if (dc.value.length == 0) {
324 goto failed;
325 }
326
327 return dc;
328
329 failed:
330 talloc_free(dc.name);
331 dc.name = NULL;
332 return dc;
333 }
334
335 struct ldb_dn *ldb_dn_new(void *mem_ctx)
/* [<][>][^][v][top][bottom][index][help] */
336 {
337 struct ldb_dn *edn;
338
339 edn = talloc(mem_ctx, struct ldb_dn);
340 LDB_DN_NULL_FAILED(edn);
341
342 /* Initially there are no components */
343 edn->comp_num = 0;
344 edn->components = NULL;
345
346 return edn;
347
348 failed:
349 return NULL;
350 }
351
352 /*
353 explode a DN string into a ldb_dn structure
354 */
355 struct ldb_dn *ldb_dn_explode(void *mem_ctx, const char *dn)
/* [<][>][^][v][top][bottom][index][help] */
356 {
357 struct ldb_dn *edn; /* the exploded dn */
358 char *pdn, *p;
359
360 if (dn == NULL) return NULL;
361
362 /* Allocate a structure to hold the exploded DN */
363 edn = ldb_dn_new(mem_ctx);
364 if (edn == NULL) {
365 return NULL;
366 }
367
368 pdn = NULL;
369
370 /* Empty DNs */
371 if (dn[0] == '\0') {
372 return edn;
373 }
374
375 /* Special DNs case */
376 if (dn[0] == '@') {
377 edn->comp_num = 1;
378 edn->components = talloc(edn, struct ldb_dn_component);
379 if (edn->components == NULL) goto failed;
380 edn->components[0].name = talloc_strdup(edn->components, LDB_SPECIAL);
381 if (edn->components[0].name == NULL) goto failed;
382 edn->components[0].value.data = (uint8_t *)talloc_strdup(edn->components, dn);
383 if (edn->components[0].value.data== NULL) goto failed;
384 edn->components[0].value.length = strlen(dn);
385 return edn;
386 }
387
388 pdn = p = talloc_strdup(edn, dn);
389 LDB_DN_NULL_FAILED(pdn);
390
391 /* get the components */
392 do {
393 char *t;
394
395 /* terminate the current component and return pointer to the next one */
396 t = seek_to_separator(p, ",;");
397 LDB_DN_NULL_FAILED(t);
398
399 if (*t) { /* here there is a separator */
400 *t = '\0'; /*terminate */
401 t++; /* a separtor means another component follows */
402 }
403
404 /* allocate space to hold the dn component */
405 edn->components = talloc_realloc(edn, edn->components,
406 struct ldb_dn_component,
407 edn->comp_num + 1);
408 if (edn->components == NULL)
409 goto failed;
410
411 /* store the exploded component in the main structure */
412 edn->components[edn->comp_num] = ldb_dn_explode_component(edn, p);
413 LDB_DN_NULL_FAILED(edn->components[edn->comp_num].name);
414
415 edn->comp_num++;
416
417 /* jump to the next component if any */
418 p = t;
419
420 } while(*p);
421
422 talloc_free(pdn);
423 return edn;
424
425 failed:
426 talloc_free(pdn);
427 talloc_free(edn);
428 return NULL;
429 }
430
431 struct ldb_dn *ldb_dn_explode_or_special(void *mem_ctx, const char *dn)
/* [<][>][^][v][top][bottom][index][help] */
432 {
433 struct ldb_dn *edn; /* the exploded dn */
434
435 if (dn == NULL) return NULL;
436
437 if (strncasecmp(dn, "<GUID=", 6) == 0) {
438 /* this is special DN returned when the
439 * exploded_dn control is used
440 */
441
442 /* Allocate a structure to hold the exploded DN */
443 if (!(edn = ldb_dn_new(mem_ctx))) {
444 return NULL;
445 }
446
447 edn->comp_num = 1;
448 edn->components = talloc(edn, struct ldb_dn_component);
449 if (edn->components == NULL) goto failed;
450 edn->components[0].name = talloc_strdup(edn->components, LDB_SPECIAL);
451 if (edn->components[0].name == NULL) goto failed;
452 edn->components[0].value.data = (uint8_t *)talloc_strdup(edn->components, dn);
453 if (edn->components[0].value.data== NULL) goto failed;
454 edn->components[0].value.length = strlen(dn);
455 return edn;
456
457 }
458
459 return ldb_dn_explode(mem_ctx, dn);
460
461 failed:
462 talloc_free(edn);
463 return NULL;
464 }
465
466 char *ldb_dn_linearize(void *mem_ctx, const struct ldb_dn *edn)
/* [<][>][^][v][top][bottom][index][help] */
467 {
468 char *dn, *value;
469 int i;
470
471 if (edn == NULL) return NULL;
472
473 /* Special DNs */
474 if (ldb_dn_is_special(edn)) {
475 dn = talloc_strdup(mem_ctx, (char *)edn->components[0].value.data);
476 return dn;
477 }
478
479 dn = talloc_strdup(mem_ctx, "");
480 LDB_DN_NULL_FAILED(dn);
481
482 for (i = 0; i < edn->comp_num; i++) {
483 value = ldb_dn_escape_value(dn, edn->components[i].value);
484 LDB_DN_NULL_FAILED(value);
485
486 if (i == 0) {
487 dn = talloc_asprintf_append(dn, "%s=%s", edn->components[i].name, value);
488 } else {
489 dn = talloc_asprintf_append(dn, ",%s=%s", edn->components[i].name, value);
490 }
491 LDB_DN_NULL_FAILED(dn);
492
493 talloc_free(value);
494 }
495
496 return dn;
497
498 failed:
499 talloc_free(dn);
500 return NULL;
501 }
502
503 /* Determine if dn is below base, in the ldap tree. Used for
504 * evaluating a subtree search.
505 * 0 if they match, otherwise non-zero
506 */
507
508 int ldb_dn_compare_base(struct ldb_context *ldb,
/* [<][>][^][v][top][bottom][index][help] */
509 const struct ldb_dn *base,
510 const struct ldb_dn *dn)
511 {
512 int ret;
513 int n0, n1;
514
515 if (base == NULL || base->comp_num == 0) return 0;
516 if (dn == NULL || dn->comp_num == 0) return -1;
517
518 /* if the base has more componts than the dn, then they differ */
519 if (base->comp_num > dn->comp_num) {
520 return (dn->comp_num - base->comp_num);
521 }
522
523 n0 = base->comp_num - 1;
524 n1 = dn->comp_num - 1;
525 while (n0 >= 0 && n1 >= 0) {
526 const struct ldb_attrib_handler *h;
527
528 /* compare names (attribute names are guaranteed to be ASCII only) */
529 ret = ldb_attr_cmp(base->components[n0].name,
530 dn->components[n1].name);
531 if (ret) {
532 return ret;
533 }
534
535 /* names match, compare values */
536 h = ldb_attrib_handler(ldb, base->components[n0].name);
537 ret = h->comparison_fn(ldb, ldb, &(base->components[n0].value),
538 &(dn->components[n1].value));
539 if (ret) {
540 return ret;
541 }
542 n1--;
543 n0--;
544 }
545
546 return 0;
547 }
548
549 /* compare DNs using casefolding compare functions.
550
551 If they match, then return 0
552 */
553
554 int ldb_dn_compare(struct ldb_context *ldb,
/* [<][>][^][v][top][bottom][index][help] */
555 const struct ldb_dn *edn0,
556 const struct ldb_dn *edn1)
557 {
558 if (edn0 == NULL || edn1 == NULL) return edn1 - edn0;
559
560 if (edn0->comp_num != edn1->comp_num)
561 return (edn1->comp_num - edn0->comp_num);
562
563 return ldb_dn_compare_base(ldb, edn0, edn1);
564 }
565
566 int ldb_dn_cmp(struct ldb_context *ldb, const char *dn0, const char *dn1)
/* [<][>][^][v][top][bottom][index][help] */
567 {
568 struct ldb_dn *edn0;
569 struct ldb_dn *edn1;
570 int ret;
571
572 if (dn0 == NULL || dn1 == NULL) return dn1 - dn0;
573
574 edn0 = ldb_dn_explode_casefold(ldb, ldb, dn0);
575 if (edn0 == NULL) return 1;
576
577 edn1 = ldb_dn_explode_casefold(ldb, ldb, dn1);
578 if (edn1 == NULL) {
579 talloc_free(edn0);
580 return -1;
581 }
582
583 ret = ldb_dn_compare(ldb, edn0, edn1);
584
585 talloc_free(edn0);
586 talloc_free(edn1);
587
588 return ret;
589 }
590
591 /*
592 casefold a dn. We need to casefold the attribute names, and canonicalize
593 attribute values of case insensitive attributes.
594 */
595 struct ldb_dn *ldb_dn_casefold(struct ldb_context *ldb, void *mem_ctx, const struct ldb_dn *edn)
/* [<][>][^][v][top][bottom][index][help] */
596 {
597 struct ldb_dn *cedn;
598 int i, ret;
599
600 if (edn == NULL) return NULL;
601
602 cedn = ldb_dn_new(mem_ctx);
603 if (!cedn) {
604 return NULL;
605 }
606
607 cedn->comp_num = edn->comp_num;
608 cedn->components = talloc_array(cedn, struct ldb_dn_component, edn->comp_num);
609 if (!cedn->components) {
610 talloc_free(cedn);
611 return NULL;
612 }
613
614 for (i = 0; i < edn->comp_num; i++) {
615 struct ldb_dn_component dc;
616 const struct ldb_attrib_handler *h;
617
618 memset(&dc, 0, sizeof(dc));
619 dc.name = ldb_attr_casefold(cedn->components, edn->components[i].name);
620 if (!dc.name) {
621 talloc_free(cedn);
622 return NULL;
623 }
624
625 h = ldb_attrib_handler(ldb, dc.name);
626 ret = h->canonicalise_fn(ldb, cedn->components,
627 &(edn->components[i].value),
628 &(dc.value));
629 if (ret != 0) {
630 talloc_free(cedn);
631 return NULL;
632 }
633
634 cedn->components[i] = dc;
635 }
636
637 return cedn;
638 }
639
640 struct ldb_dn *ldb_dn_explode_casefold(struct ldb_context *ldb, void *mem_ctx, const char *dn)
/* [<][>][^][v][top][bottom][index][help] */
641 {
642 struct ldb_dn *edn, *cdn;
643
644 if (dn == NULL) return NULL;
645
646 edn = ldb_dn_explode(ldb, dn);
647 if (edn == NULL) return NULL;
648
649 cdn = ldb_dn_casefold(ldb, mem_ctx, edn);
650
651 talloc_free(edn);
652 return cdn;
653 }
654
655 char *ldb_dn_linearize_casefold(struct ldb_context *ldb, void *mem_ctx, const struct ldb_dn *edn)
/* [<][>][^][v][top][bottom][index][help] */
656 {
657 struct ldb_dn *cdn;
658 char *dn;
659
660 if (edn == NULL) return NULL;
661
662 /* Special DNs */
663 if (ldb_dn_is_special(edn)) {
664 dn = talloc_strdup(mem_ctx, (char *)edn->components[0].value.data);
665 return dn;
666 }
667
668 cdn = ldb_dn_casefold(ldb, mem_ctx, edn);
669 if (cdn == NULL) return NULL;
670
671 dn = ldb_dn_linearize(ldb, cdn);
672 if (dn == NULL) {
673 talloc_free(cdn);
674 return NULL;
675 }
676
677 talloc_free(cdn);
678 return dn;
679 }
680
681 static struct ldb_dn_component ldb_dn_copy_component(void *mem_ctx, struct ldb_dn_component *src)
/* [<][>][^][v][top][bottom][index][help] */
682 {
683 struct ldb_dn_component dst;
684
685 memset(&dst, 0, sizeof(dst));
686
687 if (src == NULL) {
688 return dst;
689 }
690
691 dst.value = ldb_val_dup(mem_ctx, &(src->value));
692 if (dst.value.data == NULL) {
693 return dst;
694 }
695
696 dst.name = talloc_strdup(mem_ctx, src->name);
697 if (dst.name == NULL) {
698 talloc_free(dst.value.data);
699 dst.value.data = NULL;
700 }
701
702 return dst;
703 }
704
705 /* Copy a DN but replace the old with the new base DN. */
706 struct ldb_dn *ldb_dn_copy_rebase(void *mem_ctx, const struct ldb_dn *old, const struct ldb_dn *old_base, const struct ldb_dn *new_base)
/* [<][>][^][v][top][bottom][index][help] */
707 {
708 struct ldb_dn *new_dn;
709 int i, offset;
710
711 /* Perhaps we don't need to rebase at all? */
712 if (!old_base || !new_base) {
713 return ldb_dn_copy(mem_ctx, old);
714 }
715
716 offset = old->comp_num - old_base->comp_num;
717 if (!(new_dn = ldb_dn_copy_partial(mem_ctx, new_base,
718 offset + new_base->comp_num))) {
719 return NULL;
720 }
721 for (i = 0; i < offset; i++) {
722 new_dn->components[i] = ldb_dn_copy_component(new_dn->components, &(old->components[i]));
723 }
724
725 return new_dn;
726 }
727
728 /* copy specified number of elements of a dn into a new one
729 element are copied from top level up to the unique rdn
730 num_el may be greater than dn->comp_num (see ldb_dn_make_child)
731 */
732 struct ldb_dn *ldb_dn_copy_partial(void *mem_ctx, const struct ldb_dn *dn, int num_el)
/* [<][>][^][v][top][bottom][index][help] */
733 {
734 struct ldb_dn *newdn;
735 int i, n, e;
736
737 if (dn == NULL) return NULL;
738 if (num_el <= 0) return NULL;
739
740 newdn = ldb_dn_new(mem_ctx);
741 LDB_DN_NULL_FAILED(newdn);
742
743 newdn->comp_num = num_el;
744 n = newdn->comp_num - 1;
745 newdn->components = talloc_array(newdn, struct ldb_dn_component, newdn->comp_num);
746 if (newdn->components == NULL) goto failed;
747
748 if (dn->comp_num == 0) return newdn;
749 e = dn->comp_num - 1;
750
751 for (i = 0; i < newdn->comp_num; i++) {
752 newdn->components[n - i] = ldb_dn_copy_component(newdn->components,
753 &(dn->components[e - i]));
754 if ((e - i) == 0) {
755 return newdn;
756 }
757 }
758
759 return newdn;
760
761 failed:
762 talloc_free(newdn);
763 return NULL;
764 }
765
766 struct ldb_dn *ldb_dn_copy(void *mem_ctx, const struct ldb_dn *dn)
/* [<][>][^][v][top][bottom][index][help] */
767 {
768 if (dn == NULL) return NULL;
769 return ldb_dn_copy_partial(mem_ctx, dn, dn->comp_num);
770 }
771
772 struct ldb_dn *ldb_dn_get_parent(void *mem_ctx, const struct ldb_dn *dn)
/* [<][>][^][v][top][bottom][index][help] */
773 {
774 if (dn == NULL) return NULL;
775 return ldb_dn_copy_partial(mem_ctx, dn, dn->comp_num - 1);
776 }
777
778 struct ldb_dn_component *ldb_dn_build_component(void *mem_ctx, const char *attr,
/* [<][>][^][v][top][bottom][index][help] */
779 const char *val)
780 {
781 struct ldb_dn_component *dc;
782
783 if (attr == NULL || val == NULL) return NULL;
784
785 dc = talloc(mem_ctx, struct ldb_dn_component);
786 if (dc == NULL) return NULL;
787
788 dc->name = talloc_strdup(dc, attr);
789 if (dc->name == NULL) {
790 talloc_free(dc);
791 return NULL;
792 }
793
794 dc->value.data = (uint8_t *)talloc_strdup(dc, val);
795 if (dc->value.data == NULL) {
796 talloc_free(dc);
797 return NULL;
798 }
799
800 dc->value.length = strlen(val);
801
802 return dc;
803 }
804
805 struct ldb_dn *ldb_dn_build_child(void *mem_ctx, const char *attr,
/* [<][>][^][v][top][bottom][index][help] */
806 const char * value,
807 const struct ldb_dn *base)
808 {
809 struct ldb_dn *newdn;
810 if (! ldb_valid_attr_name(attr)) return NULL;
811 if (value == NULL || value == '\0') return NULL;
812
813 if (base != NULL) {
814 newdn = ldb_dn_copy_partial(mem_ctx, base, base->comp_num + 1);
815 LDB_DN_NULL_FAILED(newdn);
816 } else {
817 newdn = ldb_dn_new(mem_ctx);
818 LDB_DN_NULL_FAILED(newdn);
819
820 newdn->comp_num = 1;
821 newdn->components = talloc_array(newdn, struct ldb_dn_component, newdn->comp_num);
822 LDB_DN_NULL_FAILED(newdn->components);
823 }
824
825 newdn->components[0].name = talloc_strdup(newdn->components, attr);
826 LDB_DN_NULL_FAILED(newdn->components[0].name);
827
828 newdn->components[0].value.data = (uint8_t *)talloc_strdup(newdn->components, value);
829 LDB_DN_NULL_FAILED(newdn->components[0].value.data);
830 newdn->components[0].value.length = strlen((char *)newdn->components[0].value.data);
831
832 return newdn;
833
834 failed:
835 talloc_free(newdn);
836 return NULL;
837
838 }
839
840 struct ldb_dn *ldb_dn_compose(void *mem_ctx, const struct ldb_dn *dn1, const struct ldb_dn *dn2)
/* [<][>][^][v][top][bottom][index][help] */
841 {
842 int i;
843 struct ldb_dn *newdn;
844
845 if (dn2 == NULL && dn1 == NULL) {
846 return NULL;
847 }
848
849 if (dn2 == NULL) {
850 newdn = ldb_dn_new(mem_ctx);
851 LDB_DN_NULL_FAILED(newdn);
852
853 newdn->comp_num = dn1->comp_num;
854 newdn->components = talloc_array(newdn, struct ldb_dn_component, newdn->comp_num);
855 LDB_DN_NULL_FAILED(newdn->components);
856 } else {
857 int comp_num = dn2->comp_num;
858 if (dn1 != NULL) comp_num += dn1->comp_num;
859 newdn = ldb_dn_copy_partial(mem_ctx, dn2, comp_num);
860 LDB_DN_NULL_FAILED(newdn);
861 }
862
863 if (dn1 == NULL) {
864 return newdn;
865 }
866
867 for (i = 0; i < dn1->comp_num; i++) {
868 newdn->components[i] = ldb_dn_copy_component(newdn->components,
869 &(dn1->components[i]));
870 if (newdn->components[i].value.data == NULL) {
871 goto failed;
872 }
873 }
874
875 return newdn;
876
877 failed:
878 talloc_free(newdn);
879 return NULL;
880 }
881
882 struct ldb_dn *ldb_dn_string_compose(void *mem_ctx, const struct ldb_dn *base, const char *child_fmt, ...)
/* [<][>][^][v][top][bottom][index][help] */
883 {
884 struct ldb_dn *dn, *dn1;
885 char *child_str;
886 va_list ap;
887
888 if (child_fmt == NULL) return NULL;
889
890 va_start(ap, child_fmt);
891 child_str = talloc_vasprintf(mem_ctx, child_fmt, ap);
892 va_end(ap);
893
894 if (child_str == NULL) return NULL;
895
896 dn1 = ldb_dn_explode(mem_ctx, child_str);
897 dn = ldb_dn_compose(mem_ctx, dn1, base);
898
899 talloc_free(child_str);
900 talloc_free(dn1);
901
902 return dn;
903 }
904
905 /* Create a 'canonical name' string from a DN:
906
907 ie dc=samba,dc=org -> samba.org/
908 uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator
909
910 There are two formats, the EX format has the last / replaced with a newline (\n).
911
912 */
913 static char *ldb_dn_canonical(void *mem_ctx, const struct ldb_dn *dn, int ex_format) {
/* [<][>][^][v][top][bottom][index][help] */
914 int i;
915 char *cracked = NULL;
916
917 /* Walk backwards down the DN, grabbing 'dc' components at first */
918 for (i = dn->comp_num - 1 ; i >= 0; i--) {
919 if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) {
920 break;
921 }
922 if (cracked) {
923 cracked = talloc_asprintf(mem_ctx, "%s.%s",
924 ldb_dn_escape_value(mem_ctx, dn->components[i].value),
925 cracked);
926 } else {
927 cracked = ldb_dn_escape_value(mem_ctx, dn->components[i].value);
928 }
929 if (!cracked) {
930 return NULL;
931 }
932 }
933
934 /* Only domain components? Finish here */
935 if (i < 0) {
936 if (ex_format) {
937 cracked = talloc_asprintf(mem_ctx, "%s\n", cracked);
938 } else {
939 cracked = talloc_asprintf(mem_ctx, "%s/", cracked);
940 }
941 return cracked;
942 }
943
944 /* Now walk backwards appending remaining components */
945 for (; i > 0; i--) {
946 cracked = talloc_asprintf(mem_ctx, "%s/%s", cracked,
947 ldb_dn_escape_value(mem_ctx, dn->components[i].value));
948 if (!cracked) {
949 return NULL;
950 }
951 }
952
953 /* Last one, possibly a newline for the 'ex' format */
954 if (ex_format) {
955 cracked = talloc_asprintf(mem_ctx, "%s\n%s", cracked,
956 ldb_dn_escape_value(mem_ctx, dn->components[i].value));
957 } else {
958 cracked = talloc_asprintf(mem_ctx, "%s/%s", cracked,
959 ldb_dn_escape_value(mem_ctx, dn->components[i].value));
960 }
961 return cracked;
962 }
963
964 /* Wrapper functions for the above, for the two different string formats */
965 char *ldb_dn_canonical_string(void *mem_ctx, const struct ldb_dn *dn) {
/* [<][>][^][v][top][bottom][index][help] */
966 return ldb_dn_canonical(mem_ctx, dn, 0);
967
968 }
969
970 char *ldb_dn_canonical_ex_string(void *mem_ctx, const struct ldb_dn *dn) {
/* [<][>][^][v][top][bottom][index][help] */
971 return ldb_dn_canonical(mem_ctx, dn, 1);
972 }
973
974 int ldb_dn_get_comp_num(const struct ldb_dn *dn)
/* [<][>][^][v][top][bottom][index][help] */
975 {
976 return dn->comp_num;
977 }
978
979 const char *ldb_dn_get_component_name(const struct ldb_dn *dn, unsigned int num)
/* [<][>][^][v][top][bottom][index][help] */
980 {
981 if (num >= dn->comp_num) return NULL;
982 return dn->components[num].name;
983 }
984
985 const struct ldb_val *ldb_dn_get_component_val(const struct ldb_dn *dn, unsigned int num)
/* [<][>][^][v][top][bottom][index][help] */
986 {
987 if (num >= dn->comp_num) return NULL;
988 return &dn->components[num].value;
989 }
990
991 const char *ldb_dn_get_rdn_name(const struct ldb_dn *dn) {
/* [<][>][^][v][top][bottom][index][help] */
992 if (dn->comp_num == 0) return NULL;
993 return dn->components[0].name;
994 }
995
996 const struct ldb_val *ldb_dn_get_rdn_val(const struct ldb_dn *dn) {
/* [<][>][^][v][top][bottom][index][help] */
997 if (dn->comp_num == 0) return NULL;
998 return &dn->components[0].value;
999 }
1000
1001 int ldb_dn_set_component(struct ldb_dn *dn, int num, const char *name, const struct ldb_val val)
/* [<][>][^][v][top][bottom][index][help] */
1002 {
1003 char *n;
1004 struct ldb_val v;
1005
1006 if (num >= dn->comp_num) {
1007 return LDB_ERR_OTHER;
1008 }
1009
1010 n = talloc_strdup(dn, name);
1011 if ( ! n) {
1012 return LDB_ERR_OTHER;
1013 }
1014
1015 v.length = val.length;
1016 v.data = (uint8_t *)talloc_memdup(dn, val.data, v.length+1);
1017 if ( ! v.data) {
1018 return LDB_ERR_OTHER;
1019 }
1020
1021 talloc_free(dn->components[num].name);
1022 talloc_free(dn->components[num].value.data);
1023 dn->components[num].name = n;
1024 dn->components[num].value = v;
1025
1026 return LDB_SUCCESS;
1027 }