- struct ldb_context *ldb = ldb_module_get_ctx(module);
- struct ldb_request *mod_req, *last_req;
- struct ldb_message *mod_msg;
- struct partition_private_data *data;
- struct dsdb_partition *partition;
- const char *casefold_dn;
-
- /* Check if this is already a partition */
-
- struct dsdb_create_partition_exop *ex_op = talloc_get_type(req->op.extended.data, struct dsdb_create_partition_exop);
- struct ldb_dn *dn = ex_op->new_dn;
-
- data = talloc_get_type(module->private_data, struct partition_private_data);
- if (!data) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- if (!data) {
- /* We are not going to create a partition before we are even set up */
- return LDB_ERR_UNWILLING_TO_PERFORM;
- }
-
- for (i=0; data->partitions && data->partitions[i]; i++) {
- if (ldb_dn_compare(data->partitions[i]->ctrl->dn, dn) == 0) {
- return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
- }
- }
-
- mod_msg = ldb_msg_new(req);
- if (!mod_msg) {
- ldb_oom(ldb);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- mod_msg->dn = ldb_dn_new(mod_msg, ldb, DSDB_PARTITION_DN);
- ret = ldb_msg_add_empty(mod_msg, DSDB_PARTITION_ATTR, LDB_FLAG_MOD_ADD, NULL);
- if (ret != LDB_SUCCESS) {
- return ret;
- }
-
- casefold_dn = ldb_dn_get_casefold(dn);
-
- ret = ldb_msg_add_string(mod_msg, DSDB_PARTITION_ATTR, casefold_dn);
- if (ret != LDB_SUCCESS) {
- return ret;
- }
-
- /* Perform modify on @PARTITION record */
- ret = ldb_build_mod_req(&mod_req, ldb, req, mod_msg, NULL, NULL,
- ldb_op_default_callback, req);
-
- if (ret != LDB_SUCCESS) {
- return ret;
- }
-
- ret = ldb_next_request(module, mod_req);
- if (ret == LDB_SUCCESS) {
- ret = ldb_wait(mod_req->handle, LDB_WAIT_ALL);
- }
-
- if (ret != LDB_SUCCESS) {
- return ret;
- }
-
- ret = partition_reload_metadata(module, data, req, NULL);
- if (ret != LDB_SUCCESS) {
- return ret;
- }
-
- /* Make a partition structure for this new partition, so we can copy in the template structure */
- ret = new_partition_from_dn(ldb, data, req, ldb_dn_copy(req, dn), casefold_dn, &partition);
- if (ret != LDB_SUCCESS) {
- return ret;
- }
-
- /* Start a transaction on the DB (as it won't be in one being brand new) */
- {
- struct ldb_module *next = partition->module;
- PARTITION_FIND_OP(next, start_transaction);
-
- ret = next->ops->start_transaction(next);
- if (ret != LDB_SUCCESS) {
- return ret;
- }
- }
-
- /* otherwise, for each replicate, copy from main partition. If we get an error, we report it up the chain */
- last_req = mod_req;