+/*
+ 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);
+}
+