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) do { talloc_free(x); x = NULL; } while(0)
42 :
43 : /**
44 : internal ldb exploded dn structures
45 : */
46 : struct ldb_dn_component {
47 :
48 : char *name;
49 : struct ldb_val value;
50 :
51 : char *cf_name;
52 : struct ldb_val cf_value;
53 : };
54 :
55 : struct ldb_dn_ext_component {
56 :
57 : 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 17909 : static void ldb_dn_mark_invalid(struct ldb_dn *dn)
84 : {
85 17909 : dn->invalid = true;
86 17909 : }
87 :
88 : /* strdn may be NULL */
89 609678361 : 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 : struct ldb_dn *dn;
94 :
95 609678361 : if (ldb == NULL || strdn == NULL) {
96 0 : return NULL;
97 : }
98 609678361 : if (strdn->data
99 589777855 : && (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 609678361 : dn = talloc_zero(mem_ctx, struct ldb_dn);
105 609678361 : LDB_DN_NULL_FAILED(dn);
106 :
107 609678361 : dn->ldb = talloc_get_type(ldb, struct ldb_context);
108 609678361 : 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 1198752467 : if (strdn->data && strdn->length) {
116 589074106 : const char *data = (const char *)strdn->data;
117 589074106 : size_t length = strdn->length;
118 :
119 589074106 : if (data[0] == '@') {
120 261539470 : dn->special = true;
121 : }
122 589074106 : dn->ext_linearized = talloc_strndup(dn, data, length);
123 589074106 : LDB_DN_NULL_FAILED(dn->ext_linearized);
124 :
125 589074106 : if (data[0] == '<') {
126 28089440 : const char *p_save, *p = dn->ext_linearized;
127 : do {
128 64706477 : p_save = p;
129 64706477 : p = strstr(p, ">;");
130 64706477 : if (p) {
131 36617037 : p = p + 2;
132 : }
133 64706477 : } while (p);
134 :
135 28089440 : if (p_save == dn->ext_linearized) {
136 6080893 : dn->linearized = talloc_strdup(dn, "");
137 : } else {
138 22008547 : dn->linearized = talloc_strdup(dn, p_save);
139 : }
140 28089440 : LDB_DN_NULL_FAILED(dn->linearized);
141 : } else {
142 560984666 : dn->linearized = dn->ext_linearized;
143 560984666 : dn->ext_linearized = NULL;
144 : }
145 : } else {
146 20604255 : dn->linearized = talloc_strdup(dn, "");
147 20604255 : LDB_DN_NULL_FAILED(dn->linearized);
148 : }
149 :
150 609678361 : return dn;
151 :
152 0 : failed:
153 0 : talloc_free(dn);
154 0 : return NULL;
155 : }
156 :
157 : /* strdn may be NULL */
158 224186264 : struct ldb_dn *ldb_dn_new(TALLOC_CTX *mem_ctx,
159 : struct ldb_context *ldb,
160 : const char *strdn)
161 : {
162 : struct ldb_val blob;
163 224186264 : blob.data = discard_const_p(uint8_t, strdn);
164 224186264 : blob.length = strdn ? strlen(strdn) : 0;
165 224186264 : return ldb_dn_from_ldb_val(mem_ctx, ldb, &blob);
166 : }
167 :
168 137108553 : struct ldb_dn *ldb_dn_new_fmt(TALLOC_CTX *mem_ctx,
169 : struct ldb_context *ldb,
170 : const char *new_fmt, ...)
171 : {
172 : char *strdn;
173 : va_list ap;
174 :
175 137108553 : if (! ldb) return NULL;
176 :
177 137108553 : va_start(ap, new_fmt);
178 137108553 : strdn = talloc_vasprintf(mem_ctx, new_fmt, ap);
179 137108553 : va_end(ap);
180 :
181 137108553 : if (strdn) {
182 137108553 : struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb, strdn);
183 137108553 : talloc_free(strdn);
184 137108553 : return dn;
185 : }
186 :
187 0 : return NULL;
188 : }
189 :
190 : /* see RFC2253 section 2.4 */
191 167649272 : static int ldb_dn_escape_internal(char *dst, const char *src, int len)
192 : {
193 : char c;
194 : char *d;
195 : int i;
196 167649272 : d = dst;
197 :
198 1606739308 : for (i = 0; i < len; i++){
199 1439090036 : c = src[i];
200 1439090036 : switch (c) {
201 8363277 : case ' ':
202 8363277 : 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 8363277 : *d++ = c;
210 : }
211 8363277 : break;
212 :
213 18225 : 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 18225 : *d++ = '\\';
225 18225 : *d++ = c;
226 18225 : break;
227 :
228 1108965 : case ';':
229 : case '\r':
230 : case '\n':
231 : case '=':
232 : case '\0': {
233 : /* any others get \XX form */
234 : unsigned char v;
235 1108965 : const char *hexbytes = "0123456789ABCDEF";
236 1108965 : v = (const unsigned char)c;
237 1108965 : *d++ = '\\';
238 1108965 : *d++ = hexbytes[v>>4];
239 1108965 : *d++ = hexbytes[v&0xF];
240 1108965 : break;
241 : }
242 1429599569 : default:
243 1429599569 : *d++ = c;
244 : }
245 : }
246 :
247 : /* return the length of the resulting string */
248 167649272 : return (d - dst);
249 : }
250 :
251 10473883 : char *ldb_dn_escape_value(TALLOC_CTX *mem_ctx, struct ldb_val value)
252 : {
253 : char *dst;
254 : size_t len;
255 10473883 : if (!value.length)
256 2 : return NULL;
257 :
258 : /* allocate destination string, it will be at most 3 times the source */
259 10473881 : dst = talloc_array(mem_ctx, char, value.length * 3 + 1);
260 10473881 : if ( ! dst) {
261 0 : talloc_free(dst);
262 0 : return NULL;
263 : }
264 :
265 10473881 : len = ldb_dn_escape_internal(dst, (const char *)value.data, value.length);
266 :
267 10473881 : dst = talloc_realloc(mem_ctx, dst, char, len + 1);
268 10473881 : if ( ! dst) {
269 0 : talloc_free(dst);
270 0 : return NULL;
271 : }
272 10473881 : dst[len] = '\0';
273 10473881 : 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 797038089 : static bool ldb_dn_explode(struct ldb_dn *dn)
284 : {
285 797038089 : char *p, *ex_name = NULL, *ex_value = NULL, *data, *d, *dt, *t;
286 797038089 : bool trim = true;
287 797038089 : bool in_extended = true;
288 797038089 : bool in_ex_name = false;
289 797038089 : bool in_ex_value = false;
290 797038089 : bool in_attr = false;
291 797038089 : bool in_value = false;
292 797038089 : bool in_quote = false;
293 797038089 : bool is_oid = false;
294 797038089 : bool escape = false;
295 : unsigned int x;
296 797038089 : size_t l = 0;
297 : int ret;
298 : char *parse_dn;
299 : bool is_index;
300 :
301 797038089 : if (dn == NULL || dn->invalid) {
302 11 : return false;
303 : }
304 :
305 797038078 : if (dn->components != NULL) {
306 423216730 : return true;
307 : }
308 :
309 373821348 : if (dn->ext_linearized != NULL) {
310 25705570 : parse_dn = dn->ext_linearized;
311 : } else {
312 348115778 : parse_dn = dn->linearized;
313 : }
314 :
315 373821348 : if (parse_dn == NULL) {
316 0 : return false;
317 : }
318 :
319 373821348 : is_index = (strncmp(parse_dn, "DN=@INDEX:", 10) == 0);
320 :
321 : /* Empty DNs */
322 373821348 : if (parse_dn[0] == '\0') {
323 20166009 : return true;
324 : }
325 :
326 : /* Special DNs case */
327 353655339 : if (dn->special) {
328 168008531 : return true;
329 : }
330 :
331 185646808 : LDB_FREE(dn->ext_components);
332 185646808 : dn->ext_comp_num = 0;
333 185646808 : 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 185646808 : dn->components = talloc_zero_array(dn, struct ldb_dn_component, 3);
338 185646808 : if (dn->components == NULL) {
339 0 : return false;
340 : }
341 :
342 : /* Components data space is allocated here once */
343 185646808 : data = talloc_array(dn->components, char, strlen(parse_dn) + 1);
344 185646808 : if (data == NULL) {
345 0 : goto failed;
346 : }
347 :
348 185646808 : p = parse_dn;
349 185646808 : t = NULL;
350 185646808 : d = dt = data;
351 :
352 17719616754 : while (*p) {
353 17398698654 : if (in_extended) {
354 :
355 1756882661 : if (!in_ex_name && !in_ex_value) {
356 :
357 218845512 : if (p[0] == '<') {
358 39279609 : p++;
359 39279609 : ex_name = d;
360 39279609 : in_ex_name = true;
361 39279609 : continue;
362 : } else {
363 179565903 : in_extended = false;
364 179565903 : in_attr = true;
365 179565903 : dt = d;
366 :
367 179565903 : continue;
368 : }
369 : }
370 :
371 1538037149 : if (in_ex_name && *p == '=') {
372 39279605 : *d++ = '\0';
373 39279605 : p++;
374 39279605 : ex_value = d;
375 39279605 : in_ex_name = false;
376 39279605 : in_ex_value = true;
377 39279605 : continue;
378 : }
379 :
380 1498757544 : if (in_ex_value && *p == '>') {
381 39279605 : struct ldb_dn_ext_component *ext_comp = NULL;
382 : const struct ldb_dn_extended_syntax *ext_syntax;
383 74935180 : struct ldb_val ex_val = {
384 : .data = (uint8_t *)ex_value,
385 39279605 : .length = d - ex_value
386 : };
387 :
388 39279605 : *d++ = '\0';
389 39279605 : p++;
390 39279605 : in_ex_value = false;
391 :
392 : /* Process name and ex_value */
393 :
394 39279605 : ext_comp = talloc_realloc(
395 : dn,
396 : dn->ext_components,
397 : struct ldb_dn_ext_component,
398 : dn->ext_comp_num + 1);
399 :
400 39279605 : if (ext_comp == NULL) {
401 : /* ouch ! */
402 10 : goto failed;
403 : }
404 :
405 39279605 : dn->ext_components = ext_comp;
406 :
407 39279605 : ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, ex_name);
408 39279605 : if (ext_syntax == NULL) {
409 : /* We don't know about this type of extended DN */
410 8 : goto failed;
411 : }
412 :
413 39279597 : dn->ext_components[dn->ext_comp_num].name = ext_syntax->name;
414 74935164 : ret = ext_syntax->read_fn(dn->ldb, dn->ext_components,
415 39279597 : &ex_val, &dn->ext_components[dn->ext_comp_num].value);
416 39279597 : if (ret != LDB_SUCCESS) {
417 2 : ldb_dn_mark_invalid(dn);
418 2 : goto failed;
419 : }
420 :
421 39279595 : dn->ext_comp_num++;
422 :
423 39279595 : if (*p == '\0') {
424 : /* We have reached the end (extended component only)! */
425 6080891 : talloc_free(data);
426 6080891 : return true;
427 :
428 33198704 : } else if (*p == ';') {
429 33198704 : p++;
430 33198704 : continue;
431 : } else {
432 0 : ldb_dn_mark_invalid(dn);
433 0 : goto failed;
434 : }
435 : }
436 :
437 1459477939 : *d++ = *p++;
438 1459477939 : continue;
439 : }
440 15641815993 : if (in_attr) {
441 3087976995 : if (trim) {
442 1028682450 : if (*p == ' ') {
443 219 : p++;
444 219 : continue;
445 : }
446 :
447 : /* first char */
448 1028682231 : trim = false;
449 :
450 1028682231 : if (!isascii(*p)) {
451 : /* attr names must be ascii only */
452 0 : ldb_dn_mark_invalid(dn);
453 0 : goto failed;
454 : }
455 :
456 1028682231 : if (isdigit(*p)) {
457 0 : is_oid = true;
458 : } else
459 1028682231 : 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 1028682224 : *d++ = *p++;
469 1028682224 : continue;
470 : }
471 :
472 2059294545 : if (*p == ' ') {
473 48 : p++;
474 : /* valid only if we are at the end */
475 48 : trim = true;
476 48 : continue;
477 : }
478 :
479 2059294497 : if (*p == '=') {
480 : /* attribute terminated */
481 1028664284 : in_attr = false;
482 1028664284 : in_value = true;
483 1028664284 : trim = true;
484 1028664284 : l = 0;
485 :
486 : /* Terminate this string in d
487 : * (which is a copy of parse_dn
488 : * with spaces trimmed) */
489 1028664284 : *d++ = '\0';
490 1028664284 : dn->components[dn->comp_num].name = talloc_strdup(dn->components, dt);
491 1028664284 : if (dn->components[dn->comp_num].name == NULL) {
492 : /* ouch */
493 0 : goto failed;
494 : }
495 :
496 1028664284 : dt = d;
497 :
498 1028664284 : p++;
499 1028664284 : continue;
500 : }
501 :
502 1030630213 : if (!isascii(*p)) {
503 : /* attr names must be ascii only */
504 0 : ldb_dn_mark_invalid(dn);
505 0 : goto failed;
506 : }
507 :
508 1030630213 : 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 1030630213 : if ( ! (isalpha(*p) || isdigit(*p) || (*p == '-'))) {
515 : /* not ALPHA, DIGIT or HYPHEN */
516 409 : ldb_dn_mark_invalid(dn);
517 409 : goto failed;
518 : }
519 :
520 1030629804 : *d++ = *p++;
521 1030629804 : continue;
522 : }
523 :
524 12553838998 : if (in_value) {
525 12553838998 : 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 12553838998 : if (trim) {
539 1028664276 : if (*p == ' ') {
540 0 : p++;
541 0 : continue;
542 : }
543 :
544 : /* first char */
545 1028664276 : trim = false;
546 :
547 1028664276 : if (*p == '\"') {
548 0 : in_quote = true;
549 0 : p++;
550 0 : continue;
551 : }
552 : }
553 :
554 12553838998 : switch (*p) {
555 :
556 : /* TODO: support ber encoded values
557 : case '#':
558 : */
559 :
560 849133788 : case ',':
561 849133788 : if (escape) {
562 17507 : *d++ = *p++;
563 17507 : l++;
564 17507 : escape = false;
565 17507 : continue;
566 : }
567 : /* ok found value terminator */
568 :
569 849116281 : if (t != NULL) {
570 : /* trim back */
571 22 : d -= (p - t);
572 22 : l -= (p - t);
573 22 : t = NULL;
574 : }
575 :
576 849116281 : in_attr = true;
577 849116281 : in_value = false;
578 849116281 : trim = true;
579 :
580 849116281 : p++;
581 849116281 : *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 1698232562 : dn->components[dn->comp_num].value.data = \
589 1500907046 : (uint8_t *)talloc_memdup(dn->components, dt, l + 1);
590 849116281 : dn->components[dn->comp_num].value.length = l;
591 849116281 : if (dn->components[dn->comp_num].value.data == NULL) {
592 : /* ouch ! */
593 0 : goto failed;
594 : }
595 849116281 : talloc_set_name_const(dn->components[dn->comp_num].value.data,
596 849116281 : (const char *)dn->components[dn->comp_num].value.data);
597 :
598 849116281 : dt = d;
599 :
600 849116281 : dn->comp_num++;
601 849116281 : if (dn->comp_num > 2) {
602 495739729 : dn->components = talloc_realloc(dn,
603 : dn->components,
604 : struct ldb_dn_component,
605 : dn->comp_num + 1);
606 495739729 : if (dn->components == NULL) {
607 : /* ouch ! */
608 0 : goto failed;
609 : }
610 : /* make sure all components are zeroed, other functions depend on this */
611 495739729 : memset(&dn->components[dn->comp_num], '\0', sizeof(struct ldb_dn_component));
612 : }
613 :
614 849116281 : 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 : FALL_THROUGH;
633 : case '\"':
634 : case '<':
635 : case '>':
636 : case ';':
637 : /* a string with not escaped specials is invalid (tested) */
638 14 : if (!escape) {
639 7 : ldb_dn_mark_invalid(dn);
640 7 : goto failed;
641 : }
642 7 : escape = false;
643 :
644 7 : *d++ = *p++;
645 7 : l++;
646 :
647 7 : if (t != NULL) {
648 0 : t = NULL;
649 : }
650 7 : break;
651 :
652 58364827 : case '\\':
653 58364827 : if (!escape) {
654 58359547 : escape = true;
655 58359547 : p++;
656 58359547 : continue;
657 : }
658 5280 : escape = false;
659 :
660 5280 : *d++ = *p++;
661 5280 : l++;
662 :
663 5280 : if (t != NULL) {
664 0 : t = NULL;
665 : }
666 5280 : break;
667 :
668 11646340369 : default:
669 11646340369 : if (escape) {
670 58336753 : if (isxdigit(p[0]) && isxdigit(p[1])) {
671 58336753 : if (sscanf(p, "%02x", &x) != 1) {
672 : /* invalid escaping sequence */
673 0 : ldb_dn_mark_invalid(dn);
674 0 : goto failed;
675 : }
676 58336753 : p += 2;
677 58336753 : *d++ = (unsigned char)x;
678 : } else {
679 0 : *d++ = *p++;
680 : }
681 :
682 58336753 : escape = false;
683 58336753 : l++;
684 58336753 : if (t != NULL) {
685 0 : t = NULL;
686 : }
687 58336753 : break;
688 : }
689 :
690 11588003616 : if (*p == ' ') {
691 82717567 : if (t == NULL) {
692 82713898 : t = p;
693 : }
694 : } else {
695 11505286049 : if (t != NULL) {
696 82713726 : t = NULL;
697 : }
698 : }
699 :
700 11588003616 : *d++ = *p++;
701 11588003616 : l++;
702 :
703 11588003616 : break;
704 : }
705 :
706 0 : }
707 : }
708 :
709 179565484 : if (in_attr || in_quote) {
710 : /* invalid dn */
711 17484 : ldb_dn_mark_invalid(dn);
712 17484 : goto failed;
713 : }
714 :
715 179548000 : if (in_value) {
716 : /* save last element */
717 179547996 : if (t != NULL) {
718 : /* trim back */
719 150 : d -= (p - t);
720 150 : l -= (p - t);
721 : }
722 :
723 179547996 : *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 179547996 : dn->components[dn->comp_num].value.length = l;
730 359095992 : dn->components[dn->comp_num].value.data =
731 315243022 : (uint8_t *)talloc_memdup(dn->components, dt, l + 1);
732 179547996 : if (dn->components[dn->comp_num].value.data == NULL) {
733 : /* ouch */
734 0 : goto failed;
735 : }
736 179547996 : talloc_set_name_const(dn->components[dn->comp_num].value.data,
737 179547996 : (const char *)dn->components[dn->comp_num].value.data);
738 :
739 179547996 : dn->comp_num++;
740 : }
741 179548000 : talloc_free(data);
742 179548000 : return true;
743 :
744 17917 : failed:
745 17917 : LDB_FREE(dn->components); /* "data" is implicitly free'd */
746 17917 : dn->comp_num = 0;
747 17917 : LDB_FREE(dn->ext_components);
748 17917 : dn->ext_comp_num = 0;
749 :
750 17917 : return false;
751 : }
752 :
753 728112364 : bool ldb_dn_validate(struct ldb_dn *dn)
754 : {
755 728112364 : return ldb_dn_explode(dn);
756 : }
757 :
758 525724231 : const char *ldb_dn_get_linearized(struct ldb_dn *dn)
759 : {
760 : unsigned int i;
761 : size_t len;
762 : char *d, *n;
763 :
764 525724231 : if ( ! dn || ( dn->invalid)) return NULL;
765 :
766 525723951 : if (dn->linearized) return dn->linearized;
767 :
768 7689454 : if ( ! dn->components) {
769 0 : ldb_dn_mark_invalid(dn);
770 0 : return NULL;
771 : }
772 :
773 7689454 : if (dn->comp_num == 0) {
774 199493 : dn->linearized = talloc_strdup(dn, "");
775 199493 : if ( ! dn->linearized) return NULL;
776 199493 : return dn->linearized;
777 : }
778 :
779 : /* calculate maximum possible length of DN */
780 49070020 : for (len = 0, i = 0; i < dn->comp_num; i++) {
781 : /* name len */
782 41580059 : len += strlen(dn->components[i].name);
783 : /* max escaped data len */
784 41580059 : len += (dn->components[i].value.length * 3);
785 41580059 : len += 2; /* '=' and ',' */
786 : }
787 7489961 : dn->linearized = talloc_array(dn, char, len);
788 7489961 : if ( ! dn->linearized) return NULL;
789 :
790 7489961 : d = dn->linearized;
791 :
792 49070020 : for (i = 0; i < dn->comp_num; i++) {
793 :
794 : /* copy the name */
795 41580059 : n = dn->components[i].name;
796 49440193 : while (*n) *d++ = *n++;
797 :
798 41580059 : *d++ = '=';
799 :
800 : /* and the value */
801 83160118 : d += ldb_dn_escape_internal( d,
802 41580059 : (char *)dn->components[i].value.data,
803 41580059 : dn->components[i].value.length);
804 41580059 : *d++ = ',';
805 : }
806 :
807 7489961 : *(--d) = '\0';
808 :
809 : /* don't waste more memory than necessary */
810 7489961 : dn->linearized = talloc_realloc(dn, dn->linearized,
811 : char, (d - dn->linearized + 1));
812 :
813 7489961 : return dn->linearized;
814 : }
815 :
816 12453159 : static int ldb_dn_extended_component_compare(const void *p1, const void *p2)
817 : {
818 12453159 : const struct ldb_dn_ext_component *ec1 = (const struct ldb_dn_ext_component *)p1;
819 12453159 : const struct ldb_dn_ext_component *ec2 = (const struct ldb_dn_ext_component *)p2;
820 12453159 : return strcmp(ec1->name, ec2->name);
821 : }
822 :
823 17130118 : char *ldb_dn_get_extended_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int mode)
824 : {
825 17130118 : const char *linearized = ldb_dn_get_linearized(dn);
826 17130118 : char *p = NULL;
827 : unsigned int i;
828 :
829 17130118 : if (!linearized) {
830 96 : return NULL;
831 : }
832 :
833 17130022 : if (!ldb_dn_has_extended(dn)) {
834 1195865 : return talloc_strdup(mem_ctx, linearized);
835 : }
836 :
837 15934157 : if (!ldb_dn_validate(dn)) {
838 3 : 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 15934154 : TYPESAFE_QSORT(dn->ext_components, dn->ext_comp_num,
846 : ldb_dn_extended_component_compare);
847 :
848 70634233 : for (i = 0; i < dn->ext_comp_num; i++) {
849 : const struct ldb_dn_extended_syntax *ext_syntax;
850 21638076 : const char *name = dn->ext_components[i].name;
851 21638076 : struct ldb_val ec_val = dn->ext_components[i].value;
852 : struct ldb_val val;
853 : int ret;
854 :
855 21638076 : ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name);
856 21638076 : if (!ext_syntax) {
857 0 : return NULL;
858 : }
859 :
860 21638076 : if (mode == 1) {
861 13401493 : ret = ext_syntax->write_clear_fn(dn->ldb, mem_ctx,
862 : &ec_val, &val);
863 8236583 : } else if (mode == 0) {
864 8236583 : ret = ext_syntax->write_hex_fn(dn->ldb, mem_ctx,
865 : &ec_val, &val);
866 : } else {
867 0 : ret = -1;
868 : }
869 :
870 21638076 : if (ret != LDB_SUCCESS) {
871 0 : return NULL;
872 : }
873 :
874 21638076 : if (i == 0) {
875 29907779 : p = talloc_asprintf(mem_ctx, "<%s=%.*s>",
876 : name,
877 15934150 : (int)val.length,
878 : val.data);
879 : } else {
880 10818667 : p = talloc_asprintf_append_buffer(p, ";<%s=%.*s>",
881 : name,
882 5703926 : (int)val.length,
883 : val.data);
884 : }
885 :
886 21638076 : talloc_free(val.data);
887 :
888 21638076 : if (!p) {
889 0 : return NULL;
890 : }
891 : }
892 :
893 15934154 : if (dn->ext_comp_num && *linearized) {
894 15252544 : p = talloc_asprintf_append_buffer(p, ";%s", linearized);
895 : }
896 :
897 15934154 : if (!p) {
898 4 : return NULL;
899 : }
900 :
901 15934150 : return p;
902 : }
903 :
904 : /*
905 : filter out all but an acceptable list of extended DN components
906 : */
907 10079207 : void ldb_dn_extended_filter(struct ldb_dn *dn, const char * const *accept_list)
908 : {
909 : unsigned int i;
910 25447301 : for (i=0; i<dn->ext_comp_num; i++) {
911 15368094 : if (!ldb_attr_in_list(accept_list, dn->ext_components[i].name)) {
912 2833031 : ARRAY_DEL_ELEMENT(
913 : dn->ext_components, i, dn->ext_comp_num);
914 2833031 : dn->ext_comp_num--;
915 2833031 : i--;
916 : }
917 : }
918 10079207 : LDB_FREE(dn->ext_linearized);
919 10079207 : }
920 :
921 :
922 121185681 : char *ldb_dn_alloc_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
923 : {
924 121185681 : return talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn));
925 : }
926 :
927 : /*
928 : casefold a dn. We need to casefold the attribute names, and canonicalize
929 : attribute values of case insensitive attributes.
930 : */
931 :
932 195412751 : static bool ldb_dn_casefold_internal(struct ldb_dn *dn)
933 : {
934 : unsigned int i;
935 : int ret;
936 :
937 195412751 : if ( ! dn || dn->invalid) return false;
938 :
939 195412751 : if (dn->valid_case) return true;
940 :
941 97477881 : if (( ! dn->components) && ( ! ldb_dn_explode(dn))) {
942 630 : return false;
943 : }
944 :
945 626132260 : for (i = 0; i < dn->comp_num; i++) {
946 : const struct ldb_schema_attribute *a;
947 :
948 1057310018 : dn->components[i].cf_name =
949 932589712 : ldb_attr_casefold(dn->components,
950 528655009 : dn->components[i].name);
951 528655009 : if (!dn->components[i].cf_name) {
952 0 : goto failed;
953 : }
954 :
955 528655009 : a = ldb_schema_attribute_by_name(dn->ldb,
956 528655009 : dn->components[i].cf_name);
957 :
958 1336524415 : ret = a->syntax->canonicalise_fn(dn->ldb, dn->components,
959 528655009 : &(dn->components[i].value),
960 528655009 : &(dn->components[i].cf_value));
961 528655009 : if (ret != 0) {
962 0 : goto failed;
963 : }
964 : }
965 :
966 97477251 : dn->valid_case = true;
967 :
968 97477251 : return true;
969 :
970 0 : failed:
971 0 : for (i = 0; i < dn->comp_num; i++) {
972 0 : LDB_FREE(dn->components[i].cf_name);
973 0 : LDB_FREE(dn->components[i].cf_value.data);
974 : }
975 0 : return false;
976 : }
977 :
978 319542504 : const char *ldb_dn_get_casefold(struct ldb_dn *dn)
979 : {
980 : unsigned int i;
981 : size_t len;
982 : char *d, *n;
983 :
984 319542504 : if (dn->casefold) return dn->casefold;
985 :
986 202863156 : if (dn->special) {
987 179965825 : dn->casefold = talloc_strdup(dn, dn->linearized);
988 179965825 : if (!dn->casefold) return NULL;
989 179965825 : dn->valid_case = true;
990 179965825 : return dn->casefold;
991 : }
992 :
993 22897331 : if ( ! ldb_dn_casefold_internal(dn)) {
994 0 : return NULL;
995 : }
996 :
997 22897331 : if (dn->comp_num == 0) {
998 1030 : dn->casefold = talloc_strdup(dn, "");
999 1030 : return dn->casefold;
1000 : }
1001 :
1002 : /* calculate maximum possible length of DN */
1003 138491633 : for (len = 0, i = 0; i < dn->comp_num; i++) {
1004 : /* name len */
1005 115595332 : len += strlen(dn->components[i].cf_name);
1006 : /* max escaped data len */
1007 115595332 : len += (dn->components[i].cf_value.length * 3);
1008 115595332 : len += 2; /* '=' and ',' */
1009 : }
1010 22896301 : dn->casefold = talloc_array(dn, char, len);
1011 22896301 : if ( ! dn->casefold) return NULL;
1012 :
1013 22896301 : d = dn->casefold;
1014 :
1015 138491633 : for (i = 0; i < dn->comp_num; i++) {
1016 :
1017 : /* copy the name */
1018 115595332 : n = dn->components[i].cf_name;
1019 141444660 : while (*n) *d++ = *n++;
1020 :
1021 115595332 : *d++ = '=';
1022 :
1023 : /* and the value */
1024 231190664 : d += ldb_dn_escape_internal( d,
1025 115595332 : (char *)dn->components[i].cf_value.data,
1026 115595332 : dn->components[i].cf_value.length);
1027 115595332 : *d++ = ',';
1028 : }
1029 22896301 : *(--d) = '\0';
1030 :
1031 : /* don't waste more memory than necessary */
1032 22896301 : dn->casefold = talloc_realloc(dn, dn->casefold,
1033 : char, strlen(dn->casefold) + 1);
1034 :
1035 22896301 : return dn->casefold;
1036 : }
1037 :
1038 1924823 : char *ldb_dn_alloc_casefold(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
1039 : {
1040 1924823 : return talloc_strdup(mem_ctx, ldb_dn_get_casefold(dn));
1041 : }
1042 :
1043 : /* Determine if dn is below base, in the ldap tree. Used for
1044 : * evaluating a subtree search.
1045 : * 0 if they match, otherwise non-zero
1046 : */
1047 :
1048 392698448 : int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn)
1049 : {
1050 : int ret;
1051 : unsigned int n_base, n_dn;
1052 :
1053 392698448 : if ( ! base || base->invalid) return 1;
1054 392698448 : if ( ! dn || dn->invalid) return -1;
1055 :
1056 392698448 : if (( ! base->valid_case) || ( ! dn->valid_case)) {
1057 275747769 : 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 casfolding */
1060 : int dif;
1061 269941695 : dif = strlen(dn->linearized) - strlen(base->linearized);
1062 269941695 : if (dif < 0) {
1063 86687602 : return dif;
1064 : }
1065 322896748 : if (strcmp(base->linearized,
1066 322896748 : &dn->linearized[dif]) == 0) {
1067 109337758 : return 0;
1068 : }
1069 : }
1070 :
1071 79722409 : if ( ! ldb_dn_casefold_internal(base)) {
1072 0 : return 1;
1073 : }
1074 :
1075 79722409 : 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 196673088 : if (base->comp_num > dn->comp_num) {
1084 35742878 : return (dn->comp_num - base->comp_num);
1085 : }
1086 :
1087 160930210 : if ((dn->comp_num == 0) || (base->comp_num == 0)) {
1088 0 : if (dn->special && base->special) {
1089 0 : return strcmp(base->linearized, dn->linearized);
1090 0 : } else if (dn->special) {
1091 0 : return -1;
1092 0 : } else if (base->special) {
1093 0 : return 1;
1094 : } else {
1095 0 : return 0;
1096 : }
1097 : }
1098 :
1099 160930210 : n_base = base->comp_num - 1;
1100 160930210 : n_dn = dn->comp_num - 1;
1101 :
1102 891213191 : while (n_base != (unsigned int) -1) {
1103 689715372 : char *b_name = base->components[n_base].cf_name;
1104 689715372 : char *dn_name = dn->components[n_dn].cf_name;
1105 :
1106 689715372 : char *b_vdata = (char *)base->components[n_base].cf_value.data;
1107 689715372 : char *dn_vdata = (char *)dn->components[n_dn].cf_value.data;
1108 :
1109 689715372 : size_t b_vlen = base->components[n_base].cf_value.length;
1110 689715372 : size_t dn_vlen = dn->components[n_dn].cf_value.length;
1111 :
1112 : /* compare attr names */
1113 689715372 : ret = strcmp(b_name, dn_name);
1114 689715372 : if (ret != 0) return ret;
1115 :
1116 : /* compare attr.cf_value. */
1117 623490363 : if (b_vlen != dn_vlen) {
1118 30125070 : return b_vlen - dn_vlen;
1119 : }
1120 593365293 : ret = strncmp(b_vdata, dn_vdata, b_vlen);
1121 593365293 : if (ret != 0) return ret;
1122 :
1123 591966258 : n_base--;
1124 591966258 : n_dn--;
1125 : }
1126 :
1127 63181096 : return 0;
1128 : }
1129 :
1130 : /* compare DNs using casefolding compare functions.
1131 :
1132 : If they match, then return 0
1133 : */
1134 :
1135 41852680 : int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1)
1136 : {
1137 : unsigned int i;
1138 : int ret;
1139 :
1140 41852680 : if (( ! dn0) || dn0->invalid || ! dn1 || dn1->invalid) {
1141 2 : return -1;
1142 : }
1143 :
1144 41852678 : if (( ! dn0->valid_case) || ( ! dn1->valid_case)) {
1145 7782608 : if (dn0->linearized && dn1->linearized) {
1146 : /* try with a normal compare first, if we are lucky
1147 : * we will avoid exploding and casfolding */
1148 6127027 : if (strcmp(dn0->linearized, dn1->linearized) == 0) {
1149 1247307 : return 0;
1150 : }
1151 : }
1152 :
1153 6535301 : if ( ! ldb_dn_casefold_internal(dn0)) {
1154 0 : return 1;
1155 : }
1156 :
1157 6535301 : if ( ! ldb_dn_casefold_internal(dn1)) {
1158 630 : return -1;
1159 : }
1160 :
1161 : }
1162 :
1163 40604741 : if (dn0->comp_num != dn1->comp_num) {
1164 25283251 : return (dn1->comp_num - dn0->comp_num);
1165 : }
1166 :
1167 15321490 : if (dn0->comp_num == 0) {
1168 881177 : if (dn0->special && dn1->special) {
1169 881177 : return strcmp(dn0->linearized, dn1->linearized);
1170 0 : } else if (dn0->special) {
1171 0 : return 1;
1172 0 : } else if (dn1->special) {
1173 0 : return -1;
1174 : } else {
1175 0 : return 0;
1176 : }
1177 : }
1178 :
1179 45632294 : for (i = 0; i < dn0->comp_num; i++) {
1180 38911164 : char *dn0_name = dn0->components[i].cf_name;
1181 38911164 : char *dn1_name = dn1->components[i].cf_name;
1182 :
1183 38911164 : char *dn0_vdata = (char *)dn0->components[i].cf_value.data;
1184 38911164 : char *dn1_vdata = (char *)dn1->components[i].cf_value.data;
1185 :
1186 38911164 : size_t dn0_vlen = dn0->components[i].cf_value.length;
1187 38911164 : size_t dn1_vlen = dn1->components[i].cf_value.length;
1188 :
1189 : /* compare attr names */
1190 38911164 : ret = strcmp(dn0_name, dn1_name);
1191 38911164 : if (ret != 0) {
1192 1885997 : return ret;
1193 : }
1194 :
1195 : /* compare attr.cf_value. */
1196 37025167 : if (dn0_vlen != dn1_vlen) {
1197 3054763 : return dn0_vlen - dn1_vlen;
1198 : }
1199 33970404 : ret = strncmp(dn0_vdata, dn1_vdata, dn0_vlen);
1200 33970404 : if (ret != 0) {
1201 2778423 : return ret;
1202 : }
1203 : }
1204 :
1205 6721130 : return 0;
1206 : }
1207 :
1208 286198934 : static struct ldb_dn_component ldb_dn_copy_component(
1209 : TALLOC_CTX *mem_ctx,
1210 : struct ldb_dn_component *src)
1211 : {
1212 : struct ldb_dn_component dst;
1213 :
1214 286198934 : memset(&dst, 0, sizeof(dst));
1215 :
1216 286198934 : if (src == NULL) {
1217 0 : return dst;
1218 : }
1219 :
1220 286198934 : dst.value = ldb_val_dup(mem_ctx, &(src->value));
1221 286198934 : if (dst.value.data == NULL) {
1222 0 : return dst;
1223 : }
1224 :
1225 286198934 : dst.name = talloc_strdup(mem_ctx, src->name);
1226 286198934 : if (dst.name == NULL) {
1227 0 : LDB_FREE(dst.value.data);
1228 0 : return dst;
1229 : }
1230 :
1231 286198934 : if (src->cf_value.data) {
1232 231355843 : dst.cf_value = ldb_val_dup(mem_ctx, &(src->cf_value));
1233 231355843 : if (dst.cf_value.data == NULL) {
1234 0 : LDB_FREE(dst.value.data);
1235 0 : LDB_FREE(dst.name);
1236 0 : return dst;
1237 : }
1238 :
1239 231355843 : dst.cf_name = talloc_strdup(mem_ctx, src->cf_name);
1240 231355843 : if (dst.cf_name == NULL) {
1241 0 : LDB_FREE(dst.cf_name);
1242 0 : LDB_FREE(dst.value.data);
1243 0 : LDB_FREE(dst.name);
1244 0 : return dst;
1245 : }
1246 : } else {
1247 54843091 : dst.cf_value.data = NULL;
1248 54843091 : dst.cf_name = NULL;
1249 : }
1250 :
1251 286198934 : return dst;
1252 : }
1253 :
1254 22057142 : static struct ldb_dn_ext_component ldb_dn_ext_copy_component(
1255 : TALLOC_CTX *mem_ctx,
1256 : struct ldb_dn_ext_component *src)
1257 : {
1258 : struct ldb_dn_ext_component dst;
1259 :
1260 22057142 : memset(&dst, 0, sizeof(dst));
1261 :
1262 22057142 : if (src == NULL) {
1263 0 : return dst;
1264 : }
1265 :
1266 22057142 : dst.value = ldb_val_dup(mem_ctx, &(src->value));
1267 22057142 : if (dst.value.data == NULL) {
1268 0 : return dst;
1269 : }
1270 :
1271 22057142 : dst.name = talloc_strdup(mem_ctx, src->name);
1272 22057142 : if (dst.name == NULL) {
1273 0 : LDB_FREE(dst.value.data);
1274 0 : return dst;
1275 : }
1276 :
1277 22057142 : return dst;
1278 : }
1279 :
1280 55239382 : struct ldb_dn *ldb_dn_copy(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
1281 : {
1282 : struct ldb_dn *new_dn;
1283 :
1284 55239382 : if (!dn || dn->invalid) {
1285 2 : return NULL;
1286 : }
1287 :
1288 55239380 : new_dn = talloc_zero(mem_ctx, struct ldb_dn);
1289 55239380 : if ( !new_dn) {
1290 0 : return NULL;
1291 : }
1292 :
1293 55239380 : *new_dn = *dn;
1294 :
1295 55239380 : if (dn->components) {
1296 : unsigned int i;
1297 :
1298 48524161 : new_dn->components =
1299 48524161 : talloc_zero_array(new_dn,
1300 : struct ldb_dn_component,
1301 : dn->comp_num);
1302 48524161 : if ( ! new_dn->components) {
1303 0 : talloc_free(new_dn);
1304 0 : return NULL;
1305 : }
1306 :
1307 324430917 : for (i = 0; i < dn->comp_num; i++) {
1308 275906756 : new_dn->components[i] =
1309 275906756 : ldb_dn_copy_component(new_dn->components,
1310 275906756 : &dn->components[i]);
1311 275906756 : if ( ! new_dn->components[i].value.data) {
1312 0 : talloc_free(new_dn);
1313 0 : return NULL;
1314 : }
1315 : }
1316 : }
1317 :
1318 55239380 : if (dn->ext_components) {
1319 : unsigned int i;
1320 :
1321 17885304 : new_dn->ext_components =
1322 17885304 : talloc_zero_array(new_dn,
1323 : struct ldb_dn_ext_component,
1324 : dn->ext_comp_num);
1325 17885304 : if ( ! new_dn->ext_components) {
1326 0 : talloc_free(new_dn);
1327 0 : return NULL;
1328 : }
1329 :
1330 39942446 : for (i = 0; i < dn->ext_comp_num; i++) {
1331 22057142 : new_dn->ext_components[i] =
1332 22057142 : ldb_dn_ext_copy_component(
1333 22057142 : new_dn->ext_components,
1334 22057142 : &dn->ext_components[i]);
1335 22057142 : if ( ! new_dn->ext_components[i].value.data) {
1336 0 : talloc_free(new_dn);
1337 0 : return NULL;
1338 : }
1339 : }
1340 : }
1341 :
1342 55239380 : if (dn->casefold) {
1343 30945846 : new_dn->casefold = talloc_strdup(new_dn, dn->casefold);
1344 30945846 : if ( ! new_dn->casefold) {
1345 0 : talloc_free(new_dn);
1346 0 : return NULL;
1347 : }
1348 : }
1349 :
1350 55239380 : if (dn->linearized) {
1351 55093873 : new_dn->linearized = talloc_strdup(new_dn, dn->linearized);
1352 55093873 : if ( ! new_dn->linearized) {
1353 0 : talloc_free(new_dn);
1354 0 : return NULL;
1355 : }
1356 : }
1357 :
1358 55239380 : if (dn->ext_linearized) {
1359 1056704 : new_dn->ext_linearized = talloc_strdup(new_dn,
1360 934316 : dn->ext_linearized);
1361 934316 : if ( ! new_dn->ext_linearized) {
1362 0 : talloc_free(new_dn);
1363 0 : return NULL;
1364 : }
1365 : }
1366 :
1367 55239380 : return new_dn;
1368 : }
1369 :
1370 : /* modify the given dn by adding a base.
1371 : *
1372 : * return true if successful and false if not
1373 : * if false is returned the dn may be marked invalid
1374 : */
1375 467794 : bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base)
1376 : {
1377 : const char *s;
1378 : char *t;
1379 :
1380 467794 : if ( !base || base->invalid || !dn || dn->invalid) {
1381 0 : return false;
1382 : }
1383 :
1384 467794 : if (dn == base) {
1385 0 : return false; /* or we will visit infinity */
1386 : }
1387 :
1388 467794 : if (dn->components) {
1389 : unsigned int i;
1390 :
1391 375296 : if ( ! ldb_dn_validate(base)) {
1392 0 : return false;
1393 : }
1394 :
1395 375296 : s = NULL;
1396 375296 : if (dn->valid_case) {
1397 2 : if ( ! (s = ldb_dn_get_casefold(base))) {
1398 0 : return false;
1399 : }
1400 : }
1401 :
1402 375296 : dn->components = talloc_realloc(dn,
1403 : dn->components,
1404 : struct ldb_dn_component,
1405 : dn->comp_num + base->comp_num);
1406 375296 : if ( ! dn->components) {
1407 0 : ldb_dn_mark_invalid(dn);
1408 0 : return false;
1409 : }
1410 :
1411 2503296 : for (i = 0; i < base->comp_num; dn->comp_num++, i++) {
1412 2128000 : dn->components[dn->comp_num] =
1413 2128000 : ldb_dn_copy_component(dn->components,
1414 2128000 : &base->components[i]);
1415 2128000 : if (dn->components[dn->comp_num].value.data == NULL) {
1416 0 : ldb_dn_mark_invalid(dn);
1417 0 : return false;
1418 : }
1419 : }
1420 :
1421 375296 : if (dn->casefold && s) {
1422 0 : if (*dn->casefold) {
1423 0 : t = talloc_asprintf(dn, "%s,%s",
1424 : dn->casefold, s);
1425 : } else {
1426 0 : t = talloc_strdup(dn, s);
1427 : }
1428 0 : LDB_FREE(dn->casefold);
1429 0 : dn->casefold = t;
1430 : }
1431 : }
1432 :
1433 467794 : if (dn->linearized) {
1434 :
1435 94101 : s = ldb_dn_get_linearized(base);
1436 94101 : if ( ! s) {
1437 0 : return false;
1438 : }
1439 :
1440 94101 : if (*dn->linearized) {
1441 8076 : t = talloc_asprintf(dn, "%s,%s",
1442 : dn->linearized, s);
1443 : } else {
1444 86025 : t = talloc_strdup(dn, s);
1445 : }
1446 94101 : if ( ! t) {
1447 0 : ldb_dn_mark_invalid(dn);
1448 0 : return false;
1449 : }
1450 94101 : LDB_FREE(dn->linearized);
1451 94101 : dn->linearized = t;
1452 : }
1453 :
1454 : /* Wipe the ext_linearized DN,
1455 : * the GUID and SID are almost certainly no longer valid */
1456 467794 : LDB_FREE(dn->ext_linearized);
1457 467794 : LDB_FREE(dn->ext_components);
1458 467794 : dn->ext_comp_num = 0;
1459 :
1460 467794 : return true;
1461 : }
1462 :
1463 : /* modify the given dn by adding a base.
1464 : *
1465 : * return true if successful and false if not
1466 : * if false is returned the dn may be marked invalid
1467 : */
1468 0 : bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...)
1469 : {
1470 : struct ldb_dn *base;
1471 : char *base_str;
1472 : va_list ap;
1473 : bool ret;
1474 :
1475 0 : if ( !dn || dn->invalid) {
1476 0 : return false;
1477 : }
1478 :
1479 0 : va_start(ap, base_fmt);
1480 0 : base_str = talloc_vasprintf(dn, base_fmt, ap);
1481 0 : va_end(ap);
1482 :
1483 0 : if (base_str == NULL) {
1484 0 : return false;
1485 : }
1486 :
1487 0 : base = ldb_dn_new(base_str, dn->ldb, base_str);
1488 :
1489 0 : ret = ldb_dn_add_base(dn, base);
1490 :
1491 0 : talloc_free(base_str);
1492 :
1493 0 : return ret;
1494 : }
1495 :
1496 : /* modify the given dn by adding children elements.
1497 : *
1498 : * return true if successful and false if not
1499 : * if false is returned the dn may be marked invalid
1500 : */
1501 4361535 : bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child)
1502 : {
1503 : const char *s;
1504 : char *t;
1505 :
1506 4361535 : if ( !child || child->invalid || !dn || dn->invalid) {
1507 0 : return false;
1508 : }
1509 :
1510 4361535 : if (dn->components) {
1511 : unsigned int n;
1512 : unsigned int i, j;
1513 :
1514 4170269 : if (dn->comp_num == 0) {
1515 0 : return false;
1516 : }
1517 :
1518 4170269 : if ( ! ldb_dn_validate(child)) {
1519 0 : return false;
1520 : }
1521 :
1522 4170269 : s = NULL;
1523 4170269 : if (dn->valid_case) {
1524 2746756 : if ( ! (s = ldb_dn_get_casefold(child))) {
1525 0 : return false;
1526 : }
1527 : }
1528 :
1529 4170269 : n = dn->comp_num + child->comp_num;
1530 :
1531 4170269 : dn->components = talloc_realloc(dn,
1532 : dn->components,
1533 : struct ldb_dn_component,
1534 : n);
1535 4170269 : if ( ! dn->components) {
1536 0 : ldb_dn_mark_invalid(dn);
1537 0 : return false;
1538 : }
1539 :
1540 25815289 : for (i = dn->comp_num - 1, j = n - 1; i != (unsigned int) -1;
1541 18018558 : i--, j--) {
1542 18018558 : dn->components[j] = dn->components[i];
1543 : }
1544 :
1545 11756022 : for (i = 0; i < child->comp_num; i++) {
1546 7585753 : dn->components[i] =
1547 7585753 : ldb_dn_copy_component(dn->components,
1548 7585753 : &child->components[i]);
1549 7585753 : if (dn->components[i].value.data == NULL) {
1550 0 : ldb_dn_mark_invalid(dn);
1551 0 : return false;
1552 : }
1553 : }
1554 :
1555 4170269 : dn->comp_num = n;
1556 :
1557 4170269 : if (dn->casefold && s) {
1558 2278719 : t = talloc_asprintf(dn, "%s,%s", s, dn->casefold);
1559 2278719 : LDB_FREE(dn->casefold);
1560 2278719 : dn->casefold = t;
1561 : }
1562 : }
1563 :
1564 4361535 : if (dn->linearized) {
1565 4355053 : if (dn->linearized[0] == '\0') {
1566 0 : return false;
1567 : }
1568 :
1569 4355053 : s = ldb_dn_get_linearized(child);
1570 4355053 : if ( ! s) {
1571 0 : return false;
1572 : }
1573 :
1574 4355053 : t = talloc_asprintf(dn, "%s,%s", s, dn->linearized);
1575 4355053 : if ( ! t) {
1576 0 : ldb_dn_mark_invalid(dn);
1577 0 : return false;
1578 : }
1579 4355053 : LDB_FREE(dn->linearized);
1580 4355053 : dn->linearized = t;
1581 : }
1582 :
1583 : /* Wipe the ext_linearized DN,
1584 : * the GUID and SID are almost certainly no longer valid */
1585 4361535 : LDB_FREE(dn->ext_linearized);
1586 4361535 : LDB_FREE(dn->ext_components);
1587 4361535 : dn->ext_comp_num = 0;
1588 :
1589 4361535 : return true;
1590 : }
1591 :
1592 : /* modify the given dn by adding children elements.
1593 : *
1594 : * return true if successful and false if not
1595 : * if false is returned the dn may be marked invalid
1596 : */
1597 4213870 : bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...)
1598 : {
1599 : struct ldb_dn *child;
1600 : char *child_str;
1601 : va_list ap;
1602 : bool ret;
1603 :
1604 4213870 : if ( !dn || dn->invalid) {
1605 0 : return false;
1606 : }
1607 :
1608 4213870 : va_start(ap, child_fmt);
1609 4213870 : child_str = talloc_vasprintf(dn, child_fmt, ap);
1610 4213870 : va_end(ap);
1611 :
1612 4213870 : if (child_str == NULL) {
1613 0 : return false;
1614 : }
1615 :
1616 4213870 : child = ldb_dn_new(child_str, dn->ldb, child_str);
1617 :
1618 4213870 : ret = ldb_dn_add_child(dn, child);
1619 :
1620 4213870 : talloc_free(child_str);
1621 :
1622 4213870 : return ret;
1623 : }
1624 :
1625 : /* modify the given dn by adding a single child element.
1626 : *
1627 : * return true if successful and false if not
1628 : * if false is returned the dn may be marked invalid
1629 : */
1630 58704 : bool ldb_dn_add_child_val(struct ldb_dn *dn,
1631 : const char *rdn,
1632 : struct ldb_val value)
1633 : {
1634 : bool ret;
1635 : int ldb_ret;
1636 58704 : struct ldb_dn *child = NULL;
1637 :
1638 58704 : if ( !dn || dn->invalid) {
1639 0 : return false;
1640 : }
1641 :
1642 58704 : child = ldb_dn_new(dn, dn->ldb, "X=Y");
1643 58704 : ret = ldb_dn_add_child(dn, child);
1644 :
1645 58704 : if (ret == false) {
1646 0 : return false;
1647 : }
1648 :
1649 58704 : ldb_ret = ldb_dn_set_component(dn,
1650 : 0,
1651 : rdn,
1652 : value);
1653 58704 : if (ldb_ret != LDB_SUCCESS) {
1654 0 : return false;
1655 : }
1656 :
1657 58704 : return true;
1658 : }
1659 :
1660 460463 : bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num)
1661 : {
1662 : unsigned int i;
1663 :
1664 460463 : if ( ! ldb_dn_validate(dn)) {
1665 0 : return false;
1666 : }
1667 :
1668 460463 : if (dn->comp_num < num) {
1669 0 : return false;
1670 : }
1671 :
1672 : /* free components */
1673 3010127 : for (i = dn->comp_num - num; i < dn->comp_num; i++) {
1674 2549664 : LDB_FREE(dn->components[i].name);
1675 2549664 : LDB_FREE(dn->components[i].value.data);
1676 2549664 : LDB_FREE(dn->components[i].cf_name);
1677 2549664 : LDB_FREE(dn->components[i].cf_value.data);
1678 : }
1679 :
1680 460463 : dn->comp_num -= num;
1681 :
1682 460463 : if (dn->valid_case) {
1683 173552 : for (i = 0; i < dn->comp_num; i++) {
1684 86776 : LDB_FREE(dn->components[i].cf_name);
1685 86776 : LDB_FREE(dn->components[i].cf_value.data);
1686 : }
1687 86776 : dn->valid_case = false;
1688 : }
1689 :
1690 460463 : LDB_FREE(dn->casefold);
1691 460463 : LDB_FREE(dn->linearized);
1692 :
1693 : /* Wipe the ext_linearized DN,
1694 : * the GUID and SID are almost certainly no longer valid */
1695 460463 : LDB_FREE(dn->ext_linearized);
1696 460463 : LDB_FREE(dn->ext_components);
1697 460463 : dn->ext_comp_num = 0;
1698 :
1699 460463 : return true;
1700 : }
1701 :
1702 9780384 : bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num)
1703 : {
1704 : unsigned int i, j;
1705 :
1706 9780384 : if ( ! ldb_dn_validate(dn)) {
1707 0 : return false;
1708 : }
1709 :
1710 9780384 : if (dn->comp_num < num) {
1711 3 : return false;
1712 : }
1713 :
1714 63331615 : for (i = 0, j = num; j < dn->comp_num; i++, j++) {
1715 53551234 : if (i < num) {
1716 9779353 : LDB_FREE(dn->components[i].name);
1717 9779353 : LDB_FREE(dn->components[i].value.data);
1718 9779353 : LDB_FREE(dn->components[i].cf_name);
1719 9779353 : LDB_FREE(dn->components[i].cf_value.data);
1720 : }
1721 53551234 : dn->components[i] = dn->components[j];
1722 : }
1723 :
1724 9780381 : dn->comp_num -= num;
1725 :
1726 9780381 : if (dn->valid_case) {
1727 43123177 : for (i = 0; i < dn->comp_num; i++) {
1728 36487903 : LDB_FREE(dn->components[i].cf_name);
1729 36487903 : LDB_FREE(dn->components[i].cf_value.data);
1730 : }
1731 6635274 : dn->valid_case = false;
1732 : }
1733 :
1734 9780381 : LDB_FREE(dn->casefold);
1735 9780381 : LDB_FREE(dn->linearized);
1736 :
1737 : /* Wipe the ext_linearized DN,
1738 : * the GUID and SID are almost certainly no longer valid */
1739 9780381 : LDB_FREE(dn->ext_linearized);
1740 9780381 : LDB_FREE(dn->ext_components);
1741 9780381 : dn->ext_comp_num = 0;
1742 :
1743 9780381 : return true;
1744 : }
1745 :
1746 :
1747 : /* replace the components of a DN with those from another DN, without
1748 : * touching the extended components
1749 : *
1750 : * return true if successful and false if not
1751 : * if false is returned the dn may be marked invalid
1752 : */
1753 117069 : bool ldb_dn_replace_components(struct ldb_dn *dn, struct ldb_dn *new_dn)
1754 : {
1755 : unsigned int i;
1756 :
1757 117069 : if ( ! ldb_dn_validate(dn) || ! ldb_dn_validate(new_dn)) {
1758 0 : return false;
1759 : }
1760 :
1761 : /* free components */
1762 805112 : for (i = 0; i < dn->comp_num; i++) {
1763 688043 : LDB_FREE(dn->components[i].name);
1764 688043 : LDB_FREE(dn->components[i].value.data);
1765 688043 : LDB_FREE(dn->components[i].cf_name);
1766 688043 : LDB_FREE(dn->components[i].cf_value.data);
1767 : }
1768 :
1769 117069 : dn->components = talloc_realloc(dn,
1770 : dn->components,
1771 : struct ldb_dn_component,
1772 : new_dn->comp_num);
1773 117069 : if (dn->components == NULL) {
1774 0 : ldb_dn_mark_invalid(dn);
1775 0 : return false;
1776 : }
1777 :
1778 117069 : dn->comp_num = new_dn->comp_num;
1779 117069 : dn->valid_case = new_dn->valid_case;
1780 :
1781 695494 : for (i = 0; i < dn->comp_num; i++) {
1782 578425 : dn->components[i] = ldb_dn_copy_component(dn->components, &new_dn->components[i]);
1783 578425 : if (dn->components[i].name == NULL) {
1784 0 : ldb_dn_mark_invalid(dn);
1785 0 : return false;
1786 : }
1787 : }
1788 117069 : if (new_dn->linearized == NULL) {
1789 0 : dn->linearized = NULL;
1790 : } else {
1791 117069 : dn->linearized = talloc_strdup(dn, new_dn->linearized);
1792 117069 : if (dn->linearized == NULL) {
1793 0 : ldb_dn_mark_invalid(dn);
1794 0 : return false;
1795 : }
1796 : }
1797 :
1798 117069 : return true;
1799 : }
1800 :
1801 :
1802 9776319 : struct ldb_dn *ldb_dn_get_parent(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
1803 : {
1804 : struct ldb_dn *new_dn;
1805 :
1806 9776319 : new_dn = ldb_dn_copy(mem_ctx, dn);
1807 9776319 : if ( !new_dn ) {
1808 2 : return NULL;
1809 : }
1810 :
1811 9776317 : if ( ! ldb_dn_remove_child_components(new_dn, 1)) {
1812 3 : talloc_free(new_dn);
1813 3 : return NULL;
1814 : }
1815 :
1816 9776314 : return new_dn;
1817 : }
1818 :
1819 : /* Create a 'canonical name' string from a DN:
1820 :
1821 : ie dc=samba,dc=org -> samba.org/
1822 : uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator
1823 :
1824 : There are two formats,
1825 : the EX format has the last '/' replaced with a newline (\n).
1826 :
1827 : */
1828 1795038 : static char *ldb_dn_canonical(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int ex_format) {
1829 : unsigned int i;
1830 : TALLOC_CTX *tmpctx;
1831 1795038 : char *cracked = NULL;
1832 1795038 : const char *format = (ex_format ? "\n" : "/" );
1833 :
1834 1795038 : if ( ! ldb_dn_validate(dn)) {
1835 0 : return NULL;
1836 : }
1837 :
1838 1795038 : tmpctx = talloc_new(mem_ctx);
1839 :
1840 : /* Walk backwards down the DN, grabbing 'dc' components at first */
1841 7735473 : for (i = dn->comp_num - 1; i != (unsigned int) -1; i--) {
1842 7548349 : if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) {
1843 1607914 : break;
1844 : }
1845 5940435 : if (cracked) {
1846 4145464 : cracked = talloc_asprintf(tmpctx, "%s.%s",
1847 : ldb_dn_escape_value(tmpctx,
1848 4145464 : dn->components[i].value),
1849 : cracked);
1850 : } else {
1851 1794971 : cracked = ldb_dn_escape_value(tmpctx,
1852 1794971 : dn->components[i].value);
1853 : }
1854 5940435 : if (!cracked) {
1855 0 : goto done;
1856 : }
1857 : }
1858 :
1859 : /* Only domain components? Finish here */
1860 1795038 : if (i == (unsigned int) -1) {
1861 187124 : cracked = talloc_strdup_append_buffer(cracked, format);
1862 187124 : talloc_steal(mem_ctx, cracked);
1863 187124 : goto done;
1864 : }
1865 :
1866 : /* Now walk backwards appending remaining components */
1867 4407256 : for (; i > 0; i--) {
1868 2799342 : cracked = talloc_asprintf_append_buffer(cracked, "/%s",
1869 : ldb_dn_escape_value(tmpctx,
1870 2799342 : dn->components[i].value));
1871 2799342 : if (!cracked) {
1872 0 : goto done;
1873 : }
1874 : }
1875 :
1876 : /* Last one, possibly a newline for the 'ex' format */
1877 1607914 : cracked = talloc_asprintf_append_buffer(cracked, "%s%s", format,
1878 : ldb_dn_escape_value(tmpctx,
1879 1607914 : dn->components[i].value));
1880 :
1881 1607914 : talloc_steal(mem_ctx, cracked);
1882 1795038 : done:
1883 1795038 : talloc_free(tmpctx);
1884 1795038 : return cracked;
1885 : }
1886 :
1887 : /* Wrapper functions for the above, for the two different string formats */
1888 1794875 : char *ldb_dn_canonical_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) {
1889 1794875 : return ldb_dn_canonical(mem_ctx, dn, 0);
1890 :
1891 : }
1892 :
1893 163 : char *ldb_dn_canonical_ex_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) {
1894 163 : return ldb_dn_canonical(mem_ctx, dn, 1);
1895 : }
1896 :
1897 14720356 : int ldb_dn_get_comp_num(struct ldb_dn *dn)
1898 : {
1899 14720356 : if ( ! ldb_dn_validate(dn)) {
1900 4 : return -1;
1901 : }
1902 14720352 : return dn->comp_num;
1903 : }
1904 :
1905 9282311 : int ldb_dn_get_extended_comp_num(struct ldb_dn *dn)
1906 : {
1907 9282311 : if ( ! ldb_dn_validate(dn)) {
1908 4 : return -1;
1909 : }
1910 9282307 : return dn->ext_comp_num;
1911 : }
1912 :
1913 6815 : const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num)
1914 : {
1915 6815 : if ( ! ldb_dn_validate(dn)) {
1916 0 : return NULL;
1917 : }
1918 6815 : if (num >= dn->comp_num) return NULL;
1919 6807 : return dn->components[num].name;
1920 : }
1921 :
1922 519581 : const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn,
1923 : unsigned int num)
1924 : {
1925 519581 : if ( ! ldb_dn_validate(dn)) {
1926 0 : return NULL;
1927 : }
1928 519581 : if (num >= dn->comp_num) return NULL;
1929 519581 : return &dn->components[num].value;
1930 : }
1931 :
1932 45285672 : const char *ldb_dn_get_rdn_name(struct ldb_dn *dn)
1933 : {
1934 45285672 : if ( ! ldb_dn_validate(dn)) {
1935 0 : return NULL;
1936 : }
1937 45285672 : if (dn->comp_num == 0) return NULL;
1938 36552754 : return dn->components[0].name;
1939 : }
1940 :
1941 36266989 : const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn)
1942 : {
1943 36266989 : if ( ! ldb_dn_validate(dn)) {
1944 2 : return NULL;
1945 : }
1946 36266987 : if (dn->comp_num == 0) return NULL;
1947 27534069 : return &dn->components[0].value;
1948 : }
1949 :
1950 782872 : int ldb_dn_set_component(struct ldb_dn *dn, int num,
1951 : const char *name, const struct ldb_val val)
1952 : {
1953 : char *n;
1954 : struct ldb_val v;
1955 :
1956 782872 : if ( ! ldb_dn_validate(dn)) {
1957 0 : return LDB_ERR_OTHER;
1958 : }
1959 :
1960 782872 : if (num < 0) {
1961 0 : return LDB_ERR_OTHER;
1962 : }
1963 :
1964 782872 : if ((unsigned)num >= dn->comp_num) {
1965 2 : return LDB_ERR_OTHER;
1966 : }
1967 :
1968 782870 : if (val.length > val.length + 1) {
1969 0 : return LDB_ERR_OTHER;
1970 : }
1971 :
1972 782870 : n = talloc_strdup(dn, name);
1973 782870 : if ( ! n) {
1974 0 : return LDB_ERR_OTHER;
1975 : }
1976 :
1977 782870 : v.length = val.length;
1978 :
1979 : /*
1980 : * This is like talloc_memdup(dn, v.data, v.length + 1), but
1981 : * avoids the over-read
1982 : */
1983 782870 : v.data = (uint8_t *)talloc_size(dn, v.length+1);
1984 782870 : if ( ! v.data) {
1985 0 : talloc_free(n);
1986 0 : return LDB_ERR_OTHER;
1987 : }
1988 782870 : memcpy(v.data, val.data, val.length);
1989 :
1990 : /*
1991 : * Enforce NUL termination outside the stated length, as is
1992 : * traditional in LDB
1993 : */
1994 782870 : v.data[v.length] = '\0';
1995 :
1996 782870 : talloc_free(dn->components[num].name);
1997 782870 : talloc_free(dn->components[num].value.data);
1998 782870 : dn->components[num].name = n;
1999 782870 : dn->components[num].value = v;
2000 :
2001 782870 : if (dn->valid_case) {
2002 : unsigned int i;
2003 3157771 : for (i = 0; i < dn->comp_num; i++) {
2004 2724019 : LDB_FREE(dn->components[i].cf_name);
2005 2724019 : LDB_FREE(dn->components[i].cf_value.data);
2006 : }
2007 433752 : dn->valid_case = false;
2008 : }
2009 782870 : LDB_FREE(dn->casefold);
2010 782870 : LDB_FREE(dn->linearized);
2011 :
2012 : /* Wipe the ext_linearized DN,
2013 : * the GUID and SID are almost certainly no longer valid */
2014 782870 : LDB_FREE(dn->ext_linearized);
2015 782870 : LDB_FREE(dn->ext_components);
2016 782870 : dn->ext_comp_num = 0;
2017 :
2018 782870 : return LDB_SUCCESS;
2019 : }
2020 :
2021 166448910 : const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn,
2022 : const char *name)
2023 : {
2024 : unsigned int i;
2025 166448910 : if ( ! ldb_dn_validate(dn)) {
2026 6 : return NULL;
2027 : }
2028 197653296 : for (i=0; i < dn->ext_comp_num; i++) {
2029 73088290 : if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) {
2030 41883898 : return &dn->ext_components[i].value;
2031 : }
2032 : }
2033 124565006 : return NULL;
2034 : }
2035 :
2036 97244130 : int ldb_dn_set_extended_component(struct ldb_dn *dn,
2037 : const char *name, const struct ldb_val *val)
2038 : {
2039 : struct ldb_dn_ext_component *p;
2040 : unsigned int i;
2041 : struct ldb_val v2;
2042 : const struct ldb_dn_extended_syntax *ext_syntax;
2043 :
2044 97244130 : if ( ! ldb_dn_validate(dn)) {
2045 0 : return LDB_ERR_OTHER;
2046 : }
2047 :
2048 97244130 : ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name);
2049 97244130 : if (ext_syntax == NULL) {
2050 : /* We don't know how to handle this type of thing */
2051 0 : return LDB_ERR_INVALID_DN_SYNTAX;
2052 : }
2053 :
2054 114825862 : for (i=0; i < dn->ext_comp_num; i++) {
2055 17585706 : if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) {
2056 3974 : if (val) {
2057 3974 : dn->ext_components[i].value =
2058 3974 : ldb_val_dup(dn->ext_components, val);
2059 :
2060 3974 : dn->ext_components[i].name = ext_syntax->name;
2061 3974 : if (!dn->ext_components[i].value.data) {
2062 0 : ldb_dn_mark_invalid(dn);
2063 0 : return LDB_ERR_OPERATIONS_ERROR;
2064 : }
2065 : } else {
2066 0 : ARRAY_DEL_ELEMENT(
2067 : dn->ext_components,
2068 : i,
2069 : dn->ext_comp_num);
2070 0 : dn->ext_comp_num--;
2071 :
2072 0 : dn->ext_components = talloc_realloc(dn,
2073 : dn->ext_components,
2074 : struct ldb_dn_ext_component,
2075 : dn->ext_comp_num);
2076 0 : if (!dn->ext_components) {
2077 0 : ldb_dn_mark_invalid(dn);
2078 0 : return LDB_ERR_OPERATIONS_ERROR;
2079 : }
2080 : }
2081 3974 : LDB_FREE(dn->ext_linearized);
2082 :
2083 3974 : return LDB_SUCCESS;
2084 : }
2085 : }
2086 :
2087 97240156 : if (val == NULL) {
2088 : /* removing a value that doesn't exist is not an error */
2089 0 : return LDB_SUCCESS;
2090 : }
2091 :
2092 97240156 : v2 = *val;
2093 :
2094 97240156 : p = dn->ext_components
2095 97240156 : = talloc_realloc(dn,
2096 : dn->ext_components,
2097 : struct ldb_dn_ext_component,
2098 : dn->ext_comp_num + 1);
2099 97240156 : if (!dn->ext_components) {
2100 0 : ldb_dn_mark_invalid(dn);
2101 0 : return LDB_ERR_OPERATIONS_ERROR;
2102 : }
2103 :
2104 97240156 : p[dn->ext_comp_num].value = ldb_val_dup(dn->ext_components, &v2);
2105 97240156 : p[dn->ext_comp_num].name = talloc_strdup(p, name);
2106 :
2107 97240156 : if (!dn->ext_components[i].name || !dn->ext_components[i].value.data) {
2108 0 : ldb_dn_mark_invalid(dn);
2109 0 : return LDB_ERR_OPERATIONS_ERROR;
2110 : }
2111 97240156 : dn->ext_components = p;
2112 97240156 : dn->ext_comp_num++;
2113 :
2114 97240156 : LDB_FREE(dn->ext_linearized);
2115 :
2116 97240156 : return LDB_SUCCESS;
2117 : }
2118 :
2119 32818452 : void ldb_dn_remove_extended_components(struct ldb_dn *dn)
2120 : {
2121 32818452 : LDB_FREE(dn->ext_linearized);
2122 32818452 : LDB_FREE(dn->ext_components);
2123 32818452 : dn->ext_comp_num = 0;
2124 32818452 : }
2125 :
2126 4608 : bool ldb_dn_is_valid(struct ldb_dn *dn)
2127 : {
2128 4608 : if ( ! dn) return false;
2129 4608 : return ! dn->invalid;
2130 : }
2131 :
2132 1259215105 : bool ldb_dn_is_special(struct ldb_dn *dn)
2133 : {
2134 1259215105 : if ( ! dn || dn->invalid) return false;
2135 1258346070 : return dn->special;
2136 : }
2137 :
2138 306594535 : bool ldb_dn_has_extended(struct ldb_dn *dn)
2139 : {
2140 306594535 : if ( ! dn || dn->invalid) return false;
2141 306594535 : if (dn->ext_linearized && (dn->ext_linearized[0] == '<')) return true;
2142 295446990 : return dn->ext_comp_num != 0;
2143 : }
2144 :
2145 11133808 : bool ldb_dn_check_special(struct ldb_dn *dn, const char *check)
2146 : {
2147 11133808 : if ( ! dn || dn->invalid) return false;
2148 11133808 : return ! strcmp(dn->linearized, check);
2149 : }
2150 :
2151 266961640 : bool ldb_dn_is_null(struct ldb_dn *dn)
2152 : {
2153 266961640 : if ( ! dn || dn->invalid) return false;
2154 266961640 : if (ldb_dn_has_extended(dn)) return false;
2155 231709075 : if (dn->linearized && (dn->linearized[0] == '\0')) return true;
2156 212520079 : return false;
2157 : }
2158 :
2159 : /*
2160 : this updates dn->components, taking the components from ref_dn.
2161 : This is used by code that wants to update the DN path of a DN
2162 : while not impacting on the extended DN components
2163 : */
2164 9071 : int ldb_dn_update_components(struct ldb_dn *dn, const struct ldb_dn *ref_dn)
2165 : {
2166 9071 : dn->components = talloc_realloc(dn, dn->components,
2167 : struct ldb_dn_component, ref_dn->comp_num);
2168 9071 : if (!dn->components) {
2169 0 : return LDB_ERR_OPERATIONS_ERROR;
2170 : }
2171 9071 : memcpy(dn->components, ref_dn->components,
2172 9071 : sizeof(struct ldb_dn_component)*ref_dn->comp_num);
2173 9071 : dn->comp_num = ref_dn->comp_num;
2174 :
2175 9071 : LDB_FREE(dn->casefold);
2176 9071 : LDB_FREE(dn->linearized);
2177 9071 : LDB_FREE(dn->ext_linearized);
2178 :
2179 9071 : return LDB_SUCCESS;
2180 : }
2181 :
2182 : /*
2183 : minimise a DN. The caller must pass in a validated DN.
2184 :
2185 : If the DN has an extended component then only the first extended
2186 : component is kept, the DN string is stripped.
2187 :
2188 : The existing dn is modified
2189 : */
2190 5108272 : bool ldb_dn_minimise(struct ldb_dn *dn)
2191 : {
2192 : unsigned int i;
2193 :
2194 5108272 : if (!ldb_dn_validate(dn)) {
2195 0 : return false;
2196 : }
2197 5108272 : if (dn->ext_comp_num == 0) {
2198 0 : return true;
2199 : }
2200 :
2201 : /* free components */
2202 26780945 : for (i = 0; i < dn->comp_num; i++) {
2203 21672673 : LDB_FREE(dn->components[i].name);
2204 21672673 : LDB_FREE(dn->components[i].value.data);
2205 21672673 : LDB_FREE(dn->components[i].cf_name);
2206 21672673 : LDB_FREE(dn->components[i].cf_value.data);
2207 : }
2208 5108272 : dn->comp_num = 0;
2209 5108272 : dn->valid_case = false;
2210 :
2211 5108272 : LDB_FREE(dn->casefold);
2212 5108272 : LDB_FREE(dn->linearized);
2213 :
2214 : /* note that we don't free dn->components as this there are
2215 : * several places in ldb_dn.c that rely on it being non-NULL
2216 : * for an exploded DN
2217 : */
2218 :
2219 7426924 : for (i = 1; i < dn->ext_comp_num; i++) {
2220 2318652 : LDB_FREE(dn->ext_components[i].value.data);
2221 : }
2222 5108272 : dn->ext_comp_num = 1;
2223 :
2224 5108272 : dn->ext_components = talloc_realloc(dn, dn->ext_components, struct ldb_dn_ext_component, 1);
2225 5108272 : if (dn->ext_components == NULL) {
2226 0 : ldb_dn_mark_invalid(dn);
2227 0 : return false;
2228 : }
2229 :
2230 5108272 : LDB_FREE(dn->ext_linearized);
2231 :
2232 5108272 : return true;
2233 : }
2234 :
2235 580926 : struct ldb_context *ldb_dn_get_ldb_context(struct ldb_dn *dn)
2236 : {
2237 580926 : return dn->ldb;
2238 : }
|