* helper functions to call the next module in chain
* */
-static int partition_request(struct ldb_module *module, struct ldb_request *request)
+int partition_request(struct ldb_module *module, struct ldb_request *request)
{
int ret;
switch (request->operation) {
struct partition_context *ac;
struct ldb_module *module;
struct ldb_request *nreq;
- int ret, i;
+ int ret;
struct partition_private_data *data;
+ struct ldb_control *partition_ctrl;
ac = talloc_get_type(req->context, struct partition_context);
data = talloc_get_type(ac->module->private_data, struct partition_private_data);
LDB_ERR_OPERATIONS_ERROR);
}
+ partition_ctrl = ldb_request_get_control(req, DSDB_CONTROL_CURRENT_PARTITION_OID);
+ if (partition_ctrl && (ac->num_requests == 1 || ares->type == LDB_REPLY_ENTRY)) {
+ /* If we didn't fan this request out to mulitple partitions,
+ * or this is an individual search result, we can
+ * deterministily tell the caller what partition this was
+ * written to (repl_meta_data likes to know) */
+ ret = ldb_reply_add_control(ares,
+ DSDB_CONTROL_CURRENT_PARTITION_OID,
+ false, partition_ctrl->data);
+ if (ret != LDB_SUCCESS) {
+ return ldb_module_done(ac->req, NULL, NULL,
+ ret);
+ }
+ }
+
if (ares->error != LDB_SUCCESS && !ac->got_success) {
return ldb_module_done(ac->req, ares->controls,
ares->response, ares->error);
return ldb_module_done(ac->req, NULL, NULL,
LDB_ERR_OPERATIONS_ERROR);
}
- for (i=0; data && data->partitions && data->partitions[i]; i++) {
- if (ldb_dn_compare(ares->message->dn, data->partitions[i]->ctrl->dn) == 0) {
- struct ldb_control *part_control;
- /* this is a partition root message - make
- sure it isn't one of our fake root
- entries from a parent partition */
- part_control = ldb_request_get_control(req, DSDB_CONTROL_CURRENT_PARTITION_OID);
- if (part_control && part_control->data != data->partitions[i]->ctrl) {
- DEBUG(6,(__location__ ": Discarding partition mount object %s\n",
- ldb_dn_get_linearized(ares->message->dn)));
- talloc_free(ares);
- return LDB_SUCCESS;
- }
- }
- }
return ldb_module_send_entry(ac->req, ares->message, ares->controls);
return ldb_next_request(module, req);
}
- ret = partition_reload_if_required(module, data);
- if (ret != LDB_SUCCESS) {
- return ret;
- }
-
if (req->operation != LDB_SEARCH) {
/* Is this a special DN, we need to replicate to every backend? */
for (i=0; data->replicate && data->replicate[i]; i++) {
/* rename */
static int partition_rename(struct ldb_module *module, struct ldb_request *req)
{
- int ret;
/* Find backend */
struct dsdb_partition *backend, *backend2;
return LDB_ERR_OPERATIONS_ERROR;
}
- ret = partition_reload_if_required(module, data);
- if (ret != LDB_SUCCESS) {
- return ret;
- }
-
backend = find_partition(data, req->op.rename.olddn, req);
backend2 = find_partition(data, req->op.rename.newdn, req);
return ret;
}
+ ret = partition_reload_if_required(module, data);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+
for (i=0; data && data->partitions && data->partitions[i]; i++) {
struct ldb_module *next = data->partitions[i]->module;
PARTITION_FIND_OP(next, start_transaction);
return ret;
}
}
+
+ data->in_transaction++;
+
return LDB_SUCCESS;
}
}
}
+ if (data->in_transaction == 0) {
+ DEBUG(0,("partition end transaction mismatch\n"));
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ data->in_transaction--;
+
return ldb_next_end_trans(module);
}
}
}
+ if (data->in_transaction == 0) {
+ DEBUG(0,("partition del transaction mismatch\n"));
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ data->in_transaction--;
+
ret = ldb_next_del_trans(module);
if (ret != LDB_SUCCESS) {
final_ret = ret;
return ret;
}
- return ldb_request_done(req, ret);
+ return ldb_module_done(req, NULL, NULL, ret);
}