From: Andrew Bartlett Date: Mon, 16 Nov 2009 07:46:28 +0000 (+1100) Subject: s4:dsdb Rework samdb code to use 'storage format' DNs for defaultObjectCategory X-Git-Tag: tdb-1.2.0~80 X-Git-Url: http://git.samba.org/samba.git/?p=ira%2Fwip.git;a=commitdiff_plain;h=07953142a4755354a8e76fa217c6cbf1b5dbcf30 s4:dsdb Rework samdb code to use 'storage format' DNs for defaultObjectCategory It is important to always ensure that this attribute has an extended DN if the rest of the database stores things that way. The knowlege of what format the DN is stored on disk with is passed around in an LDB opaque. Andrew Bartlett --- diff --git a/source4/dsdb/samdb/ldb_modules/extended_dn_out.c b/source4/dsdb/samdb/ldb_modules/extended_dn_out.c index bf70c3e80f1..a3e4f57f4bc 100644 --- a/source4/dsdb/samdb/ldb_modules/extended_dn_out.c +++ b/source4/dsdb/samdb/ldb_modules/extended_dn_out.c @@ -665,6 +665,7 @@ static int extended_dn_out_ldb_init(struct ldb_module *module) int ret; struct extended_dn_out_private *p = talloc(module, struct extended_dn_out_private); + struct dsdb_extended_dn_store_format *dn_format; ldb_module_set_private(module, p); @@ -673,6 +674,20 @@ static int extended_dn_out_ldb_init(struct ldb_module *module) return LDB_ERR_OPERATIONS_ERROR; } + dn_format = talloc(p, struct dsdb_extended_dn_store_format); + if (!dn_format) { + talloc_free(p); + ldb_oom(ldb_module_get_ctx(module)); + return LDB_ERR_OPERATIONS_ERROR; + } + + dn_format->store_extended_dn_in_ldb = true; + ret = ldb_set_opaque(ldb_module_get_ctx(module), DSDB_EXTENDED_DN_STORE_FORMAT_OPAQUE_NAME, dn_format); + if (ret != LDB_SUCCESS) { + talloc_free(p); + return ret; + } + p->dereference = false; p->normalise = false; @@ -690,6 +705,7 @@ static int extended_dn_out_dereference_init(struct ldb_module *module, const cha { int ret, i = 0; struct extended_dn_out_private *p = talloc_zero(module, struct extended_dn_out_private); + struct dsdb_extended_dn_store_format *dn_format; struct dsdb_openldap_dereference_control *dereference_control; struct dsdb_attribute *cur; struct ldb_context *ldb = ldb_module_get_ctx(module); @@ -702,6 +718,21 @@ static int extended_dn_out_dereference_init(struct ldb_module *module, const cha return LDB_ERR_OPERATIONS_ERROR; } + dn_format = talloc(p, struct dsdb_extended_dn_store_format); + if (!dn_format) { + talloc_free(p); + ldb_oom(ldb_module_get_ctx(module)); + return LDB_ERR_OPERATIONS_ERROR; + } + + dn_format->store_extended_dn_in_ldb = false; + + ret = ldb_set_opaque(ldb_module_get_ctx(module), DSDB_EXTENDED_DN_STORE_FORMAT_OPAQUE_NAME, dn_format); + if (ret != LDB_SUCCESS) { + talloc_free(p); + return ret; + } + p->dereference = true; /* At the moment, servers that need dereference also need the diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c index ba28d42e7fc..a26dcd2cead 100644 --- a/source4/dsdb/samdb/ldb_modules/objectclass.c +++ b/source4/dsdb/samdb/ldb_modules/objectclass.c @@ -621,7 +621,15 @@ static int objectclass_do_add(struct oc_context *ac) } if (!ldb_msg_find_element(msg, "objectCategory")) { - value = talloc_strdup(msg, current->objectclass->defaultObjectCategory); + struct dsdb_extended_dn_store_format *dn_format = talloc_get_type(ldb_module_get_private(ac->module), struct dsdb_extended_dn_store_format); + if (dn_format && dn_format->store_extended_dn_in_ldb == false) { + /* Strip off extended components */ + struct ldb_dn *dn = ldb_dn_new(msg, ldb, current->objectclass->defaultObjectCategory); + value = ldb_dn_alloc_linearized(msg, dn); + talloc_free(dn); + } else { + value = talloc_strdup(msg, current->objectclass->defaultObjectCategory); + } if (value == NULL) { ldb_oom(ldb); talloc_free(mem_ctx); @@ -1189,9 +1197,26 @@ static int objectclass_do_rename(struct oc_context *ac) return ldb_next_request(ac->module, rename_req); } +static int objectclass_init(struct ldb_module *module) +{ + struct ldb_context *ldb = ldb_module_get_ctx(module); + int ret; + /* Init everything else */ + ret = ldb_next_init(module); + if (ret != LDB_SUCCESS) { + return ret; + } + + /* Look for the opaque to indicate we might have to cut down the DN of defaultObjectCategory */ + ldb_module_set_private(module, ldb_get_opaque(ldb, DSDB_EXTENDED_DN_STORE_FORMAT_OPAQUE_NAME)); + + return ldb_next_init(module); +} + _PUBLIC_ const struct ldb_module_ops ldb_objectclass_module_ops = { .name = "objectclass", .add = objectclass_add, .modify = objectclass_modify, .rename = objectclass_rename, + .init_context = objectclass_init }; diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c index 9cfdb37ad44..e8d9cbacd48 100644 --- a/source4/dsdb/samdb/ldb_modules/samldb.c +++ b/source4/dsdb/samdb/ldb_modules/samldb.c @@ -33,6 +33,7 @@ #include "libcli/ldap/ldap_ndr.h" #include "ldb_module.h" #include "dsdb/samdb/samdb.h" +#include "dsdb/samdb/ldb_modules/util.h" #include "libcli/security/security.h" #include "librpc/gen_ndr/ndr_security.h" #include "../lib/util/util_ldb.h" @@ -1008,6 +1009,10 @@ static int samldb_find_for_defaultObjectCategory(struct samldb_ctx *ac) if (ret != LDB_SUCCESS) { return ret; } + ret = dsdb_module_search_handle_flags(ac->module, req, DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT); + if (ret != LDB_SUCCESS) { + return ret; + } return ldb_next_request(ac->module, req); } diff --git a/source4/dsdb/samdb/samdb.h b/source4/dsdb/samdb/samdb.h index 45ab716741b..33f4fd38310 100644 --- a/source4/dsdb/samdb/samdb.h +++ b/source4/dsdb/samdb/samdb.h @@ -135,4 +135,9 @@ struct dsdb_openldap_dereference_result_control { #define DSDB_PARTITION_DN "@PARTITION" #define DSDB_PARTITION_ATTR "partition" +#define DSDB_EXTENDED_DN_STORE_FORMAT_OPAQUE_NAME "dsdb_extended_dn_store_format" +struct dsdb_extended_dn_store_format { + bool store_extended_dn_in_ldb; +}; + #endif /* __SAMDB_H__ */