r21496: A number of ldb control and LDAP changes, surrounding the
authorAndrew Bartlett <abartlet@samba.org>
Thu, 22 Feb 2007 01:54:40 +0000 (01:54 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 19:48:44 +0000 (14:48 -0500)
'phantom_root' flag in the search_options control

- Add in support for LDB controls to the js layer
- Test the behaviour
- Implement support for the 'phantom_root' flag in the partitions module
- Make the LDAP server set the 'phantom_root' flag in the search_options control
  - This replaces the global_catalog flag passed down as an opaque pointer
- Rework the string-format control parsing function into
  ldb_parse_control_strings(), returning errors by ldb_errorstring()
  method, rather than with printf to stderr
- Rework some of the ldb_control handling logic

Andrew Bartlett
(This used to be commit 2b3df7f38d7790358dbb4de1b8609bf794a351fb)

15 files changed:
source4/dsdb/samdb/ldb_modules/extended_dn.c
source4/dsdb/samdb/ldb_modules/partition.c
source4/dsdb/samdb/ldb_modules/repl_meta_data.c
source4/dsdb/samdb/ldb_modules/show_deleted.c
source4/ldap_server/ldap_backend.c
source4/lib/ldb/common/ldb_controls.c
source4/lib/ldb/include/ldb.h
source4/lib/ldb/include/ldb_private.h
source4/lib/ldb/modules/asq.c
source4/lib/ldb/modules/paged_results.c
source4/lib/ldb/modules/sort.c
source4/lib/ldb/tools/cmdline.c
source4/lib/ldb/tools/ldbsearch.c
source4/scripting/ejs/smbcalls_ldb.c
testprogs/ejs/ldap.js

index a571857bbbeddc3ae94ddeb323e414f0c8f60439..6a7492013b8f84f6879cb737c09a7083e0137289 100644 (file)
@@ -215,7 +215,7 @@ static int extended_search(struct ldb_module *module, struct ldb_request *req)
        int ret;
 
        /* check if there's an extended dn control */
-       control = get_control_from_list(req->controls, LDB_CONTROL_EXTENDED_DN_OID);
+       control = ldb_request_get_control(req, LDB_CONTROL_EXTENDED_DN_OID);
        if (control == NULL) {
                /* not found go on */
                return ldb_next_request(module, req);
index b23ceebf1b498b67c8e64ce57ab5a9f973edcbef..bd037066ca81f2d1565b851c327df518961c3325 100644 (file)
@@ -1,3 +1,4 @@
+
 /* 
    Partitions ldb module
 
@@ -219,16 +220,26 @@ static int partition_send_request(struct partition_context *ac, struct dsdb_cont
        ac->down_req = talloc_realloc(ac, ac->down_req, 
                                        struct ldb_request *, ac->num_requests + 1);
        if (!ac->down_req) {
-               ldb_set_errstring(ac->module->ldb, "Out of Memory");
+               ldb_oom(ac->module->ldb);
                return LDB_ERR_OPERATIONS_ERROR;
        }
        req = ac->down_req[ac->num_requests] = talloc(ac, struct ldb_request);
        if (req == NULL) {
-               ldb_set_errstring(ac->module->ldb, "Out of Memory");
+               ldb_oom(ac->module->ldb);
                return LDB_ERR_OPERATIONS_ERROR;
        }
        
-       *ac->down_req[ac->num_requests] = *ac->orig_req; /* copy the request */
+       *req = *ac->orig_req; /* copy the request */
+
+       if (ac->orig_req->controls) {
+               req->controls
+                       = talloc_memdup(req,
+                                       ac->orig_req->controls, talloc_get_size(ac->orig_req->controls));
+               if (req->controls == NULL) {
+                       ldb_oom(ac->module->ldb);
+                       return LDB_ERR_OPERATIONS_ERROR;
+               }
+       }
 
        if (req->operation == LDB_SEARCH) {
                /* If the search is for 'more' than this partition,
@@ -350,7 +361,14 @@ 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 */
-       if (ldb_get_opaque(module->ldb, "global_catalog")) {
+       struct ldb_control *search_control = ldb_request_get_control(req, LDB_CONTROL_SEARCH_OPTIONS_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);
+       }
+
+       if (search_options && (search_options->search_options & LDB_SEARCH_OPTION_PHANTOM_ROOT)) {
                int ret, i;
                struct partition_context *ac;
                
index 51b6612236a79deb8014cba1ce945d570bd84a1a..10f3da243b542b9101f374ef189c2635adb76de6 100644 (file)
@@ -260,7 +260,7 @@ static int replmd_prepare_originating(struct ldb_module *module, struct ldb_requ
                return LDB_ERR_CONSTRAINT_VIOLATION;
        }
 
-       partition_ctrl = get_control_from_list(req->controls, DSDB_CONTROL_CURRENT_PARTITION_OID);
+       partition_ctrl = ldb_request_get_control(req, DSDB_CONTROL_CURRENT_PARTITION_OID);
        if (!partition_ctrl) {
                ldb_debug_set(module->ldb, LDB_DEBUG_FATAL,
                              "%s: no current partition control found",
index 9d624c99824bbd8a91bacb4715075cc86b8ef428..b94fe39c9a525e940a7096beaa2e0701dd1fc8bd 100644 (file)
@@ -96,7 +96,7 @@ static int show_deleted_search(struct ldb_module *module, struct ldb_request *re
        int ret;
 
        /* check if there's a show deleted control */
-       control = get_control_from_list(req->controls, LDB_CONTROL_SHOW_DELETED_OID);
+       control = ldb_request_get_control(req, LDB_CONTROL_SHOW_DELETED_OID);
 
        /* copy the request for modification */
        down_req = talloc(req, struct ldb_request);
index b318996f432d3f35963218854ae3f950e534ee32..fa8c07fa5529dd235b334fc7787adb178a10a4eb 100644 (file)
@@ -90,10 +90,6 @@ NTSTATUS ldapsrv_backend_Init(struct ldapsrv_connection *conn)
                ldb_set_opaque(conn->ldb, "supportedSASLMechanims", sasl_mechs);
        }
 
-       if (conn->global_catalog) {
-               ldb_set_opaque(conn->ldb, "global_catalog", (void *)(-1));
-       }
-
        return NT_STATUS_OK;
 }
 
@@ -229,6 +225,21 @@ static NTSTATUS ldapsrv_SearchRequest(struct ldapsrv_call *call)
 
        lreq->controls = call->request->controls;
 
+       if (call->conn->global_catalog) {
+               struct ldb_control *search_control = ldb_request_get_control(lreq, LDB_CONTROL_SEARCH_OPTIONS_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);
+                       search_options->search_options |= LDB_SEARCH_OPTION_PHANTOM_ROOT;
+               } else {
+                       search_options = talloc(lreq, struct ldb_search_options_control);
+                       NT_STATUS_HAVE_NO_MEMORY(search_options);
+                       search_options->search_options = LDB_SEARCH_OPTION_PHANTOM_ROOT;
+                       ldb_request_add_control(lreq, LDB_CONTROL_SEARCH_OPTIONS_OID, false, search_options);
+               }
+       }
+
        lreq->context = res;
        lreq->callback = ldb_search_default_callback;
 
index 182e1b41d48166aefb534031b6906f9c64783f4e..32bf4bd9d8eb26037b939be836519382d078becd 100644 (file)
 
 /* check if a control with the specified "oid" exist and return it */
 /* returns NULL if not found */
-struct ldb_control *get_control_from_list(struct ldb_control **controls, const char *oid)
+struct ldb_control *ldb_request_get_control(struct ldb_request *req, const char *oid)
 {
        int i;
 
        /* check if there's a paged request control */
-       if (controls != NULL) {
-               for (i = 0; controls[i]; i++) {
-                       if (strcmp(oid, controls[i]->oid) == 0) {
+       if (req->controls != NULL) {
+               for (i = 0; req->controls[i]; i++) {
+                       if (strcmp(oid, req->controls[i]->oid) == 0) {
                                break;
                        }
                }
 
-               return controls[i];
+               return req->controls[i];
        }
 
        return NULL;
@@ -132,3 +132,440 @@ int ldb_request_add_control(struct ldb_request *req, const char *oid, bool criti
        ctrls[n] = ctrl;
        return LDB_SUCCESS;
 }
+
+/* Parse controls from the format used on the command line and in ejs */
+
+struct ldb_control **ldb_parse_control_strings(struct ldb_context *ldb, void *mem_ctx, const char **control_strings)
+{
+       int i;
+       struct ldb_control **ctrl;
+
+       char *error_string = NULL;
+
+       if (control_strings == NULL || control_strings[0] == NULL)
+               return NULL;
+
+       for (i = 0; control_strings[i]; i++);
+
+       ctrl = talloc_array(mem_ctx, struct ldb_control *, i + 1);
+
+       for (i = 0; control_strings[i]; i++) {
+               if (strncmp(control_strings[i], "vlv:", 4) == 0) {
+                       struct ldb_vlv_req_control *control;
+                       const char *p;
+                       char attr[1024];
+                       char ctxid[1024];
+                       int crit, bc, ac, os, cc, ret;
+
+                       attr[0] = '\0';
+                       ctxid[0] = '\0';
+                       p = &(control_strings[i][4]);
+                       ret = sscanf(p, "%d:%d:%d:%d:%d:%1023[^$]", &crit, &bc, &ac, &os, &cc, ctxid);
+                       if (ret < 5) {
+                               ret = sscanf(p, "%d:%d:%d:%1023[^:]:%1023[^$]", &crit, &bc, &ac, attr, ctxid);
+                       }
+                              
+                       if ((ret < 4) || (crit < 0) || (crit > 1)) {
+                               error_string = talloc_asprintf(mem_ctx, "invalid server_sort control syntax\n");
+                               error_string = talloc_asprintf_append(error_string, " syntax: crit(b):bc(n):ac(n):<os(n):cc(n)|attr(s)>[:ctxid(o)]\n");
+                               error_string = talloc_asprintf_append(error_string, "   note: b = boolean, n = number, s = string, o = b64 binary blob");
+                               ldb_set_errstring(ldb, error_string);
+                               talloc_free(error_string);
+                               return NULL;
+                       }
+                       if (!(ctrl[i] = talloc(ctrl, struct ldb_control))) {
+                               ldb_oom(ldb);
+                               return NULL;
+                       }
+                       ctrl[i]->oid = LDB_CONTROL_VLV_REQ_OID;
+                       ctrl[i]->critical = crit;
+                       if (!(control = talloc(ctrl[i],
+                                              struct ldb_vlv_req_control))) {
+                               ldb_oom(ldb);
+                               return NULL;
+                       }
+                       control->beforeCount = bc;
+                       control->afterCount = ac;
+                       if (attr[0]) {
+                               control->type = 1;
+                               control->match.gtOrEq.value = talloc_strdup(control, attr);
+                               control->match.gtOrEq.value_len = strlen(attr);
+                       } else {
+                               control->type = 0;
+                               control->match.byOffset.offset = os;
+                               control->match.byOffset.contentCount = cc;
+                       }
+                       if (ctxid[0]) {
+                               control->ctxid_len = ldb_base64_decode(ctxid);
+                               control->contextId = (char *)talloc_memdup(control, ctxid, control->ctxid_len);
+                       } else {
+                               control->ctxid_len = 0;
+                               control->contextId = NULL;
+                       }
+                       ctrl[i]->data = control;
+
+                       continue;
+               }
+
+               if (strncmp(control_strings[i], "dirsync:", 8) == 0) {
+                       struct ldb_dirsync_control *control;
+                       const char *p;
+                       char cookie[1024];
+                       int crit, flags, max_attrs, ret;
+                      
+                       cookie[0] = '\0';
+                       p = &(control_strings[i][8]);
+                       ret = sscanf(p, "%d:%d:%d:%1023[^$]", &crit, &flags, &max_attrs, cookie);
+
+                       if ((ret < 3) || (crit < 0) || (crit > 1) || (flags < 0) || (max_attrs < 0)) {
+                               error_string = talloc_asprintf(mem_ctx, "invalid dirsync control syntax\n");
+                               error_string = talloc_asprintf_append(error_string, " syntax: crit(b):flags(n):max_attrs(n)[:cookie(o)]\n");
+                               error_string = talloc_asprintf_append(error_string, "   note: b = boolean, n = number, o = b64 binary blob");
+                               ldb_set_errstring(ldb, error_string);
+                               talloc_free(error_string);
+                               return NULL;
+                       }
+
+                       /* w2k3 seems to ignore the parameter,
+                        * but w2k sends a wrong cookie when this value is to small
+                        * this would cause looping forever, while getting
+                        * the same data and same cookie forever
+                        */
+                       if (max_attrs == 0) max_attrs = 0x0FFFFFFF;
+
+                       ctrl[i] = talloc(ctrl, struct ldb_control);
+                       ctrl[i]->oid = LDB_CONTROL_DIRSYNC_OID;
+                       ctrl[i]->critical = crit;
+                       control = talloc(ctrl[i], struct ldb_dirsync_control);
+                       control->flags = flags;
+                       control->max_attributes = max_attrs;
+                       if (*cookie) {
+                               control->cookie_len = ldb_base64_decode(cookie);
+                               control->cookie = (char *)talloc_memdup(control, cookie, control->cookie_len);
+                       } else {
+                               control->cookie = NULL;
+                               control->cookie_len = 0;
+                       }
+                       ctrl[i]->data = control;
+
+                       continue;
+               }
+
+               if (strncmp(control_strings[i], "asq:", 4) == 0) {
+                       struct ldb_asq_control *control;
+                       const char *p;
+                       char attr[256];
+                       int crit, ret;
+
+                       attr[0] = '\0';
+                       p = &(control_strings[i][4]);
+                       ret = sscanf(p, "%d:%255[^$]", &crit, attr);
+                       if ((ret != 2) || (crit < 0) || (crit > 1) || (attr[0] == '\0')) {
+                               error_string = talloc_asprintf(mem_ctx, "invalid asq control syntax\n");
+                               error_string = talloc_asprintf_append(error_string, " syntax: crit(b):attr(s)\n");
+                               error_string = talloc_asprintf_append(error_string, "   note: b = boolean, s = string");
+                               ldb_set_errstring(ldb, error_string);
+                               talloc_free(error_string);
+                               return NULL;
+                       }
+
+                       ctrl[i] = talloc(ctrl, struct ldb_control);
+                       if (!ctrl[i]) {
+                               ldb_oom(ldb);
+                               return NULL;
+                       }
+                       ctrl[i]->oid = LDB_CONTROL_ASQ_OID;
+                       ctrl[i]->critical = crit;
+                       control = talloc(ctrl[i], struct ldb_asq_control);
+                       control->request = 1;
+                       control->source_attribute = talloc_strdup(control, attr);
+                       control->src_attr_len = strlen(attr);
+                       ctrl[i]->data = control;
+
+                       continue;
+               }
+
+               if (strncmp(control_strings[i], "extended_dn:", 12) == 0) {
+                       struct ldb_extended_dn_control *control;
+                       const char *p;
+                       int crit, type, ret;
+
+                       p = &(control_strings[i][12]);
+                       ret = sscanf(p, "%d:%d", &crit, &type);
+                       if ((ret != 2) || (crit < 0) || (crit > 1) || (type < 0) || (type > 1)) {
+                               error_string = talloc_asprintf(mem_ctx, "invalid extended_dn control syntax\n");
+                               error_string = talloc_asprintf_append(error_string, " syntax: crit(b):type(b)\n");
+                               error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
+                               ldb_set_errstring(ldb, error_string);
+                               talloc_free(error_string);
+                               return NULL;
+                       }
+
+                       ctrl[i] = talloc(ctrl, struct ldb_control);
+                       if (!ctrl[i]) {
+                               ldb_oom(ldb);
+                               return NULL;
+                       }
+                       ctrl[i]->oid = LDB_CONTROL_EXTENDED_DN_OID;
+                       ctrl[i]->critical = crit;
+                       control = talloc(ctrl[i], struct ldb_extended_dn_control);
+                       control->type = type;
+                       ctrl[i]->data = control;
+
+                       continue;
+               }
+
+               if (strncmp(control_strings[i], "sd_flags:", 9) == 0) {
+                       struct ldb_sd_flags_control *control;
+                       const char *p;
+                       int crit, ret;
+                       unsigned secinfo_flags;
+
+                       p = &(control_strings[i][9]);
+                       ret = sscanf(p, "%d:%u", &crit, &secinfo_flags);
+                       if ((ret != 2) || (crit < 0) || (crit > 1) || (secinfo_flags < 0) || (secinfo_flags > 0xF)) {
+                               error_string = talloc_asprintf(mem_ctx, "invalid sd_flags control syntax\n");
+                               error_string = talloc_asprintf_append(error_string, " syntax: crit(b):secinfo_flags(n)\n");
+                               error_string = talloc_asprintf_append(error_string, "   note: b = boolean, n = number");
+                               ldb_set_errstring(ldb, error_string);
+                               talloc_free(error_string);
+                               return NULL;
+                       }
+
+                       ctrl[i] = talloc(ctrl, struct ldb_control);
+                       if (!ctrl[i]) {
+                               ldb_oom(ldb);
+                               return NULL;
+                       }
+                       ctrl[i]->oid = LDB_CONTROL_SD_FLAGS_OID;
+                       ctrl[i]->critical = crit;
+                       control = talloc(ctrl[i], struct ldb_sd_flags_control);
+                       control->secinfo_flags = secinfo_flags;
+                       ctrl[i]->data = control;
+
+                       continue;
+               }
+
+               if (strncmp(control_strings[i], "search_options:", 15) == 0) {
+                       struct ldb_search_options_control *control;
+                       const char *p;
+                       int crit, ret;
+                       unsigned search_options;
+
+                       p = &(control_strings[i][15]);
+                       ret = sscanf(p, "%d:%u", &crit, &search_options);
+                       if ((ret != 2) || (crit < 0) || (crit > 1) || (search_options < 0) || (search_options > 0xF)) {
+                               error_string = talloc_asprintf(mem_ctx, "invalid search_options control syntax\n");
+                               error_string = talloc_asprintf_append(error_string, " syntax: crit(b):search_options(n)\n");
+                               error_string = talloc_asprintf_append(error_string, "   note: b = boolean, n = number");
+                               ldb_set_errstring(ldb, error_string);
+                               talloc_free(error_string);
+                               return NULL;
+                       }
+
+                       ctrl[i] = talloc(ctrl, struct ldb_control);
+                       if (!ctrl[i]) {
+                               ldb_oom(ldb);
+                               return NULL;
+                       }
+                       ctrl[i]->oid = LDB_CONTROL_SEARCH_OPTIONS_OID;
+                       ctrl[i]->critical = crit;
+                       control = talloc(ctrl[i], struct ldb_search_options_control);
+                       control->search_options = search_options;
+                       ctrl[i]->data = control;
+
+                       continue;
+               }
+
+               if (strncmp(control_strings[i], "domain_scope:", 13) == 0) {
+                       const char *p;
+                       int crit, ret;
+
+                       p = &(control_strings[i][13]);
+                       ret = sscanf(p, "%d", &crit);
+                       if ((ret != 1) || (crit < 0) || (crit > 1)) {
+                               error_string = talloc_asprintf(mem_ctx, "invalid domain_scope control syntax\n");
+                               error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n");
+                               error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
+                               ldb_set_errstring(ldb, error_string);
+                               talloc_free(error_string);
+                               return NULL;
+                       }
+
+                       ctrl[i] = talloc(ctrl, struct ldb_control);
+                       if (!ctrl[i]) {
+                               ldb_oom(ldb);
+                               return NULL;
+                       }
+                       ctrl[i]->oid = LDB_CONTROL_DOMAIN_SCOPE_OID;
+                       ctrl[i]->critical = crit;
+                       ctrl[i]->data = NULL;
+
+                       continue;
+               }
+
+               if (strncmp(control_strings[i], "paged_results:", 14) == 0) {
+                       struct ldb_paged_control *control;
+                       const char *p;
+                       int crit, size, ret;
+                      
+                       p = &(control_strings[i][14]);
+                       ret = sscanf(p, "%d:%d", &crit, &size);
+
+                       if ((ret != 2) || (crit < 0) || (crit > 1) || (size < 0)) {
+                               error_string = talloc_asprintf(mem_ctx, "invalid paged_results control syntax\n");
+                               error_string = talloc_asprintf_append(error_string, " syntax: crit(b):size(n)\n");
+                               error_string = talloc_asprintf_append(error_string, "   note: b = boolean, n = number");
+                               ldb_set_errstring(ldb, error_string);
+                               talloc_free(error_string);
+                               return NULL;
+                       }
+
+                       ctrl[i] = talloc(ctrl, struct ldb_control);
+                       if (!ctrl[i]) {
+                               ldb_oom(ldb);
+                               return NULL;
+                       }
+                       ctrl[i]->oid = LDB_CONTROL_PAGED_RESULTS_OID;
+                       ctrl[i]->critical = crit;
+                       control = talloc(ctrl[i], struct ldb_paged_control);
+                       control->size = size;
+                       control->cookie = NULL;
+                       control->cookie_len = 0;
+                       ctrl[i]->data = control;
+
+                       continue;
+               }
+
+               if (strncmp(control_strings[i], "server_sort:", 12) == 0) {
+                       struct ldb_server_sort_control **control;
+                       const char *p;
+                       char attr[256];
+                       char rule[128];
+                       int crit, rev, ret;
+
+                       attr[0] = '\0';
+                       rule[0] = '\0';
+                       p = &(control_strings[i][12]);
+                       ret = sscanf(p, "%d:%d:%255[^:]:%127[^:]", &crit, &rev, attr, rule);
+                       if ((ret < 3) || (crit < 0) || (crit > 1) || (rev < 0 ) || (rev > 1) ||attr[0] == '\0') {
+                               error_string = talloc_asprintf(mem_ctx, "invalid server_sort control syntax\n");
+                               error_string = talloc_asprintf_append(error_string, " syntax: crit(b):rev(b):attr(s)[:rule(s)]\n");
+                               error_string = talloc_asprintf_append(error_string, "   note: b = boolean, s = string");
+                               ldb_set_errstring(ldb, error_string);
+                               talloc_free(error_string);
+                               return NULL;
+                       }
+                       ctrl[i] = talloc(ctrl, struct ldb_control);
+                       if (!ctrl[i]) {
+                               ldb_oom(ldb);
+                               return NULL;
+                       }
+                       ctrl[i]->oid = LDB_CONTROL_SERVER_SORT_OID;
+                       ctrl[i]->critical = crit;
+                       control = talloc_array(ctrl[i], struct ldb_server_sort_control *, 2);
+                       control[0] = talloc(control, struct ldb_server_sort_control);
+                       control[0]->attributeName = talloc_strdup(control, attr);
+                       if (rule[0])
+                               control[0]->orderingRule = talloc_strdup(control, rule);
+                       else
+                               control[0]->orderingRule = NULL;
+                       control[0]->reverse = rev;
+                       control[1] = NULL;
+                       ctrl[i]->data = control;
+
+                       continue;
+               }
+
+               if (strncmp(control_strings[i], "notification:", 13) == 0) {
+                       const char *p;
+                       int crit, ret;
+
+                       p = &(control_strings[i][13]);
+                       ret = sscanf(p, "%d", &crit);
+                       if ((ret != 1) || (crit < 0) || (crit > 1)) {
+                               error_string = talloc_asprintf(mem_ctx, "invalid notification control syntax\n");
+                               error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n");
+                               error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
+                               ldb_set_errstring(ldb, error_string);
+                               talloc_free(error_string);
+                               return NULL;
+                       }
+
+                       ctrl[i] = talloc(ctrl, struct ldb_control);
+                       if (!ctrl[i]) {
+                               ldb_oom(ldb);
+                               return NULL;
+                       }
+                       ctrl[i]->oid = LDB_CONTROL_NOTIFICATION_OID;
+                       ctrl[i]->critical = crit;
+                       ctrl[i]->data = NULL;
+
+                       continue;
+               }
+
+               if (strncmp(control_strings[i], "show_deleted:", 13) == 0) {
+                       const char *p;
+                       int crit, ret;
+
+                       p = &(control_strings[i][13]);
+                       ret = sscanf(p, "%d", &crit);
+                       if ((ret != 1) || (crit < 0) || (crit > 1)) {
+                               error_string = talloc_asprintf(mem_ctx, "invalid show_deleted control syntax\n");
+                               error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n");
+                               error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
+                               ldb_set_errstring(ldb, error_string);
+                               talloc_free(error_string);
+                               return NULL;
+                       }
+
+                       ctrl[i] = talloc(ctrl, struct ldb_control);
+                       if (!ctrl[i]) {
+                               ldb_oom(ldb);
+                               return NULL;
+                       }
+                       ctrl[i]->oid = LDB_CONTROL_SHOW_DELETED_OID;
+                       ctrl[i]->critical = crit;
+                       ctrl[i]->data = NULL;
+
+                       continue;
+               }
+
+               if (strncmp(control_strings[i], "permissive_modify:", 18) == 0) {
+                       const char *p;
+                       int crit, ret;
+
+                       p = &(control_strings[i][18]);
+                       ret = sscanf(p, "%d", &crit);
+                       if ((ret != 1) || (crit < 0) || (crit > 1)) {
+                               error_string = talloc_asprintf(mem_ctx, "invalid permissive_modify control syntax\n");
+                               error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n");
+                               error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
+                               ldb_set_errstring(ldb, error_string);
+                               talloc_free(error_string);
+                               return NULL;
+                       }
+
+                       ctrl[i] = talloc(ctrl, struct ldb_control);
+                       if (!ctrl[i]) {
+                               ldb_oom(ldb);
+                               return NULL;
+                       }
+                       ctrl[i]->oid = LDB_CONTROL_PERMISSIVE_MODIFY_OID;
+                       ctrl[i]->critical = crit;
+                       ctrl[i]->data = NULL;
+
+                       continue;
+               }
+
+               /* no controls matched, throw an error */
+               ldb_asprintf_errstring(ldb, "Invalid control name: '%s'", control_strings[i]);
+               return NULL;
+       }
+
+       ctrl[i] = NULL;
+
+       return ctrl;
+}
+
+
index 9cc590434869ea5415d6d27d6cb25fae5c2a035b..3e09cf1506c6ef09badadfbd543fcfa0db35133f 100644 (file)
@@ -535,18 +535,10 @@ typedef int (*ldb_qsort_cmp_fn_t) (void *v1, void *v2, void *opaque);
 #define LDB_EXTENDED_START_TLS_OID     "1.3.6.1.4.1.1466.20037"
 
 /**
-   OID for LDAP Extended Operation START_TLS.
-
-   This Extended operation is used to start a new TLS
-   channel on top of a clear text channel.
 */
 #define LDB_EXTENDED_DYNAMIC_OID       "1.3.6.1.4.1.1466.101.119.1"
 
 /**
-   OID for LDAP Extended Operation START_TLS.
-
-   This Extended operation is used to start a new TLS
-   channel on top of a clear text channel.
 */
 #define LDB_EXTENDED_FAST_BIND_OID     "1.2.840.113556.1.4.1781"
 
@@ -560,20 +552,24 @@ struct ldb_sd_flags_control {
        unsigned secinfo_flags;
 };
 
+/*
+ * DOMAIN_SCOPE                0x00000001
+ * this limits the search to one partition,
+ * and no referrals will be returned.
+ * (Note this doesn't limit the entries by there
+ *  objectSid belonging to a domain! Builtin and Foreign Sids
+ *  are still returned)
+ *
+ * PHANTOM_ROOT                0x00000002
+ * this search on the whole tree on a domain controller
+ * over multiple partitions without referrals.
+ * (This is the default behavior on the Global Catalog Port)
+ */
+
+#define LDB_SEARCH_OPTION_DOMAIN_SCOPE 0x00000001
+#define LDB_SEARCH_OPTION_PHANTOM_ROOT 0x00000002
+
 struct ldb_search_options_control {
-       /*
-        * DOMAIN_SCOPE         0x00000001
-        * this limits the search to one partition,
-        * and no referrals will be returned.
-        * (Note this doesn't limit the entries by there
-        *  objectSid belonging to a domain! Builtin and Foreign Sids
-        *  are still returned)
-        *
-        * PHANTOM_ROOT         0x00000002
-        * this search on the whole tree on a domain controller
-        * over multiple partitions without referrals.
-        * (This is the default behavior on the Global Catalog Port)
-        */
        unsigned search_options;
 };
 
@@ -1001,6 +997,15 @@ int ldb_build_rename_req(struct ldb_request **ret_req,
 */
 int ldb_request_add_control(struct ldb_request *req, const char *oid, bool critical, void *data);
 
+/**
+   check if a control with the specified "oid" exist and return it 
+  \param req the request struct where to add the control
+  \param oid the object identifier of the control as string
+
+  \return the control, NULL if not found 
+*/
+struct ldb_control *ldb_request_get_control(struct ldb_request *req, const char *oid);
+
 /**
   Search the database
 
@@ -1676,4 +1681,17 @@ time_t ldb_string_utc_to_time(const char *s);
 
 
 void ldb_qsort (void *const pbase, size_t total_elems, size_t size, void *opaque, ldb_qsort_cmp_fn_t cmp);
+
+
+/**
+   Convert an array of string represention of a control into an array of ldb_control structures 
+   
+   \param ldb LDB context
+   \param mem_ctx TALLOC context to return result on, and to allocate error_string on
+   \param control_strings Array of string-formatted controls
+
+   \return array of ldb_control elements
+*/
+struct ldb_control **ldb_parse_control_strings(struct ldb_context *ldb, void *mem_ctx, const char **control_strings);
+
 #endif
index 3c6fb828a23b84dfd2c8d1c74024c31ebec8083c..9e4f7be202745675984905d857aab47c20fb43d8 100644 (file)
@@ -224,6 +224,9 @@ void ldb_msg_remove_element(struct ldb_message *msg, struct ldb_message_element
 */
 int ldb_sequence_number(struct ldb_context *ldb, enum ldb_sequence_type type, uint64_t *seq_num);
 
+
+/* Parse controls from the format used on the command line and in ejs */
+
 #define LDB_SEQ_GLOBAL_SEQUENCE    0x01
 #define LDB_SEQ_TIMESTAMP_SEQUENCE 0x02
 
index 413f6732ac629d57e810cfed858635e444dfc059..0c31727909e3a3cae0985238ff6348a4132cf448 100644 (file)
@@ -401,7 +401,7 @@ static int asq_search(struct ldb_module *module, struct ldb_request *req)
        struct ldb_handle *h;
 
        /* check if there's a paged request control */
-       control = get_control_from_list(req->controls, LDB_CONTROL_ASQ_OID);
+       control = ldb_request_get_control(req, LDB_CONTROL_ASQ_OID);
        if (control == NULL) {
                /* not found go on */
                return ldb_next_request(module, req);
index c4b1ecf26b35d2e3021d5f9e29c6cd8e037e93ff..8ad1f01c8c07bb6486b29b0131cb4b386cc11886 100644 (file)
@@ -239,7 +239,7 @@ static int paged_search(struct ldb_module *module, struct ldb_request *req)
        int ret;
 
        /* check if there's a paged request control */
-       control = get_control_from_list(req->controls, LDB_CONTROL_PAGED_RESULTS_OID);
+       control = ldb_request_get_control(req, LDB_CONTROL_PAGED_RESULTS_OID);
        if (control == NULL) {
                /* not found go on */
                return ldb_next_request(module, req);
index 6f34cebdb7a960c0c99c3e98206efd47d8ab0a0e..f8ee788d6c58604f67ab9200931061c31955e6b8 100644 (file)
@@ -223,7 +223,7 @@ static int server_sort_search(struct ldb_module *module, struct ldb_request *req
        int ret;
 
        /* check if there's a paged request control */
-       control = get_control_from_list(req->controls, LDB_CONTROL_SERVER_SORT_OID);
+       control = ldb_request_get_control(req, LDB_CONTROL_SERVER_SORT_OID);
        if (control == NULL) {
                /* not found go on */
                return ldb_next_request(module, req);
index 8eb7a7e9525a22f6663159cb12cd6e34c2010b48..c0de314ef187d24ee1fadfd596ca3135f29730de 100644 (file)
@@ -235,374 +235,6 @@ failed:
        return NULL;
 }
 
-struct ldb_control **parse_controls(void *mem_ctx, char **control_strings)
-{
-       int i;
-       struct ldb_control **ctrl;
-
-       if (control_strings == NULL || control_strings[0] == NULL)
-               return NULL;
-
-       for (i = 0; control_strings[i]; i++);
-
-       ctrl = talloc_array(mem_ctx, struct ldb_control *, i + 1);
-
-       for (i = 0; control_strings[i]; i++) {
-               if (strncmp(control_strings[i], "vlv:", 4) == 0) {
-                       struct ldb_vlv_req_control *control;
-                       const char *p;
-                       char attr[1024];
-                       char ctxid[1024];
-                       int crit, bc, ac, os, cc, ret;
-
-                       attr[0] = '\0';
-                       ctxid[0] = '\0';
-                       p = &(control_strings[i][4]);
-                       ret = sscanf(p, "%d:%d:%d:%d:%d:%1023[^$]", &crit, &bc, &ac, &os, &cc, ctxid);
-                       if (ret < 5) {
-                               ret = sscanf(p, "%d:%d:%d:%1023[^:]:%1023[^$]", &crit, &bc, &ac, attr, ctxid);
-                       }
-                              
-                       if ((ret < 4) || (crit < 0) || (crit > 1)) {
-                               fprintf(stderr, "invalid server_sort control syntax\n");
-                               fprintf(stderr, " syntax: crit(b):bc(n):ac(n):<os(n):cc(n)|attr(s)>[:ctxid(o)]\n");
-                               fprintf(stderr, "   note: b = boolean, n = number, s = string, o = b64 binary blob\n");
-                               return NULL;
-                       }
-                       if (!(ctrl[i] = talloc(ctrl, struct ldb_control))) {
-                               fprintf(stderr, "talloc failed\n");
-                               return NULL;
-                       }
-                       ctrl[i]->oid = LDB_CONTROL_VLV_REQ_OID;
-                       ctrl[i]->critical = crit;
-                       if (!(control = talloc(ctrl[i],
-                                              struct ldb_vlv_req_control))) {
-                               fprintf(stderr, "talloc failed\n");
-                               return NULL;
-                       }
-                       control->beforeCount = bc;
-                       control->afterCount = ac;
-                       if (attr[0]) {
-                               control->type = 1;
-                               control->match.gtOrEq.value = talloc_strdup(control, attr);
-                               control->match.gtOrEq.value_len = strlen(attr);
-                       } else {
-                               control->type = 0;
-                               control->match.byOffset.offset = os;
-                               control->match.byOffset.contentCount = cc;
-                       }
-                       if (ctxid[0]) {
-                               control->ctxid_len = ldb_base64_decode(ctxid);
-                               control->contextId = (char *)talloc_memdup(control, ctxid, control->ctxid_len);
-                       } else {
-                               control->ctxid_len = 0;
-                               control->contextId = NULL;
-                       }
-                       ctrl[i]->data = control;
-
-                       continue;
-               }
-
-               if (strncmp(control_strings[i], "dirsync:", 8) == 0) {
-                       struct ldb_dirsync_control *control;
-                       const char *p;
-                       char cookie[1024];
-                       int crit, flags, max_attrs, ret;
-                      
-                       cookie[0] = '\0';
-                       p = &(control_strings[i][8]);
-                       ret = sscanf(p, "%d:%d:%d:%1023[^$]", &crit, &flags, &max_attrs, cookie);
-
-                       if ((ret < 3) || (crit < 0) || (crit > 1) || (flags < 0) || (max_attrs < 0)) {
-                               fprintf(stderr, "invalid dirsync control syntax\n");
-                               fprintf(stderr, " syntax: crit(b):flags(n):max_attrs(n)[:cookie(o)]\n");
-                               fprintf(stderr, "   note: b = boolean, n = number, o = b64 binary blob\n");
-                               return NULL;
-                       }
-
-                       /* w2k3 seems to ignore the parameter,
-                        * but w2k sends a wrong cookie when this value is to small
-                        * this would cause looping forever, while getting
-                        * the same data and same cookie forever
-                        */
-                       if (max_attrs == 0) max_attrs = 0x0FFFFFFF;
-
-                       ctrl[i] = talloc(ctrl, struct ldb_control);
-                       ctrl[i]->oid = LDB_CONTROL_DIRSYNC_OID;
-                       ctrl[i]->critical = crit;
-                       control = talloc(ctrl[i], struct ldb_dirsync_control);
-                       control->flags = flags;
-                       control->max_attributes = max_attrs;
-                       if (*cookie) {
-                               control->cookie_len = ldb_base64_decode(cookie);
-                               control->cookie = (char *)talloc_memdup(control, cookie, control->cookie_len);
-                       } else {
-                               control->cookie = NULL;
-                               control->cookie_len = 0;
-                       }
-                       ctrl[i]->data = control;
-
-                       continue;
-               }
-
-               if (strncmp(control_strings[i], "asq:", 4) == 0) {
-                       struct ldb_asq_control *control;
-                       const char *p;
-                       char attr[256];
-                       int crit, ret;
-
-                       attr[0] = '\0';
-                       p = &(control_strings[i][4]);
-                       ret = sscanf(p, "%d:%255[^$]", &crit, attr);
-                       if ((ret != 2) || (crit < 0) || (crit > 1) || (attr[0] == '\0')) {
-                               fprintf(stderr, "invalid asq control syntax\n");
-                               fprintf(stderr, " syntax: crit(b):attr(s)\n");
-                               fprintf(stderr, "   note: b = boolean, s = string\n");
-                               return NULL;
-                       }
-
-                       ctrl[i] = talloc(ctrl, struct ldb_control);
-                       ctrl[i]->oid = LDB_CONTROL_ASQ_OID;
-                       ctrl[i]->critical = crit;
-                       control = talloc(ctrl[i], struct ldb_asq_control);
-                       control->request = 1;
-                       control->source_attribute = talloc_strdup(control, attr);
-                       control->src_attr_len = strlen(attr);
-                       ctrl[i]->data = control;
-
-                       continue;
-               }
-
-               if (strncmp(control_strings[i], "extended_dn:", 12) == 0) {
-                       struct ldb_extended_dn_control *control;
-                       const char *p;
-                       int crit, type, ret;
-
-                       p = &(control_strings[i][12]);
-                       ret = sscanf(p, "%d:%d", &crit, &type);
-                       if ((ret != 2) || (crit < 0) || (crit > 1) || (type < 0) || (type > 1)) {
-                               fprintf(stderr, "invalid extended_dn control syntax\n");
-                               fprintf(stderr, " syntax: crit(b):type(b)\n");
-                               fprintf(stderr, "   note: b = boolean\n");
-                               return NULL;
-                       }
-
-                       ctrl[i] = talloc(ctrl, struct ldb_control);
-                       ctrl[i]->oid = LDB_CONTROL_EXTENDED_DN_OID;
-                       ctrl[i]->critical = crit;
-                       control = talloc(ctrl[i], struct ldb_extended_dn_control);
-                       control->type = type;
-                       ctrl[i]->data = control;
-
-                       continue;
-               }
-
-               if (strncmp(control_strings[i], "sd_flags:", 9) == 0) {
-                       struct ldb_sd_flags_control *control;
-                       const char *p;
-                       int crit, ret;
-                       unsigned secinfo_flags;
-
-                       p = &(control_strings[i][9]);
-                       ret = sscanf(p, "%d:%u", &crit, &secinfo_flags);
-                       if ((ret != 2) || (crit < 0) || (crit > 1) || (secinfo_flags < 0) || (secinfo_flags > 0xF)) {
-                               fprintf(stderr, "invalid sd_flags control syntax\n");
-                               fprintf(stderr, " syntax: crit(b):secinfo_flags(n)\n");
-                               fprintf(stderr, "   note: b = boolean, n = number\n");
-                               return NULL;
-                       }
-
-                       ctrl[i] = talloc(ctrl, struct ldb_control);
-                       ctrl[i]->oid = LDB_CONTROL_SD_FLAGS_OID;
-                       ctrl[i]->critical = crit;
-                       control = talloc(ctrl[i], struct ldb_sd_flags_control);
-                       control->secinfo_flags = secinfo_flags;
-                       ctrl[i]->data = control;
-
-                       continue;
-               }
-
-               if (strncmp(control_strings[i], "search_options:", 15) == 0) {
-                       struct ldb_search_options_control *control;
-                       const char *p;
-                       int crit, ret;
-                       unsigned search_options;
-
-                       p = &(control_strings[i][15]);
-                       ret = sscanf(p, "%d:%u", &crit, &search_options);
-                       if ((ret != 2) || (crit < 0) || (crit > 1) || (search_options < 0) || (search_options > 0xF)) {
-                               fprintf(stderr, "invalid search_options control syntax\n");
-                               fprintf(stderr, " syntax: crit(b):search_options(n)\n");
-                               fprintf(stderr, "   note: b = boolean, n = number\n");
-                               return NULL;
-                       }
-
-                       ctrl[i] = talloc(ctrl, struct ldb_control);
-                       ctrl[i]->oid = LDB_CONTROL_SEARCH_OPTIONS_OID;
-                       ctrl[i]->critical = crit;
-                       control = talloc(ctrl[i], struct ldb_search_options_control);
-                       control->search_options = search_options;
-                       ctrl[i]->data = control;
-
-                       continue;
-               }
-
-               if (strncmp(control_strings[i], "domain_scope:", 13) == 0) {
-                       const char *p;
-                       int crit, ret;
-
-                       p = &(control_strings[i][13]);
-                       ret = sscanf(p, "%d", &crit);
-                       if ((ret != 1) || (crit < 0) || (crit > 1)) {
-                               fprintf(stderr, "invalid domain_scope control syntax\n");
-                               fprintf(stderr, " syntax: crit(b)\n");
-                               fprintf(stderr, "   note: b = boolean\n");
-                               return NULL;
-                       }
-
-                       ctrl[i] = talloc(ctrl, struct ldb_control);
-                       ctrl[i]->oid = LDB_CONTROL_DOMAIN_SCOPE_OID;
-                       ctrl[i]->critical = crit;
-                       ctrl[i]->data = NULL;
-
-                       continue;
-               }
-
-               if (strncmp(control_strings[i], "paged_results:", 14) == 0) {
-                       struct ldb_paged_control *control;
-                       const char *p;
-                       int crit, size, ret;
-                      
-                       p = &(control_strings[i][14]);
-                       ret = sscanf(p, "%d:%d", &crit, &size);
-
-                       if ((ret != 2) || (crit < 0) || (crit > 1) || (size < 0)) {
-                               fprintf(stderr, "invalid paged_results control syntax\n");
-                               fprintf(stderr, " syntax: crit(b):size(n)\n");
-                               fprintf(stderr, "   note: b = boolean, n = number\n");
-                               return NULL;
-                       }
-
-                       ctrl[i] = talloc(ctrl, struct ldb_control);
-                       ctrl[i]->oid = LDB_CONTROL_PAGED_RESULTS_OID;
-                       ctrl[i]->critical = crit;
-                       control = talloc(ctrl[i], struct ldb_paged_control);
-                       control->size = size;
-                       control->cookie = NULL;
-                       control->cookie_len = 0;
-                       ctrl[i]->data = control;
-
-                       continue;
-               }
-
-               if (strncmp(control_strings[i], "server_sort:", 12) == 0) {
-                       struct ldb_server_sort_control **control;
-                       const char *p;
-                       char attr[256];
-                       char rule[128];
-                       int crit, rev, ret;
-
-                       attr[0] = '\0';
-                       rule[0] = '\0';
-                       p = &(control_strings[i][12]);
-                       ret = sscanf(p, "%d:%d:%255[^:]:%127[^:]", &crit, &rev, attr, rule);
-                       if ((ret < 3) || (crit < 0) || (crit > 1) || (rev < 0 ) || (rev > 1) ||attr[0] == '\0') {
-                               fprintf(stderr, "invalid server_sort control syntax\n");
-                               fprintf(stderr, " syntax: crit(b):rev(b):attr(s)[:rule(s)]\n");
-                               fprintf(stderr, "   note: b = boolean, s = string\n");
-                               return NULL;
-                       }
-                       ctrl[i] = talloc(ctrl, struct ldb_control);
-                       ctrl[i]->oid = LDB_CONTROL_SERVER_SORT_OID;
-                       ctrl[i]->critical = crit;
-                       control = talloc_array(ctrl[i], struct ldb_server_sort_control *, 2);
-                       control[0] = talloc(control, struct ldb_server_sort_control);
-                       control[0]->attributeName = talloc_strdup(control, attr);
-                       if (rule[0])
-                               control[0]->orderingRule = talloc_strdup(control, rule);
-                       else
-                               control[0]->orderingRule = NULL;
-                       control[0]->reverse = rev;
-                       control[1] = NULL;
-                       ctrl[i]->data = control;
-
-                       continue;
-               }
-
-               if (strncmp(control_strings[i], "notification:", 13) == 0) {
-                       const char *p;
-                       int crit, ret;
-
-                       p = &(control_strings[i][13]);
-                       ret = sscanf(p, "%d", &crit);
-                       if ((ret != 1) || (crit < 0) || (crit > 1)) {
-                               fprintf(stderr, "invalid notification control syntax\n");
-                               fprintf(stderr, " syntax: crit(b)\n");
-                               fprintf(stderr, "   note: b = boolean\n");
-                               return NULL;
-                       }
-
-                       ctrl[i] = talloc(ctrl, struct ldb_control);
-                       ctrl[i]->oid = LDB_CONTROL_NOTIFICATION_OID;
-                       ctrl[i]->critical = crit;
-                       ctrl[i]->data = NULL;
-
-                       continue;
-               }
-
-               if (strncmp(control_strings[i], "show_deleted:", 13) == 0) {
-                       const char *p;
-                       int crit, ret;
-
-                       p = &(control_strings[i][13]);
-                       ret = sscanf(p, "%d", &crit);
-                       if ((ret != 1) || (crit < 0) || (crit > 1)) {
-                               fprintf(stderr, "invalid show_deleted control syntax\n");
-                               fprintf(stderr, " syntax: crit(b)\n");
-                               fprintf(stderr, "   note: b = boolean\n");
-                               return NULL;
-                       }
-
-                       ctrl[i] = talloc(ctrl, struct ldb_control);
-                       ctrl[i]->oid = LDB_CONTROL_SHOW_DELETED_OID;
-                       ctrl[i]->critical = crit;
-                       ctrl[i]->data = NULL;
-
-                       continue;
-               }
-
-               if (strncmp(control_strings[i], "permissive_modify:", 18) == 0) {
-                       const char *p;
-                       int crit, ret;
-
-                       p = &(control_strings[i][18]);
-                       ret = sscanf(p, "%d", &crit);
-                       if ((ret != 1) || (crit < 0) || (crit > 1)) {
-                               fprintf(stderr, "invalid permissive_modify control syntax\n");
-                               fprintf(stderr, " syntax: crit(b)\n");
-                               fprintf(stderr, "   note: b = boolean\n");
-                               return NULL;
-                       }
-
-                       ctrl[i] = talloc(ctrl, struct ldb_control);
-                       ctrl[i]->oid = LDB_CONTROL_PERMISSIVE_MODIFY_OID;
-                       ctrl[i]->critical = crit;
-                       ctrl[i]->data = NULL;
-
-                       continue;
-               }
-
-               /* no controls matched, throw an error */
-               fprintf(stderr, "Invalid control name: '%s'\n", control_strings[i]);
-               return NULL;
-       }
-
-       ctrl[i] = NULL;
-
-       return ctrl;
-}
-
-
 /* this function check controls reply and determines if more
  * processing is needed setting up the request controls correctly
  *
index 7bf9d64fc21705e67b732a1220f8c4206fae3a23..e5b9091b5cc806b4f3e4e35afda35d687b2454aa 100644 (file)
@@ -202,8 +202,11 @@ static int do_search(struct ldb_context *ldb,
        sctx->sort = options->sorted;
        sctx->num_stored = 0;
        sctx->store = NULL;
-       sctx->req_ctrls = parse_controls(ldb, options->controls);
-       if (options->controls != NULL &&  sctx->req_ctrls== NULL) return -1;
+       sctx->req_ctrls = ldb_parse_control_strings(ldb, sctx, (const char **)options->controls);
+       if (options->controls != NULL &&  sctx->req_ctrls== NULL) {
+               printf("parsing controls failed: %s\n", ldb_errstring(ldb));
+               return -1;
+       }
        sctx->entries = 0;
        sctx->refs = 0;
 
index fc44862985b9d5b82271a30fd41c18a9b02b9b1e..3f970cea58e902a18ba4d7bb8110ebdc44961544 100644 (file)
@@ -49,6 +49,7 @@ static struct ldb_context *ejs_get_ldb_context(int eid)
      ldb.search("expression", attrs);
      var basedn = "cn=this,dc=is,dc=a,dc=test";
      ldb.search("expression", basedn, ldb.SCOPE_SUBTREE, attrs);
+     ldb.search("expression", basedn, ldb.SCOPE_SUBTREE, attrs, controls);
 */
 static int ejs_ldbSearch(MprVarHandle eid, int argc, struct MprVar **argv)
 {
@@ -60,10 +61,12 @@ static int ejs_ldbSearch(MprVarHandle eid, int argc, struct MprVar **argv)
        TALLOC_CTX *tmp_ctx = talloc_new(mprMemCtx());
        struct ldb_context *ldb;
        int ret;
+       struct ldb_control **parsed_controls = NULL;
        struct ldb_result *res=NULL;
+       struct ldb_request *req;
 
        /* validate arguments */
-       if (argc < 1 || argc > 4) {
+       if (argc < 1 || argc > 5) {
                ejsSetErrorMsg(eid, "ldb.search invalid number of arguments");
                goto failed;
        }
@@ -88,6 +91,8 @@ static int ejs_ldbSearch(MprVarHandle eid, int argc, struct MprVar **argv)
                        ejsSetErrorMsg(eid, "ldb.search malformed base dn");
                        goto failed;
                }
+       } else {
+               basedn = ldb_get_default_basedn(ldb);
        }
        if (argc > 2) {
                scope = mprToInt(argv[2]);
@@ -105,14 +110,51 @@ static int ejs_ldbSearch(MprVarHandle eid, int argc, struct MprVar **argv)
        if (argc > 3) {
                attrs = mprToList(tmp_ctx, argv[3]);
        }
-       ret = ldb_search(ldb, basedn, scope, expression, attrs, &res);
+       if (argc > 4) {
+               const char **controls;
+               controls = mprToList(tmp_ctx, argv[4]);
+               if (controls) {
+                       parsed_controls = ldb_parse_control_strings(ldb, tmp_ctx, controls);
+                       if (!parsed_controls) {
+                               ejsSetErrorMsg(eid, "ldb.search cannot parse controls: %s", 
+                                              ldb_errstring(ldb));
+                               goto failed;
+                       }
+               }
+       }
+
+       res = talloc_zero(tmp_ctx, struct ldb_result);
+       if (!res) {
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+
+       ret = ldb_build_search_req(&req, ldb, tmp_ctx,
+                                  basedn,
+                                  scope,
+                                  expression,
+                                  attrs,
+                                  parsed_controls,
+                                  res,
+                                  ldb_search_default_callback);
+
+       if (ret == LDB_SUCCESS) {
+
+               ldb_set_timeout(ldb, req, 0); /* use default timeout */
+               
+               ret = ldb_request(ldb, req);
+               
+               if (ret == LDB_SUCCESS) {
+                       ret = ldb_wait(req->handle, LDB_WAIT_ALL);
+               }
+       }
+
        if (ret != LDB_SUCCESS) {
                ejsSetErrorMsg(eid, "ldb.search failed - %s", ldb_errstring(ldb));
                mpr_Return(eid, mprLdbResult(ldb, ret, NULL));
        } else {
                mpr_Return(eid, mprLdbResult(ldb, ret, res));
-               talloc_free(res);
        }
+
        talloc_free(tmp_ctx);
        return 0;
 
index 67eb28f6e3015c485927fa7fb4f11c1e4b415b2b..9fab283b70a75b34c6ffa0ede1ffb132440c4d03 100755 (executable)
@@ -218,6 +218,18 @@ objectClass: user
                assert(res.msgs[0].dn == res3gc.msgs[0].dn);
        }
 
+       println("Testing ldb.search for (&(cn=ldaptestuser)(objectCategory=PerSon)) in with 'phantom root' control");
+       var attrs = new Array("cn");
+       var controls = new Array("search_options:1:2");
+       var res3control = gc_ldb.search("(&(cn=ldaptestuser)(objectCategory=PerSon))", base_dn, ldb.SCOPE_SUBTREE, attrs, controls);
+       if (res3control.error != 0 || res3control.msgs.length != 1) {
+               println("Could not find (&(cn=ldaptestuser)(objectCategory=PerSon)) in Global Catalog");
+               assert(res3control.error == 0);
+               assert(res3control.msgs.length == 1);
+       }
+       
+       assert(res.msgs[0].dn == res3control.msgs[0].dn);
+
        ok = ldb.del(res.msgs[0].dn);
        if (ok.error != 0) {
                println(ok.errstr);
@@ -414,7 +426,21 @@ objectClass: user
        assert(res.error == 0);
        assert(res.msgs.length == 0);
 
+       println("Testing that we can get at the configuration DN from the main search base on the LDAP port with the 'phantom root' search_options control");
+       var attrs = new Array("cn");
+       var controls = new Array("search_options:1:2");
+       var res = ldb.search("objectClass=crossRef", base_dn, ldb.SCOPE_SUBTREE, attrs, controls);
+       assert(res.error == 0);
+       assert(res.msgs.length > 0);
+
        if (gc_ldb != undefined) {
+               println("Testing that we can get at the configuration DN from the main search base on the GC port with the search_options control == 0");
+               var attrs = new Array("cn");
+               var controls = new Array("search_options:1:0");
+               var res = gc_ldb.search("objectClass=crossRef", base_dn, gc_ldb.SCOPE_SUBTREE, attrs, controls);
+               assert(res.error == 0);
+               assert(res.msgs.length > 0);
+
                println("Testing that we do find configuration elements in the global catlog");
                var attrs = new Array("cn");
                var res = gc_ldb.search("objectClass=crossRef", base_dn, ldb.SCOPE_SUBTREE, attrs);