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