9ac654973a4a6949cbea53d89efaf041d537c153
[ira/wip.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                 if (!ext_syntax) {
785                         return NULL;
786                 }
787
788                 if (mode == 1) {
789                         ret = ext_syntax->write_clear_fn(dn->ldb, mem_ctx,
790                                                         &ec_val, &val);
791                 } else if (mode == 0) {
792                         ret = ext_syntax->write_hex_fn(dn->ldb, mem_ctx,
793                                                         &ec_val, &val);
794                 } else {
795                         ret = -1;
796                 }
797
798                 if (ret != LDB_SUCCESS) {
799                         return NULL;
800                 }
801
802                 if (i == 0) {
803                         p = talloc_asprintf(mem_ctx, "<%s=%s>", 
804                                             name, val.data);
805                 } else {
806                         p = talloc_asprintf_append_buffer(p, ";<%s=%s>",
807                                                           name, val.data);
808                 }
809
810                 talloc_free(val.data);
811
812                 if (!p) {
813                         return NULL;
814                 }
815         }
816
817         if (dn->ext_comp_num && *linearized) {
818                 p = talloc_asprintf_append_buffer(p, ";%s", linearized);
819         }
820
821         if (!p) {
822                 return NULL;
823         }
824
825         return p;
826 }
827
828
829
830 char *ldb_dn_alloc_linearized(void *mem_ctx, struct ldb_dn *dn)
831 {
832         return talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn));
833 }
834
835 /*
836   casefold a dn. We need to casefold the attribute names, and canonicalize
837   attribute values of case insensitive attributes.
838 */
839
840 static bool ldb_dn_casefold_internal(struct ldb_dn *dn)
841 {
842         int i, ret;
843
844         if ( ! dn || dn->invalid) return false;
845
846         if (dn->valid_case) return true;
847
848         if (( ! dn->components) && ( ! ldb_dn_explode(dn))) {
849                 return false;
850         }
851
852         for (i = 0; i < dn->comp_num; i++) {
853                 const struct ldb_schema_attribute *a;
854
855                 dn->components[i].cf_name =
856                         ldb_attr_casefold(dn->components,
857                                           dn->components[i].name);
858                 if (!dn->components[i].cf_name) {
859                         goto failed;
860                 }
861
862                 a = ldb_schema_attribute_by_name(dn->ldb,
863                                                  dn->components[i].cf_name);
864
865                 ret = a->syntax->canonicalise_fn(dn->ldb, dn->components,
866                                                  &(dn->components[i].value),
867                                                  &(dn->components[i].cf_value));
868                 if (ret != 0) {
869                         goto failed;
870                 }
871         }
872
873         dn->valid_case = true;
874
875         return true;
876
877 failed:
878         for (i = 0; i < dn->comp_num; i++) {
879                 LDB_FREE(dn->components[i].cf_name);
880                 LDB_FREE(dn->components[i].cf_value.data);
881         }
882         return false;
883 }
884
885 const char *ldb_dn_get_casefold(struct ldb_dn *dn)
886 {
887         int i, len;
888         char *d, *n;
889
890         if (dn->casefold) return dn->casefold;
891
892         if (dn->special) {
893                 dn->casefold = talloc_strdup(dn, dn->linearized);
894                 if (!dn->casefold) return NULL;
895                 dn->valid_case = true;
896                 return dn->casefold;
897         }
898
899         if ( ! ldb_dn_casefold_internal(dn)) {
900                 return NULL;
901         }
902
903         if (dn->comp_num == 0) {
904                 dn->casefold = talloc_strdup(dn, "");
905                 return dn->casefold;
906         }
907
908         /* calculate maximum possible length of DN */
909         for (len = 0, i = 0; i < dn->comp_num; i++) {
910                 /* name len */
911                 len += strlen(dn->components[i].cf_name);
912                 /* max escaped data len */
913                 len += (dn->components[i].cf_value.length * 3);
914                 len += 2; /* '=' and ',' */
915         }
916         dn->casefold = talloc_array(dn, char, len);
917         if ( ! dn->casefold) return NULL;
918
919         d = dn->casefold;
920
921         for (i = 0; i < dn->comp_num; i++) {
922
923                 /* copy the name */
924                 n = dn->components[i].cf_name;
925                 while (*n) *d++ = *n++;
926
927                 *d++ = '=';
928
929                 /* and the value */
930                 d += ldb_dn_escape_internal( d,
931                                 (char *)dn->components[i].cf_value.data,
932                                 dn->components[i].cf_value.length);
933                 *d++ = ',';
934         }
935         *(--d) = '\0';
936
937         /* don't waste more memory than necessary */
938         dn->casefold = talloc_realloc(dn, dn->casefold,
939                                       char, strlen(dn->casefold) + 1);
940
941         return dn->casefold;
942 }
943
944 char *ldb_dn_alloc_casefold(void *mem_ctx, struct ldb_dn *dn)
945 {
946         return talloc_strdup(mem_ctx, ldb_dn_get_casefold(dn));
947 }
948
949 /* Determine if dn is below base, in the ldap tree.  Used for
950  * evaluating a subtree search.
951  * 0 if they match, otherwise non-zero
952  */
953
954 int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn)
955 {
956         int ret;
957         int n_base, n_dn;
958
959         if ( ! base || base->invalid) return 1;
960         if ( ! dn || dn->invalid) return -1;
961
962         if (( ! base->valid_case) || ( ! dn->valid_case)) {
963                 if (base->linearized && dn->linearized) {
964                         /* try with a normal compare first, if we are lucky
965                          * we will avoid exploding and casfolding */
966                         int dif;
967                         dif = strlen(dn->linearized) - strlen(base->linearized);
968                         if (dif < 0) {
969                                 return dif;
970                         }
971                         if (strcmp(base->linearized,
972                                    &dn->linearized[dif]) == 0) {
973                                 return 0;
974                         }
975                 }
976
977                 if ( ! ldb_dn_casefold_internal(base)) {
978                         return 1;
979                 }
980
981                 if ( ! ldb_dn_casefold_internal(dn)) {
982                         return -1;
983                 }
984
985         }
986
987         /* if base has more components,
988          * they don't have the same base */
989         if (base->comp_num > dn->comp_num) {
990                 return (dn->comp_num - base->comp_num);
991         }
992
993         if (dn->comp_num == 0) {
994                 if (dn->special && base->special) {
995                         return strcmp(base->linearized, dn->linearized);
996                 } else if (dn->special) {
997                         return -1;
998                 } else if (base->special) {
999                         return 1;
1000                 } else {
1001                         return 0;
1002                 }
1003         }
1004
1005         n_base = base->comp_num - 1;
1006         n_dn = dn->comp_num - 1;
1007
1008         while (n_base >= 0) {
1009                 char *b_name = base->components[n_base].cf_name;
1010                 char *dn_name = dn->components[n_dn].cf_name;
1011
1012                 char *b_vdata = (char *)base->components[n_base].cf_value.data;
1013                 char *dn_vdata = (char *)dn->components[n_dn].cf_value.data;
1014
1015                 size_t b_vlen = base->components[n_base].cf_value.length;
1016                 size_t dn_vlen = dn->components[n_dn].cf_value.length;
1017
1018                 /* compare attr names */
1019                 ret = strcmp(b_name, dn_name);
1020                 if (ret != 0) return ret;
1021
1022                 /* compare attr.cf_value. */
1023                 if (b_vlen != dn_vlen) {
1024                         return b_vlen - dn_vlen;
1025                 }
1026                 ret = strcmp(b_vdata, dn_vdata);
1027                 if (ret != 0) return ret;
1028
1029                 n_base--;
1030                 n_dn--;
1031         }
1032
1033         return 0;
1034 }
1035
1036 /* compare DNs using casefolding compare functions.
1037
1038    If they match, then return 0
1039  */
1040
1041 int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1)
1042 {
1043         int i, ret;
1044
1045         if (( ! dn0) || dn0->invalid || ! dn1 || dn1->invalid) {
1046                 return -1;
1047         }
1048
1049         if (( ! dn0->valid_case) || ( ! dn1->valid_case)) {
1050                 if (dn0->linearized && dn1->linearized) {
1051                         /* try with a normal compare first, if we are lucky
1052                          * we will avoid exploding and casfolding */
1053                         if (strcmp(dn0->linearized, dn1->linearized) == 0) {
1054                                 return 0;
1055                         }
1056                 }
1057
1058                 if ( ! ldb_dn_casefold_internal(dn0)) {
1059                         return 1;
1060                 }
1061
1062                 if ( ! ldb_dn_casefold_internal(dn1)) {
1063                         return -1;
1064                 }
1065
1066         }
1067
1068         if (dn0->comp_num != dn1->comp_num) {
1069                 return (dn1->comp_num - dn0->comp_num);
1070         }
1071
1072         if (dn0->comp_num == 0) {
1073                 if (dn0->special && dn1->special) {
1074                         return strcmp(dn0->linearized, dn1->linearized);
1075                 } else if (dn0->special) {
1076                         return 1;
1077                 } else if (dn1->special) {
1078                         return -1;
1079                 } else {
1080                         return 0;
1081                 }
1082         }
1083
1084         for (i = 0; i < dn0->comp_num; i++) {
1085                 char *dn0_name = dn0->components[i].cf_name;
1086                 char *dn1_name = dn1->components[i].cf_name;
1087
1088                 char *dn0_vdata = (char *)dn0->components[i].cf_value.data;
1089                 char *dn1_vdata = (char *)dn1->components[i].cf_value.data;
1090
1091                 size_t dn0_vlen = dn0->components[i].cf_value.length;
1092                 size_t dn1_vlen = dn1->components[i].cf_value.length;
1093
1094                 /* compare attr names */
1095                 ret = strcmp(dn0_name, dn1_name);
1096                 if (ret != 0) {
1097                         return ret;
1098                 }
1099
1100                 /* compare attr.cf_value. */
1101                 if (dn0_vlen != dn1_vlen) {
1102                         return dn0_vlen - dn1_vlen;
1103                 }
1104                 ret = strcmp(dn0_vdata, dn1_vdata);
1105                 if (ret != 0) {
1106                         return ret;
1107                 }
1108         }
1109
1110         return 0;
1111 }
1112
1113 static struct ldb_dn_component ldb_dn_copy_component(
1114                                                 void *mem_ctx,
1115                                                 struct ldb_dn_component *src)
1116 {
1117         struct ldb_dn_component dst;
1118
1119         memset(&dst, 0, sizeof(dst));
1120
1121         if (src == NULL) {
1122                 return dst;
1123         }
1124
1125         dst.value = ldb_val_dup(mem_ctx, &(src->value));
1126         if (dst.value.data == NULL) {
1127                 return dst;
1128         }
1129
1130         dst.name = talloc_strdup(mem_ctx, src->name);
1131         if (dst.name == NULL) {
1132                 LDB_FREE(dst.value.data);
1133                 return dst;
1134         }
1135
1136         if (src->cf_value.data) {
1137                 dst.cf_value = ldb_val_dup(mem_ctx, &(src->cf_value));
1138                 if (dst.cf_value.data == NULL) {
1139                         LDB_FREE(dst.value.data);
1140                         LDB_FREE(dst.name);
1141                         return dst;
1142                 }
1143
1144                 dst.cf_name = talloc_strdup(mem_ctx, src->cf_name);
1145                 if (dst.cf_name == NULL) {
1146                         LDB_FREE(dst.cf_name);
1147                         LDB_FREE(dst.value.data);
1148                         LDB_FREE(dst.name);
1149                         return dst;
1150                 }
1151         } else {
1152                 dst.cf_value.data = NULL;
1153                 dst.cf_name = NULL;
1154         }
1155
1156         return dst;
1157 }
1158
1159 static struct ldb_dn_ext_component ldb_dn_ext_copy_component(
1160                                                 void *mem_ctx,
1161                                                 struct ldb_dn_ext_component *src)
1162 {
1163         struct ldb_dn_ext_component dst;
1164
1165         memset(&dst, 0, sizeof(dst));
1166
1167         if (src == NULL) {
1168                 return dst;
1169         }
1170
1171         dst.value = ldb_val_dup(mem_ctx, &(src->value));
1172         if (dst.value.data == NULL) {
1173                 return dst;
1174         }
1175
1176         dst.name = talloc_strdup(mem_ctx, src->name);
1177         if (dst.name == NULL) {
1178                 LDB_FREE(dst.value.data);
1179                 return dst;
1180         }
1181
1182         return dst;
1183 }
1184
1185 struct ldb_dn *ldb_dn_copy(void *mem_ctx, struct ldb_dn *dn)
1186 {
1187         struct ldb_dn *new_dn;
1188
1189         if (!dn || dn->invalid) {
1190                 return NULL;
1191         }
1192
1193         new_dn = talloc_zero(mem_ctx, struct ldb_dn);
1194         if ( !new_dn) {
1195                 return NULL;
1196         }
1197
1198         *new_dn = *dn;
1199
1200         if (dn->components) {
1201                 int i;
1202
1203                 new_dn->components =
1204                         talloc_zero_array(new_dn,
1205                                           struct ldb_dn_component,
1206                                           dn->comp_num);
1207                 if ( ! new_dn->components) {
1208                         talloc_free(new_dn);
1209                         return NULL;
1210                 }
1211
1212                 for (i = 0; i < dn->comp_num; i++) {
1213                         new_dn->components[i] =
1214                                 ldb_dn_copy_component(new_dn->components,
1215                                                       &dn->components[i]);
1216                         if ( ! new_dn->components[i].value.data) {
1217                                 talloc_free(new_dn);
1218                                 return NULL;
1219                         }
1220                 }
1221         }
1222
1223         if (dn->ext_components) {
1224                 int i;
1225
1226                 new_dn->ext_components =
1227                         talloc_zero_array(new_dn,
1228                                           struct ldb_dn_ext_component,
1229                                           dn->ext_comp_num);
1230                 if ( ! new_dn->ext_components) {
1231                         talloc_free(new_dn);
1232                         return NULL;
1233                 }
1234
1235                 for (i = 0; i < dn->ext_comp_num; i++) {
1236                         new_dn->ext_components[i] =
1237                                  ldb_dn_ext_copy_component(
1238                                                 new_dn->ext_components,
1239                                                 &dn->ext_components[i]);
1240                         if ( ! new_dn->ext_components[i].value.data) {
1241                                 talloc_free(new_dn);
1242                                 return NULL;
1243                         }
1244                 }
1245         }
1246
1247         if (dn->casefold) {
1248                 new_dn->casefold = talloc_strdup(new_dn, dn->casefold);
1249                 if ( ! new_dn->casefold) {
1250                         talloc_free(new_dn);
1251                         return NULL;
1252                 }
1253         }
1254
1255         if (dn->linearized) {
1256                 new_dn->linearized = talloc_strdup(new_dn, dn->linearized);
1257                 if ( ! new_dn->linearized) {
1258                         talloc_free(new_dn);
1259                         return NULL;
1260                 }
1261         }
1262
1263         if (dn->ext_linearized) {
1264                 new_dn->ext_linearized = talloc_strdup(new_dn,
1265                                                         dn->ext_linearized);
1266                 if ( ! new_dn->ext_linearized) {
1267                         talloc_free(new_dn);
1268                         return NULL;
1269                 }
1270         }
1271
1272         return new_dn;
1273 }
1274
1275 /* modify the given dn by adding a base.
1276  *
1277  * return true if successful and false if not
1278  * if false is returned the dn may be marked invalid
1279  */
1280 bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base)
1281 {
1282         const char *s;
1283         char *t;
1284
1285         if ( !base || base->invalid || !dn || dn->invalid) {
1286                 return false;
1287         }
1288
1289         if (dn->components) {
1290                 int i;
1291
1292                 if ( ! ldb_dn_validate(base)) {
1293                         return false;
1294                 }
1295
1296                 s = NULL;
1297                 if (dn->valid_case) {
1298                         if ( ! (s = ldb_dn_get_casefold(base))) {
1299                                 return false;
1300                         }
1301                 }
1302
1303                 dn->components = talloc_realloc(dn,
1304                                                 dn->components,
1305                                                 struct ldb_dn_component,
1306                                                 dn->comp_num + base->comp_num);
1307                 if ( ! dn->components) {
1308                         ldb_dn_mark_invalid(dn);
1309                         return false;
1310                 }
1311
1312                 for (i = 0; i < base->comp_num; dn->comp_num++, i++) {
1313                         dn->components[dn->comp_num] =
1314                                 ldb_dn_copy_component(dn->components,
1315                                                         &base->components[i]);
1316                         if (dn->components[dn->comp_num].value.data == NULL) {
1317                                 ldb_dn_mark_invalid(dn);
1318                                 return false;
1319                         }
1320                 }
1321
1322                 if (dn->casefold && s) {
1323                         if (*dn->casefold) {
1324                                 t = talloc_asprintf(dn, "%s,%s",
1325                                                     dn->casefold, s);
1326                         } else {
1327                                 t = talloc_strdup(dn, s);
1328                         }
1329                         LDB_FREE(dn->casefold);
1330                         dn->casefold = t;
1331                 }
1332         }
1333
1334         if (dn->linearized) {
1335
1336                 s = ldb_dn_get_linearized(base);
1337                 if ( ! s) {
1338                         return false;
1339                 }
1340
1341                 if (*dn->linearized) {
1342                         t = talloc_asprintf(dn, "%s,%s",
1343                                             dn->linearized, s);
1344                 } else {
1345                         t = talloc_strdup(dn, s);
1346                 }
1347                 if ( ! t) {
1348                         ldb_dn_mark_invalid(dn);
1349                         return false;
1350                 }
1351                 LDB_FREE(dn->linearized);
1352                 dn->linearized = t;
1353         }
1354
1355         /* Wipe the ext_linearized DN,
1356          * the GUID and SID are almost certainly no longer valid */
1357         if (dn->ext_linearized) {
1358                 LDB_FREE(dn->ext_linearized);
1359         }
1360
1361         LDB_FREE(dn->ext_components);
1362         dn->ext_comp_num = 0;
1363         return true;
1364 }
1365
1366 /* modify the given dn by adding a base.
1367  *
1368  * return true if successful and false if not
1369  * if false is returned the dn may be marked invalid
1370  */
1371 bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...)
1372 {
1373         struct ldb_dn *base;
1374         char *base_str;
1375         va_list ap;
1376         bool ret;
1377
1378         if ( !dn || dn->invalid) {
1379                 return false;
1380         }
1381
1382         va_start(ap, base_fmt);
1383         base_str = talloc_vasprintf(dn, base_fmt, ap);
1384         va_end(ap);
1385
1386         if (base_str == NULL) {
1387                 return false;
1388         }
1389
1390         base = ldb_dn_new(base_str, dn->ldb, base_str);
1391
1392         ret = ldb_dn_add_base(dn, base);
1393
1394         talloc_free(base_str);
1395
1396         return ret;
1397 }
1398
1399 /* modify the given dn by adding children elements.
1400  *
1401  * return true if successful and false if not
1402  * if false is returned the dn may be marked invalid
1403  */
1404 bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child)
1405 {
1406         const char *s;
1407         char *t;
1408
1409         if ( !child || child->invalid || !dn || dn->invalid) {
1410                 return false;
1411         }
1412
1413         if (dn->components) {
1414                 int n, i, j;
1415
1416                 if ( ! ldb_dn_validate(child)) {
1417                         return false;
1418                 }
1419
1420                 s = NULL;
1421                 if (dn->valid_case) {
1422                         if ( ! (s = ldb_dn_get_casefold(child))) {
1423                                 return false;
1424                         }
1425                 }
1426
1427                 n = dn->comp_num + child->comp_num;
1428
1429                 dn->components = talloc_realloc(dn,
1430                                                 dn->components,
1431                                                 struct ldb_dn_component,
1432                                                 n);
1433                 if ( ! dn->components) {
1434                         ldb_dn_mark_invalid(dn);
1435                         return false;
1436                 }
1437
1438                 for (i = dn->comp_num - 1, j = n - 1; i >= 0; i--, j--) {
1439                         dn->components[j] = dn->components[i];
1440                 }
1441
1442                 for (i = 0; i < child->comp_num; i++) {
1443                         dn->components[i] =
1444                                 ldb_dn_copy_component(dn->components,
1445                                                         &child->components[i]);
1446                         if (dn->components[i].value.data == NULL) {
1447                                 ldb_dn_mark_invalid(dn);
1448                                 return false;
1449                         }
1450                 }
1451
1452                 dn->comp_num = n;
1453
1454                 if (dn->casefold && s) {
1455                         t = talloc_asprintf(dn, "%s,%s", s, dn->casefold);
1456                         LDB_FREE(dn->casefold);
1457                         dn->casefold = t;
1458                 }
1459         }
1460
1461         if (dn->linearized) {
1462
1463                 s = ldb_dn_get_linearized(child);
1464                 if ( ! s) {
1465                         return false;
1466                 }
1467
1468                 t = talloc_asprintf(dn, "%s,%s", s, dn->linearized);
1469                 if ( ! t) {
1470                         ldb_dn_mark_invalid(dn);
1471                         return false;
1472                 }
1473                 LDB_FREE(dn->linearized);
1474                 dn->linearized = t;
1475         }
1476
1477         /* Wipe the ext_linearized DN,
1478          * the GUID and SID are almost certainly no longer valid */
1479         LDB_FREE(dn->ext_linearized);
1480
1481         LDB_FREE(dn->ext_components);
1482         dn->ext_comp_num = 0;
1483
1484         return true;
1485 }
1486
1487 /* modify the given dn by adding children elements.
1488  *
1489  * return true if successful and false if not
1490  * if false is returned the dn may be marked invalid
1491  */
1492 bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...)
1493 {
1494         struct ldb_dn *child;
1495         char *child_str;
1496         va_list ap;
1497         bool ret;
1498
1499         if ( !dn || dn->invalid) {
1500                 return false;
1501         }
1502
1503         va_start(ap, child_fmt);
1504         child_str = talloc_vasprintf(dn, child_fmt, ap);
1505         va_end(ap);
1506
1507         if (child_str == NULL) {
1508                 return false;
1509         }
1510
1511         child = ldb_dn_new(child_str, dn->ldb, child_str);
1512
1513         ret = ldb_dn_add_child(dn, child);
1514
1515         talloc_free(child_str);
1516
1517         return ret;
1518 }
1519
1520 bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num)
1521 {
1522         int i;
1523
1524         if ( ! ldb_dn_validate(dn)) {
1525                 return false;
1526         }
1527
1528         if (dn->comp_num < num) {
1529                 return false;
1530         }
1531
1532         /* free components */
1533         for (i = num; i > 0; i--) {
1534                 LDB_FREE(dn->components[dn->comp_num - i].name);
1535                 LDB_FREE(dn->components[dn->comp_num - i].value.data);
1536                 LDB_FREE(dn->components[dn->comp_num - i].cf_name);
1537                 LDB_FREE(dn->components[dn->comp_num - i].cf_value.data);
1538         }
1539
1540         dn->comp_num -= num;
1541
1542         if (dn->valid_case) {
1543                 for (i = 0; i < dn->comp_num; i++) {
1544                         LDB_FREE(dn->components[i].cf_name);
1545                         LDB_FREE(dn->components[i].cf_value.data);
1546                 }
1547                 dn->valid_case = false;
1548         }
1549
1550         LDB_FREE(dn->casefold);
1551         LDB_FREE(dn->linearized);
1552
1553         /* Wipe the ext_linearized DN,
1554          * the GUID and SID are almost certainly no longer valid */
1555         LDB_FREE(dn->ext_linearized);
1556
1557         LDB_FREE(dn->ext_components);
1558         dn->ext_comp_num = 0;
1559
1560         return true;
1561 }
1562
1563 bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num)
1564 {
1565         int i, j;
1566
1567         if ( ! ldb_dn_validate(dn)) {
1568                 return false;
1569         }
1570
1571         if (dn->comp_num < num) {
1572                 return false;
1573         }
1574
1575         for (i = 0, j = num; j < dn->comp_num; i++, j++) {
1576                 if (i < num) {
1577                         LDB_FREE(dn->components[i].name);
1578                         LDB_FREE(dn->components[i].value.data);
1579                         LDB_FREE(dn->components[i].cf_name);
1580                         LDB_FREE(dn->components[i].cf_value.data);
1581                 }
1582                 dn->components[i] = dn->components[j];
1583         }
1584
1585         dn->comp_num -= num;
1586
1587         if (dn->valid_case) {
1588                 for (i = 0; i < dn->comp_num; i++) {
1589                         LDB_FREE(dn->components[i].cf_name);
1590                         LDB_FREE(dn->components[i].cf_value.data);
1591                 }
1592                 dn->valid_case = false;
1593         }
1594
1595         LDB_FREE(dn->casefold);
1596         LDB_FREE(dn->linearized);
1597
1598         /* Wipe the ext_linearized DN,
1599          * the GUID and SID are almost certainly no longer valid */
1600         LDB_FREE(dn->ext_linearized);
1601
1602         LDB_FREE(dn->ext_components);
1603         dn->ext_comp_num = 0;
1604         return true;
1605 }
1606
1607 struct ldb_dn *ldb_dn_get_parent(void *mem_ctx, struct ldb_dn *dn)
1608 {
1609         struct ldb_dn *new_dn;
1610
1611         new_dn = ldb_dn_copy(mem_ctx, dn);
1612         if ( !new_dn ) {
1613                 return NULL;
1614         }
1615
1616         if ( ! ldb_dn_remove_child_components(new_dn, 1)) {
1617                 talloc_free(new_dn);
1618                 return NULL;
1619         }
1620
1621         /* Wipe the ext_linearized DN,
1622          * the GUID and SID are almost certainly no longer valid */
1623         LDB_FREE(dn->ext_linearized);
1624
1625         LDB_FREE(dn->ext_components);
1626         dn->ext_comp_num = 0;
1627         return new_dn;
1628 }
1629
1630 /* Create a 'canonical name' string from a DN:
1631
1632    ie dc=samba,dc=org -> samba.org/
1633       uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator
1634
1635    There are two formats,
1636    the EX format has the last '/' replaced with a newline (\n).
1637
1638 */
1639 static char *ldb_dn_canonical(void *mem_ctx, struct ldb_dn *dn, int ex_format) {
1640         int i;
1641         TALLOC_CTX *tmpctx;
1642         char *cracked = NULL;
1643         const char *format = (ex_format ? "\n" : "/" );
1644
1645         if ( ! ldb_dn_validate(dn)) {
1646                 return NULL;
1647         }
1648
1649         tmpctx = talloc_new(mem_ctx);
1650
1651         /* Walk backwards down the DN, grabbing 'dc' components at first */
1652         for (i = dn->comp_num - 1 ; i >= 0; i--) {
1653                 if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) {
1654                         break;
1655                 }
1656                 if (cracked) {
1657                         cracked = talloc_asprintf(tmpctx, "%s.%s",
1658                                                   ldb_dn_escape_value(tmpctx,
1659                                                         dn->components[i].value),
1660                                                   cracked);
1661                 } else {
1662                         cracked = ldb_dn_escape_value(tmpctx,
1663                                                         dn->components[i].value);
1664                 }
1665                 if (!cracked) {
1666                         goto done;
1667                 }
1668         }
1669
1670         /* Only domain components?  Finish here */
1671         if (i < 0) {
1672                 cracked = talloc_strdup_append_buffer(cracked, format);
1673                 talloc_steal(mem_ctx, cracked);
1674                 goto done;
1675         }
1676
1677         /* Now walk backwards appending remaining components */
1678         for (; i > 0; i--) {
1679                 cracked = talloc_asprintf_append_buffer(cracked, "/%s",
1680                                                         ldb_dn_escape_value(tmpctx,
1681                                                         dn->components[i].value));
1682                 if (!cracked) {
1683                         goto done;
1684                 }
1685         }
1686
1687         /* Last one, possibly a newline for the 'ex' format */
1688         cracked = talloc_asprintf_append_buffer(cracked, "%s%s", format,
1689                                                 ldb_dn_escape_value(tmpctx,
1690                                                         dn->components[i].value));
1691
1692         talloc_steal(mem_ctx, cracked);
1693 done:
1694         talloc_free(tmpctx);
1695         return cracked;
1696 }
1697
1698 /* Wrapper functions for the above, for the two different string formats */
1699 char *ldb_dn_canonical_string(void *mem_ctx, struct ldb_dn *dn) {
1700         return ldb_dn_canonical(mem_ctx, dn, 0);
1701
1702 }
1703
1704 char *ldb_dn_canonical_ex_string(void *mem_ctx, struct ldb_dn *dn) {
1705         return ldb_dn_canonical(mem_ctx, dn, 1);
1706 }
1707
1708 int ldb_dn_get_comp_num(struct ldb_dn *dn)
1709 {
1710         if ( ! ldb_dn_validate(dn)) {
1711                 return -1;
1712         }
1713         return dn->comp_num;
1714 }
1715
1716 const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num)
1717 {
1718         if ( ! ldb_dn_validate(dn)) {
1719                 return NULL;
1720         }
1721         if (num >= dn->comp_num) return NULL;
1722         return dn->components[num].name;
1723 }
1724
1725 const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn,
1726                                                 unsigned int num)
1727 {
1728         if ( ! ldb_dn_validate(dn)) {
1729                 return NULL;
1730         }
1731         if (num >= dn->comp_num) return NULL;
1732         return &dn->components[num].value;
1733 }
1734
1735 const char *ldb_dn_get_rdn_name(struct ldb_dn *dn)
1736 {
1737         if ( ! ldb_dn_validate(dn)) {
1738                 return NULL;
1739         }
1740         if (dn->comp_num == 0) return NULL;
1741         return dn->components[0].name;
1742 }
1743
1744 const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn)
1745 {
1746         if ( ! ldb_dn_validate(dn)) {
1747                 return NULL;
1748         }
1749         if (dn->comp_num == 0) return NULL;
1750         return &dn->components[0].value;
1751 }
1752
1753 int ldb_dn_set_component(struct ldb_dn *dn, int num,
1754                          const char *name, const struct ldb_val val)
1755 {
1756         char *n;
1757         struct ldb_val v;
1758
1759         if ( ! ldb_dn_validate(dn)) {
1760                 return LDB_ERR_OTHER;
1761         }
1762
1763         if (num >= dn->comp_num) {
1764                 return LDB_ERR_OTHER;
1765         }
1766
1767         n = talloc_strdup(dn, name);
1768         if ( ! n) {
1769                 return LDB_ERR_OTHER;
1770         }
1771
1772         v.length = val.length;
1773         v.data = (uint8_t *)talloc_memdup(dn, val.data, v.length+1);
1774         if ( ! v.data) {
1775                 talloc_free(n);
1776                 return LDB_ERR_OTHER;
1777         }
1778
1779         talloc_free(dn->components[num].name);
1780         talloc_free(dn->components[num].value.data);
1781         dn->components[num].name = n;
1782         dn->components[num].value = v;
1783
1784         if (dn->valid_case) {
1785                 int i;
1786                 for (i = 0; i < dn->comp_num; i++) {
1787                         LDB_FREE(dn->components[i].cf_name);
1788                         LDB_FREE(dn->components[i].cf_value.data);
1789                 }
1790                 dn->valid_case = false;
1791         }
1792         LDB_FREE(dn->casefold);
1793         LDB_FREE(dn->linearized);
1794
1795         /* Wipe the ext_linearized DN,
1796          * the GUID and SID are almost certainly no longer valid */
1797         LDB_FREE(dn->ext_linearized);
1798
1799         dn->ext_comp_num = 0;
1800         LDB_FREE(dn->ext_components);
1801         return LDB_SUCCESS;
1802 }
1803
1804 const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn,
1805                                                     const char *name)
1806 {
1807         int i;
1808         if ( ! ldb_dn_validate(dn)) {
1809                 return NULL;
1810         }
1811         for (i=0; i < dn->ext_comp_num; i++) {
1812                 if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) {
1813                         return &dn->ext_components[i].value;
1814                 }
1815         }
1816         return NULL;
1817 }
1818
1819 int ldb_dn_set_extended_component(struct ldb_dn *dn,
1820                                   const char *name, const struct ldb_val *val)
1821 {
1822         struct ldb_dn_ext_component *p;
1823         int i;
1824
1825         if ( ! ldb_dn_validate(dn)) {
1826                 return LDB_ERR_OTHER;
1827         }
1828
1829         if (!ldb_dn_extended_syntax_by_name(dn->ldb, name)) {
1830                 /* We don't know how to handle this type of thing */
1831                 return LDB_ERR_INVALID_DN_SYNTAX;
1832         }
1833
1834         for (i=0; i < dn->ext_comp_num; i++) {
1835                 if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) {
1836                         if (val) {
1837                                 dn->ext_components[i].value =
1838                                         ldb_val_dup(dn->ext_components, val);
1839
1840                                 dn->ext_components[i].name =
1841                                         talloc_strdup(dn->ext_components, name);
1842                                 if (!dn->ext_components[i].name ||
1843                                     !dn->ext_components[i].value.data) {
1844                                         ldb_dn_mark_invalid(dn);
1845                                         return LDB_ERR_OPERATIONS_ERROR;
1846                                 }
1847
1848                         } else {
1849                                 if (i != (dn->ext_comp_num - 1)) {
1850                                         memmove(&dn->ext_components[i],
1851                                                 &dn->ext_components[i+1],
1852                                                 ((dn->ext_comp_num-1) - i) *
1853                                                   sizeof(*dn->ext_components));
1854                                 }
1855                                 dn->ext_comp_num--;
1856
1857                                 dn->ext_components = talloc_realloc(dn,
1858                                                    dn->ext_components,
1859                                                    struct ldb_dn_ext_component,
1860                                                    dn->ext_comp_num);
1861                                 if (!dn->ext_components) {
1862                                         ldb_dn_mark_invalid(dn);
1863                                         return LDB_ERR_OPERATIONS_ERROR;
1864                                 }
1865                                 return LDB_SUCCESS;
1866                         }
1867                 }
1868         }
1869
1870         p = dn->ext_components
1871                 = talloc_realloc(dn,
1872                                  dn->ext_components,
1873                                  struct ldb_dn_ext_component,
1874                                  dn->ext_comp_num + 1);
1875         if (!dn->ext_components) {
1876                 ldb_dn_mark_invalid(dn);
1877                 return LDB_ERR_OPERATIONS_ERROR;
1878         }
1879
1880         p[dn->ext_comp_num].value = ldb_val_dup(dn->ext_components, val);
1881         p[dn->ext_comp_num].name = talloc_strdup(p, name);
1882
1883         if (!dn->ext_components[i].name || !dn->ext_components[i].value.data) {
1884                 ldb_dn_mark_invalid(dn);
1885                 return LDB_ERR_OPERATIONS_ERROR;
1886         }
1887         dn->ext_components = p;
1888         dn->ext_comp_num++;
1889
1890         return LDB_SUCCESS;
1891 }
1892
1893 void ldb_dn_remove_extended_components(struct ldb_dn *dn)
1894 {
1895         dn->ext_comp_num = 0;
1896         LDB_FREE(dn->ext_components);
1897 }
1898
1899 bool ldb_dn_is_valid(struct ldb_dn *dn)
1900 {
1901         if ( ! dn) return false;
1902         return ! dn->invalid;
1903 }
1904
1905 bool ldb_dn_is_special(struct ldb_dn *dn)
1906 {
1907         if ( ! dn || dn->invalid) return false;
1908         return dn->special;
1909 }
1910
1911 bool ldb_dn_has_extended(struct ldb_dn *dn)
1912 {
1913         if ( ! dn || dn->invalid) return false;
1914         if (dn->ext_linearized && (dn->ext_linearized[0] == '<')) return true;
1915         return dn->ext_comp_num != 0;
1916 }
1917
1918 bool ldb_dn_check_special(struct ldb_dn *dn, const char *check)
1919 {
1920         if ( ! dn || dn->invalid) return false;
1921         return ! strcmp(dn->linearized, check);
1922 }
1923
1924 bool ldb_dn_is_null(struct ldb_dn *dn)
1925 {
1926         if ( ! dn || dn->invalid) return false;
1927         if (ldb_dn_has_extended(dn)) return false;
1928         if (dn->linearized && (dn->linearized[0] == '\0')) return true;
1929         return false;
1930 }
1931