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