~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source4/lib/ldb/common/ldb_controls.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
struct ldb_control *ldb_request_get_control(struct ldb_request *req, const char *oid)
 
39
{
 
40
        int i;
 
41
 
 
42
        /* check if there's a paged request control */
 
43
        if (req->controls != NULL) {
 
44
                for (i = 0; req->controls[i]; i++) {
 
45
                        if (strcmp(oid, req->controls[i]->oid) == 0) {
 
46
                                break;
 
47
                        }
 
48
                }
 
49
 
 
50
                return req->controls[i];
 
51
        }
 
52
 
 
53
        return NULL;
 
54
}
 
55
 
 
56
/* check if a control with the specified "oid" exist and return it */
 
57
/* returns NULL if not found */
 
58
struct ldb_control *ldb_reply_get_control(struct ldb_reply *rep, const char *oid)
 
59
{
 
60
        int i;
 
61
 
 
62
        /* check if there's a paged request control */
 
63
        if (rep->controls != NULL) {
 
64
                for (i = 0; rep->controls[i]; i++) {
 
65
                        if (strcmp(oid, rep->controls[i]->oid) == 0) {
 
66
                                break;
 
67
                        }
 
68
                }
 
69
 
 
70
                return rep->controls[i];
 
71
        }
 
72
 
 
73
        return NULL;
 
74
}
 
75
 
 
76
/* saves the current controls list into the "saver" and replace the one in req with a new one excluding
 
77
the "exclude" control */
 
78
/* returns False on error */
 
79
int save_controls(struct ldb_control *exclude, struct ldb_request *req, struct ldb_control ***saver)
 
80
{
 
81
        struct ldb_control **lcs;
 
82
        int i, j;
 
83
 
 
84
        *saver = req->controls;
 
85
        for (i = 0; req->controls[i]; i++);
 
86
        if (i == 1) {
 
87
                req->controls = NULL;
 
88
                return 1;
 
89
        }
 
90
 
 
91
        lcs = talloc_array(req, struct ldb_control *, i);
 
92
        if (!lcs) {
 
93
                return 0;
 
94
        }
 
95
 
 
96
        for (i = 0, j = 0; (*saver)[i]; i++) {
 
97
                if (exclude == (*saver)[i]) continue;
 
98
                lcs[j] = (*saver)[i];
 
99
                j++;
 
100
        }
 
101
        lcs[j] = NULL;
 
102
 
 
103
        req->controls = lcs;
 
104
        return 1;
 
105
}
 
106
 
 
107
/* check if there's any control marked as critical in the list */
 
108
/* return True if any, False if none */
 
109
int check_critical_controls(struct ldb_control **controls)
 
110
{
 
111
        int i;
 
112
 
 
113
        if (controls == NULL) {
 
114
                return 0;
 
115
        }
 
116
 
 
117
        for (i = 0; controls[i]; i++) {
 
118
                if (controls[i]->critical) {
 
119
                        return 1;
 
120
                }
 
121
        }
 
122
 
 
123
        return 0;
 
124
}
 
125
 
 
126
int ldb_request_add_control(struct ldb_request *req, const char *oid, bool critical, void *data)
 
127
{
 
128
        unsigned n;
 
129
        struct ldb_control **ctrls;
 
130
        struct ldb_control *ctrl;
 
131
 
 
132
        for (n=0; req->controls && req->controls[n];) { n++; }
 
133
 
 
134
        ctrls = talloc_realloc(req, req->controls,
 
135
                               struct ldb_control *,
 
136
                               n + 2);
 
137
        if (!ctrls) return LDB_ERR_OPERATIONS_ERROR;
 
138
        req->controls = ctrls;
 
139
        ctrls[n] = NULL;
 
140
        ctrls[n+1] = NULL;
 
141
 
 
142
        ctrl = talloc(ctrls, struct ldb_control);
 
143
        if (!ctrl) return LDB_ERR_OPERATIONS_ERROR;
 
144
 
 
145
        ctrl->oid       = talloc_strdup(ctrl, oid);
 
146
        if (!ctrl->oid) return LDB_ERR_OPERATIONS_ERROR;
 
147
        ctrl->critical  = critical;
 
148
        ctrl->data      = data;
 
149
 
 
150
        ctrls[n] = ctrl;
 
151
        return LDB_SUCCESS;
 
152
}
 
