From b7774527faf095f612eb1de48efacec6bd710a87 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 1 Nov 2006 23:31:26 +0000 Subject: [PATCH] r19531: Make struct ldb_dn opaque and local to ldb_dn.c (This used to be commit 889fb983ba1cf8a11424a8b3dc3a5ef76e780082) --- source4/dsdb/samdb/ldb_modules/partition.c | 2 +- source4/dsdb/samdb/ldb_modules/rootdse.c | 2 +- source4/dsdb/samdb/ldb_modules/samldb.c | 26 +++---- source4/ldap_server/ldap_backend.c | 11 ++- source4/lib/ldb/common/ldb_dn.c | 119 +++++++++++++++++++++-------- source4/lib/ldb/common/ldb_match.c | 2 +- source4/lib/ldb/include/ldb.h | 62 +++++++-------- source4/lib/ldb/ldb_ildap/ldb_ildap.c | 4 +- source4/lib/ldb/ldb_tdb/ldb_search.c | 2 +- source4/lib/ldb/modules/ldb_map.c | 116 +++++++++++----------------- source4/lib/ldb/modules/ldb_map_inbound.c | 2 +- source4/lib/ldb/modules/ldb_map_outbound.c | 10 +-- source4/lib/ldb/modules/ldb_map_private.h | 4 +- source4/lib/ldb/modules/rdn_name.c | 46 ++++++----- source4/lib/ldb/samba/ldif_handlers.c | 18 ++--- source4/nbt_server/wins/winsdb.c | 17 +++-- 16 files changed, 238 insertions(+), 205 deletions(-) diff --git a/source4/dsdb/samdb/ldb_modules/partition.c b/source4/dsdb/samdb/ldb_modules/partition.c index a38f08e1040..d678364b6e7 100644 --- a/source4/dsdb/samdb/ldb_modules/partition.c +++ b/source4/dsdb/samdb/ldb_modules/partition.c @@ -316,7 +316,7 @@ static int partition_search(struct ldb_module *module, struct ldb_request *req) ac = talloc_get_type(h->private_data, struct partition_context); /* Search from the base DN */ - if (!req->op.search.base || req->op.search.base->comp_num == 0) { + if (!req->op.search.base || (ldb_dn_get_comp_num(req->op.search.base) == 0)) { return partition_send_all(module, ac, req); } for (i=0; data && data->partitions && data->partitions[i]; i++) { diff --git a/source4/dsdb/samdb/ldb_modules/rootdse.c b/source4/dsdb/samdb/ldb_modules/rootdse.c index 88f5eba2b48..c174ac65a10 100644 --- a/source4/dsdb/samdb/ldb_modules/rootdse.c +++ b/source4/dsdb/samdb/ldb_modules/rootdse.c @@ -173,7 +173,7 @@ static int rootdse_search(struct ldb_module *module, struct ldb_request *req) /* see if its for the rootDSE */ if (req->op.search.scope != LDB_SCOPE_BASE || - (req->op.search.base && req->op.search.base->comp_num != 0)) { + (req->op.search.base && ldb_dn_get_comp_num(req->op.search.base) != 0)) { return ldb_next_request(module, req); } diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c index fbb5ead537d..e86a3bfde4b 100644 --- a/source4/dsdb/samdb/ldb_modules/samldb.c +++ b/source4/dsdb/samdb/ldb_modules/samldb.c @@ -433,7 +433,7 @@ static int samldb_fill_group_object(struct ldb_module *module, const struct ldb_ int ret; const char *name; struct ldb_message *msg2; - struct ldb_dn_component *rdn; + const char *rdn_name; TALLOC_CTX *mem_ctx = talloc_new(msg); const char *errstr; if (!mem_ctx) { @@ -457,10 +457,10 @@ static int samldb_fill_group_object(struct ldb_module *module, const struct ldb_ return ret; } - rdn = ldb_dn_get_rdn(msg2, msg2->dn); + rdn_name = ldb_dn_get_rdn_name(msg2->dn); - if (strcasecmp(rdn->name, "cn") != 0) { - ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_fill_group_object: Bad RDN (%s) for group!\n", rdn->name); + if (strcasecmp(rdn_name, "cn") != 0) { + ldb_debug(module->ldb, LDB_DEBUG_FATAL, "samldb_fill_group_object: Bad RDN (%s) for group!\n", rdn_name); talloc_free(mem_ctx); return LDB_ERR_CONSTRAINT_VIOLATION; } @@ -496,7 +496,7 @@ static int samldb_fill_user_or_computer_object(struct ldb_module *module, const int ret; char *name; struct ldb_message *msg2; - struct ldb_dn_component *rdn; + const char *rdn_name; TALLOC_CTX *mem_ctx = talloc_new(msg); const char *errstr; if (!mem_ctx) { @@ -556,10 +556,10 @@ static int samldb_fill_user_or_computer_object(struct ldb_module *module, const } } - rdn = ldb_dn_get_rdn(msg2, msg2->dn); + rdn_name = ldb_dn_get_rdn_name(msg2->dn); - if (strcasecmp(rdn->name, "cn") != 0) { - ldb_asprintf_errstring(module->ldb, "Bad RDN (%s=) for user/computer, should be CN=!\n", rdn->name); + if (strcasecmp(rdn_name, "cn") != 0) { + ldb_asprintf_errstring(module->ldb, "Bad RDN (%s=) for user/computer, should be CN=!\n", rdn_name); talloc_free(mem_ctx); return LDB_ERR_CONSTRAINT_VIOLATION; } @@ -598,7 +598,7 @@ static int samldb_fill_foreignSecurityPrincipal_object(struct ldb_module *module struct ldb_message **ret_msg) { struct ldb_message *msg2; - struct ldb_dn_component *rdn; + const char *rdn_name; struct dom_sid *dom_sid; struct dom_sid *sid; const char *dom_attrs[] = { "name", NULL }; @@ -631,10 +631,10 @@ static int samldb_fill_foreignSecurityPrincipal_object(struct ldb_module *module return ret; } - rdn = ldb_dn_get_rdn(msg2, msg2->dn); + rdn_name = ldb_dn_get_rdn_name(msg2->dn); - if (strcasecmp(rdn->name, "cn") != 0) { - ldb_asprintf_errstring(module->ldb, "Bad RDN (%s=) for ForeignSecurityPrincipal, should be CN=!", rdn->name); + if (strcasecmp(rdn_name, "cn") != 0) { + ldb_asprintf_errstring(module->ldb, "Bad RDN (%s=) for ForeignSecurityPrincipal, should be CN=!", rdn_name); talloc_free(mem_ctx); return LDB_ERR_CONSTRAINT_VIOLATION; } @@ -643,7 +643,7 @@ static int samldb_fill_foreignSecurityPrincipal_object(struct ldb_module *module * domain SIDs ending up there, it would cause all sorts of * pain */ - sid = dom_sid_parse_talloc(msg2, (const char *)rdn->value.data); + sid = dom_sid_parse_talloc(msg2, (const char *)ldb_dn_get_rdn_val(msg2->dn)->data); if (!sid) { ldb_set_errstring(module->ldb, "No valid found SID in ForeignSecurityPrincipal CN!"); talloc_free(mem_ctx); diff --git a/source4/ldap_server/ldap_backend.c b/source4/ldap_server/ldap_backend.c index 9e26f1c6ebb..8e102139fe4 100644 --- a/source4/ldap_server/ldap_backend.c +++ b/source4/ldap_server/ldap_backend.c @@ -31,7 +31,7 @@ #define VALID_DN_SYNTAX(dn,i) do {\ if (!(dn)) {\ return NT_STATUS_NO_MEMORY;\ - } else if ((dn)->comp_num < (i)) {\ + } else if (ldb_dn_get_comp_num(dn) < (i)) {\ result = LDAP_INVALID_DN_SYNTAX;\ errstr = "Invalid DN (" #i " components needed for '" #dn "')";\ goto reply;\ @@ -641,7 +641,7 @@ static NTSTATUS ldapsrv_ModifyDNRequest(struct ldapsrv_call *call) goto reply; } - if (newrdn->comp_num > 1) { + if (ldb_dn_get_comp_num(newrdn) > 1) { result = LDAP_NAMING_VIOLATION; errstr = "Error new RDN invalid"; goto reply; @@ -652,7 +652,7 @@ static NTSTATUS ldapsrv_ModifyDNRequest(struct ldapsrv_call *call) VALID_DN_SYNTAX(parentdn, 0); DEBUG(10, ("ModifyDNRequest: newsuperior: [%s]\n", req->newsuperior)); - if (parentdn->comp_num < 1) { + if (ldb_dn_get_comp_num(parentdn) < 1) { result = LDAP_AFFECTS_MULTIPLE_DSAS; errstr = "Error new Superior DN invalid"; goto reply; @@ -664,7 +664,10 @@ static NTSTATUS ldapsrv_ModifyDNRequest(struct ldapsrv_call *call) NT_STATUS_HAVE_NO_MEMORY(parentdn); } - newdn = ldb_dn_make_child(local_ctx, ldb_dn_get_rdn(local_ctx, newrdn), parentdn); + newdn = ldb_dn_build_child(local_ctx, + ldb_dn_get_rdn_name(newrdn), + (char *)ldb_dn_get_rdn_val(newrdn)->data, + parentdn); NT_STATUS_HAVE_NO_MEMORY(newdn); reply: diff --git a/source4/lib/ldb/common/ldb_dn.c b/source4/lib/ldb/common/ldb_dn.c index e937a2b7fc4..550b80c26a0 100644 --- a/source4/lib/ldb/common/ldb_dn.c +++ b/source4/lib/ldb/common/ldb_dn.c @@ -41,6 +41,19 @@ #define LDB_SPECIAL "@SPECIAL" +/** + internal ldb exploded dn structures +*/ +struct ldb_dn_component { + char *name; + struct ldb_val value; +}; + +struct ldb_dn { + int comp_num; + struct ldb_dn_component *components; +}; + int ldb_dn_is_special(const struct ldb_dn *dn) { if (dn == NULL || dn->comp_num != 1) return 0; @@ -688,6 +701,26 @@ static struct ldb_dn_component ldb_dn_copy_component(void *mem_ctx, struct ldb_d return dst; } +/* Copy a DN but replace the old with the new base DN. */ +struct ldb_dn *ldb_dn_copy_rebase(void *mem_ctx, const struct ldb_dn *old, const struct ldb_dn *old_base, const struct ldb_dn *new_base) +{ + struct ldb_dn *new; + int i, offset; + + /* Perhaps we don't need to rebase at all? */ + if (!old_base || !new_base) { + return ldb_dn_copy(mem_ctx, old); + } + + offset = old->comp_num - old_base->comp_num; + new = ldb_dn_copy_partial(mem_ctx, new_base, offset + new_base->comp_num); + for (i = 0; i < offset; i++) { + new->components[i] = ldb_dn_copy_component(new->components, &(old->components[i])); + } + + return new; +} + /* 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 than dn->comp_num (see ldb_dn_make_child) @@ -799,15 +832,6 @@ failed: } -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, - (char *)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; @@ -872,28 +896,6 @@ struct ldb_dn *ldb_dn_string_compose(void *mem_ctx, const struct ldb_dn *base, c return dn; } -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; -} - /* Create a 'canonical name' string from a DN: ie dc=samba,dc=org -> samba.org/ @@ -962,3 +964,58 @@ char *ldb_dn_canonical_string(void *mem_ctx, const struct ldb_dn *dn) { char *ldb_dn_canonical_ex_string(void *mem_ctx, const struct ldb_dn *dn) { return ldb_dn_canonical(mem_ctx, dn, 1); } + +int ldb_dn_get_comp_num(const struct ldb_dn *dn) +{ + return dn->comp_num; +} + +const char *ldb_dn_get_component_name(const struct ldb_dn *dn, unsigned int num) +{ + if (num >= dn->comp_num) return NULL; + return dn->components[num].name; +} + +const struct ldb_val *ldb_dn_get_component_val(const struct ldb_dn *dn, unsigned int num) +{ + if (num >= dn->comp_num) return NULL; + return &dn->components[num].value; +} + +const char *ldb_dn_get_rdn_name(const struct ldb_dn *dn) { + if (dn->comp_num == 0) return NULL; + return dn->components[0].name; +} + +const struct ldb_val *ldb_dn_get_rdn_val(const struct ldb_dn *dn) { + if (dn->comp_num == 0) return NULL; + return &dn->components[0].value; +} + +int ldb_dn_set_component(struct ldb_dn *dn, int num, const char *name, const struct ldb_val val) +{ + char *n; + struct ldb_val v; + + if (num >= dn->comp_num) { + return LDB_ERR_OTHER; + } + + n = talloc_strdup(dn, name); + if ( ! n) { + return LDB_ERR_OTHER; + } + + v.length = val.length; + v.data = (uint8_t *)talloc_memdup(dn, val.data, v.length+1); + if ( ! v.data) { + return LDB_ERR_OTHER; + } + + talloc_free(dn->components[num].name); + talloc_free(dn->components[num].value.data); + dn->components[num].name = n; + dn->components[num].value = v; + + return LDB_SUCCESS; +} diff --git a/source4/lib/ldb/common/ldb_match.c b/source4/lib/ldb/common/ldb_match.c index 1fd12da7f39..0cd220ad607 100644 --- a/source4/lib/ldb/common/ldb_match.c +++ b/source4/lib/ldb/common/ldb_match.c @@ -58,7 +58,7 @@ static int ldb_match_scope(struct ldb_context *ldb, break; case LDB_SCOPE_ONELEVEL: - if (dn->comp_num == (base->comp_num + 1)) { + if (ldb_dn_get_comp_num(dn) == (ldb_dn_get_comp_num(base) + 1)) { if (ldb_dn_compare_base(ldb, base, dn) == 0) { ret = 1; } diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h index aa8b9447b29..17a2ec75569 100644 --- a/source4/lib/ldb/include/ldb.h +++ b/source4/lib/ldb/include/ldb.h @@ -3,7 +3,7 @@ Copyright (C) Andrew Tridgell 2004 Copyright (C) Stefan Metzmacher 2004 - Copyright (C) Simo Sorce 2005 + Copyright (C) Simo Sorce 2005-2006 ** NOTE! The following LGPL license applies to the ldb ** library. This does NOT imply that all of Samba is released @@ -86,18 +86,9 @@ struct ldb_val { #endif /*! \endcond */ -/** - internal ldb exploded dn structures -*/ -struct ldb_dn_component { - char *name; - struct ldb_val value; -}; - -struct ldb_dn { - int comp_num; - struct ldb_dn_component *components; -}; +/* opaque ldb_dn structures, see ldb_dn.c for internals */ +struct ldb_dn_component; +struct ldb_dn; /** There are a number of flags that are used with ldap_modify() in @@ -193,12 +184,6 @@ enum ldb_scope {LDB_SCOPE_DEFAULT=-1, struct ldb_context; -/* - the fuction type for the callback used in traversing the database -*/ -typedef int (*ldb_traverse_fn)(struct ldb_context *, const struct ldb_message *); - - /* debugging uses one of the following levels */ enum ldb_debug_level {LDB_DEBUG_FATAL, LDB_DEBUG_ERROR, LDB_DEBUG_WARNING, LDB_DEBUG_TRACE}; @@ -333,22 +318,25 @@ char *ldb_binary_encode_string(void *mem_ctx, const char *string); typedef int (*ldb_attr_handler_t)(struct ldb_context *, void *mem_ctx, const struct ldb_val *, struct ldb_val *); typedef int (*ldb_attr_comparison_t)(struct ldb_context *, void *mem_ctx, const struct ldb_val *, const struct ldb_val *); +/* + attribute handler structure + + attr -> The attribute name + flags -> LDB_ATTR_FLAG_* + ldif_read_fn -> convert from ldif to binary format + ldif_write_fn -> convert from binary to ldif format + canonicalise_fn -> canonicalise a value, for use by indexing and dn construction + comparison_fn -> compare two values +*/ + struct ldb_attrib_handler { - const char *attr; - /* LDB_ATTR_FLAG_* */ + const char *attr; unsigned flags; - /* convert from ldif to binary format */ ldb_attr_handler_t ldif_read_fn; - - /* convert from binary to ldif format */ ldb_attr_handler_t ldif_write_fn; - - /* canonicalise a value, for use by indexing and dn construction */ ldb_attr_handler_t canonicalise_fn; - - /* compare two values */ ldb_attr_comparison_t comparison_fn; }; @@ -1295,18 +1283,25 @@ struct ldb_dn *ldb_dn_casefold(struct ldb_context *ldb, void *mem_ctx, const str struct ldb_dn *ldb_dn_explode_casefold(struct ldb_context *ldb, void *mem_ctx, const char *dn); struct ldb_dn *ldb_dn_copy_partial(void *mem_ctx, const struct ldb_dn *dn, int num_el); struct ldb_dn *ldb_dn_copy(void *mem_ctx, const struct ldb_dn *dn); +struct ldb_dn *ldb_dn_copy_rebase(void *mem_ctx, const struct ldb_dn *old, const struct ldb_dn *old_base, const struct ldb_dn *new_base); struct ldb_dn *ldb_dn_get_parent(void *mem_ctx, const struct ldb_dn *dn); struct ldb_dn_component *ldb_dn_build_component(void *mem_ctx, const char *attr, const char *val); struct ldb_dn *ldb_dn_build_child(void *mem_ctx, const char *attr, const char * value, const struct ldb_dn *base); -struct ldb_dn *ldb_dn_make_child(void *mem_ctx, - const struct ldb_dn_component *component, - const struct ldb_dn *base); struct ldb_dn *ldb_dn_compose(void *mem_ctx, const struct ldb_dn *dn1, const struct ldb_dn *dn2); struct ldb_dn *ldb_dn_string_compose(void *mem_ctx, const struct ldb_dn *base, const char *child_fmt, ...) PRINTF_ATTRIBUTE(3,4); -struct ldb_dn_component *ldb_dn_get_rdn(void *mem_ctx, const struct ldb_dn *dn); +char *ldb_dn_canonical_string(void *mem_ctx, const struct ldb_dn *dn); +char *ldb_dn_canonical_ex_string(void *mem_ctx, const struct ldb_dn *dn); +int ldb_dn_get_comp_num(const struct ldb_dn *dn); +const char *ldb_dn_get_component_name(const struct ldb_dn *dn, unsigned int num); +const struct ldb_val *ldb_dn_get_component_val(const struct ldb_dn *dn, unsigned int num); +const char *ldb_dn_get_rdn_name(const struct ldb_dn *dn); +const struct ldb_val *ldb_dn_get_rdn_val(const struct ldb_dn *dn); +int ldb_dn_set_component(struct ldb_dn *dn, int num, const char *name, const struct ldb_val val); + + /* useful functions for ldb_message structure manipulation */ int ldb_dn_cmp(struct ldb_context *ldb, const char *dn1, const char *dn2); @@ -1546,9 +1541,6 @@ char *ldb_timestring(void *mem_ctx, time_t t); */ time_t ldb_string_to_time(const char *s); -char *ldb_dn_canonical_string(void *mem_ctx, const struct ldb_dn *dn); -char *ldb_dn_canonical_ex_string(void *mem_ctx, const struct ldb_dn *dn); - void ldb_qsort (void *const pbase, size_t total_elems, size_t size, void *opaque, ldb_qsort_cmp_fn_t cmp); #endif diff --git a/source4/lib/ldb/ldb_ildap/ldb_ildap.c b/source4/lib/ldb/ldb_ildap/ldb_ildap.c index 3843d2b8250..5a3ccd69779 100644 --- a/source4/lib/ldb/ldb_ildap/ldb_ildap.c +++ b/source4/lib/ldb/ldb_ildap/ldb_ildap.c @@ -639,8 +639,8 @@ static int ildb_rename(struct ldb_module *module, struct ldb_request *req) msg->r.ModifyDNRequest.newrdn = talloc_asprintf(msg, "%s=%s", - req->op.rename.newdn->components[0].name, - ldb_dn_escape_value(msg, req->op.rename.newdn->components[0].value)); + ldb_dn_get_rdn_name(req->op.rename.newdn), + ldb_dn_escape_value(msg, *ldb_dn_get_rdn_val(req->op.rename.newdn))); if (msg->r.ModifyDNRequest.newrdn == NULL) { talloc_free(msg); return LDB_ERR_OPERATIONS_ERROR; diff --git a/source4/lib/ldb/ldb_tdb/ldb_search.c b/source4/lib/ldb/ldb_tdb/ldb_search.c index 4b76c437b64..884eccd3622 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_search.c +++ b/source4/lib/ldb/ldb_tdb/ldb_search.c @@ -464,7 +464,7 @@ int ltdb_search(struct ldb_module *module, struct ldb_request *req) struct ldb_reply *ares; int ret; - if ((req->op.search.base == NULL || req->op.search.base->comp_num == 0) && + if ((req->op.search.base == NULL || ldb_dn_get_comp_num(req->op.search.base) == 0) && (req->op.search.scope == LDB_SCOPE_BASE || req->op.search.scope == LDB_SCOPE_ONELEVEL)) return LDB_ERR_OPERATIONS_ERROR; diff --git a/source4/lib/ldb/modules/ldb_map.c b/source4/lib/ldb/modules/ldb_map.c index 9146f2d863b..32e64f3eb2c 100644 --- a/source4/lib/ldb/modules/ldb_map.c +++ b/source4/lib/ldb/modules/ldb_map.c @@ -181,60 +181,16 @@ BOOL map_check_local_db(struct ldb_module *module) return True; } -/* WARK: verbatim copy from ldb_dn.c */ -static struct ldb_dn_component ldb_dn_copy_component(void *mem_ctx, struct ldb_dn_component *src) -{ - struct ldb_dn_component dst; - - memset(&dst, 0, sizeof(dst)); - - 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 a DN but replace the old with the new base DN. */ -static struct ldb_dn *ldb_dn_rebase(void *mem_ctx, const struct ldb_dn *old, const struct ldb_dn *old_base, const struct ldb_dn *new_base) -{ - struct ldb_dn *new; - int i, offset; - - /* Perhaps we don't need to rebase at all? */ - if (!old_base || !new_base) { - return ldb_dn_copy(mem_ctx, old); - } - - offset = old->comp_num - old_base->comp_num; - new = ldb_dn_copy_partial(mem_ctx, new_base, offset + new_base->comp_num); - for (i = 0; i < offset; i++) { - new->components[i] = ldb_dn_copy_component(new->components, &(old->components[i])); - } - - return new; -} - /* Copy a DN with the base DN of the local partition. */ static struct ldb_dn *ldb_dn_rebase_local(void *mem_ctx, const struct ldb_map_context *data, const struct ldb_dn *dn) { - return ldb_dn_rebase(mem_ctx, dn, data->remote_base_dn, data->local_base_dn); + return ldb_dn_copy_rebase(mem_ctx, dn, data->remote_base_dn, data->local_base_dn); } /* Copy a DN with the base DN of the remote partition. */ static struct ldb_dn *ldb_dn_rebase_remote(void *mem_ctx, const struct ldb_map_context *data, const struct ldb_dn *dn) { - return ldb_dn_rebase(mem_ctx, dn, data->local_base_dn, data->remote_base_dn); + return ldb_dn_copy_rebase(mem_ctx, dn, data->local_base_dn, data->remote_base_dn); } /* Run a request and make sure it targets the remote partition. */ @@ -460,23 +416,23 @@ int map_attrs_merge(struct ldb_module *module, void *mem_ctx, const char ***attr * ================== */ /* Map an ldb value into the remote partition. */ -struct ldb_val ldb_val_map_local(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, struct ldb_val val) +struct ldb_val ldb_val_map_local(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, const struct ldb_val *val) { if (map && (map->type == MAP_CONVERT) && (map->u.convert.convert_local)) { - return map->u.convert.convert_local(module, mem_ctx, &val); + return map->u.convert.convert_local(module, mem_ctx, val); } - return ldb_val_dup(mem_ctx, &val); + return ldb_val_dup(mem_ctx, val); } /* Map an ldb value back into the local partition. */ -struct ldb_val ldb_val_map_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, struct ldb_val val) +struct ldb_val ldb_val_map_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, const struct ldb_val *val) { if (map && (map->type == MAP_CONVERT) && (map->u.convert.convert_remote)) { - return map->u.convert.convert_remote(module, mem_ctx, &val); + return map->u.convert.convert_remote(module, mem_ctx, val); } - return ldb_val_dup(mem_ctx, &val); + return ldb_val_dup(mem_ctx, val); } @@ -500,10 +456,11 @@ struct ldb_dn *ldb_dn_map_local(struct ldb_module *module, void *mem_ctx, const { const struct ldb_map_context *data = map_get_context(module); struct ldb_dn *newdn; - struct ldb_dn_component *old, *new; const struct ldb_map_attribute *map; enum ldb_map_attr_type map_type; - int i; + const char *name; + struct ldb_val value; + int i, ret; if (dn == NULL) { return NULL; @@ -516,10 +473,8 @@ struct ldb_dn *ldb_dn_map_local(struct ldb_module *module, void *mem_ctx, const } /* For each RDN, map the component name and possibly the value */ - for (i = 0; i < newdn->comp_num; i++) { - old = &dn->components[i]; - new = &newdn->components[i]; - map = map_attr_find_local(data, old->name); + for (i = 0; i < ldb_dn_get_comp_num(newdn); i++) { + map = map_attr_find_local(data, ldb_dn_get_component_name(dn, i)); /* Unknown attribute - leave this RDN as is and hope the best... */ if (map == NULL) { @@ -533,21 +488,30 @@ struct ldb_dn *ldb_dn_map_local(struct ldb_module *module, void *mem_ctx, const case MAP_GENERATE: ldb_debug(module->ldb, LDB_DEBUG_ERROR, "ldb_map: " "MAP_IGNORE/MAP_GENERATE attribute '%s' " - "used in DN!\n", old->name); + "used in DN!\n", ldb_dn_get_component_name(dn, i)); goto failed; case MAP_CONVERT: if (map->u.convert.convert_local == NULL) { ldb_debug(module->ldb, LDB_DEBUG_ERROR, "ldb_map: " "'convert_local' not set for attribute '%s' " - "used in DN!\n", old->name); + "used in DN!\n", ldb_dn_get_component_name(dn, i)); goto failed; } /* fall through */ case MAP_KEEP: case MAP_RENAME: - new->name = discard_const_p(char, map_attr_map_local(newdn->components, map, old->name)); - new->value = ldb_val_map_local(module, newdn->components, map, old->value); + name = map_attr_map_local(newdn, map, ldb_dn_get_component_name(dn, i)); + if (name == NULL) goto failed; + + value = ldb_val_map_local(module, newdn, map, ldb_dn_get_component_val(dn, i)); + if (value.data == NULL) goto failed; + + ret = ldb_dn_set_component(newdn, i, name, value); + if (ret != LDB_SUCCESS) { + goto failed; + } + break; } } @@ -564,10 +528,11 @@ struct ldb_dn *ldb_dn_map_remote(struct ldb_module *module, void *mem_ctx, const { const struct ldb_map_context *data = map_get_context(module); struct ldb_dn *newdn; - struct ldb_dn_component *old, *new; const struct ldb_map_attribute *map; enum ldb_map_attr_type map_type; - int i; + const char *name; + struct ldb_val value; + int i, ret; if (dn == NULL) { return NULL; @@ -580,10 +545,8 @@ struct ldb_dn *ldb_dn_map_remote(struct ldb_module *module, void *mem_ctx, const } /* For each RDN, map the component name and possibly the value */ - for (i = 0; i < newdn->comp_num; i++) { - old = &dn->components[i]; - new = &newdn->components[i]; - map = map_attr_find_remote(data, old->name); + for (i = 0; i < ldb_dn_get_comp_num(newdn); i++) { + map = map_attr_find_remote(data, ldb_dn_get_component_name(dn, i)); /* Unknown attribute - leave this RDN as is and hope the best... */ if (map == NULL) { @@ -597,21 +560,30 @@ struct ldb_dn *ldb_dn_map_remote(struct ldb_module *module, void *mem_ctx, const case MAP_GENERATE: ldb_debug(module->ldb, LDB_DEBUG_ERROR, "ldb_map: " "MAP_IGNORE/MAP_GENERATE attribute '%s' " - "used in DN!\n", old->name); + "used in DN!\n", ldb_dn_get_component_name(dn, i)); goto failed; case MAP_CONVERT: if (map->u.convert.convert_remote == NULL) { ldb_debug(module->ldb, LDB_DEBUG_ERROR, "ldb_map: " "'convert_remote' not set for attribute '%s' " - "used in DN!\n", old->name); + "used in DN!\n", ldb_dn_get_component_name(dn, i)); goto failed; } /* fall through */ case MAP_KEEP: case MAP_RENAME: - new->name = discard_const_p(char, map_attr_map_remote(newdn->components, map, old->name)); - new->value = ldb_val_map_remote(module, newdn->components, map, old->value); + name = map_attr_map_remote(newdn, map, ldb_dn_get_component_name(dn, i)); + if (name == NULL) goto failed; + + value = ldb_val_map_remote(module, newdn, map, ldb_dn_get_component_val(dn, i)); + if (value.data == NULL) goto failed; + + ret = ldb_dn_set_component(newdn, i, name, value); + if (ret != LDB_SUCCESS) { + goto failed; + } + break; } } diff --git a/source4/lib/ldb/modules/ldb_map_inbound.c b/source4/lib/ldb/modules/ldb_map_inbound.c index b83a17e502c..38454b2b116 100644 --- a/source4/lib/ldb/modules/ldb_map_inbound.c +++ b/source4/lib/ldb/modules/ldb_map_inbound.c @@ -56,7 +56,7 @@ static struct ldb_message_element *ldb_msg_el_map_local(struct ldb_module *modul el->name = map_attr_map_local(el, map, old->name); for (i = 0; i < el->num_values; i++) { - el->values[i] = ldb_val_map_local(module, el->values, map, old->values[i]); + el->values[i] = ldb_val_map_local(module, el->values, map, &old->values[i]); } return el; diff --git a/source4/lib/ldb/modules/ldb_map_outbound.c b/source4/lib/ldb/modules/ldb_map_outbound.c index aa8d4f91653..dc213f36d18 100644 --- a/source4/lib/ldb/modules/ldb_map_outbound.c +++ b/source4/lib/ldb/modules/ldb_map_outbound.c @@ -235,7 +235,7 @@ static struct ldb_message_element *ldb_msg_el_map_remote(struct ldb_module *modu el->name = map_attr_map_remote(el, map, old->name); for (i = 0; i < el->num_values; i++) { - el->values[i] = ldb_val_map_remote(module, el->values, map, old->values[i]); + el->values[i] = ldb_val_map_remote(module, el->values, map, &old->values[i]); } return el; @@ -729,21 +729,21 @@ int map_subtree_collect_remote_simple(struct ldb_module *module, void *mem_ctx, *new = NULL; return 0; } - *(*new)->u.substring.chunks[i] = ldb_val_map_local(module, *new, map, *tree->u.substring.chunks[i]); + *(*new)->u.substring.chunks[i] = ldb_val_map_local(module, *new, map, tree->u.substring.chunks[i]); (*new)->u.substring.chunks[i+1] = NULL; } break; } case LDB_OP_EQUALITY: - (*new)->u.equality.value = ldb_val_map_local(module, *new, map, tree->u.equality.value); + (*new)->u.equality.value = ldb_val_map_local(module, *new, map, &tree->u.equality.value); break; case LDB_OP_LESS: case LDB_OP_GREATER: case LDB_OP_APPROX: - (*new)->u.comparison.value = ldb_val_map_local(module, *new, map, tree->u.comparison.value); + (*new)->u.comparison.value = ldb_val_map_local(module, *new, map, &tree->u.comparison.value); break; case LDB_OP_EXTENDED: - (*new)->u.extended.value = ldb_val_map_local(module, *new, map, tree->u.extended.value); + (*new)->u.extended.value = ldb_val_map_local(module, *new, map, &tree->u.extended.value); (*new)->u.extended.rule_id = talloc_strdup(*new, tree->u.extended.rule_id); break; default: /* unknown kind of simple subtree */ diff --git a/source4/lib/ldb/modules/ldb_map_private.h b/source4/lib/ldb/modules/ldb_map_private.h index 7fb2745179c..ae53ebbdd48 100644 --- a/source4/lib/ldb/modules/ldb_map_private.h +++ b/source4/lib/ldb/modules/ldb_map_private.h @@ -77,8 +77,8 @@ const char *map_attr_map_local(void *mem_ctx, const struct ldb_map_attribute *ma const char *map_attr_map_remote(void *mem_ctx, const struct ldb_map_attribute *map, const char *attr); int map_attrs_merge(struct ldb_module *module, void *mem_ctx, const char ***attrs, const char * const *more_attrs); -struct ldb_val ldb_val_map_local(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, struct ldb_val val); -struct ldb_val ldb_val_map_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, struct ldb_val val); +struct ldb_val ldb_val_map_local(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, const struct ldb_val *val); +struct ldb_val ldb_val_map_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_map_attribute *map, const struct ldb_val *val); struct ldb_dn *ldb_dn_map_local(struct ldb_module *module, void *mem_ctx, const struct ldb_dn *dn); struct ldb_dn *ldb_dn_map_remote(struct ldb_module *module, void *mem_ctx, const struct ldb_dn *dn); diff --git a/source4/lib/ldb/modules/rdn_name.c b/source4/lib/ldb/modules/rdn_name.c index 510a43dbc94..bab5f6a0149 100644 --- a/source4/lib/ldb/modules/rdn_name.c +++ b/source4/lib/ldb/modules/rdn_name.c @@ -58,7 +58,8 @@ static int rdn_name_add(struct ldb_module *module, struct ldb_request *req) struct ldb_request *down_req; struct ldb_message *msg; struct ldb_message_element *attribute; - struct ldb_dn_component *rdn; + const char *rdn_name; + struct ldb_val rdn_val; int i, ret; ldb_debug(module->ldb, LDB_DEBUG_TRACE, "rdn_name_add_record\n"); @@ -80,43 +81,45 @@ static int rdn_name_add(struct ldb_module *module, struct ldb_request *req) return LDB_ERR_OPERATIONS_ERROR; } - rdn = ldb_dn_get_rdn(msg, msg->dn); - if (rdn == NULL) { + rdn_name = ldb_dn_get_rdn_name(msg->dn); + if (rdn_name == NULL) { talloc_free(down_req); return LDB_ERR_OPERATIONS_ERROR; } + rdn_val = ldb_val_dup(msg, ldb_dn_get_rdn_val(msg->dn)); + /* Perhaps someone above us tried to set this? */ if ((attribute = rdn_name_find_attribute(msg, "name")) != NULL ) { attribute->num_values = 0; } - if (ldb_msg_add_value(msg, "name", &rdn->value, NULL) != 0) { + if (ldb_msg_add_value(msg, "name", &rdn_val, NULL) != 0) { talloc_free(down_req); return LDB_ERR_OPERATIONS_ERROR; } - attribute = rdn_name_find_attribute(msg, rdn->name); + attribute = rdn_name_find_attribute(msg, rdn_name); if (!attribute) { - if (ldb_msg_add_value(msg, rdn->name, &rdn->value, NULL) != 0) { + if (ldb_msg_add_value(msg, rdn_name, &rdn_val, NULL) != 0) { talloc_free(down_req); return LDB_ERR_OPERATIONS_ERROR; } } else { - const struct ldb_attrib_handler *handler = ldb_attrib_handler(module->ldb, rdn->name); + const struct ldb_attrib_handler *handler = ldb_attrib_handler(module->ldb, rdn_name); for (i = 0; i < attribute->num_values; i++) { - if (handler->comparison_fn(module->ldb, msg, &rdn->value, &attribute->values[i]) == 0) { + if (handler->comparison_fn(module->ldb, msg, &rdn_val, &attribute->values[i]) == 0) { /* overwrite so it matches in case */ - attribute->values[i] = rdn->value; + attribute->values[i] = rdn_val; break; } } if (i == attribute->num_values) { ldb_debug_set(module->ldb, LDB_DEBUG_FATAL, - "RDN mismatch on %s: %s", - ldb_dn_linearize(msg, msg->dn), rdn->name); + "RDN mismatch on %s: %s (%s)", + ldb_dn_linearize(msg, msg->dn), rdn_name, rdn_val.data); talloc_free(down_req); return LDB_ERR_OPERATIONS_ERROR; } @@ -190,16 +193,12 @@ static int rdn_name_rename(struct ldb_module *module, struct ldb_request *req) static int rdn_name_rename_do_mod(struct ldb_handle *h) { struct rename_context *ac; - struct ldb_dn_component *rdn; + const char *rdn_name; + struct ldb_val rdn_val; struct ldb_message *msg; ac = talloc_get_type(h->private_data, struct rename_context); - rdn = ldb_dn_get_rdn(ac, ac->orig_req->op.rename.newdn); - if (rdn == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - ac->mod_req = talloc_zero(ac, struct ldb_request); ac->mod_req->operation = LDB_MODIFY; @@ -213,16 +212,23 @@ static int rdn_name_rename_do_mod(struct ldb_handle *h) { return LDB_ERR_OPERATIONS_ERROR; } - if (ldb_msg_add_empty(msg, rdn->name, LDB_FLAG_MOD_REPLACE, NULL) != 0) { + rdn_name = ldb_dn_get_rdn_name(ac->orig_req->op.rename.newdn); + if (rdn_name == NULL) { + return LDB_ERR_OPERATIONS_ERROR; + } + + rdn_val = ldb_val_dup(msg, ldb_dn_get_rdn_val(ac->orig_req->op.rename.newdn)); + + if (ldb_msg_add_empty(msg, rdn_name, LDB_FLAG_MOD_REPLACE, NULL) != 0) { return LDB_ERR_OPERATIONS_ERROR; } - if (ldb_msg_add_value(msg, rdn->name, &rdn->value, NULL) != 0) { + if (ldb_msg_add_value(msg, rdn_name, &rdn_val, NULL) != 0) { return LDB_ERR_OPERATIONS_ERROR; } if (ldb_msg_add_empty(msg, "name", LDB_FLAG_MOD_REPLACE, NULL) != 0) { return LDB_ERR_OPERATIONS_ERROR; } - if (ldb_msg_add_value(msg, "name", &rdn->value, NULL) != 0) { + if (ldb_msg_add_value(msg, "name", &rdn_val, NULL) != 0) { return LDB_ERR_OPERATIONS_ERROR; } diff --git a/source4/lib/ldb/samba/ldif_handlers.c b/source4/lib/ldb/samba/ldif_handlers.c index 42f7605385c..e96ba348f96 100644 --- a/source4/lib/ldb/samba/ldif_handlers.c +++ b/source4/lib/ldb/samba/ldif_handlers.c @@ -300,9 +300,9 @@ static int ldif_canonicalise_objectCategory(struct ldb_context *ldb, void *mem_c dn1 = ldb_dn_explode(mem_ctx, (char *)in->data); if (dn1 == NULL) { oc1 = talloc_strndup(mem_ctx, (char *)in->data, in->length); - } else if (dn1->comp_num >= 1 && strcasecmp(dn1->components[0].name, "cn") == 0) { - oc1 = talloc_strndup(mem_ctx, (char *)dn1->components[0].value.data, - dn1->components[0].value.length); + } else if (ldb_dn_get_comp_num(dn1) >= 1 && strcasecmp(ldb_dn_get_rdn_name(dn1), "cn") == 0) { + const struct ldb_val *val = ldb_dn_get_rdn_val(dn1); + oc1 = talloc_strndup(mem_ctx, (char *)val->data, val->length); } else { return -1; } @@ -325,9 +325,9 @@ static int ldif_comparison_objectCategory(struct ldb_context *ldb, void *mem_ctx dn1 = ldb_dn_explode(mem_ctx, (char *)v1->data); if (dn1 == NULL) { oc1 = talloc_strndup(mem_ctx, (char *)v1->data, v1->length); - } else if (dn1->comp_num >= 1 && strcasecmp(dn1->components[0].name, "cn") == 0) { - oc1 = talloc_strndup(mem_ctx, (char *)dn1->components[0].value.data, - dn1->components[0].value.length); + } else if (ldb_dn_get_comp_num(dn1) >= 1 && strcasecmp(ldb_dn_get_rdn_name(dn1), "cn") == 0) { + const struct ldb_val *val = ldb_dn_get_rdn_val(dn1); + oc1 = talloc_strndup(mem_ctx, (char *)val->data, val->length); } else { oc1 = NULL; } @@ -335,9 +335,9 @@ static int ldif_comparison_objectCategory(struct ldb_context *ldb, void *mem_ctx dn2 = ldb_dn_explode(mem_ctx, (char *)v2->data); if (dn2 == NULL) { oc2 = talloc_strndup(mem_ctx, (char *)v2->data, v2->length); - } else if (dn2->comp_num >= 2 && strcasecmp(dn2->components[0].name, "cn") == 0) { - oc2 = talloc_strndup(mem_ctx, (char *)dn2->components[0].value.data, - dn2->components[0].value.length); + } else if (ldb_dn_get_comp_num(dn2) >= 2 && strcasecmp(ldb_dn_get_rdn_name(dn2), "cn") == 0) { + const struct ldb_val *val = ldb_dn_get_rdn_val(dn2); + oc2 = talloc_strndup(mem_ctx, (char *)val->data, val->length); } else { oc2 = NULL; } diff --git a/source4/nbt_server/wins/winsdb.c b/source4/nbt_server/wins/winsdb.c index 798663eb8b1..bc518233abb 100644 --- a/source4/nbt_server/wins/winsdb.c +++ b/source4/nbt_server/wins/winsdb.c @@ -179,6 +179,7 @@ static NTSTATUS winsdb_nbt_name(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, struct n { NTSTATUS status; struct nbt_name *name; + unsigned int comp_num; uint32_t cur = 0; name = talloc(mem_ctx, struct nbt_name); @@ -187,20 +188,22 @@ static NTSTATUS winsdb_nbt_name(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, struct n goto failed; } - if (dn->comp_num > 3) { + comp_num = ldb_dn_get_comp_num(dn); + + if (comp_num > 3) { status = NT_STATUS_INTERNAL_DB_CORRUPTION; goto failed; } - if (dn->comp_num > cur && strcasecmp("scope", dn->components[cur].name) == 0) { - name->scope = (const char *)talloc_steal(name, dn->components[cur].value.data); + if (comp_num > cur && strcasecmp("scope", ldb_dn_get_component_name(dn, cur)) == 0) { + name->scope = (const char *)talloc_strdup(name, (char *)ldb_dn_get_component_val(dn, cur)->data); cur++; } else { name->scope = NULL; } - if (dn->comp_num > cur && strcasecmp("name", dn->components[cur].name) == 0) { - name->name = (const char *)talloc_steal(name, dn->components[cur].value.data); + if (comp_num > cur && strcasecmp("name", ldb_dn_get_component_name(dn, cur)) == 0) { + name->name = (const char *)talloc_strdup(name, (char *)ldb_dn_get_component_val(dn, cur)->data); cur++; } else { name->name = talloc_strdup(name, ""); @@ -210,8 +213,8 @@ static NTSTATUS winsdb_nbt_name(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, struct n } } - if (dn->comp_num > cur && strcasecmp("type", dn->components[cur].name) == 0) { - name->type = strtoul((char *)dn->components[cur].value.data, NULL, 0); + if (comp_num > cur && strcasecmp("type", ldb_dn_get_component_name(dn, cur)) == 0) { + name->type = strtoul((char *)ldb_dn_get_component_val(dn, cur)->data, NULL, 0); cur++; } else { status = NT_STATUS_INTERNAL_DB_CORRUPTION; -- 2.11.4.GIT