[SCM] Samba Shared Repository - branch master updated
Matthias Dieter Wallnöfer
mdw at samba.org
Tue Nov 16 08:13:01 MST 2010
The branch, master has been updated
via d451ac1 s4:acl LDB module - use also here "dsdb_find_nc_root" to implement the NC-specific checks
via 856e309 s4:descriptor LDB module - also "get_default_ag" should make use of "dsdb_find_nc_root"
via cebad70 s4:descriptor LDB module - handle the NCs in a more generic way by using "dsdb_find_nc_root"
via 7cc2f98 s4:"dsdb_find_nc_root" - let it work also when the "namingContexts" attribute isn't available yet
via d2453b5 s4:descriptor LDB module - make more clear that special control entries never should be handled by modules
via f863f434 s4:objectclass LDB module - the "olddn" is the special DN for rename requests
from cce6627 s4-schema_load: Don't clean in_transaction flag until transaction is really finished
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit d451ac1f3ac7b391e3cb28dca8e665bf1e1beddd
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date: Tue Nov 16 14:22:27 2010 +0100
s4:acl LDB module - use also here "dsdb_find_nc_root" to implement the NC-specific checks
Autobuild-User: Matthias Dieter Wallnöfer <mdw at samba.org>
Autobuild-Date: Tue Nov 16 15:12:13 UTC 2010 on sn-devel-104
commit 856e309b14491849ec65d37fc23e03dd07063e21
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date: Tue Nov 16 13:17:32 2010 +0100
s4:descriptor LDB module - also "get_default_ag" should make use of "dsdb_find_nc_root"
commit cebad70ee6d8fb3e2f3d306d98fb88a4c8526f28
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date: Tue Nov 16 13:12:02 2010 +0100
s4:descriptor LDB module - handle the NCs in a more generic way by using "dsdb_find_nc_root"
commit 7cc2f9803801dcae0a4780f46cd2b642fac1b1cf
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date: Tue Nov 16 15:20:04 2010 +0100
s4:"dsdb_find_nc_root" - let it work also when the "namingContexts" attribute isn't available yet
This is needed on provisioning when the modules aren't set up yet.
commit d2453b52d84c148176b7384d0973645423647d38
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date: Tue Nov 16 13:25:34 2010 +0100
s4:descriptor LDB module - make more clear that special control entries never should be handled by modules
commit f863f434a01d49a27b963ec71a86727f0d95dc59
Author: Matthias Dieter Wallnöfer <mdw at samba.org>
Date: Tue Nov 16 13:22:05 2010 +0100
s4:objectclass LDB module - the "olddn" is the special DN for rename requests
-----------------------------------------------------------------------
Summary of changes:
source4/dsdb/common/util.c | 42 ++++++++++---
source4/dsdb/samdb/ldb_modules/acl.c | 85 +++++++++++++++++---------
source4/dsdb/samdb/ldb_modules/descriptor.c | 63 ++++++++++++-------
source4/dsdb/samdb/ldb_modules/objectclass.c | 2 +-
4 files changed, 133 insertions(+), 59 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index 7f6ce64..fb891ab 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -3282,15 +3282,41 @@ int dsdb_find_nc_root(struct ldb_context *samdb, TALLOC_CTX *mem_ctx, struct ldb
DEBUG(1,("Searching for namingContexts in rootDSE failed: %s\n", ldb_errstring(samdb)));
talloc_free(tmp_ctx);
return ret;
- }
+ }
- el = ldb_msg_find_element(root_res->msgs[0], "namingContexts");
- if (!el) {
- DEBUG(1,("Finding namingContexts element in root_res failed: %s\n",
- ldb_errstring(samdb)));
- talloc_free(tmp_ctx);
- return LDB_ERR_NO_SUCH_ATTRIBUTE;
- }
+ el = ldb_msg_find_element(root_res->msgs[0], "namingContexts");
+ if (!el) {
+ struct ldb_message *tmp_msg;
+
+ DEBUG(5,("Finding namingContexts element in root_res failed. Using a temporary list."));
+
+ /* This generates a temporary list of NCs in order to let the
+ * provisioning work. */
+ tmp_msg = ldb_msg_new(tmp_ctx);
+ if (tmp_msg == NULL) {
+ talloc_free(tmp_ctx);
+ return ldb_oom(samdb);
+ }
+ ret = ldb_msg_add_steal_string(tmp_msg, "namingContexts",
+ ldb_dn_alloc_linearized(tmp_msg, ldb_get_schema_basedn(samdb)));
+ if (ret != LDB_SUCCESS) {
+ talloc_free(tmp_ctx);
+ return ret;
+ }
+ ret = ldb_msg_add_steal_string(tmp_msg, "namingContexts",
+ ldb_dn_alloc_linearized(tmp_msg, ldb_get_config_basedn(samdb)));
+ if (ret != LDB_SUCCESS) {
+ talloc_free(tmp_ctx);
+ return ret;
+ }
+ ret = ldb_msg_add_steal_string(tmp_msg, "namingContexts",
+ ldb_dn_alloc_linearized(tmp_msg, ldb_get_default_basedn(samdb)));
+ if (ret != LDB_SUCCESS) {
+ talloc_free(tmp_ctx);
+ return ret;
+ }
+ el = &tmp_msg->elements[0];
+ }
nc_dns = talloc_array(tmp_ctx, struct ldb_dn *, el->num_values);
if (!nc_dns) {
diff --git a/source4/dsdb/samdb/ldb_modules/acl.c b/source4/dsdb/samdb/ldb_modules/acl.c
index b6635b1..69ab72a 100644
--- a/source4/dsdb/samdb/ldb_modules/acl.c
+++ b/source4/dsdb/samdb/ldb_modules/acl.c
@@ -438,6 +438,7 @@ static int acl_add(struct ldb_module *module, struct ldb_request *req)
const struct dsdb_schema *schema;
struct ldb_message_element *oc_el;
const struct GUID *guid;
+ struct ldb_dn *nc_root;
struct ldb_control *as_system = ldb_request_get_control(req, LDB_CONTROL_AS_SYSTEM_OID);
if (as_system != NULL) {
@@ -447,19 +448,24 @@ static int acl_add(struct ldb_module *module, struct ldb_request *req)
if (dsdb_module_am_system(module) || as_system) {
return ldb_next_request(module, req);
}
-
if (ldb_dn_is_special(req->op.add.message->dn)) {
return ldb_next_request(module, req);
}
+
ldb = ldb_module_get_ctx(module);
+
/* Creating an NC. There is probably something we should do here,
* but we will establish that later */
- /* FIXME: this has to be made dynamic at some point */
- if ((ldb_dn_compare(req->op.add.message->dn, (ldb_get_schema_basedn(ldb))) == 0) ||
- (ldb_dn_compare(req->op.add.message->dn, (ldb_get_config_basedn(ldb))) == 0) ||
- (ldb_dn_compare(req->op.add.message->dn, (ldb_get_default_basedn(ldb))) == 0)) {
+
+ ret = dsdb_find_nc_root(ldb, req, req->op.add.message->dn, &nc_root);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ if (ldb_dn_compare(nc_root, req->op.add.message->dn) == 0) {
+ talloc_free(nc_root);
return ldb_next_request(module, req);
}
+ talloc_free(nc_root);
schema = dsdb_get_schema(ldb, req);
if (!schema) {
@@ -812,12 +818,13 @@ fail:
}
/* similar to the modify for the time being.
- * We need to concider the special delete tree case, though - TODO */
+ * We need to consider the special delete tree case, though - TODO */
static int acl_delete(struct ldb_module *module, struct ldb_request *req)
{
int ret;
struct ldb_dn *parent = ldb_dn_get_parent(req, req->op.del.dn);
struct ldb_context *ldb;
+ struct ldb_dn *nc_root;
struct ldb_control *as_system = ldb_request_get_control(req, LDB_CONTROL_AS_SYSTEM_OID);
if (as_system != NULL) {
@@ -828,31 +835,42 @@ static int acl_delete(struct ldb_module *module, struct ldb_request *req)
if (dsdb_module_am_system(module) || as_system) {
return ldb_next_request(module, req);
}
-
if (ldb_dn_is_special(req->op.del.dn)) {
return ldb_next_request(module, req);
}
+
ldb = ldb_module_get_ctx(module);
- /* first check if we have delete object right */
- ret = dsdb_module_check_access_on_dn(module, req, req->op.del.dn, SEC_STD_DELETE, NULL);
- if (ret == LDB_SUCCESS) {
- return ldb_next_request(module, req);
+
+ /* Make sure we aren't deleting a NC */
+
+ ret = dsdb_find_nc_root(ldb, req, req->op.del.dn, &nc_root);
+ if (ret != LDB_SUCCESS) {
+ return ret;
}
+ if (ldb_dn_compare(nc_root, req->op.del.dn) == 0) {
+ talloc_free(nc_root);
+ DEBUG(10,("acl:deleting a NC\n"));
+ /* Windows returns "ERR_UNWILLING_TO_PERFORM */
+ return ldb_module_done(req, NULL, NULL,
+ LDB_ERR_UNWILLING_TO_PERFORM);
+ }
+ talloc_free(nc_root);
- /* Nope, we don't have delete object. Lets check if we have delete child on the parent */
- /* No parent, so check fails */
- /* FIXME: this has to be made dynamic at some point */
- if ((ldb_dn_compare(req->op.del.dn, (ldb_get_schema_basedn(ldb))) == 0) ||
- (ldb_dn_compare(req->op.del.dn, (ldb_get_config_basedn(ldb))) == 0) ||
- (ldb_dn_compare(req->op.del.dn, (ldb_get_default_basedn(ldb))) == 0)) {
- DEBUG(10,("acl:deleting an NC\n"));
- return ldb_module_done(req, NULL, NULL, LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS);
+ /* First check if we have delete object right */
+ ret = dsdb_module_check_access_on_dn(module, req, req->op.del.dn,
+ SEC_STD_DELETE, NULL);
+ if (ret == LDB_SUCCESS) {
+ return ldb_next_request(module, req);
}
- ret = dsdb_module_check_access_on_dn(module, req, parent, SEC_ADS_DELETE_CHILD, NULL);
+ /* Nope, we don't have delete object. Lets check if we have delete
+ * child on the parent */
+ ret = dsdb_module_check_access_on_dn(module, req, parent,
+ SEC_ADS_DELETE_CHILD, NULL);
if (ret != LDB_SUCCESS) {
return ret;
}
+
return ldb_next_request(module, req);
}
@@ -867,6 +885,7 @@ static int acl_rename(struct ldb_module *module, struct ldb_request *req)
struct dom_sid *sid = NULL;
struct ldb_result *acl_res;
const struct GUID *guid;
+ struct ldb_dn *nc_root;
struct object_tree *root = NULL;
struct object_tree *new_node = NULL;
struct ldb_control *as_system = ldb_request_get_control(req, LDB_CONTROL_AS_SYSTEM_OID);
@@ -892,8 +911,26 @@ static int acl_rename(struct ldb_module *module, struct ldb_request *req)
if (ldb_dn_is_special(req->op.rename.olddn)) {
return ldb_next_request(module, req);
}
+
ldb = ldb_module_get_ctx(module);
+ /* Make sure we aren't renaming/moving a NC */
+
+ ret = dsdb_find_nc_root(ldb, req, req->op.rename.olddn, &nc_root);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ if (ldb_dn_compare(nc_root, req->op.rename.olddn) == 0) {
+ talloc_free(nc_root);
+ DEBUG(10,("acl:renaming/moving a NC\n"));
+ /* Windows returns "ERR_UNWILLING_TO_PERFORM */
+ return ldb_module_done(req, NULL, NULL,
+ LDB_ERR_UNWILLING_TO_PERFORM);
+ }
+ talloc_free(nc_root);
+
+ /* Look for the parent */
+
ret = dsdb_module_search_dn(module, req, &acl_res, req->op.rename.olddn,
acl_attrs,
DSDB_FLAG_NEXT_MODULE |
@@ -967,14 +1004,6 @@ static int acl_rename(struct ldb_module *module, struct ldb_request *req)
return ldb_next_request(module, req);
}
- /* What exactly to do in this case? It would fail anyway.. */
- /* FIXME: this has to be made dynamic at some point */
- if ((ldb_dn_compare(req->op.rename.newdn, (ldb_get_schema_basedn(ldb))) == 0) ||
- (ldb_dn_compare(req->op.rename.newdn, (ldb_get_config_basedn(ldb))) == 0) ||
- (ldb_dn_compare(req->op.rename.newdn, (ldb_get_default_basedn(ldb))) == 0)) {
- DEBUG(10,("acl:moving as an NC\n"));
- return LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS;
- }
/* new parent should have create child */
talloc_free(tmp_ctx);
tmp_ctx = talloc_new(req);
diff --git a/source4/dsdb/samdb/ldb_modules/descriptor.c b/source4/dsdb/samdb/ldb_modules/descriptor.c
index 0515dfe..baf00ad 100644
--- a/source4/dsdb/samdb/ldb_modules/descriptor.c
+++ b/source4/dsdb/samdb/ldb_modules/descriptor.c
@@ -66,19 +66,21 @@ struct dom_sid *get_default_ag(TALLOC_CTX *mem_ctx,
struct ldb_context *ldb)
{
TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
- struct ldb_dn *default_base_dn = ldb_get_default_basedn(ldb);
- struct ldb_dn *schema_base_dn = ldb_get_schema_basedn(ldb);
- struct ldb_dn *config_base_dn = ldb_get_config_basedn(ldb);
const struct dom_sid *domain_sid = samdb_domain_sid(ldb);
struct dom_sid *da_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ADMINS);
struct dom_sid *ea_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ENTERPRISE_ADMINS);
struct dom_sid *sa_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_SCHEMA_ADMINS);
struct dom_sid *dag_sid;
+ struct ldb_dn *nc_root;
+ int ret;
- /* FIXME: this has to be fixed regarding the forest DN (root DN) and
- * the domain DN (default DN) - they aren't always the same. */
+ ret = dsdb_find_nc_root(ldb, tmp_ctx, dn, &nc_root);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(tmp_ctx);
+ return NULL;
+ }
- if (ldb_dn_compare_base(schema_base_dn, dn) == 0){
+ if (ldb_dn_compare(nc_root, ldb_get_schema_basedn(ldb)) == 0) {
if (security_token_has_sid(token, sa_sid))
dag_sid = dom_sid_dup(mem_ctx, sa_sid);
else if (security_token_has_sid(token, ea_sid))
@@ -87,25 +89,23 @@ struct dom_sid *get_default_ag(TALLOC_CTX *mem_ctx,
dag_sid = dom_sid_dup(mem_ctx, da_sid);
else
dag_sid = NULL;
- }
- else if (ldb_dn_compare_base(config_base_dn, dn) == 0){
+ } else if (ldb_dn_compare(nc_root, ldb_get_config_basedn(ldb)) == 0) {
if (security_token_has_sid(token, ea_sid))
dag_sid = dom_sid_dup(mem_ctx, ea_sid);
else if (security_token_has_sid(token, da_sid))
dag_sid = dom_sid_dup(mem_ctx, da_sid);
else
dag_sid = NULL;
- }
- else if (ldb_dn_compare_base(default_base_dn, dn) == 0){
+ } else if (ldb_dn_compare(nc_root, ldb_get_default_basedn(ldb)) == 0) {
if (security_token_has_sid(token, da_sid))
dag_sid = dom_sid_dup(mem_ctx, da_sid);
else if (security_token_has_sid(token, ea_sid))
dag_sid = dom_sid_dup(mem_ctx, ea_sid);
else
dag_sid = NULL;
- }
- else
+ } else {
dag_sid = NULL;
+ }
talloc_free(tmp_ctx);
return dag_sid;
@@ -692,16 +692,28 @@ static int descriptor_do_add(struct descriptor_context *ac)
sizeof(struct ldb_val));
}
- /* NC's have no parent */
- /* FIXME: this has to be made dynamic at some point */
- if ((ldb_dn_compare(ac->msg->dn, (ldb_get_schema_basedn(ldb))) == 0) ||
- (ldb_dn_compare(ac->msg->dn, (ldb_get_config_basedn(ldb))) == 0) ||
- (ldb_dn_compare(ac->msg->dn, (ldb_get_default_basedn(ldb))) == 0)) {
- ac->parentsd_val = NULL;
- } else if (ac->search_res != NULL) {
- struct ldb_message_element *parent_element = ldb_msg_find_element(ac->search_res->message, "nTSecurityDescriptor");
- if (parent_element) {
- ac->parentsd_val = talloc_memdup(ac, &parent_element->values[0], sizeof(struct ldb_val));
+ /* If we do have a parent, then please fetch it's security descriptor.
+ * But have in mind: NCs don't have any parents! That means
+ * "CN=Configuration,DC=example,DC=com" has no parent
+ * "DC=example,DC=com" since this is located under another NC! */
+ if (ac->search_res != NULL) {
+ struct ldb_message_element *parent_element = NULL;
+ struct ldb_dn *nc_root;
+
+ ret = dsdb_find_nc_root(ldb, ac, ac->msg->dn, &nc_root);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+
+ if (ldb_dn_compare(ac->msg->dn, nc_root) != 0) {
+ /* we aren't any NC */
+ parent_element = ldb_msg_find_element(ac->search_res->message,
+ "nTSecurityDescriptor");
+ if (parent_element != NULL) {
+ ac->parentsd_val = talloc_memdup(ac,
+ &parent_element->values[0],
+ sizeof(struct ldb_val));
+ }
}
}
@@ -785,6 +797,7 @@ static int descriptor_change(struct ldb_module *module, struct ldb_request *req)
}
ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_change: %s\n", ldb_dn_get_linearized(dn));
+ /* do not manipulate our control entries */
if (ldb_dn_is_special(dn)) {
return ldb_next_request(module, req);
}
@@ -865,6 +878,12 @@ static int descriptor_rename(struct ldb_module *module, struct ldb_request *req)
{
struct ldb_context *ldb = ldb_module_get_ctx(module);
ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_rename: %s\n", ldb_dn_get_linearized(req->op.rename.olddn));
+
+ /* do not manipulate our control entries */
+ if (ldb_dn_is_special(req->op.rename.olddn)) {
+ return ldb_next_request(module, req);
+ }
+
return ldb_next_request(module, req);
}
diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c
index 5a7c67e..7dc3ae2 100644
--- a/source4/dsdb/samdb/ldb_modules/objectclass.c
+++ b/source4/dsdb/samdb/ldb_modules/objectclass.c
@@ -1209,7 +1209,7 @@ static int objectclass_rename(struct ldb_module *module, struct ldb_request *req
ldb_debug(ldb, LDB_DEBUG_TRACE, "objectclass_rename\n");
/* do not manipulate our control entries */
- if (ldb_dn_is_special(req->op.rename.newdn)) {
+ if (ldb_dn_is_special(req->op.rename.olddn)) {
return ldb_next_request(module, req);
}
--
Samba Shared Repository
More information about the samba-cvs
mailing list