0a10ed6f2e5fc81bf7bab1eff7fd344ad26999a6
[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 creation and manipulation utility functions
29  *
30  *  Description: - explode a dn into it's own basic elements
31  *                 and put them in a structure (only if necessary)
32  *               - manipulate ldb_dn structures
33  *
34  *  Author: Simo Sorce
35  */
36
37 #include "includes.h"
38 #include <ctype.h>
39 #include "ldb/include/includes.h"
40
41 #define LDB_DN_NULL_FAILED(x) if (!(x)) goto failed
42
43 #define LDB_FREE(x) do { talloc_free(x); x = NULL; } while(0)
44
45 /**
46    internal ldb exploded dn structures
47 */
48 struct ldb_dn_component {
49
50         char *name;
51         struct ldb_val value;
52
53         char *cf_name;
54         struct ldb_val cf_value;
55 };
56
57 struct ldb_dn {
58
59         struct ldb_context *ldb;
60
61         /* Special DNs are always linearized */
62         bool special;
63         bool invalid;
64
65         bool valid_lin;
66         bool valid_comp;
67         bool valid_case;
68
69         char *linearized;
70         char *casefold;
71
72         unsigned int comp_num;
73         struct ldb_dn_component *components;
74
75 };
76
77 /* strdn may be NULL */
78 struct ldb_dn *ldb_dn_new(void *mem_ctx, struct ldb_context *ldb, const char *strdn)
79 {
80         struct ldb_dn *dn;
81
82         if ( (! mem_ctx) || (! ldb)) return NULL;
83
84         dn = talloc_zero(mem_ctx, struct ldb_dn);
85         LDB_DN_NULL_FAILED(dn);
86
87         dn->ldb = ldb;
88
89         if (strdn) {
90                 if (strdn[0] == '@') {
91                         dn->special = true;
92                 }
93                 if (strncasecmp(strdn, "<GUID=", 6) == 0) {
94                         /* this is special DN returned when the
95                          * exploded_dn control is used */
96                         dn->special = true;
97                         /* FIXME: add a GUID string to ldb_dn structure */
98                 }
99                 dn->linearized = talloc_strdup(dn, strdn);
100         } else {
101                 dn->linearized = talloc_strdup(dn, "");
102         }
103         LDB_DN_NULL_FAILED(dn->linearized);
104
105         dn->valid_lin = true;
106
107         return dn;
108
109 failed:
110         talloc_free(dn);
111         return NULL;
112 }
113
114 struct ldb_dn *ldb_dn_new_fmt(void *mem_ctx, struct ldb_context *ldb, const char *new_fmt, ...)
115 {
116         struct ldb_dn *dn;
117         char *strdn;
118         va_list ap;
119
120         if ( (! mem_ctx) || (! ldb)) return NULL;
121
122         dn = talloc_zero(mem_ctx, struct ldb_dn);
123         LDB_DN_NULL_FAILED(dn);
124
125         dn->ldb = ldb;
126
127         va_start(ap, new_fmt);
128         strdn = talloc_vasprintf(dn, new_fmt, ap);
129         va_end(ap);
130         LDB_DN_NULL_FAILED(strdn);
131
132         if (strdn[0] == '@') {
133                 dn->special = true;
134         }
135         if (strncasecmp(strdn, "<GUID=", 6) == 0) {
136                 /* this is special DN returned when the
137                  * exploded_dn control is used */
138                 dn->special = true;
139                 /* FIXME: add a GUID string to ldb_dn structure */
140         }
141         dn->linearized = strdn;
142
143         dn->valid_lin = true;
144
145         return dn;
146
147 failed:
148         talloc_free(dn);
149         return NULL;
150 }
151
152 static int ldb_dn_escape_internal(char *dst, const char *src, int len)
153 {
154         const char *p, *s;
155         char *d;
156         int l;
157
158         p = s = src;
159         d = dst;
160
161         while (p - src < len) {
162
163                 p += strcspn(p, ",=\n+<>#;\\\"");
164
165                 if (p - src == len) /* found no escapable chars */
166                         break;
167
168                 memcpy(d, s, p - s); /* copy the part of the string before the stop */
169                 d += (p - s); /* move to current position */
170
171                 if (*p) { /* it is a normal escapable character */
172                         *d++ = '\\';
173                         *d++ = *p++;
174                 } else { /* we have a zero byte in the string */
175                         strncpy(d, "\00", 3); /* escape the zero */
176                         d += 3;
177                         p++; /* skip the zero */
178                 }
179                 s = p; /* move forward */
180         }
181
182         /* copy the last part (with zero) and return */
183         l = len - (s - src);
184         memcpy(d, s, l + 1);
185
186         /* return the length of the resulting string */
187         return (l + (d - dst));
188
189
190 char *ldb_dn_escape_value(void *mem_ctx, struct ldb_val value)
191 {
192         char *dst;
193
194         if (!value.length)
195                 return NULL;
196
197         /* allocate destination string, it will be at most 3 times the source */
198         dst = talloc_array(mem_ctx, char, value.length * 3 + 1);
199         if ( ! dst) {
200                 talloc_free(dst);
201                 return NULL;
202         }
203
204         ldb_dn_escape_internal(dst, (const char *)value.data, value.length);
205
206         return dst;
207 }
208
209 /*
210   explode a DN string into a ldb_dn structure
211   based on RFC4514 except that we don't support multiple valued RDNs
212 */
213 static bool ldb_dn_explode(struct ldb_dn *dn)
214 {
215         char *p, *data, *d, *dt, *t;
216         bool trim = false;
217         bool in_attr = false;
218         bool in_value = false;
219         bool in_quote = false;
220         bool is_oid = false;
221         bool escape = false;
222         unsigned x;
223         int l;
224
225         if ( ! dn || dn->invalid) return false;
226
227         if (dn->valid_comp) {
228                 return true;
229         }
230
231         if ( ! dn->valid_lin) {
232                 return false;
233         }
234
235         /* Empty DNs */
236         if (dn->linearized[0] == '\0') {
237                 dn->valid_comp = true;
238                 return true;
239         }
240
241         /* Special DNs case */
242         if (dn->special) {
243                 return true;
244         }
245
246         /* in the common case we have 3 or more components */
247         /* make sure all components are zeroed, other functions depend on this */
248         dn->components = talloc_zero_array(dn, struct ldb_dn_component, 3);
249         if ( ! dn->components) {
250                 return false;
251         }
252         dn->comp_num = 0;
253
254         /* Components data space is allocated here once */
255         data = talloc_array(dn->components, char, strlen(dn->linearized) + 1);
256
257         p = dn->linearized;
258         in_attr = true;
259         trim = true;
260         t = NULL;
261         d = dt = data;
262
263         while (*p) {
264
265                 if (in_attr) {
266                         if (trim) {
267                                 if (*p == ' ') {
268                                         p++;
269                                         continue;
270                                 }
271
272                                 /* first char */
273                                 trim = false;
274
275                                 if (isdigit(*p)) {
276                                         is_oid = true;
277                                 } else
278                                 if ( ! isalpha(*p)) {
279                                         /* not a digit nor an alpha, invalid attribute name */
280                                         dn->invalid = true;
281                                         goto failed;
282                                 }
283                                 
284                                 *d++ = *p++;
285                                 continue;
286                         }
287
288                         if (*p == ' ') {
289                                 p++;
290                                 /* valid only if we are at the end */
291                                 trim = true;
292                                 continue;
293                         }
294
295                         if (trim && (*p != '=')) {
296                                 /* spaces/tabs are not allowed in attribute names */
297                                 dn->invalid = true;
298                                 goto failed;
299                         }
300
301                         if (*p == '=') {
302                                 /* attribute terminated */
303                                 in_attr = false;
304                                 in_value = true;
305                                 trim = true;
306                                 l = 0;
307
308                                 *d++ = '\0';
309                                 dn->components[dn->comp_num].name = dt;
310                                 dt = d;
311
312                                 p++;
313                                 continue;
314                         }
315
316                         if (is_oid && ( ! (isdigit(*p) || (*p == '.')))) {
317                                 /* not a digit nor a dot, invalid attribute oid */
318                                 dn->invalid = true;
319                                 goto failed;
320                         } else
321                         if ( ! (isalpha(*p) || isdigit(*p) || (*p == '-'))) {
322                                 /* not ALPHA, DIGIT or HYPHEN */
323                                 dn->invalid = true;
324                                 goto failed;
325                         }
326
327                         *d++ = *p++;
328                         continue;
329                 }
330
331                 if (in_value) {
332                         if (in_quote) {
333                                 if (*p == '\"') {
334                                         if (p[-1] != '\\') {
335                                                 p++;
336                                                 in_quote = false;
337                                                 continue;
338                                         }
339                                 }
340                                 *d++ = *p++;
341                                 l++;
342                                 continue;
343                         }
344
345                         if (trim) {
346                                 if (*p == ' ') {
347                                         p++;
348                                         continue;
349                                 }
350
351                                 /* first char */
352                                 trim = false;
353
354                                 if (*p == '\"') {
355                                         in_quote = true;
356                                         p++;
357                                         continue;
358                                 }
359                         }
360
361                         switch (*p) {
362
363                         /* TODO: support ber encoded values
364                         case '#':
365                         */
366
367                         case ',':
368                                 if (escape) {
369                                         *d++ = *p++;
370                                         l++;
371                                         escape = false;
372                                         continue;
373                                 }
374                                 /* ok found value terminator */
375
376                                 if ( t ) {
377                                         /* trim back */
378                                         d -= (p - t);
379                                         l -= (p - t);
380                                 }
381
382                                 in_attr = true;
383                                 in_value = false;
384                                 trim = true;
385
386                                 p++;
387                                 *d++ = '\0';
388                                 dn->components[dn->comp_num].value.data = (uint8_t *)dt;
389                                 dn->components[dn->comp_num].value.length = l;
390                                 dt = d;
391
392                                 dn->comp_num++;
393                                 if (dn->comp_num > 2) {
394                                         dn->components = talloc_realloc(dn,
395                                                                         dn->components,
396                                                                         struct ldb_dn_component,
397                                                                         dn->comp_num + 1);
398                                         if ( ! dn->components) {
399                                                 /* ouch ! */
400                                                 goto failed;
401                                         }
402                                         /* make sure all components are zeroed, other functions depend on this */
403                                         memset(&dn->components[dn->comp_num], '\0', sizeof(struct ldb_dn_component));
404                                 }
405
406                                 continue;
407
408                         case '=':
409                         case '\n':
410                         case '+':
411                         case '<':
412                         case '>':
413                         case '#':
414                         case ';':
415                         case '\"':
416                                 /* a string with not escaped specials is invalid (tested) */
417                                 if ( ! escape) {
418                                         dn->invalid = true;
419                                         goto failed;
420                                 }
421                                 escape = false;
422
423                                 *d++ = *p++;
424                                 l++;
425
426                                 if ( t ) t = NULL;
427                                 break;
428
429                         case '\\':
430                                 if ( ! escape) {
431                                         escape = true;
432                                         p++;
433                                         continue;
434                                 }
435                                 escape = false;
436
437                                 *d++ = *p++;
438                                 l++;
439
440                                 if ( t ) t = NULL;
441                                 break;
442
443                         default:
444                                 if (escape) {
445                                         if (sscanf(p, "%02x", &x) != 1) {
446                                                 /* invalid escaping sequence */
447                                                 dn->invalid = true;
448                                                 goto failed;
449                                         }
450                                         escape = false;
451
452                                         p += 2;
453                                         *d++ = (unsigned char)x;
454                                         l++;
455
456                                         if ( t ) t = NULL;
457                                         break;
458                                 }
459
460                                 if (*p == ' ') { 
461                                         if ( ! t) t = p;
462                                 } else {
463                                         if ( t ) t = NULL;
464                                 }
465
466                                 *d++ = *p++;
467                                 l++;
468                                 
469                                 break;
470                         }
471
472                 }
473         }
474
475         if (in_attr || in_quote) {
476                 /* invalid dn */
477                 dn->invalid = true;
478                 goto failed;
479         }
480
481         /* save last element */
482         if ( t ) {
483                 /* trim back */
484                 d -= (p - t);
485                 l -= (p - t);
486         }
487
488         *d++ = '\0';
489         dn->components[dn->comp_num].value.data = (uint8_t *)dt;
490         dn->components[dn->comp_num].value.length = l;
491
492         dn->comp_num++;
493
494         dn->valid_comp = true;
495         return true;
496
497 failed:
498         talloc_free(dn->components);
499         return false;
500 }
501
502 bool ldb_dn_validate(struct ldb_dn *dn)
503 {
504         return ldb_dn_explode(dn);
505 }
506
507 const char *ldb_dn_get_linearized(struct ldb_dn *dn)
508 {
509         int i, len;
510         char *d, *n;
511
512         if ( ! dn || ( dn->invalid)) return NULL;
513
514         if (dn->valid_lin) return dn->linearized;
515
516         if ( ! dn->valid_comp) {
517                 dn->invalid = true;
518                 return NULL;
519         }
520
521         if (dn->comp_num == 0) {
522                 dn->linearized = talloc_strdup(dn, "");
523                 if ( ! dn->linearized) return NULL;
524                 dn->valid_lin = true;
525                 return dn->linearized;
526         }
527
528         /* calculate maximum possible length of DN */
529         for (len = 0, i = 0; i < dn->comp_num; i++) {
530                 len += strlen(dn->components[i].name); /* name len */
531                 len += (dn->components[i].value.length * 3); /* max escaped data len */
532                 len += 2; /* '=' and ',' */
533         }
534         dn->linearized = talloc_array(dn, char, len);
535         if ( ! dn->linearized) return NULL;
536
537         d = dn->linearized;
538
539         for (i = 0; i < dn->comp_num; i++) {
540
541                 /* copy the name */
542                 n = dn->components[i].name;
543                 while (*n) *d++ = *n++;
544
545                 *d++ = '=';
546
547                 /* and the value */
548                 d += ldb_dn_escape_internal( d,
549                                 (char *)dn->components[i].value.data,
550                                 dn->components[i].value.length);
551                 *d++ = ',';
552         }
553
554         *(--d) = '\0';
555
556         dn->valid_lin = true;
557
558         /* don't waste more memory than necessary */
559         dn->linearized = talloc_realloc(dn, dn->linearized, char, (d - dn->linearized + 1));
560
561         return dn->linearized;
562 }
563
564 char *ldb_dn_linearize(void *mem_ctx, struct ldb_dn *dn)
565 {
566         return talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn));
567 }
568
569 /*
570   casefold a dn. We need to casefold the attribute names, and canonicalize 
571   attribute values of case insensitive attributes.
572 */
573
574 static bool ldb_dn_casefold_internal(struct ldb_dn *dn)
575 {
576         int i, ret;
577
578         if ( ! dn || dn->invalid) return false;
579
580         if (dn->valid_case) return true;
581
582         if (( ! dn->valid_comp) && ( ! ldb_dn_explode(dn))) {
583                 return false;
584         }
585
586         for (i = 0; i < dn->comp_num; i++) {
587                 struct ldb_dn_component dc;
588                 const struct ldb_attrib_handler *h;
589
590                 memset(&dc, 0, sizeof(dc));
591                 dn->components[i].cf_name = ldb_attr_casefold(dn->components, dn->components[i].name);
592                 if (!dn->components[i].cf_name) {
593                         return false;
594                 }
595
596                 h = ldb_attrib_handler(dn->ldb, dn->components[i].cf_name);
597                 ret = h->canonicalise_fn(dn->ldb, dn->components,
598                                          &(dn->components[i].value),
599                                          &(dn->components[i].cf_value));
600                 if (ret != 0) {
601                         return false;
602                 }
603         }
604
605         return true;
606 }
607
608 const char *ldb_dn_get_casefold(struct ldb_dn *dn)
609 {
610         int i, len;
611         char *d, *n;
612
613         if ( ! ldb_dn_casefold_internal(dn)) {
614                 return NULL;
615         }
616
617         if (dn->casefold) return dn->casefold;
618
619         if (dn->comp_num == 0) {
620                 if (dn->special) {
621                         len = strlen(dn->linearized);
622                         dn->casefold = talloc_array(dn, char, len * 3 + 1);
623                         if ( ! dn->casefold) return NULL;
624                         ldb_dn_escape_internal(dn->casefold, dn->linearized, len);
625                         /* don't waste more memory than necessary */
626                         dn->casefold = talloc_realloc(dn, dn->casefold, char, strlen(dn->casefold) + 1);
627                 } else {
628                         dn->casefold = talloc_strdup(dn, "");
629                         if ( ! dn->casefold) return NULL;
630                 }
631                 dn->valid_case = true;
632                 return dn->casefold;
633         }
634
635         /* calculate maximum possible length of DN */
636         for (len = 0, i = 0; i < dn->comp_num; i++) {
637                 len += strlen(dn->components[i].cf_name); /* name len */
638                 len += (dn->components[i].cf_value.length * 3); /* max escaped data len */
639                 len += 2; /* '=' and ',' */
640         }
641         dn->casefold = talloc_array(dn, char, len);
642         if ( ! dn->casefold) return NULL;
643
644         d = dn->casefold;
645
646         for (i = 0; i < dn->comp_num; i++) {
647
648                 /* copy the name */
649                 n = dn->components[i].cf_name;
650                 while (*n) *d++ = *n++;
651
652                 *d++ = '=';
653
654                 /* and the value */
655                 d += ldb_dn_escape_internal( d,
656                                 (char *)dn->components[i].cf_value.data,
657                                 dn->components[i].cf_value.length);
658                 *d++ = ',';
659         }
660         *(--d) = '\0';
661
662         dn->valid_case = true;
663
664         return dn->casefold;
665 }
666
667 char *ldb_dn_casefold(void *mem_ctx, struct ldb_dn *dn)
668 {
669         return talloc_strdup(mem_ctx, ldb_dn_get_casefold(dn));
670 }
671
672 /* Determine if dn is below base, in the ldap tree.  Used for
673  * evaluating a subtree search.
674  * 0 if they match, otherwise non-zero
675  */
676
677 int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn)
678 {
679         int ret;
680         int n_base, n_dn;
681
682         if ( ! base || base->invalid) return 1;
683         if ( ! dn || dn->invalid) return -1;
684
685         if (( ! base->valid_case) || ( ! dn->valid_case)) {
686                 if (base->valid_lin && dn->valid_lin) {
687                         /* try with a normal compare first, if we are lucky
688                          * we will avoid exploding and casfolding */
689                         int dif;
690                         dif = strlen(dn->linearized) - strlen(base->linearized);
691                         if (dif < 0) return dif;
692                         if (strcmp(base->linearized, &dn->linearized[dif]) == 0) return 0;
693                 }
694
695                 if ( ! ldb_dn_casefold_internal(base)) {
696                         return 1;
697                 }
698
699                 if ( ! ldb_dn_casefold_internal(dn)) {
700                         return -1;
701                 }
702
703         }
704
705         /* if base has more components,
706          * they don't have the same base */
707         if (base->comp_num > dn->comp_num) {
708                 return (dn->comp_num - base->comp_num);
709         }
710
711         if (dn->comp_num == 0) {
712                 if (dn->special && base->special) {
713                         return strcmp(base->linearized, dn->linearized);
714                 } else {
715                         return 0;
716                 }
717         }
718
719         n_base = base->comp_num - 1;
720         n_dn = dn->comp_num - 1;
721
722         while (n_base >= 0) {
723                 /* compare attr names */
724                 ret = strcmp(base->components[n_base].cf_name, dn->components[n_dn].cf_name);
725                 if (ret != 0) return ret;
726
727                 /* compare attr.cf_value. */ 
728                 if (base->components[n_base].cf_value.length != dn->components[n_dn].cf_value.length) {
729                         return base->components[n_base].cf_value.length - dn->components[n_dn].cf_value.length;
730                 }
731                 ret = strcmp((char *)base->components[n_base].cf_value.data, (char *)dn->components[n_dn].cf_value.data);
732                 if (ret != 0) return ret;
733
734                 n_base--;
735                 n_dn--;
736         }
737
738         return 0;
739 }
740
741 /* compare DNs using casefolding compare functions.  
742
743    If they match, then return 0
744  */
745
746 int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1)
747 {
748         int i, ret;
749
750         if (( ! dn0) || dn0->invalid || ! dn1 || dn1->invalid) return -1;
751
752         if (( ! dn0->valid_case) || ( ! dn1->valid_case)) {
753                 if (dn0->valid_lin && dn1->valid_lin) {
754                         /* try with a normal compare first, if we are lucky
755                          * we will avoid exploding and casfolding */
756                         if (strcmp(dn0->linearized, dn1->linearized) == 0) return 0;
757                 }
758
759                 if ( ! ldb_dn_casefold_internal(dn0)) {
760                         return 1;
761                 }
762
763                 if ( ! ldb_dn_casefold_internal(dn1)) {
764                         return -1;
765                 }
766
767         }
768
769         if (dn0->comp_num != dn1->comp_num) {
770                 return (dn1->comp_num - dn0->comp_num);
771         }
772
773         if (dn0->comp_num == 0) {
774                 if (dn0->special && dn1->special) {
775                         return strcmp(dn0->linearized, dn1->linearized);
776                 } else {
777                         return 0;
778                 }
779         }
780
781         for (i = 0; i < dn0->comp_num; i++) {
782                 /* compare attr names */
783                 ret = strcmp(dn0->components[i].cf_name, dn1->components[i].cf_name);
784                 if (ret != 0) return ret;
785
786                 /* compare attr.cf_value. */ 
787                 if (dn0->components[i].cf_value.length != dn1->components[i].cf_value.length) {
788                         return dn0->components[i].cf_value.length - dn1->components[i].cf_value.length;
789                 }
790                 ret = strcmp((char *)dn0->components[i].cf_value.data, (char *)dn1->components[i].cf_value.data);
791                 if (ret != 0) return ret;
792         }
793
794         return 0;
795 }
796
797 static struct ldb_dn_component ldb_dn_copy_component(void *mem_ctx, struct ldb_dn_component *src)
798 {
799         struct ldb_dn_component dst;
800
801         memset(&dst, 0, sizeof(dst));
802
803         if (src == NULL) {
804                 return dst;
805         }
806
807         dst.value = ldb_val_dup(mem_ctx, &(src->value));
808         if (dst.value.data == NULL) {
809                 return dst;
810         }
811
812         dst.name = talloc_strdup(mem_ctx, src->name);
813         if (dst.name == NULL) {
814                 LDB_FREE(dst.value.data);
815         }
816
817         if (src->cf_value.data) {
818                 dst.cf_value = ldb_val_dup(mem_ctx, &(src->cf_value));
819                 if (dst.cf_value.data == NULL) {
820                         LDB_FREE(dst.value.data);
821                         LDB_FREE(dst.name);
822                         return dst;
823                 }
824
825                 dst.cf_name = talloc_strdup(mem_ctx, src->cf_name);
826                 if (dst.cf_name == NULL) {
827                         LDB_FREE(dst.cf_name);
828                         LDB_FREE(dst.value.data);
829                         LDB_FREE(dst.name);
830                         return dst;
831                 }
832         } else {
833                 dst.cf_value.data = NULL;
834                 dst.cf_name = NULL;
835         }
836
837         return dst;
838 }
839
840 struct ldb_dn *ldb_dn_copy(void *mem_ctx, struct ldb_dn *dn)
841 {
842         struct ldb_dn *new_dn;
843
844         if (!dn || dn->invalid) {
845                 return NULL;
846         }
847
848         new_dn = talloc_zero(mem_ctx, struct ldb_dn);
849         if ( !new_dn) {
850                 return NULL;
851         }
852
853         *new_dn = *dn;
854
855         if (dn->valid_comp) {
856                 int i;
857
858                 new_dn->components = talloc_zero_array(new_dn, struct ldb_dn_component, dn->comp_num);
859                 if ( ! new_dn->components) {
860                         talloc_free(new_dn);
861                         return NULL;
862                 }
863
864                 for (i = 0; i < dn->comp_num; i++) {
865                         new_dn->components[i] = ldb_dn_copy_component(new_dn->components, &dn->components[i]);
866                         if ( ! new_dn->components[i].value.data) {
867                                 talloc_free(new_dn);
868                                 return NULL;
869                         }
870                 }
871
872                 if (dn->casefold) {
873                         new_dn->casefold = talloc_strdup(new_dn, dn->casefold);
874                         if ( ! new_dn->casefold) {
875                                 talloc_free(new_dn);
876                                 return NULL;
877                         }
878                 }
879         }
880
881         if (dn->valid_lin) {
882                 new_dn->linearized = talloc_strdup(new_dn, dn->linearized);
883                 if ( ! new_dn->linearized) {
884                         talloc_free(new_dn);
885                         return NULL;
886                 }
887         }
888
889         return new_dn;
890 }
891
892 /* modify the given dn by adding a base.
893  *
894  * return true if successful and false if not
895  * if false is returned the dn may be marked invalid
896  */
897 bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base)
898 {
899         const char *s;
900         char *t;
901
902         if ( !base || base->invalid || !dn || dn->invalid) {
903                 return false;
904         }
905
906         if (dn->valid_comp) {
907                 int i;
908
909                 if ( ! ldb_dn_validate(base)) {
910                         return false;
911                 }
912
913                 s = NULL;
914                 if (dn->valid_case) {
915                         if ( ! (s = ldb_dn_get_casefold(base))) {
916                                 return false;
917                         }
918                 }
919
920                 dn->components = talloc_realloc(dn,
921                                                 dn->components,
922                                                 struct ldb_dn_component,
923                                                 dn->comp_num + base->comp_num);
924                 if ( ! dn->components) {
925                         dn->invalid = true;
926                         return false;
927                 }
928
929                 for (i = 0; i < base->comp_num; dn->comp_num++, i++) {
930                         dn->components[dn->comp_num] = ldb_dn_copy_component(dn->components, &base->components[i]);
931                         if (dn->components[dn->comp_num].value.data == NULL) {
932                                 dn->invalid = true;
933                                 return false;
934                         }
935                 }
936
937                 if (s) {
938                         t = talloc_asprintf(dn, "%s,%s", dn->casefold, s);
939                         LDB_FREE(dn->casefold);
940                         dn->casefold = t;
941                 }
942         }
943
944         if (dn->valid_lin) {
945
946                 s = ldb_dn_get_linearized(base);
947                 if ( ! s) {
948                         return false;
949                 }
950                 
951                 t = talloc_asprintf(dn, "%s,%s", dn->linearized, s);
952                 if ( ! t) {
953                         dn->invalid = true;
954                         return false;
955                 }
956                 LDB_FREE(dn->linearized);
957                 dn->linearized = t;
958         }
959
960         return true;
961 }
962
963 /* modify the given dn by adding a base.
964  *
965  * return true if successful and false if not
966  * if false is returned the dn may be marked invalid
967  */
968 bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...)
969 {
970         struct ldb_dn *base;
971         char *base_str;
972         va_list ap;
973         bool ret;
974
975         if ( !dn || dn->invalid) {
976                 return false;
977         }
978
979         va_start(ap, base_fmt);
980         base_str = talloc_vasprintf(dn, base_fmt, ap);
981         va_end(ap);
982
983         if (base_str == NULL) {
984                 return false;
985         }
986
987         base = ldb_dn_new(base_str, dn->ldb, base_str);
988
989         ret = ldb_dn_add_base(dn, base);
990
991         talloc_free(base_str);
992
993         return ret;
994 }       
995
996 /* modify the given dn by adding children elements.
997  *
998  * return true if successful and false if not
999  * if false is returned the dn may be marked invalid
1000  */
1001 bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child)
1002 {
1003         const char *s;
1004         char *t;
1005
1006         if ( !child || child->invalid || !dn || dn->invalid) {
1007                 return false;
1008         }
1009
1010         if (dn->valid_comp) {
1011                 int n, i, j;
1012
1013                 if ( ! ldb_dn_validate(child)) {
1014                         return false;
1015                 }
1016
1017                 s = NULL;
1018                 if (dn->valid_case) {
1019                         if ( ! (s = ldb_dn_get_casefold(child))) {
1020                                 return false;
1021                         }
1022                 }
1023
1024                 n = dn->comp_num + child->comp_num;
1025
1026                 dn->components = talloc_realloc(dn,
1027                                                 dn->components,
1028                                                 struct ldb_dn_component,
1029                                                 n);
1030                 if ( ! dn->components) {
1031                         dn->invalid = true;
1032                         return false;
1033                 }
1034
1035                 for (i = dn->comp_num - 1, j = n - 1; i >= 0; i--, j--) {
1036                         dn->components[j] = dn->components[i];
1037                 }
1038
1039                 for (i = 0; i < child->comp_num; i++) { 
1040                         dn->components[i] = ldb_dn_copy_component(dn->components, &child->components[i]);
1041                         if (dn->components[i].value.data == NULL) {
1042                                 dn->invalid = true;
1043                                 return false;
1044                         }
1045                 }
1046
1047                 dn->comp_num = n;
1048
1049                 if (s) {
1050                         t = talloc_asprintf(dn, "%s,%s", s, dn->casefold);
1051                         LDB_FREE(dn->casefold);
1052                         dn->casefold = t;
1053                 }
1054         }
1055
1056         if (dn->valid_lin) {
1057
1058                 s = ldb_dn_get_linearized(child);
1059                 if ( ! s) {
1060                         return false;
1061                 }
1062                 
1063                 t = talloc_asprintf(dn, "%s,%s", s, dn->linearized);
1064                 if ( ! t) {
1065                         dn->invalid = true;
1066                         return false;
1067                 }
1068                 LDB_FREE(dn->linearized);
1069                 dn->linearized = t;
1070         }
1071
1072         return true;
1073 }
1074
1075 /* modify the given dn by adding children elements.
1076  *
1077  * return true if successful and false if not
1078  * if false is returned the dn may be marked invalid
1079  */
1080 bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...)
1081 {
1082         struct ldb_dn *child;
1083         char *child_str;
1084         va_list ap;
1085         bool ret;
1086
1087         if ( !dn || dn->invalid) {
1088                 return false;
1089         }
1090
1091         va_start(ap, child_fmt);
1092         child_str = talloc_vasprintf(dn, child_fmt, ap);
1093         va_end(ap);
1094
1095         if (child_str == NULL) {
1096                 return false;
1097         }
1098
1099         child = ldb_dn_new(child_str, dn->ldb, child_str);
1100
1101         ret = ldb_dn_add_child(dn, child);
1102
1103         talloc_free(child_str);
1104
1105         return ret;
1106 }
1107
1108 bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num)
1109 {
1110         if ( ! ldb_dn_validate(dn)) {
1111                 return false;
1112         }
1113
1114         if (dn->comp_num < num) {
1115                 return false;
1116         }
1117
1118         dn->comp_num -= num;
1119
1120         dn->valid_case = false;
1121
1122         if (dn->valid_lin) {    
1123                 dn->valid_lin = false;
1124                 LDB_FREE(dn->linearized);
1125         }
1126
1127         return true;
1128 }
1129
1130 bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num)
1131 {
1132         int i, j;
1133
1134         if ( ! ldb_dn_validate(dn)) {
1135                 return false;
1136         }
1137
1138         if (dn->comp_num < num) {
1139                 return false;
1140         }
1141
1142         for (i = 0, j = num; j < dn->comp_num; i++, j++) {
1143                 dn->components[i] = dn->components[j];
1144         }
1145
1146         dn->comp_num -= num;
1147
1148         dn->valid_case = false;
1149
1150         if (dn->valid_lin) {    
1151                 dn->valid_lin = false;
1152                 LDB_FREE(dn->linearized);
1153         }
1154
1155         return true;
1156 }
1157
1158 struct ldb_dn *ldb_dn_get_parent(void *mem_ctx, struct ldb_dn *dn)
1159 {
1160         struct ldb_dn *new_dn;
1161
1162         new_dn = ldb_dn_copy(mem_ctx, dn);
1163         if ( !new_dn ) {
1164                 return NULL;
1165         }
1166
1167         if ( ! ldb_dn_remove_child_components(new_dn, 1)) {
1168                 talloc_free(new_dn);
1169                 return NULL;
1170         }
1171
1172         return new_dn;
1173 }
1174
1175 /* Create a 'canonical name' string from a DN:
1176
1177    ie dc=samba,dc=org -> samba.org/
1178       uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator
1179
1180    There are two formats, the EX format has the last / replaced with a newline (\n).
1181
1182 */
1183 static char *ldb_dn_canonical(void *mem_ctx, struct ldb_dn *dn, int ex_format) {
1184         int i;
1185         char *cracked = NULL;
1186  
1187         if ( ! ldb_dn_validate(dn)) {
1188                 return NULL;
1189         }
1190         /* Walk backwards down the DN, grabbing 'dc' components at first */
1191         for (i = dn->comp_num - 1 ; i >= 0; i--) {
1192                 if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) {
1193                         break;
1194                 }
1195                 if (cracked) {
1196                         cracked = talloc_asprintf(mem_ctx, "%s.%s",
1197                                                   ldb_dn_escape_value(mem_ctx, dn->components[i].value),
1198                                                   cracked);
1199                 } else {
1200                         cracked = ldb_dn_escape_value(mem_ctx, dn->components[i].value);
1201                 }
1202                 if (!cracked) {
1203                         return NULL;
1204                 }
1205         }
1206
1207         /* Only domain components?  Finish here */
1208         if (i < 0) {
1209                 if (ex_format) {
1210                         cracked = talloc_asprintf(mem_ctx, "%s\n", cracked);
1211                 } else {
1212                         cracked = talloc_asprintf(mem_ctx, "%s/", cracked);
1213                 }
1214                 return cracked;
1215         }
1216
1217         /* Now walk backwards appending remaining components */
1218         for (; i > 0; i--) {
1219                 cracked = talloc_asprintf(mem_ctx, "%s/%s", cracked, 
1220                                           ldb_dn_escape_value(mem_ctx, dn->components[i].value));
1221                 if (!cracked) {
1222                         return NULL;
1223                 }
1224         }
1225
1226         /* Last one, possibly a newline for the 'ex' format */
1227         if (ex_format) {
1228                 cracked = talloc_asprintf(mem_ctx, "%s\n%s", cracked, 
1229                                           ldb_dn_escape_value(mem_ctx, dn->components[i].value));
1230         } else {
1231                 cracked = talloc_asprintf(mem_ctx, "%s/%s", cracked, 
1232                                           ldb_dn_escape_value(mem_ctx, dn->components[i].value));
1233         }
1234         return cracked;
1235 }
1236
1237 /* Wrapper functions for the above, for the two different string formats */
1238 char *ldb_dn_canonical_string(void *mem_ctx, struct ldb_dn *dn) {
1239         return ldb_dn_canonical(mem_ctx, dn, 0);
1240
1241 }
1242
1243 char *ldb_dn_canonical_ex_string(void *mem_ctx, struct ldb_dn *dn) {
1244         return ldb_dn_canonical(mem_ctx, dn, 1);
1245 }
1246
1247 int ldb_dn_get_comp_num(struct ldb_dn *dn)
1248 {
1249         if ( ! ldb_dn_validate(dn)) {
1250                 return -1;
1251         }
1252         return dn->comp_num;
1253 }
1254
1255 const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num)
1256 {
1257         if ( ! ldb_dn_validate(dn)) {
1258                 return NULL;
1259         }
1260         if (num >= dn->comp_num) return NULL;
1261         return dn->components[num].name;
1262 }
1263
1264 const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn, unsigned int num)
1265 {
1266         if ( ! ldb_dn_validate(dn)) {
1267                 return NULL;
1268         }
1269         if (num >= dn->comp_num) return NULL;
1270         return &dn->components[num].value;
1271 }
1272
1273 const char *ldb_dn_get_rdn_name(struct ldb_dn *dn)
1274 {
1275         if ( ! ldb_dn_validate(dn)) {
1276                 return NULL;
1277         }
1278         if (dn->comp_num == 0) return NULL;
1279         return dn->components[0].name;
1280 }
1281
1282 const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn)
1283 {
1284         if ( ! ldb_dn_validate(dn)) {
1285                 return NULL;
1286         }
1287         if (dn->comp_num == 0) return NULL;
1288         return &dn->components[0].value;
1289 }
1290
1291 int ldb_dn_set_component(struct ldb_dn *dn, int num, const char *name, const struct ldb_val val)
1292 {
1293         char *n;
1294         struct ldb_val v;
1295
1296         if ( ! ldb_dn_validate(dn)) {
1297                 return LDB_ERR_OTHER;
1298         }
1299
1300         if (num >= dn->comp_num) {
1301                 return LDB_ERR_OTHER;
1302         }
1303
1304         n = talloc_strdup(dn, name);
1305         if ( ! n) {
1306                 return LDB_ERR_OTHER;
1307         }
1308
1309         v.length = val.length;
1310         v.data = (uint8_t *)talloc_memdup(dn, val.data, v.length+1);
1311         if ( ! v.data) {
1312                 return LDB_ERR_OTHER;
1313         }
1314
1315         talloc_free(dn->components[num].name);
1316         talloc_free(dn->components[num].value.data);
1317         dn->components[num].name = n;
1318         dn->components[num].value = v;
1319
1320         if (dn->valid_case) dn->valid_case = false;
1321         if (dn->casefold) LDB_FREE(dn->casefold);
1322
1323         return LDB_SUCCESS;
1324 }
1325
1326 bool ldb_dn_is_valid(struct ldb_dn *dn)
1327 {
1328         if ( ! dn) return false;
1329         return ! dn->invalid;
1330 }
1331
1332 bool ldb_dn_is_special(struct ldb_dn *dn)
1333 {
1334         if ( ! dn || dn->invalid) return false;
1335         return dn->special;
1336 }
1337
1338 bool ldb_dn_check_special(struct ldb_dn *dn, const char *check)
1339 {
1340         if ( ! dn || dn->invalid) return false;
1341         return ! strcmp(dn->linearized, check);
1342 }
1343
1344 bool ldb_dn_is_null(struct ldb_dn *dn)
1345 {
1346         if ( ! dn || dn->invalid) return false;
1347         if (dn->special) return false;
1348         if (dn->valid_comp) {
1349                 if (dn->comp_num == 0) return true;
1350                 return false;
1351         } else {
1352                 if (dn->linearized[0] == '\0') return true;
1353         }
1354         return false;
1355 }