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