LCOV - code coverage report
Current view: top level - lib/ldb/common - ldb_controls.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 380 665 57.1 %
Date: 2024-06-13 04:01:37 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  1423371033 : struct ldb_control *ldb_request_get_control(struct ldb_request *req, const char *oid)
      39             : {
      40             :         unsigned int i;
      41             : 
      42  1423371033 :         if (req->controls != NULL) {
      43  4070988629 :                 for (i = 0; req->controls[i]; i++) {
      44  2986907522 :                         if (req->controls[i]->oid && strcmp(oid, req->controls[i]->oid) == 0) {
      45   152910535 :                                 break;
      46             :                         }
      47             :                 }
      48             : 
      49  1236991642 :                 return req->controls[i];
      50             :         }
      51             : 
      52   186379391 :         return NULL;
      53             : }
      54             : 
      55             : /* check if a control with the specified "oid" exist and return it */
      56             : /* returns NULL if not found */
      57     4825796 : struct ldb_control *ldb_reply_get_control(struct ldb_reply *rep, const char *oid)
      58             : {
      59             :         unsigned int i;
      60             : 
      61     4825796 :         if (rep->controls != NULL) {
      62     4845870 :                 for (i = 0; rep->controls[i]; i++) {
      63     4832367 :                         if (rep->controls[i]->oid && strcmp(oid, rep->controls[i]->oid) == 0) {
      64     4807154 :                                 break;
      65             :                         }
      66             :                 }
      67             : 
      68     4820657 :                 return rep->controls[i];
      69             :         }
      70             : 
      71        5139 :         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   105455187 : int ldb_save_controls(struct ldb_control *exclude, struct ldb_request *req, struct ldb_control ***saver)
      82             : {
      83             :         struct ldb_control **lcs, **lcs_old;
      84             :         unsigned int i, j;
      85             : 
      86   105455187 :         lcs_old = req->controls;
      87   105455187 :         if (saver != NULL) {
      88        8899 :                 *saver = lcs_old;
      89             :         }
      90             : 
      91   142368514 :         for (i = 0; req->controls && req->controls[i]; i++);
      92   105455187 :         if (i == 0) {
      93         144 :                 req->controls = NULL;
      94         144 :                 return 1;
      95             :         }
      96             : 
      97   105455043 :         lcs = talloc_array(req, struct ldb_control *, i + 1);
      98   105455043 :         if (!lcs) {
      99           0 :                 return 0;
     100             :         }
     101             : 
     102   432522533 :         for (i = 0, j = 0; lcs_old[i]; i++) {
     103   327067490 :                 if (exclude == lcs_old[i]) continue;
     104   321981786 :                 lcs[j] = lcs_old[i];
     105   321981786 :                 j++;
     106             :         }
     107   105455043 :         lcs[j] = NULL;
     108             : 
     109   105455043 :         req->controls = talloc_realloc(req, lcs, struct ldb_control *, j + 1);
     110   105455043 :         if (req->controls == NULL) {
     111           0 :                 return 0;
     112             :         }
     113   105455043 :         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     1210331 : struct ldb_control **ldb_controls_except_specified(struct ldb_control **controls_in, 
     124             :                                                TALLOC_CTX *mem_ctx, 
     125             :                                                struct ldb_control *exclude)
     126             : {
     127     1210331 :         struct ldb_control **lcs = NULL;
     128             :         unsigned int i, j, n;
     129             : 
     130     1335592 :         for (i = 0; controls_in && controls_in[i]; i++);
     131     1210331 :         if (i == 0) {
     132           0 :                 return NULL;
     133             :         }
     134     1210331 :         n = i;
     135             : 
     136     2420662 :         for (i = 0, j = 0; controls_in && controls_in[i]; i++) {
     137     1210331 :                 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     1210331 :         if (lcs) {
     156           0 :                 lcs[j] = NULL;
     157             : 
     158           0 :                 lcs = talloc_realloc(mem_ctx, lcs, struct ldb_control *, j + 1);
     159             :         }
     160             : 
     161     1210331 :         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             :         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   121686685 : int ldb_request_add_control(struct ldb_request *req, const char *oid, bool critical, void *data)
     184             : {
     185             :         unsigned int i, n;
     186             :         struct ldb_control **ctrls;
     187             :         struct ldb_control *ctrl;
     188             : 
     189   261500867 :         for (n=0; req->controls && req->controls[n];n++) { 
     190             :                 /* having two controls of the same OID makes no sense */
     191   139814182 :                 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   121686685 :         ctrls = talloc_array(req,
     197             :                                struct ldb_control *,
     198             :                                n + 2);
     199   121686685 :         if (!ctrls) return LDB_ERR_OPERATIONS_ERROR;
     200             : 
     201   261500867 :         for (i=0; i<n; i++) {
     202   139814182 :                 ctrls[i] = req->controls[i];
     203             :         }
     204             : 
     205   121686685 :         req->controls = ctrls;
     206   121686685 :         ctrls[n] = NULL;
     207   121686685 :         ctrls[n+1] = NULL;
     208             : 
     209   121686685 :         ctrl = talloc(ctrls, struct ldb_control);
     210   121686685 :         if (!ctrl) return LDB_ERR_OPERATIONS_ERROR;
     211             : 
     212   121686685 :         ctrl->oid    = talloc_strdup(ctrl, oid);
     213   121686685 :         if (!ctrl->oid) return LDB_ERR_OPERATIONS_ERROR;
     214   121686685 :         ctrl->critical       = critical;
     215   121686685 :         ctrl->data   = data;
     216             : 
     217   121686685 :         ctrls[n] = ctrl;
     218   121686685 :         return LDB_SUCCESS;
     219             : }
     220             : 
     221     7843277 : int ldb_reply_add_control(struct ldb_reply *ares, const char *oid, bool critical, void *data)
     222             : {
     223             :         unsigned n;
     224             :         struct ldb_control **ctrls;
     225             :         struct ldb_control *ctrl;
     226             : 
     227    14787401 :         for (n=0; ares->controls && ares->controls[n];) { 
     228             :                 /* having two controls of the same OID makes no sense */
     229        7051 :                 if (ares->controls[n]->oid && strcmp(oid, ares->controls[n]->oid) == 0) {
     230           0 :                         return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS;
     231             :                 }
     232        7051 :                 n++; 
     233             :         }
     234             : 
     235     7843277 :         ctrls = talloc_realloc(ares, ares->controls,
     236             :                                struct ldb_control *,
     237             :                                n + 2);
     238     7843277 :         if (!ctrls) return LDB_ERR_OPERATIONS_ERROR;
     239     7843277 :         ares->controls = ctrls;
     240     7843277 :         ctrls[n] = NULL;
     241     7843277 :         ctrls[n+1] = NULL;
     242             : 
     243     7843277 :         ctrl = talloc(ctrls, struct ldb_control);
     244     7843277 :         if (!ctrl) return LDB_ERR_OPERATIONS_ERROR;
     245             : 
     246     7843277 :         ctrl->oid    = talloc_strdup(ctrl, oid);
     247     7843277 :         if (!ctrl->oid) return LDB_ERR_OPERATIONS_ERROR;
     248     7843277 :         ctrl->critical       = critical;
     249     7843277 :         ctrl->data   = data;
     250             : 
     251     7843277 :         ctrls[n] = ctrl;
     252     7843277 :         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             :         unsigned int n;
     259             :         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       46557 : char *ldb_control_to_string(TALLOC_CTX *mem_ctx, const struct ldb_control *control)
     283             : {
     284       46557 :         char *res = NULL;
     285             : 
     286       46557 :         if (strcmp(control->oid, LDB_CONTROL_PAGED_RESULTS_OID) == 0) {
     287         203 :                 struct ldb_paged_control *rep_control = talloc_get_type(control->data, struct ldb_paged_control);
     288             :                 char *cookie;
     289         203 :                 if (rep_control == NULL) {
     290           0 :                         return NULL;
     291             :                 }
     292             : 
     293         203 :                 cookie = ldb_base64_encode(mem_ctx, rep_control->cookie, rep_control->cookie_len);
     294         203 :                 if (cookie == NULL) {
     295           0 :                         return NULL;
     296             :                 }
     297         203 :                 if (cookie[0] != '\0') {
     298         159 :                         res = talloc_asprintf(mem_ctx, "%s:%d:%s",
     299             :                                                 LDB_CONTROL_PAGED_RESULTS_NAME,
     300           0 :                                                 control->critical,
     301             :                                                 cookie);
     302             : 
     303         159 :                         talloc_free(cookie);
     304             :                 } else {
     305          44 :                         res = talloc_asprintf(mem_ctx, "%s:%d",
     306             :                                                 LDB_CONTROL_PAGED_RESULTS_NAME,
     307           0 :                                                 control->critical);
     308             :                 }
     309         203 :                 return res;
     310             :         }
     311             : 
     312       46354 :         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             :                 char *cookie;
     317             : 
     318       45308 :                 if (rep_control == NULL) {
     319           0 :                         return NULL;
     320             :                 }
     321             : 
     322       90616 :                 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           0 :                                                 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        1046 :         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        1046 :         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_SORT_RESP_NAME,
     365           0 :                                         control->critical,
     366             :                                         rep_control->result);
     367             : 
     368           0 :                 return res;
     369             :         }
     370             : 
     371        1046 :         if (strcmp(control->oid, LDB_CONTROL_DIRSYNC_OID) == 0) {
     372             :                 char *cookie;
     373        1046 :                 struct ldb_dirsync_control *rep_control = talloc_get_type(control->data,
     374             :                                                                 struct ldb_dirsync_control);
     375             : 
     376        1046 :                 if (rep_control == NULL) {
     377           0 :                         return NULL;
     378             :                 }
     379        1046 :                 cookie = ldb_base64_encode(mem_ctx, rep_control->cookie,
     380             :                                 rep_control->cookie_len);
     381        1046 :                 if (cookie == NULL) {
     382           0 :                         return NULL;
     383             :                 }
     384        1046 :                 res = talloc_asprintf(mem_ctx, "%s:%d:%d:%d:%s",
     385             :                                         LDB_CONTROL_DIRSYNC_NAME,
     386           0 :                                         control->critical,
     387             :                                         rep_control->flags,
     388             :                                         rep_control->max_attributes,
     389             :                                         cookie);
     390             : 
     391        1046 :                 talloc_free(cookie);
     392        1046 :                 return res;
     393             :         }
     394           0 :         if (strcmp(control->oid, LDB_CONTROL_DIRSYNC_EX_OID) == 0) {
     395             :                 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     6785278 : struct ldb_control *ldb_parse_control_from_string(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *control_strings)
     469             : {
     470             :         struct ldb_control *ctrl;
     471             : 
     472     6785278 :         if (!(ctrl = talloc(mem_ctx, struct ldb_control))) {
     473           0 :                 ldb_oom(ldb);
     474           0 :                 return NULL;
     475             :         }
     476             : 
     477     6785278 :         if (LDB_CONTROL_CMP(control_strings,
     478             :                                 LDB_CONTROL_VLV_REQ_NAME) == 0) {
     479             :                 struct ldb_vlv_req_control *control;
     480             :                 const char *p;
     481             :                 char attr[1024];
     482             :                 char ctxid[1024];
     483             :                 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             :                         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     6732245 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_DIRSYNC_NAME) == 0) {
     558             :                 struct ldb_dirsync_control *control;
     559             :                 const char *p;
     560         422 :                 char *cookie = NULL;
     561             :                 int crit, max_attrs, ret;
     562             :                 uint32_t flags;
     563             : 
     564         422 :                 cookie = talloc_zero_array(ctrl, char,
     565             :                                            strlen(control_strings) + 1);
     566         422 :                 if (cookie == NULL) {
     567           0 :                         ldb_oom(ldb);
     568           0 :                         talloc_free(ctrl);
     569           0 :                         return NULL;
     570             :                 }
     571             : 
     572         422 :                 p = &(control_strings[sizeof(LDB_CONTROL_DIRSYNC_NAME)]);
     573         422 :                 ret = sscanf(p, "%d:%u:%d:%[^$]", &crit, &flags, &max_attrs, cookie);
     574             : 
     575         422 :                 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         422 :                 if (max_attrs == 0) max_attrs = 0x0FFFFFFF;
     590             : 
     591         422 :                 ctrl->oid = LDB_CONTROL_DIRSYNC_OID;
     592         422 :                 ctrl->critical = crit;
     593         422 :                 control = talloc(ctrl, struct ldb_dirsync_control);
     594         422 :                 if (control == NULL) {
     595           0 :                         ldb_oom(ldb);
     596           0 :                         talloc_free(ctrl);
     597           0 :                         return NULL;
     598             :                 }
     599         422 :                 control->flags = flags;
     600         422 :                 control->max_attributes = max_attrs;
     601         422 :                 if (*cookie) {
     602          41 :                         int len = ldb_base64_decode(cookie);
     603          41 :                         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          41 :                         control->cookie_len = len;
     610          41 :                         control->cookie = (char *)talloc_memdup(control, cookie, control->cookie_len);
     611          41 :                         if (control->cookie == NULL) {
     612           0 :                                 ldb_oom(ldb);
     613           0 :                                 talloc_free(ctrl);
     614           0 :                                 return NULL;
     615             :                         }
     616             :                 } else {
     617         381 :                         control->cookie = NULL;
     618         381 :                         control->cookie_len = 0;
     619             :                 }
     620         422 :                 ctrl->data = control;
     621         422 :                 TALLOC_FREE(cookie);
     622             : 
     623         422 :                 return ctrl;
     624             :         }
     625     6731823 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_DIRSYNC_EX_NAME) == 0) {
     626             :                 struct ldb_dirsync_control *control;
     627             :                 const char *p;
     628           0 :                 char *cookie = NULL;
     629             :                 int crit, max_attrs, ret;
     630             :                 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     6731823 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_ASQ_NAME) == 0) {
     696             :                 struct ldb_asq_control *control;
     697             :                 const char *p;
     698             :                 char attr[256];
     699             :                 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     6731808 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_EXTENDED_DN_NAME) == 0) {
     730             :                 struct ldb_extended_dn_control *control;
     731             :                 const char *p;
     732             :                 int crit, type, ret;
     733             : 
     734     1162031 :                 p = &(control_strings[sizeof(LDB_CONTROL_EXTENDED_DN_NAME)]);
     735     1162031 :                 ret = sscanf(p, "%d:%d", &crit, &type);
     736     1162031 :                 if ((ret != 2) || (crit < 0) || (crit > 1) || (type < 0) || (type > 1)) {
     737         293 :                         ret = sscanf(p, "%d", &crit);
     738         293 :                         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         293 :                         control = NULL;
     750             :                 } else {
     751     1161738 :                         control = talloc(ctrl, struct ldb_extended_dn_control);
     752     1161738 :                         if (control == NULL) {
     753           0 :                                 ldb_oom(ldb);
     754           0 :                                 talloc_free(ctrl);
     755           0 :                                 return NULL;
     756             :                         }
     757     1161738 :                         control->type = type;
     758             :                 }
     759             : 
     760     1162031 :                 ctrl->oid = LDB_CONTROL_EXTENDED_DN_OID;
     761     1162031 :                 ctrl->critical = crit;
     762     1162031 :                 ctrl->data = control;
     763             : 
     764     1162031 :                 return ctrl;
     765             :         }
     766             : 
     767     5569777 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SD_FLAGS_NAME) == 0) {
     768             :                 struct ldb_sd_flags_control *control;
     769             :                 const char *p;
     770             :                 int crit, ret;
     771             :                 unsigned secinfo_flags;
     772             : 
     773      848212 :                 p = &(control_strings[sizeof(LDB_CONTROL_SD_FLAGS_NAME)]);
     774      848212 :                 ret = sscanf(p, "%d:%u", &crit, &secinfo_flags);
     775      848212 :                 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      848212 :                 ctrl->oid = LDB_CONTROL_SD_FLAGS_OID;
     785      848212 :                 ctrl->critical = crit;
     786      848212 :                 control = talloc(ctrl, struct ldb_sd_flags_control);
     787      848212 :                 if (control == NULL) {
     788           0 :                         ldb_oom(ldb);
     789           0 :                         talloc_free(ctrl);
     790           0 :                         return NULL;
     791             :                 }
     792             : 
     793      848212 :                 control->secinfo_flags = secinfo_flags;
     794      848212 :                 ctrl->data = control;
     795             : 
     796      848212 :                 return ctrl;
     797             :         }
     798             : 
     799     4721565 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SEARCH_OPTIONS_NAME) == 0) {
     800             :                 struct ldb_search_options_control *control;
     801             :                 const char *p;
     802             :                 int crit, ret;
     803             :                 unsigned search_options;
     804             : 
     805       28218 :                 p = &(control_strings[sizeof(LDB_CONTROL_SEARCH_OPTIONS_NAME)]);
     806       28218 :                 ret = sscanf(p, "%d:%u", &crit, &search_options);
     807       28218 :                 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       28218 :                 ctrl->oid = LDB_CONTROL_SEARCH_OPTIONS_OID;
     817       28218 :                 ctrl->critical = crit;
     818       28218 :                 control = talloc(ctrl, struct ldb_search_options_control);
     819       28218 :                 if (control == NULL) {
     820           0 :                         ldb_oom(ldb);
     821           0 :                         talloc_free(ctrl);
     822           0 :                         return NULL;
     823             :                 }
     824             : 
     825       28218 :                 control->search_options = search_options;
     826       28218 :                 ctrl->data = control;
     827             : 
     828       28218 :                 return ctrl;
     829             :         }
     830             : 
     831     4693347 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_BYPASS_OPERATIONAL_NAME) == 0) {
     832             :                 const char *p;
     833             :                 int crit, ret;
     834             : 
     835           5 :                 p = &(control_strings[sizeof(LDB_CONTROL_BYPASS_OPERATIONAL_NAME)]);
     836           5 :                 ret = sscanf(p, "%d", &crit);
     837           5 :                 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           5 :                 ctrl->oid = LDB_CONTROL_BYPASS_OPERATIONAL_OID;
     847           5 :                 ctrl->critical = crit;
     848           5 :                 ctrl->data = NULL;
     849             : 
     850           5 :                 return ctrl;
     851             :         }
     852             : 
     853     4693342 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_RELAX_NAME) == 0) {
     854             :                 const char *p;
     855             :                 int crit, ret;
     856             : 
     857      178059 :                 p = &(control_strings[sizeof(LDB_CONTROL_RELAX_NAME)]);
     858      178059 :                 ret = sscanf(p, "%d", &crit);
     859      178059 :                 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      178059 :                 ctrl->oid = LDB_CONTROL_RELAX_OID;
     869      178059 :                 ctrl->critical = crit;
     870      178059 :                 ctrl->data = NULL;
     871             : 
     872      178059 :                 return ctrl;
     873             :         }
     874             : 
     875     4515283 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_RECALCULATE_SD_NAME) == 0) {
     876             :                 const char *p;
     877             :                 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     4515283 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_DOMAIN_SCOPE_NAME) == 0) {
     898             :                 const char *p;
     899             :                 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     4515258 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_PAGED_RESULTS_NAME) == 0) {
     920             :                 struct ldb_paged_control *control;
     921             :                 const char *p;
     922             :                 char cookie[1024];
     923             :                 int crit, size, ret;
     924             : 
     925         307 :                 cookie[0] = '\0';
     926         307 :                 p = &(control_strings[sizeof(LDB_CONTROL_PAGED_RESULTS_NAME)]);
     927         307 :                 ret = sscanf(p, "%d:%d:%1023[^$]", &crit, &size, cookie);
     928         599 :                 if ((ret < 2) || (ret > 3) || (crit < 0) || (crit > 1) ||
     929         307 :                     (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         307 :                 ctrl->oid = LDB_CONTROL_PAGED_RESULTS_OID;
     939         307 :                 ctrl->critical = crit;
     940         307 :                 control = talloc(ctrl, struct ldb_paged_control);
     941         307 :                 if (control == NULL) {
     942           0 :                         ldb_oom(ldb);
     943           0 :                         talloc_free(ctrl);
     944           0 :                         return NULL;
     945             :                 }
     946             : 
     947         307 :                 control->size = size;
     948         307 :                 if (cookie[0] != '\0') {
     949          74 :                         int len = ldb_base64_decode(cookie);
     950          74 :                         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          74 :                         control->cookie_len = len;
     958          74 :                         control->cookie = talloc_memdup(control, cookie, control->cookie_len);
     959          74 :                         if (control->cookie == NULL) {
     960           0 :                                 ldb_oom(ldb);
     961           0 :                                 talloc_free(ctrl);
     962           0 :                                 return NULL;
     963             :                         }
     964             :                 } else {
     965         233 :                         control->cookie = NULL;
     966         233 :                         control->cookie_len = 0;
     967             :                 }
     968         307 :                 ctrl->data = control;
     969             : 
     970         307 :                 return ctrl;
     971             :         }
     972             : 
     973     4514951 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SERVER_SORT_NAME) == 0) {
     974             :                 struct ldb_server_sort_control **control;
     975             :                 const char *p;
     976             :                 char attr[256];
     977             :                 char rule[128];
     978             :                 int crit, rev, ret;
     979             : 
     980       53726 :                 attr[0] = '\0';
     981       53726 :                 rule[0] = '\0';
     982       53726 :                 p = &(control_strings[sizeof(LDB_CONTROL_SERVER_SORT_NAME)]);
     983       53726 :                 ret = sscanf(p, "%d:%d:%255[^:]:%127[^:]", &crit, &rev, attr, rule);
     984       53726 :                 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       53726 :                 ctrl->oid = LDB_CONTROL_SERVER_SORT_OID;
     993       53726 :                 ctrl->critical = crit;
     994       53726 :                 control = talloc_array(ctrl, struct ldb_server_sort_control *, 2);
     995       53726 :                 if (control == NULL) {
     996           0 :                         ldb_oom(ldb);
     997           0 :                         talloc_free(ctrl);
     998           0 :                         return NULL;
     999             :                 }
    1000             : 
    1001       53726 :                 control[0] = talloc(control, struct ldb_server_sort_control);
    1002       53726 :                 if (control[0] == NULL) {
    1003           0 :                         ldb_oom(ldb);
    1004           0 :                         talloc_free(ctrl);
    1005           0 :                         return NULL;
    1006             :                 }
    1007             : 
    1008       53726 :                 control[0]->attributeName = talloc_strdup(control, attr);
    1009       53726 :                 if (control[0]->attributeName == NULL) {
    1010           0 :                         ldb_oom(ldb);
    1011           0 :                         talloc_free(ctrl);
    1012           0 :                         return NULL;
    1013             :                 }
    1014             : 
    1015       53726 :                 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       53711 :                         control[0]->orderingRule = NULL;
    1024             :                 }
    1025       53726 :                 control[0]->reverse = rev;
    1026       53726 :                 control[1] = NULL;
    1027       53726 :                 ctrl->data = control;
    1028             : 
    1029       53726 :                 return ctrl;
    1030             :         }
    1031             : 
    1032     4461225 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_NOTIFICATION_NAME) == 0) {
    1033             :                 const char *p;
    1034             :                 int crit, ret;
    1035             : 
    1036        1529 :                 p = &(control_strings[sizeof(LDB_CONTROL_NOTIFICATION_NAME)]);
    1037        1529 :                 ret = sscanf(p, "%d", &crit);
    1038        1529 :                 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        1529 :                 ctrl->oid = LDB_CONTROL_NOTIFICATION_OID;
    1048        1529 :                 ctrl->critical = crit;
    1049        1529 :                 ctrl->data = NULL;
    1050             : 
    1051        1529 :                 return ctrl;
    1052             :         }
    1053             : 
    1054     4459696 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_TREE_DELETE_NAME) == 0) {
    1055             :                 const char *p;
    1056             :                 int crit, ret;
    1057             : 
    1058        2927 :                 p = &(control_strings[sizeof(LDB_CONTROL_TREE_DELETE_NAME)]);
    1059        2927 :                 ret = sscanf(p, "%d", &crit);
    1060        2927 :                 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        2927 :                 ctrl->oid = LDB_CONTROL_TREE_DELETE_OID;
    1070        2927 :                 ctrl->critical = crit;
    1071        2927 :                 ctrl->data = NULL;
    1072             : 
    1073        2927 :                 return ctrl;
    1074             :         }
    1075             : 
    1076     4456769 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SHOW_DELETED_NAME) == 0) {
    1077             :                 const char *p;
    1078             :                 int crit, ret;
    1079             : 
    1080     1168419 :                 p = &(control_strings[sizeof(LDB_CONTROL_SHOW_DELETED_NAME)]);
    1081     1168419 :                 ret = sscanf(p, "%d", &crit);
    1082     1168419 :                 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     1168419 :                 ctrl->oid = LDB_CONTROL_SHOW_DELETED_OID;
    1092     1168419 :                 ctrl->critical = crit;
    1093     1168419 :                 ctrl->data = NULL;
    1094             : 
    1095     1168419 :                 return ctrl;
    1096             :         }
    1097             : 
    1098     3288350 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SHOW_DEACTIVATED_LINK_NAME) == 0) {
    1099             :                 const char *p;
    1100             :                 int crit, ret;
    1101             : 
    1102          16 :                 p = &(control_strings[sizeof(LDB_CONTROL_SHOW_DEACTIVATED_LINK_NAME)]);
    1103          16 :                 ret = sscanf(p, "%d", &crit);
    1104          16 :                 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          16 :                 ctrl->oid = LDB_CONTROL_SHOW_DEACTIVATED_LINK_OID;
    1114          16 :                 ctrl->critical = crit;
    1115          16 :                 ctrl->data = NULL;
    1116             : 
    1117          16 :                 return ctrl;
    1118             :         }
    1119             : 
    1120     3288334 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_SHOW_RECYCLED_NAME) == 0) {
    1121             :                 const char *p;
    1122             :                 int crit, ret;
    1123             : 
    1124     1607074 :                 p = &(control_strings[sizeof(LDB_CONTROL_SHOW_RECYCLED_NAME)]);
    1125     1607074 :                 ret = sscanf(p, "%d", &crit);
    1126     1607074 :                 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     1607074 :                 ctrl->oid = LDB_CONTROL_SHOW_RECYCLED_OID;
    1136     1607074 :                 ctrl->critical = crit;
    1137     1607074 :                 ctrl->data = NULL;
    1138             : 
    1139     1607074 :                 return ctrl;
    1140             :         }
    1141             : 
    1142     1681260 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_PERMISSIVE_MODIFY_NAME) == 0) {
    1143             :                 const char *p;
    1144             :                 int crit, ret;
    1145             : 
    1146         158 :                 p = &(control_strings[sizeof(LDB_CONTROL_PERMISSIVE_MODIFY_NAME)]);
    1147         158 :                 ret = sscanf(p, "%d", &crit);
    1148         158 :                 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         158 :                 ctrl->oid = LDB_CONTROL_PERMISSIVE_MODIFY_OID;
    1158         158 :                 ctrl->critical = crit;
    1159         158 :                 ctrl->data = NULL;
    1160             : 
    1161         158 :                 return ctrl;
    1162             :         }
    1163             : 
    1164     1681102 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_REVEAL_INTERNALS_NAME) == 0) {
    1165             :                 const char *p;
    1166             :                 int crit, ret;
    1167             : 
    1168     1152252 :                 p = &(control_strings[sizeof(LDB_CONTROL_REVEAL_INTERNALS_NAME)]);
    1169     1152252 :                 ret = sscanf(p, "%d", &crit);
    1170     1152252 :                 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     1152252 :                 ctrl->oid = LDB_CONTROL_REVEAL_INTERNALS;
    1180     1152252 :                 ctrl->critical = crit;
    1181     1152252 :                 ctrl->data = NULL;
    1182             : 
    1183     1152252 :                 return ctrl;
    1184             :         }
    1185             : 
    1186      528850 :         if (strncmp(control_strings, "local_oid:", 10) == 0) {
    1187             :                 const char *p;
    1188      396701 :                 int crit = 0, ret = 0;
    1189             :                 char oid[256];
    1190             : 
    1191      396701 :                 oid[0] = '\0';
    1192      396701 :                 p = &(control_strings[10]);
    1193      396701 :                 ret = sscanf(p, "%255[^:]:%d", oid, &crit);
    1194             : 
    1195      396701 :                 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      396701 :                 ctrl->oid = talloc_strdup(ctrl, oid);
    1205      396701 :                 if (!ctrl->oid) {
    1206           0 :                         ldb_oom(ldb);
    1207           0 :                         talloc_free(ctrl);
    1208           0 :                         return NULL;
    1209             :                 }
    1210      396701 :                 ctrl->critical = crit;
    1211      396701 :                 ctrl->data = NULL;
    1212             : 
    1213      396701 :                 return ctrl;
    1214             :         }
    1215             : 
    1216      132149 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_RODC_DCPROMO_NAME) == 0) {
    1217             :                 const char *p;
    1218             :                 int crit, ret;
    1219             : 
    1220         138 :                 p = &(control_strings[sizeof(LDB_CONTROL_RODC_DCPROMO_NAME)]);
    1221         138 :                 ret = sscanf(p, "%d", &crit);
    1222         138 :                 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         138 :                 ctrl->oid = LDB_CONTROL_RODC_DCPROMO_OID;
    1232         138 :                 ctrl->critical = crit;
    1233         138 :                 ctrl->data = NULL;
    1234             : 
    1235         138 :                 return ctrl;
    1236             :         }
    1237             : 
    1238      132011 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_PROVISION_NAME) == 0) {
    1239             :                 const char *p;
    1240             :                 int crit, ret;
    1241             : 
    1242      132008 :                 p = &(control_strings[sizeof(LDB_CONTROL_PROVISION_NAME)]);
    1243      132008 :                 ret = sscanf(p, "%d", &crit);
    1244      132008 :                 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      132008 :                 ctrl->oid = LDB_CONTROL_PROVISION_OID;
    1254      132008 :                 ctrl->critical = crit;
    1255      132008 :                 ctrl->data = NULL;
    1256             : 
    1257      132008 :                 return ctrl;
    1258             :         }
    1259           3 :         if (LDB_CONTROL_CMP(control_strings, LDB_CONTROL_VERIFY_NAME_NAME) == 0) {
    1260             :                 const char *p;
    1261             :                 char gc[1024];
    1262             :                 int crit, flags, ret;
    1263             :                 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           3 :         TALLOC_FREE(ctrl);
    1308           3 :         return NULL;
    1309             : }
    1310             : 
    1311             : /* Parse controls from the format used on the command line and in ejs */
    1312     1925591 : struct ldb_control **ldb_parse_control_strings(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char **control_strings)
    1313             : {
    1314             :         unsigned int i;
    1315             :         struct ldb_control **ctrl;
    1316             : 
    1317     1925591 :         if (control_strings == NULL || control_strings[0] == NULL)
    1318        1791 :                 return NULL;
    1319             : 
    1320     2708899 :         for (i = 0; control_strings[i]; i++);
    1321             : 
    1322     1923800 :         ctrl = talloc_array(mem_ctx, struct ldb_control *, i + 1);
    1323             : 
    1324     1923800 :         ldb_reset_err_string(ldb);
    1325     8709072 :         for (i = 0; control_strings[i]; i++) {
    1326     6785272 :                 ctrl[i] = ldb_parse_control_from_string(ldb, ctrl, control_strings[i]);
    1327     6785272 :                 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     1923800 :         ctrl[i] = NULL;
    1338             : 
    1339     1923800 :         return ctrl;
    1340             : }
    1341             : 
    1342             : 

Generated by: LCOV version 1.13