TODO test/sq sort meta data after adding isDeleted
[metze/samba/wip.git] / source4 / dsdb / samdb / ldb_modules / anr.c
index da23030ed3a019352732f34ffbbda9644b499252..ec9d82512c897f94741b0844d922d45510945c08 100644 (file)
@@ -30,8 +30,9 @@
  */
 
 #include "includes.h"
-#include "ldb_includes.h"
+#include "ldb_module.h"
 #include "dsdb/samdb/samdb.h"
+#include "dsdb/samdb/ldb_modules/util.h"
 
 /**
  * Make a and 'and' or 'or' tree from the two supplied elements 
@@ -40,11 +41,14 @@ static struct ldb_parse_tree *make_parse_list(struct ldb_module *module,
                                       TALLOC_CTX *mem_ctx, enum ldb_parse_op op, 
                                       struct ldb_parse_tree *first_arm, struct ldb_parse_tree *second_arm)
 {
+       struct ldb_context *ldb;
        struct ldb_parse_tree *list;
 
+       ldb = ldb_module_get_ctx(module);
+
        list = talloc(mem_ctx, struct ldb_parse_tree);
        if (list == NULL){
-               ldb_oom(module->ldb);
+               ldb_oom(ldb);
                return NULL;
        }
        list->operation = op;
@@ -52,7 +56,7 @@ static struct ldb_parse_tree *make_parse_list(struct ldb_module *module,
        list->u.list.num_elements = 2;
        list->u.list.elements = talloc_array(list, struct ldb_parse_tree *, 2);
        if (!list->u.list.elements) {
-               ldb_oom(module->ldb);
+               ldb_oom(ldb);
                return NULL;
        }
        list->u.list.elements[0] = talloc_steal(list, first_arm);
@@ -64,11 +68,16 @@ static struct ldb_parse_tree *make_parse_list(struct ldb_module *module,
  * Make an equality or prefix match tree, from the attribute, operation and matching value supplied
  */
 static struct ldb_parse_tree *make_match_tree(struct ldb_module *module,
-                                      TALLOC_CTX *mem_ctx, enum ldb_parse_op op, 
-                                      const char *attr, const DATA_BLOB *match)
+                                             TALLOC_CTX *mem_ctx,
+                                             enum ldb_parse_op op,
+                                             const char *attr,
+                                             struct ldb_val *match)
 {
+       struct ldb_context *ldb;
        struct ldb_parse_tree *match_tree;
 
+       ldb = ldb_module_get_ctx(module);
+
        match_tree = talloc(mem_ctx, struct ldb_parse_tree);
        
        /* Depending on what type of match was selected, fill in the right part of the union */
@@ -83,7 +92,8 @@ static struct ldb_parse_tree *make_match_tree(struct ldb_module *module,
                match_tree->u.substring.chunks = talloc_array(match_tree, struct ldb_val *, 2);
                
                if (match_tree->u.substring.chunks == NULL){
-                       ldb_oom(module->ldb);
+                       talloc_free(match_tree);
+                       ldb_oom(ldb);
                        return NULL;
                }
                match_tree->u.substring.chunks[0] = match;
@@ -93,6 +103,9 @@ static struct ldb_parse_tree *make_match_tree(struct ldb_module *module,
                match_tree->u.equality.attr = attr;
                match_tree->u.equality.value = *match;
                break;
+       default:
+               talloc_free(match_tree);
+               return NULL;
        }
        return match_tree;
 }
@@ -113,31 +126,34 @@ struct anr_context {
  */
 static int anr_replace_value(struct anr_context *ac,
                             TALLOC_CTX *mem_ctx,
-                            const struct ldb_val *match,
+                            struct ldb_val *match,
                             struct ldb_parse_tree **ntree)
 {
        struct ldb_parse_tree *tree = NULL;
        struct ldb_module *module = ac->module;
        struct ldb_parse_tree *match_tree;
        struct dsdb_attribute *cur;
-       const struct dsdb_schema *schema = dsdb_get_schema(module->ldb);
+       const struct dsdb_schema *schema;
+       struct ldb_context *ldb;
        uint8_t *p;
        enum ldb_parse_op op;
 
+       ldb = ldb_module_get_ctx(module);
+
+       schema = dsdb_get_schema(ldb, ac);
        if (!schema) {
-               ldb_asprintf_errstring(module->ldb, "no schema with which to construct anr filter");
+               ldb_asprintf_errstring(ldb, "no schema with which to construct anr filter");
                return LDB_ERR_OPERATIONS_ERROR;
        }
 
        ac->found_anr = true;
 
        if (match->length > 1 && match->data[0] == '=') {
-               DATA_BLOB *match2 = talloc(mem_ctx, DATA_BLOB);
-               *match2 = data_blob_const(match->data+1, match->length - 1);
+               struct ldb_val *match2 = talloc(mem_ctx, struct ldb_val);
                if (match2 == NULL){
-                       ldb_oom(module->ldb);
-                       return LDB_ERR_OPERATIONS_ERROR;
+                       return ldb_oom(ldb);
                }
+               *match2 = data_blob_const(match->data+1, match->length - 1);
                match = match2;
                op = LDB_OP_EQUALITY;
        } else {
@@ -151,8 +167,7 @@ static int anr_replace_value(struct anr_context *ac,
                        /* Inject an 'or' with the current tree */
                        tree = make_parse_list(module, mem_ctx,  LDB_OP_OR, tree, match_tree);
                        if (tree == NULL) {
-                               ldb_oom(module->ldb);
-                               return LDB_ERR_OPERATIONS_ERROR;
+                               return ldb_oom(ldb);
                        }
                } else {
                        tree = match_tree;
@@ -167,11 +182,10 @@ static int anr_replace_value(struct anr_context *ac,
 
        if (p) {
                struct ldb_parse_tree *first_split_filter, *second_split_filter, *split_filters, *match_tree_1, *match_tree_2;
-               DATA_BLOB *first_match = talloc(tree, DATA_BLOB);
-               DATA_BLOB *second_match = talloc(tree, DATA_BLOB);
+               struct ldb_val *first_match = talloc(tree, struct ldb_val);
+               struct ldb_val *second_match = talloc(tree, struct ldb_val);
                if (!first_match || !second_match) {
-                       ldb_oom(module->ldb);
-                       return LDB_ERR_OPERATIONS_ERROR;
+                       return ldb_oom(ldb);
                }
                *first_match = data_blob_const(match->data, p-match->data);
                *second_match = data_blob_const(p+1, match->length - (p-match->data) - 1);
@@ -183,8 +197,7 @@ static int anr_replace_value(struct anr_context *ac,
 
                first_split_filter = make_parse_list(module, ac,  LDB_OP_AND, match_tree_1, match_tree_2);
                if (first_split_filter == NULL){
-                       ldb_oom(module->ldb);
-                       return LDB_ERR_OPERATIONS_ERROR;
+                       return ldb_oom(ldb);
                }
                
                match_tree_1 = make_match_tree(module, mem_ctx, op, "sn", first_match);
@@ -192,15 +205,13 @@ static int anr_replace_value(struct anr_context *ac,
 
                second_split_filter = make_parse_list(module, ac,  LDB_OP_AND, match_tree_1, match_tree_2);
                if (second_split_filter == NULL){
-                       ldb_oom(module->ldb);
-                       return LDB_ERR_OPERATIONS_ERROR;
+                       return ldb_oom(ldb);
                }
 
                split_filters = make_parse_list(module, mem_ctx,  LDB_OP_OR, 
                                                first_split_filter, second_split_filter);
                if (split_filters == NULL) {
-                       ldb_oom(module->ldb);
-                       return LDB_ERR_OPERATIONS_ERROR;
+                       return ldb_oom(ldb);
                }
 
                if (tree) {
@@ -223,7 +234,7 @@ static int anr_replace_subtrees(struct anr_context *ac,
                                struct ldb_parse_tree **ntree)
 {
        int ret;
-       int i;
+       unsigned int i;
 
        switch (tree->operation) {
        case LDB_OP_AND:
@@ -289,7 +300,7 @@ static int anr_search_callback(struct ldb_request *req, struct ldb_reply *ares)
 
        switch (ares->type) {
        case LDB_REPLY_ENTRY:
-               return ldb_module_send_entry(ac->req, ares->message);
+               return ldb_module_send_entry(ac->req, ares->message, ares->controls);
 
        case LDB_REPLY_REFERRAL:
                return ldb_module_send_referral(ac->req, ares->referral);
@@ -305,15 +316,17 @@ static int anr_search_callback(struct ldb_request *req, struct ldb_reply *ares)
 /* search */
 static int anr_search(struct ldb_module *module, struct ldb_request *req)
 {
+       struct ldb_context *ldb;
        struct ldb_parse_tree *anr_tree;
        struct ldb_request *down_req;
        struct anr_context *ac;
        int ret;
 
+       ldb = ldb_module_get_ctx(module);
+
        ac = talloc(req, struct anr_context);
        if (!ac) {
-               ldb_oom(module->ldb);
-               return LDB_ERR_OPERATIONS_ERROR;
+               return ldb_oom(ldb);
        }
 
        ac->module = module;
@@ -326,7 +339,7 @@ static int anr_search(struct ldb_module *module, struct ldb_request *req)
 
        ret = anr_replace_subtrees(ac, req->op.search.tree, "anr", &anr_tree);
        if (ret != LDB_SUCCESS) {
-               return LDB_ERR_OPERATIONS_ERROR;
+               return ldb_operr(ldb);
        }
 
        if (!ac->found_anr) {
@@ -335,7 +348,7 @@ static int anr_search(struct ldb_module *module, struct ldb_request *req)
        }
 
        ret = ldb_build_search_req_ex(&down_req,
-                                       module->ldb, ac,
+                                       ldb, ac,
                                        req->op.search.base,
                                        req->op.search.scope,
                                        anr_tree,
@@ -343,15 +356,22 @@ static int anr_search(struct ldb_module *module, struct ldb_request *req)
                                        req->controls,
                                        ac, anr_search_callback,
                                        req);
+       LDB_REQ_SET_LOCATION(down_req);
        if (ret != LDB_SUCCESS) {
-               return LDB_ERR_OPERATIONS_ERROR;
+               return ldb_operr(ldb);
        }
        talloc_steal(down_req, anr_tree);
 
        return ldb_next_request(module, down_req);
 }
 
-_PUBLIC_ const struct ldb_module_ops ldb_anr_module_ops = {
+static const struct ldb_module_ops ldb_anr_module_ops = {
        .name              = "anr",
        .search = anr_search
 };
+
+int ldb_anr_module_init(const char *version)
+{
+       LDB_MODULE_CHECK_VERSION(version);
+       return ldb_register_module(&ldb_anr_module_ops);
+}