4 Copyright (C) Simo Sorce 2005
6 ** NOTE! The following LGPL license applies to the ldb
7 ** library. This does NOT imply that all of Samba is released
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 2 of the License, or (at your option) any later version.
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.
20 You should have received a copy of the GNU Lesser General Public
21 License along with this library; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 * Component: ldb dn creation and manipulation utility functions
30 * Description: - explode a dn into it's own basic elements
31 * and put them in a structure (only if necessary)
32 * - manipulate ldb_dn structures
39 #include "ldb/include/includes.h"
41 #define LDB_DN_NULL_FAILED(x) if (!(x)) goto failed
43 #define LDB_FREE(x) do { talloc_free(x); x = NULL; } while(0)
46 internal ldb exploded dn structures
48 struct ldb_dn_component {
54 struct ldb_val cf_value;
59 struct ldb_context *ldb;
61 /* Special DNs are always linearized */
72 unsigned int comp_num;
73 struct ldb_dn_component *components;
77 /* strdn may be NULL */
78 struct ldb_dn *ldb_dn_new(void *mem_ctx, struct ldb_context *ldb, const char *strdn)
82 if ( (! mem_ctx) || (! ldb)) return NULL;
84 dn = talloc_zero(mem_ctx, struct ldb_dn);
85 LDB_DN_NULL_FAILED(dn);
90 if (strdn[0] == '@') {
93 if (strncasecmp(strdn, "<GUID=", 6) == 0) {
94 /* this is special DN returned when the
95 * exploded_dn control is used */
97 /* FIXME: add a GUID string to ldb_dn structure */
99 dn->linearized = talloc_strdup(dn, strdn);
101 dn->linearized = talloc_strdup(dn, "");
103 LDB_DN_NULL_FAILED(dn->linearized);
105 dn->valid_lin = true;
114 struct ldb_dn *ldb_dn_new_fmt(void *mem_ctx, struct ldb_context *ldb, const char *new_fmt, ...)
120 if ( (! mem_ctx) || (! ldb)) return NULL;
122 dn = talloc_zero(mem_ctx, struct ldb_dn);
123 LDB_DN_NULL_FAILED(dn);
127 va_start(ap, new_fmt);
128 strdn = talloc_vasprintf(dn, new_fmt, ap);
130 LDB_DN_NULL_FAILED(strdn);
132 if (strdn[0] == '@') {
135 if (strncasecmp(strdn, "<GUID=", 6) == 0) {
136 /* this is special DN returned when the
137 * exploded_dn control is used */
139 /* FIXME: add a GUID string to ldb_dn structure */
141 dn->linearized = strdn;
143 dn->valid_lin = true;
152 static int ldb_dn_escape_internal(char *dst, const char *src, int len)
161 while (p - src < len) {
163 p += strcspn(p, ",=\n+<>#;\\\"");
165 if (p - src == len) /* found no escapable chars */
168 memcpy(d, s, p - s); /* copy the part of the string before the stop */
169 d += (p - s); /* move to current position */
171 if (*p) { /* it is a normal escapable character */
174 } else { /* we have a zero byte in the string */
175 strncpy(d, "\00", 3); /* escape the zero */
177 p++; /* skip the zero */
179 s = p; /* move forward */
182 /* copy the last part (with zero) and return */
186 /* return the length of the resulting string */
187 return (l + (d - dst));
190 char *ldb_dn_escape_value(void *mem_ctx, struct ldb_val value)
197 /* allocate destination string, it will be at most 3 times the source */
198 dst = talloc_array(mem_ctx, char, value.length * 3 + 1);
204 ldb_dn_escape_internal(dst, (const char *)value.data, value.length);
210 explode a DN string into a ldb_dn structure
211 based on RFC4514 except that we don't support multiple valued RDNs
213 static bool ldb_dn_explode(struct ldb_dn *dn)
215 char *p, *data, *d, *dt, *t;
217 bool in_attr = false;
218 bool in_value = false;
219 bool in_quote = false;
225 if ( ! dn || dn->invalid) return false;
227 if (dn->valid_comp) {
231 if ( ! dn->valid_lin) {
236 if (dn->linearized[0] == '\0') {
237 dn->valid_comp = true;
241 /* Special DNs case */
246 /* in the common case we have 3 or more components */
247 /* make sure all components are zeroed, other functions depend on this */
248 dn->components = talloc_zero_array(dn, struct ldb_dn_component, 3);
249 if ( ! dn->components) {
254 /* Components data space is allocated here once */
255 data = talloc_array(dn->components, char, strlen(dn->linearized) + 1);
278 if ( ! isalpha(*p)) {
279 /* not a digit nor an alpha, invalid attribute name */
290 /* valid only if we are at the end */
295 if (trim && (*p != '=')) {
296 /* spaces/tabs are not allowed in attribute names */
302 /* attribute terminated */
309 dn->components[dn->comp_num].name = dt;
316 if (is_oid && ( ! (isdigit(*p) || (*p == '.')))) {
317 /* not a digit nor a dot, invalid attribute oid */
321 if ( ! (isalpha(*p) || isdigit(*p) || (*p == '-'))) {
322 /* not ALPHA, DIGIT or HYPHEN */
363 /* TODO: support ber encoded values
374 /* ok found value terminator */
388 dn->components[dn->comp_num].value.data = (uint8_t *)dt;
389 dn->components[dn->comp_num].value.length = l;
393 if (dn->comp_num > 2) {
394 dn->components = talloc_realloc(dn,
396 struct ldb_dn_component,
398 if ( ! dn->components) {
402 /* make sure all components are zeroed, other functions depend on this */
403 memset(&dn->components[dn->comp_num], '\0', sizeof(struct ldb_dn_component));
416 /* a string with not escaped specials is invalid (tested) */
445 if (sscanf(p, "%02x", &x) != 1) {
446 /* invalid escaping sequence */
453 *d++ = (unsigned char)x;
475 if (in_attr || in_quote) {
481 /* save last element */
489 dn->components[dn->comp_num].value.data = (uint8_t *)dt;
490 dn->components[dn->comp_num].value.length = l;
494 dn->valid_comp = true;
498 talloc_free(dn->components);
502 bool ldb_dn_validate(struct ldb_dn *dn)
504 return ldb_dn_explode(dn);
507 const char *ldb_dn_get_linearized(struct ldb_dn *dn)
512 if ( ! dn || ( dn->invalid)) return NULL;
514 if (dn->valid_lin) return dn->linearized;
516 if ( ! dn->valid_comp) {
521 if (dn->comp_num == 0) {
522 dn->linearized = talloc_strdup(dn, "");
523 if ( ! dn->linearized) return NULL;
524 dn->valid_lin = true;
525 return dn->linearized;
528 /* calculate maximum possible length of DN */
529 for (len = 0, i = 0; i < dn->comp_num; i++) {
530 len += strlen(dn->components[i].name); /* name len */
531 len += (dn->components[i].value.length * 3); /* max escaped data len */
532 len += 2; /* '=' and ',' */
534 dn->linearized = talloc_array(dn, char, len);
535 if ( ! dn->linearized) return NULL;
539 for (i = 0; i < dn->comp_num; i++) {
542 n = dn->components[i].name;
543 while (*n) *d++ = *n++;
548 d += ldb_dn_escape_internal( d,
549 (char *)dn->components[i].value.data,
550 dn->components[i].value.length);
556 dn->valid_lin = true;
558 /* don't waste more memory than necessary */
559 dn->linearized = talloc_realloc(dn, dn->linearized, char, (d - dn->linearized + 1));
561 return dn->linearized;
564 char *ldb_dn_linearize(void *mem_ctx, struct ldb_dn *dn)
566 return talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn));
570 casefold a dn. We need to casefold the attribute names, and canonicalize
571 attribute values of case insensitive attributes.
574 static bool ldb_dn_casefold_internal(struct ldb_dn *dn)
578 if ( ! dn || dn->invalid) return false;
580 if (dn->valid_case) return true;
582 if (( ! dn->valid_comp) && ( ! ldb_dn_explode(dn))) {
586 for (i = 0; i < dn->comp_num; i++) {
587 struct ldb_dn_component dc;
588 const struct ldb_attrib_handler *h;
590 memset(&dc, 0, sizeof(dc));
591 dn->components[i].cf_name = ldb_attr_casefold(dn->components, dn->components[i].name);
592 if (!dn->components[i].cf_name) {
596 h = ldb_attrib_handler(dn->ldb, dn->components[i].cf_name);
597 ret = h->canonicalise_fn(dn->ldb, dn->components,
598 &(dn->components[i].value),
599 &(dn->components[i].cf_value));
608 const char *ldb_dn_get_casefold(struct ldb_dn *dn)
613 if ( ! ldb_dn_casefold_internal(dn)) {
617 if (dn->casefold) return dn->casefold;
619 if (dn->comp_num == 0) {
621 len = strlen(dn->linearized);
622 dn->casefold = talloc_array(dn, char, len * 3 + 1);
623 if ( ! dn->casefold) return NULL;
624 ldb_dn_escape_internal(dn->casefold, dn->linearized, len);
625 /* don't waste more memory than necessary */
626 dn->casefold = talloc_realloc(dn, dn->casefold, char, strlen(dn->casefold) + 1);
628 dn->casefold = talloc_strdup(dn, "");
629 if ( ! dn->casefold) return NULL;
631 dn->valid_case = true;
635 /* calculate maximum possible length of DN */
636 for (len = 0, i = 0; i < dn->comp_num; i++) {
637 len += strlen(dn->components[i].cf_name); /* name len */
638 len += (dn->components[i].cf_value.length * 3); /* max escaped data len */
639 len += 2; /* '=' and ',' */
641 dn->casefold = talloc_array(dn, char, len);
642 if ( ! dn->casefold) return NULL;
646 for (i = 0; i < dn->comp_num; i++) {
649 n = dn->components[i].cf_name;
650 while (*n) *d++ = *n++;
655 d += ldb_dn_escape_internal( d,
656 (char *)dn->components[i].cf_value.data,
657 dn->components[i].cf_value.length);
662 dn->valid_case = true;
667 char *ldb_dn_casefold(void *mem_ctx, struct ldb_dn *dn)
669 return talloc_strdup(mem_ctx, ldb_dn_get_casefold(dn));
672 /* Determine if dn is below base, in the ldap tree. Used for
673 * evaluating a subtree search.
674 * 0 if they match, otherwise non-zero
677 int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn)
682 if ( ! base || base->invalid) return 1;
683 if ( ! dn || dn->invalid) return -1;
685 if (( ! base->valid_case) || ( ! dn->valid_case)) {
686 if (base->valid_lin && dn->valid_lin) {
687 /* try with a normal compare first, if we are lucky
688 * we will avoid exploding and casfolding */
690 dif = strlen(dn->linearized) - strlen(base->linearized);
691 if (dif < 0) return dif;
692 if (strcmp(base->linearized, &dn->linearized[dif]) == 0) return 0;
695 if ( ! ldb_dn_casefold_internal(base)) {
699 if ( ! ldb_dn_casefold_internal(dn)) {
705 /* if base has more components,
706 * they don't have the same base */
707 if (base->comp_num > dn->comp_num) {
708 return (dn->comp_num - base->comp_num);
711 if (dn->comp_num == 0) {
712 if (dn->special && base->special) {
713 return strcmp(base->linearized, dn->linearized);
719 n_base = base->comp_num - 1;
720 n_dn = dn->comp_num - 1;
722 while (n_base >= 0) {
723 /* compare attr names */
724 ret = strcmp(base->components[n_base].cf_name, dn->components[n_dn].cf_name);
725 if (ret != 0) return ret;
727 /* compare attr.cf_value. */
728 if (base->components[n_base].cf_value.length != dn->components[n_dn].cf_value.length) {
729 return base->components[n_base].cf_value.length - dn->components[n_dn].cf_value.length;
731 ret = strcmp((char *)base->components[n_base].cf_value.data, (char *)dn->components[n_dn].cf_value.data);
732 if (ret != 0) return ret;
741 /* compare DNs using casefolding compare functions.
743 If they match, then return 0
746 int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1)
750 if (( ! dn0) || dn0->invalid || ! dn1 || dn1->invalid) return -1;
752 if (( ! dn0->valid_case) || ( ! dn1->valid_case)) {
753 if (dn0->valid_lin && dn1->valid_lin) {
754 /* try with a normal compare first, if we are lucky
755 * we will avoid exploding and casfolding */
756 if (strcmp(dn0->linearized, dn1->linearized) == 0) return 0;
759 if ( ! ldb_dn_casefold_internal(dn0)) {
763 if ( ! ldb_dn_casefold_internal(dn1)) {
769 if (dn0->comp_num != dn1->comp_num) {
770 return (dn1->comp_num - dn0->comp_num);
773 if (dn0->comp_num == 0) {
774 if (dn0->special && dn1->special) {
775 return strcmp(dn0->linearized, dn1->linearized);
781 for (i = 0; i < dn0->comp_num; i++) {
782 /* compare attr names */
783 ret = strcmp(dn0->components[i].cf_name, dn1->components[i].cf_name);
784 if (ret != 0) return ret;
786 /* compare attr.cf_value. */
787 if (dn0->components[i].cf_value.length != dn1->components[i].cf_value.length) {
788 return dn0->components[i].cf_value.length - dn1->components[i].cf_value.length;
790 ret = strcmp((char *)dn0->components[i].cf_value.data, (char *)dn1->components[i].cf_value.data);
791 if (ret != 0) return ret;
797 static struct ldb_dn_component ldb_dn_copy_component(void *mem_ctx, struct ldb_dn_component *src)
799 struct ldb_dn_component dst;
801 memset(&dst, 0, sizeof(dst));
807 dst.value = ldb_val_dup(mem_ctx, &(src->value));
808 if (dst.value.data == NULL) {
812 dst.name = talloc_strdup(mem_ctx, src->name);
813 if (dst.name == NULL) {
814 LDB_FREE(dst.value.data);
817 if (src->cf_value.data) {
818 dst.cf_value = ldb_val_dup(mem_ctx, &(src->cf_value));
819 if (dst.cf_value.data == NULL) {
820 LDB_FREE(dst.value.data);
825 dst.cf_name = talloc_strdup(mem_ctx, src->cf_name);
826 if (dst.cf_name == NULL) {
827 LDB_FREE(dst.cf_name);
828 LDB_FREE(dst.value.data);
833 dst.cf_value.data = NULL;
840 struct ldb_dn *ldb_dn_copy(void *mem_ctx, struct ldb_dn *dn)
842 struct ldb_dn *new_dn;
844 if (!dn || dn->invalid) {
848 new_dn = talloc_zero(mem_ctx, struct ldb_dn);
855 if (dn->valid_comp) {
858 new_dn->components = talloc_zero_array(new_dn, struct ldb_dn_component, dn->comp_num);
859 if ( ! new_dn->components) {
864 for (i = 0; i < dn->comp_num; i++) {
865 new_dn->components[i] = ldb_dn_copy_component(new_dn->components, &dn->components[i]);
866 if ( ! new_dn->components[i].value.data) {
873 new_dn->casefold = talloc_strdup(new_dn, dn->casefold);
874 if ( ! new_dn->casefold) {
882 new_dn->linearized = talloc_strdup(new_dn, dn->linearized);
883 if ( ! new_dn->linearized) {
892 /* modify the given dn by adding a base.
894 * return true if successful and false if not
895 * if false is returned the dn may be marked invalid
897 bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base)
902 if ( !base || base->invalid || !dn || dn->invalid) {
906 if (dn->valid_comp) {
909 if ( ! ldb_dn_validate(base)) {
914 if (dn->valid_case) {
915 if ( ! (s = ldb_dn_get_casefold(base))) {
920 dn->components = talloc_realloc(dn,
922 struct ldb_dn_component,
923 dn->comp_num + base->comp_num);
924 if ( ! dn->components) {
929 for (i = 0; i < base->comp_num; dn->comp_num++, i++) {
930 dn->components[dn->comp_num] = ldb_dn_copy_component(dn->components, &base->components[i]);
931 if (dn->components[dn->comp_num].value.data == NULL) {
938 t = talloc_asprintf(dn, "%s,%s", dn->casefold, s);
939 LDB_FREE(dn->casefold);
946 s = ldb_dn_get_linearized(base);
951 t = talloc_asprintf(dn, "%s,%s", dn->linearized, s);
956 LDB_FREE(dn->linearized);
963 /* modify the given dn by adding a base.
965 * return true if successful and false if not
966 * if false is returned the dn may be marked invalid
968 bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...)
975 if ( !dn || dn->invalid) {
979 va_start(ap, base_fmt);
980 base_str = talloc_vasprintf(dn, base_fmt, ap);
983 if (base_str == NULL) {
987 base = ldb_dn_new(base_str, dn->ldb, base_str);
989 ret = ldb_dn_add_base(dn, base);
991 talloc_free(base_str);
996 /* modify the given dn by adding children elements.
998 * return true if successful and false if not
999 * if false is returned the dn may be marked invalid
1001 bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child)
1006 if ( !child || child->invalid || !dn || dn->invalid) {
1010 if (dn->valid_comp) {
1013 if ( ! ldb_dn_validate(child)) {
1018 if (dn->valid_case) {
1019 if ( ! (s = ldb_dn_get_casefold(child))) {
1024 n = dn->comp_num + child->comp_num;
1026 dn->components = talloc_realloc(dn,
1028 struct ldb_dn_component,
1030 if ( ! dn->components) {
1035 for (i = dn->comp_num - 1, j = n - 1; i >= 0; i--, j--) {
1036 dn->components[j] = dn->components[i];
1039 for (i = 0; i < child->comp_num; i++) {
1040 dn->components[i] = ldb_dn_copy_component(dn->components, &child->components[i]);
1041 if (dn->components[i].value.data == NULL) {
1050 t = talloc_asprintf(dn, "%s,%s", s, dn->casefold);
1051 LDB_FREE(dn->casefold);
1056 if (dn->valid_lin) {
1058 s = ldb_dn_get_linearized(child);
1063 t = talloc_asprintf(dn, "%s,%s", s, dn->linearized);
1068 LDB_FREE(dn->linearized);
1075 /* modify the given dn by adding children elements.
1077 * return true if successful and false if not
1078 * if false is returned the dn may be marked invalid
1080 bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...)
1082 struct ldb_dn *child;
1087 if ( !dn || dn->invalid) {
1091 va_start(ap, child_fmt);
1092 child_str = talloc_vasprintf(dn, child_fmt, ap);
1095 if (child_str == NULL) {
1099 child = ldb_dn_new(child_str, dn->ldb, child_str);
1101 ret = ldb_dn_add_child(dn, child);
1103 talloc_free(child_str);
1108 bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num)
1110 if ( ! ldb_dn_validate(dn)) {
1114 if (dn->comp_num < num) {
1118 dn->comp_num -= num;
1120 dn->valid_case = false;
1122 if (dn->valid_lin) {
1123 dn->valid_lin = false;
1124 LDB_FREE(dn->linearized);
1130 bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num)
1134 if ( ! ldb_dn_validate(dn)) {
1138 if (dn->comp_num < num) {
1142 for (i = 0, j = num; j < dn->comp_num; i++, j++) {
1143 dn->components[i] = dn->components[j];
1146 dn->comp_num -= num;
1148 dn->valid_case = false;
1150 if (dn->valid_lin) {
1151 dn->valid_lin = false;
1152 LDB_FREE(dn->linearized);
1158 struct ldb_dn *ldb_dn_get_parent(void *mem_ctx, struct ldb_dn *dn)
1160 struct ldb_dn *new_dn;
1162 new_dn = ldb_dn_copy(mem_ctx, dn);
1167 if ( ! ldb_dn_remove_child_components(new_dn, 1)) {
1168 talloc_free(new_dn);
1175 /* Create a 'canonical name' string from a DN:
1177 ie dc=samba,dc=org -> samba.org/
1178 uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator
1180 There are two formats, the EX format has the last / replaced with a newline (\n).
1183 static char *ldb_dn_canonical(void *mem_ctx, struct ldb_dn *dn, int ex_format) {
1185 char *cracked = NULL;
1187 if ( ! ldb_dn_validate(dn)) {
1190 /* Walk backwards down the DN, grabbing 'dc' components at first */
1191 for (i = dn->comp_num - 1 ; i >= 0; i--) {
1192 if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) {
1196 cracked = talloc_asprintf(mem_ctx, "%s.%s",
1197 ldb_dn_escape_value(mem_ctx, dn->components[i].value),
1200 cracked = ldb_dn_escape_value(mem_ctx, dn->components[i].value);
1207 /* Only domain components? Finish here */
1210 cracked = talloc_asprintf(mem_ctx, "%s\n", cracked);
1212 cracked = talloc_asprintf(mem_ctx, "%s/", cracked);
1217 /* Now walk backwards appending remaining components */
1218 for (; i > 0; i--) {
1219 cracked = talloc_asprintf(mem_ctx, "%s/%s", cracked,
1220 ldb_dn_escape_value(mem_ctx, dn->components[i].value));
1226 /* Last one, possibly a newline for the 'ex' format */
1228 cracked = talloc_asprintf(mem_ctx, "%s\n%s", cracked,
1229 ldb_dn_escape_value(mem_ctx, dn->components[i].value));
1231 cracked = talloc_asprintf(mem_ctx, "%s/%s", cracked,
1232 ldb_dn_escape_value(mem_ctx, dn->components[i].value));
1237 /* Wrapper functions for the above, for the two different string formats */
1238 char *ldb_dn_canonical_string(void *mem_ctx, struct ldb_dn *dn) {
1239 return ldb_dn_canonical(mem_ctx, dn, 0);
1243 char *ldb_dn_canonical_ex_string(void *mem_ctx, struct ldb_dn *dn) {
1244 return ldb_dn_canonical(mem_ctx, dn, 1);
1247 int ldb_dn_get_comp_num(struct ldb_dn *dn)
1249 if ( ! ldb_dn_validate(dn)) {
1252 return dn->comp_num;
1255 const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num)
1257 if ( ! ldb_dn_validate(dn)) {
1260 if (num >= dn->comp_num) return NULL;
1261 return dn->components[num].name;
1264 const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn, unsigned int num)
1266 if ( ! ldb_dn_validate(dn)) {
1269 if (num >= dn->comp_num) return NULL;
1270 return &dn->components[num].value;
1273 const char *ldb_dn_get_rdn_name(struct ldb_dn *dn)
1275 if ( ! ldb_dn_validate(dn)) {
1278 if (dn->comp_num == 0) return NULL;
1279 return dn->components[0].name;
1282 const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn)
1284 if ( ! ldb_dn_validate(dn)) {
1287 if (dn->comp_num == 0) return NULL;
1288 return &dn->components[0].value;
1291 int ldb_dn_set_component(struct ldb_dn *dn, int num, const char *name, const struct ldb_val val)
1296 if ( ! ldb_dn_validate(dn)) {
1297 return LDB_ERR_OTHER;
1300 if (num >= dn->comp_num) {
1301 return LDB_ERR_OTHER;
1304 n = talloc_strdup(dn, name);
1306 return LDB_ERR_OTHER;
1309 v.length = val.length;
1310 v.data = (uint8_t *)talloc_memdup(dn, val.data, v.length+1);
1312 return LDB_ERR_OTHER;
1315 talloc_free(dn->components[num].name);
1316 talloc_free(dn->components[num].value.data);
1317 dn->components[num].name = n;
1318 dn->components[num].value = v;
1320 if (dn->valid_case) dn->valid_case = false;
1321 if (dn->casefold) LDB_FREE(dn->casefold);
1326 bool ldb_dn_is_valid(struct ldb_dn *dn)
1328 if ( ! dn) return false;
1329 return ! dn->invalid;
1332 bool ldb_dn_is_special(struct ldb_dn *dn)
1334 if ( ! dn || dn->invalid) return false;
1338 bool ldb_dn_check_special(struct ldb_dn *dn, const char *check)
1340 if ( ! dn || dn->invalid) return false;
1341 return ! strcmp(dn->linearized, check);
1344 bool ldb_dn_is_null(struct ldb_dn *dn)
1346 if ( ! dn || dn->invalid) return false;
1347 if (dn->special) return false;
1348 if (dn->valid_comp) {
1349 if (dn->comp_num == 0) return true;
1352 if (dn->linearized[0] == '\0') return true;