Imported Upstream version 4.0.0+dfsg1
[abartlet/samba-debian.git] / source4 / dsdb / samdb / ldb_modules / partition_init.c
index 50aabc92fe670449a077b117caa7578b937ffacf..98896a7a84080ac21820bdb71ae0991395223371 100644 (file)
@@ -138,7 +138,8 @@ static int partition_reload_metadata(struct ldb_module *module, struct partition
        struct ldb_message *msg, *module_msg;
        struct ldb_result *res;
        struct ldb_context *ldb = ldb_module_get_ctx(module);
-       const char *attrs[] = { "partition", "replicateEntries", "modules", "ldapBackend", NULL };
+       const char *attrs[] = { "partition", "replicateEntries", "modules", "ldapBackend",
+                               "partialReplica", NULL };
        /* perform search for @PARTITION, looking for module, replicateEntries and ldapBackend */
        ret = dsdb_module_search_dn(module, mem_ctx, &res, 
                                    ldb_dn_new(mem_ctx, ldb, DSDB_PARTITION_DN),
@@ -208,7 +209,7 @@ static int new_partition_from_dn(struct ldb_context *ldb, struct partition_priva
        const char **modules;
        int ret;
 
-       (*partition) = talloc(mem_ctx, struct dsdb_partition);
+       (*partition) = talloc_zero(mem_ctx, struct dsdb_partition);
        if (!*partition) {
                return ldb_oom(ldb);
        }
@@ -383,6 +384,7 @@ int partition_reload_if_required(struct ldb_module *module,
        struct ldb_context *ldb = ldb_module_get_ctx(module);
        struct ldb_message *msg;
        struct ldb_message_element *partition_attributes;
+       struct ldb_message_element *partial_replicas;
        TALLOC_CTX *mem_ctx;
 
        if (!data) {
@@ -395,7 +397,7 @@ int partition_reload_if_required(struct ldb_module *module,
                return ldb_oom(ldb);
        }
 
-       ret = partition_primary_sequence_number(module, mem_ctx, LDB_SEQ_HIGHEST_SEQ, &seq);
+       ret = partition_primary_sequence_number(module, mem_ctx, &seq, parent);
        if (ret != LDB_SUCCESS) {
                talloc_free(mem_ctx);
                return ret;
@@ -414,6 +416,7 @@ int partition_reload_if_required(struct ldb_module *module,
        data->metadata_seq = seq;
 
        partition_attributes = ldb_msg_find_element(msg, "partition");
+       partial_replicas     = ldb_msg_find_element(msg, "partialReplica");
 
        for (i=0; partition_attributes && i < partition_attributes->num_values; i++) {
                unsigned int j;
@@ -523,6 +526,15 @@ int partition_reload_if_required(struct ldb_module *module,
                        return ret;
                }
 
+               /* see if it is a partial replica */
+               for (j=0; partial_replicas && j<partial_replicas->num_values; j++) {
+                       struct ldb_dn *pa_dn = ldb_dn_from_ldb_val(mem_ctx, ldb, &partial_replicas->values[j]);
+                       if (pa_dn != NULL && ldb_dn_compare(pa_dn, partition->ctrl->dn) == 0) {
+                               partition->partial_replica = true;
+                       }
+                       talloc_free(pa_dn);
+               }
+
                ret = add_partition_to_data(ldb, data, partition);
                if (ret != LDB_SUCCESS) {
                        talloc_free(mem_ctx);
@@ -695,6 +707,12 @@ int partition_create(struct ldb_module *module, struct ldb_request *req)
                return LDB_ERR_UNWILLING_TO_PERFORM;
        }
 
+       /* see if we are still up-to-date */
+       ret = partition_reload_if_required(module, data, req);
+       if (ret != LDB_SUCCESS) {
+               return ret;
+       }
+
        for (i=0; data->partitions && data->partitions[i]; i++) {
                if (ldb_dn_compare(data->partitions[i]->ctrl->dn, dn) == 0) {
                        partition = data->partitions[i];
@@ -758,6 +776,18 @@ int partition_create(struct ldb_module *module, struct ldb_request *req)
                if (ret != LDB_SUCCESS) {
                        return ret;
                }
+
+               if (ldb_request_get_control(req, DSDB_CONTROL_PARTIAL_REPLICA)) {
+                       /* this new partition is a partial replica */
+                       ret = ldb_msg_add_empty(mod_msg, "partialReplica", LDB_FLAG_MOD_ADD, NULL);
+                       if (ret != LDB_SUCCESS) {
+                               return ret;
+                       }
+                       ret = ldb_msg_add_fmt(mod_msg, "partialReplica", "%s", ldb_dn_get_linearized(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, 
@@ -851,5 +881,11 @@ int partition_init(struct ldb_module *module)
                return ldb_operr(ldb);
        }
 
+       /* This loads metadata tdb. If it's missing, creates it */
+       ret = partition_metadata_init(module);
+       if (ret != LDB_SUCCESS) {
+               return ret;
+       }
+
        return ldb_next_init(module);
 }