root/source3/lib/ldb/tools/cmdline.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ldb_cmdline_process
  2. parse_controls
  3. handle_controls_reply

   1 /* 
   2    ldb database library - command line handling for ldb tools
   3 
   4    Copyright (C) Andrew Tridgell  2005
   5 
   6      ** NOTE! The following LGPL license applies to the ldb
   7      ** library. This does NOT imply that all of Samba is released
   8      ** under the LGPL
   9    
  10    This library is free software; you can redistribute it and/or
  11    modify it under the terms of the GNU Lesser General Public
  12    License as published by the Free Software Foundation; either
  13    version 3 of the License, or (at your option) any later version.
  14 
  15    This library is distributed in the hope that it will be useful,
  16    but WITHOUT ANY WARRANTY; without even the implied warranty of
  17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  18    Lesser General Public License for more details.
  19 
  20    You should have received a copy of the GNU Lesser General Public
  21    License along with this library; if not, see <http://www.gnu.org/licenses/>.
  22 */
  23 
  24 #include "includes.h"
  25 #include "ldb/include/includes.h"
  26 #include "ldb/tools/cmdline.h"
  27 
  28 #if (_SAMBA_BUILD_ >= 4)
  29 #include "lib/cmdline/popt_common.h"
  30 #include "lib/ldb/samba/ldif_handlers.h"
  31 #include "auth/gensec/gensec.h"
  32 #include "auth/auth.h"
  33 #include "db_wrap.h"
  34 #endif
  35 
  36 
  37 
  38 /*
  39   process command line options
  40 */
  41 struct ldb_cmdline *ldb_cmdline_process(struct ldb_context *ldb, int argc, const char **argv,
     /* [<][>][^][v][top][bottom][index][help] */
  42                                         void (*usage)(void))
  43 {
  44         static struct ldb_cmdline options; /* needs to be static for older compilers */
  45         struct ldb_cmdline *ret=NULL;
  46         poptContext pc;
  47 #if (_SAMBA_BUILD_ >= 4)
  48         int r;
  49 #endif
  50         int num_options = 0;
  51         int opt;
  52         int flags = 0;
  53 
  54         struct poptOption popt_options[] = {
  55                 POPT_AUTOHELP
  56                 { "url",       'H', POPT_ARG_STRING, &options.url, 0, "database URL", "URL" },
  57                 { "basedn",    'b', POPT_ARG_STRING, &options.basedn, 0, "base DN", "DN" },
  58                 { "editor",    'e', POPT_ARG_STRING, &options.editor, 0, "external editor", "PROGRAM" },
  59                 { "scope",     's', POPT_ARG_STRING, NULL, 's', "search scope", "SCOPE" },
  60                 { "verbose",   'v', POPT_ARG_NONE, NULL, 'v', "increase verbosity", NULL },
  61                 { "interactive", 'i', POPT_ARG_NONE, &options.interactive, 0, "input from stdin", NULL },
  62                 { "recursive", 'r', POPT_ARG_NONE, &options.recursive, 0, "recursive delete", NULL },
  63                 { "num-searches", 0, POPT_ARG_INT, &options.num_searches, 0, "number of test searches", NULL },
  64                 { "num-records", 0, POPT_ARG_INT, &options.num_records, 0, "number of test records", NULL },
  65                 { "all", 'a',    POPT_ARG_NONE, &options.all_records, 0, "(|(objectClass=*)(distinguishedName=*))", NULL },
  66                 { "nosync", 0,   POPT_ARG_NONE, &options.nosync, 0, "non-synchronous transactions", NULL },
  67                 { "sorted", 'S', POPT_ARG_NONE, &options.sorted, 0, "sort attributes", NULL },
  68                 { "sasl-mechanism", 0, POPT_ARG_STRING, &options.sasl_mechanism, 0, "choose SASL mechanism", "MECHANISM" },
  69                 { "input", 'I', POPT_ARG_STRING, &options.input, 0, "Input File", "Input" },
  70                 { "output", 'O', POPT_ARG_STRING, &options.output, 0, "Output File", "Output" },
  71                 { NULL,    'o', POPT_ARG_STRING, NULL, 'o', "ldb_connect option", "OPTION" },
  72                 { "controls", 0, POPT_ARG_STRING, NULL, 'c', "controls", NULL },
  73 #if (_SAMBA_BUILD_ >= 4)
  74                 POPT_COMMON_SAMBA
  75                 POPT_COMMON_CREDENTIALS
  76                 POPT_COMMON_VERSION
  77 #endif
  78                 { NULL }
  79         };
  80 
  81         ldb_global_init();
  82 
  83 #if (_SAMBA_BUILD_ >= 4)
  84         r = ldb_register_samba_handlers(ldb);
  85         if (r != 0) {
  86                 goto failed;
  87         }
  88 
  89 #endif
  90 
  91         ret = talloc_zero(ldb, struct ldb_cmdline);
  92         if (ret == NULL) {
  93                 ldb_oom(ldb);
  94                 goto failed;
  95         }
  96 
  97         options = *ret;
  98         
  99         /* pull in URL */
 100         options.url = getenv("LDB_URL");
 101 
 102         /* and editor (used by ldbedit) */
 103         options.editor = getenv("VISUAL");
 104         if (!options.editor) {
 105                 options.editor = getenv("EDITOR");
 106         }
 107         if (!options.editor) {
 108                 options.editor = "vi";
 109         }
 110 
 111         options.scope = LDB_SCOPE_DEFAULT;
 112 
 113         pc = poptGetContext(argv[0], argc, argv, popt_options, 
 114                             POPT_CONTEXT_KEEP_FIRST);
 115 
 116         while((opt = poptGetNextOpt(pc)) != -1) {
 117                 switch (opt) {
 118                 case 's': {
 119                         const char *arg = poptGetOptArg(pc);
 120                         if (strcmp(arg, "base") == 0) {
 121                                 options.scope = LDB_SCOPE_BASE;
 122                         } else if (strcmp(arg, "sub") == 0) {
 123                                 options.scope = LDB_SCOPE_SUBTREE;
 124                         } else if (strcmp(arg, "one") == 0) {
 125                                 options.scope = LDB_SCOPE_ONELEVEL;
 126                         } else {
 127                                 fprintf(stderr, "Invalid scope '%s'\n", arg);
 128                                 goto failed;
 129                         }
 130                         break;
 131                 }
 132 
 133                 case 'v':
 134                         options.verbose++;
 135                         break;
 136 
 137                 case 'o':
 138                         options.options = talloc_realloc(ret, options.options, 
 139                                                          const char *, num_options+3);
 140                         if (options.options == NULL) {
 141                                 ldb_oom(ldb);
 142                                 goto failed;
 143                         }
 144                         options.options[num_options] = poptGetOptArg(pc);
 145                         options.options[num_options+1] = NULL;
 146                         num_options++;
 147                         break;
 148 
 149                 case 'c': {
 150                         const char *cs = poptGetOptArg(pc);
 151                         const char *p, *q;
 152                         int cc;
 153 
 154                         for (p = cs, cc = 1; (q = strchr(p, ',')); cc++, p = q + 1) ;
 155 
 156                         options.controls = talloc_array(ret, char *, cc + 1);
 157                         if (options.controls == NULL) {
 158                                 ldb_oom(ldb);
 159                                 goto failed;
 160                         }
 161                         for (p = cs, cc = 0; p != NULL; cc++) {
 162                                 const char *t;
 163 
 164                                 t = strchr(p, ',');
 165                                 if (t == NULL) {
 166                                         options.controls[cc] = talloc_strdup(options.controls, p);
 167                                         p = NULL;
 168                                 } else {
 169                                         options.controls[cc] = talloc_strndup(options.controls, p, t-p);
 170                                         p = t + 1;
 171                                 }
 172                         }
 173                         options.controls[cc] = NULL;
 174 
 175                         break;    
 176                 }
 177                 default:
 178                         fprintf(stderr, "Invalid option %s: %s\n", 
 179                                 poptBadOption(pc, 0), poptStrerror(opt));
 180                         if (usage) usage();
 181                         goto failed;
 182                 }
 183         }
 184 
 185         /* setup the remaining options for the main program to use */
 186         options.argv = poptGetArgs(pc);
 187         if (options.argv) {
 188                 options.argv++;
 189                 while (options.argv[options.argc]) options.argc++;
 190         }
 191 
 192         *ret = options;
 193 
 194         /* all utils need some option */
 195         if (ret->url == NULL) {
 196                 fprintf(stderr, "You must supply a url with -H or with $LDB_URL\n");
 197                 if (usage) usage();
 198                 goto failed;
 199         }
 200 
 201         if (strcmp(ret->url, "NONE") == 0) {
 202                 return ret;
 203         }
 204 
 205         if (options.nosync) {
 206                 flags |= LDB_FLG_NOSYNC;
 207         }
 208 
 209 #if (_SAMBA_BUILD_ >= 4)
 210         /* Must be after we have processed command line options */
 211         gensec_init(); 
 212         
 213         if (ldb_set_opaque(ldb, "sessionInfo", system_session(ldb))) {
 214                 goto failed;
 215         }
 216         if (ldb_set_opaque(ldb, "credentials", cmdline_credentials)) {
 217                 goto failed;
 218         }
 219         ldb_set_utf8_fns(ldb, NULL, wrap_casefold);
 220 #endif
 221 
 222         /* now connect to the ldb */
 223         if (ldb_connect(ldb, ret->url, flags, ret->options) != 0) {
 224                 fprintf(stderr, "Failed to connect to %s - %s\n", 
 225                         ret->url, ldb_errstring(ldb));
 226                 goto failed;
 227         }
 228 
 229         return ret;
 230 
 231 failed:
 232         talloc_free(ret);
 233         exit(1);
 234         return NULL;
 235 }
 236 
 237 struct ldb_control **parse_controls(void *mem_ctx, char **control_strings)
     /* [<][>][^][v][top][bottom][index][help] */
 238 {
 239         int i;
 240         struct ldb_control **ctrl;
 241 
 242         if (control_strings == NULL || control_strings[0] == NULL)
 243                 return NULL;
 244 
 245         for (i = 0; control_strings[i]; i++);
 246 
 247         ctrl = talloc_array(mem_ctx, struct ldb_control *, i + 1);
 248 
 249         for (i = 0; control_strings[i]; i++) {
 250                 if (strncmp(control_strings[i], "vlv:", 4) == 0) {
 251                         struct ldb_vlv_req_control *control;
 252                         const char *p;
 253                         char attr[1024];
 254                         char ctxid[1024];
 255                         int crit, bc, ac, os, cc, ret;
 256 
 257                         attr[0] = '\0';
 258                         ctxid[0] = '\0';
 259                         p = &(control_strings[i][4]);
 260                         ret = sscanf(p, "%d:%d:%d:%d:%d:%1023[^$]", &crit, &bc, &ac, &os, &cc, ctxid);
 261                         if (ret < 5) {
 262                                 ret = sscanf(p, "%d:%d:%d:%1023[^:]:%1023[^$]", &crit, &bc, &ac, attr, ctxid);
 263                         }
 264                                
 265                         if ((ret < 4) || (crit < 0) || (crit > 1)) {
 266                                 fprintf(stderr, "invalid server_sort control syntax\n");
 267                                 fprintf(stderr, " syntax: crit(b):bc(n):ac(n):<os(n):cc(n)|attr(s)>[:ctxid(o)]\n");
 268                                 fprintf(stderr, "   note: b = boolean, n = number, s = string, o = b64 binary blob\n");
 269                                 return NULL;
 270                         }
 271                         if (!(ctrl[i] = talloc(ctrl, struct ldb_control))) {
 272                                 fprintf(stderr, "talloc failed\n");
 273                                 return NULL;
 274                         }
 275                         ctrl[i]->oid = LDB_CONTROL_VLV_REQ_OID;
 276                         ctrl[i]->critical = crit;
 277                         if (!(control = talloc(ctrl[i],
 278                                                struct ldb_vlv_req_control))) {
 279                                 fprintf(stderr, "talloc failed\n");
 280                                 return NULL;
 281                         }
 282                         control->beforeCount = bc;
 283                         control->afterCount = ac;
 284                         if (attr[0]) {
 285                                 control->type = 1;
 286                                 control->match.gtOrEq.value = talloc_strdup(control, attr);
 287                                 control->match.gtOrEq.value_len = strlen(attr);
 288                         } else {
 289                                 control->type = 0;
 290                                 control->match.byOffset.offset = os;
 291                                 control->match.byOffset.contentCount = cc;
 292                         }
 293                         if (ctxid[0]) {
 294                                 control->ctxid_len = ldb_base64_decode(ctxid);
 295                                 control->contextId = (char *)talloc_memdup(control, ctxid, control->ctxid_len);
 296                         } else {
 297                                 control->ctxid_len = 0;
 298                                 control->contextId = NULL;
 299                         }
 300                         ctrl[i]->data = control;
 301 
 302                         continue;
 303                 }
 304 
 305                 if (strncmp(control_strings[i], "dirsync:", 8) == 0) {
 306                         struct ldb_dirsync_control *control;
 307                         const char *p;
 308                         char cookie[1024];
 309                         int crit, flags, max_attrs, ret;
 310                        
 311                         cookie[0] = '\0';
 312                         p = &(control_strings[i][8]);
 313                         ret = sscanf(p, "%d:%d:%d:%1023[^$]", &crit, &flags, &max_attrs, cookie);
 314 
 315                         if ((ret < 3) || (crit < 0) || (crit > 1) || (flags < 0) || (max_attrs < 0)) {
 316                                 fprintf(stderr, "invalid dirsync control syntax\n");
 317                                 fprintf(stderr, " syntax: crit(b):flags(n):max_attrs(n)[:cookie(o)]\n");
 318                                 fprintf(stderr, "   note: b = boolean, n = number, o = b64 binary blob\n");
 319                                 return NULL;
 320                         }
 321 
 322                         /* w2k3 seems to ignore the parameter,
 323                          * but w2k sends a wrong cookie when this value is to small
 324                          * this would cause looping forever, while getting
 325                          * the same data and same cookie forever
 326                          */
 327                         if (max_attrs == 0) max_attrs = 0x0FFFFFFF;
 328 
 329                         ctrl[i] = talloc(ctrl, struct ldb_control);
 330                         ctrl[i]->oid = LDB_CONTROL_DIRSYNC_OID;
 331                         ctrl[i]->critical = crit;
 332                         control = talloc(ctrl[i], struct ldb_dirsync_control);
 333                         control->flags = flags;
 334                         control->max_attributes = max_attrs;
 335                         if (*cookie) {
 336                                 control->cookie_len = ldb_base64_decode(cookie);
 337                                 control->cookie = (char *)talloc_memdup(control, cookie, control->cookie_len);
 338                         } else {
 339                                 control->cookie = NULL;
 340                                 control->cookie_len = 0;
 341                         }
 342                         ctrl[i]->data = control;
 343 
 344                         continue;
 345                 }
 346 
 347                 if (strncmp(control_strings[i], "asq:", 4) == 0) {
 348                         struct ldb_asq_control *control;
 349                         const char *p;
 350                         char attr[256];
 351                         int crit, ret;
 352 
 353                         attr[0] = '\0';
 354                         p = &(control_strings[i][4]);
 355                         ret = sscanf(p, "%d:%255[^$]", &crit, attr);
 356                         if ((ret != 2) || (crit < 0) || (crit > 1) || (attr[0] == '\0')) {
 357                                 fprintf(stderr, "invalid asq control syntax\n");
 358                                 fprintf(stderr, " syntax: crit(b):attr(s)\n");
 359                                 fprintf(stderr, "   note: b = boolean, s = string\n");
 360                                 return NULL;
 361                         }
 362 
 363                         ctrl[i] = talloc(ctrl, struct ldb_control);
 364                         ctrl[i]->oid = LDB_CONTROL_ASQ_OID;
 365                         ctrl[i]->critical = crit;
 366                         control = talloc(ctrl[i], struct ldb_asq_control);
 367                         control->request = 1;
 368                         control->source_attribute = talloc_strdup(control, attr);
 369                         control->src_attr_len = strlen(attr);
 370                         ctrl[i]->data = control;
 371 
 372                         continue;
 373                 }
 374 
 375                 if (strncmp(control_strings[i], "extended_dn:", 12) == 0) {
 376                         struct ldb_extended_dn_control *control;
 377                         const char *p;
 378                         int crit, type, ret;
 379 
 380                         p = &(control_strings[i][12]);
 381                         ret = sscanf(p, "%d:%d", &crit, &type);
 382                         if ((ret != 2) || (crit < 0) || (crit > 1) || (type < 0) || (type > 1)) {
 383                                 fprintf(stderr, "invalid extended_dn control syntax\n");
 384                                 fprintf(stderr, " syntax: crit(b):type(b)\n");
 385                                 fprintf(stderr, "   note: b = boolean\n");
 386                                 return NULL;
 387                         }
 388 
 389                         ctrl[i] = talloc(ctrl, struct ldb_control);
 390                         ctrl[i]->oid = LDB_CONTROL_EXTENDED_DN_OID;
 391                         ctrl[i]->critical = crit;
 392                         control = talloc(ctrl[i], struct ldb_extended_dn_control);
 393                         control->type = type;
 394                         ctrl[i]->data = control;
 395 
 396                         continue;
 397                 }
 398 
 399                 if (strncmp(control_strings[i], "sd_flags:", 9) == 0) {
 400                         struct ldb_sd_flags_control *control;
 401                         const char *p;
 402                         int crit, ret;
 403                         unsigned secinfo_flags;
 404 
 405                         p = &(control_strings[i][9]);
 406                         ret = sscanf(p, "%d:%u", &crit, &secinfo_flags);
 407                         if ((ret != 2) || (crit < 0) || (crit > 1) || (secinfo_flags < 0) || (secinfo_flags > 0xF)) {
 408                                 fprintf(stderr, "invalid sd_flags control syntax\n");
 409                                 fprintf(stderr, " syntax: crit(b):secinfo_flags(n)\n");
 410                                 fprintf(stderr, "   note: b = boolean, n = number\n");
 411                                 return NULL;
 412                         }
 413 
 414                         ctrl[i] = talloc(ctrl, struct ldb_control);
 415                         ctrl[i]->oid = LDB_CONTROL_SD_FLAGS_OID;
 416                         ctrl[i]->critical = crit;
 417                         control = talloc(ctrl[i], struct ldb_sd_flags_control);
 418                         control->secinfo_flags = secinfo_flags;
 419                         ctrl[i]->data = control;
 420 
 421                         continue;
 422                 }
 423 
 424                 if (strncmp(control_strings[i], "search_options:", 15) == 0) {
 425                         struct ldb_search_options_control *control;
 426                         const char *p;
 427                         int crit, ret;
 428                         unsigned search_options;
 429 
 430                         p = &(control_strings[i][15]);
 431                         ret = sscanf(p, "%d:%u", &crit, &search_options);
 432                         if ((ret != 2) || (crit < 0) || (crit > 1) || (search_options < 0) || (search_options > 0xF)) {
 433                                 fprintf(stderr, "invalid search_options control syntax\n");
 434                                 fprintf(stderr, " syntax: crit(b):search_options(n)\n");
 435                                 fprintf(stderr, "   note: b = boolean, n = number\n");
 436                                 return NULL;
 437                         }
 438 
 439                         ctrl[i] = talloc(ctrl, struct ldb_control);
 440                         ctrl[i]->oid = LDB_CONTROL_SEARCH_OPTIONS_OID;
 441                         ctrl[i]->critical = crit;
 442                         control = talloc(ctrl[i], struct ldb_search_options_control);
 443                         control->search_options = search_options;
 444                         ctrl[i]->data = control;
 445 
 446                         continue;
 447                 }
 448 
 449                 if (strncmp(control_strings[i], "domain_scope:", 13) == 0) {
 450                         const char *p;
 451                         int crit, ret;
 452 
 453                         p = &(control_strings[i][13]);
 454                         ret = sscanf(p, "%d", &crit);
 455                         if ((ret != 1) || (crit < 0) || (crit > 1)) {
 456                                 fprintf(stderr, "invalid domain_scope control syntax\n");
 457                                 fprintf(stderr, " syntax: crit(b)\n");
 458                                 fprintf(stderr, "   note: b = boolean\n");
 459                                 return NULL;
 460                         }
 461 
 462                         ctrl[i] = talloc(ctrl, struct ldb_control);
 463                         ctrl[i]->oid = LDB_CONTROL_DOMAIN_SCOPE_OID;
 464                         ctrl[i]->critical = crit;
 465                         ctrl[i]->data = NULL;
 466 
 467                         continue;
 468                 }
 469 
 470                 if (strncmp(control_strings[i], "paged_results:", 14) == 0) {
 471                         struct ldb_paged_control *control;
 472                         const char *p;
 473                         int crit, size, ret;
 474                        
 475                         p = &(control_strings[i][14]);
 476                         ret = sscanf(p, "%d:%d", &crit, &size);
 477 
 478                         if ((ret != 2) || (crit < 0) || (crit > 1) || (size < 0)) {
 479                                 fprintf(stderr, "invalid paged_results control syntax\n");
 480                                 fprintf(stderr, " syntax: crit(b):size(n)\n");
 481                                 fprintf(stderr, "   note: b = boolean, n = number\n");
 482                                 return NULL;
 483                         }
 484 
 485                         ctrl[i] = talloc(ctrl, struct ldb_control);
 486                         ctrl[i]->oid = LDB_CONTROL_PAGED_RESULTS_OID;
 487                         ctrl[i]->critical = crit;
 488                         control = talloc(ctrl[i], struct ldb_paged_control);
 489                         control->size = size;
 490                         control->cookie = NULL;
 491                         control->cookie_len = 0;
 492                         ctrl[i]->data = control;
 493 
 494                         continue;
 495                 }
 496 
 497                 if (strncmp(control_strings[i], "server_sort:", 12) == 0) {
 498                         struct ldb_server_sort_control **control;
 499                         const char *p;
 500                         char attr[256];
 501                         char rule[128];
 502                         int crit, rev, ret;
 503 
 504                         attr[0] = '\0';
 505                         rule[0] = '\0';
 506                         p = &(control_strings[i][12]);
 507                         ret = sscanf(p, "%d:%d:%255[^:]:%127[^:]", &crit, &rev, attr, rule);
 508                         if ((ret < 3) || (crit < 0) || (crit > 1) || (rev < 0 ) || (rev > 1) ||attr[0] == '\0') {
 509                                 fprintf(stderr, "invalid server_sort control syntax\n");
 510                                 fprintf(stderr, " syntax: crit(b):rev(b):attr(s)[:rule(s)]\n");
 511                                 fprintf(stderr, "   note: b = boolean, s = string\n");
 512                                 return NULL;
 513                         }
 514                         ctrl[i] = talloc(ctrl, struct ldb_control);
 515                         ctrl[i]->oid = LDB_CONTROL_SERVER_SORT_OID;
 516                         ctrl[i]->critical = crit;
 517                         control = talloc_array(ctrl[i], struct ldb_server_sort_control *, 2);
 518                         control[0] = talloc(control, struct ldb_server_sort_control);
 519                         control[0]->attributeName = talloc_strdup(control, attr);
 520                         if (rule[0])
 521                                 control[0]->orderingRule = talloc_strdup(control, rule);
 522                         else
 523                                 control[0]->orderingRule = NULL;
 524                         control[0]->reverse = rev;
 525                         control[1] = NULL;
 526                         ctrl[i]->data = control;
 527 
 528                         continue;
 529                 }
 530 
 531                 if (strncmp(control_strings[i], "notification:", 13) == 0) {
 532                         const char *p;
 533                         int crit, ret;
 534 
 535                         p = &(control_strings[i][13]);
 536                         ret = sscanf(p, "%d", &crit);
 537                         if ((ret != 1) || (crit < 0) || (crit > 1)) {
 538                                 fprintf(stderr, "invalid notification control syntax\n");
 539                                 fprintf(stderr, " syntax: crit(b)\n");
 540                                 fprintf(stderr, "   note: b = boolean\n");
 541                                 return NULL;
 542                         }
 543 
 544                         ctrl[i] = talloc(ctrl, struct ldb_control);
 545                         ctrl[i]->oid = LDB_CONTROL_NOTIFICATION_OID;
 546                         ctrl[i]->critical = crit;
 547                         ctrl[i]->data = NULL;
 548 
 549                         continue;
 550                 }
 551 
 552                 if (strncmp(control_strings[i], "show_deleted:", 13) == 0) {
 553                         const char *p;
 554                         int crit, ret;
 555 
 556                         p = &(control_strings[i][13]);
 557                         ret = sscanf(p, "%d", &crit);
 558                         if ((ret != 1) || (crit < 0) || (crit > 1)) {
 559                                 fprintf(stderr, "invalid show_deleted control syntax\n");
 560                                 fprintf(stderr, " syntax: crit(b)\n");
 561                                 fprintf(stderr, "   note: b = boolean\n");
 562                                 return NULL;
 563                         }
 564 
 565                         ctrl[i] = talloc(ctrl, struct ldb_control);
 566                         ctrl[i]->oid = LDB_CONTROL_SHOW_DELETED_OID;
 567                         ctrl[i]->critical = crit;
 568                         ctrl[i]->data = NULL;
 569 
 570                         continue;
 571                 }
 572 
 573                 if (strncmp(control_strings[i], "permissive_modify:", 18) == 0) {
 574                         const char *p;
 575                         int crit, ret;
 576 
 577                         p = &(control_strings[i][18]);
 578                         ret = sscanf(p, "%d", &crit);
 579                         if ((ret != 1) || (crit < 0) || (crit > 1)) {
 580                                 fprintf(stderr, "invalid permissive_modify control syntax\n");
 581                                 fprintf(stderr, " syntax: crit(b)\n");
 582                                 fprintf(stderr, "   note: b = boolean\n");
 583                                 return NULL;
 584                         }
 585 
 586                         ctrl[i] = talloc(ctrl, struct ldb_control);
 587                         ctrl[i]->oid = LDB_CONTROL_PERMISSIVE_MODIFY_OID;
 588                         ctrl[i]->critical = crit;
 589                         ctrl[i]->data = NULL;
 590 
 591                         continue;
 592                 }
 593 
 594                 /* no controls matched, throw an error */
 595                 fprintf(stderr, "Invalid control name: '%s'\n", control_strings[i]);
 596                 return NULL;
 597         }
 598 
 599         ctrl[i] = NULL;
 600 
 601         return ctrl;
 602 }
 603 
 604 
 605 /* this function check controls reply and determines if more
 606  * processing is needed setting up the request controls correctly
 607  *
 608  * returns:
 609  *      -1 error
 610  *      0 all ok
 611  *      1 all ok, more processing required
 612  */
 613 int handle_controls_reply(struct ldb_control **reply, struct ldb_control **request)
     /* [<][>][^][v][top][bottom][index][help] */
 614 {
 615         int i, j;
 616         int ret = 0;
 617 
 618         if (reply == NULL || request == NULL) return -1;
 619         
 620         for (i = 0; reply[i]; i++) {
 621                 if (strcmp(LDB_CONTROL_VLV_RESP_OID, reply[i]->oid) == 0) {
 622                         struct ldb_vlv_resp_control *rep_control;
 623 
 624                         rep_control = talloc_get_type(reply[i]->data, struct ldb_vlv_resp_control);
 625                         
 626                         /* check we have a matching control in the request */
 627                         for (j = 0; request[j]; j++) {
 628                                 if (strcmp(LDB_CONTROL_VLV_REQ_OID, request[j]->oid) == 0)
 629                                         break;
 630                         }
 631                         if (! request[j]) {
 632                                 fprintf(stderr, "Warning VLV reply received but no request have been made\n");
 633                                 continue;
 634                         }
 635 
 636                         /* check the result */
 637                         if (rep_control->vlv_result != 0) {
 638                                 fprintf(stderr, "Warning: VLV not performed with error: %d\n", rep_control->vlv_result);
 639                         } else {
 640                                 fprintf(stderr, "VLV Info: target position = %d, content count = %d\n", rep_control->targetPosition, rep_control->contentCount);
 641                         }
 642 
 643                         continue;
 644                 }
 645 
 646                 if (strcmp(LDB_CONTROL_ASQ_OID, reply[i]->oid) == 0) {
 647                         struct ldb_asq_control *rep_control;
 648 
 649                         rep_control = talloc_get_type(reply[i]->data, struct ldb_asq_control);
 650 
 651                         /* check the result */
 652                         if (rep_control->result != 0) {
 653                                 fprintf(stderr, "Warning: ASQ not performed with error: %d\n", rep_control->result);
 654                         }
 655 
 656                         continue;
 657                 }
 658 
 659                 if (strcmp(LDB_CONTROL_PAGED_RESULTS_OID, reply[i]->oid) == 0) {
 660                         struct ldb_paged_control *rep_control, *req_control;
 661 
 662                         rep_control = talloc_get_type(reply[i]->data, struct ldb_paged_control);
 663                         if (rep_control->cookie_len == 0) /* we are done */
 664                                 break;
 665 
 666                         /* more processing required */
 667                         /* let's fill in the request control with the new cookie */
 668 
 669                         for (j = 0; request[j]; j++) {
 670                                 if (strcmp(LDB_CONTROL_PAGED_RESULTS_OID, request[j]->oid) == 0)
 671                                         break;
 672                         }
 673                         /* if there's a reply control we must find a request
 674                          * control matching it */
 675                         if (! request[j]) return -1;
 676 
 677                         req_control = talloc_get_type(request[j]->data, struct ldb_paged_control);
 678 
 679                         if (req_control->cookie)
 680                                 talloc_free(req_control->cookie);
 681                         req_control->cookie = (char *)talloc_memdup(
 682                                 req_control, rep_control->cookie,
 683                                 rep_control->cookie_len);
 684                         req_control->cookie_len = rep_control->cookie_len;
 685 
 686                         ret = 1;
 687 
 688                         continue;
 689                 }
 690 
 691                 if (strcmp(LDB_CONTROL_SORT_RESP_OID, reply[i]->oid) == 0) {
 692                         struct ldb_sort_resp_control *rep_control;
 693 
 694                         rep_control = talloc_get_type(reply[i]->data, struct ldb_sort_resp_control);
 695 
 696                         /* check we have a matching control in the request */
 697                         for (j = 0; request[j]; j++) {
 698                                 if (strcmp(LDB_CONTROL_SERVER_SORT_OID, request[j]->oid) == 0)
 699                                         break;
 700                         }
 701                         if (! request[j]) {
 702                                 fprintf(stderr, "Warning Server Sort reply received but no request found\n");
 703                                 continue;
 704                         }
 705 
 706                         /* check the result */
 707                         if (rep_control->result != 0) {
 708                                 fprintf(stderr, "Warning: Sorting not performed with error: %d\n", rep_control->result);
 709                         }
 710 
 711                         continue;
 712                 }
 713 
 714                 if (strcmp(LDB_CONTROL_DIRSYNC_OID, reply[i]->oid) == 0) {
 715                         struct ldb_dirsync_control *rep_control, *req_control;
 716                         char *cookie;
 717 
 718                         rep_control = talloc_get_type(reply[i]->data, struct ldb_dirsync_control);
 719                         if (rep_control->cookie_len == 0) /* we are done */
 720                                 break;
 721 
 722                         /* more processing required */
 723                         /* let's fill in the request control with the new cookie */
 724 
 725                         for (j = 0; request[j]; j++) {
 726                                 if (strcmp(LDB_CONTROL_DIRSYNC_OID, request[j]->oid) == 0)
 727                                         break;
 728                         }
 729                         /* if there's a reply control we must find a request
 730                          * control matching it */
 731                         if (! request[j]) return -1;
 732 
 733                         req_control = talloc_get_type(request[j]->data, struct ldb_dirsync_control);
 734 
 735                         if (req_control->cookie)
 736                                 talloc_free(req_control->cookie);
 737                         req_control->cookie = (char *)talloc_memdup(
 738                                 req_control, rep_control->cookie,
 739                                 rep_control->cookie_len);
 740                         req_control->cookie_len = rep_control->cookie_len;
 741 
 742                         cookie = ldb_base64_encode(req_control, rep_control->cookie, rep_control->cookie_len);
 743                         printf("# DIRSYNC cookie returned was:\n# %s\n", cookie);
 744 
 745                         continue;
 746                 }
 747 
 748                 /* no controls matched, throw a warning */
 749                 fprintf(stderr, "Unknown reply control oid: %s\n", reply[i]->oid);
 750         }
 751 
 752         return ret;
 753 }
 754 

/* [<][>][^][v][top][bottom][index][help] */