s4:ldb Remove DN+Binary code from the core ldb_dn
[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 3 of the License, or (at your option) any later version.
14
15    This library is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    Lesser General Public License for more details.
19
20    You should have received a copy of the GNU Lesser General Public
21    License along with this library; if not, see <http://www.gnu.org/licenses/>.
22 */
23
24 /*
25  *  Name: ldb
26  *
27  *  Component: ldb dn creation and manipulation utility functions
28  *
29  *  Description: - explode a dn into it's own basic elements
30  *                 and put them in a structure (only if necessary)
31  *               - manipulate ldb_dn structures
32  *
33  *  Author: Simo Sorce
34  */
35
36 #include "ldb_private.h"
37 #include <ctype.h>
38
39 #define LDB_DN_NULL_FAILED(x) if (!(x)) goto failed
40
41 #define LDB_FREE(x) do { talloc_free(x); x = NULL; } while(0)
42
43 /**
44    internal ldb exploded dn structures
45 */
46 struct ldb_dn_component {
47
48         char *name;
49         struct ldb_val value;
50
51         char *cf_name;
52         struct ldb_val cf_value;
53 };
54
55 struct ldb_dn_ext_component {
56
57         char *name;
58         struct ldb_val value;
59 };
60
61 struct ldb_dn {
62
63         struct ldb_context *ldb;
64
65         /* Special DNs are always linearized */
66         bool special;
67         bool invalid;
68
69         bool valid_case;
70
71         char *linearized;
72         char *ext_linearized;
73         char *casefold;
74
75         unsigned int comp_num;
76         struct ldb_dn_component *components;
77
78         unsigned int ext_comp_num;
79         struct ldb_dn_ext_component *ext_components;
80 };
81
82 /* it is helpful to be able to break on this in gdb */
83 static void ldb_dn_mark_invalid(struct ldb_dn *dn)
84 {
85         dn->invalid = true;
86 }
87
88 /* strdn may be NULL */
89 struct ldb_dn *ldb_dn_from_ldb_val(void *mem_ctx,
90                                    struct ldb_context *ldb,
91                                    const struct ldb_val *strdn)
92 {
93         struct ldb_dn *dn;
94
95         if (! ldb) return NULL;
96
97         if (strdn && strdn->data
98             && (strnlen((const char*)strdn->data, strdn->length) != strdn->length)) {
99                 /* The RDN must not contain a character with value 0x0 */
100                 return NULL;
101         }
102
103         dn = talloc_zero(mem_ctx, struct ldb_dn);
104         LDB_DN_NULL_FAILED(dn);
105
106         dn->ldb = ldb;
107
108         if (strdn->data && strdn->length) {
109                 const char *data = (const char *)strdn->data;
110                 size_t length = strdn->length;
111
112                 if (data[0] == '@') {
113                         dn->special = true;
114                 }
115                 dn->ext_linearized = talloc_strndup(dn, data, length);
116                 LDB_DN_NULL_FAILED(dn->ext_linearized);
117
118                 if (data[0] == '<') {
119                         const char *p_save, *p = dn->ext_linearized;
120                         do {
121                                 p_save = p;
122                                 p = strstr(p, ">;");
123                                 if (p) {
124                                         p = p + 2;
125                                 }
126                         } while (p);
127
128                         if (p_save == dn->ext_linearized) {
129                                 dn->linearized = talloc_strdup(dn, "");
130                         } else {
131                                 dn->linearized = talloc_strdup(dn, p_save);
132                         }
133                         LDB_DN_NULL_FAILED(dn->linearized);
134                 } else {
135                         dn->linearized = dn->ext_linearized;
136                         dn->ext_linearized = NULL;
137                 }
138         } else {
139                 dn->linearized = talloc_strdup(dn, "");
140                 LDB_DN_NULL_FAILED(dn->linearized);
141         }
142
143         return dn;
144
145 failed:
146         talloc_free(dn);
147         return NULL;
148 }
149
150 /* strdn may be NULL */
151 struct ldb_dn *ldb_dn_new(void *mem_ctx,
152                           struct ldb_context *ldb,
153                           const char *strdn)
154 {
155         struct ldb_val blob;
156         blob.data = discard_const_p(uint8_t, strdn);
157         blob.length = strdn ? strlen(strdn) : 0;
158         return ldb_dn_from_ldb_val(mem_ctx, ldb, &blob);
159 }
160
161 struct ldb_dn *ldb_dn_new_fmt(void *mem_ctx,
162                               struct ldb_context *ldb,
163                               const char *new_fmt, ...)
164 {
165         char *strdn;
166         va_list ap;
167
168         if ( (! mem_ctx) || (! ldb)) return NULL;
169
170         va_start(ap, new_fmt);
171         strdn = talloc_vasprintf(mem_ctx, new_fmt, ap);
172         va_end(ap);
173
174         if (strdn) {
175                 struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb, strdn);
176                 talloc_free(strdn);
177                 return dn;
178         }
179
180         return NULL;
181 }
182
183 static int ldb_dn_escape_internal(char *dst, const char *src, int len)
184 {
185         const char *p, *s;
186         char *d;
187         int l;
188
189         p = s = src;
190         d = dst;
191
192         while (p - src < len) {
193
194                 p += strcspn(p, ",=\n+<>#;\\\"");
195
196                 if (p - src == len) /* found no escapable chars */
197                         break;
198
199                 /* copy the part of the string before the stop */
200                 memcpy(d, s, p - s);
201                 d += (p - s); /* move to current position */
202
203                 if (*p) { /* it is a normal escapable character */
204                         *d++ = '\\';
205                         *d++ = *p++;
206                 } else { /* we have a zero byte in the string */
207                         strncpy(d, "\00", 3); /* escape the zero */
208                         d += 3;
209                         p++; /* skip the zero */
210                 }
211                 s = p; /* move forward */
212         }
213
214         /* copy the last part (with zero) and return */
215         l = len - (s - src);
216         memcpy(d, s, l + 1);
217
218         /* return the length of the resulting string */
219         return (l + (d - dst));
220 }
221
222 char *ldb_dn_escape_value(void *mem_ctx, struct ldb_val value)
223 {
224         char *dst;
225
226         if (!value.length)
227                 return NULL;
228
229         /* allocate destination string, it will be at most 3 times the source */
230         dst = talloc_array(mem_ctx, char, value.length * 3 + 1);
231         if ( ! dst) {
232                 talloc_free(dst);
233                 return NULL;
234         }
235
236         ldb_dn_escape_internal(dst, (const char *)value.data, value.length);
237
238         dst = talloc_realloc(mem_ctx, dst, char, strlen(dst) + 1);
239
240         return dst;
241 }
242
243 /*
244   explode a DN string into a ldb_dn structure
245   based on RFC4514 except that we don't support multiple valued RDNs
246
247   TODO: according to MS-ADTS:3.1.1.5.2 Naming Constraints
248   DN must be compliant with RFC2253
249 */
250 static bool ldb_dn_explode(struct ldb_dn *dn)
251 {
252         char *p, *ex_name, *ex_value, *data, *d, *dt, *t;
253         bool trim = false;
254         bool in_extended = false;
255         bool in_ex_name = false;
256         bool in_ex_value = false;
257         bool in_attr = false;
258         bool in_value = false;
259         bool in_quote = false;
260         bool is_oid = false;
261         bool escape = false;
262         unsigned x;
263         int l, ret;
264         char *parse_dn;
265         bool is_index;
266
267         if ( ! dn || dn->invalid) return false;
268
269         if (dn->components) {
270                 return true;
271         }
272
273         if (dn->ext_linearized) {
274                 parse_dn = dn->ext_linearized;
275         } else {
276                 parse_dn = dn->linearized;
277         }
278
279         if ( ! parse_dn ) {
280                 return false;
281         }
282
283         is_index = (strncmp(parse_dn, "DN=@INDEX:", 10) == 0);
284
285         /* Empty DNs */
286         if (parse_dn[0] == '\0') {
287                 return true;
288         }
289
290         /* Special DNs case */
291         if (dn->special) {
292                 return true;
293         }
294
295         /* make sure we free this if alloced previously before replacing */
296         talloc_free(dn->components);
297
298         talloc_free(dn->ext_components);
299         dn->ext_components = NULL;
300
301         /* in the common case we have 3 or more components */
302         /* make sure all components are zeroed, other functions depend on it */
303         dn->components = talloc_zero_array(dn, struct ldb_dn_component, 3);
304         if ( ! dn->components) {
305                 return false;
306         }
307         dn->comp_num = 0;
308
309         /* Components data space is allocated here once */
310         data = talloc_array(dn->components, char, strlen(parse_dn) + 1);
311         if (!data) {
312                 return false;
313         }
314
315         p = parse_dn;
316         in_extended = true;
317         in_ex_name = false;
318         in_ex_value = false;
319         trim = true;
320         t = NULL;
321         d = dt = data;
322
323         while (*p) {
324                 if (in_extended) {
325
326                         if (!in_ex_name && !in_ex_value) {
327
328                                 if (p[0] == '<') {
329                                         p++;
330                                         ex_name = d;
331                                         in_ex_name = true;
332                                         continue;
333                                 } else if (p[0] == '\0') {
334                                         p++;
335                                         continue;
336                                 } else {
337                                         in_extended = false;
338                                         in_attr = true;
339                                         dt = d;
340
341                                         continue;
342                                 }
343                         }
344
345                         if (in_ex_name && *p == '=') {
346                                 *d++ = '\0';
347                                 p++;
348                                 ex_value = d;
349                                 in_ex_name = false;
350                                 in_ex_value = true;
351                                 continue;
352                         }
353
354                         if (in_ex_value && *p == '>') {
355                                 const struct ldb_dn_extended_syntax *ext_syntax;
356                                 struct ldb_val ex_val = {
357                                         .data = (uint8_t *)ex_value,
358                                         .length = d - ex_value
359                                 };
360
361                                 *d++ = '\0';
362                                 p++;
363                                 in_ex_value = false;
364
365                                 /* Process name and ex_value */
366
367                                 dn->ext_components = talloc_realloc(dn,
368                                                                     dn->ext_components,
369                                                                     struct ldb_dn_ext_component,
370                                                                     dn->ext_comp_num + 1);
371                                 if ( ! dn->ext_components) {
372                                         /* ouch ! */
373                                         goto failed;
374                                 }
375
376                                 ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, ex_name);
377                                 if (!ext_syntax) {
378                                         /* We don't know about this type of extended DN */
379                                         goto failed;
380                                 }
381
382                                 dn->ext_components[dn->ext_comp_num].name = talloc_strdup(dn->ext_components, ex_name);
383                                 if (!dn->ext_components[dn->ext_comp_num].name) {
384                                         /* ouch */
385                                         goto failed;
386                                 }
387                                 ret = ext_syntax->read_fn(dn->ldb, dn->ext_components,
388                                                           &ex_val, &dn->ext_components[dn->ext_comp_num].value);
389                                 if (ret != LDB_SUCCESS) {
390                                         ldb_dn_mark_invalid(dn);
391                                         goto failed;
392                                 }
393
394                                 dn->ext_comp_num++;
395
396                                 if (*p == '\0') {
397                                         /* We have reached the end (extended component only)! */
398                                         talloc_free(data);
399                                         return true;
400
401                                 } else if (*p == ';') {
402                                         p++;
403                                         continue;
404                                 } else {
405                                         ldb_dn_mark_invalid(dn);
406                                         goto failed;
407                                 }
408                         }
409
410                         *d++ = *p++;
411                         continue;
412                 }
413                 if (in_attr) {
414                         if (trim) {
415                                 if (*p == ' ') {
416                                         p++;
417                                         continue;
418                                 }
419
420                                 /* first char */
421                                 trim = false;
422
423                                 if (!isascii(*p)) {
424                                         /* attr names must be ascii only */
425                                         ldb_dn_mark_invalid(dn);
426                                         goto failed;
427                                 }
428
429                                 if (isdigit(*p)) {
430                                         is_oid = true;
431                                 } else
432                                 if ( ! isalpha(*p)) {
433                                         /* not a digit nor an alpha,
434                                          * invalid attribute name */
435                                         ldb_dn_mark_invalid(dn);
436                                         goto failed;
437                                 }
438
439                                 /* Copy this character across from parse_dn,
440                                  * now we have trimmed out spaces */
441                                 *d++ = *p++;
442                                 continue;
443                         }
444
445                         if (*p == ' ') {
446                                 p++;
447                                 /* valid only if we are at the end */
448                                 trim = true;
449                                 continue;
450                         }
451
452                         if (trim && (*p != '=')) {
453                                 /* spaces/tabs are not allowed */
454                                 ldb_dn_mark_invalid(dn);
455                                 goto failed;
456                         }
457
458                         if (*p == '=') {
459                                 /* attribute terminated */
460                                 in_attr = false;
461                                 in_value = true;
462                                 trim = true;
463                                 l = 0;
464
465                                 /* Terminate this string in d
466                                  * (which is a copy of parse_dn
467                                  *  with spaces trimmed) */
468                                 *d++ = '\0';
469                                 dn->components[dn->comp_num].name = talloc_strdup(dn->components, dt);
470                                 if ( ! dn->components[dn->comp_num].name) {
471                                         /* ouch */
472                                         goto failed;
473                                 }
474
475                                 dt = d;
476
477                                 p++;
478                                 continue;
479                         }
480
481                         if (!isascii(*p)) {
482                                 /* attr names must be ascii only */
483                                 ldb_dn_mark_invalid(dn);
484                                 goto failed;
485                         }
486
487                         if (is_oid && ( ! (isdigit(*p) || (*p == '.')))) {
488                                 /* not a digit nor a dot,
489                                  * invalid attribute oid */
490                                 ldb_dn_mark_invalid(dn);
491                                 goto failed;
492                         } else
493                         if ( ! (isalpha(*p) || isdigit(*p) || (*p == '-'))) {
494                                 /* not ALPHA, DIGIT or HYPHEN */
495                                 ldb_dn_mark_invalid(dn);
496                                 goto failed;
497                         }
498
499                         *d++ = *p++;
500                         continue;
501                 }
502
503                 if (in_value) {
504                         if (in_quote) {
505                                 if (*p == '\"') {
506                                         if (p[-1] != '\\') {
507                                                 p++;
508                                                 in_quote = false;
509                                                 continue;
510                                         }
511                                 }
512                                 *d++ = *p++;
513                                 l++;
514                                 continue;
515                         }
516
517                         if (trim) {
518                                 if (*p == ' ') {
519                                         p++;
520                                         continue;
521                                 }
522
523                                 /* first char */
524                                 trim = false;
525
526                                 if (*p == '\"') {
527                                         in_quote = true;
528                                         p++;
529                                         continue;
530                                 }
531                         }
532
533                         switch (*p) {
534
535                         /* TODO: support ber encoded values
536                         case '#':
537                         */
538
539                         case ',':
540                                 if (escape) {
541                                         *d++ = *p++;
542                                         l++;
543                                         escape = false;
544                                         continue;
545                                 }
546                                 /* ok found value terminator */
547
548                                 if ( t ) {
549                                         /* trim back */
550                                         d -= (p - t);
551                                         l -= (p - t);
552                                 }
553
554                                 in_attr = true;
555                                 in_value = false;
556                                 trim = true;
557
558                                 p++;
559                                 *d++ = '\0';
560                                 dn->components[dn->comp_num].value.data = (uint8_t *)talloc_strdup(dn->components, dt);
561                                 dn->components[dn->comp_num].value.length = l;
562                                 if ( ! dn->components[dn->comp_num].value.data) {
563                                         /* ouch ! */
564                                         goto failed;
565                                 }
566
567                                 dt = d;
568
569                                 dn->comp_num++;
570                                 if (dn->comp_num > 2) {
571                                         dn->components = talloc_realloc(dn,
572                                                                         dn->components,
573                                                                         struct ldb_dn_component,
574                                                                         dn->comp_num + 1);
575                                         if ( ! dn->components) {
576                                                 /* ouch ! */
577                                                 goto failed;
578                                         }
579                                         /* make sure all components are zeroed, other functions depend on this */
580                                         memset(&dn->components[dn->comp_num], '\0', sizeof(struct ldb_dn_component));
581                                 }
582
583                                 continue;
584
585                         case '=':
586                         case '+':
587                                 /* to main compatibility with earlier
588                                 versions of ldb indexing, we have to
589                                 accept the base64 encoded binary index
590                                 values, which contain a '=' */
591                                 if (is_index) {
592                                         if ( t ) t = NULL;
593                                         *d++ = *p++;
594                                         l++;
595                                         break;
596                                 }
597                                 /* fall through */
598                         case '\n':
599                         case '<':
600                         case '>':
601                         case '#':
602                         case ';':
603                         case '\"':
604                                 /* a string with not escaped specials is invalid (tested) */
605                                 if ( ! escape) {
606                                         ldb_dn_mark_invalid(dn);
607                                         goto failed;
608                                 }
609                                 escape = false;
610
611                                 *d++ = *p++;
612                                 l++;
613
614                                 if ( t ) t = NULL;
615                                 break;
616
617                         case '\\':
618                                 if ( ! escape) {
619                                         escape = true;
620                                         p++;
621                                         continue;
622                                 }
623                                 escape = false;
624
625                                 *d++ = *p++;
626                                 l++;
627
628                                 if ( t ) t = NULL;
629                                 break;
630
631                         default:
632                                 if (escape) {
633                                         if (sscanf(p, "%02x", &x) != 1) {
634                                                 /* invalid escaping sequence */
635                                                 ldb_dn_mark_invalid(dn);
636                                                 goto failed;
637                                         }
638                                         escape = false;
639
640                                         p += 2;
641                                         *d++ = (unsigned char)x;
642                                         l++;
643
644                                         if ( t ) t = NULL;
645                                         break;
646                                 }
647
648                                 if (*p == ' ') {
649                                         if ( ! t) t = p;
650                                 } else {
651                                         if ( t ) t = NULL;
652                                 }
653
654                                 *d++ = *p++;
655                                 l++;
656
657                                 break;
658                         }
659
660                 }
661         }
662
663         if (in_attr || in_quote) {
664                 /* invalid dn */
665                 ldb_dn_mark_invalid(dn);
666                 goto failed;
667         }
668
669         /* save last element */
670         if ( t ) {
671                 /* trim back */
672                 d -= (p - t);
673                 l -= (p - t);
674         }
675
676         *d++ = '\0';
677         dn->components[dn->comp_num].value.length = l;
678         dn->components[dn->comp_num].value.data =
679                                 (uint8_t *)talloc_strdup(dn->components, dt);
680         if ( ! dn->components[dn->comp_num].value.data) {
681                 /* ouch */
682                 goto failed;
683         }
684
685         dn->comp_num++;
686
687         talloc_free(data);
688         return true;
689
690 failed:
691         dn->comp_num = 0;
692         talloc_free(dn->components);
693         return false;
694 }
695
696 bool ldb_dn_validate(struct ldb_dn *dn)
697 {
698         return ldb_dn_explode(dn);
699 }
700
701 const char *ldb_dn_get_linearized(struct ldb_dn *dn)
702 {
703         int i, len;
704         char *d, *n;
705
706         if ( ! dn || ( dn->invalid)) return NULL;
707
708         if (dn->linearized) return dn->linearized;
709
710         if ( ! dn->components) {
711                 ldb_dn_mark_invalid(dn);
712                 return NULL;
713         }
714
715         if (dn->comp_num == 0) {
716                 dn->linearized = talloc_strdup(dn, "");
717                 if ( ! dn->linearized) return NULL;
718                 return dn->linearized;
719         }
720
721         /* calculate maximum possible length of DN */
722         for (len = 0, i = 0; i < dn->comp_num; i++) {
723                 /* name len */
724                 len += strlen(dn->components[i].name);
725                 /* max escaped data len */
726                 len += (dn->components[i].value.length * 3);
727                 len += 2; /* '=' and ',' */
728         }
729         dn->linearized = talloc_array(dn, char, len);
730         if ( ! dn->linearized) return NULL;
731
732         d = dn->linearized;
733
734         for (i = 0; i < dn->comp_num; i++) {
735
736                 /* copy the name */
737                 n = dn->components[i].name;
738                 while (*n) *d++ = *n++;
739
740                 *d++ = '=';
741
742                 /* and the value */
743                 d += ldb_dn_escape_internal( d,
744                                 (char *)dn->components[i].value.data,
745                                 dn->components[i].value.length);
746                 *d++ = ',';
747         }
748
749         *(--d) = '\0';
750
751         /* don't waste more memory than necessary */
752         dn->linearized = talloc_realloc(dn, dn->linearized,
753                                         char, (d - dn->linearized + 1));
754
755         return dn->linearized;
756 }
757
758 char *ldb_dn_get_extended_linearized(void *mem_ctx, struct ldb_dn *dn, int mode)
759 {
760         const char *linearized = ldb_dn_get_linearized(dn);
761         char *p;
762         int i;
763
764         if (!linearized) {
765                 return NULL;
766         }
767
768         if (!ldb_dn_has_extended(dn)) {
769                 return talloc_strdup(mem_ctx, linearized);
770         }
771
772         if (!ldb_dn_validate(dn)) {
773                 return NULL;
774         }
775
776         for (i = 0; i < dn->ext_comp_num; i++) {
777                 const struct ldb_dn_extended_syntax *ext_syntax;
778                 const char *name = dn->ext_components[i].name;
779                 struct ldb_val ec_val = dn->ext_components[i].value;
780                 struct ldb_val val;
781                 int ret;
782
783                 ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name);
784
785                 if (mode == 1) {
786                         ret = ext_syntax->write_clear_fn(dn->ldb, mem_ctx,
787                                                         &ec_val, &val);
788                 } else if (mode == 0) {
789                         ret = ext_syntax->write_hex_fn(dn->ldb, mem_ctx,
790                                                         &ec_val, &val);
791                 } else {
792                         ret = -1;
793                 }
794
795                 if (ret != LDB_SUCCESS) {
796                         return NULL;
797                 }
798
799                 if (i == 0) {
800                         p = talloc_asprintf(mem_ctx, "<%s=%s>", 
801                                             name, val.data);
802                 } else {
803                         p = talloc_asprintf_append_buffer(p, ";<%s=%s>",
804                                                           name, val.data);
805                 }
806
807                 talloc_free(val.data);
808
809                 if (!p) {
810                         return NULL;
811                 }
812         }
813
814         if (dn->ext_comp_num && *linearized) {
815                 p = talloc_asprintf_append_buffer(p, ";%s", linearized);
816         }
817
818         if (!p) {
819                 return NULL;
820         }
821
822         return p;
823 }
824
825
826
827 char *ldb_dn_alloc_linearized(void *mem_ctx, struct ldb_dn *dn)
828 {
829         return talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn));
830 }
831
832 /*
833   casefold a dn. We need to casefold the attribute names, and canonicalize
834   attribute values of case insensitive attributes.
835 */
836
837 static bool ldb_dn_casefold_internal(struct ldb_dn *dn)
838 {
839         int i, ret;
840
841         if ( ! dn || dn->invalid) return false;
842
843         if (dn->valid_case) return true;
844
845         if (( ! dn->components) && ( ! ldb_dn_explode(dn))) {
846                 return false;
847         }
848
849         for (i = 0; i < dn->comp_num; i++) {
850                 const struct ldb_schema_attribute *a;
851
852                 dn->components[i].cf_name =
853                         ldb_attr_casefold(dn->components,
854                                           dn->components[i].name);
855                 if (!dn->components[i].cf_name) {
856                         goto failed;
857                 }
858
859                 a = ldb_schema_attribute_by_name(dn->ldb,
860                                                  dn->components[i].cf_name);
861
862                 ret = a->syntax->canonicalise_fn(dn->ldb, dn->components,
863                                                  &(dn->components[i].value),
864                                                  &(dn->components[i].cf_value));
865                 if (ret != 0) {
866                         goto failed;
867                 }
868         }
869
870         dn->valid_case = true;
871
872         return true;
873
874 failed:
875         for (i = 0; i < dn->comp_num; i++) {
876                 LDB_FREE(dn->components[i].cf_name);
877                 LDB_FREE(dn->components[i].cf_value.data);
878         }
879         return false;
880 }
881
882 const char *ldb_dn_get_casefold(struct ldb_dn *dn)
883 {
884         int i, len;
885         char *d, *n;
886
887         if (dn->casefold) return dn->casefold;
888
889         if (dn->special) {
890                 dn->casefold = talloc_strdup(dn, dn->linearized);
891                 if (!dn->casefold) return NULL;
892                 dn->valid_case = true;
893                 return dn->casefold;
894         }
895
896         if ( ! ldb_dn_casefold_internal(dn)) {
897                 return NULL;
898         }
899
900         if (dn->comp_num == 0) {
901                 dn->casefold = talloc_strdup(dn, "");
902                 return dn->casefold;
903         }
904
905         /* calculate maximum possible length of DN */
906         for (len = 0, i = 0; i < dn->comp_num; i++) {
907                 /* name len */
908                 len += strlen(dn->components[i].cf_name);
909                 /* max escaped data len */
910                 len += (dn->components[i].cf_value.length * 3);
911                 len += 2; /* '=' and ',' */
912         }
913         dn->casefold = talloc_array(dn, char, len);
914         if ( ! dn->casefold) return NULL;
915
916         d = dn->casefold;
917
918         for (i = 0; i < dn->comp_num; i++) {
919
920                 /* copy the name */
921                 n = dn->components[i].cf_name;
922                 while (*n) *d++ = *n++;
923
924                 *d++ = '=';
925
926                 /* and the value */
927                 d += ldb_dn_escape_internal( d,
928                                 (char *)dn->components[i].cf_value.data,
929                                 dn->components[i].cf_value.length);
930                 *d++ = ',';
931         }
932         *(--d) = '\0';
933
934         /* don't waste more memory than necessary */
935         dn->casefold = talloc_realloc(dn, dn->casefold,
936                                       char, strlen(dn->casefold) + 1);
937
938         return dn->casefold;
939 }
940
941 char *ldb_dn_alloc_casefold(void *mem_ctx, struct ldb_dn *dn)
942 {
943         return talloc_strdup(mem_ctx, ldb_dn_get_casefold(dn));
944 }
945
946 /* Determine if dn is below base, in the ldap tree.  Used for
947  * evaluating a subtree search.
948  * 0 if they match, otherwise non-zero
949  */
950
951 int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn)
952 {
953         int ret;
954         int n_base, n_dn;
955
956         if ( ! base || base->invalid) return 1;
957         if ( ! dn || dn->invalid) return -1;
958
959         if (( ! base->valid_case) || ( ! dn->valid_case)) {
960                 if (base->linearized && dn->linearized) {
961                         /* try with a normal compare first, if we are lucky
962                          * we will avoid exploding and casfolding */
963                         int dif;
964                         dif = strlen(dn->linearized) - strlen(base->linearized);
965                         if (dif < 0) {
966                                 return dif;
967                         }
968                         if (strcmp(base->linearized,
969                                    &dn->linearized[dif]) == 0) {
970                                 return 0;
971                         }
972                 }
973
974                 if ( ! ldb_dn_casefold_internal(base)) {
975                         return 1;
976                 }
977
978                 if ( ! ldb_dn_casefold_internal(dn)) {
979                         return -1;
980                 }
981
982         }
983
984         /* if base has more components,
985          * they don't have the same base */
986         if (base->comp_num > dn->comp_num) {
987                 return (dn->comp_num - base->comp_num);
988         }
989
990         if (dn->comp_num == 0) {
991                 if (dn->special && base->special) {
992                         return strcmp(base->linearized, dn->linearized);
993                 } else if (dn->special) {
994                         return -1;
995                 } else if (base->special) {
996                         return 1;
997                 } else {
998                         return 0;
999                 }
1000         }
1001
1002         n_base = base->comp_num - 1;
1003         n_dn = dn->comp_num - 1;
1004
1005         while (n_base >= 0) {
1006                 char *b_name = base->components[n_base].cf_name;
1007                 char *dn_name = dn->components[n_dn].cf_name;
1008
1009                 char *b_vdata = (char *)base->components[n_base].cf_value.data;
1010                 char *dn_vdata = (char *)dn->components[n_dn].cf_value.data;
1011
1012                 size_t b_vlen = base->components[n_base].cf_value.length;
1013                 size_t dn_vlen = dn->components[n_dn].cf_value.length;
1014
1015                 /* compare attr names */
1016                 ret = strcmp(b_name, dn_name);
1017                 if (ret != 0) return ret;
1018
1019                 /* compare attr.cf_value. */
1020                 if (b_vlen != dn_vlen) {
1021                         return b_vlen - dn_vlen;
1022                 }
1023                 ret = strcmp(b_vdata, dn_vdata);
1024                 if (ret != 0) return ret;
1025
1026                 n_base--;
1027                 n_dn--;
1028         }
1029
1030         return 0;
1031 }
1032
1033 /* compare DNs using casefolding compare functions.
1034
1035    If they match, then return 0
1036  */
1037
1038 int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1)
1039 {
1040         int i, ret;
1041
1042         if (( ! dn0) || dn0->invalid || ! dn1 || dn1->invalid) {
1043                 return -1;
1044         }
1045
1046         if (( ! dn0->valid_case) || ( ! dn1->valid_case)) {
1047                 if (dn0->linearized && dn1->linearized) {
1048                         /* try with a normal compare first, if we are lucky
1049                          * we will avoid exploding and casfolding */
1050                         if (strcmp(dn0->linearized, dn1->linearized) == 0) {
1051                                 return 0;
1052                         }
1053                 }
1054
1055                 if ( ! ldb_dn_casefold_internal(dn0)) {
1056                         return 1;
1057                 }
1058
1059                 if ( ! ldb_dn_casefold_internal(dn1)) {
1060                         return -1;
1061                 }
1062
1063         }
1064
1065         if (dn0->comp_num != dn1->comp_num) {
1066                 return (dn1->comp_num - dn0->comp_num);
1067         }
1068
1069         if (dn0->comp_num == 0) {
1070                 if (dn0->special && dn1->special) {
1071                         return strcmp(dn0->linearized, dn1->linearized);
1072                 } else if (dn0->special) {
1073                         return 1;
1074                 } else if (dn1->special) {
1075                         return -1;
1076                 } else {
1077                         return 0;
1078                 }
1079         }
1080
1081         for (i = 0; i < dn0->comp_num; i++) {
1082                 char *dn0_name = dn0->components[i].cf_name;
1083                 char *dn1_name = dn1->components[i].cf_name;
1084
1085                 char *dn0_vdata = (char *)dn0->components[i].cf_value.data;
1086                 char *dn1_vdata = (char *)dn1->components[i].cf_value.data;
1087
1088                 size_t dn0_vlen = dn0->components[i].cf_value.length;
1089                 size_t dn1_vlen = dn1->components[i].cf_value.length;
1090
1091                 /* compare attr names */
1092                 ret = strcmp(dn0_name, dn1_name);
1093                 if (ret != 0) {
1094                         return ret;
1095                 }
1096
1097                 /* compare attr.cf_value. */
1098                 if (dn0_vlen != dn1_vlen) {
1099                         return dn0_vlen - dn1_vlen;
1100                 }
1101                 ret = strcmp(dn0_vdata, dn1_vdata);
1102                 if (ret != 0) {
1103                         return ret;
1104                 }
1105         }
1106
1107         return 0;
1108 }
1109
1110 static struct ldb_dn_component ldb_dn_copy_component(
1111                                                 void *mem_ctx,
1112                                                 struct ldb_dn_component *src)
1113 {
1114         struct ldb_dn_component dst;
1115
1116         memset(&dst, 0, sizeof(dst));
1117
1118         if (src == NULL) {
1119                 return dst;
1120         }
1121
1122         dst.value = ldb_val_dup(mem_ctx, &(src->value));
1123         if (dst.value.data == NULL) {
1124                 return dst;
1125         }
1126
1127         dst.name = talloc_strdup(mem_ctx, src->name);
1128         if (dst.name == NULL) {
1129                 LDB_FREE(dst.value.data);
1130                 return dst;
1131         }
1132
1133         if (src->cf_value.data) {
1134                 dst.cf_value = ldb_val_dup(mem_ctx, &(src->cf_value));
1135                 if (dst.cf_value.data == NULL) {
1136                         LDB_FREE(dst.value.data);
1137                         LDB_FREE(dst.name);
1138                         return dst;
1139                 }
1140
1141                 dst.cf_name = talloc_strdup(mem_ctx, src->cf_name);
1142                 if (dst.cf_name == NULL) {
1143                         LDB_FREE(dst.cf_name);
1144                         LDB_FREE(dst.value.data);
1145                         LDB_FREE(dst.name);
1146                         return dst;
1147                 }
1148         } else {
1149                 dst.cf_value.data = NULL;
1150                 dst.cf_name = NULL;
1151         }
1152
1153         return dst;
1154 }
1155
1156 static struct ldb_dn_ext_component ldb_dn_ext_copy_component(
1157                                                 void *mem_ctx,
1158                                                 struct ldb_dn_ext_component *src)
1159 {
1160         struct ldb_dn_ext_component dst;
1161
1162         memset(&dst, 0, sizeof(dst));
1163
1164         if (src == NULL) {
1165                 return dst;
1166         }
1167
1168         dst.value = ldb_val_dup(mem_ctx, &(src->value));
1169         if (dst.value.data == NULL) {
1170                 return dst;
1171         }
1172
1173         dst.name = talloc_strdup(mem_ctx, src->name);
1174         if (dst.name == NULL) {
1175                 LDB_FREE(dst.value.data);
1176                 return dst;
1177         }
1178
1179         return dst;
1180 }
1181
1182 struct ldb_dn *ldb_dn_copy(void *mem_ctx, struct ldb_dn *dn)
1183 {
1184         struct ldb_dn *new_dn;
1185
1186         if (!dn || dn->invalid) {
1187                 return NULL;
1188         }
1189
1190         new_dn = talloc_zero(mem_ctx, struct ldb_dn);
1191         if ( !new_dn) {
1192                 return NULL;
1193         }
1194
1195         *new_dn = *dn;
1196
1197         if (dn->components) {
1198                 int i;
1199
1200                 new_dn->components =
1201                         talloc_zero_array(new_dn,
1202                                           struct ldb_dn_component,
1203                                           dn->comp_num);
1204                 if ( ! new_dn->components) {
1205                         talloc_free(new_dn);
1206                         return NULL;
1207                 }
1208
1209                 for (i = 0; i < dn->comp_num; i++) {
1210                         new_dn->components[i] =
1211                                 ldb_dn_copy_component(new_dn->components,
1212                                                       &dn->components[i]);
1213                         if ( ! new_dn->components[i].value.data) {
1214                                 talloc_free(new_dn);
1215                                 return NULL;
1216                         }
1217                 }
1218         }
1219
1220         if (dn->ext_components) {
1221                 int i;
1222
1223                 new_dn->ext_components =
1224                         talloc_zero_array(new_dn,
1225                                           struct ldb_dn_ext_component,
1226                                           dn->ext_comp_num);
1227                 if ( ! new_dn->ext_components) {
1228                         talloc_free(new_dn);
1229                         return NULL;
1230                 }
1231
1232                 for (i = 0; i < dn->ext_comp_num; i++) {
1233                         new_dn->ext_components[i] =
1234                                  ldb_dn_ext_copy_component(
1235                                                 new_dn->ext_components,
1236                                                 &dn->ext_components[i]);
1237                         if ( ! new_dn->ext_components[i].value.data) {
1238                                 talloc_free(new_dn);
1239                                 return NULL;
1240                         }
1241                 }
1242         }
1243
1244         if (dn->casefold) {
1245                 new_dn->casefold = talloc_strdup(new_dn, dn->casefold);
1246                 if ( ! new_dn->casefold) {
1247                         talloc_free(new_dn);
1248                         return NULL;
1249                 }
1250         }
1251
1252         if (dn->linearized) {
1253                 new_dn->linearized = talloc_strdup(new_dn, dn->linearized);
1254                 if ( ! new_dn->linearized) {
1255                         talloc_free(new_dn);
1256                         return NULL;
1257                 }
1258         }
1259
1260         if (dn->ext_linearized) {
1261                 new_dn->ext_linearized = talloc_strdup(new_dn,
1262                                                         dn->ext_linearized);
1263                 if ( ! new_dn->ext_linearized) {
1264                         talloc_free(new_dn);
1265                         return NULL;
1266                 }
1267         }
1268
1269         return new_dn;
1270 }
1271
1272 /* modify the given dn by adding a base.
1273  *
1274  * return true if successful and false if not
1275  * if false is returned the dn may be marked invalid
1276  */
1277 bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base)
1278 {
1279         const char *s;
1280         char *t;
1281
1282         if ( !base || base->invalid || !dn || dn->invalid) {
1283                 return false;
1284         }
1285
1286         if (dn->components) {
1287                 int i;
1288
1289                 if ( ! ldb_dn_validate(base)) {
1290                         return false;
1291                 }
1292
1293                 s = NULL;
1294                 if (dn->valid_case) {
1295                         if ( ! (s = ldb_dn_get_casefold(base))) {
1296                                 return false;
1297                         }
1298                 }
1299
1300                 dn->components = talloc_realloc(dn,
1301                                                 dn->components,
1302                                                 struct ldb_dn_component,
1303                                                 dn->comp_num + base->comp_num);
1304                 if ( ! dn->components) {
1305                         ldb_dn_mark_invalid(dn);
1306                         return false;
1307                 }
1308
1309                 for (i = 0; i < base->comp_num; dn->comp_num++, i++) {
1310                         dn->components[dn->comp_num] =
1311                                 ldb_dn_copy_component(dn->components,
1312                                                         &base->components[i]);
1313                         if (dn->components[dn->comp_num].value.data == NULL) {
1314                                 ldb_dn_mark_invalid(dn);
1315                                 return false;
1316                         }
1317                 }
1318
1319                 if (dn->casefold && s) {
1320                         if (*dn->casefold) {
1321                                 t = talloc_asprintf(dn, "%s,%s",
1322                                                     dn->casefold, s);
1323                         } else {
1324                                 t = talloc_strdup(dn, s);
1325                         }
1326                         LDB_FREE(dn->casefold);
1327                         dn->casefold = t;
1328                 }
1329         }
1330
1331         if (dn->linearized) {
1332
1333                 s = ldb_dn_get_linearized(base);
1334                 if ( ! s) {
1335                         return false;
1336                 }
1337
1338                 if (*dn->linearized) {
1339                         t = talloc_asprintf(dn, "%s,%s",
1340                                             dn->linearized, s);
1341                 } else {
1342                         t = talloc_strdup(dn, s);
1343                 }
1344                 if ( ! t) {
1345                         ldb_dn_mark_invalid(dn);
1346                         return false;
1347                 }
1348                 LDB_FREE(dn->linearized);
1349                 dn->linearized = t;
1350         }
1351
1352         /* Wipe the ext_linearized DN,
1353          * the GUID and SID are almost certainly no longer valid */
1354         if (dn->ext_linearized) {
1355                 LDB_FREE(dn->ext_linearized);
1356         }
1357
1358         LDB_FREE(dn->ext_components);
1359         dn->ext_comp_num = 0;
1360         return true;
1361 }
1362
1363 /* modify the given dn by adding a base.
1364  *
1365  * return true if successful and false if not
1366  * if false is returned the dn may be marked invalid
1367  */
1368 bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...)
1369 {
1370         struct ldb_dn *base;
1371         char *base_str;
1372         va_list ap;
1373         bool ret;
1374
1375         if ( !dn || dn->invalid) {
1376                 return false;
1377         }
1378
1379         va_start(ap, base_fmt);
1380         base_str = talloc_vasprintf(dn, base_fmt, ap);
1381         va_end(ap);
1382
1383         if (base_str == NULL) {
1384                 return false;
1385         }
1386
1387         base = ldb_dn_new(base_str, dn->ldb, base_str);
1388
1389         ret = ldb_dn_add_base(dn, base);
1390
1391         talloc_free(base_str);
1392
1393         return ret;
1394 }
1395
1396 /* modify the given dn by adding children elements.
1397  *
1398  * return true if successful and false if not
1399  * if false is returned the dn may be marked invalid
1400  */
1401 bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child)
1402 {
1403         const char *s;
1404         char *t;
1405
1406         if ( !child || child->invalid || !dn || dn->invalid) {
1407                 return false;
1408         }
1409
1410         if (dn->components) {
1411                 int n, i, j;
1412
1413                 if ( ! ldb_dn_validate(child)) {
1414                         return false;
1415                 }
1416
1417                 s = NULL;
1418                 if (dn->valid_case) {
1419                         if ( ! (s = ldb_dn_get_casefold(child))) {
1420                                 return false;
1421                         }
1422                 }
1423
1424                 n = dn->comp_num + child->comp_num;
1425
1426                 dn->components = talloc_realloc(dn,
1427                                                 dn->components,
1428                                                 struct ldb_dn_component,
1429                                                 n);
1430                 if ( ! dn->components) {
1431                         ldb_dn_mark_invalid(dn);
1432                         return false;
1433                 }
1434
1435                 for (i = dn->comp_num - 1, j = n - 1; i >= 0; i--, j--) {
1436                         dn->components[j] = dn->components[i];
1437                 }
1438
1439                 for (i = 0; i < child->comp_num; i++) {
1440                         dn->components[i] =
1441                                 ldb_dn_copy_component(dn->components,
1442                                                         &child->components[i]);
1443                         if (dn->components[i].value.data == NULL) {
1444                                 ldb_dn_mark_invalid(dn);
1445                                 return false;
1446                         }
1447                 }
1448
1449                 dn->comp_num = n;
1450
1451                 if (dn->casefold && s) {
1452                         t = talloc_asprintf(dn, "%s,%s", s, dn->casefold);
1453                         LDB_FREE(dn->casefold);
1454                         dn->casefold = t;
1455                 }
1456         }
1457
1458         if (dn->linearized) {
1459
1460                 s = ldb_dn_get_linearized(child);
1461                 if ( ! s) {
1462                         return false;
1463                 }
1464
1465                 t = talloc_asprintf(dn, "%s,%s", s, dn->linearized);
1466                 if ( ! t) {
1467                         ldb_dn_mark_invalid(dn);
1468                         return false;
1469                 }
1470                 LDB_FREE(dn->linearized);
1471                 dn->linearized = t;
1472         }
1473
1474         /* Wipe the ext_linearized DN,
1475          * the GUID and SID are almost certainly no longer valid */
1476         LDB_FREE(dn->ext_linearized);
1477
1478         LDB_FREE(dn->ext_components);
1479         dn->ext_comp_num = 0;
1480
1481         return true;
1482 }
1483
1484 /* modify the given dn by adding children elements.
1485  *
1486  * return true if successful and false if not
1487  * if false is returned the dn may be marked invalid
1488  */
1489 bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...)
1490 {
1491         struct ldb_dn *child;
1492         char *child_str;
1493         va_list ap;
1494         bool ret;
1495
1496         if ( !dn || dn->invalid) {
1497                 return false;
1498         }
1499
1500         va_start(ap, child_fmt);
1501         child_str = talloc_vasprintf(dn, child_fmt, ap);
1502         va_end(ap);
1503
1504         if (child_str == NULL) {
1505                 return false;
1506         }
1507
1508         child = ldb_dn_new(child_str, dn->ldb, child_str);
1509
1510         ret = ldb_dn_add_child(dn, child);
1511
1512         talloc_free(child_str);
1513
1514         return ret;
1515 }
1516
1517 bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num)
1518 {
1519         int i;
1520
1521         if ( ! ldb_dn_validate(dn)) {
1522                 return false;
1523         }
1524
1525         if (dn->comp_num < num) {
1526                 return false;
1527         }
1528
1529         /* free components */
1530         for (i = num; i > 0; i--) {
1531                 LDB_FREE(dn->components[dn->comp_num - i].name);
1532                 LDB_FREE(dn->components[dn->comp_num - i].value.data);
1533                 LDB_FREE(dn->components[dn->comp_num - i].cf_name);
1534                 LDB_FREE(dn->components[dn->comp_num - i].cf_value.data);
1535         }
1536
1537         dn->comp_num -= num;
1538
1539         if (dn->valid_case) {
1540                 for (i = 0; i < dn->comp_num; i++) {
1541                         LDB_FREE(dn->components[i].cf_name);
1542                         LDB_FREE(dn->components[i].cf_value.data);
1543                 }
1544                 dn->valid_case = false;
1545         }
1546
1547         LDB_FREE(dn->casefold);
1548         LDB_FREE(dn->linearized);
1549
1550         /* Wipe the ext_linearized DN,
1551          * the GUID and SID are almost certainly no longer valid */
1552         LDB_FREE(dn->ext_linearized);
1553
1554         LDB_FREE(dn->ext_components);
1555         dn->ext_comp_num = 0;
1556
1557         return true;
1558 }
1559
1560 bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num)
1561 {
1562         int i, j;
1563
1564         if ( ! ldb_dn_validate(dn)) {
1565                 return false;
1566         }
1567
1568         if (dn->comp_num < num) {
1569                 return false;
1570         }
1571
1572         for (i = 0, j = num; j < dn->comp_num; i++, j++) {
1573                 if (i < num) {
1574                         LDB_FREE(dn->components[i].name);
1575                         LDB_FREE(dn->components[i].value.data);
1576                         LDB_FREE(dn->components[i].cf_name);
1577                         LDB_FREE(dn->components[i].cf_value.data);
1578                 }
1579                 dn->components[i] = dn->components[j];
1580         }
1581
1582         dn->comp_num -= num;
1583
1584         if (dn->valid_case) {
1585                 for (i = 0; i < dn->comp_num; i++) {
1586                         LDB_FREE(dn->components[i].cf_name);
1587                         LDB_FREE(dn->components[i].cf_value.data);
1588                 }
1589                 dn->valid_case = false;
1590         }
1591
1592         LDB_FREE(dn->casefold);
1593         LDB_FREE(dn->linearized);
1594
1595         /* Wipe the ext_linearized DN,
1596          * the GUID and SID are almost certainly no longer valid */
1597         LDB_FREE(dn->ext_linearized);
1598
1599         LDB_FREE(dn->ext_components);
1600         dn->ext_comp_num = 0;
1601         return true;
1602 }
1603
1604 struct ldb_dn *ldb_dn_get_parent(void *mem_ctx, struct ldb_dn *dn)
1605 {
1606         struct ldb_dn *new_dn;
1607
1608         new_dn = ldb_dn_copy(mem_ctx, dn);
1609         if ( !new_dn ) {
1610                 return NULL;
1611         }
1612
1613         if ( ! ldb_dn_remove_child_components(new_dn, 1)) {
1614                 talloc_free(new_dn);
1615                 return NULL;
1616         }
1617
1618         /* Wipe the ext_linearized DN,
1619          * the GUID and SID are almost certainly no longer valid */
1620         LDB_FREE(dn->ext_linearized);
1621
1622         LDB_FREE(dn->ext_components);
1623         dn->ext_comp_num = 0;
1624         return new_dn;
1625 }
1626
1627 /* Create a 'canonical name' string from a DN:
1628
1629    ie dc=samba,dc=org -> samba.org/
1630       uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator
1631
1632    There are two formats,
1633    the EX format has the last '/' replaced with a newline (\n).
1634
1635 */
1636 static char *ldb_dn_canonical(void *mem_ctx, struct ldb_dn *dn, int ex_format) {
1637         int i;
1638         TALLOC_CTX *tmpctx;
1639         char *cracked = NULL;
1640         const char *format = (ex_format ? "\n" : "/" );
1641
1642         if ( ! ldb_dn_validate(dn)) {
1643                 return NULL;
1644         }
1645
1646         tmpctx = talloc_new(mem_ctx);
1647
1648         /* Walk backwards down the DN, grabbing 'dc' components at first */
1649         for (i = dn->comp_num - 1 ; i >= 0; i--) {
1650                 if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) {
1651                         break;
1652                 }
1653                 if (cracked) {
1654                         cracked = talloc_asprintf(tmpctx, "%s.%s",
1655                                                   ldb_dn_escape_value(tmpctx,
1656                                                         dn->components[i].value),
1657                                                   cracked);
1658                 } else {
1659                         cracked = ldb_dn_escape_value(tmpctx,
1660                                                         dn->components[i].value);
1661                 }
1662                 if (!cracked) {
1663                         goto done;
1664                 }
1665         }
1666
1667         /* Only domain components?  Finish here */
1668         if (i < 0) {
1669                 cracked = talloc_strdup_append_buffer(cracked, format);
1670                 talloc_steal(mem_ctx, cracked);
1671                 goto done;
1672         }
1673
1674         /* Now walk backwards appending remaining components */
1675         for (; i > 0; i--) {
1676                 cracked = talloc_asprintf_append_buffer(cracked, "/%s",
1677                                                         ldb_dn_escape_value(tmpctx,
1678                                                         dn->components[i].value));
1679                 if (!cracked) {
1680                         goto done;
1681                 }
1682         }
1683
1684         /* Last one, possibly a newline for the 'ex' format */
1685         cracked = talloc_asprintf_append_buffer(cracked, "%s%s", format,
1686                                                 ldb_dn_escape_value(tmpctx,
1687                                                         dn->components[i].value));
1688
1689         talloc_steal(mem_ctx, cracked);
1690 done:
1691         talloc_free(tmpctx);
1692         return cracked;
1693 }
1694
1695 /* Wrapper functions for the above, for the two different string formats */
1696 char *ldb_dn_canonical_string(void *mem_ctx, struct ldb_dn *dn) {
1697         return ldb_dn_canonical(mem_ctx, dn, 0);
1698
1699 }
1700
1701 char *ldb_dn_canonical_ex_string(void *mem_ctx, struct ldb_dn *dn) {
1702         return ldb_dn_canonical(mem_ctx, dn, 1);
1703 }
1704
1705 int ldb_dn_get_comp_num(struct ldb_dn *dn)
1706 {
1707         if ( ! ldb_dn_validate(dn)) {
1708                 return -1;
1709         }
1710         return dn->comp_num;
1711 }
1712
1713 const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num)
1714 {
1715         if ( ! ldb_dn_validate(dn)) {
1716                 return NULL;
1717         }
1718         if (num >= dn->comp_num) return NULL;
1719         return dn->components[num].name;
1720 }
1721
1722 const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn,
1723                                                 unsigned int num)
1724 {
1725         if ( ! ldb_dn_validate(dn)) {
1726                 return NULL;
1727         }
1728         if (num >= dn->comp_num) return NULL;
1729         return &dn->components[num].value;
1730 }
1731
1732 const char *ldb_dn_get_rdn_name(struct ldb_dn *dn)
1733 {
1734         if ( ! ldb_dn_validate(dn)) {
1735                 return NULL;
1736         }
1737         if (dn->comp_num == 0) return NULL;
1738         return dn->components[0].name;
1739 }
1740
1741 const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn)
1742 {
1743         if ( ! ldb_dn_validate(dn)) {
1744                 return NULL;
1745         }
1746         if (dn->comp_num == 0) return NULL;
1747         return &dn->components[0].value;
1748 }
1749
1750 int ldb_dn_set_component(struct ldb_dn *dn, int num,
1751                          const char *name, const struct ldb_val val)
1752 {
1753         char *n;
1754         struct ldb_val v;
1755
1756         if ( ! ldb_dn_validate(dn)) {
1757                 return LDB_ERR_OTHER;
1758         }
1759
1760         if (num >= dn->comp_num) {
1761                 return LDB_ERR_OTHER;
1762         }
1763
1764         n = talloc_strdup(dn, name);
1765         if ( ! n) {
1766                 return LDB_ERR_OTHER;
1767         }
1768
1769         v.length = val.length;
1770         v.data = (uint8_t *)talloc_memdup(dn, val.data, v.length+1);
1771         if ( ! v.data) {
1772                 talloc_free(n);
1773                 return LDB_ERR_OTHER;
1774         }
1775
1776         talloc_free(dn->components[num].name);
1777         talloc_free(dn->components[num].value.data);
1778         dn->components[num].name = n;
1779         dn->components[num].value = v;
1780
1781         if (dn->valid_case) {
1782                 int i;
1783                 for (i = 0; i < dn->comp_num; i++) {
1784                         LDB_FREE(dn->components[i].cf_name);
1785                         LDB_FREE(dn->components[i].cf_value.data);
1786                 }
1787                 dn->valid_case = false;
1788         }
1789         LDB_FREE(dn->casefold);
1790         LDB_FREE(dn->linearized);
1791
1792         /* Wipe the ext_linearized DN,
1793          * the GUID and SID are almost certainly no longer valid */
1794         LDB_FREE(dn->ext_linearized);
1795
1796         dn->ext_comp_num = 0;
1797         LDB_FREE(dn->ext_components);
1798         return LDB_SUCCESS;
1799 }
1800
1801 const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn,
1802                                                     const char *name)
1803 {
1804         int i;
1805         if ( ! ldb_dn_validate(dn)) {
1806                 return NULL;
1807         }
1808         for (i=0; i < dn->ext_comp_num; i++) {
1809                 if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) {
1810                         return &dn->ext_components[i].value;
1811                 }
1812         }
1813         return NULL;
1814 }
1815
1816 int ldb_dn_set_extended_component(struct ldb_dn *dn,
1817                                   const char *name, const struct ldb_val *val)
1818 {
1819         struct ldb_dn_ext_component *p;
1820         int i;
1821
1822         if ( ! ldb_dn_validate(dn)) {
1823                 return LDB_ERR_OTHER;
1824         }
1825
1826         for (i=0; i < dn->ext_comp_num; i++) {
1827                 if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) {
1828                         if (val) {
1829                                 dn->ext_components[i].value =
1830                                         ldb_val_dup(dn->ext_components, val);
1831
1832                                 dn->ext_components[i].name =
1833                                         talloc_strdup(dn->ext_components, name);
1834                                 if (!dn->ext_components[i].name ||
1835                                     !dn->ext_components[i].value.data) {
1836                                         ldb_dn_mark_invalid(dn);
1837                                         return LDB_ERR_OPERATIONS_ERROR;
1838                                 }
1839
1840                         } else {
1841                                 if (i != (dn->ext_comp_num - 1)) {
1842                                         memmove(&dn->ext_components[i],
1843                                                 &dn->ext_components[i+1],
1844                                                 ((dn->ext_comp_num-1) - i) *
1845                                                   sizeof(*dn->ext_components));
1846                                 }
1847                                 dn->ext_comp_num--;
1848
1849                                 dn->ext_components = talloc_realloc(dn,
1850                                                    dn->ext_components,
1851                                                    struct ldb_dn_ext_component,
1852                                                    dn->ext_comp_num);
1853                                 if (!dn->ext_components) {
1854                                         ldb_dn_mark_invalid(dn);
1855                                         return LDB_ERR_OPERATIONS_ERROR;
1856                                 }
1857                                 return LDB_SUCCESS;
1858                         }
1859                 }
1860         }
1861
1862         p = dn->ext_components
1863                 = talloc_realloc(dn,
1864                                  dn->ext_components,
1865                                  struct ldb_dn_ext_component,
1866                                  dn->ext_comp_num + 1);
1867         if (!dn->ext_components) {
1868                 ldb_dn_mark_invalid(dn);
1869                 return LDB_ERR_OPERATIONS_ERROR;
1870         }
1871
1872         p[dn->ext_comp_num].value = ldb_val_dup(dn->ext_components, val);
1873         p[dn->ext_comp_num].name = talloc_strdup(p, name);
1874
1875         if (!dn->ext_components[i].name || !dn->ext_components[i].value.data) {
1876                 ldb_dn_mark_invalid(dn);
1877                 return LDB_ERR_OPERATIONS_ERROR;
1878         }
1879         dn->ext_components = p;
1880         dn->ext_comp_num++;
1881
1882         return LDB_SUCCESS;
1883 }
1884
1885 void ldb_dn_remove_extended_components(struct ldb_dn *dn)
1886 {
1887         dn->ext_comp_num = 0;
1888         LDB_FREE(dn->ext_components);
1889 }
1890
1891 bool ldb_dn_is_valid(struct ldb_dn *dn)
1892 {
1893         if ( ! dn) return false;
1894         return ! dn->invalid;
1895 }
1896
1897 bool ldb_dn_is_special(struct ldb_dn *dn)
1898 {
1899         if ( ! dn || dn->invalid) return false;
1900         return dn->special;
1901 }
1902
1903 bool ldb_dn_has_extended(struct ldb_dn *dn)
1904 {
1905         if ( ! dn || dn->invalid) return false;
1906         if (dn->ext_linearized && (dn->ext_linearized[0] == '<')) return true;
1907         return dn->ext_comp_num != 0;
1908 }
1909
1910 bool ldb_dn_check_special(struct ldb_dn *dn, const char *check)
1911 {
1912         if ( ! dn || dn->invalid) return false;
1913         return ! strcmp(dn->linearized, check);
1914 }
1915
1916 bool ldb_dn_is_null(struct ldb_dn *dn)
1917 {
1918         if ( ! dn || dn->invalid) return false;
1919         if (ldb_dn_has_extended(dn)) return false;
1920         if (dn->linearized && (dn->linearized[0] == '\0')) return true;
1921         return false;
1922 }
1923