Rework control handling to remove the 'domain_scope' control
authorAndrew Bartlett <abartlet@samba.org>
Tue, 15 Jan 2008 21:49:54 +0000 (08:49 +1100)
committerAndrew Bartlett <abartlet@samba.org>
Tue, 15 Jan 2008 21:49:54 +0000 (08:49 +1100)
Also remove the search_options control earlier, before, rather than
after duplicating the request.

When we generate referalls in the partition module, the domain_scope
control with suppress them.

Andrew Bartlett

source/dsdb/samdb/ldb_modules/partition.c

index 4586810d9643606e9e58fd3277aae11cf1f2021b..61b64441a749ac817d3e593719d9099b52341a94 100644 (file)
@@ -169,13 +169,12 @@ static int partition_other_callback(struct ldb_context *ldb, void *context, stru
 }
 
 
-static int partition_send_request(struct partition_context *ac, struct ldb_control *remove_control, 
+static int partition_send_request(struct partition_context *ac, 
                                  struct dsdb_control_current_partition *partition)
 {
        int ret;
        struct ldb_module *backend;
        struct ldb_request *req;
-       struct ldb_control **saved_controls;
 
        if (partition) {
                backend = make_module_for_next_request(ac, ac->module->ldb, partition->module);
@@ -225,12 +224,6 @@ static int partition_send_request(struct partition_context *ac, struct ldb_contr
                req->context = ac;
        }
 
-       /* Remove a control, so we don't confuse a backend server */
-       if (remove_control && !save_controls(remove_control, req, &saved_controls)) {
-               ldb_oom(ac->module->ldb);
-               return LDB_ERR_OPERATIONS_ERROR;
-       }
-       
        if (partition) {
                ret = ldb_request_add_control(req, DSDB_CONTROL_CURRENT_PARTITION_OID, false, partition);
                if (ret != LDB_SUCCESS) {
@@ -253,18 +246,17 @@ static int partition_send_request(struct partition_context *ac, struct ldb_contr
  */
 static int partition_send_all(struct ldb_module *module, 
                              struct partition_context *ac, 
-                             struct ldb_control *remove_control, 
                              struct ldb_request *req) 
 {
        int i;
        struct partition_private_data *data = talloc_get_type(module->private_data, 
                                                              struct partition_private_data);
-       int ret = partition_send_request(ac, remove_control, NULL);
+       int ret = partition_send_request(ac, NULL);
        if (ret != LDB_SUCCESS) {
                return ret;
        }
        for (i=0; data && data->partitions && data->partitions[i]; i++) {
-               ret = partition_send_request(ac, remove_control, data->partitions[i]);
+               ret = partition_send_request(ac, data->partitions[i]);
                if (ret != LDB_SUCCESS) {
                        return ret;
                }
@@ -297,7 +289,7 @@ static int partition_replicate(struct ldb_module *module, struct ldb_request *re
                                        return LDB_ERR_OPERATIONS_ERROR;
                                }
                                
-                               return partition_send_all(module, ac, NULL, req);
+                               return partition_send_all(module, ac, req);
                        }
                }
        }
@@ -314,6 +306,7 @@ static int partition_replicate(struct ldb_module *module, struct ldb_request *re
                 * TODO: we should maybe return an error here
                 *       if it's not a special dn
                 */
+
                return ldb_next_request(module, req);
        }
 
@@ -334,6 +327,8 @@ static int partition_replicate(struct ldb_module *module, struct ldb_request *re
 /* search */
 static int partition_search(struct ldb_module *module, struct ldb_request *req)
 {
+       struct ldb_control **saved_controls;
+       
        /* Find backend */
        struct partition_private_data *data = talloc_get_type(module->private_data, 
                                                              struct partition_private_data);
@@ -342,19 +337,34 @@ static int partition_search(struct ldb_module *module, struct ldb_request *req)
        /* (later) consider if we should be searching multiple
         * partitions (for 'invisible' partition behaviour */
        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_search_options_control *search_options = NULL;
        if (search_control) {
                search_options = talloc_get_type(search_control->data, struct ldb_search_options_control);
        }
 
+       /* Remove the domain_scope control, so we don't confuse a backend server */
+       if (domain_scope_control && !save_controls(domain_scope_control, req, &saved_controls)) {
+               ldb_oom(module->ldb);
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+
+       /* TODO:
+          Generate referrals (look for a partition under this DN) if we don't have the above control specified
+       */
+       
        if (search_options && (search_options->search_options & LDB_SEARCH_OPTION_PHANTOM_ROOT)) {
                int ret, i;
                struct partition_context *ac;
-               struct ldb_control *remove_control = NULL;
                if ((search_options->search_options & ~LDB_SEARCH_OPTION_PHANTOM_ROOT) == 0) {
                        /* We have processed this flag, so we are done with this control now */
-                       remove_control = search_control;
+
+                       /* Remove search control, so we don't confuse a backend server */
+                       if (search_control && !save_controls(search_control, req, &saved_controls)) {
+                               ldb_oom(module->ldb);
+                               return LDB_ERR_OPERATIONS_ERROR;
+                       }
                }
                ac = partition_init_handle(req, module);
                if (!ac) {
@@ -363,12 +373,12 @@ static int partition_search(struct ldb_module *module, struct ldb_request *req)
 
                /* Search from the base DN */
                if (!req->op.search.base || ldb_dn_is_null(req->op.search.base)) {
-                       return partition_send_all(module, ac, remove_control, req);
+                       return partition_send_all(module, ac, req);
                }
                for (i=0; data && data->partitions && data->partitions[i]; i++) {
                        /* Find all partitions under the search base */
                        if (ldb_dn_compare_base(req->op.search.base, data->partitions[i]->dn) == 0) {
-                               ret = partition_send_request(ac, remove_control, data->partitions[i]);
+                               ret = partition_send_request(ac, data->partitions[i]);
                                if (ret != LDB_SUCCESS) {
                                        return ret;
                                }
@@ -384,6 +394,16 @@ static int partition_search(struct ldb_module *module, struct ldb_request *req)
                return LDB_SUCCESS;
        } else {
                /* Handle this like all other requests */
+               if (search_control && (search_options->search_options & ~LDB_SEARCH_OPTION_PHANTOM_ROOT) == 0) {
+                       /* We have processed this flag, so we are done with this control now */
+
+                       /* Remove search control, so we don't confuse a backend server */
+                       if (search_control && !save_controls(search_control, req, &saved_controls)) {
+                               ldb_oom(module->ldb);
+                               return LDB_ERR_OPERATIONS_ERROR;
+                       }
+               }
+
                return partition_replicate(module, req, req->op.search.base);
        }
 }
@@ -693,7 +713,7 @@ static int partition_extended(struct ldb_module *module, struct ldb_request *req
                return LDB_ERR_OPERATIONS_ERROR;
        }
                        
-       return partition_send_all(module, ac, NULL, req);
+       return partition_send_all(module, ac, req);
 }
 
 static int sort_compare(void *void1,