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