return ldb_next_request(module, add_req);
}
+struct descriptor_modify_state {
+ struct ldb_module *module;
+ struct ldb_request *req;
+};
+
+static int descriptor_modify_callback(struct ldb_request *mod_req,
+ struct ldb_reply *ares);
+
static int descriptor_modify(struct ldb_module *module, struct ldb_request *req)
{
- struct ldb_context *ldb;
+ struct descriptor_modify_state *state = NULL;
+ struct ldb_context *ldb = ldb_module_get_ctx(module);
struct ldb_control *sd_recalculate_control, *sd_flags_control, *show_deleted_control;
struct ldb_request *mod_req;
struct ldb_message *msg;
static const char * const current_attrs[] = { "nTSecurityDescriptor",
"instanceType",
"objectClass", NULL };
- ldb = ldb_module_get_ctx(module);
+
+ state = talloc_zero(req, struct descriptor_modify_state);
+ if (state == NULL) {
+ return ldb_oom(ldb);
+ }
+ state->module = module;
+ state->req = req;
+
dn = req->op.mod.message->dn;
user_sd = ldb_msg_find_ldb_val(req->op.mod.message, "nTSecurityDescriptor");
/* This control forces the recalculation of the SD also when
if (show_deleted_control) {
flags |= DSDB_SEARCH_SHOW_DELETED;
}
- ret = dsdb_module_search_dn(module, req, ¤t_res, dn,
+ ret = dsdb_module_search_dn(module, state, ¤t_res, dn,
current_attrs,
flags,
req);
if (parent_dn == NULL) {
return ldb_oom(ldb);
}
- ret = dsdb_module_search_dn(module, req, &parent_res, parent_dn,
+ ret = dsdb_module_search_dn(module, state, &parent_res,
+ parent_dn,
parent_attrs,
DSDB_FLAG_NEXT_MODULE,
req);
old_sd = ldb_msg_find_ldb_val(current_res->msgs[0], "nTSecurityDescriptor");
}
- sd = get_new_descriptor(module, dn, req,
+ sd = get_new_descriptor(module, dn, state,
objectclass, parent_sd,
user_sd, old_sd, sd_flags);
- msg = ldb_msg_copy_shallow(req, req->op.mod.message);
+ msg = ldb_msg_copy_shallow(state, req->op.mod.message);
if (sd != NULL) {
struct ldb_message_element *sd_element;
if (user_sd != NULL) {
sd_recalculate_control->critical = 0;
}
- ret = ldb_build_mod_req(&mod_req, ldb, req,
+ ret = ldb_build_mod_req(&mod_req, ldb, state,
msg,
req->controls,
- req,
- dsdb_next_callback,
+ state,
+ descriptor_modify_callback,
req);
LDB_REQ_SET_LOCATION(mod_req);
if (ret != LDB_SUCCESS) {
return ldb_next_request(module, mod_req);
}
+/*
+ used to chain to the callers callback
+ */
+static int descriptor_modify_callback(struct ldb_request *mod_req,
+ struct ldb_reply *ares)
+{
+ struct descriptor_modify_state *state =
+ talloc_get_type_abort(mod_req->context,
+ struct descriptor_modify_state);
+ struct ldb_module *module = state->module;
+ struct ldb_context *ldb = ldb_module_get_ctx(module);
+ struct ldb_request *req = state->req;
+ struct ldb_result *res = NULL;
+ const char * const no_attrs[] = { NULL };
+ unsigned int i;
+ int ret;
+
+ if (!ares) {
+ return ldb_module_done(req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+
+ if (ares->type == LDB_REPLY_REFERRAL) {
+ return ldb_module_send_referral(req, ares->referral);
+ }
+
+ if (ares->error != LDB_SUCCESS) {
+ return ldb_module_done(req, ares->controls,
+ ares->response, ares->error);
+ }
+
+ if (ares->type != LDB_REPLY_DONE) {
+ talloc_free(ares);
+ return ldb_module_done(req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+
+ ret = dsdb_module_search(module, ares, &res,
+ req->op.mod.message->dn,
+ LDB_SCOPE_ONELEVEL, no_attrs,
+ DSDB_FLAG_NEXT_MODULE |
+ DSDB_FLAG_AS_SYSTEM |
+ DSDB_SEARCH_SHOW_RECYCLED |
+ DSDB_SEARCH_SHOW_DELETED,
+ req, "(objectClass=*)");
+ if (ret != LDB_SUCCESS) {
+ talloc_free(ares);
+ return ldb_module_done(req, NULL, NULL, ret);
+ }
+
+ for (i=0; i < res->count; i++) {
+ struct ldb_request *sub_req;
+ struct ldb_result *mod_res;
+
+ mod_res = talloc_zero(res, struct ldb_result);
+ if (!mod_res) {
+ return ldb_module_done(req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+
+ ret = ldb_build_mod_req(&sub_req, ldb, req,
+ res->msgs[i],
+ NULL,
+ mod_res,
+ ldb_modify_default_callback,
+ req);
+ LDB_REQ_SET_LOCATION(sub_req);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(ares);
+ return ldb_module_done(req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+
+ ret = ldb_request_add_control(sub_req,
+ LDB_CONTROL_RECALCULATE_SD_OID,
+ true, NULL);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(ares);
+ return ldb_module_done(req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+ ret = ldb_request_add_control(sub_req,
+ LDB_CONTROL_AS_SYSTEM_OID,
+ false, NULL);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(ares);
+ return ldb_module_done(req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+
+ ret = ldb_request_add_control(sub_req,
+ LDB_CONTROL_SHOW_DELETED_OID,
+ false, NULL);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(ares);
+ return ldb_module_done(req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+ ret = ldb_request_add_control(sub_req,
+ LDB_CONTROL_SHOW_RECYCLED_OID,
+ false, NULL);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(ares);
+ return ldb_module_done(req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+
+ ret = descriptor_modify(module, sub_req);
+ if (ret == LDB_SUCCESS) {
+ ret = ldb_wait(sub_req->handle, LDB_WAIT_ALL);
+ }
+ if (ret != LDB_SUCCESS) {
+ talloc_free(ares);
+ return ldb_module_done(req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+
+ talloc_free(mod_res);
+ }
+
+ return ldb_module_done(req, ares->controls,
+ ares->response, ares->error);
+}
+
static int descriptor_search(struct ldb_module *module, struct ldb_request *req)
{
int ret;
return ldb_next_request(ac->module, down_req);
}
-/* TODO */
+
+struct descriptor_rename_state {
+ struct ldb_module *module;
+ struct ldb_request *req;
+};
+
+static int descriptor_rename_callback(struct ldb_request *req,
+ struct ldb_reply *reply);
+
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));
+ struct descriptor_rename_state *state;
+ int ret;
+ struct ldb_request *rename_req = NULL;
+
+ 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);
+ state = talloc_zero(req, struct descriptor_rename_state);
+ if (state == NULL) {
+ return ldb_oom(ldb);
+ }
+ state->module = module;
+ state->req = req;
+
+ ret = ldb_build_rename_req(&rename_req, ldb, state,
+ req->op.rename.olddn,
+ req->op.rename.newdn,
+ req->controls,
+ state,
+ descriptor_rename_callback,
+ req);
+ LDB_REQ_SET_LOCATION(rename_req);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+
+ return ldb_next_request(module, rename_req);
+}
+
+static int descriptor_rename_callback(struct ldb_request *rename_req,
+ struct ldb_reply *ares)
+{
+ struct descriptor_rename_state *state =
+ talloc_get_type_abort(rename_req->context,
+ struct descriptor_rename_state);
+ struct ldb_module *module = state->module;
+ struct ldb_context *ldb = ldb_module_get_ctx(module);
+ struct ldb_request *req = state->req;
+ struct ldb_message *msg;
+ struct ldb_request *mod_req;
+ int ret;
+ struct ldb_result *mod_res;
+
+ if (!ares) {
+ return ldb_module_done(req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+
+ if (ares->type == LDB_REPLY_REFERRAL) {
+ return ldb_module_send_referral(req, ares->referral);
+ }
+
+ if (ares->error != LDB_SUCCESS) {
+ return ldb_module_done(req, ares->controls,
+ ares->response, ares->error);
+ }
+
+ if (ares->type != LDB_REPLY_DONE) {
+ talloc_free(ares);
+ return ldb_module_done(req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+
+ msg = ldb_msg_new(ares);
+ if (msg == NULL) {
+ talloc_free(ares);
+ return ldb_module_done(req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+ msg->dn = req->op.rename.newdn;
+
+ mod_res = talloc_zero(msg, struct ldb_result);
+ if (mod_res == NULL) {
+ talloc_free(ares);
+ return ldb_module_done(req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+
+ ret = ldb_build_mod_req(&mod_req, ldb, msg,
+ msg,
+ NULL,
+ mod_res,
+ ldb_modify_default_callback,
+ req);
+ LDB_REQ_SET_LOCATION(mod_req);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(ares);
+ return ldb_module_done(req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+
+ ret = ldb_request_add_control(mod_req,
+ LDB_CONTROL_RECALCULATE_SD_OID,
+ true, NULL);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(ares);
+ return ldb_module_done(req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+ ret = ldb_request_add_control(mod_req,
+ LDB_CONTROL_AS_SYSTEM_OID,
+ false, NULL);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(ares);
+ return ldb_module_done(req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+
+ ret = ldb_request_add_control(mod_req,
+ LDB_CONTROL_SHOW_DELETED_OID,
+ false, NULL);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(ares);
+ return ldb_module_done(req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+ ret = ldb_request_add_control(mod_req,
+ LDB_CONTROL_SHOW_RECYCLED_OID,
+ false, NULL);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(ares);
+ return ldb_module_done(req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+
+ ret = descriptor_modify(module, mod_req);
+ if (ret == LDB_SUCCESS) {
+ ret = ldb_wait(mod_req->handle, LDB_WAIT_ALL);
+ }
+ if (ret != LDB_SUCCESS) {
+ talloc_free(ares);
+ return ldb_module_done(req, NULL, NULL,
+ LDB_ERR_OPERATIONS_ERROR);
+ }
+
+ talloc_free(msg);
+
+ return ldb_module_done(req, ares->controls,
+ ares->response, ares->error);
}
static int descriptor_init(struct ldb_module *module)