153
 
 
154
/* Parse controls from the format used on the command line and in ejs */
 
155
 
 
156
struct ldb_control **ldb_parse_control_strings(struct ldb_context *ldb, void *mem_ctx, const char **control_strings)
 
157
{
 
158
        int i;
 
159
        struct ldb_control **ctrl;
 
160
 
 
161
        char *error_string = NULL;
 
162
 
 
163
        if (control_strings == NULL || control_strings[0] == NULL)
 
164
                return NULL;
 
165
 
 
166
        for (i = 0; control_strings[i]; i++);
 
167
 
 
168
        ctrl = talloc_array(mem_ctx, struct ldb_control *, i + 1);
 
169
 
 
170
        for (i = 0; control_strings[i]; i++) {
 
171
                if (strncmp(control_strings[i], "vlv:", 4) == 0) {
 
172
                        struct ldb_vlv_req_control *control;
 
173
                        const char *p;
 
174
                        char attr[1024];
 
175
                        char ctxid[1024];
 
176
                        int crit, bc, ac, os, cc, ret;
 
177
 
 
178
                        attr[0] = '\0';
 
179
                        ctxid[0] = '\0';
 
180
                        p = &(control_strings[i][4]);
 
181
                        ret = sscanf(p, "%d:%d:%d:%d:%d:%1023[^$]", &crit, &bc, &ac, &os, &cc, ctxid);
 
182
                        if (ret < 5) {
 
183
                                ret = sscanf(p, "%d:%d:%d:%1023[^:]:%1023[^$]", &crit, &bc, &ac, attr, ctxid);
 
184
                        }
 
185
                               
 
186
                        if ((ret < 4) || (crit < 0) || (crit > 1)) {
 
187
                                error_string = talloc_asprintf(mem_ctx, "invalid server_sort control syntax\n");
 
188
                                error_string = talloc_asprintf_append(error_string, " syntax: crit(b):bc(n):ac(n):<os(n):cc(n)|attr(s)>[:ctxid(o)]\n");
 
189
                                error_string = talloc_asprintf_append(error_string, "   note: b = boolean, n = number, s = string, o = b64 binary blob");
 
190
                                ldb_set_errstring(ldb, error_string);
 
191
                                talloc_free(error_string);
 
192
                                return NULL;
 
193
                        }
 
194
                        if (!(ctrl[i] = talloc(ctrl, struct ldb_control))) {
 
195
                                ldb_oom(ldb);
 
196
                                return NULL;
 
197
                        }
 
198
                        ctrl[i]->oid = LDB_CONTROL_VLV_REQ_OID;
 
199
                        ctrl[i]->critical = crit;
 
200
                        if (!(control = talloc(ctrl[i],
 
201
                                               struct ldb_vlv_req_control))) {
 
202
                                ldb_oom(ldb);
 
203
                                return NULL;
 
204
                        }
 
205
                        control->beforeCount = bc;
 
206
                        control->afterCount = ac;
 
207
                        if (attr[0]) {
 
208
                                control->type = 1;
 
209
                                control->match.gtOrEq.value = talloc_strdup(control, attr);
 
210
                                control->match.gtOrEq.value_len = strlen(attr);
 
211
                        } else {
 
212
                                control->type = 0;
 
213
                                control->match.byOffset.offset = os;
 
214
                                control->match.byOffset.contentCount = cc;
 
215
                        }
 
216
                        if (ctxid[0]) {
 
217
                                control->ctxid_len = ldb_base64_decode(ctxid);
 
218
                                control->contextId = (char *)talloc_memdup(control, ctxid, control->ctxid_len);
 
219
                        } else {
 
220
                                control->ctxid_len = 0;
 
221
                                control->contextId = NULL;
 
222
                        }
 
223
                        ctrl[i]->data = control;
 
224
 
 
225
                        continue;
 
226
                }
 
227
 
 
228
                if (strncmp(control_strings[i], "dirsync:", 8) == 0) {
 
229
                        struct ldb_dirsync_control *control;
 
230
                        const char *p;
 
231
                        char cookie[1024];
 
232
                        int crit, flags, max_attrs, ret;
 
233
                       
 
234
                        cookie[0] = '\0';
 
235
                        p = &(control_strings[i][8]);
 
236
                        ret = sscanf(p, "%d:%d:%d:%1023[^$]", &crit, &flags, &max_attrs, cookie);
 
237
 
 
238
                        if ((ret < 3) || (crit < 0) || (crit > 1) || (flags < 0) || (max_attrs < 0)) {
 
239
                                error_string = talloc_asprintf(mem_ctx, "invalid dirsync control syntax\n");
 
240
                                error_string = talloc_asprintf_append(error_string, " syntax: crit(b):flags(n):max_attrs(n)[:cookie(o)]\n");
 
241
                                error_string = talloc_asprintf_append(error_string, "   note: b = boolean, n = number, o = b64 binary blob");
 
242
                                ldb_set_errstring(ldb, error_string);
 
243
                                talloc_free(error_string);
 
244
                                return NULL;
 
245
                        }
 
246
 
 
247
                        /* w2k3 seems to ignore the parameter,
 
248
                         * but w2k sends a wrong cookie when this value is to small
 
249
                         * this would cause looping forever, while getting
 
250
                         * the same data and same cookie forever
 
251
                         */
 
252
                        if (max_attrs == 0) max_attrs = 0x0FFFFFFF;
 
253
 
 
254
                        ctrl[i] = talloc(ctrl, struct ldb_control);
 
255
                        ctrl[i]->oid = LDB_CONTROL_DIRSYNC_OID;
 
256
                        ctrl[i]->critical = crit;
 
257
                        control = talloc(ctrl[i], struct ldb_dirsync_control);
 
258
                        control->flags = flags;
 
259
                        control->max_attributes = max_attrs;
 
260
                        if (*cookie) {
 
261
                                control->cookie_len = ldb_base64_decode(cookie);
 
262
                                control->cookie = (char *)talloc_memdup(control, cookie, control->cookie_len);
 
263
                        } else {
 
264
                                control->cookie = NULL;
 
265
                                control->cookie_len = 0;
 
266
                        }
 
267
                        ctrl[i]->data = control;
 
268
 
 
269
                        continue;
 
270
                }
 
271
 
 
272
                if (strncmp(control_strings[i], "asq:", 4) == 0) {
 
273
                        struct ldb_asq_control *control;
 
274
                        const char *p;
 
275
                        char attr[256];
 
276
                        int crit, ret;
 
277
 
 
278
                        attr[0] = '\0';
 
279
                        p = &(control_strings[i][4]);
 
280
                        ret = sscanf(p, "%d:%255[^$]", &crit, attr);
 
281
                        if ((ret != 2) || (crit < 0) || (crit > 1) || (attr[0] == '\0')) {
 
282
                                error_string = talloc_asprintf(mem_ctx, "invalid asq control syntax\n");
 
283
                                error_string = talloc_asprintf_append(error_string, " syntax: crit(b):attr(s)\n");
 
284
                                error_string = talloc_asprintf_append(error_string, "   note: b = boolean, s = string");
 
285
                                ldb_set_errstring(ldb, error_string);
 
286
                                talloc_free(error_string);
 
287
                                return NULL;
 
288
                        }
 
289
 
 
290
                        ctrl[i] = talloc(ctrl, struct ldb_control);
 
291
                        if (!ctrl[i]) {
 
292
                                ldb_oom(ldb);
 
293
                                return NULL;
 
294
                        }
 
295
                        ctrl[i]->oid = LDB_CONTROL_ASQ_OID;
 
296
                        ctrl[i]->critical = crit;
 
297
                        control = talloc(ctrl[i], struct ldb_asq_control);
 
298
                        control->request = 1;
 
299
                        control->source_attribute = talloc_strdup(control, attr);
 
300
                        control->src_attr_len = strlen(attr);
 
301
                        ctrl[i]->data = control;
 
302
 
 
303
                        continue;
 
304
                }
 
305
 
 
306
                if (strncmp(control_strings[i], "extended_dn:", 12) == 0) {
 
307
                        struct ldb_extended_dn_control *control;
 
308
                        const char *p;
 
309
                        int crit, type, ret;
 
310
 
 
311
                        p = &(control_strings[i][12]);
 
312
                        ret = sscanf(p, "%d:%d", &crit, &type);
 
313
                        if ((ret != 2) || (crit < 0) || (crit > 1) || (type < 0) || (type > 1)) {
 
314
                                ret = sscanf(p, "%d", &crit);
 
315
                                if ((ret != 1) || (crit < 0) || (crit > 1)) {
 
316
                                        error_string = talloc_asprintf(mem_ctx, "invalid extended_dn control syntax\n");
 
317
                                        error_string = talloc_asprintf_append(error_string, " syntax: crit(b)[:type(i)]\n");
 
318
                                        error_string = talloc_asprintf_append(error_string, "   note: b = boolean\n");
 
319
                                        error_string = talloc_asprintf_append(error_string, "         i = integer\n");
 
320
                                        error_string = talloc_asprintf_append(error_string, "   valid values are: 0 - hexadecimal representation\n");
 
321
                                        error_string = talloc_asprintf_append(error_string, "                     1 - normal string representation");
 
322
                                        ldb_set_errstring(ldb, error_string);
 
323
                                        talloc_free(error_string);
 
324
                                        return NULL;
 
325
                                }
 
326
                                control = NULL;
 
327
                        } else {
 
328
                                control = talloc(ctrl, struct ldb_extended_dn_control);
 
329
                                control->type = type;
 
330
                        }
 
331
 
 
332
                        ctrl[i] = talloc(ctrl, struct ldb_control);
 
333
                        if (!ctrl[i]) {
 
334
                                ldb_oom(ldb);
 
335
                                return NULL;
 
336
                        }
 
337
                        ctrl[i]->oid = LDB_CONTROL_EXTENDED_DN_OID;
 
338
                        ctrl[i]->critical = crit;
 
339
                        ctrl[i]->data = talloc_steal(ctrl[i], control);
 
340
 
 
341
                        continue;
 
342
                }
 
343
 
 
344
                if (strncmp(control_strings[i], "sd_flags:", 9) == 0) {
 
345
                        struct ldb_sd_flags_control *control;
 
346
                        const char *p;
 
347
                        int crit, ret;
 
348
                        unsigned secinfo_flags;
 
349
 
 
350
                        p = &(control_strings[i][9]);
 
351
                        ret = sscanf(p, "%d:%u", &crit, &secinfo_flags);
 
352
                        if ((ret != 2) || (crit < 0) || (crit > 1) || (secinfo_flags < 0) || (secinfo_flags > 0xF)) {
 
353
                                error_string = talloc_asprintf(mem_ctx, "invalid sd_flags control syntax\n");
 
354
                                error_string = talloc_asprintf_append(error_string, " syntax: crit(b):secinfo_flags(n)\n");
 
355
                                error_string = talloc_asprintf_append(error_string, "   note: b = boolean, n = number");
 
356
                                ldb_set_errstring(ldb, error_string);
 
357
                                talloc_free(error_string);
 
358
                                return NULL;
 
359
                        }
 
360
 
 
361
                        ctrl[i] = talloc(ctrl, struct ldb_control);
 
362
                        if (!ctrl[i]) {
 
363
                                ldb_oom(ldb);
 
364
                                return NULL;
 
365
                        }
 
366
                        ctrl[i]->oid = LDB_CONTROL_SD_FLAGS_OID;
 
367
                        ctrl[i]->critical = crit;
 
368
                        control = talloc(ctrl[i], struct ldb_sd_flags_control);
 
369
                        control->secinfo_flags = secinfo_flags;
 
370
                        ctrl[i]->data = control;
 
371
 
 
372
                        continue;
 
373
                }
 
374
 
 
375
                if (strncmp(control_strings[i], "search_options:", 15) == 0) {
 
376
                        struct ldb_search_options_control *control;
 
377
                        const char *p;
 
378
                        int crit, ret;
 
379
                        unsigned search_options;
 
380
 
 
381
                        p = &(control_strings[i][15]);
 
382
                        ret = sscanf(p, "%d:%u", &crit, &search_options);
 
383
                        if ((ret != 2) || (crit < 0) || (crit > 1) || (search_options < 0) || (search_options > 0xF)) {
 
384
                                error_string = talloc_asprintf(mem_ctx, "invalid search_options control syntax\n");
 
385
                                error_string = talloc_asprintf_append(error_string, " syntax: crit(b):search_options(n)\n");
 
386
                                error_string = talloc_asprintf_append(error_string, "   note: b = boolean, n = number");
 
387
                                ldb_set_errstring(ldb, error_string);
 
388
                                talloc_free(error_string);
 
389
                                return NULL;
 
390
                        }
 
391
 
 
392
                        ctrl[i] = talloc(ctrl, struct ldb_control);
 
393
                        if (!ctrl[i]) {
 
394
                                ldb_oom(ldb);
 
395
                                return NULL;
 
396
                        }
 
397
                        ctrl[i]->oid = LDB_CONTROL_SEARCH_OPTIONS_OID;
 
398
                        ctrl[i]->critical = crit;
 
399
                        control = talloc(ctrl[i], struct ldb_search_options_control);
 
400
                        control->search_options = search_options;
 
401
                        ctrl[i]->data = control;
 
402
 
 
403
                        continue;
 
404
                }
 
405
 
 
406
                if (strncmp(control_strings[i], "domain_scope:", 13) == 0) {
 
407
                        const char *p;
 
408
                        int crit, ret;
 
409
 
 
410
                        p = &(control_strings[i][13]);
 
411
                        ret = sscanf(p, "%d", &crit);
 
412
                        if ((ret != 1) || (crit < 0) || (crit > 1)) {
 
413
                                error_string = talloc_asprintf(mem_ctx, "invalid domain_scope control syntax\n");
 
414
                                error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n");
 
415
                                error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
 
416
                                ldb_set_errstring(ldb, error_string);
 
417
                                talloc_free(error_string);
 
418
                                return NULL;
 
419
                        }
 
420
 
 
421
                        ctrl[i] = talloc(ctrl, struct ldb_control);
 
422
                        if (!ctrl[i]) {
 
423
                                ldb_oom(ldb);
 
424
                                return NULL;
 
425
                        }
 
426
                        ctrl[i]->oid = LDB_CONTROL_DOMAIN_SCOPE_OID;
 
427
                        ctrl[i]->critical = crit;
 
428
                        ctrl[i]->data = NULL;
 
429
 
 
430
                        continue;
 
431
                }
 
432
 
 
433
                if (strncmp(control_strings[i], "paged_results:", 14) == 0) {
 
434
                        struct ldb_paged_control *control;
 
435
                        const char *p;
 
436
                        int crit, size, ret;
 
437
                       
 
438
                        p = &(control_strings[i][14]);
 
439
                        ret = sscanf(p, "%d:%d", &crit, &size);
 
440
 
 
441
                        if ((ret != 2) || (crit < 0) || (crit > 1) || (size < 0)) {
 
442
                                error_string = talloc_asprintf(mem_ctx, "invalid paged_results control syntax\n");
 
443
                                error_string = talloc_asprintf_append(error_string, " syntax: crit(b):size(n)\n");
 
444
                                error_string = talloc_asprintf_append(error_string, "   note: b = boolean, n = number");
 
445
                                ldb_set_errstring(ldb, error_string);
 
446
                                talloc_free(error_string);
 
447
                                return NULL;
 
448
                        }
 
449
 
 
450
                        ctrl[i] = talloc(ctrl, struct ldb_control);
 
451
                        if (!ctrl[i]) {
 
452
                                ldb_oom(ldb);
 
453
                                return NULL;
 
454
                        }
 
455
                        ctrl[i]->oid = LDB_CONTROL_PAGED_RESULTS_OID;
 
456
                        ctrl[i]->critical = crit;
 
457
                        control = talloc(ctrl[i], struct ldb_paged_control);
 
458
                        control->size = size;
 
459
                        control->cookie = NULL;
 
460
                        control->cookie_len = 0;
 
461
                        ctrl[i]->data = control;
 
462
 
 
463
                        continue;
 
464
                }
 
465
 
 
466
                if (strncmp(control_strings[i], "server_sort:", 12) == 0) {
 
467
                        struct ldb_server_sort_control **control;
 
468
                        const char *p;
 
469
                        char attr[256];
 
470
                        char rule[128];
 
471
                        int crit, rev, ret;
 
472
 
 
473
                        attr[0] = '\0';
 
474
                        rule[0] = '\0';
 
475
                        p = &(control_strings[i][12]);
 
476
                        ret = sscanf(p, "%d:%d:%255[^:]:%127[^:]", &crit, &rev, attr, rule);
 
477
                        if ((ret < 3) || (crit < 0) || (crit > 1) || (rev < 0 ) || (rev > 1) ||attr[0] == '\0') {
 
478
                                error_string = talloc_asprintf(mem_ctx, "invalid server_sort control syntax\n");
 
479
                                error_string = talloc_asprintf_append(error_string, " syntax: crit(b):rev(b):attr(s)[:rule(s)]\n");
 
480
                                error_string = talloc_asprintf_append(error_string, "   note: b = boolean, s = string");
 
481
                                ldb_set_errstring(ldb, error_string);
 
482
                                talloc_free(error_string);
 
483
                                return NULL;
 
484
                        }
 
485
                        ctrl[i] = talloc(ctrl, struct ldb_control);
 
486
                        if (!ctrl[i]) {
 
487
                                ldb_oom(ldb);
 
488
                                return NULL;
 
489
                        }
 
490
                        ctrl[i]->oid = LDB_CONTROL_SERVER_SORT_OID;
 
491
                        ctrl[i]->critical = crit;
 
492
                        control = talloc_array(ctrl[i], struct ldb_server_sort_control *, 2);
 
493
                        control[0] = talloc(control, struct ldb_server_sort_control);
 
494
                        control[0]->attributeName = talloc_strdup(control, attr);
 
495
                        if (rule[0])
 
496
                                control[0]->orderingRule = talloc_strdup(control, rule);
 
497
                        else
 
498
                                control[0]->orderingRule = NULL;
 
499
                        control[0]->reverse = rev;
 
500
                        control[1] = NULL;
 
501
                        ctrl[i]->data = control;
 
502
 
 
503
                        continue;
 
504
                }
 
505
 
 
506
                if (strncmp(control_strings[i], "notification:", 13) == 0) {
 
507
                        const char *p;
 
508
                        int crit, ret;
 
509
 
 
510
                        p = &(control_strings[i][13]);
 
511
                        ret = sscanf(p, "%d", &crit);
 
512
                        if ((ret != 1) || (crit < 0) || (crit > 1)) {
 
513
                                error_string = talloc_asprintf(mem_ctx, "invalid notification control syntax\n");
 
514
                                error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n");
 
515
                                error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
 
516
                                ldb_set_errstring(ldb, error_string);
 
517
                                talloc_free(error_string);
 
518
                                return NULL;
 
519
                        }
 
520
 
 
521
                        ctrl[i] = talloc(ctrl, struct ldb_control);
 
522
                        if (!ctrl[i]) {
 
523
                                ldb_oom(ldb);
 
524
                                return NULL;
 
525
                        }
 
526
                        ctrl[i]->oid = LDB_CONTROL_NOTIFICATION_OID;
 
527
                        ctrl[i]->critical = crit;
 
528
                        ctrl[i]->data = NULL;
 
529
 
 
530
                        continue;
 
531
                }
 
532
 
 
533
                if (strncmp(control_strings[i], "show_deleted:", 13) == 0) {
 
534
                        const char *p;
 
535
                        int crit, ret;
 
536
 
 
537
                        p = &(control_strings[i][13]);
 
538
                        ret = sscanf(p, "%d", &crit);
 
539
                        if ((ret != 1) || (crit < 0) || (crit > 1)) {
 
540
                                error_string = talloc_asprintf(mem_ctx, "invalid show_deleted control syntax\n");
 
541
                                error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n");
 
542
                                error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
 
543
                                ldb_set_errstring(ldb, error_string);
 
544
                                talloc_free(error_string);
 
545
                                return NULL;
 
546
                        }
 
547
 
 
548
                        ctrl[i] = talloc(ctrl, struct ldb_control);
 
549
                        if (!ctrl[i]) {
 
550
                                ldb_oom(ldb);
 
551
                                return NULL;
 
552
                        }
 
553
                        ctrl[i]->oid = LDB_CONTROL_SHOW_DELETED_OID;
 
554
                        ctrl[i]->critical = crit;
 
555
                        ctrl[i]->data = NULL;
 
556
 
 
557
                        continue;
 
558
                }
 
559
 
 
560
                if (strncmp(control_strings[i], "permissive_modify:", 18) == 0) {
 
561
                        const char *p;
 
562
                        int crit, ret;
 
563
 
 
564
                        p = &(control_strings[i][18]);
 
565
                        ret = sscanf(p, "%d", &crit);
 
566
                        if ((ret != 1) || (crit < 0) || (crit > 1)) {
 
567
                                error_string = talloc_asprintf(mem_ctx, "invalid permissive_modify control syntax\n");
 
568
                                error_string = talloc_asprintf_append(error_string, " syntax: crit(b)\n");
 
569
                                error_string = talloc_asprintf_append(error_string, "   note: b = boolean");
 
570
                                ldb_set_errstring(ldb, error_string);
 
571
                                talloc_free(error_string);
 
572
                                return NULL;
 
573
                        }
 
574
 
 
575
                        ctrl[i] = talloc(ctrl, struct ldb_control);
 
576
                        if (!ctrl[i]) {
 
577
                                ldb_oom(ldb);
 
578
                                return NULL;
 
579
                        }
 
580
                        ctrl[i]->oid = LDB_CONTROL_PERMISSIVE_MODIFY_OID;
 
581
                        ctrl[i]->critical = crit;
 
582
                        ctrl[i]->data = NULL;
 
583
 
 
584
                        continue;
 
585
                }
 
586
 
 
587
                /* no controls matched, throw an error */
 
588
                ldb_asprintf_errstring(ldb, "Invalid control name: '%s'", control_strings[i]);
 
589
                return NULL;
 
590
        }
 
591
 
 
592
        ctrl[i] = NULL;
 
593
 
 
594
        return ctrl;
 
595
}
 
596
 
 
597