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 19941 : static void ldb_dn_mark_invalid(struct ldb_dn *dn)
84 : {
85 19941 : dn->invalid = true;
86 19922 : }
87 :
88 : /* strdn may be NULL */
89 922753678 : 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 25414793 : struct ldb_dn *dn;
94 :
95 922753678 : if (ldb == NULL || strdn == NULL) {
96 0 : return NULL;
97 : }
98 922753678 : if (strdn->data
99 893072666 : && (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 922753675 : dn = talloc_zero(mem_ctx, struct ldb_dn);
105 922753675 : LDB_DN_NULL_FAILED(dn);
106 :
107 922753675 : dn->ldb = talloc_get_type(ldb, struct ldb_context);
108 922753675 : 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 1790099454 : if (strdn->data && strdn->length) {
116 892151654 : const char *data = (const char *)strdn->data;
117 892151654 : size_t length = strdn->length;
118 :
119 892151654 : if (data[0] == '@') {
120 416771926 : dn->special = true;
121 : }
122 892151654 : dn->ext_linearized = talloc_strndup(dn, data, length);
123 892151654 : LDB_DN_NULL_FAILED(dn->ext_linearized);
124 :
125 892151654 : if (data[0] == '<') {
126 42674878 : const char *p_save, *p = dn->ext_linearized;
127 2343850 : do {
128 123514860 : p_save = p;
129 123514860 : p = strstr(p, ">;");
130 123514860 : if (p) {
131 79717391 : p = p + 2;
132 : }
133 123514860 : } while (p);
134 :
135 43797469 : if (p_save == dn->ext_linearized) {
136 8511344 : dn->linearized = talloc_strdup(dn, "");
137 : } else {
138 35286125 : dn->linearized = talloc_strdup(dn, p_save);
139 : }
140 43797469 : LDB_DN_NULL_FAILED(dn->linearized);
141 : } else {
142 848354185 : dn->linearized = dn->ext_linearized;
143 848354185 : dn->ext_linearized = NULL;
144 : }
145 : } else {
146 30602021 : dn->linearized = talloc_strdup(dn, "");
147 30602021 : LDB_DN_NULL_FAILED(dn->linearized);
148 : }
149 :
150 897338885 : return dn;
151 :
152 0 : failed:
153 0 : talloc_free(dn);
154 0 : return NULL;
155 : }
156 :
157 : /* strdn may be NULL */
158 347363018 : struct ldb_dn *ldb_dn_new(TALLOC_CTX *mem_ctx,
159 : struct ldb_context *ldb,
160 : const char *strdn)
161 : {
162 11391148 : struct ldb_val blob;
163 347363018 : blob.data = discard_const_p(uint8_t, strdn);
164 347363018 : blob.length = strdn ? strlen(strdn) : 0;
165 347363018 : return ldb_dn_from_ldb_val(mem_ctx, ldb, &blob);
166 : }
167 :
168 202899022 : struct ldb_dn *ldb_dn_new_fmt(TALLOC_CTX *mem_ctx,
169 : struct ldb_context *ldb,
170 : const char *new_fmt, ...)
171 : {
172 6638984 : char *strdn;
173 6638984 : va_list ap;
174 :
175 202899022 : if (! ldb) return NULL;
176 :
177 202899022 : va_start(ap, new_fmt);
178 202899022 : strdn = talloc_vasprintf(mem_ctx, new_fmt, ap);
179 202899022 : va_end(ap);
180 :
181 202899022 : if (strdn) {
182 202899022 : struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb, strdn);
183 202899022 : talloc_free(strdn);
184 202899022 : return dn;
185 : }
186 :
187 0 : return NULL;
188 : }
189 :
190 : /* see RFC2253 section 2.4 */
191 234214531 : static int ldb_dn_escape_internal(char *dst, const char *src, int len)
192 : {
193 14394149 : char c;
194 14394149 : char *d;
195 14394149 : int i;
196 234214531 : d = dst;
197 :
198 2249262617 : for (i = 0; i < len; i++){
199 2015048086 : c = src[i];
200 2015048086 : switch (c) {
201 14973277 : case ' ':
202 14973277 : 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 14973277 : *d++ = c;
210 : }
211 14038723 : 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 1726428 : case ';':
229 : case '\r':
230 : case '\n':
231 : case '=':
232 : case '\0': {
233 : /* any others get \XX form */
234 927 : unsigned char v;
235 1726428 : const char *hexbytes = "0123456789ABCDEF";
236 1726428 : v = (const unsigned char)c;
237 1726428 : *d++ = '\\';
238 1726428 : *d++ = hexbytes[v>>4];
239 1726428 : *d++ = hexbytes[v&0xF];
240 1726428 : break;
241 : }
242 1998311294 : default:
243 1998311294 : *d++ = c;
244 : }
245 : }
246 :
247 : /* return the length of the resulting string */
248 234214531 : return (d - dst);
249 : }
250 :
251 15663463 : char *ldb_dn_escape_value(TALLOC_CTX *mem_ctx, struct ldb_val value)
252 : {
253 958552 : char *dst;
254 958552 : size_t len;
255 15663463 : if (!value.length)
256 2 : return NULL;
257 :
258 : /* allocate destination string, it will be at most 3 times the source */
259 15663461 : dst = talloc_array(mem_ctx, char, value.length * 3 + 1);
260 15663461 : if ( ! dst) {
261 0 : talloc_free(dst);
262 0 : return NULL;
263 : }
264 :
265 15663461 : len = ldb_dn_escape_internal(dst, (const char *)value.data, value.length);
266 :
267 15663461 : dst = talloc_realloc(mem_ctx, dst, char, len + 1);
268 15663461 : if ( ! dst) {
269 0 : talloc_free(dst);
270 0 : return NULL;
271 : }
272 15663461 : dst[len] = '\0';
273 15663461 : 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 1238214336 : static bool ldb_dn_explode(struct ldb_dn *dn)
284 : {
285 1238214336 : char *p, *ex_name = NULL, *ex_value = NULL, *data, *d, *dt, *t;
286 1238214336 : bool trim = true;
287 1238214336 : bool in_extended = true;
288 1238214336 : bool in_ex_name = false;
289 1238214336 : bool in_ex_value = false;
290 1238214336 : bool in_attr = false;
291 1238214336 : bool in_value = false;
292 1238214336 : bool in_quote = false;
293 1238214336 : bool is_oid = false;
294 1238214336 : bool escape = false;
295 36439565 : unsigned int x;
296 1238214336 : size_t l = 0;
297 36439565 : int ret;
298 36439565 : char *parse_dn;
299 36439565 : bool is_index;
300 :
301 1238214336 : if (dn == NULL || dn->invalid) {
302 710 : return false;
303 : }
304 :
305 1238213621 : if (dn->components != NULL) {
306 647423734 : return true;
307 : }
308 :
309 568179146 : if (dn->ext_linearized != NULL) {
310 39180303 : parse_dn = dn->ext_linearized;
311 : } else {
312 528125575 : parse_dn = dn->linearized;
313 : }
314 :
315 568179146 : if (parse_dn == NULL) {
316 0 : return false;
317 : }
318 :
319 568179146 : is_index = (strncmp(parse_dn, "DN=@INDEX:", 10) == 0);
320 :
321 : /* Empty DNs */
322 568179146 : if (parse_dn[0] == '\0') {
323 30675043 : return true;
324 : }
325 :
326 : /* Special DNs case */
327 536575852 : if (dn->special) {
328 259269815 : return true;
329 : }
330 :
331 269488178 : LDB_FREE(dn->ext_components);
332 269488178 : dn->ext_comp_num = 0;
333 269488178 : 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 269488178 : dn->components = talloc_zero_array(dn, struct ldb_dn_component, 3);
338 269488178 : if (dn->components == NULL) {
339 0 : return false;
340 : }
341 :
342 : /* Components data space is allocated here once */
343 269488178 : data = talloc_array(dn->components, char, strlen(parse_dn) + 1);
344 269488178 : if (data == NULL) {
345 0 : goto failed;
346 : }
347 :
348 264405469 : p = parse_dn;
349 264405469 : t = NULL;
350 264405469 : d = dt = data;
351 :
352 26334434958 : while (*p) {
353 26073459374 : if (in_extended) {
354 :
355 3305833798 : if (!in_ex_name && !in_ex_value) {
356 :
357 340750532 : if (p[0] == '<') {
358 79773714 : p++;
359 79773714 : ex_name = d;
360 79773714 : in_ex_name = true;
361 79773714 : continue;
362 : } else {
363 260976818 : in_extended = false;
364 260976818 : in_attr = true;
365 260976818 : dt = d;
366 :
367 260976818 : continue;
368 : }
369 : }
370 :
371 2965083266 : if (in_ex_name && *p == '=') {
372 79773710 : *d++ = '\0';
373 79773710 : p++;
374 79773710 : ex_value = d;
375 79773710 : in_ex_name = false;
376 79773710 : in_ex_value = true;
377 79773710 : continue;
378 : }
379 :
380 2885309556 : if (in_ex_value && *p == '>') {
381 79773710 : struct ldb_dn_ext_component *ext_comp = NULL;
382 1174344 : const struct ldb_dn_extended_syntax *ext_syntax;
383 79773710 : struct ldb_val ex_val = {
384 : .data = (uint8_t *)ex_value,
385 79773710 : .length = d - ex_value
386 : };
387 :
388 79773710 : *d++ = '\0';
389 79773710 : p++;
390 79773710 : in_ex_value = false;
391 :
392 : /* Process name and ex_value */
393 :
394 79773710 : ext_comp = talloc_realloc(
395 : dn,
396 : dn->ext_components,
397 : struct ldb_dn_ext_component,
398 : dn->ext_comp_num + 1);
399 :
400 79773710 : if (ext_comp == NULL) {
401 : /* ouch ! */
402 442 : goto failed;
403 : }
404 :
405 79773710 : dn->ext_components = ext_comp;
406 :
407 79773710 : ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, ex_name);
408 79773710 : if (ext_syntax == NULL) {
409 : /* We don't know about this type of extended DN */
410 9 : goto failed;
411 : }
412 :
413 79773701 : dn->ext_components[dn->ext_comp_num].name = ext_syntax->name;
414 79773701 : ret = ext_syntax->read_fn(dn->ldb, dn->ext_components,
415 78599366 : &ex_val, &dn->ext_components[dn->ext_comp_num].value);
416 79773701 : if (ret != LDB_SUCCESS) {
417 433 : ldb_dn_mark_invalid(dn);
418 433 : goto failed;
419 : }
420 :
421 79773268 : dn->ext_comp_num++;
422 :
423 79773268 : if (*p == '\0') {
424 : /* We have reached the end (extended component only)! */
425 8510914 : talloc_free(data);
426 8510914 : return true;
427 :
428 71262354 : } else if (*p == ';') {
429 71262354 : p++;
430 71262354 : continue;
431 : } else {
432 0 : ldb_dn_mark_invalid(dn);
433 0 : goto failed;
434 : }
435 : }
436 :
437 2805535846 : *d++ = *p++;
438 2805535846 : continue;
439 : }
440 22767625576 : if (in_attr) {
441 4535304764 : if (trim) {
442 1533189141 : if (*p == ' ') {
443 34066599 : p++;
444 34066599 : continue;
445 : }
446 :
447 : /* first char */
448 1499122542 : trim = false;
449 :
450 1499122542 : if (!isascii(*p)) {
451 : /* attr names must be ascii only */
452 0 : ldb_dn_mark_invalid(dn);
453 0 : goto failed;
454 : }
455 :
456 1499122542 : if (isdigit(*p)) {
457 0 : is_oid = true;
458 : } else
459 1499122542 : 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 1499122535 : *d++ = *p++;
469 1499122535 : continue;
470 : }
471 :
472 3002115623 : if (*p == ' ') {
473 96 : p++;
474 : /* valid only if we are at the end */
475 96 : trim = true;
476 96 : continue;
477 : }
478 :
479 3002115527 : if (*p == '=') {
480 : /* attribute terminated */
481 1499102943 : in_attr = false;
482 1499102943 : in_value = true;
483 1499102943 : trim = true;
484 1499102943 : l = 0;
485 :
486 : /* Terminate this string in d
487 : * (which is a copy of parse_dn
488 : * with spaces trimmed) */
489 1499102943 : *d++ = '\0';
490 1499102943 : dn->components[dn->comp_num].name = talloc_strdup(dn->components, dt);
491 1499102943 : if (dn->components[dn->comp_num].name == NULL) {
492 : /* ouch */
493 0 : goto failed;
494 : }
495 :
496 1499102943 : dt = d;
497 :
498 1499102943 : p++;
499 1499102943 : continue;
500 : }
501 :
502 1503012584 : if (!isascii(*p)) {
503 : /* attr names must be ascii only */
504 0 : ldb_dn_mark_invalid(dn);
505 0 : goto failed;
506 : }
507 :
508 1503012584 : 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 1503012584 : 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 1503011353 : *d++ = *p++;
521 1503011353 : continue;
522 : }
523 :
524 18232320812 : if (in_value) {
525 18232320812 : 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 18232320812 : if (trim) {
539 1499102935 : if (*p == ' ') {
540 0 : p++;
541 0 : continue;
542 : }
543 :
544 : /* first char */
545 1499102935 : trim = false;
546 :
547 1499102935 : if (*p == '\"') {
548 0 : in_quote = true;
549 0 : p++;
550 0 : continue;
551 : }
552 : }
553 :
554 18232320812 : switch (*p) {
555 :
556 : /* TODO: support ber encoded values
557 : case '#':
558 : */
559 :
560 1238172486 : case ',':
561 1238172486 : if (escape) {
562 26853 : *d++ = *p++;
563 26853 : l++;
564 26853 : escape = false;
565 26853 : continue;
566 : }
567 : /* ok found value terminator */
568 :
569 1238145633 : if (t != NULL) {
570 : /* trim back */
571 22 : d -= (p - t);
572 22 : l -= (p - t);
573 22 : t = NULL;
574 : }
575 :
576 1238145633 : in_attr = true;
577 1238145633 : in_value = false;
578 1238145633 : trim = true;
579 :
580 1238145633 : p++;
581 1238145633 : *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 2476291266 : dn->components[dn->comp_num].value.data = \
589 1238145633 : (uint8_t *)talloc_memdup(dn->components, dt, l + 1);
590 1238145633 : dn->components[dn->comp_num].value.length = l;
591 1238145633 : if (dn->components[dn->comp_num].value.data == NULL) {
592 : /* ouch ! */
593 0 : goto failed;
594 : }
595 1238145633 : talloc_set_name_const(dn->components[dn->comp_num].value.data,
596 1213622004 : (const char *)dn->components[dn->comp_num].value.data);
597 :
598 1238145633 : dt = d;
599 :
600 1238145633 : dn->comp_num++;
601 1238145633 : if (dn->comp_num > 2) {
602 724804540 : dn->components = talloc_realloc(dn,
603 : dn->components,
604 : struct ldb_dn_component,
605 : dn->comp_num + 1);
606 724804540 : if (dn->components == NULL) {
607 : /* ouch ! */
608 0 : goto failed;
609 : }
610 : /* make sure all components are zeroed, other functions depend on this */
611 724804540 : memset(&dn->components[dn->comp_num], '\0', sizeof(struct ldb_dn_component));
612 : }
613 :
614 1238145633 : 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 85684392 : case '\\':
653 85684392 : if (!escape) {
654 85673592 : escape = true;
655 85673592 : p++;
656 85673592 : 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 16908463934 : default:
669 16908463934 : if (escape) {
670 85635939 : if (isxdigit(p[0]) && isxdigit(p[1])) {
671 85635939 : if (sscanf(p, "%02x", &x) != 1) {
672 : /* invalid escaping sequence */
673 0 : ldb_dn_mark_invalid(dn);
674 0 : goto failed;
675 : }
676 85635939 : p += 2;
677 85635939 : *d++ = (unsigned char)x;
678 : } else {
679 0 : *d++ = *p++;
680 : }
681 :
682 85635939 : escape = false;
683 85635939 : l++;
684 85635939 : if (t != NULL) {
685 0 : t = NULL;
686 : }
687 85635031 : break;
688 : }
689 :
690 16822827995 : if (*p == ' ') {
691 124778152 : if (t == NULL) {
692 124774084 : t = p;
693 : }
694 : } else {
695 16441101973 : if (t != NULL) {
696 123652412 : t = NULL;
697 : }
698 : }
699 :
700 16822827995 : *d++ = *p++;
701 16822827995 : l++;
702 :
703 16822827995 : break;
704 : }
705 :
706 : }
707 : }
708 :
709 260975584 : if (in_attr || in_quote) {
710 : /* invalid dn */
711 18270 : ldb_dn_mark_invalid(dn);
712 18270 : goto failed;
713 : }
714 :
715 260957314 : if (in_value) {
716 : /* save last element */
717 260957310 : if (t != NULL) {
718 : /* trim back */
719 190 : d -= (p - t);
720 190 : l -= (p - t);
721 : }
722 :
723 260957310 : *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 260957310 : dn->components[dn->comp_num].value.length = l;
730 521914620 : dn->components[dn->comp_num].value.data =
731 260957310 : (uint8_t *)talloc_memdup(dn->components, dt, l + 1);
732 260957310 : if (dn->components[dn->comp_num].value.data == NULL) {
733 : /* ouch */
734 0 : goto failed;
735 : }
736 260957310 : talloc_set_name_const(dn->components[dn->comp_num].value.data,
737 256104760 : (const char *)dn->components[dn->comp_num].value.data);
738 :
739 260957310 : dn->comp_num++;
740 : }
741 260957314 : talloc_free(data);
742 260957314 : return true;
743 :
744 19950 : failed:
745 19950 : LDB_FREE(dn->components); /* "data" is implicitly free'd */
746 19950 : dn->comp_num = 0;
747 19950 : LDB_FREE(dn->ext_components);
748 19950 : dn->ext_comp_num = 0;
749 :
750 19950 : return false;
751 : }
752 :
753 1140556745 : bool ldb_dn_validate(struct ldb_dn *dn)
754 : {
755 1140556745 : return ldb_dn_explode(dn);
756 : }
757 :
758 768911530 : const char *ldb_dn_get_linearized(struct ldb_dn *dn)
759 : {
760 25271307 : unsigned int i;
761 25271307 : size_t len;
762 25271307 : char *d, *n;
763 :
764 768911530 : if ( ! dn || ( dn->invalid)) return NULL;
765 :
766 768911161 : if (dn->linearized) return dn->linearized;
767 :
768 10788726 : if ( ! dn->components) {
769 0 : ldb_dn_mark_invalid(dn);
770 0 : return NULL;
771 : }
772 :
773 10788726 : if (dn->comp_num == 0) {
774 529229 : dn->linearized = talloc_strdup(dn, "");
775 529229 : if ( ! dn->linearized) return NULL;
776 529229 : return dn->linearized;
777 : }
778 :
779 : /* calculate maximum possible length of DN */
780 66940524 : for (len = 0, i = 0; i < dn->comp_num; i++) {
781 : /* name len */
782 56681027 : len += strlen(dn->components[i].name);
783 : /* max escaped data len */
784 56681027 : len += (dn->components[i].value.length * 3);
785 56681027 : len += 2; /* '=' and ',' */
786 : }
787 10259497 : dn->linearized = talloc_array(dn, char, len);
788 10259497 : if ( ! dn->linearized) return NULL;
789 :
790 9630636 : d = dn->linearized;
791 :
792 66940524 : for (i = 0; i < dn->comp_num; i++) {
793 :
794 : /* copy the name */
795 56681027 : n = dn->components[i].name;
796 170043666 : while (*n) *d++ = *n++;
797 :
798 56681027 : *d++ = '=';
799 :
800 : /* and the value */
801 113362054 : d += ldb_dn_escape_internal( d,
802 56681027 : (char *)dn->components[i].value.data,
803 56681027 : dn->components[i].value.length);
804 56681027 : *d++ = ',';
805 : }
806 :
807 10259497 : *(--d) = '\0';
808 :
809 : /* don't waste more memory than necessary */
810 10259497 : dn->linearized = talloc_realloc(dn, dn->linearized,
811 : char, (d - dn->linearized + 1));
812 :
813 10259497 : return dn->linearized;
814 : }
815 :
816 49949302 : static int ldb_dn_extended_component_compare(const void *p1, const void *p2)
817 : {
818 49949302 : const struct ldb_dn_ext_component *ec1 = (const struct ldb_dn_ext_component *)p1;
819 49949302 : const struct ldb_dn_ext_component *ec2 = (const struct ldb_dn_ext_component *)p2;
820 49949302 : return strcmp(ec1->name, ec2->name);
821 : }
822 :
823 28148791 : char *ldb_dn_get_extended_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int mode)
824 : {
825 28148791 : const char *linearized = ldb_dn_get_linearized(dn);
826 28148791 : char *p = NULL;
827 621861 : unsigned int i;
828 :
829 28148791 : if (!linearized) {
830 96 : return NULL;
831 : }
832 :
833 28148695 : if (!ldb_dn_has_extended(dn)) {
834 1540215 : return talloc_strdup(mem_ctx, linearized);
835 : }
836 :
837 26608480 : 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 26608477 : TYPESAFE_QSORT(dn->ext_components, dn->ext_comp_num,
846 : ldb_dn_extended_component_compare);
847 :
848 78386735 : for (i = 0; i < dn->ext_comp_num; i++) {
849 629250 : const struct ldb_dn_extended_syntax *ext_syntax;
850 51778258 : const char *name = dn->ext_components[i].name;
851 51778258 : struct ldb_val ec_val = dn->ext_components[i].value;
852 629250 : struct ldb_val val;
853 629250 : int ret;
854 :
855 51778258 : ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name);
856 51778258 : if (!ext_syntax) {
857 0 : return NULL;
858 : }
859 :
860 51778258 : if (mode == 1) {
861 41460512 : ret = ext_syntax->write_clear_fn(dn->ldb, mem_ctx,
862 : &ec_val, &val);
863 10317746 : } else if (mode == 0) {
864 10317746 : ret = ext_syntax->write_hex_fn(dn->ldb, mem_ctx,
865 : &ec_val, &val);
866 : } else {
867 0 : ret = -1;
868 : }
869 :
870 51778258 : if (ret != LDB_SUCCESS) {
871 0 : return NULL;
872 : }
873 :
874 51778258 : if (i == 0) {
875 26608473 : p = talloc_asprintf(mem_ctx, "<%s=%.*s>",
876 : name,
877 26608473 : (int)val.length,
878 : val.data);
879 : } else {
880 25169785 : talloc_asprintf_addbuf(&p, ";<%s=%.*s>",
881 : name,
882 25169785 : (int)val.length,
883 : val.data);
884 : }
885 :
886 51778258 : talloc_free(val.data);
887 : }
888 :
889 26608477 : if (dn->ext_comp_num && *linearized) {
890 25367092 : talloc_asprintf_addbuf(&p, ";%s", linearized);
891 : }
892 :
893 26608477 : if (!p) {
894 4 : return NULL;
895 : }
896 :
897 26096089 : return p;
898 : }
899 :
900 : /*
901 : filter out all but an acceptable list of extended DN components
902 : */
903 16917634 : void ldb_dn_extended_filter(struct ldb_dn *dn, const char * const *accept_list)
904 : {
905 204154 : unsigned int i;
906 59106973 : for (i=0; i<dn->ext_comp_num; i++) {
907 42189339 : if (!ldb_attr_in_list(accept_list, dn->ext_components[i].name)) {
908 19263128 : ARRAY_DEL_ELEMENT(
909 3206 : dn->ext_components, i, dn->ext_comp_num);
910 19263128 : dn->ext_comp_num--;
911 19263128 : i--;
912 : }
913 : }
914 16917634 : LDB_FREE(dn->ext_linearized);
915 16917634 : }
916 :
917 :
918 173491613 : char *ldb_dn_alloc_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
919 : {
920 173491613 : 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 278944105 : static bool ldb_dn_casefold_internal(struct ldb_dn *dn)
929 : {
930 4283213 : unsigned int i;
931 4283213 : int ret;
932 :
933 278944105 : if ( ! dn || dn->invalid) return false;
934 :
935 278944105 : if (dn->valid_case) return true;
936 :
937 139606743 : if (( ! dn->components) && ( ! ldb_dn_explode(dn))) {
938 736 : return false;
939 : }
940 :
941 884937330 : for (i = 0; i < dn->comp_num; i++) {
942 12268069 : const struct ldb_schema_attribute *a;
943 :
944 1490662646 : dn->components[i].cf_name =
945 745331323 : ldb_attr_casefold(dn->components,
946 745331323 : dn->components[i].name);
947 745331323 : if (!dn->components[i].cf_name) {
948 0 : goto failed;
949 : }
950 :
951 745331323 : a = ldb_schema_attribute_by_name(dn->ldb,
952 733063254 : dn->components[i].cf_name);
953 :
954 757599392 : ret = a->syntax->canonicalise_fn(dn->ldb, dn->components,
955 745331323 : &(dn->components[i].value),
956 745331323 : &(dn->components[i].cf_value));
957 745331323 : if (ret != 0) {
958 0 : goto failed;
959 : }
960 : }
961 :
962 139606007 : dn->valid_case = true;
963 :
964 139606007 : 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 506552513 : const char *ldb_dn_get_casefold(struct ldb_dn *dn)
975 : {
976 16139704 : unsigned int i;
977 16139704 : size_t len;
978 16139704 : char *d, *n;
979 :
980 506552513 : if (dn->casefold) return dn->casefold;
981 :
982 316310234 : if (dn->special) {
983 283831089 : dn->casefold = talloc_strdup(dn, dn->linearized);
984 283831089 : if (!dn->casefold) return NULL;
985 283831089 : dn->valid_case = true;
986 283831089 : return dn->casefold;
987 : }
988 :
989 32479145 : if ( ! ldb_dn_casefold_internal(dn)) {
990 0 : return NULL;
991 : }
992 :
993 32479145 : if (dn->comp_num == 0) {
994 1372 : dn->casefold = talloc_strdup(dn, "");
995 1372 : return dn->casefold;
996 : }
997 :
998 : /* calculate maximum possible length of DN */
999 194347816 : for (len = 0, i = 0; i < dn->comp_num; i++) {
1000 : /* name len */
1001 161870043 : len += strlen(dn->components[i].cf_name);
1002 : /* max escaped data len */
1003 161870043 : len += (dn->components[i].cf_value.length * 3);
1004 161870043 : len += 2; /* '=' and ',' */
1005 : }
1006 32477773 : dn->casefold = talloc_array(dn, char, len);
1007 32477773 : if ( ! dn->casefold) return NULL;
1008 :
1009 30507698 : d = dn->casefold;
1010 :
1011 194347816 : for (i = 0; i < dn->comp_num; i++) {
1012 :
1013 : /* copy the name */
1014 161870043 : n = dn->components[i].cf_name;
1015 487097061 : while (*n) *d++ = *n++;
1016 :
1017 161870043 : *d++ = '=';
1018 :
1019 : /* and the value */
1020 323740086 : d += ldb_dn_escape_internal( d,
1021 161870043 : (char *)dn->components[i].cf_value.data,
1022 161870043 : dn->components[i].cf_value.length);
1023 161870043 : *d++ = ',';
1024 : }
1025 32477773 : *(--d) = '\0';
1026 :
1027 : /* don't waste more memory than necessary */
1028 32477773 : dn->casefold = talloc_realloc(dn, dn->casefold,
1029 : char, strlen(dn->casefold) + 1);
1030 :
1031 32477773 : return dn->casefold;
1032 : }
1033 :
1034 2473993 : char *ldb_dn_alloc_casefold(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
1035 : {
1036 2473993 : 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 : *
1042 : * 0 if they match, otherwise non-zero.
1043 : *
1044 : * This is not for use in a qsort()-like function, as the comparison
1045 : * is not symmetric.
1046 : */
1047 :
1048 577865297 : int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn)
1049 : {
1050 12373459 : int ret;
1051 12373459 : unsigned int n_base, n_dn;
1052 :
1053 577865297 : if ( ! base || base->invalid) return 1;
1054 577865297 : if ( ! dn || dn->invalid) return -1;
1055 :
1056 577865297 : if (( ! base->valid_case) || ( ! dn->valid_case)) {
1057 398937530 : if (base->linearized && dn->linearized && dn->special == base->special) {
1058 : /* try with a normal compare first, if we are lucky
1059 : * we will avoid exploding and casefolding */
1060 6512193 : int dif;
1061 391284656 : dif = strlen(dn->linearized) - strlen(base->linearized);
1062 391284656 : if (dif < 0) {
1063 128216228 : return dif;
1064 : }
1065 260675053 : if (strcmp(base->linearized,
1066 260675053 : &dn->linearized[dif]) == 0) {
1067 150442347 : return 0;
1068 : }
1069 : }
1070 :
1071 114153850 : if ( ! ldb_dn_casefold_internal(base)) {
1072 0 : return 1;
1073 : }
1074 :
1075 114153850 : if ( ! ldb_dn_casefold_internal(dn)) {
1076 0 : return -1;
1077 : }
1078 :
1079 : }
1080 :
1081 : /* if base has more components,
1082 : * they don't have the same base */
1083 293081617 : if (base->comp_num > dn->comp_num) {
1084 55049042 : return (dn->comp_num - base->comp_num);
1085 : }
1086 :
1087 238032575 : if ((dn->comp_num == 0) || (base->comp_num == 0)) {
1088 1 : if (dn->special && base->special) {
1089 0 : return strcmp(base->linearized, dn->linearized);
1090 1 : } else if (dn->special) {
1091 0 : return -1;
1092 1 : } else if (base->special) {
1093 0 : return 1;
1094 : } else {
1095 0 : return 0;
1096 : }
1097 : }
1098 :
1099 238032574 : n_base = base->comp_num - 1;
1100 238032574 : n_dn = dn->comp_num - 1;
1101 :
1102 1118711367 : while (n_base != (unsigned int) -1) {
1103 1022457088 : char *b_name = base->components[n_base].cf_name;
1104 1022457088 : char *dn_name = dn->components[n_dn].cf_name;
1105 :
1106 1022457088 : char *b_vdata = (char *)base->components[n_base].cf_value.data;
1107 1022457088 : char *dn_vdata = (char *)dn->components[n_dn].cf_value.data;
1108 :
1109 1022457088 : size_t b_vlen = base->components[n_base].cf_value.length;
1110 1022457088 : size_t dn_vlen = dn->components[n_dn].cf_value.length;
1111 :
1112 : /* compare attr names */
1113 1022457088 : ret = strcmp(b_name, dn_name);
1114 1022457088 : if (ret != 0) return ret;
1115 :
1116 : /* compare attr.cf_value. */
1117 930106300 : if (b_vlen != dn_vlen) {
1118 47745133 : return NUMERIC_CMP(b_vlen, dn_vlen);
1119 : }
1120 882361167 : ret = strncmp(b_vdata, dn_vdata, b_vlen);
1121 882361167 : if (ret != 0) return ret;
1122 :
1123 880678793 : n_base--;
1124 880678793 : n_dn--;
1125 : }
1126 :
1127 92683698 : return 0;
1128 : }
1129 :
1130 : /* compare DNs using casefolding compare functions.
1131 :
1132 : If they match, then return 0
1133 : */
1134 :
1135 67617739 : int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1)
1136 : {
1137 4491657 : unsigned int i;
1138 4491657 : int ret;
1139 : /*
1140 : * If used in sort, we shift NULL and invalid DNs to the end.
1141 : *
1142 : * If ldb_dn_casefold_internal() fails, that goes to the end too, so
1143 : * we end up with:
1144 : *
1145 : * | normal DNs, sorted | casefold failed DNs | invalid DNs | NULLs |
1146 : */
1147 :
1148 67617739 : if (dn0 == dn1) {
1149 : /* this includes the both-NULL case */
1150 3060 : return 0;
1151 : }
1152 67614580 : if (dn0 == NULL) {
1153 0 : return 1;
1154 : }
1155 67614580 : if (dn1 == NULL) {
1156 0 : return -1;
1157 : }
1158 67614580 : if (dn0->invalid && dn1->invalid) {
1159 0 : return 0;
1160 : }
1161 67614580 : if (dn0->invalid) {
1162 2 : return 1;
1163 : }
1164 67614578 : if (dn1->invalid) {
1165 0 : return -1;
1166 : }
1167 :
1168 67614578 : if (( ! dn0->valid_case) || ( ! dn1->valid_case)) {
1169 9591005 : if (dn0->linearized && dn1->linearized) {
1170 : /* try with a normal compare first, if we are lucky
1171 : * we will avoid exploding and casefolding */
1172 7457630 : if (strcmp(dn0->linearized, dn1->linearized) == 0) {
1173 498320 : return 0;
1174 : }
1175 : }
1176 :
1177 9078630 : if ( ! ldb_dn_casefold_internal(dn0)) {
1178 0 : return 1;
1179 : }
1180 :
1181 9078630 : if ( ! ldb_dn_casefold_internal(dn1)) {
1182 736 : return -1;
1183 : }
1184 :
1185 : }
1186 :
1187 : /*
1188 : * Notice that for comp_num, Samba reverses the usual order of
1189 : * comparison. A DN with fewer components is greater than one
1190 : * with more.
1191 : */
1192 67101467 : if (dn0->comp_num > dn1->comp_num) {
1193 18244024 : return -1;
1194 46397535 : } else if (dn0->comp_num < dn1->comp_num) {
1195 19731211 : return 1;
1196 : }
1197 :
1198 25698699 : if (dn0->comp_num == 0) {
1199 1107079 : if (dn0->special && dn1->special) {
1200 1107079 : return strcmp(dn0->linearized, dn1->linearized);
1201 0 : } else if (dn0->special) {
1202 0 : return 1;
1203 0 : } else if (dn1->special) {
1204 0 : return -1;
1205 : } else {
1206 0 : return 0;
1207 : }
1208 : }
1209 :
1210 72269935 : for (i = 0; i < dn0->comp_num; i++) {
1211 61949132 : char *dn0_name = dn0->components[i].cf_name;
1212 61949132 : char *dn1_name = dn1->components[i].cf_name;
1213 :
1214 61949132 : char *dn0_vdata = (char *)dn0->components[i].cf_value.data;
1215 61949132 : char *dn1_vdata = (char *)dn1->components[i].cf_value.data;
1216 :
1217 61949132 : size_t dn0_vlen = dn0->components[i].cf_value.length;
1218 61949132 : size_t dn1_vlen = dn1->components[i].cf_value.length;
1219 :
1220 : /* compare attr names */
1221 61949132 : ret = strcmp(dn0_name, dn1_name);
1222 61949132 : if (ret != 0) {
1223 3406944 : return ret;
1224 : }
1225 :
1226 : /* compare attr.cf_value. */
1227 58542188 : if (dn0_vlen != dn1_vlen) {
1228 6105071 : return NUMERIC_CMP(dn0_vlen, dn1_vlen);
1229 : }
1230 52437117 : ret = strncmp(dn0_vdata, dn1_vdata, dn0_vlen);
1231 52437117 : if (ret != 0) {
1232 4758802 : return ret;
1233 : }
1234 : }
1235 :
1236 9781948 : return 0;
1237 : }
1238 :
1239 414572550 : static struct ldb_dn_component ldb_dn_copy_component(
1240 : TALLOC_CTX *mem_ctx,
1241 : struct ldb_dn_component *src)
1242 : {
1243 20889697 : struct ldb_dn_component dst;
1244 :
1245 414572550 : memset(&dst, 0, sizeof(dst));
1246 :
1247 414572550 : if (src == NULL) {
1248 0 : return dst;
1249 : }
1250 :
1251 414572550 : dst.value = ldb_val_dup(mem_ctx, &(src->value));
1252 414572550 : if (dst.value.data == NULL) {
1253 0 : return dst;
1254 : }
1255 :
1256 414572550 : dst.name = talloc_strdup(mem_ctx, src->name);
1257 414572550 : if (dst.name == NULL) {
1258 0 : LDB_FREE(dst.value.data);
1259 0 : return dst;
1260 : }
1261 :
1262 414572550 : if (src->cf_value.data) {
1263 344270471 : dst.cf_value = ldb_val_dup(mem_ctx, &(src->cf_value));
1264 344270471 : if (dst.cf_value.data == NULL) {
1265 0 : LDB_FREE(dst.value.data);
1266 0 : LDB_FREE(dst.name);
1267 0 : return dst;
1268 : }
1269 :
1270 344270471 : dst.cf_name = talloc_strdup(mem_ctx, src->cf_name);
1271 344270471 : if (dst.cf_name == NULL) {
1272 0 : LDB_FREE(dst.cf_name);
1273 0 : LDB_FREE(dst.value.data);
1274 0 : LDB_FREE(dst.name);
1275 0 : return dst;
1276 : }
1277 : } else {
1278 67208075 : dst.cf_value.data = NULL;
1279 67208075 : dst.cf_name = NULL;
1280 : }
1281 :
1282 414572550 : return dst;
1283 : }
1284 :
1285 32253366 : static struct ldb_dn_ext_component ldb_dn_ext_copy_component(
1286 : TALLOC_CTX *mem_ctx,
1287 : struct ldb_dn_ext_component *src)
1288 : {
1289 935203 : struct ldb_dn_ext_component dst;
1290 :
1291 32253366 : memset(&dst, 0, sizeof(dst));
1292 :
1293 32253366 : if (src == NULL) {
1294 0 : return dst;
1295 : }
1296 :
1297 32253366 : dst.value = ldb_val_dup(mem_ctx, &(src->value));
1298 32253366 : if (dst.value.data == NULL) {
1299 0 : return dst;
1300 : }
1301 :
1302 32253366 : dst.name = talloc_strdup(mem_ctx, src->name);
1303 32253366 : if (dst.name == NULL) {
1304 0 : LDB_FREE(dst.value.data);
1305 0 : return dst;
1306 : }
1307 :
1308 32253366 : return dst;
1309 : }
1310 :
1311 79057930 : struct ldb_dn *ldb_dn_copy(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
1312 : {
1313 3809486 : struct ldb_dn *new_dn;
1314 :
1315 79057930 : if (!dn || dn->invalid) {
1316 2 : return NULL;
1317 : }
1318 :
1319 79057928 : new_dn = talloc_zero(mem_ctx, struct ldb_dn);
1320 79057928 : if ( !new_dn) {
1321 0 : return NULL;
1322 : }
1323 :
1324 79057928 : *new_dn = *dn;
1325 :
1326 79057928 : if (dn->components) {
1327 3583526 : unsigned int i;
1328 :
1329 74021149 : new_dn->components =
1330 70437623 : talloc_zero_array(new_dn,
1331 : struct ldb_dn_component,
1332 : dn->comp_num);
1333 70437623 : if ( ! new_dn->components) {
1334 0 : talloc_free(new_dn);
1335 0 : return NULL;
1336 : }
1337 :
1338 469266758 : for (i = 0; i < dn->comp_num; i++) {
1339 398829135 : new_dn->components[i] =
1340 398829135 : ldb_dn_copy_component(new_dn->components,
1341 398829135 : &dn->components[i]);
1342 398829135 : if ( ! new_dn->components[i].value.data) {
1343 0 : talloc_free(new_dn);
1344 0 : return NULL;
1345 : }
1346 : }
1347 : }
1348 :
1349 79057928 : if (dn->ext_components) {
1350 803234 : unsigned int i;
1351 :
1352 26079314 : new_dn->ext_components =
1353 25276080 : talloc_zero_array(new_dn,
1354 : struct ldb_dn_ext_component,
1355 : dn->ext_comp_num);
1356 25276080 : if ( ! new_dn->ext_components) {
1357 0 : talloc_free(new_dn);
1358 0 : return NULL;
1359 : }
1360 :
1361 57529446 : for (i = 0; i < dn->ext_comp_num; i++) {
1362 32253366 : new_dn->ext_components[i] =
1363 32253366 : ldb_dn_ext_copy_component(
1364 32253366 : new_dn->ext_components,
1365 32253366 : &dn->ext_components[i]);
1366 32253366 : if ( ! new_dn->ext_components[i].value.data) {
1367 0 : talloc_free(new_dn);
1368 0 : return NULL;
1369 : }
1370 : }
1371 : }
1372 :
1373 79057928 : if (dn->casefold) {
1374 44912576 : new_dn->casefold = talloc_strdup(new_dn, dn->casefold);
1375 44912576 : if ( ! new_dn->casefold) {
1376 0 : talloc_free(new_dn);
1377 0 : return NULL;
1378 : }
1379 : }
1380 :
1381 79057928 : if (dn->linearized) {
1382 78912460 : new_dn->linearized = talloc_strdup(new_dn, dn->linearized);
1383 78912460 : if ( ! new_dn->linearized) {
1384 0 : talloc_free(new_dn);
1385 0 : return NULL;
1386 : }
1387 : }
1388 :
1389 79057928 : if (dn->ext_linearized) {
1390 2905868 : new_dn->ext_linearized = talloc_strdup(new_dn,
1391 1404505 : dn->ext_linearized);
1392 1501363 : if ( ! new_dn->ext_linearized) {
1393 0 : talloc_free(new_dn);
1394 0 : return NULL;
1395 : }
1396 : }
1397 :
1398 75248442 : return new_dn;
1399 : }
1400 :
1401 : /* modify the given dn by adding a base.
1402 : *
1403 : * return true if successful and false if not
1404 : * if false is returned the dn may be marked invalid
1405 : */
1406 629172 : bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base)
1407 : {
1408 4935 : const char *s;
1409 4935 : char *t;
1410 :
1411 629172 : if ( !base || base->invalid || !dn || dn->invalid) {
1412 0 : return false;
1413 : }
1414 :
1415 629172 : if (dn == base) {
1416 0 : return false; /* or we will visit infinity */
1417 : }
1418 :
1419 629172 : if (dn->components) {
1420 479 : unsigned int i;
1421 :
1422 455226 : if ( ! ldb_dn_validate(base)) {
1423 0 : return false;
1424 : }
1425 :
1426 455226 : s = NULL;
1427 455226 : if (dn->valid_case) {
1428 2 : if ( ! (s = ldb_dn_get_casefold(base))) {
1429 0 : return false;
1430 : }
1431 : }
1432 :
1433 455226 : dn->components = talloc_realloc(dn,
1434 : dn->components,
1435 : struct ldb_dn_component,
1436 : dn->comp_num + base->comp_num);
1437 455226 : if ( ! dn->components) {
1438 0 : ldb_dn_mark_invalid(dn);
1439 0 : return false;
1440 : }
1441 :
1442 2998448 : for (i = 0; i < base->comp_num; dn->comp_num++, i++) {
1443 2543222 : dn->components[dn->comp_num] =
1444 2543222 : ldb_dn_copy_component(dn->components,
1445 2543222 : &base->components[i]);
1446 2543222 : if (dn->components[dn->comp_num].value.data == NULL) {
1447 0 : ldb_dn_mark_invalid(dn);
1448 0 : return false;
1449 : }
1450 : }
1451 :
1452 455226 : if (dn->casefold && s) {
1453 0 : if (*dn->casefold) {
1454 0 : t = talloc_asprintf(dn, "%s,%s",
1455 : dn->casefold, s);
1456 : } else {
1457 0 : t = talloc_strdup(dn, s);
1458 : }
1459 0 : LDB_FREE(dn->casefold);
1460 0 : dn->casefold = t;
1461 : }
1462 : }
1463 :
1464 629172 : if (dn->linearized) {
1465 :
1466 176585 : s = ldb_dn_get_linearized(base);
1467 176585 : if ( ! s) {
1468 0 : return false;
1469 : }
1470 :
1471 176585 : if (*dn->linearized) {
1472 14534 : t = talloc_asprintf(dn, "%s,%s",
1473 : dn->linearized, s);
1474 : } else {
1475 162051 : t = talloc_strdup(dn, s);
1476 : }
1477 176585 : if ( ! t) {
1478 0 : ldb_dn_mark_invalid(dn);
1479 0 : return false;
1480 : }
1481 176585 : LDB_FREE(dn->linearized);
1482 176585 : dn->linearized = t;
1483 : }
1484 :
1485 : /* Wipe the ext_linearized DN,
1486 : * the GUID and SID are almost certainly no longer valid */
1487 629172 : LDB_FREE(dn->ext_linearized);
1488 629172 : LDB_FREE(dn->ext_components);
1489 629172 : dn->ext_comp_num = 0;
1490 :
1491 629172 : return true;
1492 : }
1493 :
1494 : /* modify the given dn by adding a base.
1495 : *
1496 : * return true if successful and false if not
1497 : * if false is returned the dn may be marked invalid
1498 : */
1499 2 : bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...)
1500 : {
1501 2 : struct ldb_dn *base;
1502 2 : char *base_str;
1503 2 : va_list ap;
1504 2 : bool ret;
1505 :
1506 2 : if ( !dn || dn->invalid) {
1507 0 : return false;
1508 : }
1509 :
1510 2 : va_start(ap, base_fmt);
1511 2 : base_str = talloc_vasprintf(dn, base_fmt, ap);
1512 2 : va_end(ap);
1513 :
1514 2 : if (base_str == NULL) {
1515 0 : return false;
1516 : }
1517 :
1518 2 : base = ldb_dn_new(base_str, dn->ldb, base_str);
1519 :
1520 2 : ret = ldb_dn_add_base(dn, base);
1521 :
1522 2 : talloc_free(base_str);
1523 :
1524 2 : return ret;
1525 : }
1526 :
1527 : /* modify the given dn by adding children elements.
1528 : *
1529 : * return true if successful and false if not
1530 : * if false is returned the dn may be marked invalid
1531 : */
1532 6767589 : bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child)
1533 : {
1534 369738 : const char *s;
1535 369738 : char *t;
1536 :
1537 6767589 : if ( !child || child->invalid || !dn || dn->invalid) {
1538 0 : return false;
1539 : }
1540 :
1541 6767589 : if (dn->components) {
1542 366047 : unsigned int n;
1543 366047 : unsigned int i, j;
1544 :
1545 6526465 : if (dn->comp_num == 0) {
1546 0 : return false;
1547 : }
1548 :
1549 6526465 : if ( ! ldb_dn_validate(child)) {
1550 0 : return false;
1551 : }
1552 :
1553 6526465 : s = NULL;
1554 6526465 : if (dn->valid_case) {
1555 4659463 : if ( ! (s = ldb_dn_get_casefold(child))) {
1556 0 : return false;
1557 : }
1558 : }
1559 :
1560 6526465 : n = dn->comp_num + child->comp_num;
1561 :
1562 6526465 : dn->components = talloc_realloc(dn,
1563 : dn->components,
1564 : struct ldb_dn_component,
1565 : n);
1566 6526465 : if ( ! dn->components) {
1567 0 : ldb_dn_mark_invalid(dn);
1568 0 : return false;
1569 : }
1570 :
1571 35246520 : for (i = dn->comp_num - 1, j = n - 1; i != (unsigned int) -1;
1572 28720055 : i--, j--) {
1573 28720055 : dn->components[j] = dn->components[i];
1574 : }
1575 :
1576 19081559 : for (i = 0; i < child->comp_num; i++) {
1577 12555094 : dn->components[i] =
1578 12555094 : ldb_dn_copy_component(dn->components,
1579 12555094 : &child->components[i]);
1580 12555094 : if (dn->components[i].value.data == NULL) {
1581 0 : ldb_dn_mark_invalid(dn);
1582 0 : return false;
1583 : }
1584 : }
1585 :
1586 6526465 : dn->comp_num = n;
1587 :
1588 6526465 : if (dn->casefold && s) {
1589 3391965 : t = talloc_asprintf(dn, "%s,%s", s, dn->casefold);
1590 3391965 : LDB_FREE(dn->casefold);
1591 3391965 : dn->casefold = t;
1592 : }
1593 : }
1594 :
1595 6767589 : if (dn->linearized) {
1596 6760501 : if (dn->linearized[0] == '\0') {
1597 0 : return false;
1598 : }
1599 :
1600 6760500 : s = ldb_dn_get_linearized(child);
1601 6760500 : if ( ! s) {
1602 0 : return false;
1603 : }
1604 :
1605 6760500 : t = talloc_asprintf(dn, "%s,%s", s, dn->linearized);
1606 6760500 : if ( ! t) {
1607 0 : ldb_dn_mark_invalid(dn);
1608 0 : return false;
1609 : }
1610 6760500 : LDB_FREE(dn->linearized);
1611 6760500 : dn->linearized = t;
1612 : }
1613 :
1614 : /* Wipe the ext_linearized DN,
1615 : * the GUID and SID are almost certainly no longer valid */
1616 6767588 : LDB_FREE(dn->ext_linearized);
1617 6767588 : LDB_FREE(dn->ext_components);
1618 6767588 : dn->ext_comp_num = 0;
1619 :
1620 6767588 : return true;
1621 : }
1622 :
1623 : /* modify the given dn by adding children elements.
1624 : *
1625 : * return true if successful and false if not
1626 : * if false is returned the dn may be marked invalid
1627 : */
1628 6566766 : bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...)
1629 : {
1630 368376 : struct ldb_dn *child;
1631 368376 : char *child_str;
1632 368376 : va_list ap;
1633 368376 : bool ret;
1634 :
1635 6566766 : if ( !dn || dn->invalid) {
1636 0 : return false;
1637 : }
1638 :
1639 6566766 : va_start(ap, child_fmt);
1640 6566766 : child_str = talloc_vasprintf(dn, child_fmt, ap);
1641 6566766 : va_end(ap);
1642 :
1643 6566766 : if (child_str == NULL) {
1644 0 : return false;
1645 : }
1646 :
1647 6566766 : child = ldb_dn_new(child_str, dn->ldb, child_str);
1648 :
1649 6566766 : ret = ldb_dn_add_child(dn, child);
1650 :
1651 6566766 : talloc_free(child_str);
1652 :
1653 6566766 : return ret;
1654 : }
1655 :
1656 : /* modify the given dn by adding a single child element.
1657 : *
1658 : * return true if successful and false if not
1659 : * if false is returned the dn may be marked invalid
1660 : */
1661 25522 : bool ldb_dn_add_child_val(struct ldb_dn *dn,
1662 : const char *rdn,
1663 : struct ldb_val value)
1664 : {
1665 10 : bool ret;
1666 10 : int ldb_ret;
1667 25522 : struct ldb_dn *child = NULL;
1668 :
1669 25522 : if ( !dn || dn->invalid) {
1670 0 : return false;
1671 : }
1672 :
1673 25522 : child = ldb_dn_new(dn, dn->ldb, "X=Y");
1674 25522 : ret = ldb_dn_add_child(dn, child);
1675 :
1676 25522 : if (ret == false) {
1677 0 : return false;
1678 : }
1679 :
1680 25522 : ldb_ret = ldb_dn_set_component(dn,
1681 : 0,
1682 : rdn,
1683 : value);
1684 25522 : if (ldb_ret != LDB_SUCCESS) {
1685 0 : return false;
1686 : }
1687 :
1688 25512 : return true;
1689 : }
1690 :
1691 603886 : bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num)
1692 : {
1693 454 : unsigned int i;
1694 :
1695 603886 : if ( ! ldb_dn_validate(dn)) {
1696 0 : return false;
1697 : }
1698 :
1699 603886 : if (dn->comp_num < num) {
1700 0 : return false;
1701 : }
1702 :
1703 : /* free components */
1704 3840056 : for (i = dn->comp_num - num; i < dn->comp_num; i++) {
1705 3236170 : LDB_FREE(dn->components[i].name);
1706 3236170 : LDB_FREE(dn->components[i].value.data);
1707 3236170 : LDB_FREE(dn->components[i].cf_name);
1708 3236170 : LDB_FREE(dn->components[i].cf_value.data);
1709 : }
1710 :
1711 603886 : dn->comp_num -= num;
1712 :
1713 603886 : if (dn->valid_case) {
1714 303213 : for (i = 0; i < dn->comp_num; i++) {
1715 151600 : LDB_FREE(dn->components[i].cf_name);
1716 151600 : LDB_FREE(dn->components[i].cf_value.data);
1717 : }
1718 151613 : dn->valid_case = false;
1719 : }
1720 :
1721 603886 : LDB_FREE(dn->casefold);
1722 603886 : LDB_FREE(dn->linearized);
1723 :
1724 : /* Wipe the ext_linearized DN,
1725 : * the GUID and SID are almost certainly no longer valid */
1726 603886 : LDB_FREE(dn->ext_linearized);
1727 603886 : LDB_FREE(dn->ext_components);
1728 603886 : dn->ext_comp_num = 0;
1729 :
1730 603886 : return true;
1731 : }
1732 :
1733 13026903 : bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num)
1734 : {
1735 785133 : unsigned int i, j;
1736 :
1737 13026903 : if ( ! ldb_dn_validate(dn)) {
1738 0 : return false;
1739 : }
1740 :
1741 13026903 : if (dn->comp_num < num) {
1742 1 : return false;
1743 : }
1744 :
1745 84243489 : for (i = 0, j = num; j < dn->comp_num; i++, j++) {
1746 71216587 : if (i < num) {
1747 13025592 : LDB_FREE(dn->components[i].name);
1748 13025592 : LDB_FREE(dn->components[i].value.data);
1749 13025592 : LDB_FREE(dn->components[i].cf_name);
1750 13025592 : LDB_FREE(dn->components[i].cf_value.data);
1751 : }
1752 71216587 : dn->components[i] = dn->components[j];
1753 : }
1754 :
1755 13026902 : dn->comp_num -= num;
1756 :
1757 13026902 : if (dn->valid_case) {
1758 61316188 : for (i = 0; i < dn->comp_num; i++) {
1759 51849733 : LDB_FREE(dn->components[i].cf_name);
1760 51849733 : LDB_FREE(dn->components[i].cf_value.data);
1761 : }
1762 9466455 : dn->valid_case = false;
1763 : }
1764 :
1765 13026902 : LDB_FREE(dn->casefold);
1766 13026902 : LDB_FREE(dn->linearized);
1767 :
1768 : /* Wipe the ext_linearized DN,
1769 : * the GUID and SID are almost certainly no longer valid */
1770 13026902 : LDB_FREE(dn->ext_linearized);
1771 13026902 : LDB_FREE(dn->ext_components);
1772 13026902 : dn->ext_comp_num = 0;
1773 :
1774 13026902 : return true;
1775 : }
1776 :
1777 :
1778 : /* replace the components of a DN with those from another DN, without
1779 : * touching the extended components
1780 : *
1781 : * return true if successful and false if not
1782 : * if false is returned the dn may be marked invalid
1783 : */
1784 129673 : bool ldb_dn_replace_components(struct ldb_dn *dn, struct ldb_dn *new_dn)
1785 : {
1786 1636 : unsigned int i;
1787 :
1788 129673 : if ( ! ldb_dn_validate(dn) || ! ldb_dn_validate(new_dn)) {
1789 0 : return false;
1790 : }
1791 :
1792 : /* free components */
1793 896816 : for (i = 0; i < dn->comp_num; i++) {
1794 767143 : LDB_FREE(dn->components[i].name);
1795 767143 : LDB_FREE(dn->components[i].value.data);
1796 767143 : LDB_FREE(dn->components[i].cf_name);
1797 767143 : LDB_FREE(dn->components[i].cf_value.data);
1798 : }
1799 :
1800 129673 : dn->components = talloc_realloc(dn,
1801 : dn->components,
1802 : struct ldb_dn_component,
1803 : new_dn->comp_num);
1804 129673 : if (dn->components == NULL) {
1805 0 : ldb_dn_mark_invalid(dn);
1806 0 : return false;
1807 : }
1808 :
1809 129673 : dn->comp_num = new_dn->comp_num;
1810 129673 : dn->valid_case = new_dn->valid_case;
1811 :
1812 774772 : for (i = 0; i < dn->comp_num; i++) {
1813 645099 : dn->components[i] = ldb_dn_copy_component(dn->components, &new_dn->components[i]);
1814 645099 : if (dn->components[i].name == NULL) {
1815 0 : ldb_dn_mark_invalid(dn);
1816 0 : return false;
1817 : }
1818 : }
1819 129673 : if (new_dn->linearized == NULL) {
1820 0 : dn->linearized = NULL;
1821 : } else {
1822 129673 : dn->linearized = talloc_strdup(dn, new_dn->linearized);
1823 129673 : if (dn->linearized == NULL) {
1824 0 : ldb_dn_mark_invalid(dn);
1825 0 : return false;
1826 : }
1827 : }
1828 :
1829 128037 : return true;
1830 : }
1831 :
1832 :
1833 13022505 : struct ldb_dn *ldb_dn_get_parent(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
1834 : {
1835 785103 : struct ldb_dn *new_dn;
1836 :
1837 13022505 : new_dn = ldb_dn_copy(mem_ctx, dn);
1838 13022505 : if ( !new_dn ) {
1839 2 : return NULL;
1840 : }
1841 :
1842 13022503 : if ( ! ldb_dn_remove_child_components(new_dn, 1)) {
1843 1 : talloc_free(new_dn);
1844 1 : return NULL;
1845 : }
1846 :
1847 12237399 : return new_dn;
1848 : }
1849 :
1850 : /* Create a 'canonical name' string from a DN:
1851 :
1852 : ie dc=samba,dc=org -> samba.org/
1853 : uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator
1854 :
1855 : There are two formats,
1856 : the EX format has the last '/' replaced with a newline (\n).
1857 :
1858 : */
1859 2660892 : static char *ldb_dn_canonical(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int ex_format) {
1860 152152 : unsigned int i;
1861 152152 : TALLOC_CTX *tmpctx;
1862 2660892 : char *cracked = NULL;
1863 2660892 : const char *format = (ex_format ? "\n" : "/" );
1864 :
1865 2660892 : if ( ! ldb_dn_validate(dn)) {
1866 0 : return NULL;
1867 : }
1868 :
1869 2660892 : tmpctx = talloc_new(mem_ctx);
1870 :
1871 : /* Walk backwards down the DN, grabbing 'dc' components at first */
1872 11550723 : for (i = dn->comp_num - 1; i != (unsigned int) -1; i--) {
1873 11255672 : if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) {
1874 2222842 : break;
1875 : }
1876 8889831 : if (cracked) {
1877 6229077 : cracked = talloc_asprintf(tmpctx, "%s.%s",
1878 : ldb_dn_escape_value(tmpctx,
1879 5902819 : dn->components[i].value),
1880 : cracked);
1881 : } else {
1882 2660754 : cracked = ldb_dn_escape_value(tmpctx,
1883 2508736 : dn->components[i].value);
1884 : }
1885 8889831 : if (!cracked) {
1886 0 : goto done;
1887 : }
1888 : }
1889 :
1890 : /* Only domain components? Finish here */
1891 2660892 : if (i == (unsigned int) -1) {
1892 295051 : cracked = talloc_strdup_append_buffer(cracked, format);
1893 295051 : talloc_steal(mem_ctx, cracked);
1894 295051 : goto done;
1895 : }
1896 :
1897 : /* Now walk backwards appending remaining components */
1898 6508651 : for (; i > 0; i--) {
1899 4142810 : cracked = talloc_asprintf_append_buffer(cracked, "/%s",
1900 : ldb_dn_escape_value(tmpctx,
1901 4142810 : dn->components[i].value));
1902 4142810 : if (!cracked) {
1903 0 : goto done;
1904 : }
1905 : }
1906 :
1907 : /* Last one, possibly a newline for the 'ex' format */
1908 2365841 : cracked = talloc_asprintf_append_buffer(cracked, "%s%s", format,
1909 : ldb_dn_escape_value(tmpctx,
1910 2365841 : dn->components[i].value));
1911 :
1912 2365841 : talloc_steal(mem_ctx, cracked);
1913 2660892 : done:
1914 2660892 : talloc_free(tmpctx);
1915 2660892 : return cracked;
1916 : }
1917 :
1918 : /* Wrapper functions for the above, for the two different string formats */
1919 2660629 : char *ldb_dn_canonical_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) {
1920 2660629 : return ldb_dn_canonical(mem_ctx, dn, 0);
1921 :
1922 : }
1923 :
1924 263 : char *ldb_dn_canonical_ex_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) {
1925 263 : return ldb_dn_canonical(mem_ctx, dn, 1);
1926 : }
1927 :
1928 26256457 : int ldb_dn_get_comp_num(struct ldb_dn *dn)
1929 : {
1930 26256457 : if ( ! ldb_dn_validate(dn)) {
1931 176 : return -1;
1932 : }
1933 26256277 : return dn->comp_num;
1934 : }
1935 :
1936 14791948 : int ldb_dn_get_extended_comp_num(struct ldb_dn *dn)
1937 : {
1938 14791948 : if ( ! ldb_dn_validate(dn)) {
1939 176 : return -1;
1940 : }
1941 14791768 : return dn->ext_comp_num;
1942 : }
1943 :
1944 9145 : const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num)
1945 : {
1946 9145 : if ( ! ldb_dn_validate(dn)) {
1947 0 : return NULL;
1948 : }
1949 9145 : if (num >= dn->comp_num) return NULL;
1950 9137 : return dn->components[num].name;
1951 : }
1952 :
1953 600160 : const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn,
1954 : unsigned int num)
1955 : {
1956 600160 : if ( ! ldb_dn_validate(dn)) {
1957 0 : return NULL;
1958 : }
1959 600160 : if (num >= dn->comp_num) return NULL;
1960 600160 : return &dn->components[num].value;
1961 : }
1962 :
1963 70576582 : const char *ldb_dn_get_rdn_name(struct ldb_dn *dn)
1964 : {
1965 70576582 : if ( ! ldb_dn_validate(dn)) {
1966 0 : return NULL;
1967 : }
1968 70576582 : if (dn->comp_num == 0) return NULL;
1969 56669130 : return dn->components[0].name;
1970 : }
1971 :
1972 56364007 : const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn)
1973 : {
1974 56364007 : if ( ! ldb_dn_validate(dn)) {
1975 2 : return NULL;
1976 : }
1977 56364005 : if (dn->comp_num == 0) return NULL;
1978 42456553 : return &dn->components[0].value;
1979 : }
1980 :
1981 1227653 : int ldb_dn_set_component(struct ldb_dn *dn, int num,
1982 : const char *name, const struct ldb_val val)
1983 : {
1984 156832 : char *n;
1985 156832 : struct ldb_val v;
1986 :
1987 1227653 : if ( ! ldb_dn_validate(dn)) {
1988 0 : return LDB_ERR_OTHER;
1989 : }
1990 :
1991 1227653 : if (num < 0) {
1992 0 : return LDB_ERR_OTHER;
1993 : }
1994 :
1995 1227653 : if ((unsigned)num >= dn->comp_num) {
1996 2 : return LDB_ERR_OTHER;
1997 : }
1998 :
1999 1227651 : if (val.length > val.length + 1) {
2000 0 : return LDB_ERR_OTHER;
2001 : }
2002 :
2003 1227651 : n = talloc_strdup(dn, name);
2004 1227651 : if ( ! n) {
2005 0 : return LDB_ERR_OTHER;
2006 : }
2007 :
2008 1227651 : v.length = val.length;
2009 :
2010 : /*
2011 : * This is like talloc_memdup(dn, v.data, v.length + 1), but
2012 : * avoids the over-read
2013 : */
2014 1227651 : v.data = (uint8_t *)talloc_size(dn, v.length+1);
2015 1227651 : if ( ! v.data) {
2016 0 : talloc_free(n);
2017 0 : return LDB_ERR_OTHER;
2018 : }
2019 1227651 : memcpy(v.data, val.data, val.length);
2020 :
2021 : /*
2022 : * Enforce NUL termination outside the stated length, as is
2023 : * traditional in LDB
2024 : */
2025 1227651 : v.data[v.length] = '\0';
2026 :
2027 1227651 : talloc_free(dn->components[num].name);
2028 1227651 : talloc_free(dn->components[num].value.data);
2029 1227651 : dn->components[num].name = n;
2030 1227651 : dn->components[num].value = v;
2031 :
2032 1227651 : if (dn->valid_case) {
2033 : unsigned int i;
2034 4942671 : for (i = 0; i < dn->comp_num; i++) {
2035 4270899 : LDB_FREE(dn->components[i].cf_name);
2036 4270899 : LDB_FREE(dn->components[i].cf_value.data);
2037 : }
2038 671772 : dn->valid_case = false;
2039 : }
2040 1227651 : LDB_FREE(dn->casefold);
2041 1227651 : LDB_FREE(dn->linearized);
2042 :
2043 : /* Wipe the ext_linearized DN,
2044 : * the GUID and SID are almost certainly no longer valid */
2045 1227651 : LDB_FREE(dn->ext_linearized);
2046 1227651 : LDB_FREE(dn->ext_components);
2047 1227651 : dn->ext_comp_num = 0;
2048 :
2049 1227651 : return LDB_SUCCESS;
2050 : }
2051 :
2052 258575068 : const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn,
2053 : const char *name)
2054 : {
2055 6820075 : unsigned int i;
2056 258575068 : if ( ! ldb_dn_validate(dn)) {
2057 710 : return NULL;
2058 : }
2059 323562933 : for (i=0; i < dn->ext_comp_num; i++) {
2060 129089138 : if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) {
2061 64100563 : return &dn->ext_components[i].value;
2062 : }
2063 : }
2064 189321874 : return NULL;
2065 : }
2066 :
2067 157702994 : int ldb_dn_set_extended_component(struct ldb_dn *dn,
2068 : const char *name, const struct ldb_val *val)
2069 : {
2070 3756199 : struct ldb_dn_ext_component *p;
2071 3756199 : unsigned int i;
2072 3756199 : struct ldb_val v2;
2073 3756199 : const struct ldb_dn_extended_syntax *ext_syntax;
2074 :
2075 157702994 : if ( ! ldb_dn_validate(dn)) {
2076 0 : return LDB_ERR_OTHER;
2077 : }
2078 :
2079 157702994 : ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name);
2080 157702994 : if (ext_syntax == NULL) {
2081 : /* We don't know how to handle this type of thing */
2082 0 : return LDB_ERR_INVALID_DN_SYNTAX;
2083 : }
2084 :
2085 249745845 : for (i=0; i < dn->ext_comp_num; i++) {
2086 92053587 : if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) {
2087 10736 : if (val) {
2088 10736 : dn->ext_components[i].value =
2089 10736 : ldb_val_dup(dn->ext_components, val);
2090 :
2091 10736 : dn->ext_components[i].name = ext_syntax->name;
2092 10736 : if (!dn->ext_components[i].value.data) {
2093 0 : ldb_dn_mark_invalid(dn);
2094 0 : return LDB_ERR_OPERATIONS_ERROR;
2095 : }
2096 : } else {
2097 0 : ARRAY_DEL_ELEMENT(
2098 : dn->ext_components,
2099 : i,
2100 0 : dn->ext_comp_num);
2101 0 : dn->ext_comp_num--;
2102 :
2103 0 : dn->ext_components = talloc_realloc(dn,
2104 : dn->ext_components,
2105 : struct ldb_dn_ext_component,
2106 : dn->ext_comp_num);
2107 0 : if (!dn->ext_components) {
2108 0 : ldb_dn_mark_invalid(dn);
2109 0 : return LDB_ERR_OPERATIONS_ERROR;
2110 : }
2111 : }
2112 10736 : LDB_FREE(dn->ext_linearized);
2113 :
2114 10736 : return LDB_SUCCESS;
2115 : }
2116 : }
2117 :
2118 157692258 : if (val == NULL) {
2119 : /* removing a value that doesn't exist is not an error */
2120 0 : return LDB_SUCCESS;
2121 : }
2122 :
2123 157692258 : v2 = *val;
2124 :
2125 161448397 : p = dn->ext_components
2126 157692258 : = talloc_realloc(dn,
2127 : dn->ext_components,
2128 : struct ldb_dn_ext_component,
2129 : dn->ext_comp_num + 1);
2130 157692258 : if (!dn->ext_components) {
2131 0 : ldb_dn_mark_invalid(dn);
2132 0 : return LDB_ERR_OPERATIONS_ERROR;
2133 : }
2134 :
2135 157692258 : p[dn->ext_comp_num].value = ldb_val_dup(dn->ext_components, &v2);
2136 157692258 : p[dn->ext_comp_num].name = talloc_strdup(p, name);
2137 :
2138 157692258 : if (!dn->ext_components[i].name || !dn->ext_components[i].value.data) {
2139 0 : ldb_dn_mark_invalid(dn);
2140 0 : return LDB_ERR_OPERATIONS_ERROR;
2141 : }
2142 157692258 : dn->ext_components = p;
2143 157692258 : dn->ext_comp_num++;
2144 :
2145 157692258 : LDB_FREE(dn->ext_linearized);
2146 :
2147 153936119 : return LDB_SUCCESS;
2148 : }
2149 :
2150 46042406 : void ldb_dn_remove_extended_components(struct ldb_dn *dn)
2151 : {
2152 46042406 : LDB_FREE(dn->ext_linearized);
2153 46042406 : LDB_FREE(dn->ext_components);
2154 46042406 : dn->ext_comp_num = 0;
2155 46042406 : }
2156 :
2157 4504 : bool ldb_dn_is_valid(struct ldb_dn *dn)
2158 : {
2159 4504 : if ( ! dn) return false;
2160 4504 : return ! dn->invalid;
2161 : }
2162 :
2163 1865619000 : bool ldb_dn_is_special(struct ldb_dn *dn)
2164 : {
2165 1865619000 : if ( ! dn || dn->invalid) return false;
2166 1865618999 : return dn->special;
2167 : }
2168 :
2169 462967751 : bool ldb_dn_has_extended(struct ldb_dn *dn)
2170 : {
2171 462967751 : if ( ! dn || dn->invalid) return false;
2172 462967751 : if (dn->ext_linearized && (dn->ext_linearized[0] == '<')) return true;
2173 448071327 : return dn->ext_comp_num != 0;
2174 : }
2175 :
2176 15745040 : bool ldb_dn_check_special(struct ldb_dn *dn, const char *check)
2177 : {
2178 15745040 : if ( ! dn || dn->invalid) return false;
2179 15745040 : return ! strcmp(dn->linearized, check);
2180 : }
2181 :
2182 399233297 : bool ldb_dn_is_null(struct ldb_dn *dn)
2183 : {
2184 399233297 : if ( ! dn || dn->invalid) return false;
2185 399233297 : if (ldb_dn_has_extended(dn)) return false;
2186 346429546 : if (dn->linearized && (dn->linearized[0] == '\0')) return true;
2187 309298945 : return false;
2188 : }
2189 :
2190 : /*
2191 : this updates dn->components, taking the components from ref_dn.
2192 : This is used by code that wants to update the DN path of a DN
2193 : while not impacting on the extended DN components
2194 : */
2195 11009 : int ldb_dn_update_components(struct ldb_dn *dn, const struct ldb_dn *ref_dn)
2196 : {
2197 11009 : dn->components = talloc_realloc(dn, dn->components,
2198 : struct ldb_dn_component, ref_dn->comp_num);
2199 11009 : if (!dn->components) {
2200 0 : return LDB_ERR_OPERATIONS_ERROR;
2201 : }
2202 11009 : memcpy(dn->components, ref_dn->components,
2203 11009 : sizeof(struct ldb_dn_component)*ref_dn->comp_num);
2204 11009 : dn->comp_num = ref_dn->comp_num;
2205 :
2206 11009 : LDB_FREE(dn->casefold);
2207 11009 : LDB_FREE(dn->linearized);
2208 11009 : LDB_FREE(dn->ext_linearized);
2209 :
2210 10956 : return LDB_SUCCESS;
2211 : }
2212 :
2213 : /*
2214 : minimise a DN. The caller must pass in a validated DN.
2215 :
2216 : If the DN has an extended component then only the first extended
2217 : component is kept, the DN string is stripped.
2218 :
2219 : The existing dn is modified
2220 : */
2221 8073355 : bool ldb_dn_minimise(struct ldb_dn *dn)
2222 : {
2223 292787 : unsigned int i;
2224 :
2225 8073355 : if (!ldb_dn_validate(dn)) {
2226 0 : return false;
2227 : }
2228 8073355 : if (dn->ext_comp_num == 0) {
2229 0 : return true;
2230 : }
2231 :
2232 : /* free components */
2233 41337708 : for (i = 0; i < dn->comp_num; i++) {
2234 33264353 : LDB_FREE(dn->components[i].name);
2235 33264353 : LDB_FREE(dn->components[i].value.data);
2236 33264353 : LDB_FREE(dn->components[i].cf_name);
2237 33264353 : LDB_FREE(dn->components[i].cf_value.data);
2238 : }
2239 8073355 : dn->comp_num = 0;
2240 8073355 : dn->valid_case = false;
2241 :
2242 8073355 : LDB_FREE(dn->casefold);
2243 8073355 : LDB_FREE(dn->linearized);
2244 :
2245 : /* note that we don't free dn->components as this there are
2246 : * several places in ldb_dn.c that rely on it being non-NULL
2247 : * for an exploded DN
2248 : */
2249 :
2250 11485747 : for (i = 1; i < dn->ext_comp_num; i++) {
2251 3412392 : LDB_FREE(dn->ext_components[i].value.data);
2252 : }
2253 8073355 : dn->ext_comp_num = 1;
2254 :
2255 8073355 : dn->ext_components = talloc_realloc(dn, dn->ext_components, struct ldb_dn_ext_component, 1);
2256 8073355 : if (dn->ext_components == NULL) {
2257 0 : ldb_dn_mark_invalid(dn);
2258 0 : return false;
2259 : }
2260 :
2261 8073355 : LDB_FREE(dn->ext_linearized);
2262 :
2263 7780568 : return true;
2264 : }
2265 :
2266 155969315 : struct ldb_context *ldb_dn_get_ldb_context(struct ldb_dn *dn)
2267 : {
2268 155969315 : return dn->ldb;
2269 : }
|