s4-dsdb: load the partialReplica attribute in the @PARTITION object
authorAndrew Tridgell <tridge@samba.org>
Wed, 21 Sep 2011 23:52:29 +0000 (09:52 +1000)
committerAndrew Tridgell <tridge@samba.org>
Thu, 22 Sep 2011 00:00:49 +0000 (10:00 +1000)
this modifies the partition module to honor a partialReplica attribute
on the @PARTITION module, marking partiations as partial replicas so
the NO_GLOBAL_CATALOG control can be honoured

source4/dsdb/samdb/ldb_modules/partition.c
source4/dsdb/samdb/ldb_modules/partition.h
source4/dsdb/samdb/ldb_modules/partition_init.c

index 93f2d6be07560f9c5a3920341d32b523d74f698d..92918c798d98d760731461ff68bfb7f85ba04745 100644 (file)
@@ -543,6 +543,7 @@ static int partition_search(struct ldb_module *module, struct ldb_request *req)
 
        struct ldb_control *search_control = ldb_request_get_control(req, LDB_CONTROL_SEARCH_OPTIONS_OID);
        struct ldb_control *domain_scope_control = ldb_request_get_control(req, LDB_CONTROL_DOMAIN_SCOPE_OID);
+       struct ldb_control *no_gc_control = ldb_request_get_control(req, DSDB_CONTROL_NO_GLOBAL_CATALOG);
        
        struct ldb_search_options_control *search_options = NULL;
        struct dsdb_partition *p;
@@ -618,6 +619,17 @@ static int partition_search(struct ldb_module *module, struct ldb_request *req)
        for (i=0; data->partitions[i]; i++) {
                bool match = false, stop = false;
 
+               if (data->partitions[i]->partial_replica && no_gc_control != NULL) {
+                       if (ldb_dn_compare_base(data->partitions[i]->ctrl->dn,
+                                               req->op.search.base) == 0) {
+                               /* base DN is in a partial replica
+                                  with the NO_GLOBAL_CATALOG
+                                  control. This partition is invisible */
+                               /* DEBUG(0,("DENYING NON-GC OP: %s\n", ldb_module_call_chain(req, req))); */
+                               continue;
+                       }
+               }
+
                if (phantom_root) {
                        /* Phantom root: Find all partitions under the
                         * search base. We match if:
index 45568ba40473d166d01a9de4dd4c39918fc65923..d05ff5db0119729e8cec07a514aec47f53dec69f 100644 (file)
@@ -31,6 +31,7 @@ struct dsdb_partition {
        struct dsdb_control_current_partition *ctrl;
        const char *backend_url;
        DATA_BLOB orig_record;
+       bool partial_replica; /* a GC partition */
 };
 
 struct partition_module {
index 50aabc92fe670449a077b117caa7578b937ffacf..0dd3a472c2a39bf66885736f347e834b459afcf1 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) {
@@ -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);