r12745: Initial work to support a syntax to pass over controls via
authorSimo Sorce <idra@samba.org>
Fri, 6 Jan 2006 19:42:08 +0000 (19:42 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:49:48 +0000 (13:49 -0500)
command line to ldbsearch. Very rough work, no checks are
done on the input yet (will segfault if you make it wrong).
Controls are passed via the --controls switch an are comma
separated (no escaping yet).

General syntax is <ctrl_name>:<criticality>
<ctrl_name> is a string
<criticality> is 1 or 0

Current semi-parsed controls are:

server_sort
syntax: server_sort:1:0:attributename

1st parm: criticality
2nd parm: reversed
3rd parm: attribute name to be used for sorting

todo: still missing suport for multiple sorting
  attributes and ordering rule
no check on result code

paged_results
syntax: paged_results:1:100

1st parm: criticality
2nd parm: number of results to be returned

todo: ldbsearch will return only the first batch
  (missing code to cycle over conditionally)
no check on result code

extended_dn
syntax: extended_dn:1:0

1st parm: criticality
2nd parm: type, see MS docs on meaning

Simo.

source/lib/ldb/tools/cmdline.c
source/lib/ldb/tools/cmdline.h
source/lib/ldb/tools/ldbsearch.c
source/setup/provision_init.ldif

index c134c3befd1657735bef44a392961fc7beb4bba4..bac444fe75c2e6fbf68f904273f66f68b6b5ba72 100644 (file)
@@ -62,6 +62,7 @@ struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb, int argc, const
                { "input", 'I', POPT_ARG_STRING, &options.input, 0, "Input File", "Input" },
                { "output", 'O', POPT_ARG_STRING, &options.output, 0, "Output File", "Output" },
                { NULL,    'o', POPT_ARG_STRING, NULL, 'o', "ldb_connect option", "OPTION" },
+               { "controls", 0, POPT_ARG_STRING, NULL, 'c', "controls", NULL },
 #ifdef _SAMBA_BUILD_
                POPT_COMMON_SAMBA
                POPT_COMMON_CREDENTIALS
@@ -137,7 +138,35 @@ struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb, int argc, const
                        options.options[num_options+1] = NULL;
                        num_options++;
                        break;
-                       
+
+               case 'c': {
+                       const char *cs = poptGetOptArg(pc);
+                       const char *p;
+                       int cc;
+
+                       for (p = cs, cc = 1; p = strchr(p, ','); cc++) ;
+
+                       options.controls = talloc_array(ret, char *, cc + 1);
+                       if (options.controls == NULL) {
+                               ldb_oom(ldb);
+                               goto failed;
+                       }
+                       for (p = cs, cc = 0; p != NULL; cc++) {
+                               const char *t;
+
+                               t = strchr(p, ',');
+                               if (t == NULL) {
+                                       options.controls[cc] = talloc_strdup(options.controls, p);
+                                       p = NULL;
+                               } else {
+                                       options.controls[cc] = talloc_strndup(options.controls, p, t-p);
+                                       p = t + 1;
+                               }
+                       }
+                       options.controls[cc + 1] = NULL;
+
+                       break;    
+               }
                default:
                        fprintf(stderr, "Invalid option %s: %s\n", 
                                poptBadOption(pc, 0), poptStrerror(opt));
index 9aaf37a9781b2b78d2c63633b7b15008eb6612be..3b195f3e844b829415d11d523307f5b4afb5c990 100644 (file)
@@ -43,6 +43,7 @@ struct ldb_cmdline {
        const char *sasl_mechanism;
        const char *input;
        const char *output;
+       char **controls;
 };
 
 struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb, int argc, const char **argv,
index a340e16d08c835a5206660055d6815f3f8225443..406c81f765658367a3b3df3c7eaff39dc17b6d1e 100644 (file)
@@ -64,25 +64,93 @@ static int do_compare_msg(struct ldb_message **el1,
        return ldb_dn_compare(ldb, (*el1)->dn, (*el2)->dn);
 }
 
+static 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], "extended_dn:", 12) == 0) {
+                       struct ldb_extended_dn_control *control;
+
+                       ctrl[i] = talloc(ctrl, struct ldb_control);
+                       ctrl[i]->oid = LDB_CONTROL_EXTENDED_DN_OID;
+                       ctrl[i]->critical = control_strings[i][12]=='1'?1:0;
+                       control = talloc(ctrl[i], struct ldb_extended_dn_control);
+                       control->type = atoi(&control_strings[i][14]);
+                       ctrl[i]->data = control;
+               }
+
+               if (strncmp(control_strings[i], "paged_results:", 14) == 0) {
+                       struct ldb_paged_control *control;
+
+                       ctrl[i] = talloc(ctrl, struct ldb_control);
+                       ctrl[i]->oid = LDB_CONTROL_PAGED_RESULTS_OID;
+                       ctrl[i]->critical = control_strings[i][14]=='1'?1:0;
+                       control = talloc(ctrl[i], struct ldb_paged_control);
+                       control->size = atoi(&control_strings[i][16]);
+                       control->cookie = NULL;
+                       control->cookie_len = 0;
+                       ctrl[i]->data = control;
+               }
+
+               if (strncmp(control_strings[i], "server_sort:", 12) == 0) {
+                       struct ldb_server_sort_control **control;
+
+                       ctrl[i] = talloc(ctrl, struct ldb_control);
+                       ctrl[i]->oid = LDB_CONTROL_SERVER_SORT_OID;
+                       ctrl[i]->critical = control_strings[i][12]=='1'?1:0;
+                       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, &control_strings[i][16]);
+                       control[0]->orderingRule = NULL;
+                       control[0]->reverse = control_strings[i][14]=='1'?1:0;
+                       control[1] = NULL;
+                       ctrl[i]->data = control;
+               }
+       }
+
+       ctrl[i + 1] = NULL;
+
+       return ctrl;
+}
+
 static int do_search(struct ldb_context *ldb,
                     const struct ldb_dn *basedn,
-                    int scope,
-                     int sort_attribs,
+                    struct ldb_cmdline *options,
                     const char *expression,
                     const char * const *attrs)
 {
        int ret, i;
+       struct ldb_request req;
        struct ldb_result *result = NULL;
 
-       ret = ldb_search(ldb, basedn, scope, expression, attrs, &result);
+       req.operation = LDB_REQ_SEARCH;
+       req.op.search.base = basedn;
+       req.op.search.scope = options->scope;
+       req.op.search.tree = ldb_parse_tree(ldb, expression);
+       req.op.search.attrs = attrs;
+       req.op.search.res = NULL;
+       req.controls = parse_controls(ldb, options->controls);
+       req.creds = NULL;
+
+       ret = ldb_request(ldb, &req);
        if (ret != LDB_SUCCESS) {
                printf("search failed - %s\n", ldb_errstring(ldb));
                return -1;
        }
 
+       result = req.op.search.res;
        printf("# returned %d records\n", ret);
 
-       if (sort_attribs) {
+       if (options->sorted) {
                ldb_qsort(result->msgs, ret, sizeof(struct ldb_message *),
                          ldb, (ldb_qsort_cmp_fn_t)do_compare_msg);
        }
@@ -94,7 +162,7 @@ static int do_search(struct ldb_context *ldb,
                ldif.changetype = LDB_CHANGETYPE_NONE;
                ldif.msg = result->msgs[i];
 
-                if (sort_attribs) {
+                if (options->sorted) {
                         /*
                          * Ensure attributes are always returned in the same
                          * order.  For testing, this makes comparison of old
@@ -154,14 +222,12 @@ static int do_search(struct ldb_context *ldb,
        if (options->interactive) {
                char line[1024];
                while (fgets(line, sizeof(line), stdin)) {
-                       if (do_search(ldb, basedn, 
-                                     options->scope, options->sorted, line, attrs) == -1) {
+                       if (do_search(ldb, basedn, options, line, attrs) == -1) {
                                ret = -1;
                        }
                }
        } else {
-               ret = do_search(ldb, basedn, options->scope, options->sorted, 
-                               expression, attrs);
+               ret = do_search(ldb, basedn, options, expression, attrs);
        }
 
        talloc_free(ldb);
index cac851e97bd3ed45f97a257a2ef87de2ab4156fa..6d452a17e7bbb99afcf658eff04c0697b412bdd7 100644 (file)
@@ -69,5 +69,5 @@ isSynchronized: TRUE
 #Add modules to the list to activate them by default
 #beware often order is important
 dn: @MODULES
-@LIST: rootdse,samldb,password_hash,operational,objectguid,rdn_name,objectclass
+@LIST: rootdse,paged_results,server_sort,extended_dn,samldb,password_hash,operational,objectguid,rdn_name,objectclass