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 : }
|