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 20171 : static void ldb_dn_mark_invalid(struct ldb_dn *dn)
84 : {
85 20171 : dn->invalid = true;
86 20154 : }
87 :
88 : /* strdn may be NULL */
89 915333763 : 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 25241471 : struct ldb_dn *dn;
94 :
95 915333763 : if (ldb == NULL || strdn == NULL) {
96 0 : return NULL;
97 : }
98 915333763 : if (strdn->data
99 885866169 : && (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 915333760 : dn = talloc_zero(mem_ctx, struct ldb_dn);
105 915333760 : LDB_DN_NULL_FAILED(dn);
106 :
107 915333760 : dn->ldb = talloc_get_type(ldb, struct ldb_context);
108 915333760 : 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 1775668492 : if (strdn->data && strdn->length) {
116 884957307 : const char *data = (const char *)strdn->data;
117 884957307 : size_t length = strdn->length;
118 :
119 884957307 : if (data[0] == '@') {
120 413367402 : dn->special = true;
121 : }
122 884957307 : dn->ext_linearized = talloc_strndup(dn, data, length);
123 884957307 : LDB_DN_NULL_FAILED(dn->ext_linearized);
124 :
125 884957307 : if (data[0] == '<') {
126 42293439 : const char *p_save, *p = dn->ext_linearized;
127 2313156 : do {
128 122355082 : p_save = p;
129 122355082 : p = strstr(p, ">;");
130 122355082 : if (p) {
131 78953539 : p = p + 2;
132 : }
133 122355082 : } while (p);
134 :
135 43401543 : if (p_save == dn->ext_linearized) {
136 8514847 : dn->linearized = talloc_strdup(dn, "");
137 : } else {
138 34886696 : dn->linearized = talloc_strdup(dn, p_save);
139 : }
140 43401543 : LDB_DN_NULL_FAILED(dn->linearized);
141 : } else {
142 841555764 : dn->linearized = dn->ext_linearized;
143 841555764 : dn->ext_linearized = NULL;
144 : }
145 : } else {
146 30376453 : dn->linearized = talloc_strdup(dn, "");
147 30376453 : LDB_DN_NULL_FAILED(dn->linearized);
148 : }
149 :
150 890092292 : return dn;
151 :
152 0 : failed:
153 0 : talloc_free(dn);
154 0 : return NULL;
155 : }
156 :
157 : /* strdn may be NULL */
158 344839920 : struct ldb_dn *ldb_dn_new(TALLOC_CTX *mem_ctx,
159 : struct ldb_context *ldb,
160 : const char *strdn)
161 : {
162 11319035 : struct ldb_val blob;
163 344839920 : blob.data = discard_const_p(uint8_t, strdn);
164 344839920 : blob.length = strdn ? strlen(strdn) : 0;
165 344839920 : return ldb_dn_from_ldb_val(mem_ctx, ldb, &blob);
166 : }
167 :
168 201978240 : struct ldb_dn *ldb_dn_new_fmt(TALLOC_CTX *mem_ctx,
169 : struct ldb_context *ldb,
170 : const char *new_fmt, ...)
171 : {
172 6616060 : char *strdn;
173 6616060 : va_list ap;
174 :
175 201978240 : if (! ldb) return NULL;
176 :
177 201978240 : va_start(ap, new_fmt);
178 201978240 : strdn = talloc_vasprintf(mem_ctx, new_fmt, ap);
179 201978240 : va_end(ap);
180 :
181 201978240 : if (strdn) {
182 201978240 : struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb, strdn);
183 201978240 : talloc_free(strdn);
184 201978240 : return dn;
185 : }
186 :
187 0 : return NULL;
188 : }
189 :
190 : /* see RFC2253 section 2.4 */
191 234501565 : static int ldb_dn_escape_internal(char *dst, const char *src, int len)
192 : {
193 14354446 : char c;
194 14354446 : char *d;
195 14354446 : int i;
196 234501565 : d = dst;
197 :
198 2252874382 : for (i = 0; i < len; i++){
199 2018372817 : c = src[i];
200 2018372817 : switch (c) {
201 14993540 : case ' ':
202 14993540 : 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 14993540 : *d++ = c;
210 : }
211 14062568 : break;
212 :
213 37089 : 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 37089 : *d++ = '\\';
225 37089 : *d++ = c;
226 37089 : break;
227 :
228 1722089 : case ';':
229 : case '\r':
230 : case '\n':
231 : case '=':
232 : case '\0': {
233 : /* any others get \XX form */
234 925 : unsigned char v;
235 1722089 : const char *hexbytes = "0123456789ABCDEF";
236 1722089 : v = (const unsigned char)c;
237 1722089 : *d++ = '\\';
238 1722089 : *d++ = hexbytes[v>>4];
239 1722089 : *d++ = hexbytes[v&0xF];
240 1722089 : break;
241 : }
242 2001620099 : default:
243 2001620099 : *d++ = c;
244 : }
245 : }
246 :
247 : /* return the length of the resulting string */
248 234501565 : return (d - dst);
249 : }
250 :
251 15556736 : char *ldb_dn_escape_value(TALLOC_CTX *mem_ctx, struct ldb_val value)
252 : {
253 952973 : char *dst;
254 952973 : size_t len;
255 15556736 : if (!value.length)
256 2 : return NULL;
257 :
258 : /* allocate destination string, it will be at most 3 times the source */
259 15556734 : dst = talloc_array(mem_ctx, char, value.length * 3 + 1);
260 15556734 : if ( ! dst) {
261 0 : talloc_free(dst);
262 0 : return NULL;
263 : }
264 :
265 15556734 : len = ldb_dn_escape_internal(dst, (const char *)value.data, value.length);
266 :
267 15556734 : dst = talloc_realloc(mem_ctx, dst, char, len + 1);
268 15556734 : if ( ! dst) {
269 0 : talloc_free(dst);
270 0 : return NULL;
271 : }
272 15556734 : dst[len] = '\0';
273 15556734 : 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 1229945543 : static bool ldb_dn_explode(struct ldb_dn *dn)
284 : {
285 1229945543 : char *p, *ex_name = NULL, *ex_value = NULL, *data, *d, *dt, *t;
286 1229945543 : bool trim = true;
287 1229945543 : bool in_extended = true;
288 1229945543 : bool in_ex_name = false;
289 1229945543 : bool in_ex_value = false;
290 1229945543 : bool in_attr = false;
291 1229945543 : bool in_value = false;
292 1229945543 : bool in_quote = false;
293 1229945543 : bool is_oid = false;
294 1229945543 : bool escape = false;
295 36212681 : unsigned int x;
296 1229945543 : size_t l = 0;
297 36212681 : int ret;
298 36212681 : char *parse_dn;
299 36212681 : bool is_index;
300 :
301 1229945543 : if (dn == NULL || dn->invalid) {
302 724 : return false;
303 : }
304 :
305 1229944819 : if (dn->components != NULL) {
306 643421576 : return true;
307 : }
308 :
309 564032721 : if (dn->ext_linearized != NULL) {
310 38824537 : parse_dn = dn->ext_linearized;
311 : } else {
312 524341308 : parse_dn = dn->linearized;
313 : }
314 :
315 564032721 : if (parse_dn == NULL) {
316 0 : return false;
317 : }
318 :
319 564032721 : is_index = (strncmp(parse_dn, "DN=@INDEX:", 10) == 0);
320 :
321 : /* Empty DNs */
322 564032721 : if (parse_dn[0] == '\0') {
323 30802996 : return true;
324 : }
325 :
326 : /* Special DNs case */
327 532290297 : if (dn->special) {
328 256988674 : return true;
329 : }
330 :
331 267576152 : LDB_FREE(dn->ext_components);
332 267576152 : dn->ext_comp_num = 0;
333 267576152 : 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 267576152 : dn->components = talloc_zero_array(dn, struct ldb_dn_component, 3);
338 267576152 : if (dn->components == NULL) {
339 0 : return false;
340 : }
341 :
342 : /* Components data space is allocated here once */
343 267576152 : data = talloc_array(dn->components, char, strlen(parse_dn) + 1);
344 267576152 : if (data == NULL) {
345 0 : goto failed;
346 : }
347 :
348 262518892 : p = parse_dn;
349 262518892 : t = NULL;
350 262518892 : d = dt = data;
351 :
352 26116955221 : while (*p) {
353 25857895137 : if (in_extended) {
354 :
355 3277817566 : if (!in_ex_name && !in_ex_value) {
356 :
357 338182096 : if (p[0] == '<') {
358 79120807 : p++;
359 79120807 : ex_name = d;
360 79120807 : in_ex_name = true;
361 79120807 : continue;
362 : } else {
363 259061289 : in_extended = false;
364 259061289 : in_attr = true;
365 259061289 : dt = d;
366 :
367 259061289 : continue;
368 : }
369 : }
370 :
371 2939635470 : if (in_ex_name && *p == '=') {
372 79120803 : *d++ = '\0';
373 79120803 : p++;
374 79120803 : ex_value = d;
375 79120803 : in_ex_name = false;
376 79120803 : in_ex_value = true;
377 79120803 : continue;
378 : }
379 :
380 2860514667 : if (in_ex_value && *p == '>') {
381 79120803 : struct ldb_dn_ext_component *ext_comp = NULL;
382 1165146 : const struct ldb_dn_extended_syntax *ext_syntax;
383 79120803 : struct ldb_val ex_val = {
384 : .data = (uint8_t *)ex_value,
385 79120803 : .length = d - ex_value
386 : };
387 :
388 79120803 : *d++ = '\0';
389 79120803 : p++;
390 79120803 : in_ex_value = false;
391 :
392 : /* Process name and ex_value */
393 :
394 79120803 : ext_comp = talloc_realloc(
395 : dn,
396 : dn->ext_components,
397 : struct ldb_dn_ext_component,
398 : dn->ext_comp_num + 1);
399 :
400 79120803 : if (ext_comp == NULL) {
401 : /* ouch ! */
402 450 : goto failed;
403 : }
404 :
405 79120803 : dn->ext_components = ext_comp;
406 :
407 79120803 : ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, ex_name);
408 79120803 : if (ext_syntax == NULL) {
409 : /* We don't know about this type of extended DN */
410 9 : goto failed;
411 : }
412 :
413 79120794 : dn->ext_components[dn->ext_comp_num].name = ext_syntax->name;
414 79120794 : ret = ext_syntax->read_fn(dn->ldb, dn->ext_components,
415 77955649 : &ex_val, &dn->ext_components[dn->ext_comp_num].value);
416 79120794 : if (ret != LDB_SUCCESS) {
417 441 : ldb_dn_mark_invalid(dn);
418 441 : goto failed;
419 : }
420 :
421 79120353 : dn->ext_comp_num++;
422 :
423 79120353 : if (*p == '\0') {
424 : /* We have reached the end (extended component only)! */
425 8514409 : talloc_free(data);
426 8514409 : return true;
427 :
428 70605944 : } else if (*p == ';') {
429 70605944 : p++;
430 70605944 : continue;
431 : } else {
432 0 : ldb_dn_mark_invalid(dn);
433 0 : goto failed;
434 : }
435 : }
436 :
437 2781393864 : *d++ = *p++;
438 2781393864 : continue;
439 : }
440 22580077571 : if (in_attr) {
441 4493668223 : if (trim) {
442 1519296851 : if (*p == ' ') {
443 34066664 : p++;
444 34066664 : continue;
445 : }
446 :
447 : /* first char */
448 1485230187 : trim = false;
449 :
450 1485230187 : if (!isascii(*p)) {
451 : /* attr names must be ascii only */
452 0 : ldb_dn_mark_invalid(dn);
453 0 : goto failed;
454 : }
455 :
456 1485230187 : if (isdigit(*p)) {
457 0 : is_oid = true;
458 : } else
459 1485230187 : 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 1485230180 : *d++ = *p++;
469 1485230180 : continue;
470 : }
471 :
472 2974371372 : if (*p == ' ') {
473 96 : p++;
474 : /* valid only if we are at the end */
475 96 : trim = true;
476 96 : continue;
477 : }
478 :
479 2974371276 : if (*p == '=') {
480 : /* attribute terminated */
481 1485210366 : in_attr = false;
482 1485210366 : in_value = true;
483 1485210366 : trim = true;
484 1485210366 : l = 0;
485 :
486 : /* Terminate this string in d
487 : * (which is a copy of parse_dn
488 : * with spaces trimmed) */
489 1485210366 : *d++ = '\0';
490 1485210366 : dn->components[dn->comp_num].name = talloc_strdup(dn->components, dt);
491 1485210366 : if (dn->components[dn->comp_num].name == NULL) {
492 : /* ouch */
493 0 : goto failed;
494 : }
495 :
496 1485210366 : dt = d;
497 :
498 1485210366 : p++;
499 1485210366 : continue;
500 : }
501 :
502 1489160910 : if (!isascii(*p)) {
503 : /* attr names must be ascii only */
504 0 : ldb_dn_mark_invalid(dn);
505 0 : goto failed;
506 : }
507 :
508 1489160910 : 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 1489160910 : if ( ! (isalpha(*p) || isdigit(*p) || (*p == '-'))) {
515 : /* not ALPHA, DIGIT or HYPHEN */
516 1202 : ldb_dn_mark_invalid(dn);
517 1202 : goto failed;
518 : }
519 :
520 1489159708 : *d++ = *p++;
521 1489159708 : continue;
522 : }
523 :
524 18086409348 : if (in_value) {
525 18086409348 : 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 18086409348 : if (trim) {
539 1485210358 : if (*p == ' ') {
540 0 : p++;
541 0 : continue;
542 : }
543 :
544 : /* first char */
545 1485210358 : trim = false;
546 :
547 1485210358 : if (*p == '\"') {
548 0 : in_quote = true;
549 0 : p++;
550 0 : continue;
551 : }
552 : }
553 :
554 18086409348 : switch (*p) {
555 :
556 : /* TODO: support ber encoded values
557 : case '#':
558 : */
559 :
560 1226195654 : case ',':
561 1226195654 : if (escape) {
562 26847 : *d++ = *p++;
563 26847 : l++;
564 26847 : escape = false;
565 26847 : continue;
566 : }
567 : /* ok found value terminator */
568 :
569 1226168807 : if (t != NULL) {
570 : /* trim back */
571 44 : d -= (p - t);
572 44 : l -= (p - t);
573 44 : t = NULL;
574 : }
575 :
576 1226168807 : in_attr = true;
577 1226168807 : in_value = false;
578 1226168807 : trim = true;
579 :
580 1226168807 : p++;
581 1226168807 : *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 2452337614 : dn->components[dn->comp_num].value.data = \
589 1226168807 : (uint8_t *)talloc_memdup(dn->components, dt, l + 1);
590 1226168807 : dn->components[dn->comp_num].value.length = l;
591 1226168807 : if (dn->components[dn->comp_num].value.data == NULL) {
592 : /* ouch ! */
593 0 : goto failed;
594 : }
595 1226168807 : talloc_set_name_const(dn->components[dn->comp_num].value.data,
596 1201931304 : (const char *)dn->components[dn->comp_num].value.data);
597 :
598 1226168807 : dt = d;
599 :
600 1226168807 : dn->comp_num++;
601 1226168807 : if (dn->comp_num > 2) {
602 716874494 : dn->components = talloc_realloc(dn,
603 : dn->components,
604 : struct ldb_dn_component,
605 : dn->comp_num + 1);
606 716874494 : if (dn->components == NULL) {
607 : /* ouch ! */
608 0 : goto failed;
609 : }
610 : /* make sure all components are zeroed, other functions depend on this */
611 716874494 : memset(&dn->components[dn->comp_num], '\0', sizeof(struct ldb_dn_component));
612 : }
613 :
614 1226168807 : 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 85304016 : case '\\':
653 85304016 : if (!escape) {
654 85293216 : escape = true;
655 85293216 : p++;
656 85293216 : 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 16774909678 : default:
669 16774909678 : if (escape) {
670 85255569 : if (isxdigit(p[0]) && isxdigit(p[1])) {
671 85255569 : if (sscanf(p, "%02x", &x) != 1) {
672 : /* invalid escaping sequence */
673 0 : ldb_dn_mark_invalid(dn);
674 0 : goto failed;
675 : }
676 85255569 : p += 2;
677 85255569 : *d++ = (unsigned char)x;
678 : } else {
679 0 : *d++ = *p++;
680 : }
681 :
682 85255569 : escape = false;
683 85255569 : l++;
684 85255569 : if (t != NULL) {
685 0 : t = NULL;
686 : }
687 85254661 : break;
688 : }
689 :
690 16689654109 : if (*p == ' ') {
691 124234053 : if (t == NULL) {
692 124229960 : t = p;
693 : }
694 : } else {
695 16309874879 : if (t != NULL) {
696 123119196 : t = NULL;
697 : }
698 : }
699 :
700 16689654109 : *d++ = *p++;
701 16689654109 : l++;
702 :
703 16689654109 : break;
704 : }
705 :
706 : }
707 : }
708 :
709 259060084 : if (in_attr || in_quote) {
710 : /* invalid dn */
711 18521 : ldb_dn_mark_invalid(dn);
712 18521 : goto failed;
713 : }
714 :
715 259041563 : if (in_value) {
716 : /* save last element */
717 259041559 : if (t != NULL) {
718 : /* trim back */
719 190 : d -= (p - t);
720 190 : l -= (p - t);
721 : }
722 :
723 259041559 : *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 259041559 : dn->components[dn->comp_num].value.length = l;
730 518083118 : dn->components[dn->comp_num].value.data =
731 259041559 : (uint8_t *)talloc_memdup(dn->components, dt, l + 1);
732 259041559 : if (dn->components[dn->comp_num].value.data == NULL) {
733 : /* ouch */
734 0 : goto failed;
735 : }
736 259041559 : talloc_set_name_const(dn->components[dn->comp_num].value.data,
737 254213289 : (const char *)dn->components[dn->comp_num].value.data);
738 :
739 259041559 : dn->comp_num++;
740 : }
741 259041563 : talloc_free(data);
742 259041563 : return true;
743 :
744 20180 : failed:
745 20180 : LDB_FREE(dn->components); /* "data" is implicitly free'd */
746 20180 : dn->comp_num = 0;
747 20180 : LDB_FREE(dn->ext_components);
748 20180 : dn->ext_comp_num = 0;
749 :
750 20180 : return false;
751 : }
752 :
753 1132526437 : bool ldb_dn_validate(struct ldb_dn *dn)
754 : {
755 1132526437 : return ldb_dn_explode(dn);
756 : }
757 :
758 764102013 : const char *ldb_dn_get_linearized(struct ldb_dn *dn)
759 : {
760 25129327 : unsigned int i;
761 25129327 : size_t len;
762 25129327 : char *d, *n;
763 :
764 764102013 : if ( ! dn || ( dn->invalid)) return NULL;
765 :
766 764101596 : if (dn->linearized) return dn->linearized;
767 :
768 10807775 : if ( ! dn->components) {
769 0 : ldb_dn_mark_invalid(dn);
770 0 : return NULL;
771 : }
772 :
773 10807775 : if (dn->comp_num == 0) {
774 539185 : dn->linearized = talloc_strdup(dn, "");
775 539185 : if ( ! dn->linearized) return NULL;
776 539185 : return dn->linearized;
777 : }
778 :
779 : /* calculate maximum possible length of DN */
780 66995147 : for (len = 0, i = 0; i < dn->comp_num; i++) {
781 : /* name len */
782 56726557 : len += strlen(dn->components[i].name);
783 : /* max escaped data len */
784 56726557 : len += (dn->components[i].value.length * 3);
785 56726557 : len += 2; /* '=' and ',' */
786 : }
787 10268590 : dn->linearized = talloc_array(dn, char, len);
788 10268590 : if ( ! dn->linearized) return NULL;
789 :
790 9642381 : d = dn->linearized;
791 :
792 66995147 : for (i = 0; i < dn->comp_num; i++) {
793 :
794 : /* copy the name */
795 56726557 : n = dn->components[i].name;
796 170180250 : while (*n) *d++ = *n++;
797 :
798 56726557 : *d++ = '=';
799 :
800 : /* and the value */
801 113453114 : d += ldb_dn_escape_internal( d,
802 56726557 : (char *)dn->components[i].value.data,
803 56726557 : dn->components[i].value.length);
804 56726557 : *d++ = ',';
805 : }
806 :
807 10268590 : *(--d) = '\0';
808 :
809 : /* don't waste more memory than necessary */
810 10268590 : dn->linearized = talloc_realloc(dn, dn->linearized,
811 : char, (d - dn->linearized + 1));
812 :
813 10268590 : return dn->linearized;
814 : }
815 :
816 49395853 : static int ldb_dn_extended_component_compare(const void *p1, const void *p2)
817 : {
818 49395853 : const struct ldb_dn_ext_component *ec1 = (const struct ldb_dn_ext_component *)p1;
819 49395853 : const struct ldb_dn_ext_component *ec2 = (const struct ldb_dn_ext_component *)p2;
820 49395853 : return strcmp(ec1->name, ec2->name);
821 : }
822 :
823 27765822 : char *ldb_dn_get_extended_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int mode)
824 : {
825 27765822 : const char *linearized = ldb_dn_get_linearized(dn);
826 27765822 : char *p = NULL;
827 619614 : unsigned int i;
828 :
829 27765822 : if (!linearized) {
830 96 : return NULL;
831 : }
832 :
833 27765726 : if (!ldb_dn_has_extended(dn)) {
834 1538154 : return talloc_strdup(mem_ctx, linearized);
835 : }
836 :
837 26227572 : 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 26227569 : TYPESAFE_QSORT(dn->ext_components, dn->ext_comp_num,
846 : ldb_dn_extended_component_compare);
847 :
848 77373915 : for (i = 0; i < dn->ext_comp_num; i++) {
849 626413 : const struct ldb_dn_extended_syntax *ext_syntax;
850 51146346 : const char *name = dn->ext_components[i].name;
851 51146346 : struct ldb_val ec_val = dn->ext_components[i].value;
852 626413 : struct ldb_val val;
853 626413 : int ret;
854 :
855 51146346 : ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name);
856 51146346 : if (!ext_syntax) {
857 0 : return NULL;
858 : }
859 :
860 51146346 : if (mode == 1) {
861 40902766 : ret = ext_syntax->write_clear_fn(dn->ldb, mem_ctx,
862 : &ec_val, &val);
863 10243580 : } else if (mode == 0) {
864 10243580 : ret = ext_syntax->write_hex_fn(dn->ldb, mem_ctx,
865 : &ec_val, &val);
866 : } else {
867 0 : ret = -1;
868 : }
869 :
870 51146346 : if (ret != LDB_SUCCESS) {
871 0 : return NULL;
872 : }
873 :
874 51146346 : if (i == 0) {
875 26227565 : p = talloc_asprintf(mem_ctx, "<%s=%.*s>",
876 : name,
877 26227565 : (int)val.length,
878 : val.data);
879 : } else {
880 24918781 : talloc_asprintf_addbuf(&p, ";<%s=%.*s>",
881 : name,
882 24918781 : (int)val.length,
883 : val.data);
884 : }
885 :
886 51146346 : talloc_free(val.data);
887 : }
888 :
889 26227569 : if (dn->ext_comp_num && *linearized) {
890 24988876 : talloc_asprintf_addbuf(&p, ";%s", linearized);
891 : }
892 :
893 26227569 : if (!p) {
894 4 : return NULL;
895 : }
896 :
897 25716862 : return p;
898 : }
899 :
900 : /*
901 : filter out all but an acceptable list of extended DN components
902 : */
903 16545622 : void ldb_dn_extended_filter(struct ldb_dn *dn, const char * const *accept_list)
904 : {
905 202699 : unsigned int i;
906 58106359 : for (i=0; i<dn->ext_comp_num; i++) {
907 41560737 : if (!ldb_attr_in_list(accept_list, dn->ext_components[i].name)) {
908 19034511 : ARRAY_DEL_ELEMENT(
909 3052 : dn->ext_components, i, dn->ext_comp_num);
910 19034511 : dn->ext_comp_num--;
911 19034511 : i--;
912 : }
913 : }
914 16545622 : LDB_FREE(dn->ext_linearized);
915 16545622 : }
916 :
917 :
918 171995322 : char *ldb_dn_alloc_linearized(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
919 : {
920 171995322 : 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 278316816 : static bool ldb_dn_casefold_internal(struct ldb_dn *dn)
929 : {
930 4284712 : unsigned int i;
931 4284712 : int ret;
932 :
933 278316816 : if ( ! dn || dn->invalid) return false;
934 :
935 278316816 : if (dn->valid_case) return true;
936 :
937 139352049 : if (( ! dn->components) && ( ! ldb_dn_explode(dn))) {
938 892 : return false;
939 : }
940 :
941 881982450 : for (i = 0; i < dn->comp_num; i++) {
942 12232192 : const struct ldb_schema_attribute *a;
943 :
944 1485262586 : dn->components[i].cf_name =
945 742631293 : ldb_attr_casefold(dn->components,
946 742631293 : dn->components[i].name);
947 742631293 : if (!dn->components[i].cf_name) {
948 0 : goto failed;
949 : }
950 :
951 742631293 : a = ldb_schema_attribute_by_name(dn->ldb,
952 730399101 : dn->components[i].cf_name);
953 :
954 754863485 : ret = a->syntax->canonicalise_fn(dn->ldb, dn->components,
955 742631293 : &(dn->components[i].value),
956 742631293 : &(dn->components[i].cf_value));
957 742631293 : if (ret != 0) {
958 0 : goto failed;
959 : }
960 : }
961 :
962 139351157 : dn->valid_case = true;
963 :
964 139351157 : 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 501454023 : const char *ldb_dn_get_casefold(struct ldb_dn *dn)
975 : {
976 15996441 : unsigned int i;
977 15996441 : size_t len;
978 15996441 : char *d, *n;
979 :
980 501454023 : if (dn->casefold) return dn->casefold;
981 :
982 314236953 : if (dn->special) {
983 281559877 : dn->casefold = talloc_strdup(dn, dn->linearized);
984 281559877 : if (!dn->casefold) return NULL;
985 281559877 : dn->valid_case = true;
986 281559877 : return dn->casefold;
987 : }
988 :
989 32677076 : if ( ! ldb_dn_casefold_internal(dn)) {
990 0 : return NULL;
991 : }
992 :
993 32677076 : if (dn->comp_num == 0) {
994 1506 : dn->casefold = talloc_strdup(dn, "");
995 1506 : return dn->casefold;
996 : }
997 :
998 : /* calculate maximum possible length of DN */
999 194893844 : for (len = 0, i = 0; i < dn->comp_num; i++) {
1000 : /* name len */
1001 162218274 : len += strlen(dn->components[i].cf_name);
1002 : /* max escaped data len */
1003 162218274 : len += (dn->components[i].cf_value.length * 3);
1004 162218274 : len += 2; /* '=' and ',' */
1005 : }
1006 32675570 : dn->casefold = talloc_array(dn, char, len);
1007 32675570 : if ( ! dn->casefold) return NULL;
1008 :
1009 30689458 : d = dn->casefold;
1010 :
1011 194893844 : for (i = 0; i < dn->comp_num; i++) {
1012 :
1013 : /* copy the name */
1014 162218274 : n = dn->components[i].cf_name;
1015 488178951 : while (*n) *d++ = *n++;
1016 :
1017 162218274 : *d++ = '=';
1018 :
1019 : /* and the value */
1020 324436548 : d += ldb_dn_escape_internal( d,
1021 162218274 : (char *)dn->components[i].cf_value.data,
1022 162218274 : dn->components[i].cf_value.length);
1023 162218274 : *d++ = ',';
1024 : }
1025 32675570 : *(--d) = '\0';
1026 :
1027 : /* don't waste more memory than necessary */
1028 32675570 : dn->casefold = talloc_realloc(dn, dn->casefold,
1029 : char, strlen(dn->casefold) + 1);
1030 :
1031 32675570 : return dn->casefold;
1032 : }
1033 :
1034 2476866 : char *ldb_dn_alloc_casefold(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
1035 : {
1036 2476866 : return talloc_strdup(mem_ctx, ldb_dn_get_casefold(dn));
1037 : }
1038 :
1039 : /* Determine if dn is below base, in the ldap tree. Used for
1040 : * evaluating a subtree search.
1041 : * 0 if they match, otherwise non-zero
1042 : */
1043 :
1044 573715218 : int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn)
1045 : {
1046 12288350 : int ret;
1047 12288350 : unsigned int n_base, n_dn;
1048 :
1049 573715218 : if ( ! base || base->invalid) return 1;
1050 573715218 : if ( ! dn || dn->invalid) return -1;
1051 :
1052 573715218 : if (( ! base->valid_case) || ( ! dn->valid_case)) {
1053 395063385 : if (base->linearized && dn->linearized && dn->special == base->special) {
1054 : /* try with a normal compare first, if we are lucky
1055 : * we will avoid exploding and casefolding */
1056 6455595 : int dif;
1057 387396025 : dif = strlen(dn->linearized) - strlen(base->linearized);
1058 387396025 : if (dif < 0) {
1059 126284526 : return dif;
1060 : }
1061 258745206 : if (strcmp(base->linearized,
1062 258745206 : &dn->linearized[dif]) == 0) {
1063 148980826 : return 0;
1064 : }
1065 : }
1066 :
1067 113726375 : if ( ! ldb_dn_casefold_internal(base)) {
1068 0 : return 1;
1069 : }
1070 :
1071 113726375 : if ( ! ldb_dn_casefold_internal(dn)) {
1072 0 : return -1;
1073 : }
1074 :
1075 : }
1076 :
1077 : /* if base has more components,
1078 : * they don't have the same base */
1079 292378208 : if (base->comp_num > dn->comp_num) {
1080 54946053 : return (dn->comp_num - base->comp_num);
1081 : }
1082 :
1083 237432155 : if ((dn->comp_num == 0) || (base->comp_num == 0)) {
1084 1 : if (dn->special && base->special) {
1085 0 : return strcmp(base->linearized, dn->linearized);
1086 1 : } else if (dn->special) {
1087 0 : return -1;
1088 1 : } else if (base->special) {
1089 0 : return 1;
1090 : } else {
1091 0 : return 0;
1092 : }
1093 : }
1094 :
1095 237432154 : n_base = base->comp_num - 1;
1096 237432154 : n_dn = dn->comp_num - 1;
1097 :
1098 1115105401 : while (n_base != (unsigned int) -1) {
1099 1018859751 : char *b_name = base->components[n_base].cf_name;
1100 1018859751 : char *dn_name = dn->components[n_dn].cf_name;
1101 :
1102 1018859751 : char *b_vdata = (char *)base->components[n_base].cf_value.data;
1103 1018859751 : char *dn_vdata = (char *)dn->components[n_dn].cf_value.data;
1104 :
1105 1018859751 : size_t b_vlen = base->components[n_base].cf_value.length;
1106 1018859751 : size_t dn_vlen = dn->components[n_dn].cf_value.length;
1107 :
1108 : /* compare attr names */
1109 1018859751 : ret = strcmp(b_name, dn_name);
1110 1018859751 : if (ret != 0) return ret;
1111 :
1112 : /* compare attr.cf_value. */
1113 926810967 : if (b_vlen != dn_vlen) {
1114 47457121 : return b_vlen - dn_vlen;
1115 : }
1116 879353846 : ret = strncmp(b_vdata, dn_vdata, b_vlen);
1117 879353846 : if (ret != 0) return ret;
1118 :
1119 877673247 : n_base--;
1120 877673247 : n_dn--;
1121 : }
1122 :
1123 92692697 : return 0;
1124 : }
1125 :
1126 : /* compare DNs using casefolding compare functions.
1127 :
1128 : If they match, then return 0
1129 : */
1130 :
1131 68694090 : int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1)
1132 : {
1133 4485239 : unsigned int i;
1134 4485239 : int ret;
1135 :
1136 68694090 : if (( ! dn0) || dn0->invalid || ! dn1 || dn1->invalid) {
1137 8 : return -1;
1138 : }
1139 :
1140 68694082 : if (( ! dn0->valid_case) || ( ! dn1->valid_case)) {
1141 10582859 : if (dn0->linearized && dn1->linearized) {
1142 : /* try with a normal compare first, if we are lucky
1143 : * we will avoid exploding and casefolding */
1144 8471965 : if (strcmp(dn0->linearized, dn1->linearized) == 0) {
1145 1475484 : return 0;
1146 : }
1147 : }
1148 :
1149 9093495 : if ( ! ldb_dn_casefold_internal(dn0)) {
1150 0 : return 1;
1151 : }
1152 :
1153 9093495 : if ( ! ldb_dn_casefold_internal(dn1)) {
1154 892 : return -1;
1155 : }
1156 :
1157 : }
1158 :
1159 67203826 : if (dn0->comp_num != dn1->comp_num) {
1160 41626342 : return (dn1->comp_num - dn0->comp_num);
1161 : }
1162 :
1163 25577484 : if (dn0->comp_num == 0) {
1164 1113457 : if (dn0->special && dn1->special) {
1165 1113457 : return strcmp(dn0->linearized, dn1->linearized);
1166 0 : } else if (dn0->special) {
1167 0 : return 1;
1168 0 : } else if (dn1->special) {
1169 0 : return -1;
1170 : } else {
1171 0 : return 0;
1172 : }
1173 : }
1174 :
1175 71926175 : for (i = 0; i < dn0->comp_num; i++) {
1176 61656580 : char *dn0_name = dn0->components[i].cf_name;
1177 61656580 : char *dn1_name = dn1->components[i].cf_name;
1178 :
1179 61656580 : char *dn0_vdata = (char *)dn0->components[i].cf_value.data;
1180 61656580 : char *dn1_vdata = (char *)dn1->components[i].cf_value.data;
1181 :
1182 61656580 : size_t dn0_vlen = dn0->components[i].cf_value.length;
1183 61656580 : size_t dn1_vlen = dn1->components[i].cf_value.length;
1184 :
1185 : /* compare attr names */
1186 61656580 : ret = strcmp(dn0_name, dn1_name);
1187 61656580 : if (ret != 0) {
1188 3441928 : return ret;
1189 : }
1190 :
1191 : /* compare attr.cf_value. */
1192 58214652 : if (dn0_vlen != dn1_vlen) {
1193 6037381 : return dn0_vlen - dn1_vlen;
1194 : }
1195 52177271 : ret = strncmp(dn0_vdata, dn1_vdata, dn0_vlen);
1196 52177271 : if (ret != 0) {
1197 4715123 : return ret;
1198 : }
1199 : }
1200 :
1201 9731678 : return 0;
1202 : }
1203 :
1204 413992623 : static struct ldb_dn_component ldb_dn_copy_component(
1205 : TALLOC_CTX *mem_ctx,
1206 : struct ldb_dn_component *src)
1207 : {
1208 20825377 : struct ldb_dn_component dst;
1209 :
1210 413992623 : memset(&dst, 0, sizeof(dst));
1211 :
1212 413992623 : if (src == NULL) {
1213 0 : return dst;
1214 : }
1215 :
1216 413992623 : dst.value = ldb_val_dup(mem_ctx, &(src->value));
1217 413992623 : if (dst.value.data == NULL) {
1218 0 : return dst;
1219 : }
1220 :
1221 413992623 : dst.name = talloc_strdup(mem_ctx, src->name);
1222 413992623 : if (dst.name == NULL) {
1223 0 : LDB_FREE(dst.value.data);
1224 0 : return dst;
1225 : }
1226 :
1227 413992623 : if (src->cf_value.data) {
1228 343527787 : dst.cf_value = ldb_val_dup(mem_ctx, &(src->cf_value));
1229 343527787 : if (dst.cf_value.data == NULL) {
1230 0 : LDB_FREE(dst.value.data);
1231 0 : LDB_FREE(dst.name);
1232 0 : return dst;
1233 : }
1234 :
1235 343527787 : dst.cf_name = talloc_strdup(mem_ctx, src->cf_name);
1236 343527787 : if (dst.cf_name == NULL) {
1237 0 : LDB_FREE(dst.cf_name);
1238 0 : LDB_FREE(dst.value.data);
1239 0 : LDB_FREE(dst.name);
1240 0 : return dst;
1241 : }
1242 : } else {
1243 67386616 : dst.cf_value.data = NULL;
1244 67386616 : dst.cf_name = NULL;
1245 : }
1246 :
1247 413992623 : return dst;
1248 : }
1249 :
1250 32223643 : static struct ldb_dn_ext_component ldb_dn_ext_copy_component(
1251 : TALLOC_CTX *mem_ctx,
1252 : struct ldb_dn_ext_component *src)
1253 : {
1254 931929 : struct ldb_dn_ext_component dst;
1255 :
1256 32223643 : memset(&dst, 0, sizeof(dst));
1257 :
1258 32223643 : if (src == NULL) {
1259 0 : return dst;
1260 : }
1261 :
1262 32223643 : dst.value = ldb_val_dup(mem_ctx, &(src->value));
1263 32223643 : if (dst.value.data == NULL) {
1264 0 : return dst;
1265 : }
1266 :
1267 32223643 : dst.name = talloc_strdup(mem_ctx, src->name);
1268 32223643 : if (dst.name == NULL) {
1269 0 : LDB_FREE(dst.value.data);
1270 0 : return dst;
1271 : }
1272 :
1273 32223643 : return dst;
1274 : }
1275 :
1276 79178223 : struct ldb_dn *ldb_dn_copy(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
1277 : {
1278 3807403 : struct ldb_dn *new_dn;
1279 :
1280 79178223 : if (!dn || dn->invalid) {
1281 5 : return NULL;
1282 : }
1283 :
1284 79178218 : new_dn = talloc_zero(mem_ctx, struct ldb_dn);
1285 79178218 : if ( !new_dn) {
1286 0 : return NULL;
1287 : }
1288 :
1289 79178218 : *new_dn = *dn;
1290 :
1291 79178218 : if (dn->components) {
1292 3585722 : unsigned int i;
1293 :
1294 74018327 : new_dn->components =
1295 70432605 : talloc_zero_array(new_dn,
1296 : struct ldb_dn_component,
1297 : dn->comp_num);
1298 70432605 : if ( ! new_dn->components) {
1299 0 : talloc_free(new_dn);
1300 0 : return NULL;
1301 : }
1302 :
1303 468692035 : for (i = 0; i < dn->comp_num; i++) {
1304 398259430 : new_dn->components[i] =
1305 398259430 : ldb_dn_copy_component(new_dn->components,
1306 398259430 : &dn->components[i]);
1307 398259430 : if ( ! new_dn->components[i].value.data) {
1308 0 : talloc_free(new_dn);
1309 0 : return NULL;
1310 : }
1311 : }
1312 : }
1313 :
1314 79178218 : if (dn->ext_components) {
1315 801314 : unsigned int i;
1316 :
1317 26026679 : new_dn->ext_components =
1318 25225365 : talloc_zero_array(new_dn,
1319 : struct ldb_dn_ext_component,
1320 : dn->ext_comp_num);
1321 25225365 : if ( ! new_dn->ext_components) {
1322 0 : talloc_free(new_dn);
1323 0 : return NULL;
1324 : }
1325 :
1326 57449008 : for (i = 0; i < dn->ext_comp_num; i++) {
1327 32223643 : new_dn->ext_components[i] =
1328 32223643 : ldb_dn_ext_copy_component(
1329 32223643 : new_dn->ext_components,
1330 32223643 : &dn->ext_components[i]);
1331 32223643 : if ( ! new_dn->ext_components[i].value.data) {
1332 0 : talloc_free(new_dn);
1333 0 : return NULL;
1334 : }
1335 : }
1336 : }
1337 :
1338 79178218 : if (dn->casefold) {
1339 44978524 : new_dn->casefold = talloc_strdup(new_dn, dn->casefold);
1340 44978524 : if ( ! new_dn->casefold) {
1341 0 : talloc_free(new_dn);
1342 0 : return NULL;
1343 : }
1344 : }
1345 :
1346 79178218 : if (dn->linearized) {
1347 79031452 : new_dn->linearized = talloc_strdup(new_dn, dn->linearized);
1348 79031452 : if ( ! new_dn->linearized) {
1349 0 : talloc_free(new_dn);
1350 0 : return NULL;
1351 : }
1352 : }
1353 :
1354 79178218 : if (dn->ext_linearized) {
1355 2819994 : new_dn->ext_linearized = talloc_strdup(new_dn,
1356 1361604 : dn->ext_linearized);
1357 1458390 : if ( ! new_dn->ext_linearized) {
1358 0 : talloc_free(new_dn);
1359 0 : return NULL;
1360 : }
1361 : }
1362 :
1363 75370815 : return new_dn;
1364 : }
1365 :
1366 : /* modify the given dn by adding a base.
1367 : *
1368 : * return true if successful and false if not
1369 : * if false is returned the dn may be marked invalid
1370 : */
1371 626898 : bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base)
1372 : {
1373 4928 : const char *s;
1374 4928 : char *t;
1375 :
1376 626898 : if ( !base || base->invalid || !dn || dn->invalid) {
1377 0 : return false;
1378 : }
1379 :
1380 626898 : if (dn == base) {
1381 0 : return false; /* or we will visit infinity */
1382 : }
1383 :
1384 626898 : if (dn->components) {
1385 479 : unsigned int i;
1386 :
1387 453081 : if ( ! ldb_dn_validate(base)) {
1388 0 : return false;
1389 : }
1390 :
1391 453081 : s = NULL;
1392 453081 : if (dn->valid_case) {
1393 2 : if ( ! (s = ldb_dn_get_casefold(base))) {
1394 0 : return false;
1395 : }
1396 : }
1397 :
1398 453081 : dn->components = talloc_realloc(dn,
1399 : dn->components,
1400 : struct ldb_dn_component,
1401 : dn->comp_num + base->comp_num);
1402 453081 : if ( ! dn->components) {
1403 0 : ldb_dn_mark_invalid(dn);
1404 0 : return false;
1405 : }
1406 :
1407 2985875 : for (i = 0; i < base->comp_num; dn->comp_num++, i++) {
1408 2532794 : dn->components[dn->comp_num] =
1409 2532794 : ldb_dn_copy_component(dn->components,
1410 2532794 : &base->components[i]);
1411 2532794 : if (dn->components[dn->comp_num].value.data == NULL) {
1412 0 : ldb_dn_mark_invalid(dn);
1413 0 : return false;
1414 : }
1415 : }
1416 :
1417 453081 : if (dn->casefold && s) {
1418 0 : if (*dn->casefold) {
1419 0 : t = talloc_asprintf(dn, "%s,%s",
1420 : dn->casefold, s);
1421 : } else {
1422 0 : t = talloc_strdup(dn, s);
1423 : }
1424 0 : LDB_FREE(dn->casefold);
1425 0 : dn->casefold = t;
1426 : }
1427 : }
1428 :
1429 626898 : if (dn->linearized) {
1430 :
1431 176463 : s = ldb_dn_get_linearized(base);
1432 176463 : if ( ! s) {
1433 0 : return false;
1434 : }
1435 :
1436 176463 : if (*dn->linearized) {
1437 14412 : t = talloc_asprintf(dn, "%s,%s",
1438 : dn->linearized, s);
1439 : } else {
1440 162051 : t = talloc_strdup(dn, s);
1441 : }
1442 176463 : if ( ! t) {
1443 0 : ldb_dn_mark_invalid(dn);
1444 0 : return false;
1445 : }
1446 176463 : LDB_FREE(dn->linearized);
1447 176463 : dn->linearized = t;
1448 : }
1449 :
1450 : /* Wipe the ext_linearized DN,
1451 : * the GUID and SID are almost certainly no longer valid */
1452 626898 : LDB_FREE(dn->ext_linearized);
1453 626898 : LDB_FREE(dn->ext_components);
1454 626898 : dn->ext_comp_num = 0;
1455 :
1456 626898 : return true;
1457 : }
1458 :
1459 : /* modify the given dn by adding a base.
1460 : *
1461 : * return true if successful and false if not
1462 : * if false is returned the dn may be marked invalid
1463 : */
1464 2 : bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...)
1465 : {
1466 2 : struct ldb_dn *base;
1467 2 : char *base_str;
1468 2 : va_list ap;
1469 2 : bool ret;
1470 :
1471 2 : if ( !dn || dn->invalid) {
1472 0 : return false;
1473 : }
1474 :
1475 2 : va_start(ap, base_fmt);
1476 2 : base_str = talloc_vasprintf(dn, base_fmt, ap);
1477 2 : va_end(ap);
1478 :
1479 2 : if (base_str == NULL) {
1480 0 : return false;
1481 : }
1482 :
1483 2 : base = ldb_dn_new(base_str, dn->ldb, base_str);
1484 :
1485 2 : ret = ldb_dn_add_base(dn, base);
1486 :
1487 2 : talloc_free(base_str);
1488 :
1489 2 : return ret;
1490 : }
1491 :
1492 : /* modify the given dn by adding children elements.
1493 : *
1494 : * return true if successful and false if not
1495 : * if false is returned the dn may be marked invalid
1496 : */
1497 6784736 : bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child)
1498 : {
1499 368560 : const char *s;
1500 368560 : char *t;
1501 :
1502 6784736 : if ( !child || child->invalid || !dn || dn->invalid) {
1503 0 : return false;
1504 : }
1505 :
1506 6784736 : if (dn->components) {
1507 364873 : unsigned int n;
1508 364873 : unsigned int i, j;
1509 :
1510 6544367 : if (dn->comp_num == 0) {
1511 0 : return false;
1512 : }
1513 :
1514 6544367 : if ( ! ldb_dn_validate(child)) {
1515 0 : return false;
1516 : }
1517 :
1518 6544367 : s = NULL;
1519 6544367 : if (dn->valid_case) {
1520 4637503 : if ( ! (s = ldb_dn_get_casefold(child))) {
1521 0 : return false;
1522 : }
1523 : }
1524 :
1525 6544367 : n = dn->comp_num + child->comp_num;
1526 :
1527 6544367 : dn->components = talloc_realloc(dn,
1528 : dn->components,
1529 : struct ldb_dn_component,
1530 : n);
1531 6544367 : if ( ! dn->components) {
1532 0 : ldb_dn_mark_invalid(dn);
1533 0 : return false;
1534 : }
1535 :
1536 35305419 : for (i = dn->comp_num - 1, j = n - 1; i != (unsigned int) -1;
1537 28761052 : i--, j--) {
1538 28761052 : dn->components[j] = dn->components[i];
1539 : }
1540 :
1541 19143663 : for (i = 0; i < child->comp_num; i++) {
1542 12599296 : dn->components[i] =
1543 12599296 : ldb_dn_copy_component(dn->components,
1544 12599296 : &child->components[i]);
1545 12599296 : if (dn->components[i].value.data == NULL) {
1546 0 : ldb_dn_mark_invalid(dn);
1547 0 : return false;
1548 : }
1549 : }
1550 :
1551 6544367 : dn->comp_num = n;
1552 :
1553 6544367 : if (dn->casefold && s) {
1554 3373245 : t = talloc_asprintf(dn, "%s,%s", s, dn->casefold);
1555 3373245 : LDB_FREE(dn->casefold);
1556 3373245 : dn->casefold = t;
1557 : }
1558 : }
1559 :
1560 6784736 : if (dn->linearized) {
1561 6777596 : if (dn->linearized[0] == '\0') {
1562 0 : return false;
1563 : }
1564 :
1565 6777595 : s = ldb_dn_get_linearized(child);
1566 6777595 : if ( ! s) {
1567 0 : return false;
1568 : }
1569 :
1570 6777595 : t = talloc_asprintf(dn, "%s,%s", s, dn->linearized);
1571 6777595 : if ( ! t) {
1572 0 : ldb_dn_mark_invalid(dn);
1573 0 : return false;
1574 : }
1575 6777595 : LDB_FREE(dn->linearized);
1576 6777595 : dn->linearized = t;
1577 : }
1578 :
1579 : /* Wipe the ext_linearized DN,
1580 : * the GUID and SID are almost certainly no longer valid */
1581 6784735 : LDB_FREE(dn->ext_linearized);
1582 6784735 : LDB_FREE(dn->ext_components);
1583 6784735 : dn->ext_comp_num = 0;
1584 :
1585 6784735 : return true;
1586 : }
1587 :
1588 : /* modify the given dn by adding children elements.
1589 : *
1590 : * return true if successful and false if not
1591 : * if false is returned the dn may be marked invalid
1592 : */
1593 6588399 : bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...)
1594 : {
1595 367280 : struct ldb_dn *child;
1596 367280 : char *child_str;
1597 367280 : va_list ap;
1598 367280 : bool ret;
1599 :
1600 6588399 : if ( !dn || dn->invalid) {
1601 0 : return false;
1602 : }
1603 :
1604 6588399 : va_start(ap, child_fmt);
1605 6588399 : child_str = talloc_vasprintf(dn, child_fmt, ap);
1606 6588399 : va_end(ap);
1607 :
1608 6588399 : if (child_str == NULL) {
1609 0 : return false;
1610 : }
1611 :
1612 6588399 : child = ldb_dn_new(child_str, dn->ldb, child_str);
1613 :
1614 6588399 : ret = ldb_dn_add_child(dn, child);
1615 :
1616 6588399 : talloc_free(child_str);
1617 :
1618 6588399 : return ret;
1619 : }
1620 :
1621 : /* modify the given dn by adding a single child element.
1622 : *
1623 : * return true if successful and false if not
1624 : * if false is returned the dn may be marked invalid
1625 : */
1626 25650 : bool ldb_dn_add_child_val(struct ldb_dn *dn,
1627 : const char *rdn,
1628 : struct ldb_val value)
1629 : {
1630 8 : bool ret;
1631 8 : int ldb_ret;
1632 25650 : struct ldb_dn *child = NULL;
1633 :
1634 25650 : if ( !dn || dn->invalid) {
1635 0 : return false;
1636 : }
1637 :
1638 25650 : child = ldb_dn_new(dn, dn->ldb, "X=Y");
1639 25650 : ret = ldb_dn_add_child(dn, child);
1640 :
1641 25650 : if (ret == false) {
1642 0 : return false;
1643 : }
1644 :
1645 25650 : ldb_ret = ldb_dn_set_component(dn,
1646 : 0,
1647 : rdn,
1648 : value);
1649 25650 : if (ldb_ret != LDB_SUCCESS) {
1650 0 : return false;
1651 : }
1652 :
1653 25642 : return true;
1654 : }
1655 :
1656 598553 : bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num)
1657 : {
1658 454 : unsigned int i;
1659 :
1660 598553 : if ( ! ldb_dn_validate(dn)) {
1661 0 : return false;
1662 : }
1663 :
1664 598553 : if (dn->comp_num < num) {
1665 0 : return false;
1666 : }
1667 :
1668 : /* free components */
1669 3810410 : for (i = dn->comp_num - num; i < dn->comp_num; i++) {
1670 3211857 : LDB_FREE(dn->components[i].name);
1671 3211857 : LDB_FREE(dn->components[i].value.data);
1672 3211857 : LDB_FREE(dn->components[i].cf_name);
1673 3211857 : LDB_FREE(dn->components[i].cf_value.data);
1674 : }
1675 :
1676 598553 : dn->comp_num -= num;
1677 :
1678 598553 : if (dn->valid_case) {
1679 296853 : for (i = 0; i < dn->comp_num; i++) {
1680 148420 : LDB_FREE(dn->components[i].cf_name);
1681 148420 : LDB_FREE(dn->components[i].cf_value.data);
1682 : }
1683 148433 : dn->valid_case = false;
1684 : }
1685 :
1686 598553 : LDB_FREE(dn->casefold);
1687 598553 : LDB_FREE(dn->linearized);
1688 :
1689 : /* Wipe the ext_linearized DN,
1690 : * the GUID and SID are almost certainly no longer valid */
1691 598553 : LDB_FREE(dn->ext_linearized);
1692 598553 : LDB_FREE(dn->ext_components);
1693 598553 : dn->ext_comp_num = 0;
1694 :
1695 598553 : return true;
1696 : }
1697 :
1698 13040581 : bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num)
1699 : {
1700 781410 : unsigned int i, j;
1701 :
1702 13040581 : if ( ! ldb_dn_validate(dn)) {
1703 0 : return false;
1704 : }
1705 :
1706 13040581 : if (dn->comp_num < num) {
1707 1 : return false;
1708 : }
1709 :
1710 84308840 : for (i = 0, j = num; j < dn->comp_num; i++, j++) {
1711 71268260 : if (i < num) {
1712 13039134 : LDB_FREE(dn->components[i].name);
1713 13039134 : LDB_FREE(dn->components[i].value.data);
1714 13039134 : LDB_FREE(dn->components[i].cf_name);
1715 13039134 : LDB_FREE(dn->components[i].cf_value.data);
1716 : }
1717 71268260 : dn->components[i] = dn->components[j];
1718 : }
1719 :
1720 13040580 : dn->comp_num -= num;
1721 :
1722 13040580 : if (dn->valid_case) {
1723 61324883 : for (i = 0; i < dn->comp_num; i++) {
1724 51853022 : LDB_FREE(dn->components[i].cf_name);
1725 51853022 : LDB_FREE(dn->components[i].cf_value.data);
1726 : }
1727 9471861 : dn->valid_case = false;
1728 : }
1729 :
1730 13040580 : LDB_FREE(dn->casefold);
1731 13040580 : LDB_FREE(dn->linearized);
1732 :
1733 : /* Wipe the ext_linearized DN,
1734 : * the GUID and SID are almost certainly no longer valid */
1735 13040580 : LDB_FREE(dn->ext_linearized);
1736 13040580 : LDB_FREE(dn->ext_components);
1737 13040580 : dn->ext_comp_num = 0;
1738 :
1739 13040580 : return true;
1740 : }
1741 :
1742 :
1743 : /* replace the components of a DN with those from another DN, without
1744 : * touching the extended components
1745 : *
1746 : * return true if successful and false if not
1747 : * if false is returned the dn may be marked invalid
1748 : */
1749 124869 : bool ldb_dn_replace_components(struct ldb_dn *dn, struct ldb_dn *new_dn)
1750 : {
1751 958 : unsigned int i;
1752 :
1753 124869 : if ( ! ldb_dn_validate(dn) || ! ldb_dn_validate(new_dn)) {
1754 0 : return false;
1755 : }
1756 :
1757 : /* free components */
1758 844034 : for (i = 0; i < dn->comp_num; i++) {
1759 719165 : LDB_FREE(dn->components[i].name);
1760 719165 : LDB_FREE(dn->components[i].value.data);
1761 719165 : LDB_FREE(dn->components[i].cf_name);
1762 719165 : LDB_FREE(dn->components[i].cf_value.data);
1763 : }
1764 :
1765 124869 : dn->components = talloc_realloc(dn,
1766 : dn->components,
1767 : struct ldb_dn_component,
1768 : new_dn->comp_num);
1769 124869 : if (dn->components == NULL) {
1770 0 : ldb_dn_mark_invalid(dn);
1771 0 : return false;
1772 : }
1773 :
1774 124869 : dn->comp_num = new_dn->comp_num;
1775 124869 : dn->valid_case = new_dn->valid_case;
1776 :
1777 725972 : for (i = 0; i < dn->comp_num; i++) {
1778 601103 : dn->components[i] = ldb_dn_copy_component(dn->components, &new_dn->components[i]);
1779 601103 : if (dn->components[i].name == NULL) {
1780 0 : ldb_dn_mark_invalid(dn);
1781 0 : return false;
1782 : }
1783 : }
1784 124869 : if (new_dn->linearized == NULL) {
1785 0 : dn->linearized = NULL;
1786 : } else {
1787 124869 : dn->linearized = talloc_strdup(dn, new_dn->linearized);
1788 124869 : if (dn->linearized == NULL) {
1789 0 : ldb_dn_mark_invalid(dn);
1790 0 : return false;
1791 : }
1792 : }
1793 :
1794 123911 : return true;
1795 : }
1796 :
1797 :
1798 13036249 : struct ldb_dn *ldb_dn_get_parent(TALLOC_CTX *mem_ctx, struct ldb_dn *dn)
1799 : {
1800 781380 : struct ldb_dn *new_dn;
1801 :
1802 13036249 : new_dn = ldb_dn_copy(mem_ctx, dn);
1803 13036249 : if ( !new_dn ) {
1804 5 : return NULL;
1805 : }
1806 :
1807 13036244 : if ( ! ldb_dn_remove_child_components(new_dn, 1)) {
1808 1 : talloc_free(new_dn);
1809 1 : return NULL;
1810 : }
1811 :
1812 12254863 : return new_dn;
1813 : }
1814 :
1815 : /* Create a 'canonical name' string from a DN:
1816 :
1817 : ie dc=samba,dc=org -> samba.org/
1818 : uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator
1819 :
1820 : There are two formats,
1821 : the EX format has the last '/' replaced with a newline (\n).
1822 :
1823 : */
1824 2642177 : static char *ldb_dn_canonical(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, int ex_format) {
1825 149595 : unsigned int i;
1826 149595 : TALLOC_CTX *tmpctx;
1827 2642177 : char *cracked = NULL;
1828 2642177 : const char *format = (ex_format ? "\n" : "/" );
1829 :
1830 2642177 : if ( ! ldb_dn_validate(dn)) {
1831 0 : return NULL;
1832 : }
1833 :
1834 2642177 : tmpctx = talloc_new(mem_ctx);
1835 :
1836 : /* Walk backwards down the DN, grabbing 'dc' components at first */
1837 11468457 : for (i = dn->comp_num - 1; i != (unsigned int) -1; i--) {
1838 11171730 : if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) {
1839 2204096 : break;
1840 : }
1841 8826280 : if (cracked) {
1842 6184173 : cracked = talloc_asprintf(tmpctx, "%s.%s",
1843 : ldb_dn_escape_value(tmpctx,
1844 5859113 : dn->components[i].value),
1845 : cracked);
1846 : } else {
1847 2642107 : cracked = ldb_dn_escape_value(tmpctx,
1848 2492513 : dn->components[i].value);
1849 : }
1850 8826280 : if (!cracked) {
1851 0 : goto done;
1852 : }
1853 : }
1854 :
1855 : /* Only domain components? Finish here */
1856 2642177 : if (i == (unsigned int) -1) {
1857 296727 : cracked = talloc_strdup_append_buffer(cracked, format);
1858 296727 : talloc_steal(mem_ctx, cracked);
1859 296727 : goto done;
1860 : }
1861 :
1862 : /* Now walk backwards appending remaining components */
1863 6465475 : for (; i > 0; i--) {
1864 4120025 : cracked = talloc_asprintf_append_buffer(cracked, "/%s",
1865 : ldb_dn_escape_value(tmpctx,
1866 4120025 : dn->components[i].value));
1867 4120025 : if (!cracked) {
1868 0 : goto done;
1869 : }
1870 : }
1871 :
1872 : /* Last one, possibly a newline for the 'ex' format */
1873 2345450 : cracked = talloc_asprintf_append_buffer(cracked, "%s%s", format,
1874 : ldb_dn_escape_value(tmpctx,
1875 2345450 : dn->components[i].value));
1876 :
1877 2345450 : talloc_steal(mem_ctx, cracked);
1878 2642177 : done:
1879 2642177 : talloc_free(tmpctx);
1880 2642177 : return cracked;
1881 : }
1882 :
1883 : /* Wrapper functions for the above, for the two different string formats */
1884 2641913 : char *ldb_dn_canonical_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) {
1885 2641913 : return ldb_dn_canonical(mem_ctx, dn, 0);
1886 :
1887 : }
1888 :
1889 264 : char *ldb_dn_canonical_ex_string(TALLOC_CTX *mem_ctx, struct ldb_dn *dn) {
1890 264 : return ldb_dn_canonical(mem_ctx, dn, 1);
1891 : }
1892 :
1893 26236186 : int ldb_dn_get_comp_num(struct ldb_dn *dn)
1894 : {
1895 26236186 : if ( ! ldb_dn_validate(dn)) {
1896 182 : return -1;
1897 : }
1898 26236004 : return dn->comp_num;
1899 : }
1900 :
1901 14794521 : int ldb_dn_get_extended_comp_num(struct ldb_dn *dn)
1902 : {
1903 14794521 : if ( ! ldb_dn_validate(dn)) {
1904 182 : return -1;
1905 : }
1906 14794339 : return dn->ext_comp_num;
1907 : }
1908 :
1909 9135 : const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num)
1910 : {
1911 9135 : if ( ! ldb_dn_validate(dn)) {
1912 0 : return NULL;
1913 : }
1914 9135 : if (num >= dn->comp_num) return NULL;
1915 9123 : return dn->components[num].name;
1916 : }
1917 :
1918 598981 : const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn,
1919 : unsigned int num)
1920 : {
1921 598981 : if ( ! ldb_dn_validate(dn)) {
1922 0 : return NULL;
1923 : }
1924 598981 : if (num >= dn->comp_num) return NULL;
1925 598981 : return &dn->components[num].value;
1926 : }
1927 :
1928 70548188 : const char *ldb_dn_get_rdn_name(struct ldb_dn *dn)
1929 : {
1930 70548188 : if ( ! ldb_dn_validate(dn)) {
1931 0 : return NULL;
1932 : }
1933 70548188 : if (dn->comp_num == 0) return NULL;
1934 56612573 : return dn->components[0].name;
1935 : }
1936 :
1937 56262896 : const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn)
1938 : {
1939 56262896 : if ( ! ldb_dn_validate(dn)) {
1940 3 : return NULL;
1941 : }
1942 56262893 : if (dn->comp_num == 0) return NULL;
1943 42327278 : return &dn->components[0].value;
1944 : }
1945 :
1946 1227065 : int ldb_dn_set_component(struct ldb_dn *dn, int num,
1947 : const char *name, const struct ldb_val val)
1948 : {
1949 156807 : char *n;
1950 156807 : struct ldb_val v;
1951 :
1952 1227065 : if ( ! ldb_dn_validate(dn)) {
1953 0 : return LDB_ERR_OTHER;
1954 : }
1955 :
1956 1227065 : if (num < 0) {
1957 0 : return LDB_ERR_OTHER;
1958 : }
1959 :
1960 1227065 : if ((unsigned)num >= dn->comp_num) {
1961 3 : return LDB_ERR_OTHER;
1962 : }
1963 :
1964 1227062 : if (val.length > val.length + 1) {
1965 0 : return LDB_ERR_OTHER;
1966 : }
1967 :
1968 1227062 : n = talloc_strdup(dn, name);
1969 1227062 : if ( ! n) {
1970 0 : return LDB_ERR_OTHER;
1971 : }
1972 :
1973 1227062 : v.length = val.length;
1974 :
1975 : /*
1976 : * This is like talloc_memdup(dn, v.data, v.length + 1), but
1977 : * avoids the over-read
1978 : */
1979 1227062 : v.data = (uint8_t *)talloc_size(dn, v.length+1);
1980 1227062 : if ( ! v.data) {
1981 0 : talloc_free(n);
1982 0 : return LDB_ERR_OTHER;
1983 : }
1984 1227062 : memcpy(v.data, val.data, val.length);
1985 :
1986 : /*
1987 : * Enforce NUL termination outside the stated length, as is
1988 : * traditional in LDB
1989 : */
1990 1227062 : v.data[v.length] = '\0';
1991 :
1992 1227062 : talloc_free(dn->components[num].name);
1993 1227062 : talloc_free(dn->components[num].value.data);
1994 1227062 : dn->components[num].name = n;
1995 1227062 : dn->components[num].value = v;
1996 :
1997 1227062 : if (dn->valid_case) {
1998 : unsigned int i;
1999 4948809 : for (i = 0; i < dn->comp_num; i++) {
2000 4276231 : LDB_FREE(dn->components[i].cf_name);
2001 4276231 : LDB_FREE(dn->components[i].cf_value.data);
2002 : }
2003 672578 : dn->valid_case = false;
2004 : }
2005 1227062 : LDB_FREE(dn->casefold);
2006 1227062 : LDB_FREE(dn->linearized);
2007 :
2008 : /* Wipe the ext_linearized DN,
2009 : * the GUID and SID are almost certainly no longer valid */
2010 1227062 : LDB_FREE(dn->ext_linearized);
2011 1227062 : LDB_FREE(dn->ext_components);
2012 1227062 : dn->ext_comp_num = 0;
2013 :
2014 1227062 : return LDB_SUCCESS;
2015 : }
2016 :
2017 256664089 : const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn,
2018 : const char *name)
2019 : {
2020 6769243 : unsigned int i;
2021 256664089 : if ( ! ldb_dn_validate(dn)) {
2022 718 : return NULL;
2023 : }
2024 321454520 : for (i=0; i < dn->ext_comp_num; i++) {
2025 128527707 : if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) {
2026 63736558 : return &dn->ext_components[i].value;
2027 : }
2028 : }
2029 187816774 : return NULL;
2030 : }
2031 :
2032 156159754 : int ldb_dn_set_extended_component(struct ldb_dn *dn,
2033 : const char *name, const struct ldb_val *val)
2034 : {
2035 3714117 : struct ldb_dn_ext_component *p;
2036 3714117 : unsigned int i;
2037 3714117 : struct ldb_val v2;
2038 3714117 : const struct ldb_dn_extended_syntax *ext_syntax;
2039 :
2040 156159754 : if ( ! ldb_dn_validate(dn)) {
2041 0 : return LDB_ERR_OTHER;
2042 : }
2043 :
2044 156159754 : ext_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name);
2045 156159754 : if (ext_syntax == NULL) {
2046 : /* We don't know how to handle this type of thing */
2047 0 : return LDB_ERR_INVALID_DN_SYNTAX;
2048 : }
2049 :
2050 247266278 : for (i=0; i < dn->ext_comp_num; i++) {
2051 91117183 : if (ldb_attr_cmp(dn->ext_components[i].name, name) == 0) {
2052 10659 : if (val) {
2053 10659 : dn->ext_components[i].value =
2054 10659 : ldb_val_dup(dn->ext_components, val);
2055 :
2056 10659 : dn->ext_components[i].name = ext_syntax->name;
2057 10659 : if (!dn->ext_components[i].value.data) {
2058 0 : ldb_dn_mark_invalid(dn);
2059 0 : return LDB_ERR_OPERATIONS_ERROR;
2060 : }
2061 : } else {
2062 0 : ARRAY_DEL_ELEMENT(
2063 : dn->ext_components,
2064 : i,
2065 0 : dn->ext_comp_num);
2066 0 : dn->ext_comp_num--;
2067 :
2068 0 : dn->ext_components = talloc_realloc(dn,
2069 : dn->ext_components,
2070 : struct ldb_dn_ext_component,
2071 : dn->ext_comp_num);
2072 0 : if (!dn->ext_components) {
2073 0 : ldb_dn_mark_invalid(dn);
2074 0 : return LDB_ERR_OPERATIONS_ERROR;
2075 : }
2076 : }
2077 10659 : LDB_FREE(dn->ext_linearized);
2078 :
2079 10659 : return LDB_SUCCESS;
2080 : }
2081 : }
2082 :
2083 156149095 : if (val == NULL) {
2084 : /* removing a value that doesn't exist is not an error */
2085 0 : return LDB_SUCCESS;
2086 : }
2087 :
2088 156149095 : v2 = *val;
2089 :
2090 159863152 : p = dn->ext_components
2091 156149095 : = talloc_realloc(dn,
2092 : dn->ext_components,
2093 : struct ldb_dn_ext_component,
2094 : dn->ext_comp_num + 1);
2095 156149095 : if (!dn->ext_components) {
2096 0 : ldb_dn_mark_invalid(dn);
2097 0 : return LDB_ERR_OPERATIONS_ERROR;
2098 : }
2099 :
2100 156149095 : p[dn->ext_comp_num].value = ldb_val_dup(dn->ext_components, &v2);
2101 156149095 : p[dn->ext_comp_num].name = talloc_strdup(p, name);
2102 :
2103 156149095 : if (!dn->ext_components[i].name || !dn->ext_components[i].value.data) {
2104 0 : ldb_dn_mark_invalid(dn);
2105 0 : return LDB_ERR_OPERATIONS_ERROR;
2106 : }
2107 156149095 : dn->ext_components = p;
2108 156149095 : dn->ext_comp_num++;
2109 :
2110 156149095 : LDB_FREE(dn->ext_linearized);
2111 :
2112 156149095 : return LDB_SUCCESS;
2113 : }
2114 :
2115 46183545 : void ldb_dn_remove_extended_components(struct ldb_dn *dn)
2116 : {
2117 46183545 : LDB_FREE(dn->ext_linearized);
2118 46183545 : LDB_FREE(dn->ext_components);
2119 46183545 : dn->ext_comp_num = 0;
2120 46183545 : }
2121 :
2122 4506 : bool ldb_dn_is_valid(struct ldb_dn *dn)
2123 : {
2124 4506 : if ( ! dn) return false;
2125 4506 : return ! dn->invalid;
2126 : }
2127 :
2128 1851687265 : bool ldb_dn_is_special(struct ldb_dn *dn)
2129 : {
2130 1851687265 : if ( ! dn || dn->invalid) return false;
2131 1851687264 : return dn->special;
2132 : }
2133 :
2134 459351297 : bool ldb_dn_has_extended(struct ldb_dn *dn)
2135 : {
2136 459351297 : if ( ! dn || dn->invalid) return false;
2137 459351297 : if (dn->ext_linearized && (dn->ext_linearized[0] == '<')) return true;
2138 444598532 : return dn->ext_comp_num != 0;
2139 : }
2140 :
2141 15903013 : bool ldb_dn_check_special(struct ldb_dn *dn, const char *check)
2142 : {
2143 15903013 : if ( ! dn || dn->invalid) return false;
2144 15903013 : return ! strcmp(dn->linearized, check);
2145 : }
2146 :
2147 396036931 : bool ldb_dn_is_null(struct ldb_dn *dn)
2148 : {
2149 396036931 : if ( ! dn || dn->invalid) return false;
2150 396036931 : if (ldb_dn_has_extended(dn)) return false;
2151 343318657 : if (dn->linearized && (dn->linearized[0] == '\0')) return true;
2152 306451780 : return false;
2153 : }
2154 :
2155 : /*
2156 : this updates dn->components, taking the components from ref_dn.
2157 : This is used by code that wants to update the DN path of a DN
2158 : while not impacting on the extended DN components
2159 : */
2160 11046 : int ldb_dn_update_components(struct ldb_dn *dn, const struct ldb_dn *ref_dn)
2161 : {
2162 11046 : dn->components = talloc_realloc(dn, dn->components,
2163 : struct ldb_dn_component, ref_dn->comp_num);
2164 11046 : if (!dn->components) {
2165 0 : return LDB_ERR_OPERATIONS_ERROR;
2166 : }
2167 11046 : memcpy(dn->components, ref_dn->components,
2168 11046 : sizeof(struct ldb_dn_component)*ref_dn->comp_num);
2169 11046 : dn->comp_num = ref_dn->comp_num;
2170 :
2171 11046 : LDB_FREE(dn->casefold);
2172 11046 : LDB_FREE(dn->linearized);
2173 11046 : LDB_FREE(dn->ext_linearized);
2174 :
2175 11046 : return LDB_SUCCESS;
2176 : }
2177 :
2178 : /*
2179 : minimise a DN. The caller must pass in a validated DN.
2180 :
2181 : If the DN has an extended component then only the first extended
2182 : component is kept, the DN string is stripped.
2183 :
2184 : The existing dn is modified
2185 : */
2186 8098062 : bool ldb_dn_minimise(struct ldb_dn *dn)
2187 : {
2188 291240 : unsigned int i;
2189 :
2190 8098062 : if (!ldb_dn_validate(dn)) {
2191 0 : return false;
2192 : }
2193 8098062 : if (dn->ext_comp_num == 0) {
2194 0 : return true;
2195 : }
2196 :
2197 : /* free components */
2198 41265805 : for (i = 0; i < dn->comp_num; i++) {
2199 33167743 : LDB_FREE(dn->components[i].name);
2200 33167743 : LDB_FREE(dn->components[i].value.data);
2201 33167743 : LDB_FREE(dn->components[i].cf_name);
2202 33167743 : LDB_FREE(dn->components[i].cf_value.data);
2203 : }
2204 8098062 : dn->comp_num = 0;
2205 8098062 : dn->valid_case = false;
2206 :
2207 8098062 : LDB_FREE(dn->casefold);
2208 8098062 : LDB_FREE(dn->linearized);
2209 :
2210 : /* note that we don't free dn->components as this there are
2211 : * several places in ldb_dn.c that rely on it being non-NULL
2212 : * for an exploded DN
2213 : */
2214 :
2215 11520425 : for (i = 1; i < dn->ext_comp_num; i++) {
2216 3422363 : LDB_FREE(dn->ext_components[i].value.data);
2217 : }
2218 8098062 : dn->ext_comp_num = 1;
2219 :
2220 8098062 : dn->ext_components = talloc_realloc(dn, dn->ext_components, struct ldb_dn_ext_component, 1);
2221 8098062 : if (dn->ext_components == NULL) {
2222 0 : ldb_dn_mark_invalid(dn);
2223 0 : return false;
2224 : }
2225 :
2226 8098062 : LDB_FREE(dn->ext_linearized);
2227 :
2228 8098062 : return true;
2229 : }
2230 :
2231 916616 : struct ldb_context *ldb_dn_get_ldb_context(struct ldb_dn *dn)
2232 : {
2233 916616 : return dn->ldb;
2234 : }
|