LCOV - code coverage report
Current view: top level - lib/ldb/common - ldb_controls.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 432 752 57.4 %
Date: 2024-04-21 15:09:00 Functions: 10 12 83.3 %

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

Generated by: LCOV version 1.14