LCOV - code coverage report
Current view: top level - lib/ldb/common - ldb_controls.c (source / functions) Hit Total Coverage
Test: coverage report for fix-15632 9995c5c2 Lines: 436 756 57.7 %
Date: 2024-04-13 12:30:31 Functions: 9 11 81.8 %

          Line data    Source code
       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  2111221376 : struct ldb_control *ldb_request_get_control(struct ldb_request *req, const char *oid)
      39             : {
      40    68634153 :         unsigned int i;
      41             : 
      42  2111221376 :         if (req->controls != NULL) {
      43  6061639855 :                 for (i = 0; req->controls[i]; i++) {
      44  4449235198 :                         if (req->controls[i]->oid && strcmp(oid, req->controls[i]->oid) == 0) {
      45   217450356 :                                 break;
      46             :                         }
      47             :                 }
      48             : 
      49  1840211567 :                 return req->controls[i];
      50             :         }
      51             : 
      52   261703744 :         return NULL;
      53             : }
      54             : 
      55             : /* check if a control with the specified "oid" exist and return it */
      56             : /* returns NULL if not found */
      57     7852218 : struct ldb_control *ldb_reply_get_control(struct ldb_reply *rep, const char *oid)
      58             : {
      59      619929 :         unsigned int i;
      60             : 
      61     7852218 :         if (rep->controls != NULL) {
      62     7870232 :                 for (i = 0; rep->controls[i]; i++) {
      63     7856774 :                         if (rep->controls[i]->oid && strcmp(oid, rep->controls[i]->oid) == 0) {
      64     7212245 :                                 break;
      65             :                         }
      66             :                 }
      67             : 
      68     7845474 :                 return rep->controls[i];
      69             :         }
      70             : 
      71        6648 :         return NULL;
      72             : }
      73             : 
      74             : /*
      75             :  * Saves the current controls list into the "saver" (can also be NULL) and
      76             :  * replace the one in "req" with a new one excluding the "exclude" control
      77             :  * (if it is NULL then the list remains the same)
      78             :  *
      79             :  * Returns 0 on error.
      80             :  */
      81   156591275 : int ldb_save_controls(struct ldb_control *exclude, struct ldb_request *req, struct ldb_control ***saver)
      82             : {
      83     3850198 :         struct ldb_control **lcs, **lcs_old;
      84     3850198 :         unsigned int i, j;
      85             : 
      86   156591275 :         lcs_old = req->controls;
      87   156591275 :         if (saver != NULL) {
      88        9007 :                 *saver = lcs_old;
      89             :         }
      90             : 
      91   642442806 :         for (i = 0; req->controls && req->controls[i]; i++);
      92   156591275 :         if (i == 0) {
      93         144 :                 req->controls = NULL;
      94         144 :                 return 1;
      95             :         }
      96             : 
      97   156591131 :         lcs = talloc_array(req, struct ldb_control *, i + 1);
      98   156591131 :         if (!lcs) {
      99           0 :                 return 0;
     100             :         }
     101             : 
     102   642442662 :         for (i = 0, j = 0; lcs_old[i]; i++) {
     103   485851531 :                 if (exclude == lcs_old[i]) continue;
     104   477674998 :                 lcs[j] = lcs_old[i];
     105   477674998 :                 j++;
     106             :         }
     107   156591131 :         lcs[j] = NULL;
     108             : 
     109   156591131 :         req->controls = talloc_realloc(req, lcs, struct ldb_control *, j + 1);
     110   156591131 :         if (req->controls == NULL) {
     111           0 :                 return 0;
     112             :         }
     113   152740933 :         return 1;
     114             : }
     115             : 
     116             : /*
     117             :  * Returns a list of controls, except the one specified with "exclude" (can
     118             :  * also be NULL).  Included controls become a child of returned list if they
     119             :  * were children of "controls_in".
     120             :  *
     121             :  * Returns NULL on error (OOM) or an empty control list.
     122             :  */
     123     1701600 : struct ldb_control **ldb_controls_except_specified(struct ldb_control **controls_in, 
     124             :                                                TALLOC_CTX *mem_ctx, 
     125             :                                                struct ldb_control *exclude)
     126             : {
     127     1701600 :         struct ldb_control **lcs = NULL;
     128      106966 :         unsigned int i, j, n;
     129             : 
     130     3403200 :         for (i = 0; controls_in && controls_in[i]; i++);
     131     1701600 :         if (i == 0) {
     132           0 :                 return NULL;
     133             :         }
     134     1594634 :         n = i;
     135             : 
     136     3403200 :         for (i = 0, j = 0; controls_in && controls_in[i]; i++) {
     137     1701600 :                 if (exclude == controls_in[i]) continue;
     138             : 
     139           0 :                 if (!lcs) {
     140             :                         /* Allocate here so if we remove the only
     141             :                          * control, or there were no controls, we
     142             :                          * don't allocate at all, and just return
     143             :                          * NULL */
     144           0 :                         lcs = talloc_array(mem_ctx, struct ldb_control *,
     145             :                                            n + 1);
     146           0 :                         if (!lcs) {
     147           0 :                                 return NULL;
     148             :                         }
     149             :                 }
     150             : 
     151           0 :                 lcs[j] = controls_in[i];
     152           0 :                 talloc_reparent(controls_in, lcs, lcs[j]);
     153           0 :                 j++;
     154             :         }
     155     1701600 :         if (lcs) {
     156           0 :                 lcs[j] = NULL;
     157             : 
     158           0 :                 lcs = talloc_realloc(mem_ctx, lcs, struct ldb_control *, j + 1);
     159             :         }
     160             : 
     161     1594634 :         return lcs;
     162             : }
     163             : 
     164             : /* check if there's any control marked as critical in the list */
     165             : /* return True if any, False if none */
     166           0 : int ldb_check_critical_controls(struct ldb_control **controls)
     167             : {
     168           0 :         unsigned int i;
     169             : 
     170           0 :         if (controls == NULL) {
     171           0 :                 return 0;
     172             :         }
     173             : 
     174           0 :         for (i = 0; controls[i]; i++) {
     175           0 :                 if (controls[i]->critical) {
     176           0 :                         return 1;
     177             :                 }
     178             :         }
     179             : 
     180           0 :         return 0;
     181             : }
     182             : 
     183   180597871 : int ldb_request_add_control(struct ldb_request *req, const char *oid, bool critical, void *data)
     184             : {
     185     6778126 :         unsigned int i, n;
     186     6778126 :         struct ldb_control **ctrls;
     187     6778126 :         struct ldb_control *ctrl;
     188             : 
     189   392771721 :         for (n=0; req->controls && req->controls[n];n++) { 
     190             :                 /* having two controls of the same OID makes no sense */
     191   212173850 :                 if (req->controls[n]->oid && strcmp(oid, req->controls[n]->oid) == 0) {
     192           0 :                         return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
     193             :                 }
     194             :         }
     195             : 
     196   180597871 :         ctrls = talloc_array(req,
     197             :                                struct ldb_control *,
     198             :                                n + 2);
     199   180597871 :         if (!ctrls) return LDB_ERR_OPERATIONS_ERROR;
     200             : 
     201   392771721 :         for (i=0; i<n; i++) {
     202   212173850 :                 ctrls[i] = req->controls[i];
     203             :         }
     204             : 
     205   180597871 :         req->controls = ctrls;
     206   180597871 :         ctrls[n] = NULL;
     207   180597871 :         ctrls[n+1] = NULL;
     208             : 
     209   180597871 :         ctrl = talloc(ctrls, struct ldb_control);
     210   180597871 :         if (!ctrl) return LDB_ERR_OPERATIONS_ERROR;
     211             : 
     212   180597871 :         ctrl->oid    = talloc_strdup(ctrl, oid);
     213   180597871 :         if (!ctrl->oid) return LDB_ERR_OPERATIONS_ERROR;
     214   180597871 :         ctrl->critical       = critical;
     215   180597871 :         ctrl->data   = data;
     216             : 
     217   180597871 :         ctrls[n] = ctrl;
     218   180597871 :         return LDB_SUCCESS;
     219             : }
     220             : 
     221    12446965 : int ldb_reply_add_control(struct ldb_reply *ares, const char *oid, bool critical, void *data)
     222             : {
     223      882921 :         unsigned n;
     224      882921 :         struct ldb_control **ctrls;
     225      882921 :         struct ldb_control *ctrl;
     226             : 
     227    12454259 :         for (n=0; ares->controls && ares->controls[n];) { 
     228             :                 /* having two controls of the same OID makes no sense */
     229        7294 :                 if (ares->controls[n]->oid && strcmp(oid, ares->controls[n]->oid) == 0) {
     230           0 :                         return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
     231             :                 }
     232        7294 :                 n++; 
     233             :         }
     234             : 
     235    12446965 :         ctrls = talloc_realloc(ares, ares->controls,
     236             :                                struct ldb_control *,
     237             :                                n + 2);
     238    12446965 :         if (!ctrls) return LDB_ERR_OPERATIONS_ERROR;
     239    12446965 :         ares->controls = ctrls;
     240    12446965 :         ctrls[n] = NULL;
     241    12446965 :         ctrls[n+1] = NULL;
     242             : 
     243    12446965 :         ctrl = talloc(ctrls, struct ldb_control);
     244    12446965 :         if (!ctrl) return LDB_ERR_OPERATIONS_ERROR;
     245             : 
     246    12446965 :         ctrl->oid    = talloc_strdup(ctrl, oid);
     247    12446965 :         if (!ctrl->oid) return LDB_ERR_OPERATIONS_ERROR;
     248    12446965 :         ctrl->critical       = critical;
     249    12446965 :         ctrl->data   = data;
     250             : 
     251    12446965 :         ctrls[n] = ctrl;
     252    12446965 :         return LDB_SUCCESS;
     253             : }
     254             : 
     255             : /* Add a control to the request, replacing the old one if it is already in the request */
     256           0 : int ldb_request_replace_control(struct ldb_request *req, const char *oid, bool critical, void *data)
     257             : {
     258           0 :         unsigned int n;
     259           0 :         int ret;
     260             : 
     261           0 :         ret = ldb_request_add_control(req, oid, critical, data);
     262           0 :         if (ret != LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) {
     263           0 :                 return ret;
     264             :         }
     265             : 
     266           0 :         for (n=0; req->controls[n];n++) {
     267           0 :                 if (req->controls[n]->oid && strcmp(oid, req->controls[n]->oid) == 0) {
     268           0 :                         req->controls[n]->critical = critical;
     269           0 :                         req->controls[n]->data = data;
     270           0 :                         return LDB_SUCCESS;
     271             :                 }
     272             :         }
     273             : 
     274           0 :         return LDB_ERR_OPERATIONS_ERROR;
     275             : }
     276             : 
     277             : /*
     278             :  * Return a control as string
     279             :  * the project (ie. name:value1:value2:...:valuen
     280             :  * The string didn't include the criticity of the critical flag
     281             :  */
     282       54671 : char *ldb_control_to_string(TALLOC_CTX *mem_ctx, const struct ldb_control *control)
     283             : {
     284       54671 :         char *res = NULL;
     285             : 
     286       54671 :         if (strcmp(control->oid, LDB_CONTROL_PAGED_RESULTS_OID) == 0) {
     287         215 :                 struct ldb_paged_control *rep_control = talloc_get_type(control->data, struct ldb_paged_control);
     288           0 :                 char *cookie;
     289         215 :                 if (rep_control == NULL) {
     290           0 :                         return NULL;
     291             :                 }
     292             : 
     293         215 :                 cookie = ldb_base64_encode(mem_ctx, rep_control->cookie, rep_control->cookie_len);
     294         215 :                 if (cookie == NULL) {
     295           0 :                         return NULL;
     296             :                 }
     297         215 :                 if (cookie[0] != '\0') {
     298         171 :                         res = talloc_asprintf(mem_ctx, "%s:%d:%s",
     299             :                                                 LDB_CONTROL_PAGED_RESULTS_NAME,
     300         171 :                                                 control->critical,
     301             :                                                 cookie);
     302             : 
     303         171 :                         talloc_free(cookie);
     304             :                 } else {
     305          44 :                         res = talloc_asprintf(mem_ctx, "%s:%d",
     306             :                                                 LDB_CONTROL_PAGED_RESULTS_NAME,
     307          44 :                                                 control->critical);
     308             :                 }
     309         215 :                 return res;
     310             :         }
     311             : 
     312       54456 :         if (strcmp(control->oid, LDB_CONTROL_VLV_RESP_OID) == 0) {
     313       45308 :                 struct ldb_vlv_resp_control *rep_control = talloc_get_type(control->data,
     314             :                                                                 struct ldb_vlv_resp_control);
     315             : 
     316           0 :                 char *cookie;
     317             : 
     318       45308 :                 if (rep_control == NULL) {
     319           0 :                         return NULL;
     320             :                 }
     321             : 
     322       45308 :                 cookie = ldb_base64_encode(mem_ctx,
     323       45308 :                                            (char *)rep_control->contextId,
     324             :                                            rep_control->ctxid_len);
     325       45308 :                 if (cookie == NULL) {
     326           0 :                         return NULL;
     327             :                 }
     328             : 
     329       45308 :                 res = talloc_asprintf(mem_ctx, "%s:%d:%d:%d:%d:%s",
     330             :                                                 LDB_CONTROL_VLV_RESP_NAME,
     331       45308 :                                                 control->critical,
     332             :                                                 rep_control->targetPosition,
     333             :                                                 rep_control->contentCount,
     334             :                                                 rep_control->vlv_result,
     335             :                                                 cookie);
     336             : 
     337       45308 :                 return res;
     338             :         }
     339             : 
     340        9148 :         if (strcmp(control->oid, LDB_CONTROL_SORT_RESP_OID) == 0) {
     341           0 :                 struct ldb_sort_resp_control *rep_control = talloc_get_type(control->data,
     342             :                                                                 struct ldb_sort_resp_control);
     343             : 
     344           0 :                 if (rep_control == NULL) {
     345           0 :                         return NULL;
     346             :                 }
     347           0 :                 res = talloc_asprintf(mem_ctx, "%s:%d:%d:%s",
     348             :                                         LDB_CONTROL_SORT_RESP_NAME,
     349           0 :                                         control->critical,
     350             :                                         rep_control->result,
     351             :                                         rep_control->attr_desc);
     352             : 
     353           0 :                 return res;
     354             :         }
     355             : 
     356        9148 :         if (strcmp(control->oid, LDB_CONTROL_ASQ_OID) == 0) {
     357           0 :                 struct ldb_asq_control *rep_control = talloc_get_type(control->data,
     358             :                                                                 struct ldb_asq_control);
     359             : 
     360           0 :                 if (rep_control == NULL) {
     361           0 :                         return NULL;
     362             :                 }
     363           0 :                 res = talloc_asprintf(mem_ctx, "%s:%d:%d",
     364             :                                         LDB_CONTROL_ASQ_NAME,
     365           0 :                                         control->critical,
     366             :                                         rep_control->result);
     367             : 
     368           0 :                 return res;
     369             :         }
     370             : 
     371        9148 :         if (strcmp(control->oid, LDB_CONTROL_DIRSYNC_OID) == 0) {
     372           0 :                 char *cookie;
     373        9148 :                 struct ldb_dirsync_control *rep_control = talloc_get_type(control->data,
     374             :                                                                 struct ldb_dirsync_control);
     375             : 
     376        9148 :                 if (rep_control == NULL) {
     377           0 :                         return NULL;
     378             :                 }
     379        9148 :                 cookie = ldb_base64_encode(mem_ctx, rep_control->cookie,
     380             :                                 rep_control->cookie_len);
     381        9148 :                 if (cookie == NULL) {
     382           0 :                         return NULL;
     383             :                 }
     384        9148 :                 res = talloc_asprintf(mem_ctx, "%s:%d:%d:%d:%s",
     385             :                                         LDB_CONTROL_DIRSYNC_NAME,
     386        9148 :                                         control->critical,
     387             :                                         rep_control->flags,
     388             :                                         rep_control->max_attributes,
     389             :                                         cookie);
     390             : 
     391        9148 :                 talloc_free(cookie);
     392        9148 :                 return res;
     393             :         }
     394           0 :         if (strcmp(control->oid, LDB_CONTROL_DIRSYNC_EX_OID) == 0) {
     395           0 :                 char *cookie;
     396           0 :                 struct ldb_dirsync_control *rep_control = talloc_get_type(control->data,
     397             :                                                                 struct ldb_dirsync_control);
     398             : 
     399           0 :                 if (rep_control == NULL) {
     400           0 :                         return NULL;
     401             :                 }
     402           0 :                 cookie = ldb_base64_encode(mem_ctx, rep_control->cookie,
     403             :                                 rep_control->cookie_len);
     404           0 :                 if (cookie == NULL) {
     405           0 :                         return NULL;
     406             :                 }
     407           0 :                 res = talloc_asprintf(mem_ctx, "%s:%d:%d:%d:%s",
     408             :                                         LDB_CONTROL_DIRSYNC_EX_NAME,
     409           0 :                                         control->critical,
     410             :                                         rep_control->flags,
     411             :                                         rep_control->max_attributes,
     412             :                                         cookie);
     413             : 
     414           0 :                 talloc_free(cookie);
     415           0 :                 return res;
     416             :         }
     417             : 
     418           0 :         if (strcmp(control->oid, LDB_CONTROL_VERIFY_NAME_OID) == 0) {
     419           0 :                 struct ldb_verify_name_control *rep_control = talloc_get_type(control->data, struct ldb_verify_name_control);
     420             : 
     421           0 :                 if (rep_control == NULL) {
     422           0 :                         return NULL;
     423             :                 }
     424           0 :                 if (rep_control->gc != NULL) {
     425           0 :                         res = talloc_asprintf(mem_ctx, "%s:%d:%d:%s",
     426             :                                                 LDB_CONTROL_VERIFY_NAME_NAME,
     427           0 :                                                 control->critical,
     428             :                                                 rep_control->flags,
     429             :                                                 rep_control->gc);
     430             : 
     431             :                 } else {
     432           0 :                         res = talloc_asprintf(mem_ctx, "%s:%d:%d",
     433             :                                                 LDB_CONTROL_VERIFY_NAME_NAME,
     434           0 :                                                 control->critical,
     435             :                                                 rep_control->flags);
     436             :                 }
     437           0 :                 return res;
     438             :         }
     439             : 
     440             :         /*
     441             :          * From here we don't know the control
     442             :          */
     443           0 :         if (control->data == NULL) {
     444             :                 /*
     445             :                  * We don't know the control but there is no real data attached
     446             :                  * to it so we can represent it with local_oid:oid:criticity.
     447             :                  */
     448           0 :                 res = talloc_asprintf(mem_ctx, "local_oid:%s:%d",
     449           0 :                                         control->oid,
     450           0 :                                         control->critical);
     451             :         } else {
     452           0 :                 res = talloc_asprintf(mem_ctx, "unknown oid:%s",
     453           0 :                                         control->oid);
     454             :         }
     455           0 :         return res;
     456             : }
     457             : 
     458             : 
     459             : /*
     460             :  * A little trick to allow one to use constants defined in headers rather than
     461             :  * hardwritten in the file.
     462             :  * "sizeof" will return the \0 char as well so it will take the place of ":"
     463             :  * in the length of the string.
     464             :  */
     465             : #define LDB_CONTROL_CMP(control, NAME) strncmp(control, NAME ":", sizeof(NAME))
     466             : 
     467             : /* Parse one string and return associated control if parsing is successful*/
     468    10771718 : struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *control_strings)
     469             : {
     470     1142663 :         struct ldb_control *ctrl;
     471             : 
     472    10771718 :         if (!(ctrl = talloc(mem_ctx, struct ldb_control))) {
     473           0 :                 ldb_oom(ldb);
     474           0 :                 return NULL;
     475             :         }
     476             : 
     477    10771718 :         if (LDB_CONTROL_CMP(control_strings,
     478             :                                 LDB_CONTROL_VLV_REQ_NAME) == 0) {
     479           0 :                 struct ldb_vlv_req_control *control;
     480           0 :                 const char *p;
     481           0 :                 char attr[1024];
     482           0 :                 char ctxid[1024];
     483           0 :                 int crit, bc, ac, os, cc, ret;
     484             : 
     485       53033 :                 attr[0] = '\0';
     486       53033 :                 ctxid[0] = '\0';
     487       53033 :                 p = &(control_strings[sizeof(LDB_CONTROL_VLV_REQ_NAME)]);
     488       53033 :                 ret = sscanf(p, "%d:%d:%d:%d:%d:%1023[^$]", &crit, &bc, &ac, &os, &cc, ctxid);
     489             :                 /* We allow 2 ways to encode the GT_EQ case, because the
     490             :                    comparison string might contain null bytes or colons, which
     491             :                    would break sscanf (or indeed any parsing mechanism). */
     492       53033 :                 if (ret == 3) {
     493       22275 :                         ret = sscanf(p, "%d:%d:%d:>=%1023[^:]:%1023[^$]", &crit, &bc, &ac, attr, ctxid);
     494             :                 }
     495       53033 :                 if (ret == 3) {
     496           0 :                         int len;
     497           0 :                         ret = sscanf(p, "%d:%d:%d:base64>=%1023[^:]:%1023[^$]", &crit, &bc, &ac, attr, ctxid);
     498           0 :                         len = ldb_base64_decode(attr);
     499           0 :                         if (len < 0) {
     500           0 :                                 ret = -1;
     501             :                         }
     502             :                 }
     503             : 
     504       53033 :                 if ((ret < 4) || (crit < 0) || (crit > 1)) {
     505           0 :                         ldb_set_errstring(ldb,
     506             :                                           "invalid VLV control syntax\n"
     507             :                                           " syntax: crit(b):bc(n):ac(n):"
     508             :                                           "{os(n):cc(n)|>=val(s)|base64>=val(o)}[:ctxid(o)]\n"
     509             :                                           "   note: b = boolean, n = number, s = string, o = b64 binary blob");
     510           0 :                         talloc_free(ctrl);
     511           0 :                         return NULL;
     512             :                 }
     513       53033 :                 ctrl->oid = LDB_CONTROL_VLV_REQ_OID;
     514       53033 :                 ctrl->critical = crit;
     515       53033 :                 if (!(control = talloc(ctrl,
     516             :                                         struct ldb_vlv_req_control))) {
     517           0 :                         ldb_oom(ldb);
     518           0 :                         talloc_free(ctrl);
     519           0 :                         return NULL;
     520             :                 }
     521       53033 :                 control->beforeCount = bc;
     522       53033 :                 control->afterCount = ac;
     523       53033 :                 if (attr[0]) {
     524       22275 :                         control->type = 1;
     525       22275 :                         control->match.gtOrEq.value = talloc_strdup(control, attr);
     526       22275 :                         control->match.gtOrEq.value_len = strlen(attr);
     527             :                 } else {
     528       30758 :                         control->type = 0;
     529       30758 :                         control->match.byOffset.offset = os;
     530       30758 :                         control->match.byOffset.contentCount = cc;
     531             :                 }
     532       53033 :                 if (ctxid[0]) {
     533       45278 :                         int len = ldb_base64_decode(ctxid);
     534       45278 :                         if (len < 0) {
     535           0 :                                 ldb_set_errstring(ldb,
     536             :                                                   "invalid VLV context_id\n");
     537           0 :                                 talloc_free(ctrl);
     538           0 :                                 return NULL;
     539             :                         }
     540       45278 :                         control->ctxid_len = len;
     541       45278 :                         control->contextId = talloc_memdup(control, ctxid,
     542             :                                                            control->ctxid_len);
     543       45278 :                         if (control->contextId == NULL) {
     544           0 :                                 ldb_oom(ldb);
     545           0 :                                 talloc_free(ctrl);
     546           0 :                                 return NULL;
     547             :                         }
     548             :                 } else {
     549        7755 :                         control->ctxid_len = 0;
     550        7755 :                         control->contextId = NULL;
     551             :                 }
     552       53033 :                 ctrl->data = control;
     553             : 
     554       53033 :                 return ctrl;
     555             :         }
     556             : 
     557    10718685 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_DIRSYNC_NAME) == 0) {
     558           0 :                 struct ldb_dirsync_control *control;
     559           0 :                 const char *p;
     560         526 :                 char *cookie = NULL;
     561           0 :                 int crit, max_attrs, ret;
     562           0 :                 uint32_t flags;
     563             : 
     564         526 :                 cookie = talloc_zero_array(ctrl, char,
     565             :                                            strlen(control_strings) + 1);
     566         526 :                 if (cookie == NULL) {
     567           0 :                         ldb_oom(ldb);
     568           0 :                         talloc_free(ctrl);
     569           0 :                         return NULL;
     570             :                 }
     571             : 
     572         526 :                 p = &(control_strings[sizeof(LDB_CONTROL_DIRSYNC_NAME)]);
     573         526 :                 ret = sscanf(p, "%d:%u:%d:%[^$]", &crit, &flags, &max_attrs, cookie);
     574             : 
     575         526 :                 if ((ret < 3) || (crit < 0) || (crit > 1) || (max_attrs < 0)) {
     576           0 :                         ldb_set_errstring(ldb,
     577             :                                           "invalid dirsync control syntax\n"
     578             :                                           " syntax: crit(b):flags(n):max_attrs(n)[:cookie(o)]\n"
     579             :                                           "   note: b = boolean, n = number, o = b64 binary blob");
     580           0 :                         talloc_free(ctrl);
     581           0 :                         return NULL;
     582             :                 }
     583             : 
     584             :                 /* w2k3 seems to ignore the parameter,
     585             :                  * but w2k sends a wrong cookie when this value is to small
     586             :                  * this would cause looping forever, while getting
     587             :                  * the same data and same cookie forever
     588             :                  */
     589         526 :                 if (max_attrs == 0) max_attrs = 0x0FFFFFFF;
     590             : 
     591         526 :                 ctrl->oid = LDB_CONTROL_DIRSYNC_OID;
     592         526 :                 ctrl->critical = crit;
     593         526 :                 control = talloc(ctrl, struct ldb_dirsync_control);
     594         526 :                 if (control == NULL) {
     595           0 :                         ldb_oom(ldb);
     596           0 :                         talloc_free(ctrl);
     597           0 :                         return NULL;
     598             :                 }
     599         526 :                 control->flags = flags;
     600         526 :                 control->max_attributes = max_attrs;
     601         526 :                 if (*cookie) {
     602         141 :                         int len = ldb_base64_decode(cookie);
     603         141 :                         if (len < 0) {
     604           0 :                                 ldb_set_errstring(ldb,
     605             :                                                   "invalid dirsync cookie\n");
     606           0 :                                 talloc_free(ctrl);
     607           0 :                                 return NULL;
     608             :                         }
     609         141 :                         control->cookie_len = len;
     610         141 :                         control->cookie = (char *)talloc_memdup(control, cookie, control->cookie_len);
     611         141 :                         if (control->cookie == NULL) {
     612           0 :                                 ldb_oom(ldb);
     613           0 :                                 talloc_free(ctrl);
     614           0 :                                 return NULL;
     615             :                         }
     616             :                 } else {
     617         385 :                         control->cookie = NULL;
     618         385 :                         control->cookie_len = 0;
     619             :                 }
     620         526 :                 ctrl->data = control;
     621         526 :                 TALLOC_FREE(cookie);
     622             : 
     623         526 :                 return ctrl;
     624             :         }
     625    10718159 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_DIRSYNC_EX_NAME) == 0) {
     626           0 :                 struct ldb_dirsync_control *control;
     627           0 :                 const char *p;
     628           0 :                 char *cookie = NULL;
     629           0 :                 int crit, max_attrs, ret;
     630           0 :                 uint32_t flags;
     631             : 
     632           0 :                 cookie = talloc_zero_array(ctrl, char,
     633             :                                            strlen(control_strings) + 1);
     634           0 :                 if (cookie == NULL) {
     635           0 :                         ldb_oom(ldb);
     636           0 :                         talloc_free(ctrl);
     637           0 :                         return NULL;
     638             :                 }
     639             : 
     640           0 :                 p = &(control_strings[sizeof(LDB_CONTROL_DIRSYNC_EX_NAME)]);
     641           0 :                 ret = sscanf(p, "%d:%u:%d:%1023[^$]", &crit, &flags, &max_attrs, cookie);
     642             : 
     643           0 :                 if ((ret < 3) || (crit < 0) || (crit > 1) || (max_attrs < 0)) {
     644           0 :                         ldb_set_errstring(ldb,
     645             :                                           "invalid dirsync_ex control syntax\n"
     646             :                                           " syntax: crit(b):flags(n):max_attrs(n)[:cookie(o)]\n"
     647             :                                           "   note: b = boolean, n = number, o = b64 binary blob");
     648           0 :                         talloc_free(ctrl);
     649           0 :                         return NULL;
     650             :                 }
     651             : 
     652             :                 /* w2k3 seems to ignore the parameter,
     653             :                  * but w2k sends a wrong cookie when this value is to small
     654             :                  * this would cause looping forever, while getting
     655             :                  * the same data and same cookie forever
     656             :                  */
     657           0 :                 if (max_attrs == 0) max_attrs = 0x0FFFFFFF;
     658             : 
     659           0 :                 ctrl->oid = LDB_CONTROL_DIRSYNC_EX_OID;
     660           0 :                 ctrl->critical = crit;
     661           0 :                 control = talloc(ctrl, struct ldb_dirsync_control);
     662           0 :                 if (control == NULL) {
     663           0 :                         ldb_oom(ldb);
     664           0 :                         talloc_free(ctrl);
     665           0 :                         return NULL;
     666             :                 }
     667           0 :                 control->flags = flags;
     668           0 :                 control->max_attributes = max_attrs;
     669           0 :                 if (*cookie) {
     670           0 :                         int len = ldb_base64_decode(cookie);
     671           0 :                         if (len < 0) {
     672           0 :                                 ldb_set_errstring(ldb,
     673             :                                                   "invalid dirsync_ex cookie"
     674             :                                                   " (probably too long)\n");
     675           0 :                                 talloc_free(ctrl);
     676           0 :                                 return NULL;
     677             :                         }
     678           0 :                         control->cookie_len = len;
     679           0 :                         control->cookie = (char *)talloc_memdup(control, cookie, control->cookie_len);
     680           0 :                         if (control->cookie == NULL) {
     681           0 :                                 ldb_oom(ldb);
     682           0 :                                 talloc_free(ctrl);
     683           0 :                                 return NULL;
     684             :                         }
     685             :                 } else {
     686           0 :                         control->cookie = NULL;
     687           0 :                         control->cookie_len = 0;
     688             :                 }
     689           0 :                 ctrl->data = control;
     690           0 :                 TALLOC_FREE(cookie);
     691             : 
     692           0 :                 return ctrl;
     693             :         }
     694             : 
     695    10718159 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_ASQ_NAME) == 0) {
     696           0 :                 struct ldb_asq_control *control;
     697           0 :                 const char *p;
     698           0 :                 char attr[256];
     699           0 :                 int crit, ret;
     700             : 
     701          15 :                 attr[0] = '\0';
     702          15 :                 p = &(control_strings[sizeof(LDB_CONTROL_ASQ_NAME)]);
     703          15 :                 ret = sscanf(p, "%d:%255[^$]", &crit, attr);
     704          15 :                 if ((ret != 2) || (crit < 0) || (crit > 1) || (attr[0] == '\0')) {
     705           0 :                         ldb_set_errstring(ldb,
     706             :                                           "invalid asq control syntax\n"
     707             :                                           " syntax: crit(b):attr(s)\n"
     708             :                                           "   note: b = boolean, s = string");
     709           0 :                         talloc_free(ctrl);
     710           0 :                         return NULL;
     711             :                 }
     712             : 
     713          15 :                 ctrl->oid = LDB_CONTROL_ASQ_OID;
     714          15 :                 ctrl->critical = crit;
     715          15 :                 control = talloc(ctrl, struct ldb_asq_control);
     716          15 :                 if (control == NULL) {
     717           0 :                         ldb_oom(ldb);
     718           0 :                         talloc_free(ctrl);
     719           0 :                         return NULL;
     720             :                 }
     721          15 :                 control->request = 1;
     722          15 :                 control->source_attribute = talloc_strdup(control, attr);
     723          15 :                 control->src_attr_len = strlen(attr);
     724          15 :                 ctrl->data = control;
     725             : 
     726          15 :                 return ctrl;
     727             :         }
     728             : 
     729    10718144 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_EXTENDED_DN_NAME) == 0) {
     730      204006 :                 struct ldb_extended_dn_control *control;
     731      204006 :                 const char *p;
     732      204006 :                 int crit, type, ret;
     733             : 
     734     1893495 :                 p = &(control_strings[sizeof(LDB_CONTROL_EXTENDED_DN_NAME)]);
     735     1893495 :                 ret = sscanf(p, "%d:%d", &crit, &type);
     736     1893495 :                 if ((ret != 2) || (crit < 0) || (crit > 1) || (type < 0) || (type > 1)) {
     737         360 :                         ret = sscanf(p, "%d", &crit);
     738         360 :                         if ((ret != 1) || (crit < 0) || (crit > 1)) {
     739           0 :                                 ldb_set_errstring(ldb,
     740             :                                                   "invalid extended_dn control syntax\n"
     741             :                                                   " syntax: crit(b)[:type(i)]\n"
     742             :                                                   "   note: b = boolean\n"
     743             :                                                   "         i = integer\n"
     744             :                                                   "   valid values are: 0 - hexadecimal representation\n"
     745             :                                                   "                     1 - normal string representation");
     746           0 :                                 talloc_free(ctrl);
     747           0 :                                 return NULL;
     748             :                         }
     749         353 :                         control = NULL;
     750             :                 } else {
     751     1893135 :                         control = talloc(ctrl, struct ldb_extended_dn_control);
     752     1893135 :                         if (control == NULL) {
     753           0 :                                 ldb_oom(ldb);
     754           0 :                                 talloc_free(ctrl);
     755           0 :                                 return NULL;
     756             :                         }
     757     1893135 :                         control->type = type;
     758             :                 }
     759             : 
     760     1893495 :                 ctrl->oid = LDB_CONTROL_EXTENDED_DN_OID;
     761     1893495 :                 ctrl->critical = crit;
     762     1893495 :                 ctrl->data = control;
     763             : 
     764     1893495 :                 return ctrl;
     765             :         }
     766             : 
     767     8824649 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SD_FLAGS_NAME) == 0) {
     768      122890 :                 struct ldb_sd_flags_control *control;
     769      122890 :                 const char *p;
     770      122890 :                 int crit, ret;
     771      122890 :                 unsigned secinfo_flags;
     772             : 
     773     1314835 :                 p = &(control_strings[sizeof(LDB_CONTROL_SD_FLAGS_NAME)]);
     774     1314835 :                 ret = sscanf(p, "%d:%u", &crit, &secinfo_flags);
     775     1314835 :                 if ((ret != 2) || (crit < 0) || (crit > 1) || (secinfo_flags > 0xF)) {
     776           0 :                         ldb_set_errstring(ldb,
     777             :                                           "invalid sd_flags control syntax\n"
     778             :                                           " syntax: crit(b):secinfo_flags(n)\n"
     779             :                                           "   note: b = boolean, n = number");
     780           0 :                         talloc_free(ctrl);
     781           0 :                         return NULL;
     782             :                 }
     783             : 
     784     1314835 :                 ctrl->oid = LDB_CONTROL_SD_FLAGS_OID;
     785     1314835 :                 ctrl->critical = crit;
     786     1314835 :                 control = talloc(ctrl, struct ldb_sd_flags_control);
     787     1314835 :                 if (control == NULL) {
     788           0 :                         ldb_oom(ldb);
     789           0 :                         talloc_free(ctrl);
     790           0 :                         return NULL;
     791             :                 }
     792             : 
     793     1314835 :                 control->secinfo_flags = secinfo_flags;
     794     1314835 :                 ctrl->data = control;
     795             : 
     796     1314835 :                 return ctrl;
     797             :         }
     798             : 
     799     7509814 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SEARCH_OPTIONS_NAME) == 0) {
     800          58 :                 struct ldb_search_options_control *control;
     801          58 :                 const char *p;
     802          58 :                 int crit, ret;
     803          58 :                 unsigned search_options;
     804             : 
     805       28540 :                 p = &(control_strings[sizeof(LDB_CONTROL_SEARCH_OPTIONS_NAME)]);
     806       28540 :                 ret = sscanf(p, "%d:%u", &crit, &search_options);
     807       28540 :                 if ((ret != 2) || (crit < 0) || (crit > 1) || (search_options > 0xF)) {
     808           0 :                         ldb_set_errstring(ldb,
     809             :                                           "invalid search_options control syntax\n"
     810             :                                           " syntax: crit(b):search_options(n)\n"
     811             :                                           "   note: b = boolean, n = number");
     812           0 :                         talloc_free(ctrl);
     813           0 :                         return NULL;
     814             :                 }
     815             : 
     816       28540 :                 ctrl->oid = LDB_CONTROL_SEARCH_OPTIONS_OID;
     817       28540 :                 ctrl->critical = crit;
     818       28540 :                 control = talloc(ctrl, struct ldb_search_options_control);
     819       28540 :                 if (control == NULL) {
     820           0 :                         ldb_oom(ldb);
     821           0 :                         talloc_free(ctrl);
     822           0 :                         return NULL;
     823             :                 }
     824             : 
     825       28540 :                 control->search_options = search_options;
     826       28540 :                 ctrl->data = control;
     827             : 
     828       28540 :                 return ctrl;
     829             :         }
     830             : 
     831     7481274 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_BYPASS_OPERATIONAL_NAME) == 0) {
     832           1 :                 const char *p;
     833           1 :                 int crit, ret;
     834             : 
     835           6 :                 p = &(control_strings[sizeof(LDB_CONTROL_BYPASS_OPERATIONAL_NAME)]);
     836           6 :                 ret = sscanf(p, "%d", &crit);
     837           6 :                 if ((ret != 1) || (crit < 0) || (crit > 1)) {
     838           0 :                         ldb_set_errstring(ldb,
     839             :                                           "invalid bypassoperational control syntax\n"
     840             :                                           " syntax: crit(b)\n"
     841             :                                           "   note: b = boolean");
     842           0 :                         talloc_free(ctrl);
     843           0 :                         return NULL;
     844             :                 }
     845             : 
     846           6 :                 ctrl->oid = LDB_CONTROL_BYPASS_OPERATIONAL_OID;
     847           6 :                 ctrl->critical = crit;
     848           6 :                 ctrl->data = NULL;
     849             : 
     850           6 :                 return ctrl;
     851             :         }
     852             : 
     853     7481268 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_RELAX_NAME) == 0) {
     854       51332 :                 const char *p;
     855       51332 :                 int crit, ret;
     856             : 
     857      296893 :                 p = &(control_strings[sizeof(LDB_CONTROL_RELAX_NAME)]);
     858      296893 :                 ret = sscanf(p, "%d", &crit);
     859      296893 :                 if ((ret != 1) || (crit < 0) || (crit > 1)) {
     860           0 :                         ldb_set_errstring(ldb,
     861             :                                           "invalid relax control syntax\n"
     862             :                                           " syntax: crit(b)\n"
     863             :                                           "   note: b = boolean");
     864           0 :                         talloc_free(ctrl);
     865           0 :                         return NULL;
     866             :                 }
     867             : 
     868      296893 :                 ctrl->oid = LDB_CONTROL_RELAX_OID;
     869      296893 :                 ctrl->critical = crit;
     870      296893 :                 ctrl->data = NULL;
     871             : 
     872      296893 :                 return ctrl;
     873             :         }
     874             : 
     875     7184375 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_RECALCULATE_SD_NAME) == 0) {
     876           0 :                 const char *p;
     877           0 :                 int crit, ret;
     878             : 
     879           0 :                 p = &(control_strings[sizeof(LDB_CONTROL_RECALCULATE_SD_NAME)]);
     880           0 :                 ret = sscanf(p, "%d", &crit);
     881           0 :                 if ((ret != 1) || (crit < 0) || (crit > 1)) {
     882           0 :                         ldb_set_errstring(ldb,
     883             :                                           "invalid recalculate_sd control syntax\n"
     884             :                                           " syntax: crit(b)\n"
     885             :                                           "   note: b = boolean");
     886           0 :                         talloc_free(ctrl);
     887           0 :                         return NULL;
     888             :                 }
     889             : 
     890           0 :                 ctrl->oid = LDB_CONTROL_RECALCULATE_SD_OID;
     891           0 :                 ctrl->critical = crit;
     892           0 :                 ctrl->data = NULL;
     893             : 
     894           0 :                 return ctrl;
     895             :         }
     896             : 
     897     7184375 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_DOMAIN_SCOPE_NAME) == 0) {
     898           0 :                 const char *p;
     899           0 :                 int crit, ret;
     900             : 
     901          25 :                 p = &(control_strings[sizeof(LDB_CONTROL_DOMAIN_SCOPE_NAME)]);
     902          25 :                 ret = sscanf(p, "%d", &crit);
     903          25 :                 if ((ret != 1) || (crit < 0) || (crit > 1)) {
     904           0 :                         ldb_set_errstring(ldb,
     905             :                                           "invalid domain_scope control syntax\n"
     906             :                                           " syntax: crit(b)\n"
     907             :                                           "   note: b = boolean");
     908           0 :                         talloc_free(ctrl);
     909           0 :                         return NULL;
     910             :                 }
     911             : 
     912          25 :                 ctrl->oid = LDB_CONTROL_DOMAIN_SCOPE_OID;
     913          25 :                 ctrl->critical = crit;
     914          25 :                 ctrl->data = NULL;
     915             : 
     916          25 :                 return ctrl;
     917             :         }
     918             : 
     919     7184350 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_PAGED_RESULTS_NAME) == 0) {
     920          22 :                 struct ldb_paged_control *control;
     921          22 :                 const char *p;
     922          22 :                 char cookie[1024];
     923          22 :                 int crit, size, ret;
     924             : 
     925         365 :                 cookie[0] = '\0';
     926         365 :                 p = &(control_strings[sizeof(LDB_CONTROL_PAGED_RESULTS_NAME)]);
     927         365 :                 ret = sscanf(p, "%d:%d:%1023[^$]", &crit, &size, cookie);
     928         365 :                 if ((ret < 2) || (ret > 3) || (crit < 0) || (crit > 1) ||
     929         365 :                     (size < 0)) {
     930           0 :                         ldb_set_errstring(ldb,
     931             :                                 "invalid paged_results control syntax\n"
     932             :                                 " syntax: crit(b):size(n)[:cookie(base64)]\n"
     933             :                                 "   note: b = boolean, n = number");
     934           0 :                         talloc_free(ctrl);
     935           0 :                         return NULL;
     936             :                 }
     937             : 
     938         365 :                 ctrl->oid = LDB_CONTROL_PAGED_RESULTS_OID;
     939         365 :                 ctrl->critical = crit;
     940         365 :                 control = talloc(ctrl, struct ldb_paged_control);
     941         365 :                 if (control == NULL) {
     942           0 :                         ldb_oom(ldb);
     943           0 :                         talloc_free(ctrl);
     944           0 :                         return NULL;
     945             :                 }
     946             : 
     947         365 :                 control->size = size;
     948         365 :                 if (cookie[0] != '\0') {
     949          79 :                         int len = ldb_base64_decode(cookie);
     950          79 :                         if (len < 0) {
     951           0 :                                 ldb_set_errstring(ldb,
     952             :                                                   "invalid paged_results cookie"
     953             :                                                   " (probably too long)\n");
     954           0 :                                 talloc_free(ctrl);
     955           0 :                                 return NULL;
     956             :                         }
     957          79 :                         control->cookie_len = len;
     958          79 :                         control->cookie = talloc_memdup(control, cookie, control->cookie_len);
     959          79 :                         if (control->cookie == NULL) {
     960           0 :                                 ldb_oom(ldb);
     961           0 :                                 talloc_free(ctrl);
     962           0 :                                 return NULL;
     963             :                         }
     964             :                 } else {
     965         286 :                         control->cookie = NULL;
     966         286 :                         control->cookie_len = 0;
     967             :                 }
     968         365 :                 ctrl->data = control;
     969             : 
     970         365 :                 return ctrl;
     971             :         }
     972             : 
     973     7183985 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SERVER_SORT_NAME) == 0) {
     974          22 :                 struct ldb_server_sort_control **control;
     975          22 :                 const char *p;
     976          22 :                 char attr[256];
     977          22 :                 char rule[128];
     978          22 :                 int crit, rev, ret;
     979             : 
     980       53780 :                 attr[0] = '\0';
     981       53780 :                 rule[0] = '\0';
     982       53780 :                 p = &(control_strings[sizeof(LDB_CONTROL_SERVER_SORT_NAME)]);
     983       53780 :                 ret = sscanf(p, "%d:%d:%255[^:]:%127[^:]", &crit, &rev, attr, rule);
     984       53780 :                 if ((ret < 3) || (crit < 0) || (crit > 1) || (rev < 0 ) || (rev > 1) ||attr[0] == '\0') {
     985           0 :                         ldb_set_errstring(ldb,
     986             :                                           "invalid server_sort control syntax\n"
     987             :                                           " syntax: crit(b):rev(b):attr(s)[:rule(s)]\n"
     988             :                                           "   note: b = boolean, s = string");
     989           0 :                         talloc_free(ctrl);
     990           0 :                         return NULL;
     991             :                 }
     992       53780 :                 ctrl->oid = LDB_CONTROL_SERVER_SORT_OID;
     993       53780 :                 ctrl->critical = crit;
     994       53780 :                 control = talloc_array(ctrl, struct ldb_server_sort_control *, 2);
     995       53780 :                 if (control == NULL) {
     996           0 :                         ldb_oom(ldb);
     997           0 :                         talloc_free(ctrl);
     998           0 :                         return NULL;
     999             :                 }
    1000             : 
    1001       53780 :                 control[0] = talloc(control, struct ldb_server_sort_control);
    1002       53780 :                 if (control[0] == NULL) {
    1003           0 :                         ldb_oom(ldb);
    1004           0 :                         talloc_free(ctrl);
    1005           0 :                         return NULL;
    1006             :                 }
    1007             : 
    1008       53780 :                 control[0]->attributeName = talloc_strdup(control, attr);
    1009       53780 :                 if (control[0]->attributeName == NULL) {
    1010           0 :                         ldb_oom(ldb);
    1011           0 :                         talloc_free(ctrl);
    1012           0 :                         return NULL;
    1013             :                 }
    1014             : 
    1015       53780 :                 if (rule[0]) {
    1016          15 :                         control[0]->orderingRule = talloc_strdup(control, rule);
    1017          15 :                         if (control[0]->orderingRule == NULL) {
    1018           0 :                                 ldb_oom(ldb);
    1019           0 :                                 talloc_free(ctrl);
    1020           0 :                                 return NULL;
    1021             :                         }
    1022             :                 } else {
    1023       53765 :                         control[0]->orderingRule = NULL;
    1024             :                 }
    1025       53780 :                 control[0]->reverse = rev;
    1026       53780 :                 control[1] = NULL;
    1027       53780 :                 ctrl->data = control;
    1028             : 
    1029       53780 :                 return ctrl;
    1030             :         }
    1031             : 
    1032     7130205 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_NOTIFICATION_NAME) == 0) {
    1033           0 :                 const char *p;
    1034           0 :                 int crit, ret;
    1035             : 
    1036        1422 :                 p = &(control_strings[sizeof(LDB_CONTROL_NOTIFICATION_NAME)]);
    1037        1422 :                 ret = sscanf(p, "%d", &crit);
    1038        1422 :                 if ((ret != 1) || (crit < 0) || (crit > 1)) {
    1039           0 :                         ldb_set_errstring(ldb,
    1040             :                                           "invalid notification control syntax\n"
    1041             :                                           " syntax: crit(b)\n"
    1042             :                                           "   note: b = boolean");
    1043           0 :                         talloc_free(ctrl);
    1044           0 :                         return NULL;
    1045             :                 }
    1046             : 
    1047        1422 :                 ctrl->oid = LDB_CONTROL_NOTIFICATION_OID;
    1048        1422 :                 ctrl->critical = crit;
    1049        1422 :                 ctrl->data = NULL;
    1050             : 
    1051        1422 :                 return ctrl;
    1052             :         }
    1053             : 
    1054     7128783 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_TREE_DELETE_NAME) == 0) {
    1055           9 :                 const char *p;
    1056           9 :                 int crit, ret;
    1057             : 
    1058        3206 :                 p = &(control_strings[sizeof(LDB_CONTROL_TREE_DELETE_NAME)]);
    1059        3206 :                 ret = sscanf(p, "%d", &crit);
    1060        3206 :                 if ((ret != 1) || (crit < 0) || (crit > 1)) {
    1061           0 :                         ldb_set_errstring(ldb,
    1062             :                                           "invalid tree_delete control syntax\n"
    1063             :                                           " syntax: crit(b)\n"
    1064             :                                           "   note: b = boolean");
    1065           0 :                         talloc_free(ctrl);
    1066           0 :                         return NULL;
    1067             :                 }
    1068             : 
    1069        3206 :                 ctrl->oid = LDB_CONTROL_TREE_DELETE_OID;
    1070        3206 :                 ctrl->critical = crit;
    1071        3206 :                 ctrl->data = NULL;
    1072             : 
    1073        3206 :                 return ctrl;
    1074             :         }
    1075             : 
    1076     7125577 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SHOW_DELETED_NAME) == 0) {
    1077      177877 :                 const char *p;
    1078      177877 :                 int crit, ret;
    1079             : 
    1080     1870807 :                 p = &(control_strings[sizeof(LDB_CONTROL_SHOW_DELETED_NAME)]);
    1081     1870807 :                 ret = sscanf(p, "%d", &crit);
    1082     1870807 :                 if ((ret != 1) || (crit < 0) || (crit > 1)) {
    1083           0 :                         ldb_set_errstring(ldb,
    1084             :                                           "invalid show_deleted control syntax\n"
    1085             :                                           " syntax: crit(b)\n"
    1086             :                                           "   note: b = boolean");
    1087           0 :                         talloc_free(ctrl);
    1088           0 :                         return NULL;
    1089             :                 }
    1090             : 
    1091     1870807 :                 ctrl->oid = LDB_CONTROL_SHOW_DELETED_OID;
    1092     1870807 :                 ctrl->critical = crit;
    1093     1870807 :                 ctrl->data = NULL;
    1094             : 
    1095     1870807 :                 return ctrl;
    1096             :         }
    1097             : 
    1098     5254770 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SHOW_DEACTIVATED_LINK_NAME) == 0) {
    1099           2 :                 const char *p;
    1100           2 :                 int crit, ret;
    1101             : 
    1102          34 :                 p = &(control_strings[sizeof(LDB_CONTROL_SHOW_DEACTIVATED_LINK_NAME)]);
    1103          34 :                 ret = sscanf(p, "%d", &crit);
    1104          34 :                 if ((ret != 1) || (crit < 0) || (crit > 1)) {
    1105           0 :                         ldb_set_errstring(ldb,
    1106             :                                           "invalid show_deactivated_link control syntax\n"
    1107             :                                           " syntax: crit(b)\n"
    1108             :                                           "   note: b = boolean");
    1109           0 :                         talloc_free(ctrl);
    1110           0 :                         return NULL;
    1111             :                 }
    1112             : 
    1113          34 :                 ctrl->oid = LDB_CONTROL_SHOW_DEACTIVATED_LINK_OID;
    1114          34 :                 ctrl->critical = crit;
    1115          34 :                 ctrl->data = NULL;
    1116             : 
    1117          34 :                 return ctrl;
    1118             :         }
    1119             : 
    1120     5254736 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SHOW_RECYCLED_NAME) == 0) {
    1121      262137 :                 const char *p;
    1122      262137 :                 int crit, ret;
    1123             : 
    1124     2591087 :                 p = &(control_strings[sizeof(LDB_CONTROL_SHOW_RECYCLED_NAME)]);
    1125     2591087 :                 ret = sscanf(p, "%d", &crit);
    1126     2591087 :                 if ((ret != 1) || (crit < 0) || (crit > 1)) {
    1127           0 :                         ldb_set_errstring(ldb,
    1128             :                                           "invalid show_recycled control syntax\n"
    1129             :                                           " syntax: crit(b)\n"
    1130             :                                           "   note: b = boolean");
    1131           0 :                         talloc_free(ctrl);
    1132           0 :                         return NULL;
    1133             :                 }
    1134             : 
    1135     2591087 :                 ctrl->oid = LDB_CONTROL_SHOW_RECYCLED_OID;
    1136     2591087 :                 ctrl->critical = crit;
    1137     2591087 :                 ctrl->data = NULL;
    1138             : 
    1139     2591087 :                 return ctrl;
    1140             :         }
    1141             : 
    1142     2663649 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_PERMISSIVE_MODIFY_NAME) == 0) {
    1143           0 :                 const char *p;
    1144           0 :                 int crit, ret;
    1145             : 
    1146         252 :                 p = &(control_strings[sizeof(LDB_CONTROL_PERMISSIVE_MODIFY_NAME)]);
    1147         252 :                 ret = sscanf(p, "%d", &crit);
    1148         252 :                 if ((ret != 1) || (crit < 0) || (crit > 1)) {
    1149           0 :                         ldb_set_errstring(ldb,
    1150             :                                           "invalid permissive_modify control syntax\n"
    1151             :                                           " syntax: crit(b)\n"
    1152             :                                           "   note: b = boolean");
    1153           0 :                         talloc_free(ctrl);
    1154           0 :                         return NULL;
    1155             :                 }
    1156             : 
    1157         252 :                 ctrl->oid = LDB_CONTROL_PERMISSIVE_MODIFY_OID;
    1158         252 :                 ctrl->critical = crit;
    1159         252 :                 ctrl->data = NULL;
    1160             : 
    1161         252 :                 return ctrl;
    1162             :         }
    1163             : 
    1164     2663397 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_REVEAL_INTERNALS_NAME) == 0) {
    1165      201458 :                 const char *p;
    1166      201458 :                 int crit, ret;
    1167             : 
    1168     1880340 :                 p = &(control_strings[sizeof(LDB_CONTROL_REVEAL_INTERNALS_NAME)]);
    1169     1880340 :                 ret = sscanf(p, "%d", &crit);
    1170     1880340 :                 if ((ret != 1) || (crit < 0) || (crit > 1)) {
    1171           0 :                         ldb_set_errstring(ldb,
    1172             :                                           "invalid reveal_internals control syntax\n"
    1173             :                                           " syntax: crit(b)\n"
    1174             :                                           "   note: b = boolean");
    1175           0 :                         talloc_free(ctrl);
    1176           0 :                         return NULL;
    1177             :                 }
    1178             : 
    1179     1880340 :                 ctrl->oid = LDB_CONTROL_REVEAL_INTERNALS;
    1180     1880340 :                 ctrl->critical = crit;
    1181     1880340 :                 ctrl->data = NULL;
    1182             : 
    1183     1880340 :                 return ctrl;
    1184             :         }
    1185             : 
    1186      783057 :         if (strncmp(control_strings, "local_oid:", 10) == 0) {
    1187       82279 :                 const char *p;
    1188      557035 :                 int crit = 0, ret = 0;
    1189       82279 :                 char oid[256];
    1190             : 
    1191      557035 :                 oid[0] = '\0';
    1192      557035 :                 p = &(control_strings[10]);
    1193      557035 :                 ret = sscanf(p, "%255[^:]:%d", oid, &crit);
    1194             : 
    1195      557035 :                 if ((ret != 2) || strlen(oid) == 0 || (crit < 0) || (crit > 1)) {
    1196           0 :                         ldb_set_errstring(ldb,
    1197             :                                           "invalid local_oid control syntax\n"
    1198             :                                           " syntax: oid(s):crit(b)\n"
    1199             :                                           "   note: b = boolean, s = string");
    1200           0 :                         talloc_free(ctrl);
    1201           0 :                         return NULL;
    1202             :                 }
    1203             : 
    1204      557035 :                 ctrl->oid = talloc_strdup(ctrl, oid);
    1205      557035 :                 if (!ctrl->oid) {
    1206           0 :                         ldb_oom(ldb);
    1207           0 :                         talloc_free(ctrl);
    1208           0 :                         return NULL;
    1209             :                 }
    1210      557035 :                 ctrl->critical = crit;
    1211      557035 :                 ctrl->data = NULL;
    1212             : 
    1213      557035 :                 return ctrl;
    1214             :         }
    1215             : 
    1216      226022 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_RODC_DCPROMO_NAME) == 0) {
    1217           0 :                 const char *p;
    1218           0 :                 int crit, ret;
    1219             : 
    1220         184 :                 p = &(control_strings[sizeof(LDB_CONTROL_RODC_DCPROMO_NAME)]);
    1221         184 :                 ret = sscanf(p, "%d", &crit);
    1222         184 :                 if ((ret != 1) || (crit < 0) || (crit > 1)) {
    1223           0 :                         ldb_set_errstring(ldb,
    1224             :                                           "invalid rodc_join control syntax\n"
    1225             :                                           " syntax: crit(b)\n"
    1226             :                                           "   note: b = boolean");
    1227           0 :                         talloc_free(ctrl);
    1228           0 :                         return NULL;
    1229             :                 }
    1230             : 
    1231         184 :                 ctrl->oid = LDB_CONTROL_RODC_DCPROMO_OID;
    1232         184 :                 ctrl->critical = crit;
    1233         184 :                 ctrl->data = NULL;
    1234             : 
    1235         184 :                 return ctrl;
    1236             :         }
    1237             : 
    1238      225838 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_PROVISION_NAME) == 0) {
    1239       40570 :                 const char *p;
    1240       40570 :                 int crit, ret;
    1241             : 
    1242      225834 :                 p = &(control_strings[sizeof(LDB_CONTROL_PROVISION_NAME)]);
    1243      225834 :                 ret = sscanf(p, "%d", &crit);
    1244      225834 :                 if ((ret != 1) || (crit < 0) || (crit > 1)) {
    1245           0 :                         ldb_set_errstring(ldb,
    1246             :                                           "invalid provision control syntax\n"
    1247             :                                           " syntax: crit(b)\n"
    1248             :                                           "   note: b = boolean");
    1249           0 :                         talloc_free(ctrl);
    1250           0 :                         return NULL;
    1251             :                 }
    1252             : 
    1253      225834 :                 ctrl->oid = LDB_CONTROL_PROVISION_OID;
    1254      225834 :                 ctrl->critical = crit;
    1255      225834 :                 ctrl->data = NULL;
    1256             : 
    1257      225834 :                 return ctrl;
    1258             :         }
    1259           4 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_VERIFY_NAME_NAME) == 0) {
    1260           0 :                 const char *p;
    1261           0 :                 char gc[1024];
    1262           0 :                 int crit, flags, ret;
    1263           0 :                 struct ldb_verify_name_control *control;
    1264             : 
    1265           0 :                 gc[0] = '\0';
    1266             : 
    1267           0 :                 p = &(control_strings[sizeof(LDB_CONTROL_VERIFY_NAME_NAME)]);
    1268           0 :                 ret = sscanf(p, "%d:%d:%1023[^$]", &crit, &flags, gc);
    1269           0 :                 if ((ret != 3) || (crit < 0) || (crit > 1)) {
    1270           0 :                         ret = sscanf(p, "%d:%d", &crit, &flags);
    1271           0 :                         if ((ret != 2) || (crit < 0) || (crit > 1)) {
    1272           0 :                                 ldb_set_errstring(ldb,
    1273             :                                                   "invalid verify_name control syntax\n"
    1274             :                                                   " syntax: crit(b):flags(i)[:gc(s)]\n"
    1275             :                                                   "   note: b = boolean"
    1276             :                                                   "   note: i = integer"
    1277             :                                                   "   note: s = string");
    1278           0 :                                 talloc_free(ctrl);
    1279           0 :                                 return NULL;
    1280             :                         }
    1281             :                 }
    1282             : 
    1283           0 :                 ctrl->oid = LDB_CONTROL_VERIFY_NAME_OID;
    1284           0 :                 ctrl->critical = crit;
    1285           0 :                 control = talloc(ctrl, struct ldb_verify_name_control);
    1286           0 :                 if (control == NULL) {
    1287           0 :                         ldb_oom(ldb);
    1288           0 :                         talloc_free(ctrl);
    1289           0 :                         return NULL;
    1290             :                 }
    1291             : 
    1292           0 :                 control->gc = talloc_strdup(control, gc);
    1293           0 :                 if (control->gc == NULL) {
    1294           0 :                         ldb_oom(ldb);
    1295           0 :                         talloc_free(ctrl);
    1296           0 :                         return NULL;
    1297             :                 }
    1298             : 
    1299           0 :                 control->gc_len = strlen(gc);
    1300           0 :                 control->flags = flags;
    1301           0 :                 ctrl->data = control;
    1302           0 :                 return ctrl;
    1303             :         }
    1304             :         /*
    1305             :          * When no matching control has been found.
    1306             :          */
    1307           4 :         TALLOC_FREE(ctrl);
    1308           4 :         return NULL;
    1309             : }
    1310             : 
    1311             : /* Parse controls from the format used on the command line and in ejs */
    1312     3046919 : struct ldb_control **ldb_parse_control_strings(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char **control_strings)
    1313             : {
    1314      324443 :         unsigned int i;
    1315      324443 :         struct ldb_control **ctrl;
    1316             : 
    1317     3046919 :         if (control_strings == NULL || control_strings[0] == NULL)
    1318        2684 :                 return NULL;
    1319             : 
    1320    13815675 :         for (i = 0; control_strings[i]; i++);
    1321             : 
    1322     3043965 :         ctrl = talloc_array(mem_ctx, struct ldb_control *, i + 1);
    1323             : 
    1324     3043965 :         ldb_reset_err_string(ldb);
    1325    14139848 :         for (i = 0; control_strings[i]; i++) {
    1326    10771710 :                 ctrl[i] = ldb_parse_control_from_string(ldb, ctrl, control_strings[i]);
    1327    10771710 :                 if (ctrl[i] == NULL) {
    1328           0 :                         if (ldb_errstring(ldb) == NULL) {
    1329             :                                 /* no controls matched, throw an error */
    1330           0 :                                 ldb_asprintf_errstring(ldb, "Invalid control name: '%s'", control_strings[i]);
    1331             :                         }
    1332           0 :                         talloc_free(ctrl);
    1333           0 :                         return NULL;
    1334             :                 }
    1335             :         }
    1336             : 
    1337     3043965 :         ctrl[i] = NULL;
    1338             : 
    1339     3043965 :         return ctrl;
    1340             : }
    1341             : 
    1342             : 

Generated by: LCOV version 1.14