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