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