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