Line data Source code
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) TALLOC_FREE(x)
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 : const 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 19949 : static void ldb_dn_mark_invalid(struct ldb_dn *dn)
84 : {
85 19949 : dn->invalid = true;
86 19930 : }
87 :
88 : /* strdn may be NULL */
89 917197685 : struct ldb_dn *ldb_dn_from_ldb_val(TALLOC_CTX *mem_ctx,
90 : struct ldb_context *ldb,
91 : const struct ldb_val *strdn)
92 : {
93 25374748 : struct ldb_dn *dn;
94 :
95 917197685 : if (ldb == NULL || strdn == NULL) {
96 0 : return NULL;
97 : }
98 917197685 : if (strdn->data
99 887701708 : && (strnlen((const char*)strdn->data, strdn->length) != strdn->length)) {
100 : /* The RDN must not contain a character with value 0x0 */
101 0 : return NULL;
102 : }
103 :
104 917197682 : dn = talloc_zero(mem_ctx, struct ldb_dn);
105 917197682 : LDB_DN_NULL_FAILED(dn);
106 :
107 917197682 : dn->ldb = talloc_get_type(ldb, struct ldb_context);
108 917197682 : if (dn->ldb == NULL) {
109 : /* the caller probably got the arguments to
110 : ldb_dn_new() mixed up */
111 0 : talloc_free(dn);
112 0 : return NULL;
113 : }
114 :
115 1779235414 : if (strdn->data && strdn->length) {
116 886790506 : const char *data = (const char *)strdn->data;
117 886790506 : size_t length = strdn->length;
118 :
119 886790506 : if (data[0] == '@') {
120 413798608 : dn->special = true;
121 : }
122 886790506 : dn->ext_linearized = talloc_strndup(dn, data, length);
123 886790506 : LDB_DN_NULL_FAILED(dn->ext_linearized);
124 :
125 886790506 : if (data[0] == '<') {
126 42466883 : const char *p_save, *p = dn->ext_linearized;
127 2322040 : do {
128 123006953 : p_save = p;
129 123006953 : p = strstr(p, ">;");
130 123006953 : if (p) {
131 79427619 : p = p + 2;
132 : }
133 123006953 : } while (p);
134 :
135 43579334 : if (p_save == dn->ext_linearized) {
136 8470124 : dn->linearized = talloc_strdup(dn, "");
137 : } else {
138 35109210 : dn->linearized = talloc_strdup(dn, p_save);
139 : }
140 43579334 : LDB_DN_NULL_FAILED(dn->linearized);
141 : } else {
142 843211172 : dn->linearized = dn->ext_linearized;
143 843211172 : dn->ext_linearized = NULL;
144 : }
145 : } else {
146 30407176 : dn->linearized = talloc_strdup(dn, "");
147 30407176 : LDB_DN_NULL_FAILED(dn->linearized);
148 : }
149 :
150 891822937 : return dn;
151 :
152 0 : failed:
153 0 : talloc_free(dn);
154 0 : return NULL;
155 : }
156 :
157 : /* strdn may be NULL */
158 345095843 : struct ldb_dn *ldb_dn_new(TALLOC_CTX *mem_ctx,
159 : struct ldb_context *ldb,
160 : const char *strdn)
161 : {
162 11391814 : struct ldb_val blob;
163 345095843 : blob.data = discard_const_p(uint8_t, strdn);
164 345095843 : blob.length = strdn ? strlen(strdn) : 0;
165 345095843 : return ldb_dn_from_ldb_val(mem_ctx, ldb, &blob);
166 : }
167 :
168 201755502 : struct ldb_dn *ldb_dn_new_fmt(TALLOC_CTX *mem_ctx,
169 : struct ldb_context *ldb,
170 : const char *new_fmt, ...)
171 : {
172 6647543 : char *strdn;
173 6647543 : va_list ap;
174 :
175 201755502 : if (! ldb) return NULL;
176 :
177 201755502 : va_start(ap, new_fmt);
178 201755502 : strdn = talloc_vasprintf(mem_ctx, new_fmt, ap);
179 201755502 : va_end(ap);
180 :
181 201755502 : if (strdn) {
182 201755502 : struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb, strdn);
183 201755502 : talloc_free(strdn);
184 201755502 : return dn;
185 : }
186 :
187 0 : return NULL;
188 : }
189 :
190 : /* see RFC2253 section 2.4 */
191 233569421 : static int ldb_dn_escape_internal(char *dst, const char *src, int len)
192 : {
193 14403401 : char c;
194 14403401 : char *d;
195 14403401 : int i;
196 233569421 : d = dst;
197 :
198 2242387301 : for (i = 0; i < len; i++){
199 2008817880 : c = src[i];
200 2008817880 : switch (c) {
201 15007853 : case ' ':
202 15007853 : if (i == 0 || i == len - 1) {
203 : /* if at the beginning or end
204 : * of the string then escape */
205 0 : *d++ = '\\';
206 0 : *d++ = c;
207 : } else {
208 : /* otherwise don't escape */
209 15007853 : *d++ = c;
210 : }
211 14074605 : break;
212 :
213 37087 : case '#':
214 : /* despite the RFC, windows escapes a #
215 : anywhere in the string */
216 : case ',':
217 : case '+':
218 : case '"':
219 : case '\\':
220 : case '<':
221 : case '>':
222 : case '?':
223 : /* these must be escaped using \c form */
224 37087 : *d++ = '\\';
225 37087 : *d++ = c;
226 37087 : break;
227 :
228 1696423 : case ';':
229 : case '\r':
230 : case '\n':
231 : case '=':
232 : case '\0': {
233 : /* any others get \XX form */
234 927 : unsigned char v;
235 1696423 : const char *hexbytes = "0123456789ABCDEF";
236 1696423 : v = (const unsigned char)c;
237 1696423 : *d++ = '\\';
238 1696423 : *d++ = hexbytes[v>>4];
239 1696423 : *d++ = hexbytes[v&0xF];
240 1696423 : break;
241 : }
242 1992076517 : default:
243 1992076517 : *d++ = c;
244 : }
245 : }
246 :
247 : /* return the length of the resulting string */
248 233569421 : return (d - dst);
249 : }
250 :
251 15561603 : char *ldb_dn_escape_value(TALLOC_CTX *mem_ctx, struct ldb_val value)
252 : {
253 957728 : char *dst;
254 957728 : size_t len;
255 15561603 : if (!value.length)
256 2 : return NULL;
257 :
258 : /* allocate destination string, it will be at most 3 times the source */
259 15561601 : dst = talloc_array(mem_ctx, char, value.length * 3 + 1);
260 15561601 : if ( ! dst) {
261 0 : talloc_free(dst);
262 0 : return NULL;
263 : }
264 :
265 15561601 : len = ldb_dn_escape_internal(dst, (const char *)value.data, value.length);
266 :
267 15561601 : dst = talloc_realloc(mem_ctx, dst, char, len + 1);
268 15561601 : if ( ! dst) {
269 0 : talloc_free(dst);
270 0 : return NULL;
271 : }
272 15561601 : dst[len] = '\0';
273 15561601 : return dst;
274 : }
275 :
276 : /*
277 : explode a DN string into a ldb_dn structure
278 : based on RFC4514 except that we don't support multiple valued RDNs
279 :
280 : TODO: according to MS-ADTS:3.1.1.5.2 Naming Constraints
281 : DN must be compliant with RFC2253
282 : */
283 1231503079 : static bool ldb_dn_explode(struct ldb_dn *dn)
284 : {
285 1231503079 : char *p, *ex_name = NULL, *ex_value = NULL, *data, *d, *dt, *t;
286 1231503079 : bool trim = true;
287 1231503079 : bool in_extended = true;
288 1231503079 : bool in_ex_name = false;
289 1231503079 : bool in_ex_value = false;
290 1231503079 : bool in_attr = false;
291 1231503079 : bool in_value = false;
292 1231503079 : bool in_quote = false;
293 1231503079 : bool is_oid = false;
294 1231503079 : bool escape = false;
295 36347095 : unsigned int x;
296 1231503079 : size_t l = 0;
297 36347095 : int ret;
298 36347095 : char *parse_dn;
299 36347095 : bool is_index;
300 :
301 1231503079 : if (dn == NULL || dn->invalid) {
302 718 : return false;
303 : }
304 :
305 1231502356 : if (dn->components != NULL) {
306 643692392 : return true;
307 : }
308 :
309 565266444 : if (dn->ext_linearized != NULL) {
310 38945203 : parse_dn = dn->ext_linearized;
311 : } else {
312 525452749 : parse_dn = dn->linearized;
313 : }
314 :
315 565266444 : if (parse_dn == NULL) {
316 0 : return false;
317 : }
318 :
319 565266444 : is_index = (strncmp(parse_dn, "DN=@INDEX:", 10) == 0);
320 :
321 : /* Empty DNs */
322 565266444 : if (parse_dn[0] == '\0') {
323 30609776 : return true;
324 : }
325 :
326 : /* Special DNs case */
327 533715318 : if (dn->special) {
328 257373328 : return true;
329 : }
330 :
331 268553135 : LDB_FREE(dn->ext_components);
332 268553135 : dn->ext_comp_num = 0;
333 268553135 : dn->comp_num = 0;
334 :
335 : /* in the common case we have 3 or more components */
336 : /* make sure all components are zeroed, other functions depend on it */
337 268553135 : dn->components = talloc_zero_array(dn, struct ldb_dn_component, 3);
338 268553135 : if (dn->components == NULL) {
339 0 : return false;
340 : }
341 :
342 : /* Components data space is allocated here once */
343 268553135 : data = talloc_array(dn->components, char, strlen(parse_dn) + 1);
344 268553135 : if (data == NULL) {
345 0 : goto failed;
346 : }
347 :
348 263479770 : p = parse_dn;
349 263479770 : t = NULL;
350 263479770 : d = dt = data;
351 :
352 26235790349 : while (*p) {
353 25975708588 : if (in_extended) {
354 :
355 3289285023 : if (!in_ex_name && !in_ex_value) {
356 :
357 339532821 : if (p[0] == '<') {
358 79449826 : p++;
359 79449826 : ex_name = d;
360 79449826 : in_ex_name = true;
361 79449826 : continue;
362 : } else {
363 260082995 : in_extended = false;
364 260082995 : in_attr = true;
365 260082995 : dt = d;
366 :
367 260082995 : continue;
368 : }
369 : }
370 :
371 2949752202 : if (in_ex_name && *p == '=') {
372 79449822 : *d++ = '\0';
373 79449822 : p++;
374 79449822 : ex_value = d;
375 79449822 : in_ex_name = false;
376 79449822 : in_ex_value = true;
377 79449822 : continue;
378 : }
379 :
380 2870302380 : if (in_ex_value && *p == '>') {
381 79449822 : struct ldb_dn_ext_component *ext_comp = NULL;
382 1167105 : const struct ldb_dn_extended_syntax *ext_syntax;
383 79449822 : struct ldb_val ex_val = {
384 : .data = (uint8_t *)ex_value,
385 79449822 : .length = d - ex_value
386 : };
387 :
388 79449822 : *d++ = '\0';
389 79449822 : p++;
390 79449822 : in_ex_value = false;
391 :
392 : /* Process name and ex_value */
393 :
394 79449822 : ext_comp = talloc_realloc(
395 : dn,
396 : dn->ext_components,
397 : struct ldb_dn_ext_component,
398 : dn->ext_comp_num + 1);
399 :
400 79449822 : if (ext_comp == NULL) {
401 : /* ouch ! */
402 450 : goto failed;
403 : }
404 :
405 79449822 : dn->ext_components = ext_comp;
406 :
407 79449822 : ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, ex_name);
408 79449822 : if (ext_syntax == NULL) {
409 : /* We don't know about this type of extended DN */
410 9 : goto failed;
411 : }
412 :
413 79449813 : dn->ext_components[dn->ext_comp_num].name = ext_syntax->name;
414 79449813 : ret = ext_syntax->read_fn(dn->ldb, dn->ext_components,
415 78282717 : &ex_val, &dn->ext_components[dn->ext_comp_num].value);
416 79449813 : if (ret != LDB_SUCCESS) {
417 441 : ldb_dn_mark_invalid(dn);
418 441 : goto failed;
419 : }
420 :
421 79449372 : dn->ext_comp_num++;
422 :
423 79449372 : if (*p == '\0') {
424 : /* We have reached the end (extended component only)! */
425 8469686 : talloc_free(data);
426 8469686 : return true;
427 :
428 70979686 : } else if (*p == ';') {
429 70979686 : p++;
430 70979686 : continue;
431 : } else {
432 0 : ldb_dn_mark_invalid(dn);
433 0 : goto failed;
434 : }
435 : }
436 :
437 2790852558 : *d++ = *p++;
438 2790852558 : continue;
439 : }
440 22686423565 : if (in_attr) {
441 4516389630 : if (trim) {
442 1526869250 : if (*p == ' ') {
443 34066599 : p++;
444 34066599 : continue;
445 : }
446 :
447 : /* first char */
448 1492802651 : trim = false;
449 :
450 1492802651 : if (!isascii(*p)) {
451 : /* attr names must be ascii only */
452 0 : ldb_dn_mark_invalid(dn);
453 0 : goto failed;
454 : }
455 :
456 1492802651 : if (isdigit(*p)) {
457 0 : is_oid = true;
458 : } else
459 1492802651 : if ( ! isalpha(*p)) {
460 : /* not a digit nor an alpha,
461 : * invalid attribute name */
462 7 : ldb_dn_mark_invalid(dn);
463 7 : goto failed;
464 : }
465 :
466 : /* Copy this character across from parse_dn,
467 : * now we have trimmed out spaces */
468 1492802644 : *d++ = *p++;
469 1492802644 : continue;
470 : }
471 :
472 2989520380 : if (*p == ' ') {
473 96 : p++;
474 : /* valid only if we are at the end */
475 96 : trim = true;
476 96 : continue;
477 : }
478 :
479 2989520284 : if (*p == '=') {
480 : /* attribute terminated */
481 1492783052 : in_attr = false;
482 1492783052 : in_value = true;
483 1492783052 : trim = true;
484 1492783052 : l = 0;
485 :
486 : /* Terminate this string in d
487 : * (which is a copy of parse_dn
488 : * with spaces trimmed) */
489 1492783052 : *d++ = '\0';
490 1492783052 : dn->components[dn->comp_num].name = talloc_strdup(dn->components, dt);
491 1492783052 : if (dn->components[dn->comp_num].name == NULL) {
492 : /* ouch */
493 0 : goto failed;
494 : }
495 :
496 1492783052 : dt = d;
497 :
498 1492783052 : p++;
499 1492783052 : continue;
500 : }
501 :
502 1496737232 : if (!isascii(*p)) {
503 : /* attr names must be ascii only */
504 0 : ldb_dn_mark_invalid(dn);
505 0 : goto failed;
506 : }
507 :
508 1496737232 : if (is_oid && ( ! (isdigit(*p) || (*p == '.')))) {
509 : /* not a digit nor a dot,
510 : * invalid attribute oid */
511 0 : ldb_dn_mark_invalid(dn);
512 0 : goto failed;
513 : } else
514 1496737232 : if ( ! (isalpha(*p) || isdigit(*p) || (*p == '-'))) {
515 : /* not ALPHA, DIGIT or HYPHEN */
516 1231 : ldb_dn_mark_invalid(dn);
517 1231 : goto failed;
518 : }
519 :
520 1496736001 : *d++ = *p++;
521 1496736001 : continue;
522 : }
523 :
524 18170033935 : if (in_value) {
525 18170033935 : if (in_quote) {
526 0 : if (*p == '\"') {
527 0 : if (p[-1] != '\\') {
528 0 : p++;
529 0 : in_quote = false;
530 0 : continue;
531 : }
532 : }
533 0 : *d++ = *p++;
534 0 : l++;
535 0 : continue;
536 : }
537 :
538 18170033935 : if (trim) {
539 1492783075 : if (*p == ' ') {
540 31 : p++;
541 31 : continue;
542 : }
543 :
544 : /* first char */
545 1492783044 : trim = false;
546 :
547 1492783044 : if (*p == '\"') {
548 0 : in_quote = true;
549 0 : p++;
550 0 : continue;
551 : }
552 : }
553 :
554 18170033904 : switch (*p) {
555 :
556 : /* TODO: support ber encoded values
557 : case '#':
558 : */
559 :
560 1232746415 : case ',':
561 1232746415 : if (escape) {
562 26850 : *d++ = *p++;
563 26850 : l++;
564 26850 : escape = false;
565 26850 : continue;
566 : }
567 : /* ok found value terminator */
568 :
569 1232719565 : if (t != NULL) {
570 : /* trim back */
571 22 : d -= (p - t);
572 22 : l -= (p - t);
573 22 : t = NULL;
574 : }
575 :
576 1232719565 : in_attr = true;
577 1232719565 : in_value = false;
578 1232719565 : trim = true;
579 :
580 1232719565 : p++;
581 1232719565 : *d++ = '\0';
582 :
583 : /*
584 : * This talloc_memdup() is OK with the
585 : * +1 because *d has been set to '\0'
586 : * just above
587 : */
588 2465439130 : dn->components[dn->comp_num].value.data = \
589 1232719565 : (uint8_t *)talloc_memdup(dn->components, dt, l + 1);
590 1232719565 : dn->components[dn->comp_num].value.length = l;
591 1232719565 : if (dn->components[dn->comp_num].value.data == NULL) {
592 : /* ouch ! */
593 0 : goto failed;
594 : }
595 1232719565 : talloc_set_name_const(dn->components[dn->comp_num].value.data,
596 1208454113 : (const char *)dn->components[dn->comp_num].value.data);
597 :
598 1232719565 : dt = d;
599 :
600 1232719565 : dn->comp_num++;
601 1232719565 : if (dn->comp_num > 2) {
602 721309813 : dn->components = talloc_realloc(dn,
603 : dn->components,
604 : struct ldb_dn_component,
605 : dn->comp_num + 1);
606 721309813 : if (dn->components == NULL) {
607 : /* ouch ! */
608 0 : goto failed;
609 : }
610 : /* make sure all components are zeroed, other functions depend on this */
611 721309813 : memset(&dn->components[dn->comp_num], '\0', sizeof(struct ldb_dn_component));
612 : }
613 :
614 1232719565 : continue;
615 :
616 0 : case '+':
617 : case '=':
618 : /* to main compatibility with earlier
619 : versions of ldb indexing, we have to
620 : accept the base64 encoded binary index
621 : values, which contain a '+' or '='
622 : which should normally be escaped */
623 0 : if (is_index) {
624 0 : if (t != NULL) {
625 0 : t = NULL;
626 : }
627 0 : *d++ = *p++;
628 0 : l++;
629 0 : break;
630 : }
631 :
632 0 : FALL_THROUGH;
633 : case '\"':
634 : case '<':
635 : case '>':
636 : case ';':
637 : /* a string with not escaped specials is invalid (tested) */
638 0 : if (!escape) {
639 0 : ldb_dn_mark_invalid(dn);
640 0 : goto failed;
641 : }
642 0 : escape = false;
643 :
644 0 : *d++ = *p++;
645 0 : l++;
646 :
647 0 : if (t != NULL) {
648 0 : t = NULL;
649 : }
650 0 : break;
651 :
652 85599004 : case '\\':
653 85599004 : if (!escape) {
654 85588204 : escape = true;
655 85588204 : p++;
656 85588204 : continue;
657 : }
658 10800 : escape = false;
659 :
660 10800 : *d++ = *p++;
661 10800 : l++;
662 :
663 10800 : if (t != NULL) {
664 0 : t = NULL;
665 : }
666 10800 : break;
667 :
668 16851688485 : default:
669 16851688485 : if (escape) {
670 85550554 : if (isxdigit(p[0]) && isxdigit(p[1])) {
671 85550554 : if (sscanf(p, "%02x", &x) != 1) {
672 : /* invalid escaping sequence */
673 0 : ldb_dn_mark_invalid(dn);
674 0 : goto failed;
675 : }
676 85550554 : p += 2;
677 85550554 : *d++ = (unsigned char)x;
678 : } else {
679 0 : *d++ = *p++;
680 : }
681 :
682 85550554 : escape = false;
683 85550554 : l++;
684 85550554 : if (t != NULL) {
685 0 : t = NULL;
686 : }
687 85549646 : break;
688 : }
689 :
690 16766137931 : if (*p == ' ') {
691 124629360 : if (t == NULL) {
692 124625289 : t = p;
693 : }
694 : } else {
695 16385527390 : if (t != NULL) {
696 123511713 : t = NULL;
697 : }
698 : }
699 :
700 16766137931 : *d++ = *p++;
701 16766137931 : l++;
702 :
703 16766137931 : break;
704 : }
705 :
706 : }
707 : }
708 :
709 260081761 : if (in_attr || in_quote) {
710 : /* invalid dn */
711 18270 : ldb_dn_mark_invalid(dn);
712 18270 : goto failed;
713 : }
714 :
715 260063491 : if (in_value) {
716 : /* save last element */
717 260063487 : if (t != NULL) {
718 : /* trim back */
719 190 : d -= (p - t);
720 190 : l -= (p - t);
721 : }
722 :
723 260063487 : *d++ = '\0';
724 : /*
725 : * This talloc_memdup() is OK with the
726 : * +1 because *d has been set to '\0'
727 : * just above.
728 : */
729 260063487 : dn->components[dn->comp_num].value.length = l;
730 520126974 : dn->components[dn->comp_num].value.data =
731 260063487 : (uint8_t *)talloc_memdup(dn->components, dt, l + 1);
732 260063487 : if (dn->components[dn->comp_num].value.data == NULL) {
733 : /* ouch */
734 0 : goto failed;
735 : }
736 260063487 : talloc_set_name_const(dn->components[dn->comp_num].value.data,
737 255219278 : (const char *)dn->components[dn->comp_num].value.data);
738 :
739 260063487 : dn->comp_num++;
740 : }
741 260063491 : talloc_free(data);
742 260063491 : return true;
743 :
744 19958 : failed:
745 19958 : LDB_FREE(dn->components); /* "data" is implicitly free'd */
746 19958 : dn->comp_num = 0;
747 19958 : LDB_FREE(dn->ext_components);
748 19958 : dn->ext_comp_num = 0;
749 :
750 19958 : return false;
751 : }
752 :
753 1133856710 : bool ldb_dn_validate(struct ldb_dn *dn)
754 : {
755 1133856710 : return ldb_dn_explode(dn);
756 : }
757 :
758 763279143 : const char *ldb_dn_get_linearized(struct ldb_dn *dn)
759 : {
760 25217101 : unsigned int i;
761 25217101 : size_t len;
762 25217101 : char *d, *n;
763 :
764 763279143 : if ( ! dn || ( dn->invalid)) return NULL;
765 :
766 763278802 : if (dn->linearized) return dn->linearized;
767 :
768 10792089 : if ( ! dn->components) {
769 0 : ldb_dn_mark_invalid(dn);
770 0 : return NULL;
771 : }
772 :
773 10792089 : if (dn->comp_num == 0) {
774 531265 : dn->linearized = talloc_strdup(dn, "");
775 531265 : if ( ! dn->linearized) return NULL;
776 531265 : return dn->linearized;
777 : }
778 :
779 : /* calculate maximum possible length of DN */
780 66907259 : for (len = 0, i = 0; i < dn->comp_num; i++) {
781 : /* name len */
782 56646435 : len += strlen(dn->components[i].name);
783 : /* max escaped data len */
784 56646435 : len += (dn->components[i].value.length * 3);
785 56646435 : len += 2; /* '=' and ',' */
786 : }
787 10260824 : dn->linearized = talloc_array(dn, char, len);
788 10260824 : if ( ! dn->linearized) return NULL;
789 :
790 9633525 : d = dn->linearized;
791 :
792 66907259 : for (i = 0; i < dn->comp_num; i++) {
793 :
794 : /* copy the name */
795 56646435 : n = dn->components[i].name;
796 169939890 : while (*n) *d++ = *n++;
797 :
798 56646435 : *d++ = '=';
799 :
800 : /* and the value */
801 113292870 : d += ldb_dn_escape_internal( d,
802 56646435 : (char *)dn->components[i].value.data,
803 56646435 : dn->components[i].value.length);
804 56646435 : *d++ = ',';
805 : }
806 :
807 10260824 : *(--d) = '\0';
808 :
809 : /* don't waste more memory than necessary */
810 10260824 : dn->linearized = talloc_realloc(dn, dn->linearized,
811 : char, (d - dn->linearized + 1));
812 :
813 10260824 : return dn->linearized;
814 : }
815 :
816 49785541 : static int ldb_dn_extended_component_compare(const void *p1, const void *p2)
817 : {
818 49785541 : const struct ldb_dn_ext_component *ec1 = (const struct ldb_dn_ext_component *)p1;
819 49785541 : const struct ldb_dn_ext_component *ec2 = (const struct ldb_dn_ext_component *)p2;
820 49785541 : return strcmp(ec1->name, ec2->name);
821 : }
822 :
823 27967023 : char *ldb_dn_get_extended_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int mode)
824 : {
825 27967023 : const char *linearized = ldb_dn_get_linearized(dn);
826 27967023 : char *p = NULL;
827 620780 : unsigned int i;
828 :
829 27967023 : if (!linearized) {
830 96 : return NULL;
831 : }
832 :
833 27966927 : if (!ldb_dn_has_extended(dn)) {
834 1564152 : return talloc_strdup(mem_ctx, linearized);
835 : }
836 :
837 26402775 : if (!ldb_dn_validate(dn)) {
838 0 : return NULL;
839 : }
840 :
841 : /* sort the extended components by name. The idea is to make
842 : * the resulting DNs consistent, plus to ensure that we put
843 : * 'DELETED' first, so it can be very quickly recognised
844 : */
845 26402772 : TYPESAFE_QSORT(dn->ext_components, dn->ext_comp_num,
846 : ldb_dn_extended_component_compare);
847 :
848 77911549 : for (i = 0; i < dn->ext_comp_num; i++) {
849 626980 : const struct ldb_dn_extended_syntax *ext_syntax;
850 51508777 : const char *name = dn->ext_components[i].name;
851 51508777 : struct ldb_val ec_val = dn->ext_components[i].value;
852 626980 : struct ldb_val val;
853 626980 : int ret;
854 :
855 51508777 : ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name);
856 51508777 : if (!ext_syntax) {
857 0 : return NULL;
858 : }
859 :
860 51508777 : if (mode == 1) {
861 41250597 : ret = ext_syntax->write_clear_fn(dn->ldb, mem_ctx,
862 : &ec_val, &val);
863 10258180 : } else if (mode == 0) {
864 10258180 : ret = ext_syntax->write_hex_fn(dn->ldb, mem_ctx,
865 : &ec_val, &val);
866 : } else {
867 0 : ret = -1;
868 : }
869 :
870 51508777 : if (ret != LDB_SUCCESS) {
871 0 : return NULL;
872 : }
873 :
874 51508777 : if (i == 0) {
875 26402768 : p = talloc_asprintf(mem_ctx, "<%s=%.*s>",
876 : name,
877 26402768 : (int)val.length,
878 : val.data);
879 : } else {
880 25106009 : talloc_asprintf_addbuf(&p, ";<%s=%.*s>",
881 : name,
882 25106009 : (int)val.length,
883 : val.data);
884 : }
885 :
886 51508777 : talloc_free(val.data);
887 : }
888 :
889 26402772 : if (dn->ext_comp_num && *linearized) {
890 25158944 : talloc_asprintf_addbuf(&p, ";%s", linearized);
891 : }
892 :
893 26402772 : if (!p) {
894 4 : return NULL;
895 : }
896 :
897 25891587 : return p;
898 : }
899 :
900 : /*
901 : filter out all but an acceptable list of extended DN components
902 : */
903 16753293 : void ldb_dn_extended_filter(struct ldb_dn *dn, const char * const *accept_list)
904 : {
905 203108 : unsigned int i;
906 58714134 : for (i=0; i<dn->ext_comp_num; i++) {
907 41960841 : if (!ldb_attr_in_list(accept_list, dn->ext_components[i].name)) {
908 19186677 : ARRAY_DEL_ELEMENT(
909 3206 : dn->ext_components, i, dn->ext_comp_num);
910 19186677 : dn->ext_comp_num--;
911 19186677 : i--;
912 : }
913 : }
914 16753293 : LDB_FREE(dn->ext_linearized);
915 16753293 : }
916 :
917 :
918 172561890 : char *ldb_dn_alloc_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
919 : {
920 172561890 : return talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn));
921 : }
922 :
923 : /*
924 : casefold a dn. We need to casefold the attribute names, and canonicalize
925 : attribute values of case insensitive attributes.
926 : */
927 :
928 278618952 : static bool ldb_dn_casefold_internal(struct ldb_dn *dn)
929 : {
930 4305448 : unsigned int i;
931 4305448 : int ret;
932 :
933 278618952 : if ( ! dn || dn->invalid) return false;
934 :
935 278618952 : if (dn->valid_case) return true;
936 :
937 139466087 : if (( ! dn->components) && ( ! ldb_dn_explode(dn))) {
938 736 : return false;
939 : }
940 :
941 883327282 : for (i = 0; i < dn->comp_num; i++) {
942 12272058 : const struct ldb_schema_attribute *a;
943 :
944 1487723862 : dn->components[i].cf_name =
945 743861931 : ldb_attr_casefold(dn->components,
946 743861931 : dn->components[i].name);
947 743861931 : if (!dn->components[i].cf_name) {
948 0 : goto failed;
949 : }
950 :
951 743861931 : a = ldb_schema_attribute_by_name(dn->ldb,
952 731589873 : dn->components[i].cf_name);
953 :
954 756133989 : ret = a->syntax->canonicalise_fn(dn->ldb, dn->components,
955 743861931 : &(dn->components[i].value),
956 743861931 : &(dn->components[i].cf_value));
957 743861931 : if (ret != 0) {
958 0 : goto failed;
959 : }
960 : }
961 :
962 139465351 : dn->valid_case = true;
963 :
964 139465351 : return true;
965 :
966 0 : failed:
967 0 : for (i = 0; i < dn->comp_num; i++) {
968 0 : LDB_FREE(dn->components[i].cf_name);
969 0 : LDB_FREE(dn->components[i].cf_value.data);
970 : }
971 0 : return false;
972 : }
973 :
974 502543102 : const char *ldb_dn_get_casefold(struct ldb_dn *dn)
975 : {
976 16112516 : unsigned int i;
977 16112516 : size_t len;
978 16112516 : char *d, *n;
979 :
980 502543102 : if (dn->casefold) return dn->casefold;
981 :
982 314292807 : if (dn->special) {
983 281837039 : dn->casefold = talloc_strdup(dn, dn->linearized);
984 281837039 : if (!dn->casefold) return NULL;
985 281837039 : dn->valid_case = true;
986 281837039 : return dn->casefold;
987 : }
988 :
989 32455768 : if ( ! ldb_dn_casefold_internal(dn)) {
990 0 : return NULL;
991 : }
992 :
993 32455768 : if (dn->comp_num == 0) {
994 1358 : dn->casefold = talloc_strdup(dn, "");
995 1358 : return dn->casefold;
996 : }
997 :
998 : /* calculate maximum possible length of DN */
999 193815795 : for (len = 0, i = 0; i < dn->comp_num; i++) {
1000 : /* name len */
1001 161361385 : len += strlen(dn->components[i].cf_name);
1002 : /* max escaped data len */
1003 161361385 : len += (dn->components[i].cf_value.length * 3);
1004 161361385 : len += 2; /* '=' and ',' */
1005 : }
1006 32454410 : dn->casefold = talloc_array(dn, char, len);
1007 32454410 : if ( ! dn->casefold) return NULL;
1008 :
1009 30452512 : d = dn->casefold;
1010 :
1011 193815795 : for (i = 0; i < dn->comp_num; i++) {
1012 :
1013 : /* copy the name */
1014 161361385 : n = dn->components[i].cf_name;
1015 485615356 : while (*n) *d++ = *n++;
1016 :
1017 161361385 : *d++ = '=';
1018 :
1019 : /* and the value */
1020 322722770 : d += ldb_dn_escape_internal( d,
1021 161361385 : (char *)dn->components[i].cf_value.data,
1022 161361385 : dn->components[i].cf_value.length);
1023 161361385 : *d++ = ',';
1024 : }
1025 32454410 : *(--d) = '\0';
1026 :
1027 : /* don't waste more memory than necessary */
1028 32454410 : dn->casefold = talloc_realloc(dn, dn->casefold,
1029 : char, strlen(dn->casefold) + 1);
1030 :
1031 32454410 : return dn->casefold;
1032 : }
1033 :
1034 2464710 : char *ldb_dn_alloc_casefold(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
1035 : {
1036 2464710 : return talloc_strdup(mem_ctx, ldb_dn_get_casefold(dn));
1037 : }
1038 :
1039 : /* Determine if dn is below base, in the ldap tree. Used for
1040 : * evaluating a subtree search.
1041 : * 0 if they match, otherwise non-zero
1042 : */
1043 :
1044 574858814 : int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn)
1045 : {
1046 12305505 : int ret;
1047 12305505 : unsigned int n_base, n_dn;
1048 :
1049 574858814 : if ( ! base || base->invalid) return 1;
1050 574858814 : if ( ! dn || dn->invalid) return -1;
1051 :
1052 574858814 : if (( ! base->valid_case) || ( ! dn->valid_case)) {
1053 396712909 : if (base->linearized && dn->linearized && dn->special == base->special) {
1054 : /* try with a normal compare first, if we are lucky
1055 : * we will avoid exploding and casefolding */
1056 6468510 : int dif;
1057 389051555 : dif = strlen(dn->linearized) - strlen(base->linearized);
1058 389051555 : if (dif < 0) {
1059 126894824 : return dif;
1060 : }
1061 259782343 : if (strcmp(base->linearized,
1062 259782343 : &dn->linearized[dif]) == 0) {
1063 149706211 : return 0;
1064 : }
1065 : }
1066 :
1067 114028056 : if ( ! ldb_dn_casefold_internal(base)) {
1068 0 : return 1;
1069 : }
1070 :
1071 114028056 : if ( ! ldb_dn_casefold_internal(dn)) {
1072 0 : return -1;
1073 : }
1074 :
1075 : }
1076 :
1077 : /* if base has more components,
1078 : * they don't have the same base */
1079 292173961 : if (base->comp_num > dn->comp_num) {
1080 54961221 : return (dn->comp_num - base->comp_num);
1081 : }
1082 :
1083 237212740 : if ((dn->comp_num == 0) || (base->comp_num == 0)) {
1084 1 : if (dn->special && base->special) {
1085 0 : return strcmp(base->linearized, dn->linearized);
1086 1 : } else if (dn->special) {
1087 0 : return -1;
1088 1 : } else if (base->special) {
1089 0 : return 1;
1090 : } else {
1091 0 : return 0;
1092 : }
1093 : }
1094 :
1095 237212739 : n_base = base->comp_num - 1;
1096 237212739 : n_dn = dn->comp_num - 1;
1097 :
1098 1114703527 : while (n_base != (unsigned int) -1) {
1099 1018896690 : char *b_name = base->components[n_base].cf_name;
1100 1018896690 : char *dn_name = dn->components[n_dn].cf_name;
1101 :
1102 1018896690 : char *b_vdata = (char *)base->components[n_base].cf_value.data;
1103 1018896690 : char *dn_vdata = (char *)dn->components[n_dn].cf_value.data;
1104 :
1105 1018896690 : size_t b_vlen = base->components[n_base].cf_value.length;
1106 1018896690 : size_t dn_vlen = dn->components[n_dn].cf_value.length;
1107 :
1108 : /* compare attr names */
1109 1018896690 : ret = strcmp(b_name, dn_name);
1110 1018896690 : if (ret != 0) return ret;
1111 :
1112 : /* compare attr.cf_value. */
1113 926792923 : if (b_vlen != dn_vlen) {
1114 47633760 : return NUMERIC_CMP(b_vlen, dn_vlen);
1115 : }
1116 879159163 : ret = strncmp(b_vdata, dn_vdata, b_vlen);
1117 879159163 : if (ret != 0) return ret;
1118 :
1119 877490788 : n_base--;
1120 877490788 : n_dn--;
1121 : }
1122 :
1123 92250482 : return 0;
1124 : }
1125 :
1126 : /* compare DNs using casefolding compare functions.
1127 :
1128 : If they match, then return 0
1129 : */
1130 :
1131 68284613 : int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1)
1132 : {
1133 4487022 : unsigned int i;
1134 4487022 : int ret;
1135 :
1136 68284613 : if (( ! dn0) || dn0->invalid || ! dn1 || dn1->invalid) {
1137 2 : return -1;
1138 : }
1139 :
1140 68284611 : if (( ! dn0->valid_case) || ( ! dn1->valid_case)) {
1141 10509160 : if (dn0->linearized && dn1->linearized) {
1142 : /* try with a normal compare first, if we are lucky
1143 : * we will avoid exploding and casefolding */
1144 8376849 : if (strcmp(dn0->linearized, dn1->linearized) == 0) {
1145 1441644 : return 0;
1146 : }
1147 : }
1148 :
1149 9053536 : if ( ! ldb_dn_casefold_internal(dn0)) {
1150 0 : return 1;
1151 : }
1152 :
1153 9053536 : if ( ! ldb_dn_casefold_internal(dn1)) {
1154 736 : return -1;
1155 : }
1156 :
1157 : }
1158 :
1159 : /*
1160 : * Notice that for comp_num, Samba reverses the usual order of
1161 : * comparison. A DN with fewer components is greater than one
1162 : * with more.
1163 : */
1164 66828251 : if (dn0->comp_num > dn1->comp_num) {
1165 18258607 : return -1;
1166 46110182 : } else if (dn0->comp_num < dn1->comp_num) {
1167 19671347 : return 1;
1168 : }
1169 :
1170 25474574 : if (dn0->comp_num == 0) {
1171 1106191 : if (dn0->special && dn1->special) {
1172 1106191 : return strcmp(dn0->linearized, dn1->linearized);
1173 0 : } else if (dn0->special) {
1174 0 : return 1;
1175 0 : } else if (dn1->special) {
1176 0 : return -1;
1177 : } else {
1178 0 : return 0;
1179 : }
1180 : }
1181 :
1182 71780023 : for (i = 0; i < dn0->comp_num; i++) {
1183 61524302 : char *dn0_name = dn0->components[i].cf_name;
1184 61524302 : char *dn1_name = dn1->components[i].cf_name;
1185 :
1186 61524302 : char *dn0_vdata = (char *)dn0->components[i].cf_value.data;
1187 61524302 : char *dn1_vdata = (char *)dn1->components[i].cf_value.data;
1188 :
1189 61524302 : size_t dn0_vlen = dn0->components[i].cf_value.length;
1190 61524302 : size_t dn1_vlen = dn1->components[i].cf_value.length;
1191 :
1192 : /* compare attr names */
1193 61524302 : ret = strcmp(dn0_name, dn1_name);
1194 61524302 : if (ret != 0) {
1195 3414088 : return ret;
1196 : }
1197 :
1198 : /* compare attr.cf_value. */
1199 58110214 : if (dn0_vlen != dn1_vlen) {
1200 6021879 : return NUMERIC_CMP(dn0_vlen, dn1_vlen);
1201 : }
1202 52088335 : ret = strncmp(dn0_vdata, dn1_vdata, dn0_vlen);
1203 52088335 : if (ret != 0) {
1204 4676695 : return ret;
1205 : }
1206 : }
1207 :
1208 9717677 : return 0;
1209 : }
1210 :
1211 412982283 : static struct ldb_dn_component ldb_dn_copy_component(
1212 : TALLOC_CTX *mem_ctx,
1213 : struct ldb_dn_component *src)
1214 : {
1215 20865033 : struct ldb_dn_component dst;
1216 :
1217 412982283 : memset(&dst, 0, sizeof(dst));
1218 :
1219 412982283 : if (src == NULL) {
1220 0 : return dst;
1221 : }
1222 :
1223 412982283 : dst.value = ldb_val_dup(mem_ctx, &(src->value));
1224 412982283 : if (dst.value.data == NULL) {
1225 0 : return dst;
1226 : }
1227 :
1228 412982283 : dst.name = talloc_strdup(mem_ctx, src->name);
1229 412982283 : if (dst.name == NULL) {
1230 0 : LDB_FREE(dst.value.data);
1231 0 : return dst;
1232 : }
1233 :
1234 412982283 : if (src->cf_value.data) {
1235 342827467 : dst.cf_value = ldb_val_dup(mem_ctx, &(src->cf_value));
1236 342827467 : if (dst.cf_value.data == NULL) {
1237 0 : LDB_FREE(dst.value.data);
1238 0 : LDB_FREE(dst.name);
1239 0 : return dst;
1240 : }
1241 :
1242 342827467 : dst.cf_name = talloc_strdup(mem_ctx, src->cf_name);
1243 342827467 : if (dst.cf_name == NULL) {
1244 0 : LDB_FREE(dst.cf_name);
1245 0 : LDB_FREE(dst.value.data);
1246 0 : LDB_FREE(dst.name);
1247 0 : return dst;
1248 : }
1249 : } else {
1250 67062705 : dst.cf_value.data = NULL;
1251 67062705 : dst.cf_name = NULL;
1252 : }
1253 :
1254 412982283 : return dst;
1255 : }
1256 :
1257 32052661 : static struct ldb_dn_ext_component ldb_dn_ext_copy_component(
1258 : TALLOC_CTX *mem_ctx,
1259 : struct ldb_dn_ext_component *src)
1260 : {
1261 932129 : struct ldb_dn_ext_component dst;
1262 :
1263 32052661 : memset(&dst, 0, sizeof(dst));
1264 :
1265 32052661 : if (src == NULL) {
1266 0 : return dst;
1267 : }
1268 :
1269 32052661 : dst.value = ldb_val_dup(mem_ctx, &(src->value));
1270 32052661 : if (dst.value.data == NULL) {
1271 0 : return dst;
1272 : }
1273 :
1274 32052661 : dst.name = talloc_strdup(mem_ctx, src->name);
1275 32052661 : if (dst.name == NULL) {
1276 0 : LDB_FREE(dst.value.data);
1277 0 : return dst;
1278 : }
1279 :
1280 32052661 : return dst;
1281 : }
1282 :
1283 78886804 : struct ldb_dn *ldb_dn_copy(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
1284 : {
1285 3818534 : struct ldb_dn *new_dn;
1286 :
1287 78886804 : if (!dn || dn->invalid) {
1288 2 : return NULL;
1289 : }
1290 :
1291 78886802 : new_dn = talloc_zero(mem_ctx, struct ldb_dn);
1292 78886802 : if ( !new_dn) {
1293 0 : return NULL;
1294 : }
1295 :
1296 78886802 : *new_dn = *dn;
1297 :
1298 78886802 : if (dn->components) {
1299 3593982 : unsigned int i;
1300 :
1301 73845603 : new_dn->components =
1302 70251621 : talloc_zero_array(new_dn,
1303 : struct ldb_dn_component,
1304 : dn->comp_num);
1305 70251621 : if ( ! new_dn->components) {
1306 0 : talloc_free(new_dn);
1307 0 : return NULL;
1308 : }
1309 :
1310 467532486 : for (i = 0; i < dn->comp_num; i++) {
1311 397280865 : new_dn->components[i] =
1312 397280865 : ldb_dn_copy_component(new_dn->components,
1313 397280865 : &dn->components[i]);
1314 397280865 : if ( ! new_dn->components[i].value.data) {
1315 0 : talloc_free(new_dn);
1316 0 : return NULL;
1317 : }
1318 : }
1319 : }
1320 :
1321 78886802 : if (dn->ext_components) {
1322 801495 : unsigned int i;
1323 :
1324 25856022 : new_dn->ext_components =
1325 25054527 : talloc_zero_array(new_dn,
1326 : struct ldb_dn_ext_component,
1327 : dn->ext_comp_num);
1328 25054527 : if ( ! new_dn->ext_components) {
1329 0 : talloc_free(new_dn);
1330 0 : return NULL;
1331 : }
1332 :
1333 57107188 : for (i = 0; i < dn->ext_comp_num; i++) {
1334 32052661 : new_dn->ext_components[i] =
1335 32052661 : ldb_dn_ext_copy_component(
1336 32052661 : new_dn->ext_components,
1337 32052661 : &dn->ext_components[i]);
1338 32052661 : if ( ! new_dn->ext_components[i].value.data) {
1339 0 : talloc_free(new_dn);
1340 0 : return NULL;
1341 : }
1342 : }
1343 : }
1344 :
1345 78886802 : if (dn->casefold) {
1346 44933998 : new_dn->casefold = talloc_strdup(new_dn, dn->casefold);
1347 44933998 : if ( ! new_dn->casefold) {
1348 0 : talloc_free(new_dn);
1349 0 : return NULL;
1350 : }
1351 : }
1352 :
1353 78886802 : if (dn->linearized) {
1354 78741641 : new_dn->linearized = talloc_strdup(new_dn, dn->linearized);
1355 78741641 : if ( ! new_dn->linearized) {
1356 0 : talloc_free(new_dn);
1357 0 : return NULL;
1358 : }
1359 : }
1360 :
1361 78886802 : if (dn->ext_linearized) {
1362 2869544 : new_dn->ext_linearized = talloc_strdup(new_dn,
1363 1386343 : dn->ext_linearized);
1364 1483201 : if ( ! new_dn->ext_linearized) {
1365 0 : talloc_free(new_dn);
1366 0 : return NULL;
1367 : }
1368 : }
1369 :
1370 75068268 : return new_dn;
1371 : }
1372 :
1373 : /* modify the given dn by adding a base.
1374 : *
1375 : * return true if successful and false if not
1376 : * if false is returned the dn may be marked invalid
1377 : */
1378 626502 : bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base)
1379 : {
1380 4928 : const char *s;
1381 4928 : char *t;
1382 :
1383 626502 : if ( !base || base->invalid || !dn || dn->invalid) {
1384 0 : return false;
1385 : }
1386 :
1387 626502 : if (dn == base) {
1388 0 : return false; /* or we will visit infinity */
1389 : }
1390 :
1391 626502 : if (dn->components) {
1392 479 : unsigned int i;
1393 :
1394 452499 : if ( ! ldb_dn_validate(base)) {
1395 0 : return false;
1396 : }
1397 :
1398 452499 : s = NULL;
1399 452499 : if (dn->valid_case) {
1400 2 : if ( ! (s = ldb_dn_get_casefold(base))) {
1401 0 : return false;
1402 : }
1403 : }
1404 :
1405 452499 : dn->components = talloc_realloc(dn,
1406 : dn->components,
1407 : struct ldb_dn_component,
1408 : dn->comp_num + base->comp_num);
1409 452499 : if ( ! dn->components) {
1410 0 : ldb_dn_mark_invalid(dn);
1411 0 : return false;
1412 : }
1413 :
1414 2984063 : for (i = 0; i < base->comp_num; dn->comp_num++, i++) {
1415 2531564 : dn->components[dn->comp_num] =
1416 2531564 : ldb_dn_copy_component(dn->components,
1417 2531564 : &base->components[i]);
1418 2531564 : if (dn->components[dn->comp_num].value.data == NULL) {
1419 0 : ldb_dn_mark_invalid(dn);
1420 0 : return false;
1421 : }
1422 : }
1423 :
1424 452499 : if (dn->casefold && s) {
1425 0 : if (*dn->casefold) {
1426 0 : t = talloc_asprintf(dn, "%s,%s",
1427 : dn->casefold, s);
1428 : } else {
1429 0 : t = talloc_strdup(dn, s);
1430 : }
1431 0 : LDB_FREE(dn->casefold);
1432 0 : dn->casefold = t;
1433 : }
1434 : }
1435 :
1436 626502 : if (dn->linearized) {
1437 :
1438 176642 : s = ldb_dn_get_linearized(base);
1439 176642 : if ( ! s) {
1440 0 : return false;
1441 : }
1442 :
1443 176642 : if (*dn->linearized) {
1444 14591 : t = talloc_asprintf(dn, "%s,%s",
1445 : dn->linearized, s);
1446 : } else {
1447 162051 : t = talloc_strdup(dn, s);
1448 : }
1449 176642 : if ( ! t) {
1450 0 : ldb_dn_mark_invalid(dn);
1451 0 : return false;
1452 : }
1453 176642 : LDB_FREE(dn->linearized);
1454 176642 : dn->linearized = t;
1455 : }
1456 :
1457 : /* Wipe the ext_linearized DN,
1458 : * the GUID and SID are almost certainly no longer valid */
1459 626502 : LDB_FREE(dn->ext_linearized);
1460 626502 : LDB_FREE(dn->ext_components);
1461 626502 : dn->ext_comp_num = 0;
1462 :
1463 626502 : return true;
1464 : }
1465 :
1466 : /* modify the given dn by adding a base.
1467 : *
1468 : * return true if successful and false if not
1469 : * if false is returned the dn may be marked invalid
1470 : */
1471 2 : bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...)
1472 : {
1473 2 : struct ldb_dn *base;
1474 2 : char *base_str;
1475 2 : va_list ap;
1476 2 : bool ret;
1477 :
1478 2 : if ( !dn || dn->invalid) {
1479 0 : return false;
1480 : }
1481 :
1482 2 : va_start(ap, base_fmt);
1483 2 : base_str = talloc_vasprintf(dn, base_fmt, ap);
1484 2 : va_end(ap);
1485 :
1486 2 : if (base_str == NULL) {
1487 0 : return false;
1488 : }
1489 :
1490 2 : base = ldb_dn_new(base_str, dn->ldb, base_str);
1491 :
1492 2 : ret = ldb_dn_add_base(dn, base);
1493 :
1494 2 : talloc_free(base_str);
1495 :
1496 2 : return ret;
1497 : }
1498 :
1499 : /* modify the given dn by adding children elements.
1500 : *
1501 : * return true if successful and false if not
1502 : * if false is returned the dn may be marked invalid
1503 : */
1504 6775999 : bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child)
1505 : {
1506 368864 : const char *s;
1507 368864 : char *t;
1508 :
1509 6775999 : if ( !child || child->invalid || !dn || dn->invalid) {
1510 0 : return false;
1511 : }
1512 :
1513 6775999 : if (dn->components) {
1514 365173 : unsigned int n;
1515 365173 : unsigned int i, j;
1516 :
1517 6535519 : if (dn->comp_num == 0) {
1518 0 : return false;
1519 : }
1520 :
1521 6535519 : if ( ! ldb_dn_validate(child)) {
1522 0 : return false;
1523 : }
1524 :
1525 6535519 : s = NULL;
1526 6535519 : if (dn->valid_case) {
1527 4655734 : if ( ! (s = ldb_dn_get_casefold(child))) {
1528 0 : return false;
1529 : }
1530 : }
1531 :
1532 6535519 : n = dn->comp_num + child->comp_num;
1533 :
1534 6535519 : dn->components = talloc_realloc(dn,
1535 : dn->components,
1536 : struct ldb_dn_component,
1537 : n);
1538 6535519 : if ( ! dn->components) {
1539 0 : ldb_dn_mark_invalid(dn);
1540 0 : return false;
1541 : }
1542 :
1543 35289052 : for (i = dn->comp_num - 1, j = n - 1; i != (unsigned int) -1;
1544 28753533 : i--, j--) {
1545 28753533 : dn->components[j] = dn->components[i];
1546 : }
1547 :
1548 19089925 : for (i = 0; i < child->comp_num; i++) {
1549 12554406 : dn->components[i] =
1550 12554406 : ldb_dn_copy_component(dn->components,
1551 12554406 : &child->components[i]);
1552 12554406 : if (dn->components[i].value.data == NULL) {
1553 0 : ldb_dn_mark_invalid(dn);
1554 0 : return false;
1555 : }
1556 : }
1557 :
1558 6535519 : dn->comp_num = n;
1559 :
1560 6535519 : if (dn->casefold && s) {
1561 3393821 : t = talloc_asprintf(dn, "%s,%s", s, dn->casefold);
1562 3393821 : LDB_FREE(dn->casefold);
1563 3393821 : dn->casefold = t;
1564 : }
1565 : }
1566 :
1567 6775999 : if (dn->linearized) {
1568 6768915 : if (dn->linearized[0] == '\0') {
1569 0 : return false;
1570 : }
1571 :
1572 6768914 : s = ldb_dn_get_linearized(child);
1573 6768914 : if ( ! s) {
1574 0 : return false;
1575 : }
1576 :
1577 6768914 : t = talloc_asprintf(dn, "%s,%s", s, dn->linearized);
1578 6768914 : if ( ! t) {
1579 0 : ldb_dn_mark_invalid(dn);
1580 0 : return false;
1581 : }
1582 6768914 : LDB_FREE(dn->linearized);
1583 6768914 : dn->linearized = t;
1584 : }
1585 :
1586 : /* Wipe the ext_linearized DN,
1587 : * the GUID and SID are almost certainly no longer valid */
1588 6775998 : LDB_FREE(dn->ext_linearized);
1589 6775998 : LDB_FREE(dn->ext_components);
1590 6775998 : dn->ext_comp_num = 0;
1591 :
1592 6775998 : return true;
1593 : }
1594 :
1595 : /* modify the given dn by adding children elements.
1596 : *
1597 : * return true if successful and false if not
1598 : * if false is returned the dn may be marked invalid
1599 : */
1600 6580769 : bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...)
1601 : {
1602 367516 : struct ldb_dn *child;
1603 367516 : char *child_str;
1604 367516 : va_list ap;
1605 367516 : bool ret;
1606 :
1607 6580769 : if ( !dn || dn->invalid) {
1608 0 : return false;
1609 : }
1610 :
1611 6580769 : va_start(ap, child_fmt);
1612 6580769 : child_str = talloc_vasprintf(dn, child_fmt, ap);
1613 6580769 : va_end(ap);
1614 :
1615 6580769 : if (child_str == NULL) {
1616 0 : return false;
1617 : }
1618 :
1619 6580769 : child = ldb_dn_new(child_str, dn->ldb, child_str);
1620 :
1621 6580769 : ret = ldb_dn_add_child(dn, child);
1622 :
1623 6580769 : talloc_free(child_str);
1624 :
1625 6580769 : return ret;
1626 : }
1627 :
1628 : /* modify the given dn by adding a single child element.
1629 : *
1630 : * return true if successful and false if not
1631 : * if false is returned the dn may be marked invalid
1632 : */
1633 25072 : bool ldb_dn_add_child_val(struct ldb_dn *dn,
1634 : const char *rdn,
1635 : struct ldb_val value)
1636 : {
1637 10 : bool ret;
1638 10 : int ldb_ret;
1639 25072 : struct ldb_dn *child = NULL;
1640 :
1641 25072 : if ( !dn || dn->invalid) {
1642 0 : return false;
1643 : }
1644 :
1645 25072 : child = ldb_dn_new(dn, dn->ldb, "X=Y");
1646 25072 : ret = ldb_dn_add_child(dn, child);
1647 :
1648 25072 : if (ret == false) {
1649 0 : return false;
1650 : }
1651 :
1652 25072 : ldb_ret = ldb_dn_set_component(dn,
1653 : 0,
1654 : rdn,
1655 : value);
1656 25072 : if (ldb_ret != LDB_SUCCESS) {
1657 0 : return false;
1658 : }
1659 :
1660 25062 : return true;
1661 : }
1662 :
1663 595616 : bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num)
1664 : {
1665 454 : unsigned int i;
1666 :
1667 595616 : if ( ! ldb_dn_validate(dn)) {
1668 0 : return false;
1669 : }
1670 :
1671 595616 : if (dn->comp_num < num) {
1672 0 : return false;
1673 : }
1674 :
1675 : /* free components */
1676 3797809 : for (i = dn->comp_num - num; i < dn->comp_num; i++) {
1677 3202193 : LDB_FREE(dn->components[i].name);
1678 3202193 : LDB_FREE(dn->components[i].value.data);
1679 3202193 : LDB_FREE(dn->components[i].cf_name);
1680 3202193 : LDB_FREE(dn->components[i].cf_value.data);
1681 : }
1682 :
1683 595616 : dn->comp_num -= num;
1684 :
1685 595616 : if (dn->valid_case) {
1686 292127 : for (i = 0; i < dn->comp_num; i++) {
1687 146057 : LDB_FREE(dn->components[i].cf_name);
1688 146057 : LDB_FREE(dn->components[i].cf_value.data);
1689 : }
1690 146070 : dn->valid_case = false;
1691 : }
1692 :
1693 595616 : LDB_FREE(dn->casefold);
1694 595616 : LDB_FREE(dn->linearized);
1695 :
1696 : /* Wipe the ext_linearized DN,
1697 : * the GUID and SID are almost certainly no longer valid */
1698 595616 : LDB_FREE(dn->ext_linearized);
1699 595616 : LDB_FREE(dn->ext_components);
1700 595616 : dn->ext_comp_num = 0;
1701 :
1702 595616 : return true;
1703 : }
1704 :
1705 13025798 : bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num)
1706 : {
1707 783571 : unsigned int i, j;
1708 :
1709 13025798 : if ( ! ldb_dn_validate(dn)) {
1710 0 : return false;
1711 : }
1712 :
1713 13025798 : if (dn->comp_num < num) {
1714 1 : return false;
1715 : }
1716 :
1717 84182776 : for (i = 0, j = num; j < dn->comp_num; i++, j++) {
1718 71156979 : if (i < num) {
1719 13024499 : LDB_FREE(dn->components[i].name);
1720 13024499 : LDB_FREE(dn->components[i].value.data);
1721 13024499 : LDB_FREE(dn->components[i].cf_name);
1722 13024499 : LDB_FREE(dn->components[i].cf_value.data);
1723 : }
1724 71156979 : dn->components[i] = dn->components[j];
1725 : }
1726 :
1727 13025797 : dn->comp_num -= num;
1728 :
1729 13025797 : if (dn->valid_case) {
1730 61298734 : for (i = 0; i < dn->comp_num; i++) {
1731 51825385 : LDB_FREE(dn->components[i].cf_name);
1732 51825385 : LDB_FREE(dn->components[i].cf_value.data);
1733 : }
1734 9473349 : dn->valid_case = false;
1735 : }
1736 :
1737 13025797 : LDB_FREE(dn->casefold);
1738 13025797 : LDB_FREE(dn->linearized);
1739 :
1740 : /* Wipe the ext_linearized DN,
1741 : * the GUID and SID are almost certainly no longer valid */
1742 13025797 : LDB_FREE(dn->ext_linearized);
1743 13025797 : LDB_FREE(dn->ext_components);
1744 13025797 : dn->ext_comp_num = 0;
1745 :
1746 13025797 : return true;
1747 : }
1748 :
1749 :
1750 : /* replace the components of a DN with those from another DN, without
1751 : * touching the extended components
1752 : *
1753 : * return true if successful and false if not
1754 : * if false is returned the dn may be marked invalid
1755 : */
1756 126081 : bool ldb_dn_replace_components(struct ldb_dn *dn, struct ldb_dn *new_dn)
1757 : {
1758 1705 : unsigned int i;
1759 :
1760 126081 : if ( ! ldb_dn_validate(dn) || ! ldb_dn_validate(new_dn)) {
1761 0 : return false;
1762 : }
1763 :
1764 : /* free components */
1765 859803 : for (i = 0; i < dn->comp_num; i++) {
1766 733722 : LDB_FREE(dn->components[i].name);
1767 733722 : LDB_FREE(dn->components[i].value.data);
1768 733722 : LDB_FREE(dn->components[i].cf_name);
1769 733722 : LDB_FREE(dn->components[i].cf_value.data);
1770 : }
1771 :
1772 126081 : dn->components = talloc_realloc(dn,
1773 : dn->components,
1774 : struct ldb_dn_component,
1775 : new_dn->comp_num);
1776 126081 : if (dn->components == NULL) {
1777 0 : ldb_dn_mark_invalid(dn);
1778 0 : return false;
1779 : }
1780 :
1781 126081 : dn->comp_num = new_dn->comp_num;
1782 126081 : dn->valid_case = new_dn->valid_case;
1783 :
1784 741529 : for (i = 0; i < dn->comp_num; i++) {
1785 615448 : dn->components[i] = ldb_dn_copy_component(dn->components, &new_dn->components[i]);
1786 615448 : if (dn->components[i].name == NULL) {
1787 0 : ldb_dn_mark_invalid(dn);
1788 0 : return false;
1789 : }
1790 : }
1791 126081 : if (new_dn->linearized == NULL) {
1792 0 : dn->linearized = NULL;
1793 : } else {
1794 126081 : dn->linearized = talloc_strdup(dn, new_dn->linearized);
1795 126081 : if (dn->linearized == NULL) {
1796 0 : ldb_dn_mark_invalid(dn);
1797 0 : return false;
1798 : }
1799 : }
1800 :
1801 124376 : return true;
1802 : }
1803 :
1804 :
1805 13021551 : struct ldb_dn *ldb_dn_get_parent(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
1806 : {
1807 783541 : struct ldb_dn *new_dn;
1808 :
1809 13021551 : new_dn = ldb_dn_copy(mem_ctx, dn);
1810 13021551 : if ( !new_dn ) {
1811 2 : return NULL;
1812 : }
1813 :
1814 13021549 : if ( ! ldb_dn_remove_child_components(new_dn, 1)) {
1815 1 : talloc_free(new_dn);
1816 1 : return NULL;
1817 : }
1818 :
1819 12238007 : return new_dn;
1820 : }
1821 :
1822 : /* Create a 'canonical name' string from a DN:
1823 :
1824 : ie dc=samba,dc=org -> samba.org/
1825 : uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator
1826 :
1827 : There are two formats,
1828 : the EX format has the last '/' replaced with a newline (\n).
1829 :
1830 : */
1831 2645904 : static char *ldb_dn_canonical(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int ex_format) {
1832 151974 : unsigned int i;
1833 151974 : TALLOC_CTX *tmpctx;
1834 2645904 : char *cracked = NULL;
1835 2645904 : const char *format = (ex_format ? "\n" : "/" );
1836 :
1837 2645904 : if ( ! ldb_dn_validate(dn)) {
1838 0 : return NULL;
1839 : }
1840 :
1841 2645904 : tmpctx = talloc_new(mem_ctx);
1842 :
1843 : /* Walk backwards down the DN, grabbing 'dc' components at first */
1844 11483242 : for (i = dn->comp_num - 1; i != (unsigned int) -1; i--) {
1845 11182271 : if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) {
1846 2201990 : break;
1847 : }
1848 8837338 : if (cracked) {
1849 6191572 : cracked = talloc_asprintf(tmpctx, "%s.%s",
1850 : ldb_dn_escape_value(tmpctx,
1851 5865848 : dn->components[i].value),
1852 : cracked);
1853 : } else {
1854 2645766 : cracked = ldb_dn_escape_value(tmpctx,
1855 2493926 : dn->components[i].value);
1856 : }
1857 8837338 : if (!cracked) {
1858 0 : goto done;
1859 : }
1860 : }
1861 :
1862 : /* Only domain components? Finish here */
1863 2645904 : if (i == (unsigned int) -1) {
1864 300971 : cracked = talloc_strdup_append_buffer(cracked, format);
1865 300971 : talloc_steal(mem_ctx, cracked);
1866 300971 : goto done;
1867 : }
1868 :
1869 : /* Now walk backwards appending remaining components */
1870 6459284 : for (; i > 0; i--) {
1871 4114351 : cracked = talloc_asprintf_append_buffer(cracked, "/%s",
1872 : ldb_dn_escape_value(tmpctx,
1873 4114351 : dn->components[i].value));
1874 4114351 : if (!cracked) {
1875 0 : goto done;
1876 : }
1877 : }
1878 :
1879 : /* Last one, possibly a newline for the 'ex' format */
1880 2344933 : cracked = talloc_asprintf_append_buffer(cracked, "%s%s", format,
1881 : ldb_dn_escape_value(tmpctx,
1882 2344933 : dn->components[i].value));
1883 :
1884 2344933 : talloc_steal(mem_ctx, cracked);
1885 2645904 : done:
1886 2645904 : talloc_free(tmpctx);
1887 2645904 : return cracked;
1888 : }
1889 :
1890 : /* Wrapper functions for the above, for the two different string formats */
1891 2645641 : char *ldb_dn_canonical_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) {
1892 2645641 : return ldb_dn_canonical(mem_ctx, dn, 0);
1893 :
1894 : }
1895 :
1896 263 : char *ldb_dn_canonical_ex_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) {
1897 263 : return ldb_dn_canonical(mem_ctx, dn, 1);
1898 : }
1899 :
1900 26205658 : int ldb_dn_get_comp_num(struct ldb_dn *dn)
1901 : {
1902 26205658 : if ( ! ldb_dn_validate(dn)) {
1903 178 : return -1;
1904 : }
1905 26205476 : return dn->comp_num;
1906 : }
1907 :
1908 14731981 : int ldb_dn_get_extended_comp_num(struct ldb_dn *dn)
1909 : {
1910 14731981 : if ( ! ldb_dn_validate(dn)) {
1911 178 : return -1;
1912 : }
1913 14731799 : return dn->ext_comp_num;
1914 : }
1915 :
1916 9145 : const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num)
1917 : {
1918 9145 : if ( ! ldb_dn_validate(dn)) {
1919 0 : return NULL;
1920 : }
1921 9145 : if (num >= dn->comp_num) return NULL;
1922 9137 : return dn->components[num].name;
1923 : }
1924 :
1925 598482 : const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn,
1926 : unsigned int num)
1927 : {
1928 598482 : if ( ! ldb_dn_validate(dn)) {
1929 0 : return NULL;
1930 : }
1931 598482 : if (num >= dn->comp_num) return NULL;
1932 598482 : return &dn->components[num].value;
1933 : }
1934 :
1935 70399952 : const char *ldb_dn_get_rdn_name(struct ldb_dn *dn)
1936 : {
1937 70399952 : if ( ! ldb_dn_validate(dn)) {
1938 0 : return NULL;
1939 : }
1940 70399952 : if (dn->comp_num == 0) return NULL;
1941 56537427 : return dn->components[0].name;
1942 : }
1943 :
1944 56142526 : const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn)
1945 : {
1946 56142526 : if ( ! ldb_dn_validate(dn)) {
1947 2 : return NULL;
1948 : }
1949 56142524 : if (dn->comp_num == 0) return NULL;
1950 42279999 : return &dn->components[0].value;
1951 : }
1952 :
1953 1226928 : int ldb_dn_set_component(struct ldb_dn *dn, int num,
1954 : const char *name, const struct ldb_val val)
1955 : {
1956 156832 : char *n;
1957 156832 : struct ldb_val v;
1958 :
1959 1226928 : if ( ! ldb_dn_validate(dn)) {
1960 0 : return LDB_ERR_OTHER;
1961 : }
1962 :
1963 1226928 : if (num < 0) {
1964 0 : return LDB_ERR_OTHER;
1965 : }
1966 :
1967 1226928 : if ((unsigned)num >= dn->comp_num) {
1968 2 : return LDB_ERR_OTHER;
1969 : }
1970 :
1971 1226926 : if (val.length > val.length + 1) {
1972 0 : return LDB_ERR_OTHER;
1973 : }
1974 :
1975 1226926 : n = talloc_strdup(dn, name);
1976 1226926 : if ( ! n) {
1977 0 : return LDB_ERR_OTHER;
1978 : }
1979 :
1980 1226926 : v.length = val.length;
1981 :
1982 : /*
1983 : * This is like talloc_memdup(dn, v.data, v.length + 1), but
1984 : * avoids the over-read
1985 : */
1986 1226926 : v.data = (uint8_t *)talloc_size(dn, v.length+1);
1987 1226926 : if ( ! v.data) {
1988 0 : talloc_free(n);
1989 0 : return LDB_ERR_OTHER;
1990 : }
1991 1226926 : memcpy(v.data, val.data, val.length);
1992 :
1993 : /*
1994 : * Enforce NUL termination outside the stated length, as is
1995 : * traditional in LDB
1996 : */
1997 1226926 : v.data[v.length] = '\0';
1998 :
1999 1226926 : talloc_free(dn->components[num].name);
2000 1226926 : talloc_free(dn->components[num].value.data);
2001 1226926 : dn->components[num].name = n;
2002 1226926 : dn->components[num].value = v;
2003 :
2004 1226926 : if (dn->valid_case) {
2005 : unsigned int i;
2006 4941895 : for (i = 0; i < dn->comp_num; i++) {
2007 4270230 : LDB_FREE(dn->components[i].cf_name);
2008 4270230 : LDB_FREE(dn->components[i].cf_value.data);
2009 : }
2010 671665 : dn->valid_case = false;
2011 : }
2012 1226926 : LDB_FREE(dn->casefold);
2013 1226926 : LDB_FREE(dn->linearized);
2014 :
2015 : /* Wipe the ext_linearized DN,
2016 : * the GUID and SID are almost certainly no longer valid */
2017 1226926 : LDB_FREE(dn->ext_linearized);
2018 1226926 : LDB_FREE(dn->ext_components);
2019 1226926 : dn->ext_comp_num = 0;
2020 :
2021 1226926 : return LDB_SUCCESS;
2022 : }
2023 :
2024 256777288 : const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn,
2025 : const char *name)
2026 : {
2027 6786727 : unsigned int i;
2028 256777288 : if ( ! ldb_dn_validate(dn)) {
2029 718 : return NULL;
2030 : }
2031 321520615 : for (i=0; i < dn->ext_comp_num; i++) {
2032 128384076 : if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) {
2033 63640031 : return &dn->ext_components[i].value;
2034 : }
2035 : }
2036 188010660 : return NULL;
2037 : }
2038 :
2039 156936032 : int ldb_dn_set_extended_component(struct ldb_dn *dn,
2040 : const char *name, const struct ldb_val *val)
2041 : {
2042 3714430 : struct ldb_dn_ext_component *p;
2043 3714430 : unsigned int i;
2044 3714430 : struct ldb_val v2;
2045 3714430 : const struct ldb_dn_extended_syntax *ext_syntax;
2046 :
2047 156936032 : if ( ! ldb_dn_validate(dn)) {
2048 0 : return LDB_ERR_OTHER;
2049 : }
2050 :
2051 156936032 : ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name);
2052 156936032 : if (ext_syntax == NULL) {
2053 : /* We don't know how to handle this type of thing */
2054 0 : return LDB_ERR_INVALID_DN_SYNTAX;
2055 : }
2056 :
2057 248718492 : for (i=0; i < dn->ext_comp_num; i++) {
2058 91793196 : if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) {
2059 10736 : if (val) {
2060 10736 : dn->ext_components[i].value =
2061 10736 : ldb_val_dup(dn->ext_components, val);
2062 :
2063 10736 : dn->ext_components[i].name = ext_syntax->name;
2064 10736 : if (!dn->ext_components[i].value.data) {
2065 0 : ldb_dn_mark_invalid(dn);
2066 0 : return LDB_ERR_OPERATIONS_ERROR;
2067 : }
2068 : } else {
2069 0 : ARRAY_DEL_ELEMENT(
2070 : dn->ext_components,
2071 : i,
2072 0 : dn->ext_comp_num);
2073 0 : dn->ext_comp_num--;
2074 :
2075 0 : dn->ext_components = talloc_realloc(dn,
2076 : dn->ext_components,
2077 : struct ldb_dn_ext_component,
2078 : dn->ext_comp_num);
2079 0 : if (!dn->ext_components) {
2080 0 : ldb_dn_mark_invalid(dn);
2081 0 : return LDB_ERR_OPERATIONS_ERROR;
2082 : }
2083 : }
2084 10736 : LDB_FREE(dn->ext_linearized);
2085 :
2086 10736 : return LDB_SUCCESS;
2087 : }
2088 : }
2089 :
2090 156925296 : if (val == NULL) {
2091 : /* removing a value that doesn't exist is not an error */
2092 0 : return LDB_SUCCESS;
2093 : }
2094 :
2095 156925296 : v2 = *val;
2096 :
2097 160639666 : p = dn->ext_components
2098 156925296 : = talloc_realloc(dn,
2099 : dn->ext_components,
2100 : struct ldb_dn_ext_component,
2101 : dn->ext_comp_num + 1);
2102 156925296 : if (!dn->ext_components) {
2103 0 : ldb_dn_mark_invalid(dn);
2104 0 : return LDB_ERR_OPERATIONS_ERROR;
2105 : }
2106 :
2107 156925296 : p[dn->ext_comp_num].value = ldb_val_dup(dn->ext_components, &v2);
2108 156925296 : p[dn->ext_comp_num].name = talloc_strdup(p, name);
2109 :
2110 156925296 : if (!dn->ext_components[i].name || !dn->ext_components[i].value.data) {
2111 0 : ldb_dn_mark_invalid(dn);
2112 0 : return LDB_ERR_OPERATIONS_ERROR;
2113 : }
2114 156925296 : dn->ext_components = p;
2115 156925296 : dn->ext_comp_num++;
2116 :
2117 156925296 : LDB_FREE(dn->ext_linearized);
2118 :
2119 153210926 : return LDB_SUCCESS;
2120 : }
2121 :
2122 45941793 : void ldb_dn_remove_extended_components(struct ldb_dn *dn)
2123 : {
2124 45941793 : LDB_FREE(dn->ext_linearized);
2125 45941793 : LDB_FREE(dn->ext_components);
2126 45941793 : dn->ext_comp_num = 0;
2127 45941793 : }
2128 :
2129 4504 : bool ldb_dn_is_valid(struct ldb_dn *dn)
2130 : {
2131 4504 : if ( ! dn) return false;
2132 4504 : return ! dn->invalid;
2133 : }
2134 :
2135 1855334201 : bool ldb_dn_is_special(struct ldb_dn *dn)
2136 : {
2137 1855334201 : if ( ! dn || dn->invalid) return false;
2138 1855334200 : return dn->special;
2139 : }
2140 :
2141 459880983 : bool ldb_dn_has_extended(struct ldb_dn *dn)
2142 : {
2143 459880983 : if ( ! dn || dn->invalid) return false;
2144 459880983 : if (dn->ext_linearized && (dn->ext_linearized[0] == '<')) return true;
2145 445155395 : return dn->ext_comp_num != 0;
2146 : }
2147 :
2148 15682110 : bool ldb_dn_check_special(struct ldb_dn *dn, const char *check)
2149 : {
2150 15682110 : if ( ! dn || dn->invalid) return false;
2151 15682110 : return ! strcmp(dn->linearized, check);
2152 : }
2153 :
2154 396417950 : bool ldb_dn_is_null(struct ldb_dn *dn)
2155 : {
2156 396417950 : if ( ! dn || dn->invalid) return false;
2157 396417950 : if (ldb_dn_has_extended(dn)) return false;
2158 343986815 : if (dn->linearized && (dn->linearized[0] == '\0')) return true;
2159 307050221 : return false;
2160 : }
2161 :
2162 : /*
2163 : this updates dn->components, taking the components from ref_dn.
2164 : This is used by code that wants to update the DN path of a DN
2165 : while not impacting on the extended DN components
2166 : */
2167 10895 : int ldb_dn_update_components(struct ldb_dn *dn, const struct ldb_dn *ref_dn)
2168 : {
2169 10895 : dn->components = talloc_realloc(dn, dn->components,
2170 : struct ldb_dn_component, ref_dn->comp_num);
2171 10895 : if (!dn->components) {
2172 0 : return LDB_ERR_OPERATIONS_ERROR;
2173 : }
2174 10895 : memcpy(dn->components, ref_dn->components,
2175 10895 : sizeof(struct ldb_dn_component)*ref_dn->comp_num);
2176 10895 : dn->comp_num = ref_dn->comp_num;
2177 :
2178 10895 : LDB_FREE(dn->casefold);
2179 10895 : LDB_FREE(dn->linearized);
2180 10895 : LDB_FREE(dn->ext_linearized);
2181 :
2182 10842 : return LDB_SUCCESS;
2183 : }
2184 :
2185 : /*
2186 : minimise a DN. The caller must pass in a validated DN.
2187 :
2188 : If the DN has an extended component then only the first extended
2189 : component is kept, the DN string is stripped.
2190 :
2191 : The existing dn is modified
2192 : */
2193 8076345 : bool ldb_dn_minimise(struct ldb_dn *dn)
2194 : {
2195 291242 : unsigned int i;
2196 :
2197 8076345 : if (!ldb_dn_validate(dn)) {
2198 0 : return false;
2199 : }
2200 8076345 : if (dn->ext_comp_num == 0) {
2201 0 : return true;
2202 : }
2203 :
2204 : /* free components */
2205 41263283 : for (i = 0; i < dn->comp_num; i++) {
2206 33186938 : LDB_FREE(dn->components[i].name);
2207 33186938 : LDB_FREE(dn->components[i].value.data);
2208 33186938 : LDB_FREE(dn->components[i].cf_name);
2209 33186938 : LDB_FREE(dn->components[i].cf_value.data);
2210 : }
2211 8076345 : dn->comp_num = 0;
2212 8076345 : dn->valid_case = false;
2213 :
2214 8076345 : LDB_FREE(dn->casefold);
2215 8076345 : LDB_FREE(dn->linearized);
2216 :
2217 : /* note that we don't free dn->components as this there are
2218 : * several places in ldb_dn.c that rely on it being non-NULL
2219 : * for an exploded DN
2220 : */
2221 :
2222 11512606 : for (i = 1; i < dn->ext_comp_num; i++) {
2223 3436261 : LDB_FREE(dn->ext_components[i].value.data);
2224 : }
2225 8076345 : dn->ext_comp_num = 1;
2226 :
2227 8076345 : dn->ext_components = talloc_realloc(dn, dn->ext_components, struct ldb_dn_ext_component, 1);
2228 8076345 : if (dn->ext_components == NULL) {
2229 0 : ldb_dn_mark_invalid(dn);
2230 0 : return false;
2231 : }
2232 :
2233 8076345 : LDB_FREE(dn->ext_linearized);
2234 :
2235 7785103 : return true;
2236 : }
2237 :
2238 155971152 : struct ldb_context *ldb_dn_get_ldb_context(struct ldb_dn *dn)
2239 : {
2240 155971152 : return dn->ldb;
2241 : }
|