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 3 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, see <http://www.gnu.org/licenses/>.
27
* Component: ldb dn creation and manipulation utility functions
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
36
#include "ldb_private.h"
39
#define LDB_DN_NULL_FAILED(x) if (!(x)) goto failed
41
#define LDB_FREE(x) do { talloc_free(x); x = NULL; } while(0)
44
internal ldb exploded dn structures
46
struct ldb_dn_component {
52
struct ldb_val cf_value;
55
struct ldb_dn_extended_component {
63
struct ldb_context *ldb;
65
/* Special DNs are always linearized */
72
char *extended_linearized;
75
unsigned int comp_num;
76
struct ldb_dn_component *components;
78
unsigned int extended_comp_num;
79
struct ldb_dn_extended_component *extended_components;
82
/* strdn may be NULL */
83
struct ldb_dn *ldb_dn_from_ldb_val(void *mem_ctx, struct ldb_context *ldb, const struct ldb_val *strdn)
87
if (! ldb) return NULL;
89
dn = talloc_zero(mem_ctx, struct ldb_dn);
90
LDB_DN_NULL_FAILED(dn);
94
if (strdn->data && strdn->length) {
95
if (strdn->data[0] == '@') {
98
dn->extended_linearized = talloc_strndup(dn, (const char *)strdn->data, strdn->length);
99
LDB_DN_NULL_FAILED(dn->extended_linearized);
101
if (strdn->data[0] == '<') {
102
const char *p_save, *p = dn->extended_linearized;
111
if (p_save == dn->extended_linearized) {
112
dn->linearized = talloc_strdup(dn, "");
114
dn->linearized = talloc_strdup(dn, p_save);
116
LDB_DN_NULL_FAILED(dn->linearized);
118
dn->linearized = dn->extended_linearized;
119
dn->extended_linearized = NULL;
122
dn->linearized = talloc_strdup(dn, "");
123
LDB_DN_NULL_FAILED(dn->linearized);
133
/* strdn may be NULL */
134
struct ldb_dn *ldb_dn_new(void *mem_ctx, struct ldb_context *ldb, const char *strdn)
138
blob.length = strdn ? strlen(strdn) : 0;
139
return ldb_dn_from_ldb_val(mem_ctx, ldb, &blob);
142
struct ldb_dn *ldb_dn_new_fmt(void *mem_ctx, struct ldb_context *ldb, const char *new_fmt, ...)
147
if ( (! mem_ctx) || (! ldb)) return NULL;
149
va_start(ap, new_fmt);
150
strdn = talloc_vasprintf(mem_ctx, new_fmt, ap);
154
struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb, strdn);
162
static int ldb_dn_escape_internal(char *dst, const char *src, int len)
171
while (p - src < len) {
173
p += strcspn(p, ",=\n+<>#;\\\"");
175
if (p - src == len) /* found no escapable chars */
178
memcpy(d, s, p - s); /* copy the part of the string before the stop */
179
d += (p - s); /* move to current position */
181
if (*p) { /* it is a normal escapable character */
184
} else { /* we have a zero byte in the string */
185
strncpy(d, "\00", 3); /* escape the zero */
187
p++; /* skip the zero */
189
s = p; /* move forward */
192
/* copy the last part (with zero) and return */
196
/* return the length of the resulting string */
197
return (l + (d - dst));
200
char *ldb_dn_escape_value(void *mem_ctx, struct ldb_val value)
207
/* allocate destination string, it will be at most 3 times the source */
208
dst = talloc_array(mem_ctx, char, value.length * 3 + 1);
214
ldb_dn_escape_internal(dst, (const char *)value.data, value.length);
216
dst = talloc_realloc(mem_ctx, dst, char, strlen(dst) + 1);
222
explode a DN string into a ldb_dn structure
223
based on RFC4514 except that we don't support multiple valued RDNs
225
static bool ldb_dn_explode(struct ldb_dn *dn)
227
char *p, *ex_name, *ex_value, *data, *d, *dt, *t;
229
bool in_extended = false;
230
bool in_ex_name = false;
231
bool in_ex_value = false;
232
bool in_attr = false;
233
bool in_value = false;
234
bool in_quote = false;
241
if ( ! dn || dn->invalid) return false;
243
if (dn->components) {
247
if (dn->extended_linearized) {
248
parse_dn = dn->extended_linearized;
250
parse_dn = dn->linearized;
258
if (parse_dn[0] == '\0') {
262
/* Special DNs case */
267
/* make sure we free this if alloced previously before replacing */
268
talloc_free(dn->components);
270
talloc_free(dn->extended_components);
271
dn->extended_components = NULL;
273
/* in the common case we have 3 or more components */
274
/* make sure all components are zeroed, other functions depend on this */
275
dn->components = talloc_zero_array(dn, struct ldb_dn_component, 3);
276
if ( ! dn->components) {
281
/* Components data space is allocated here once */
282
data = talloc_array(dn->components, char, strlen(parse_dn) + 1);
298
if (!in_ex_name && !in_ex_value) {
305
} else if (p[0] == '\0') {
317
if (in_ex_name && *p == '=') {
326
if (in_ex_value && *p == '>') {
327
const struct ldb_dn_extended_syntax *extended_syntax;
328
struct ldb_val ex_val = {
330
.length = d - ex_value
337
/* Process name and ex_value */
339
dn->extended_components = talloc_realloc(dn,
340
dn->extended_components,
341
struct ldb_dn_extended_component,
342
dn->extended_comp_num + 1);
343
if ( ! dn->extended_components) {
348
extended_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, ex_name);
349
if (!extended_syntax) {
350
/* We don't know about this type of extended DN */
354
dn->extended_components[dn->extended_comp_num].name = talloc_strdup(dn->extended_components, ex_name);
355
if (!dn->extended_components[dn->extended_comp_num].name) {
359
ret = extended_syntax->read_fn(dn->ldb, dn->extended_components,
360
&ex_val, &dn->extended_components[dn->extended_comp_num].value);
361
if (ret != LDB_SUCCESS) {
366
dn->extended_comp_num++;
369
/* We have reached the end (extended component only)! */
373
} else if (*p == ';') {
396
/* attr names must be ascii only */
404
if ( ! isalpha(*p)) {
405
/* not a digit nor an alpha, invalid attribute name */
410
/* Copy this character across from parse_dn, now we have trimmed out spaces */
417
/* valid only if we are at the end */
422
if (trim && (*p != '=')) {
423
/* spaces/tabs are not allowed in attribute names */
429
/* attribute terminated */
435
/* Terminate this string in d (which is a copy of parse_dn with spaces trimmed) */
437
dn->components[dn->comp_num].name = talloc_strdup(dn->components, dt);
438
if ( ! dn->components[dn->comp_num].name) {
450
/* attr names must be ascii only */
455
if (is_oid && ( ! (isdigit(*p) || (*p == '.')))) {
456
/* not a digit nor a dot, invalid attribute oid */
460
if ( ! (isalpha(*p) || isdigit(*p) || (*p == '-'))) {
461
/* not ALPHA, DIGIT or HYPHEN */
502
/* TODO: support ber encoded values
513
/* ok found value terminator */
527
dn->components[dn->comp_num].value.data = (uint8_t *)talloc_strdup(dn->components, dt);
528
dn->components[dn->comp_num].value.length = l;
529
if ( ! dn->components[dn->comp_num].value.data) {
537
if (dn->comp_num > 2) {
538
dn->components = talloc_realloc(dn,
540
struct ldb_dn_component,
542
if ( ! dn->components) {
546
/* make sure all components are zeroed, other functions depend on this */
547
memset(&dn->components[dn->comp_num], '\0', sizeof(struct ldb_dn_component));
560
/* a string with not escaped specials is invalid (tested) */
589
if (sscanf(p, "%02x", &x) != 1) {
590
/* invalid escaping sequence */
597
*d++ = (unsigned char)x;
619
if (in_attr || in_quote) {
625
/* save last element */
633
dn->components[dn->comp_num].value.data = (uint8_t *)talloc_strdup(dn->components, dt);
634
dn->components[dn->comp_num].value.length = l;
636
if ( ! dn->components[dn->comp_num].value.data) {
648
talloc_free(dn->components);
652
bool ldb_dn_validate(struct ldb_dn *dn)
654
return ldb_dn_explode(dn);
657
const char *ldb_dn_get_linearized(struct ldb_dn *dn)
662
if ( ! dn || ( dn->invalid)) return NULL;
664
if (dn->linearized) return dn->linearized;
666
if ( ! dn->components) {
671
if (dn->comp_num == 0) {
672
dn->linearized = talloc_strdup(dn, "");
673
if ( ! dn->linearized) return NULL;
674
return dn->linearized;
677
/* calculate maximum possible length of DN */
678
for (len = 0, i = 0; i < dn->comp_num; i++) {
679
len += strlen(dn->components[i].name); /* name len */
680
len += (dn->components[i].value.length * 3); /* max escaped data len */
681
len += 2; /* '=' and ',' */
683
dn->linearized = talloc_array(dn, char, len);
684
if ( ! dn->linearized) return NULL;
688
for (i = 0; i < dn->comp_num; i++) {
691
n = dn->components[i].name;
692
while (*n) *d++ = *n++;
697
d += ldb_dn_escape_internal( d,
698
(char *)dn->components[i].value.data,
699
dn->components[i].value.length);
705
/* don't waste more memory than necessary */
706
dn->linearized = talloc_realloc(dn, dn->linearized, char, (d - dn->linearized + 1));
708
return dn->linearized;
711
char *ldb_dn_get_extended_linearized(void *mem_ctx, struct ldb_dn *dn, int mode)
713
const char *linearized = ldb_dn_get_linearized(dn);
721
if (!ldb_dn_has_extended(dn)) {
722
return talloc_strdup(mem_ctx, linearized);
725
if (!ldb_dn_validate(dn)) {
729
for (i=0; i < dn->extended_comp_num; i++) {
732
const struct ldb_dn_extended_syntax *extended_syntax;
733
const char *name = dn->extended_components[i].name;
735
extended_syntax = ldb_dn_extended_syntax_by_name(dn->ldb, name);
738
ret = extended_syntax->write_clear_fn(dn->ldb, mem_ctx,
739
&dn->extended_components[i].value,
741
} else if (mode == 0) {
742
ret = extended_syntax->write_hex_fn(dn->ldb, mem_ctx,
743
&dn->extended_components[i].value,
749
if (ret != LDB_SUCCESS) {
754
p = talloc_asprintf(mem_ctx, "<%s=%s>", dn->extended_components[i].name, val.data);
756
p = talloc_asprintf_append(p, ";<%s=%s>", dn->extended_components[i].name, val.data);
759
talloc_free(val.data);
766
if (dn->extended_comp_num && *linearized) {
767
p = talloc_asprintf_append(p, ";%s", linearized);
779
char *ldb_dn_alloc_linearized(void *mem_ctx, struct ldb_dn *dn)
781
return talloc_strdup(mem_ctx, ldb_dn_get_linearized(dn));
785
casefold a dn. We need to casefold the attribute names, and canonicalize
786
attribute values of case insensitive attributes.
789
static bool ldb_dn_casefold_internal(struct ldb_dn *dn)
793
if ( ! dn || dn->invalid) return false;
795
if (dn->valid_case) return true;
797
if (( ! dn->components) && ( ! ldb_dn_explode(dn))) {
801
for (i = 0; i < dn->comp_num; i++) {
802
const struct ldb_schema_attribute *a;
804
dn->components[i].cf_name = ldb_attr_casefold(dn->components, dn->components[i].name);
805
if (!dn->components[i].cf_name) {
809
a = ldb_schema_attribute_by_name(dn->ldb, dn->components[i].cf_name);
810
ret = a->syntax->canonicalise_fn(dn->ldb, dn->components,
811
&(dn->components[i].value),
812
&(dn->components[i].cf_value));
818
dn->valid_case = true;
823
for (i = 0; i < dn->comp_num; i++) {
824
LDB_FREE(dn->components[i].cf_name);
825
LDB_FREE(dn->components[i].cf_value.data);
830
const char *ldb_dn_get_casefold(struct ldb_dn *dn)
835
if (dn->casefold) return dn->casefold;
838
dn->casefold = talloc_strdup(dn, dn->linearized);
839
if (!dn->casefold) return NULL;
840
dn->valid_case = true;
844
if ( ! ldb_dn_casefold_internal(dn)) {
848
if (dn->comp_num == 0) {
849
if (dn->linearized && dn->linearized[0] == '\0') {
850
/* hmm a NULL dn, should we faild casefolding ? */
851
dn->casefold = talloc_strdup(dn, "");
854
/* A DN must be NULL, special, or have components */
859
/* calculate maximum possible length of DN */
860
for (len = 0, i = 0; i < dn->comp_num; i++) {
861
len += strlen(dn->components[i].cf_name); /* name len */
862
len += (dn->components[i].cf_value.length * 3); /* max escaped data len */
863
len += 2; /* '=' and ',' */
865
dn->casefold = talloc_array(dn, char, len);
866
if ( ! dn->casefold) return NULL;
870
for (i = 0; i < dn->comp_num; i++) {
873
n = dn->components[i].cf_name;
874
while (*n) *d++ = *n++;
879
d += ldb_dn_escape_internal( d,
880
(char *)dn->components[i].cf_value.data,
881
dn->components[i].cf_value.length);
886
/* don't waste more memory than necessary */
887
dn->casefold = talloc_realloc(dn, dn->casefold, char, strlen(dn->casefold) + 1);
892
char *ldb_dn_alloc_casefold(void *mem_ctx, struct ldb_dn *dn)
894
return talloc_strdup(mem_ctx, ldb_dn_get_casefold(dn));
897
/* Determine if dn is below base, in the ldap tree. Used for
898
* evaluating a subtree search.
899
* 0 if they match, otherwise non-zero
902
int ldb_dn_compare_base(struct ldb_dn *base, struct ldb_dn *dn)
907
if ( ! base || base->invalid) return 1;
908
if ( ! dn || dn->invalid) return -1;
910
if (( ! base->valid_case) || ( ! dn->valid_case)) {
911
if (base->linearized && dn->linearized) {
912
/* try with a normal compare first, if we are lucky
913
* we will avoid exploding and casfolding */
915
dif = strlen(dn->linearized) - strlen(base->linearized);
916
if (dif < 0) return dif;
917
if (strcmp(base->linearized, &dn->linearized[dif]) == 0) return 0;
920
if ( ! ldb_dn_casefold_internal(base)) {
924
if ( ! ldb_dn_casefold_internal(dn)) {
930
/* if base has more components,
931
* they don't have the same base */
932
if (base->comp_num > dn->comp_num) {
933
return (dn->comp_num - base->comp_num);
936
if (dn->comp_num == 0) {
937
if (dn->special && base->special) {
938
return strcmp(base->linearized, dn->linearized);
939
} else if (dn->special) {
941
} else if (base->special) {
948
n_base = base->comp_num - 1;
949
n_dn = dn->comp_num - 1;
951
while (n_base >= 0) {
952
/* compare attr names */
953
ret = strcmp(base->components[n_base].cf_name, dn->components[n_dn].cf_name);
954
if (ret != 0) return ret;
956
/* compare attr.cf_value. */
957
if (base->components[n_base].cf_value.length != dn->components[n_dn].cf_value.length) {
958
return base->components[n_base].cf_value.length - dn->components[n_dn].cf_value.length;
960
ret = strcmp((char *)base->components[n_base].cf_value.data, (char *)dn->components[n_dn].cf_value.data);
961
if (ret != 0) return ret;
970
/* compare DNs using casefolding compare functions.
972
If they match, then return 0
975
int ldb_dn_compare(struct ldb_dn *dn0, struct ldb_dn *dn1)
979
if (( ! dn0) || dn0->invalid || ! dn1 || dn1->invalid) return -1;
981
if (( ! dn0->valid_case) || ( ! dn1->valid_case)) {
982
if (dn0->linearized && dn1->linearized) {
983
/* try with a normal compare first, if we are lucky
984
* we will avoid exploding and casfolding */
985
if (strcmp(dn0->linearized, dn1->linearized) == 0) return 0;
988
if ( ! ldb_dn_casefold_internal(dn0)) {
992
if ( ! ldb_dn_casefold_internal(dn1)) {
998
if (dn0->comp_num != dn1->comp_num) {
999
return (dn1->comp_num - dn0->comp_num);
1002
if (dn0->comp_num == 0) {
1003
if (dn0->special && dn1->special) {
1004
return strcmp(dn0->linearized, dn1->linearized);
1005
} else if (dn0->special) {
1007
} else if (dn1->special) {
1014
for (i = 0; i < dn0->comp_num; i++) {
1015
/* compare attr names */
1016
ret = strcmp(dn0->components[i].cf_name, dn1->components[i].cf_name);
1017
if (ret != 0) return ret;
1019
/* compare attr.cf_value. */
1020
if (dn0->components[i].cf_value.length != dn1->components[i].cf_value.length) {
1021
return dn0->components[i].cf_value.length - dn1->components[i].cf_value.length;
1023
ret = strcmp((char *)dn0->components[i].cf_value.data, (char *)dn1->components[i].cf_value.data);
1024
if (ret != 0) return ret;
1030
static struct ldb_dn_component ldb_dn_copy_component(void *mem_ctx, struct ldb_dn_component *src)
1032
struct ldb_dn_component dst;
1034
memset(&dst, 0, sizeof(dst));
1040
dst.value = ldb_val_dup(mem_ctx, &(src->value));
1041
if (dst.value.data == NULL) {
1045
dst.name = talloc_strdup(mem_ctx, src->name);
1046
if (dst.name == NULL) {
1047
LDB_FREE(dst.value.data);
1051
if (src->cf_value.data) {
1052
dst.cf_value = ldb_val_dup(mem_ctx, &(src->cf_value));
1053
if (dst.cf_value.data == NULL) {
1054
LDB_FREE(dst.value.data);
1059
dst.cf_name = talloc_strdup(mem_ctx, src->cf_name);
1060
if (dst.cf_name == NULL) {
1061
LDB_FREE(dst.cf_name);
1062
LDB_FREE(dst.value.data);
1067
dst.cf_value.data = NULL;
1074
static struct ldb_dn_extended_component ldb_dn_extended_copy_component(void *mem_ctx, struct ldb_dn_extended_component *src)
1076
struct ldb_dn_extended_component dst;
1078
memset(&dst, 0, sizeof(dst));
1084
dst.value = ldb_val_dup(mem_ctx, &(src->value));
1085
if (dst.value.data == NULL) {
1089
dst.name = talloc_strdup(mem_ctx, src->name);
1090
if (dst.name == NULL) {
1091
LDB_FREE(dst.value.data);
1098
struct ldb_dn *ldb_dn_copy(void *mem_ctx, struct ldb_dn *dn)
1100
struct ldb_dn *new_dn;
1102
if (!dn || dn->invalid) {
1106
new_dn = talloc_zero(mem_ctx, struct ldb_dn);
1113
if (dn->components) {
1116
new_dn->components = talloc_zero_array(new_dn, struct ldb_dn_component, dn->comp_num);
1117
if ( ! new_dn->components) {
1118
talloc_free(new_dn);
1122
for (i = 0; i < dn->comp_num; i++) {
1123
new_dn->components[i] = ldb_dn_copy_component(new_dn->components, &dn->components[i]);
1124
if ( ! new_dn->components[i].value.data) {
1125
talloc_free(new_dn);
1131
if (dn->extended_components) {
1134
new_dn->extended_components = talloc_zero_array(new_dn, struct ldb_dn_extended_component, dn->extended_comp_num);
1135
if ( ! new_dn->extended_components) {
1136
talloc_free(new_dn);
1140
for (i = 0; i < dn->extended_comp_num; i++) {
1141
new_dn->extended_components[i] = ldb_dn_extended_copy_component(new_dn->extended_components, &dn->extended_components[i]);
1142
if ( ! new_dn->extended_components[i].value.data) {
1143
talloc_free(new_dn);
1150
new_dn->casefold = talloc_strdup(new_dn, dn->casefold);
1151
if ( ! new_dn->casefold) {
1152
talloc_free(new_dn);
1157
if (dn->linearized) {
1158
new_dn->linearized = talloc_strdup(new_dn, dn->linearized);
1159
if ( ! new_dn->linearized) {
1160
talloc_free(new_dn);
1165
if (dn->extended_linearized) {
1166
new_dn->extended_linearized = talloc_strdup(new_dn, dn->extended_linearized);
1167
if ( ! new_dn->extended_linearized) {
1168
talloc_free(new_dn);
1176
/* modify the given dn by adding a base.
1178
* return true if successful and false if not
1179
* if false is returned the dn may be marked invalid
1181
bool ldb_dn_add_base(struct ldb_dn *dn, struct ldb_dn *base)
1186
if ( !base || base->invalid || !dn || dn->invalid) {
1190
if (dn->components) {
1193
if ( ! ldb_dn_validate(base)) {
1198
if (dn->valid_case) {
1199
if ( ! (s = ldb_dn_get_casefold(base))) {
1204
dn->components = talloc_realloc(dn,
1206
struct ldb_dn_component,
1207
dn->comp_num + base->comp_num);
1208
if ( ! dn->components) {
1213
for (i = 0; i < base->comp_num; dn->comp_num++, i++) {
1214
dn->components[dn->comp_num] = ldb_dn_copy_component(dn->components, &base->components[i]);
1215
if (dn->components[dn->comp_num].value.data == NULL) {
1221
if (dn->casefold && s) {
1222
if (*dn->casefold) {
1223
t = talloc_asprintf(dn, "%s,%s", dn->casefold, s);
1225
t = talloc_strdup(dn, s);
1227
LDB_FREE(dn->casefold);
1232
if (dn->linearized) {
1234
s = ldb_dn_get_linearized(base);
1239
if (*dn->linearized) {
1240
t = talloc_asprintf(dn, "%s,%s", dn->linearized, s);
1242
t = talloc_strdup(dn, s);
1248
LDB_FREE(dn->linearized);
1252
/* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
1253
if (dn->extended_linearized) {
1254
LDB_FREE(dn->extended_linearized);
1257
LDB_FREE(dn->extended_components);
1258
dn->extended_comp_num = 0;
1262
/* modify the given dn by adding a base.
1264
* return true if successful and false if not
1265
* if false is returned the dn may be marked invalid
1267
bool ldb_dn_add_base_fmt(struct ldb_dn *dn, const char *base_fmt, ...)
1269
struct ldb_dn *base;
1274
if ( !dn || dn->invalid) {
1278
va_start(ap, base_fmt);
1279
base_str = talloc_vasprintf(dn, base_fmt, ap);
1282
if (base_str == NULL) {
1286
base = ldb_dn_new(base_str, dn->ldb, base_str);
1288
ret = ldb_dn_add_base(dn, base);
1290
talloc_free(base_str);
1295
/* modify the given dn by adding children elements.
1297
* return true if successful and false if not
1298
* if false is returned the dn may be marked invalid
1300
bool ldb_dn_add_child(struct ldb_dn *dn, struct ldb_dn *child)
1305
if ( !child || child->invalid || !dn || dn->invalid) {
1309
if (dn->components) {
1312
if ( ! ldb_dn_validate(child)) {
1317
if (dn->valid_case) {
1318
if ( ! (s = ldb_dn_get_casefold(child))) {
1323
n = dn->comp_num + child->comp_num;
1325
dn->components = talloc_realloc(dn,
1327
struct ldb_dn_component,
1329
if ( ! dn->components) {
1334
for (i = dn->comp_num - 1, j = n - 1; i >= 0; i--, j--) {
1335
dn->components[j] = dn->components[i];
1338
for (i = 0; i < child->comp_num; i++) {
1339
dn->components[i] = ldb_dn_copy_component(dn->components, &child->components[i]);
1340
if (dn->components[i].value.data == NULL) {
1348
if (dn->casefold && s) {
1349
t = talloc_asprintf(dn, "%s,%s", s, dn->casefold);
1350
LDB_FREE(dn->casefold);
1355
if (dn->linearized) {
1357
s = ldb_dn_get_linearized(child);
1362
t = talloc_asprintf(dn, "%s,%s", s, dn->linearized);
1367
LDB_FREE(dn->linearized);
1371
/* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
1372
LDB_FREE(dn->extended_linearized);
1374
LDB_FREE(dn->extended_components);
1375
dn->extended_comp_num = 0;
1380
/* modify the given dn by adding children elements.
1382
* return true if successful and false if not
1383
* if false is returned the dn may be marked invalid
1385
bool ldb_dn_add_child_fmt(struct ldb_dn *dn, const char *child_fmt, ...)
1387
struct ldb_dn *child;
1392
if ( !dn || dn->invalid) {
1396
va_start(ap, child_fmt);
1397
child_str = talloc_vasprintf(dn, child_fmt, ap);
1400
if (child_str == NULL) {
1404
child = ldb_dn_new(child_str, dn->ldb, child_str);
1406
ret = ldb_dn_add_child(dn, child);
1408
talloc_free(child_str);
1413
bool ldb_dn_remove_base_components(struct ldb_dn *dn, unsigned int num)
1417
if ( ! ldb_dn_validate(dn)) {
1421
if (dn->comp_num < num) {
1425
/* free components */
1426
for (i = num; i > 0; i--) {
1427
LDB_FREE(dn->components[dn->comp_num - i].name);
1428
LDB_FREE(dn->components[dn->comp_num - i].value.data);
1429
LDB_FREE(dn->components[dn->comp_num - i].cf_name);
1430
LDB_FREE(dn->components[dn->comp_num - i].cf_value.data);
1433
dn->comp_num -= num;
1435
if (dn->valid_case) {
1436
for (i = 0; i < dn->comp_num; i++) {
1437
LDB_FREE(dn->components[i].cf_name);
1438
LDB_FREE(dn->components[i].cf_value.data);
1440
dn->valid_case = false;
1443
LDB_FREE(dn->casefold);
1444
LDB_FREE(dn->linearized);
1446
/* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
1447
LDB_FREE(dn->extended_linearized);
1449
LDB_FREE(dn->extended_components);
1450
dn->extended_comp_num = 0;
1455
bool ldb_dn_remove_child_components(struct ldb_dn *dn, unsigned int num)
1459
if ( ! ldb_dn_validate(dn)) {
1463
if (dn->comp_num < num) {
1467
for (i = 0, j = num; j < dn->comp_num; i++, j++) {
1469
LDB_FREE(dn->components[i].name);
1470
LDB_FREE(dn->components[i].value.data);
1471
LDB_FREE(dn->components[i].cf_name);
1472
LDB_FREE(dn->components[i].cf_value.data);
1474
dn->components[i] = dn->components[j];
1477
dn->comp_num -= num;
1479
if (dn->valid_case) {
1480
for (i = 0; i < dn->comp_num; i++) {
1481
LDB_FREE(dn->components[i].cf_name);
1482
LDB_FREE(dn->components[i].cf_value.data);
1484
dn->valid_case = false;
1487
LDB_FREE(dn->casefold);
1488
LDB_FREE(dn->linearized);
1490
/* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
1491
LDB_FREE(dn->extended_linearized);
1493
LDB_FREE(dn->extended_components);
1494
dn->extended_comp_num = 0;
1498
struct ldb_dn *ldb_dn_get_parent(void *mem_ctx, struct ldb_dn *dn)
1500
struct ldb_dn *new_dn;
1502
new_dn = ldb_dn_copy(mem_ctx, dn);
1507
if ( ! ldb_dn_remove_child_components(new_dn, 1)) {
1508
talloc_free(new_dn);
1512
/* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
1513
LDB_FREE(dn->extended_linearized);
1515
LDB_FREE(dn->extended_components);
1516
dn->extended_comp_num = 0;
1520
/* Create a 'canonical name' string from a DN:
1522
ie dc=samba,dc=org -> samba.org/
1523
uid=administrator,ou=users,dc=samba,dc=org = samba.org/users/administrator
1525
There are two formats, the EX format has the last / replaced with a newline (\n).
1528
static char *ldb_dn_canonical(void *mem_ctx, struct ldb_dn *dn, int ex_format) {
1531
char *cracked = NULL;
1532
const char *format = (ex_format ? "\n" : "/" );
1534
if ( ! ldb_dn_validate(dn)) {
1538
tmpctx = talloc_new(mem_ctx);
1540
/* Walk backwards down the DN, grabbing 'dc' components at first */
1541
for (i = dn->comp_num - 1 ; i >= 0; i--) {
1542
if (ldb_attr_cmp(dn->components[i].name, "dc") != 0) {
1546
cracked = talloc_asprintf(tmpctx, "%s.%s",
1547
ldb_dn_escape_value(tmpctx, dn->components[i].value),
1550
cracked = ldb_dn_escape_value(tmpctx, dn->components[i].value);
1557
/* Only domain components? Finish here */
1559
cracked = talloc_strdup_append_buffer(cracked, format);
1560
talloc_steal(mem_ctx, cracked);
1564
/* Now walk backwards appending remaining components */
1565
for (; i > 0; i--) {
1566
cracked = talloc_asprintf_append_buffer(cracked, "/%s",
1567
ldb_dn_escape_value(tmpctx, dn->components[i].value));
1573
/* Last one, possibly a newline for the 'ex' format */
1574
cracked = talloc_asprintf_append_buffer(cracked, "%s%s", format,
1575
ldb_dn_escape_value(tmpctx, dn->components[i].value));
1577
talloc_steal(mem_ctx, cracked);
1579
talloc_free(tmpctx);
1583
/* Wrapper functions for the above, for the two different string formats */
1584
char *ldb_dn_canonical_string(void *mem_ctx, struct ldb_dn *dn) {
1585
return ldb_dn_canonical(mem_ctx, dn, 0);
1589
char *ldb_dn_canonical_ex_string(void *mem_ctx, struct ldb_dn *dn) {
1590
return ldb_dn_canonical(mem_ctx, dn, 1);
1593
int ldb_dn_get_comp_num(struct ldb_dn *dn)
1595
if ( ! ldb_dn_validate(dn)) {
1598
return dn->comp_num;
1601
const char *ldb_dn_get_component_name(struct ldb_dn *dn, unsigned int num)
1603
if ( ! ldb_dn_validate(dn)) {
1606
if (num >= dn->comp_num) return NULL;
1607
return dn->components[num].name;
1610
const struct ldb_val *ldb_dn_get_component_val(struct ldb_dn *dn, unsigned int num)
1612
if ( ! ldb_dn_validate(dn)) {
1615
if (num >= dn->comp_num) return NULL;
1616
return &dn->components[num].value;
1619
const char *ldb_dn_get_rdn_name(struct ldb_dn *dn)
1621
if ( ! ldb_dn_validate(dn)) {
1624
if (dn->comp_num == 0) return NULL;
1625
return dn->components[0].name;
1628
const struct ldb_val *ldb_dn_get_rdn_val(struct ldb_dn *dn)
1630
if ( ! ldb_dn_validate(dn)) {
1633
if (dn->comp_num == 0) return NULL;
1634
return &dn->components[0].value;
1637
int ldb_dn_set_component(struct ldb_dn *dn, int num, const char *name, const struct ldb_val val)
1642
if ( ! ldb_dn_validate(dn)) {
1643
return LDB_ERR_OTHER;
1646
if (num >= dn->comp_num) {
1647
return LDB_ERR_OTHER;
1650
n = talloc_strdup(dn, name);
1652
return LDB_ERR_OTHER;
1655
v.length = val.length;
1656
v.data = (uint8_t *)talloc_memdup(dn, val.data, v.length+1);
1659
return LDB_ERR_OTHER;
1662
talloc_free(dn->components[num].name);
1663
talloc_free(dn->components[num].value.data);
1664
dn->components[num].name = n;
1665
dn->components[num].value = v;
1667
if (dn->valid_case) {
1669
for (i = 0; i < dn->comp_num; i++) {
1670
LDB_FREE(dn->components[i].cf_name);
1671
LDB_FREE(dn->components[i].cf_value.data);
1673
dn->valid_case = false;
1675
LDB_FREE(dn->casefold);
1676
LDB_FREE(dn->linearized);
1678
/* Wipe the extended_linearized DN, as the GUID and SID are almost certainly no longer valid */
1679
LDB_FREE(dn->extended_linearized);
1681
dn->extended_comp_num = 0;
1682
LDB_FREE(dn->extended_components);
1686
const struct ldb_val *ldb_dn_get_extended_component(struct ldb_dn *dn, const char *name)
1689
if ( ! ldb_dn_validate(dn)) {
1692
for (i=0; i < dn->extended_comp_num; i++) {
1693
if (ldb_attr_cmp(dn->extended_components[i].name, name) == 0) {
1694
return &dn->extended_components[i].value;
1700
int ldb_dn_set_extended_component(struct ldb_dn *dn, const char *name, const struct ldb_val *val)
1702
struct ldb_dn_extended_component *p;
1705
if ( ! ldb_dn_validate(dn)) {
1706
return LDB_ERR_OTHER;
1709
for (i=0; i < dn->extended_comp_num; i++) {
1710
if (ldb_attr_cmp(dn->extended_components[i].name, name) == 0) {
1712
dn->extended_components[i].value = ldb_val_dup(dn->extended_components, val);
1714
dn->extended_components[i].name = talloc_strdup(dn->extended_components, name);
1715
if (!dn->extended_components[i].name || !dn->extended_components[i].value.data) {
1717
return LDB_ERR_OPERATIONS_ERROR;
1721
if (i != (dn->extended_comp_num - 1)) {
1722
memmove(&dn->extended_components[i], &dn->extended_components[i+1],
1723
((dn->extended_comp_num-1) - i)*sizeof(*dn->extended_components));
1725
dn->extended_comp_num--;
1727
dn->extended_components = talloc_realloc(dn,
1728
dn->extended_components,
1729
struct ldb_dn_extended_component,
1730
dn->extended_comp_num);
1731
if (!dn->extended_components) {
1733
return LDB_ERR_OPERATIONS_ERROR;
1740
p = dn->extended_components
1741
= talloc_realloc(dn,
1742
dn->extended_components,
1743
struct ldb_dn_extended_component,
1744
dn->extended_comp_num + 1);
1745
if (!dn->extended_components) {
1747
return LDB_ERR_OPERATIONS_ERROR;
1750
p[dn->extended_comp_num].value = ldb_val_dup(dn->extended_components, val);
1751
p[dn->extended_comp_num].name = talloc_strdup(p, name);
1753
if (!dn->extended_components[i].name || !dn->extended_components[i].value.data) {
1755
return LDB_ERR_OPERATIONS_ERROR;
1757
dn->extended_components = p;
1758
dn->extended_comp_num++;
1763
void ldb_dn_remove_extended_components(struct ldb_dn *dn)
1765
dn->extended_comp_num = 0;
1766
LDB_FREE(dn->extended_components);
1769
bool ldb_dn_is_valid(struct ldb_dn *dn)
1771
if ( ! dn) return false;
1772
return ! dn->invalid;
1775
bool ldb_dn_is_special(struct ldb_dn *dn)
1777
if ( ! dn || dn->invalid) return false;
1781
bool ldb_dn_has_extended(struct ldb_dn *dn)
1783
if ( ! dn || dn->invalid) return false;
1784
if (dn->extended_linearized && (dn->extended_linearized[0] == '<')) return true;
1785
return dn->extended_comp_num != 0;
1788
bool ldb_dn_check_special(struct ldb_dn *dn, const char *check)
1790
if ( ! dn || dn->invalid) return false;
1791
return ! strcmp(dn->linearized, check);
1794
bool ldb_dn_is_null(struct ldb_dn *dn)
1796
if ( ! dn || dn->invalid) return false;
1797
if (ldb_dn_has_extended(dn)) return false;
1798
if (dn->linearized && (dn->linearized[0] == '\0')) return true;