root/source4/lib/ldb/common/ldb_controls.c

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

DEFINITIONS

This source file includes following definitions.
  1. ldb_request_get_control
  2. ldb_reply_get_control
  3. save_controls
  4. check_critical_controls
  5. ldb_request_add_control
  6. ldb_parse_control_strings

   1 /* 
   2    ldb database library
   3 
   4    Copyright (C) Simo Sorce  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 /*
  25  *  Name: ldb_controls.c
  26  *
  27  *  Component: ldb controls utility functions
  28  *
  29  *  Description: helper functions for control modules
  30  *
  31  *  Author: Simo Sorce
  32  */
  33 
  34 #include "ldb_private.h"
  35 
  36 /* check if a control with the specified "oid" exist and return it */
  37 /* returns NULL if not found */
  38 struct ldb_control *ldb_request_get_control(struct ldb_request *req, const char *oid)
     /* [<][>][^][v][top][bottom][index][help] */
  39 {
  40         int i;
  41 
  42         /* check if there's a paged request control */
  43         if (req->controls != NULL) {
  44                 for (i = 0; req->controls[i]; i++) {
  45                         if (strcmp(oid, req->controls[i]->oid) == 0) {
  46                                 break;
  47                         }
  48                 }
  49 
  50                 return req->controls[i];
  51         }
  52 
  53         return NULL;
  54 }
  55 
  56 /* check if a control with the specified "oid" exist and return it */
  57 /* returns NULL if not found */
  58 struct ldb_control *ldb_reply_get_control(struct ldb_reply *rep, const char *oid)
     /* [<][>][^][v][top][bottom][index][help] */
  59 {
  60         int i;
  61 
  62         /* check if there's a paged request control */
  63         if (rep->controls != NULL) {
  64                 for (i = 0; rep->controls[i]; i++) {
  65                         if (strcmp(oid, rep->controls[i]->oid) == 0) {
  66                                 break;
  67                         }
  68                 }
  69 
  70                 return rep->controls[i];
  71         }
  72 
  73         return NULL;
  74 }
  75 
  76 /* saves the current controls list into the "saver" and replace the one in req with a new one excluding
  77 the "exclude" control */
  78 /* returns False on error */
  79 int save_controls(struct ldb_control *exclude, struct ldb_request *req, struct ldb_control ***saver)
     /* [<][>][^][v][top][bottom][index][help] */
  80 {
  81         struct ldb_control **lcs;
  82         int i, j;
  83 
  84         *saver = req->controls;
  85         for (i = 0; req->controls[i]; i++);
  86         if (i == 1) {
  87                 req->controls = NULL;
  88                 return 1;
  89         }
  90 
  91         lcs = talloc_array(req, struct ldb_control *, i);
  92         if (!lcs) {
  93                 return 0;
  94         }
  95 
  96         for (i = 0, j = 0; (*saver)[i]; i++) {
  97                 if (exclude == (*saver)[i]) continue;
  98                 lcs[j] = (*saver)[i];
  99                 j++;
 100         }
 101         lcs[j] = NULL;
 102 
 103         req->controls = lcs;
 104         return 1;
 105 }
 106 
 107 /* check if there's any control marked as critical in the list */
 108 /* return True if any, False if none */
 109 int check_critical_controls(struct ldb_control **controls)
     /* [<][>][^][v][top][bottom][index][help] */
 110 {
 111         int i;
 112 
 113         if (controls == NULL) {
 114                 return 0;
 115         }
 116 
 117         for (i = 0; controls[i]; i++) {
 118                 if (controls[i]->critical) {
 119                         return 1;
 120                 }
 121         }
 122 
 123         return 0;
 124 }
 125 
 126 int ldb_request_add_control(struct ldb_request *req, const char *oid, bool critical, void *data)
     /* [<][>][^][v][top][bottom][index][help] */
 127 {
 128         unsigned n;
 129         struct ldb_control **ctrls;
 130         struct ldb_control *ctrl;
 131 
 132         for (n=0; req->controls && req->controls[n];) { n++; }
 133 
 134         ctrls = talloc_realloc(req, req->controls,
 135                                struct ldb_control *,
 136                                n + 2);
 137         if (!ctrls) return LDB_ERR_OPERATIONS_ERROR;
 138         req->controls = ctrls;
 139         ctrls[n] = NULL;
 140         ctrls[n+1] = NULL;
 141 
 142         ctrl = talloc(ctrls, struct ldb_control);
 143         if (!ctrl) return LDB_ERR_OPERATIONS_ERROR;
 144 
 145         ctrl->oid       = talloc_strdup(ctrl, oid);
 146         if (!ctrl->oid) return LDB_ERR_OPERATIONS_ERROR;
 147         ctrl->critical  = critical;
 148         ctrl->data      = data;
 149 
 150         ctrls[n] = ctrl;
 151         return LDB_SUCCESS;
 152 }
 153 
 154 /* Parse controls from the format used on the command line and in ejs */
 155 
 156 struct ldb_control **ldb_parse_control_strings(struct ldb_context *ldb, void *mem_ctx, const char **control_strings)
     /* [<][>][^][v][top][bottom][index][help] */
 157 {
 158         int i;
 159         struct ldb_control **ctrl;
 160 
 161         char *error_string = NULL;
 162 
 163         if (control_strings == NULL || control_strings[0] == NULL)
 164                 return NULL;
 165 
 166         for (i = 0; control_strings[i]; i++);
 167 
 168         ctrl = talloc_array(mem_ctx, struct ldb_control *, i + 1);
 169 
 170         for (i = 0; control_strings[i]; i++) {
 171                 if (strncmp(control_strings[i], "vlv:", 4) == 0) {
 172                         struct ldb_vlv_req_control *control;
 173                         const char *p;
 174                         char attr[1024];
 175                         char ctxid[1024];
 176                         int crit, bc, ac, os, cc, ret;
 177 
 178                         attr[0] = '\0';
 179                         ctxid[0] = '\0';
 180                         p = &(control_strings[i][4]);
 181                         ret = sscanf(p, "%d:%d:%d:%d:%d:%1023[^$]", &crit, &bc, &ac, &os, &cc, ctxid);
 182                         if (ret < 5) {
 183                                 ret = sscanf(p, "%d:%d:%d:%1023[^:]:%1023[^$]", &crit, &bc, &ac, attr, ctxid);
 184                         }
 185                                
 186                         if ((ret < 4) || (crit < 0) || (crit > 1)) {
 187                                 error_string = talloc_asprintf(mem_ctx, "invalid server_sort control syntax\n");
 188                                 error_string = talloc_asprintf_append(error_string, " syntax: crit(b):bc(n):ac(n):<os(n):cc(n)|attr(s)>[:ctxid(o)]\n");
 189                                 error_string = talloc_asprintf_append(error_string, "   note: b = boolean, n = number, s = string, o = b64 binary blob");
 190                                 ldb_set_errstring(ldb, error_string);
 191                                 talloc_free(error_string);
 192                                 return NULL;
 193                         }
 194                         if (!(ctrl[i] = talloc(ctrl, struct ldb_control))) {
 195                                 ldb_oom(ldb);
 196                                 return NULL;
 197                         }
 198                         ctrl[i]->oid = LDB_CONTROL_VLV_REQ_OID;
 199                         ctrl[i]->critical = crit;
 200                         if (!(control = talloc(ctrl[i],
 201                                                struct ldb_vlv_req_control))) {
 202                                 ldb_oom(ldb);
 203                                 return NULL;
 204                         }
 205                         control->beforeCount = bc;
 206                         control->afterCount = ac;
 207                         if (attr[0]) {
 208                                 control->type = 1;
 209                                 control->match.gtOrEq.value = talloc_strdup(control, attr);
 210                                 control->match.gtOrEq.value_len = strlen(attr);
 211                         } else {
 212                                 control->type = 0;
 213                                 control->match.byOffset.offset = os;
 214                                 control->match.byOffset.contentCount = cc;
 215                         }
 216                         if (ctxid[0]) {
 217                                 control->ctxid_len = ldb_base64_decode(ctxid);
 218                                 control->contextId = (char *)talloc_memdup(control, ctxid, control->ctxid_len);
 219                         } else {
 220                                 control->ctxid_len = 0;
 221                                 control->contextId = NULL;
 222                         }
 223                         ctrl[i]->data = control;
 224 
 225                         continue;
 226                 }
 227 
 228                 if (strncmp(control_strings[i], "dirsync:", 8) == 0) {
 229                         struct ldb_dirsync_control *control;
 230                         const char *p;
 231                         char cookie[1024];
 232                         int crit, flags, max_attrs, ret;
 233                        
 234                         cookie[0] = '\0';
 235                         p = &(control_strings[i][8]);
 236                         ret = sscanf(p, "%d:%d:%d:%1023[^$]", &crit, &flags, &max_attrs, cookie);
 237 
 238                         if ((ret < 3) || (crit < 0) || (crit > 1) || (flags < 0) || (max_attrs < 0)) {
 239                                 error_string = talloc_asprintf(mem_ctx, "invalid dirsync control syntax\n");
 240                                 error_string = talloc_asprintf_append(error_string, " syntax: crit(b):flags(n):max_attrs(n)[:cookie(o)]\n");
 241                                 error_string = talloc_asprintf_append(error_string, "   note: b = boolean, n = number, o = b64 binary blob");
 242                                 ldb_set_errstring(ldb, error_string);
 243                                 talloc_free(error_string);
 244                                 return NULL;
 245                         }
 246 
 247                         /* w2k3 seems to ignore the parameter,
 248                          * but w2k sends a wrong cookie when this value is to small
 249                          * this would cause looping forever, while getting
 250                          * the same data and same cookie forever
 251                          */
 252                         if (max_attrs == 0) max_attrs = 0x0FFFFFFF;
 253 
 254                         ctrl[i] = talloc(ctrl, struct ldb_control);
 255                         ctrl[i]->oid = LDB_CONTROL_DIRSYNC_OID;
 256                         ctrl[i]->critical = crit;
 257                         control = talloc(ctrl[i], struct ldb_dirsync_control);
 258                         control->flags = flags;
 259                         control->max_attributes = max_attrs;
 260                         if (*cookie) {
 261                                 control->cookie_len = ldb_base64_decode(cookie);
 262                                 control->cookie = (char *)talloc_memdup(control, cookie, control->cookie_len);
 263                         } else {
 264                                 control->cookie = NULL;
 265                                 control->cookie_len = 0;
 266                         }
 267                         ctrl[i]->data = control;
 268 
 269                         continue;
 270                 }
 271 
 272                 if (strncmp(control_strings[i], "asq:", 4) == 0) {
 273                         struct ldb_asq_control *control;
 274                         const char *p;
 275                         char attr[256];
 276                         int crit, ret;
 277 
 278                         attr[0] = '\0';
 279                         p = &(control_strings[i][4]);
 280                         ret = sscanf(p, "%d:%255[^$]", &crit, attr);
 281                         if ((ret != 2) || (crit < 0) || (crit > 1) || (attr[0] == '\0')) {
 282                                 error_string = talloc_asprintf(mem_ctx, "invalid asq control syntax\n");
 283                                 error_string = talloc_asprintf_append(error_string, " syntax: crit(b):attr(s)\n");
 284                                 error_string = talloc_asprintf_append(error_string, "   note: b = boolean, s = string");
 285                                 ldb_set_errstring(ldb, error_string);
 286                                 talloc_free(error_string);
 287                                 return NULL;
 288                         }
 289 
 290                         ctrl[i] = talloc(ctrl, struct ldb_control);
 291                         if (!ctrl[i]) {
 292                                 ldb_oom(ldb);
 293                                 return NULL;
 294                         }
 295                         ctrl[i]->oid = LDB_CONTROL_ASQ_OID;
 296                         ctrl[i]->critical = crit;
 297                         control = talloc(ctrl[i], struct ldb_asq_control);
 298                         control->request = 1;
 299                         control->source_attribute = talloc_strdup(control, attr);
 300                         control->src_attr_len = strlen(attr);
 301                         ctrl[i]->data = control;
 302 
 303                         continue;
 304                 }
 305 
 306                 if (strncmp(control_strings[i], "extended_dn:", 12) == 0) {
 307                         struct ldb_extended_dn_control *control;
 308                         const char *p;
 309                         int crit, type, ret;
 310 
 311                         p = &(control_strings[i][12]);
 312                         ret = sscanf(p, "%d:%d", &crit, &type);
 313                         if ((ret != 2) || (crit < 0) || (crit > 1) || (type < 0) || (type > 1)) {
 314                                 ret = sscanf(p, "%d", &crit);
 315                                 if ((ret != 1) || (crit < 0) || (crit > 1)) {
 316                                         error_string = talloc_asprintf(mem_ctx, "invalid extended_dn control syntax\n");
 317                                         error_string = talloc_asprintf_append(error_string, " syntax: crit(b)[:type(i)]\n");
 318                                         error_string = talloc_asprintf_append(error_string, "   note: b = boolean\n");
 319                                         error_string = talloc_asprintf_append(error_string, "         i = integer\n");
 320                                         error_string = talloc_asprintf_append(error_string, "   valid values are: 0 - hexadecimal representation\n");
 321                                         error_string = talloc_asprintf_append(error_string, "                     1 - normal string representation");
 322                                         ldb_set_errstring(ldb, error_string);
 323                                         talloc_free(error_string);
 324                                         return NULL;
 325                                 }
 326                                 control = NULL;
 327                         } else {
 328                                 control = talloc(ctrl, struct ldb_extended_dn_control);
 329                                 control->type = type;
 330                         }
 331 
 332                         ctrl[i] = talloc(ctrl, struct ldb_control);
 333                         if (!ctrl[i]) {
 334                                 ldb_oom(ldb);
 335                                 return NULL;
 336                         }
 337                         ctrl[i]->oid = LDB_CONTROL_EXTENDED_DN_OID;
 338                         ctrl[i]->critical = crit;
 339                         ctrl[i]->data = talloc_steal(ctrl[i], control);
 340 
 341                         continue;
 342                 }
 343 
 344                 if (strncmp(control_strings[i], "sd_flags:", 9) == 0) {
 345                         struct ldb_sd_flags_control *control;
 346                         const char *p;
 347                         int crit, ret;
 348                         unsigned secinfo_flags;
 349 
 350                         p = &(control_strings[i][9]);
 351                         ret = sscanf(p, "%d:%u", &crit, &secinfo_flags);
 352                         if ((ret != 2) || (crit < 0) || (crit > 1) || (secinfo_flags < 0) || (secinfo_flags > 0xF)) {
 353                                 error_string = talloc_asprintf(mem_ctx, "invalid sd_flags control syntax\n");
 354                                 error_string = talloc_asprintf_append(error_string, " syntax: crit(b):secinfo_flags(n)\n");
 355                                 error_string = talloc_asprintf_append(error_string, "   note: b = boolean, n = number");
 356                                 ldb_set_errstring(ldb, error_string);
 357                                 talloc_free(error_string);
 358                                 return NULL;
 359                         }
 360 
 361                         ctrl[i] = talloc(ctrl, struct ldb_control);
 362                         if (!ctrl[i]) {
 363                                 ldb_oom(ldb);
 364                                 return NULL;
 365                         }
 366                         ctrl[i]->oid = LDB_CONTROL_SD_FLAGS_OID;
 367                         ctrl[i]->critical = crit;
 368                         control = talloc(ctrl[i], struct ldb_sd_flags_control);
 369                         control->secinfo_flags = secinfo_flags;
 370                         ctrl[i]->data = control;
 371 
 372                         continue;
 373                 }
 374 
 375                 if (strncmp(control_strings[i], "search_options:", 15) == 0) {
 376                         struct ldb_search_options_control *control;
 377                         const char *p;
 378                         int crit, ret;
 379                         unsigned search_options;
 380 
 381                         p = &(control_strings[i][15]);
 382                         ret = sscanf(p, "%d:%u", &crit, &search_options);
 383                         if ((ret != 2) || (crit < 0) || (crit > 1) || (search_options < 0) || (search_options > 0xF)) {
 384                                 error_string = talloc_asprintf(mem_ctx, "invalid search_options control syntax\n");
 385                                 error_string = talloc_asprintf_append(error_string, " syntax: crit(b):search_options(n)\n");
 386                                 error_string = talloc_asprintf_append(error_string, "   note: b = boolean, n = number");
 387                                 ldb_set_errstring(ldb, error_string);
 388                                 talloc_free(error_string);
 389                                 return NULL;
 390                         }
 391 
 392                         ctrl[i] = talloc(ctrl, struct ldb_control);
 393                         if (!ctrl[i]) {
 394                                 ldb_oom(ldb);
 395                                 return NULL;
 396                         }
 397                         ctrl[i]->oid = LDB_CONTROL_SEARCH_OPTIONS_OID;
 398                         ctrl[i]->critical = crit;
 399                         control = talloc(ctrl[i], struct ldb_search_options_control);
 400                         control->search_options = search_options;
 401                         ctrl[i]->data = control;
 402 
 403                         continue;
 404                 }
 405 
 406                 if (strncmp(control_strings[i], "domain_scope:", 13) == 0) {
 407                         const char *p;
 408                         int crit, ret;
 409 
 410                         p = &(control_strings[i][13]);
 411                         ret = sscanf(p, "%d", &crit);
 412                         if ((ret != 1) || (crit < 0) || (crit > 1)) {
 413                                 error_string = talloc_asprintf(mem_ctx, "invalid domain_scope control syntax\n");
 414                                 error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n");
 415                                 error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
 416                                 ldb_set_errstring(ldb, error_string);
 417                                 talloc_free(error_string);
 418                                 return NULL;
 419                         }
 420 
 421                         ctrl[i] = talloc(ctrl, struct ldb_control);
 422                         if (!ctrl[i]) {
 423                                 ldb_oom(ldb);
 424                                 return NULL;
 425                         }
 426                         ctrl[i]->oid = LDB_CONTROL_DOMAIN_SCOPE_OID;
 427                         ctrl[i]->critical = crit;
 428                         ctrl[i]->data = NULL;
 429 
 430                         continue;
 431                 }
 432 
 433                 if (strncmp(control_strings[i], "paged_results:", 14) == 0) {
 434                         struct ldb_paged_control *control;
 435                         const char *p;
 436                         int crit, size, ret;
 437                        
 438                         p = &(control_strings[i][14]);
 439                         ret = sscanf(p, "%d:%d", &crit, &size);
 440 
 441                         if ((ret != 2) || (crit < 0) || (crit > 1) || (size < 0)) {
 442                                 error_string = talloc_asprintf(mem_ctx, "invalid paged_results control syntax\n");
 443                                 error_string = talloc_asprintf_append(error_string, " syntax: crit(b):size(n)\n");
 444                                 error_string = talloc_asprintf_append(error_string, "   note: b = boolean, n = number");
 445                                 ldb_set_errstring(ldb, error_string);
 446                                 talloc_free(error_string);
 447                                 return NULL;
 448                         }
 449 
 450                         ctrl[i] = talloc(ctrl, struct ldb_control);
 451                         if (!ctrl[i]) {
 452                                 ldb_oom(ldb);
 453                                 return NULL;
 454                         }
 455                         ctrl[i]->oid = LDB_CONTROL_PAGED_RESULTS_OID;
 456                         ctrl[i]->critical = crit;
 457                         control = talloc(ctrl[i], struct ldb_paged_control);
 458                         control->size = size;
 459                         control->cookie = NULL;
 460                         control->cookie_len = 0;
 461                         ctrl[i]->data = control;
 462 
 463                         continue;
 464                 }
 465 
 466                 if (strncmp(control_strings[i], "server_sort:", 12) == 0) {
 467                         struct ldb_server_sort_control **control;
 468                         const char *p;
 469                         char attr[256];
 470                         char rule[128];
 471                         int crit, rev, ret;
 472 
 473                         attr[0] = '\0';
 474                         rule[0] = '\0';
 475                         p = &(control_strings[i][12]);
 476                         ret = sscanf(p, "%d:%d:%255[^:]:%127[^:]", &crit, &rev, attr, rule);
 477                         if ((ret < 3) || (crit < 0) || (crit > 1) || (rev < 0 ) || (rev > 1) ||attr[0] == '\0') {
 478                                 error_string = talloc_asprintf(mem_ctx, "invalid server_sort control syntax\n");
 479                                 error_string = talloc_asprintf_append(error_string, " syntax: crit(b):rev(b):attr(s)[:rule(s)]\n");
 480                                 error_string = talloc_asprintf_append(error_string, "   note: b = boolean, s = string");
 481                                 ldb_set_errstring(ldb, error_string);
 482                                 talloc_free(error_string);
 483                                 return NULL;
 484                         }
 485                         ctrl[i] = talloc(ctrl, struct ldb_control);
 486                         if (!ctrl[i]) {
 487                                 ldb_oom(ldb);
 488                                 return NULL;
 489                         }
 490                         ctrl[i]->oid = LDB_CONTROL_SERVER_SORT_OID;
 491                         ctrl[i]->critical = crit;
 492                         control = talloc_array(ctrl[i], struct ldb_server_sort_control *, 2);
 493                         control[0] = talloc(control, struct ldb_server_sort_control);
 494                         control[0]->attributeName = talloc_strdup(control, attr);
 495                         if (rule[0])
 496                                 control[0]->orderingRule = talloc_strdup(control, rule);
 497                         else
 498                                 control[0]->orderingRule = NULL;
 499                         control[0]->reverse = rev;
 500                         control[1] = NULL;
 501                         ctrl[i]->data = control;
 502 
 503                         continue;
 504                 }
 505 
 506                 if (strncmp(control_strings[i], "notification:", 13) == 0) {
 507                         const char *p;
 508                         int crit, ret;
 509 
 510                         p = &(control_strings[i][13]);
 511                         ret = sscanf(p, "%d", &crit);
 512                         if ((ret != 1) || (crit < 0) || (crit > 1)) {
 513                                 error_string = talloc_asprintf(mem_ctx, "invalid notification control syntax\n");
 514                                 error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n");
 515                                 error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
 516                                 ldb_set_errstring(ldb, error_string);
 517                                 talloc_free(error_string);
 518                                 return NULL;
 519                         }
 520 
 521                         ctrl[i] = talloc(ctrl, struct ldb_control);
 522                         if (!ctrl[i]) {
 523                                 ldb_oom(ldb);
 524                                 return NULL;
 525                         }
 526                         ctrl[i]->oid = LDB_CONTROL_NOTIFICATION_OID;
 527                         ctrl[i]->critical = crit;
 528                         ctrl[i]->data = NULL;
 529 
 530                         continue;
 531                 }
 532 
 533                 if (strncmp(control_strings[i], "show_deleted:", 13) == 0) {
 534                         const char *p;
 535                         int crit, ret;
 536 
 537                         p = &(control_strings[i][13]);
 538                         ret = sscanf(p, "%d", &crit);
 539                         if ((ret != 1) || (crit < 0) || (crit > 1)) {
 540                                 error_string = talloc_asprintf(mem_ctx, "invalid show_deleted control syntax\n");
 541                                 error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n");
 542                                 error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
 543                                 ldb_set_errstring(ldb, error_string);
 544                                 talloc_free(error_string);
 545                                 return NULL;
 546                         }
 547 
 548                         ctrl[i] = talloc(ctrl, struct ldb_control);
 549                         if (!ctrl[i]) {
 550                                 ldb_oom(ldb);
 551                                 return NULL;
 552                         }
 553                         ctrl[i]->oid = LDB_CONTROL_SHOW_DELETED_OID;
 554                         ctrl[i]->critical = crit;
 555                         ctrl[i]->data = NULL;
 556 
 557                         continue;
 558                 }
 559 
 560                 if (strncmp(control_strings[i], "permissive_modify:", 18) == 0) {
 561                         const char *p;
 562                         int crit, ret;
 563 
 564                         p = &(control_strings[i][18]);
 565                         ret = sscanf(p, "%d", &crit);
 566                         if ((ret != 1) || (crit < 0) || (crit > 1)) {
 567                                 error_string = talloc_asprintf(mem_ctx, "invalid permissive_modify control syntax\n");
 568                                 error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n");
 569                                 error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
 570                                 ldb_set_errstring(ldb, error_string);
 571                                 talloc_free(error_string);
 572                                 return NULL;
 573                         }
 574 
 575                         ctrl[i] = talloc(ctrl, struct ldb_control);
 576                         if (!ctrl[i]) {
 577                                 ldb_oom(ldb);
 578                                 return NULL;
 579                         }
 580                         ctrl[i]->oid = LDB_CONTROL_PERMISSIVE_MODIFY_OID;
 581                         ctrl[i]->critical = crit;
 582                         ctrl[i]->data = NULL;
 583 
 584                         continue;
 585                 }
 586 
 587                 /* no controls matched, throw an error */
 588                 ldb_asprintf_errstring(ldb, "Invalid control name: '%s'", control_strings[i]);
 589                 return NULL;
 590         }
 591 
 592         ctrl[i] = NULL;
 593 
 594         return ctrl;
 595 }
 596 
 597 

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