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