diff options
author | Simo Sorce <idra@samba.org> | 2005-08-18 15:02:01 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:33:32 -0500 |
commit | 3e4c4cff2177af33efdb15f03a1bbcb639505cee (patch) | |
tree | 852723e443ca41ef6b1d91dd3c11224eddebbd48 /source4/lib/ldb/common/ldb_dn.c | |
parent | a8d51f87620a688a286603766cbb7edb2b7c6e60 (diff) | |
download | samba-3e4c4cff2177af33efdb15f03a1bbcb639505cee.tar.gz samba-3e4c4cff2177af33efdb15f03a1bbcb639505cee.tar.bz2 samba-3e4c4cff2177af33efdb15f03a1bbcb639505cee.zip |
r9391: Convert all the code to use struct ldb_dn to ohandle ldap like distinguished names
Provide more functions to handle DNs in this form
(This used to be commit 692e35b7797e39533dd2a1c4b63d9da30f1eb5ba)
Diffstat (limited to 'source4/lib/ldb/common/ldb_dn.c')
-rw-r--r-- | source4/lib/ldb/common/ldb_dn.c | 308 |
1 files changed, 299 insertions, 9 deletions
diff --git a/source4/lib/ldb/common/ldb_dn.c b/source4/lib/ldb/common/ldb_dn.c index d13238cc17..dae79fd9e1 100644 --- a/source4/lib/ldb/common/ldb_dn.c +++ b/source4/lib/ldb/common/ldb_dn.c @@ -41,8 +41,26 @@ #define LDB_DN_NULL_FAILED(x) if (!(x)) goto failed +#define LDB_SPECIAL "@SPECIAL" + +BOOL ldb_dn_is_special(const struct ldb_dn *dn) +{ + if (dn == NULL || dn->comp_num != 1) return 0; + + return ! strcmp(dn->components[0].name, LDB_SPECIAL); +} + +BOOL ldb_dn_check_special(const struct ldb_dn *dn, const char *check) +{ + if (dn == NULL || dn->comp_num != 1) return 0; + + return ! strcmp(dn->components[0].value.data, check); +} + static int ldb_dn_is_valid_attribute_name(const char *name) { + if (name == NULL) return 0; + while (*name) { if (! isascii(*name)) { return 0; @@ -165,6 +183,8 @@ static int get_quotes_position(const char *source, int *quote_start, int *quote_ { const char *p; + if (source == NULL || quote_start == NULL || quote_end == NULL) return -1; + p = source; /* check if there are quotes surrounding the value */ @@ -197,6 +217,8 @@ static char *seek_to_separator(char *string, const char *separators) char *p; int ret, qs, qe; + if (string == NULL || separators == NULL) return NULL; + p = strchr(string, '='); LDB_DN_NULL_FAILED(p); @@ -254,6 +276,11 @@ static struct ldb_dn_component ldb_dn_explode_component(void *mem_ctx, char *raw char *p; int ret, qs, qe; + if (raw_component == NULL) { + dc.name = NULL; + return dc; + } + /* find attribute type/value separator */ p = strchr(raw_component, '='); LDB_DN_NULL_FAILED(p); @@ -300,14 +327,10 @@ failed: return dc; } -struct ldb_dn *ldb_dn_explode(void *mem_ctx, const char *dn) +struct ldb_dn *ldb_dn_new(void *mem_ctx) { - struct ldb_dn *edn; /* the exploded dn */ - char *pdn, *p; + struct ldb_dn *edn; - pdn = NULL; - - /* Allocate a structure to hold the exploded DN */ edn = talloc(mem_ctx, struct ldb_dn); LDB_DN_NULL_FAILED(edn); @@ -315,12 +338,33 @@ struct ldb_dn *ldb_dn_explode(void *mem_ctx, const char *dn) edn->comp_num = 0; edn->components = NULL; + return edn; + +failed: + return NULL; +} + +struct ldb_dn *ldb_dn_explode(void *mem_ctx, const char *dn) +{ + struct ldb_dn *edn; /* the exploded dn */ + char *pdn, *p; + + if (dn == NULL) return NULL; + + /* Allocate a structure to hold the exploded DN */ + edn = ldb_dn_new(mem_ctx); + + /* Empty DNs */ + if (dn[0] == '\0') { + return edn; + } + /* Special DNs case */ if (dn[0] == '@') { edn->comp_num = 1; edn->components = talloc(edn, struct ldb_dn_component); if (edn->components == NULL) goto failed; - edn->components[0].name = talloc_strdup(edn->components, "@SPECIAL"); + edn->components[0].name = talloc_strdup(edn->components, LDB_SPECIAL); if (edn->components[0].name == NULL) goto failed; edn->components[0].value.data = talloc_strdup(edn->components, dn); if (edn->components[0].value.data== NULL) goto failed; @@ -376,8 +420,10 @@ char *ldb_dn_linearize(void *mem_ctx, const struct ldb_dn *edn) char *dn, *value; int i; + if (edn == NULL) return NULL; + /* Special DNs */ - if ((edn->comp_num == 1) && strcmp("@SPECIAL", edn->components[0].name) == 0) { + if (ldb_dn_is_special(edn)) { dn = talloc_strdup(mem_ctx, edn->components[0].value.data); return dn; } @@ -419,6 +465,10 @@ int ldb_dn_compare_base(struct ldb_context *ldb, return (dn->comp_num - base->comp_num); } + if (base == NULL || base->comp_num == 0) return 0; + if (dn == NULL || dn->comp_num == 0) return -1; + if (base->comp_num > dn->comp_num) return -1; + /* if the number of components doesn't match they differ */ n0 = base->comp_num - 1; n1 = dn->comp_num - 1; @@ -450,6 +500,8 @@ int ldb_dn_compare(struct ldb_context *ldb, const struct ldb_dn *edn0, const struct ldb_dn *edn1) { + if (edn0 == NULL || edn1 == NULL) return edn1 - edn0; + if (edn0->comp_num != edn1->comp_num) return (edn1->comp_num - edn0->comp_num); @@ -462,6 +514,8 @@ int ldb_dn_cmp(struct ldb_context *ldb, const char *dn0, const char *dn1) struct ldb_dn *edn1; int ret; + if (dn0 == NULL || dn1 == NULL) return dn1 - dn0; + edn0 = ldb_dn_explode_casefold(ldb, dn0); if (edn0 == NULL) return 0; @@ -488,7 +542,9 @@ struct ldb_dn *ldb_dn_casefold(struct ldb_context *ldb, const struct ldb_dn *edn struct ldb_dn *cedn; int i; - cedn = talloc(ldb, struct ldb_dn); + if (edn == NULL) return NULL; + + cedn = ldb_dn_new(ldb); LDB_DN_NULL_FAILED(cedn); cedn->comp_num = edn->comp_num; @@ -521,6 +577,8 @@ struct ldb_dn *ldb_dn_explode_casefold(struct ldb_context *ldb, const char *dn) { struct ldb_dn *edn, *cdn; + if (dn == NULL) return NULL; + edn = ldb_dn_explode(ldb, dn); if (edn == NULL) return NULL; @@ -529,3 +587,235 @@ struct ldb_dn *ldb_dn_explode_casefold(struct ldb_context *ldb, const char *dn) talloc_free(edn); return cdn; } + +char *ldb_dn_linearize_casefold(struct ldb_context *ldb, const struct ldb_dn *edn) +{ + struct ldb_dn *cdn; + char *dn; + + if (edn == NULL) return NULL; + + /* Special DNs */ + if (ldb_dn_is_special(edn)) { + dn = talloc_strdup(ldb, edn->components[0].value.data); + return dn; + } + + cdn = ldb_dn_casefold(ldb, edn); + if (cdn == NULL) return NULL; + + dn = ldb_dn_linearize(ldb, cdn); + if (dn == NULL) { + talloc_free(cdn); + return NULL; + } + + talloc_free(cdn); + return dn; +} + +static struct ldb_dn_component ldb_dn_copy_component(void *mem_ctx, struct ldb_dn_component *src) +{ + struct ldb_dn_component dst; + + dst.name = NULL; + + if (src == NULL) { + return dst; + } + + dst.value = ldb_val_dup(mem_ctx, &(src->value)); + if (dst.value.data == NULL) { + return dst; + } + + dst.name = talloc_strdup(mem_ctx, src->name); + if (dst.name == NULL) { + talloc_free(dst.value.data); + } + + return dst; +} + +/* copy specified number of elements of a dn into a new one + element are copied from top level up to the unique rdn + num_el may be greater then dn->comp_num (see ldb_dn_make_child) +*/ +struct ldb_dn *ldb_dn_copy_partial(void *mem_ctx, const struct ldb_dn *dn, int num_el) +{ + struct ldb_dn *new; + int i, n, e; + + if (dn == NULL) return NULL; + if (num_el <= 0) return NULL; + + new = ldb_dn_new(mem_ctx); + LDB_DN_NULL_FAILED(new); + + new->comp_num = num_el; + n = new->comp_num - 1; + new->components = talloc_array(new, struct ldb_dn_component, new->comp_num); + + if (dn->comp_num == 0) return new; + e = dn->comp_num - 1; + + for (i = 0; i < new->comp_num; i++) { + new->components[n - i] = ldb_dn_copy_component(new->components, + &(dn->components[e - i])); + if ((e - i) == 0) { + return new; + } + } + + return new; + +failed: + talloc_free(new); + return NULL; +} + +struct ldb_dn *ldb_dn_copy(void *mem_ctx, const struct ldb_dn *dn) +{ + if (dn == NULL) return NULL; + return ldb_dn_copy_partial(mem_ctx, dn, dn->comp_num); +} + +struct ldb_dn *ldb_dn_get_parent(void *mem_ctx, const struct ldb_dn *dn) +{ + if (dn == NULL) return NULL; + return ldb_dn_copy_partial(mem_ctx, dn, dn->comp_num - 1); +} + +struct ldb_dn_component *ldb_dn_build_component(void *mem_ctx, const char *attr, + const char *val) +{ + struct ldb_dn_component *dc; + + if (attr == NULL || val == NULL) return NULL; + + dc = talloc(mem_ctx, struct ldb_dn_component); + if (dc == NULL) return NULL; + + dc->name = talloc_strdup(dc, attr); + if (dc->name == NULL) { + talloc_free(dc); + return NULL; + } + + dc->value.data = talloc_strdup(dc, val); + if (dc->value.data == NULL) { + talloc_free(dc); + return NULL; + } + + dc->value.length = strlen(val); + + return dc; +} + +struct ldb_dn *ldb_dn_build_child(void *mem_ctx, const char *attr, + const char * value, + const struct ldb_dn *base) +{ + struct ldb_dn *new; + if (! ldb_dn_is_valid_attribute_name(attr)) return NULL; + if (value == NULL || value == '\0') return NULL; + + if (base != NULL) { + new = ldb_dn_copy_partial(mem_ctx, base, base->comp_num + 1); + LDB_DN_NULL_FAILED(new); + } else { + new = ldb_dn_new(mem_ctx); + LDB_DN_NULL_FAILED(new); + + new->comp_num = 1; + new->components = talloc_array(new, struct ldb_dn_component, new->comp_num); + } + + new->components[0].name = talloc_strdup(new->components, attr); + LDB_DN_NULL_FAILED(new->components[0].name); + + new->components[0].value.data = talloc_strdup(new->components, value); + LDB_DN_NULL_FAILED(new->components[0].value.data); + new->components[0].value.length = strlen(new->components[0].value.data); + + return new; + +failed: + talloc_free(new); + return NULL; + +} + +struct ldb_dn *ldb_dn_make_child(void *mem_ctx, const struct ldb_dn_component *component, + const struct ldb_dn *base) +{ + if (component == NULL) return NULL; + + return ldb_dn_build_child(mem_ctx, component->name, component->value.data, base); +} + +struct ldb_dn *ldb_dn_compose(void *mem_ctx, const struct ldb_dn *dn1, const struct ldb_dn *dn2) +{ + int i; + struct ldb_dn *new; + + if (dn2 == NULL && dn1 == NULL) { + return NULL; + } + + if (dn2 == NULL) { + new = ldb_dn_new(mem_ctx); + LDB_DN_NULL_FAILED(new); + + new->comp_num = dn1->comp_num; + new->components = talloc_array(new, struct ldb_dn_component, new->comp_num); + } else { + new = ldb_dn_copy_partial(mem_ctx, dn2, dn2->comp_num + dn1?dn1->comp_num:0); + } + + if (dn1 == NULL) { + return new; + } + + for (i = 0; i < dn1->comp_num; i++) { + new->components[i] = ldb_dn_copy_component(new->components, + &(dn1->components[i])); + } + + return new; + +failed: + talloc_free(new); + return NULL; +} + +struct ldb_dn *ldb_dn_compose_string_dn(void *mem_ctx, const char *dn1, const struct ldb_dn *dn2) +{ + if (dn1 == NULL) return NULL; + + return ldb_dn_compose(mem_ctx, ldb_dn_explode(mem_ctx, dn1), dn2); +} + +struct ldb_dn_component *ldb_dn_get_rdn(void *mem_ctx, const struct ldb_dn *dn) +{ + struct ldb_dn_component *rdn; + + if (dn == NULL) return NULL; + + if (dn->comp_num < 1) { + return NULL; + } + + rdn = talloc(mem_ctx, struct ldb_dn_component); + if (rdn == NULL) return NULL; + + *rdn = ldb_dn_copy_component(mem_ctx, &dn->components[0]); + if (rdn->name == NULL) { + talloc_free(rdn); + return NULL; + } + + return rdn; +} + |