diff options
author | Nadezhda Ivanova <nivanova@samba.org> | 2011-02-21 17:04:27 +0200 |
---|---|---|
committer | Nadezhda Ivanova <nivanova@samba.org> | 2011-02-21 17:04:27 +0200 |
commit | 85877c0bd1279a6c19bb8354f56e9cdbe1901630 (patch) | |
tree | cbd1a5c3a10a56f1823b184acac40846259d6e9f /source4 | |
parent | fb45c8890458dd15db1add360f5761d3ef4d60ee (diff) | |
download | samba-85877c0bd1279a6c19bb8354f56e9cdbe1901630.tar.gz samba-85877c0bd1279a6c19bb8354f56e9cdbe1901630.tar.xz samba-85877c0bd1279a6c19bb8354f56e9cdbe1901630.zip |
s4-descriptor: Replaced the synchronous descriptor_change with the synchronous descriptor_add.
The purpose is to make descriptor module synchronous. This will simplify reading and debugging, and also will make the
implementation of SD hierarchy recalculation on modify much easier.
Diffstat (limited to 'source4')
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/descriptor.c | 109 |
1 files changed, 108 insertions, 1 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/descriptor.c b/source4/dsdb/samdb/ldb_modules/descriptor.c index dfbfdf6dec2..51371798db1 100644 --- a/source4/dsdb/samdb/ldb_modules/descriptor.c +++ b/source4/dsdb/samdb/ldb_modules/descriptor.c @@ -763,6 +763,113 @@ static int descriptor_do_add(struct descriptor_context *ac) } } +static int descriptor_add(struct ldb_module *module, struct ldb_request *req) +{ + struct ldb_context *ldb; + struct ldb_request *add_req; + struct ldb_message *msg; + struct ldb_result *parent_res; + const struct ldb_val *parent_sd = NULL; + const struct ldb_val *user_sd; + struct ldb_dn *parent_dn, *dn, *nc_root; + struct ldb_message_element *objectclass_element, *sd_element; + int ret; + const struct dsdb_schema *schema; + DATA_BLOB *sd; + const struct dsdb_class *objectclass; + static const char * const parent_attrs[] = { "nTSecurityDescriptor", NULL }; + + ldb = ldb_module_get_ctx(module); + dn = req->op.add.message->dn; + user_sd = ldb_msg_find_ldb_val(req->op.add.message, "nTSecurityDescriptor"); + sd_element = ldb_msg_find_element(req->op.add.message, "nTSecurityDescriptor"); + /* nTSecurityDescriptor without a value is an error, letting through so it is handled */ + if (user_sd == NULL && sd_element) { + return ldb_next_request(module, req); + } + + ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_add: %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); + } + + /* if the object has a parent, retrieve its SD to + * use for calculation. unfortunately we do not yet have + * instanceType*/ + parent_dn = ldb_dn_get_parent(req, dn); + if (parent_dn == NULL) { + return ldb_oom(ldb); + } + + ret = dsdb_find_nc_root(ldb, req, dn, &nc_root); + if (ret != LDB_SUCCESS) { + ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_add: Could not find NC root for %s\n", + ldb_dn_get_linearized(dn)); + return ret; + } + + if (ldb_dn_compare(dn, nc_root) != 0) { + /* we aren't any NC */ + ret = dsdb_module_search_dn(module, req, &parent_res, parent_dn, + parent_attrs, + DSDB_FLAG_NEXT_MODULE, + req); + if (ret != LDB_SUCCESS) { + ldb_debug(ldb, LDB_DEBUG_TRACE,"descriptor_add: Could not find SD for %s\n", + ldb_dn_get_linearized(parent_dn)); + return ret; + } + if (parent_res->count != 1) { + return ldb_operr(ldb); + } + parent_sd = ldb_msg_find_ldb_val(parent_res->msgs[0], "nTSecurityDescriptor"); + } + + schema = dsdb_get_schema(ldb, req); + + objectclass_element = ldb_msg_find_element(req->op.add.message, "objectClass"); + if (objectclass_element == NULL) { + return ldb_operr(ldb); + } + + objectclass = get_last_structural_class(schema, objectclass_element, req); + if (objectclass == NULL) { + return ldb_operr(ldb); + } + + sd = get_new_descriptor(module, dn, req, + objectclass, parent_sd, + user_sd, NULL, 0); + msg = ldb_msg_copy_shallow(req, req->op.add.message); + if (sd != NULL) { + if (sd_element != NULL) { + sd_element->values[0] = *sd; + } else { + ret = ldb_msg_add_steal_value(msg, + "nTSecurityDescriptor", + sd); + if (ret != LDB_SUCCESS) { + return ret; + } + } + } + + ret = ldb_build_add_req(&add_req, ldb, req, + msg, + req->controls, + req, dsdb_next_callback, + req); + LDB_REQ_SET_LOCATION(add_req); + if (ret != LDB_SUCCESS) { + return ldb_error(ldb, ret, + "descriptor_add: Error creating new add request."); + } + + return ldb_next_request(module, add_req); +} + static int descriptor_change(struct ldb_module *module, struct ldb_request *req) { struct ldb_context *ldb; @@ -903,7 +1010,7 @@ static int descriptor_init(struct ldb_module *module) static const struct ldb_module_ops ldb_descriptor_module_ops = { .name = "descriptor", .search = descriptor_search, - .add = descriptor_change, + .add = descriptor_add, .modify = descriptor_change, .rename = descriptor_rename, .init_context = descriptor_init |