~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source4/libcli/ldap/ldap_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
   Unix SMB/CIFS mplementation.
 
3
   LDAP protocol helper functions for SAMBA
 
4
   
 
5
   Copyright (C) Simo Sorce 2005
 
6
    
 
7
   This program is free software; you can redistribute it and/or modify
 
8
   it under the terms of the GNU General Public License as published by
 
9
   the Free Software Foundation; either version 3 of the License, or
 
10
   (at your option) any later version.
 
11
   
 
12
   This program is distributed in the hope that it will be useful,
 
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
   GNU General Public License for more details.
 
16
   
 
17
   You should have received a copy of the GNU General Public License
 
18
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
19
   
 
20
*/
 
21
 
 
22
#include "includes.h"
 
23
#include "../lib/util/asn1.h"
 
24
#include "libcli/ldap/ldap.h"
 
25
#include "lib/ldb/include/ldb.h"
 
26
#include "libcli/ldap/ldap_proto.h"
 
27
#include "dsdb/samdb/samdb.h"
 
28
 
 
29
static bool decode_server_sort_response(void *mem_ctx, DATA_BLOB in, void *_out)
 
30
{
 
31
        void **out = (void **)_out;
 
32
        DATA_BLOB attr;
 
33
        struct asn1_data *data = asn1_init(mem_ctx);
 
34
        struct ldb_sort_resp_control *lsrc;
 
35
 
 
36
        if (!data) return false;
 
37
 
 
38
        if (!asn1_load(data, in)) {
 
39
                return false;
 
40
        }
 
41
 
 
42
        lsrc = talloc(mem_ctx, struct ldb_sort_resp_control);
 
43
        if (!lsrc) {
 
44
                return false;
 
45
        }
 
46
 
 
47
        if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
 
48
                return false;
 
49
        }
 
50
 
 
51
        if (!asn1_read_enumerated(data, &(lsrc->result))) {
 
52
                return false;
 
53
        }
 
54
 
 
55
        lsrc->attr_desc = NULL;
 
56
        if (asn1_peek_tag(data, ASN1_OCTET_STRING)) {
 
57
                if (!asn1_read_OctetString(data, mem_ctx, &attr)) {
 
58
                        return false;
 
59
                }
 
60
                lsrc->attr_desc = talloc_strndup(lsrc, (const char *)attr.data, attr.length);
 
61
                if (!lsrc->attr_desc) {
 
62
                        return false;
 
63
                }
 
64
        }
 
65
 
 
66
        if (!asn1_end_tag(data)) {
 
67
                return false;
 
68
        }
 
69
 
 
70
        *out = lsrc;
 
71
 
 
72
        return true;
 
73
}
 
74
 
 
75
static bool decode_server_sort_request(void *mem_ctx, DATA_BLOB in, void *_out)
 
76
{
 
77
        void **out = (void **)_out;
 
78
        DATA_BLOB attr;
 
79
        DATA_BLOB rule;
 
80
        struct asn1_data *data = asn1_init(mem_ctx);
 
81
        struct ldb_server_sort_control **lssc;
 
82
        int num;
 
83
 
 
84
        if (!data) return false;
 
85
 
 
86
        if (!asn1_load(data, in)) {
 
87
                return false;
 
88
        }
 
89
 
 
90
        if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
 
91
                return false;
 
92
        }
 
93
 
 
94
        lssc = NULL;
 
95
 
 
96
        for (num = 0; asn1_peek_tag(data, ASN1_SEQUENCE(0)); num++) {
 
97
                lssc = talloc_realloc(mem_ctx, lssc, struct ldb_server_sort_control *, num + 2);
 
98
                if (!lssc) {
 
99
                        return false;
 
100
                }
 
101
                lssc[num] = talloc_zero(lssc, struct ldb_server_sort_control);
 
102
                if (!lssc[num]) {
 
103
                        return false;
 
104
                }
 
105
 
 
106
                if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
 
107
                        return false;
 
108
                }
 
109
 
 
110
                if (!asn1_read_OctetString(data, mem_ctx, &attr)) {
 
111
                        return false;
 
112
                }
 
113
 
 
114
                lssc[num]->attributeName = talloc_strndup(lssc[num], (const char *)attr.data, attr.length);
 
115
                if (!lssc [num]->attributeName) {
 
116
                        return false;
 
117
                }
 
118
        
 
119
                if (asn1_peek_tag(data, ASN1_OCTET_STRING)) {
 
120
                        if (!asn1_read_OctetString(data, mem_ctx, &rule)) {
 
121
                                return false;
 
122
                        }
 
123
                        lssc[num]->orderingRule = talloc_strndup(lssc[num], (const char *)rule.data, rule.length);
 
124
                        if (!lssc[num]->orderingRule) {
 
125
                                return false;
 
126
                        }
 
127
                }
 
128
 
 
129
                if (asn1_peek_tag(data, ASN1_BOOLEAN)) {
 
130
                        bool reverse;
 
131
                        if (!asn1_read_BOOLEAN(data, &reverse)) {
 
132
                        return false;
 
133
                        }
 
134
                        lssc[num]->reverse = reverse;
 
135
                }
 
136
        
 
137
                if (!asn1_end_tag(data)) {
 
138
                        return false;
 
139
                }
 
140
        }
 
141
 
 
142
        if (lssc != NULL) {
 
143
                lssc[num] = NULL;
 
144
        }
 
145
 
 
146
        if (!asn1_end_tag(data)) {
 
147
                return false;
 
148
        }
 
149
 
 
150
        *out = lssc;
 
151
 
 
152
        return true;
 
153
}
 
154
 
 
155
static bool decode_extended_dn_request(void *mem_ctx, DATA_BLOB in, void *_out)
 
156
{
 
157
        void **out = (void **)_out;
 
158
        struct asn1_data *data;
 
159
        struct ldb_extended_dn_control *ledc;
 
160
 
 
161
        /* The content of this control is optional */
 
162
        if (in.length == 0) {
 
163
                *out = NULL;
 
164
                return true;
 
165
        }
 
166
 
 
167
        data = asn1_init(mem_ctx);
 
168
        if (!data) return false;
 
169
 
 
170
        if (!asn1_load(data, in)) {
 
171
                return false;
 
172
        }
 
173
 
 
174
        ledc = talloc(mem_ctx, struct ldb_extended_dn_control);
 
175
        if (!ledc) {
 
176
                return false;
 
177
        }
 
178
 
 
179
        if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
 
180
                return false;
 
181
        }
 
182
 
 
183
        if (!asn1_read_Integer(data, &(ledc->type))) {
 
184
                return false;
 
185
        }
 
186
        
 
187
        if (!asn1_end_tag(data)) {
 
188
                return false;
 
189
        }
 
190
 
 
191
        *out = ledc;
 
192
 
 
193
        return true;
 
194
}
 
195
 
 
196
static bool decode_sd_flags_request(void *mem_ctx, DATA_BLOB in, void *_out)
 
197
{
 
198
        void **out = (void **)_out;
 
199
        struct asn1_data *data = asn1_init(mem_ctx);
 
200
        struct ldb_sd_flags_control *lsdfc;
 
201
 
 
202
        if (!data) return false;
 
203
 
 
204
        if (!asn1_load(data, in)) {
 
205
                return false;
 
206
        }
 
207
 
 
208
        lsdfc = talloc(mem_ctx, struct ldb_sd_flags_control);
 
209
        if (!lsdfc) {
 
210
                return false;
 
211
        }
 
212
 
 
213
        if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
 
214
                return false;
 
215
        }
 
216
 
 
217
        if (!asn1_read_Integer(data, &(lsdfc->secinfo_flags))) {
 
218
                return false;
 
219
        }
 
220
 
 
221
        if (!asn1_end_tag(data)) {
 
222
                return false;
 
223
        }
 
224
 
 
225
        *out = lsdfc;
 
226
 
 
227
        return true;
 
228
}
 
229
 
 
230
static bool decode_search_options_request(void *mem_ctx, DATA_BLOB in, void *_out)
 
231
{
 
232
        void **out = (void **)_out;
 
233
        struct asn1_data *data = asn1_init(mem_ctx);
 
234
        struct ldb_search_options_control *lsoc;
 
235
 
 
236
        if (!data) return false;
 
237
 
 
238
        if (!asn1_load(data, in)) {
 
239
                return false;
 
240
        }
 
241
 
 
242
        lsoc = talloc(mem_ctx, struct ldb_search_options_control);
 
243
        if (!lsoc) {
 
244
                return false;
 
245
        }
 
246
 
 
247
        if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
 
248
                return false;
 
249
        }
 
250
 
 
251
        if (!asn1_read_Integer(data, &(lsoc->search_options))) {
 
252
                return false;
 
253
        }
 
254
 
 
255
        if (!asn1_end_tag(data)) {
 
256
                return false;
 
257
        }
 
258
 
 
259
        *out = lsoc;
 
260
 
 
261
        return true;
 
262
}
 
263
 
 
264
static bool decode_paged_results_request(void *mem_ctx, DATA_BLOB in, void *_out)
 
265
{
 
266
        void **out = (void **)_out;
 
267
        DATA_BLOB cookie;
 
268
        struct asn1_data *data = asn1_init(mem_ctx);
 
269
        struct ldb_paged_control *lprc;
 
270
 
 
271
        if (!data) return false;
 
272
 
 
273
        if (!asn1_load(data, in)) {
 
274
                return false;
 
275
        }
 
276
 
 
277
        lprc = talloc(mem_ctx, struct ldb_paged_control);
 
278
        if (!lprc) {
 
279
                return false;
 
280
        }
 
281
 
 
282
        if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
 
283
                return false;
 
284
        }
 
285
 
 
286
        if (!asn1_read_Integer(data, &(lprc->size))) {
 
287
                return false;
 
288
        }
 
289
        
 
290
        if (!asn1_read_OctetString(data, mem_ctx, &cookie)) {
 
291
                return false;
 
292
        }
 
293
        lprc->cookie_len = cookie.length;
 
294
        if (lprc->cookie_len) {
 
295
                lprc->cookie = talloc_memdup(lprc, cookie.data, cookie.length);
 
296
 
 
297
                if (!(lprc->cookie)) {
 
298
                        return false;
 
299
                }
 
300
        } else {
 
301
                lprc->cookie = NULL;
 
302
        }
 
303
 
 
304
        if (!asn1_end_tag(data)) {
 
305
                return false;
 
306
        }
 
307
 
 
308
        *out = lprc;
 
309
 
 
310
        return true;
 
311
}
 
312
 
 
313
static bool decode_dirsync_request(void *mem_ctx, DATA_BLOB in, void *_out)
 
314
{
 
315
        void **out = (void **)_out;
 
316
        DATA_BLOB cookie;
 
317
        struct asn1_data *data = asn1_init(mem_ctx);
 
318
        struct ldb_dirsync_control *ldc;
 
319
 
 
320
        if (!data) return false;
 
321
 
 
322
        if (!asn1_load(data, in)) {
 
323
                return false;
 
324
        }
 
325
 
 
326
        ldc = talloc(mem_ctx, struct ldb_dirsync_control);
 
327
        if (!ldc) {
 
328
                return false;
 
329
        }
 
330
 
 
331
        if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
 
332
                return false;
 
333
        }
 
334
 
 
335
        if (!asn1_read_Integer(data, &(ldc->flags))) {
 
336
                return false;
 
337
        }
 
338
        
 
339
        if (!asn1_read_Integer(data, &(ldc->max_attributes))) {
 
340
                return false;
 
341
        }
 
342
        
 
343
        if (!asn1_read_OctetString(data, mem_ctx, &cookie)) {
 
344
                return false;
 
345
        }
 
346
        ldc->cookie_len = cookie.length;
 
347
        if (ldc->cookie_len) {
 
348
                ldc->cookie = talloc_memdup(ldc, cookie.data, cookie.length);
 
349
 
 
350
                if (!(ldc->cookie)) {
 
351
                        return false;
 
352
                }
 
353
        } else {
 
354
                ldc->cookie = NULL;
 
355
        }
 
356
 
 
357
        if (!asn1_end_tag(data)) {
 
358
                return false;
 
359
        }
 
360
 
 
361
        *out = ldc;
 
362
 
 
363
        return true;
 
364
}
 
365
 
 
366
/* seem that this controls has 2 forms one in case it is used with
 
367
 * a Search Request and another when used ina Search Response
 
368
 */
 
369
static bool decode_asq_control(void *mem_ctx, DATA_BLOB in, void *_out)
 
370
{
 
371
        void **out = (void **)_out;
 
372
        DATA_BLOB source_attribute;
 
373
        struct asn1_data *data = asn1_init(mem_ctx);
 
374
        struct ldb_asq_control *lac;
 
375
 
 
376
        if (!data) return false;
 
377
 
 
378
        if (!asn1_load(data, in)) {
 
379
                return false;
 
380
        }
 
381
 
 
382
        lac = talloc(mem_ctx, struct ldb_asq_control);
 
383
        if (!lac) {
 
384
                return false;
 
385
        }
 
386
 
 
387
        if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
 
388
                return false;
 
389
        }
 
390
 
 
391
        if (asn1_peek_tag(data, ASN1_OCTET_STRING)) {
 
392
 
 
393
                if (!asn1_read_OctetString(data, mem_ctx, &source_attribute)) {
 
394
                        return false;
 
395
                }
 
396
                lac->src_attr_len = source_attribute.length;
 
397
                if (lac->src_attr_len) {
 
398
                        lac->source_attribute = talloc_strndup(lac, (const char *)source_attribute.data, source_attribute.length);
 
399
 
 
400
                        if (!(lac->source_attribute)) {
 
401
                                return false;
 
402
                        }
 
403
                } else {
 
404
                        lac->source_attribute = NULL;
 
405
                }
 
406
 
 
407
                lac->request = 1;
 
408
 
 
409
        } else if (asn1_peek_tag(data, ASN1_ENUMERATED)) {
 
410
 
 
411
                if (!asn1_read_enumerated(data, &(lac->result))) {
 
412
                        return false;
 
413
                }
 
414
 
 
415
                lac->request = 0;
 
416
 
 
417
        } else {
 
418
                return false;
 
419
        }
 
420
 
 
421
        if (!asn1_end_tag(data)) {
 
422
                return false;
 
423
        }
 
424
 
 
425
        *out = lac;
 
426
 
 
427
        return true;
 
428
}
 
429
 
 
430
static bool decode_domain_scope_request(void *mem_ctx, DATA_BLOB in, void *_out)
 
431
{
 
432
        if (in.length != 0) {
 
433
                return false;
 
434
        }
 
435
 
 
436
        return true;
 
437
}
 
438
 
 
439
static bool decode_notification_request(void *mem_ctx, DATA_BLOB in, void *_out)
 
440
{
 
441
        if (in.length != 0) {
 
442
                return false;
 
443
        }
 
444
 
 
445
        return true;
 
446
}
 
447
 
 
448
static bool decode_show_deleted_request(void *mem_ctx, DATA_BLOB in, void *_out)
 
449
{
 
450
        if (in.length != 0) {
 
451
                return false;
 
452
        }
 
453
 
 
454
        return true;
 
455
}
 
456
 
 
457
static bool decode_permissive_modify_request(void *mem_ctx, DATA_BLOB in, void *_out)
 
458
{
 
459
        if (in.length != 0) {
 
460
                return false;
 
461
        }
 
462
 
 
463
        return true;
 
464
}
 
465
 
 
466
static bool decode_manageDSAIT_request(void *mem_ctx, DATA_BLOB in, void *_out)
 
467
{
 
468
        if (in.length != 0) {
 
469
                return false;
 
470
        }
 
471
 
 
472
        return true;
 
473
}
 
474
 
 
475
static bool decode_vlv_request(void *mem_ctx, DATA_BLOB in, void *_out)
 
476
{
 
477
        void **out = (void **)_out;
 
478
        DATA_BLOB assertion_value, context_id;
 
479
        struct asn1_data *data = asn1_init(mem_ctx);
 
480
        struct ldb_vlv_req_control *lvrc;
 
481
 
 
482
        if (!data) return false;
 
483
 
 
484
        if (!asn1_load(data, in)) {
 
485
                return false;
 
486
        }
 
487
 
 
488
        lvrc = talloc(mem_ctx, struct ldb_vlv_req_control);
 
489
        if (!lvrc) {
 
490
                return false;
 
491
        }
 
492
 
 
493
        if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
 
494
                return false;
 
495
        }
 
496
 
 
497
        if (!asn1_read_Integer(data, &(lvrc->beforeCount))) {
 
498
                return false;
 
499
        }
 
500
        
 
501
        if (!asn1_read_Integer(data, &(lvrc->afterCount))) {
 
502
                return false;
 
503
        }
 
504
 
 
505
        if (asn1_peek_tag(data, ASN1_CONTEXT(0))) {
 
506
 
 
507
                lvrc->type = 0;
 
508
                
 
509
                if (!asn1_start_tag(data, ASN1_CONTEXT(0))) {
 
510
                        return false;
 
511
                }
 
512
 
 
513
                if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
 
514
                        return false;
 
515
                }
 
516
 
 
517
                if (!asn1_read_Integer(data, &(lvrc->match.byOffset.offset))) {
 
518
                        return false;
 
519
                }
 
520
 
 
521
                if (!asn1_read_Integer(data, &(lvrc->match.byOffset.contentCount))) {
 
522
                        return false;
 
523
                }
 
524
 
 
525
                if (!asn1_end_tag(data)) { /*SEQUENCE*/
 
526
                        return false;
 
527
                }
 
528
 
 
529
                if (!asn1_end_tag(data)) { /*CONTEXT*/
 
530
                        return false;
 
531
                }
 
532
 
 
533
        } else {
 
534
 
 
535
                lvrc->type = 1;
 
536
 
 
537
                if (!asn1_start_tag(data, ASN1_CONTEXT(1))) {
 
538
                        return false;
 
539
                }
 
540
 
 
541
                if (!asn1_read_OctetString(data, mem_ctx, &assertion_value)) {
 
542
                        return false;
 
543
                }
 
544
                lvrc->match.gtOrEq.value_len = assertion_value.length;
 
545
                if (lvrc->match.gtOrEq.value_len) {
 
546
                        lvrc->match.gtOrEq.value = talloc_memdup(lvrc, assertion_value.data, assertion_value.length);
 
547
 
 
548
                        if (!(lvrc->match.gtOrEq.value)) {
 
549
                                return false;
 
550
                        }
 
551
                } else {
 
552
                        lvrc->match.gtOrEq.value = NULL;
 
553
                }
 
554
 
 
555
                if (!asn1_end_tag(data)) { /*CONTEXT*/
 
556
                        return false;
 
557
                }
 
558
        }
 
559
 
 
560
        if (asn1_peek_tag(data, ASN1_OCTET_STRING)) {
 
561
                if (!asn1_read_OctetString(data, mem_ctx, &context_id)) {
 
562
                        return false;
 
563
                }
 
564
                lvrc->ctxid_len = context_id.length;
 
565
                if (lvrc->ctxid_len) {
 
566
                        lvrc->contextId = talloc_memdup(lvrc, context_id.data, context_id.length);
 
567
 
 
568
                        if (!(lvrc->contextId)) {
 
569
                                return false;
 
570
                        }
 
571
                } else {
 
572
                        lvrc->contextId = NULL;
 
573
                }
 
574
        } else {
 
575
                lvrc->contextId = NULL;
 
576
                lvrc->ctxid_len = 0;
 
577
        }
 
578
 
 
579
        if (!asn1_end_tag(data)) {
 
580
                return false;
 
581
        }
 
582
 
 
583
        *out = lvrc;
 
584
 
 
585
        return true;
 
586
}
 
587
 
 
588
static bool decode_vlv_response(void *mem_ctx, DATA_BLOB in, void *_out)
 
589
{
 
590
        void **out = (void **)_out;
 
591
        DATA_BLOB context_id;
 
592
        struct asn1_data *data = asn1_init(mem_ctx);
 
593
        struct ldb_vlv_resp_control *lvrc;
 
594
 
 
595
        if (!data) return false;
 
596
 
 
597
        if (!asn1_load(data, in)) {
 
598
                return false;
 
599
        }
 
600
 
 
601
        lvrc = talloc(mem_ctx, struct ldb_vlv_resp_control);
 
602
        if (!lvrc) {
 
603
                return false;
 
604
        }
 
605
 
 
606
        if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
 
607
                return false;
 
608
        }
 
609
 
 
610
        if (!asn1_read_Integer(data, &(lvrc->targetPosition))) {
 
611
                return false;
 
612
        }
 
613
        
 
614
        if (!asn1_read_Integer(data, &(lvrc->contentCount))) {
 
615
                return false;
 
616
        }
 
617
        
 
618
        if (!asn1_read_enumerated(data, &(lvrc->vlv_result))) {
 
619
                return false;
 
620
        }
 
621
 
 
622
        if (asn1_peek_tag(data, ASN1_OCTET_STRING)) {
 
623
                if (!asn1_read_OctetString(data, mem_ctx, &context_id)) {
 
624
                        return false;
 
625
                }
 
626
                lvrc->contextId = talloc_strndup(lvrc, (const char *)context_id.data, context_id.length);
 
627
                if (!lvrc->contextId) {
 
628
                        return false;
 
629
                }
 
630
                lvrc->ctxid_len = context_id.length;
 
631
        } else {
 
632
                lvrc->contextId = NULL;
 
633
                lvrc->ctxid_len = 0;
 
634
        }
 
635
 
 
636
        if (!asn1_end_tag(data)) {
 
637
                return false;
 
638
        }
 
639
 
 
640
        *out = lvrc;
 
641
 
 
642
        return true;
 
643
}
 
644
 
 
645
static bool encode_server_sort_response(void *mem_ctx, void *in, DATA_BLOB *out)
 
646
{
 
647
        struct ldb_sort_resp_control *lsrc = talloc_get_type(in, struct ldb_sort_resp_control);
 
648
        struct asn1_data *data = asn1_init(mem_ctx);
 
649
 
 
650
        if (!data) return false;
 
651
 
 
652
        if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
 
653
                return false;
 
654
        }
 
655
 
 
656
        if (!asn1_write_enumerated(data, lsrc->result)) {
 
657
                return false;
 
658
        }
 
659
 
 
660
        if (lsrc->attr_desc) {
 
661
                if (!asn1_write_OctetString(data, lsrc->attr_desc, strlen(lsrc->attr_desc))) {
 
662
                        return false;
 
663
                }
 
664
        }
 
665
 
 
666
        if (!asn1_pop_tag(data)) {
 
667
                return false;
 
668
        }
 
669
 
 
670
        *out = data_blob_talloc(mem_ctx, data->data, data->length);
 
671
        if (out->data == NULL) {
 
672
                return false;
 
673
        }
 
674
        talloc_free(data);
 
675
 
 
676
        return true;
 
677
}
 
678
 
 
679
static bool encode_server_sort_request(void *mem_ctx, void *in, DATA_BLOB *out)
 
680
{
 
681
        struct ldb_server_sort_control **lssc = talloc_get_type(in, struct ldb_server_sort_control *);
 
682
        struct asn1_data *data = asn1_init(mem_ctx);
 
683
        int num;
 
684
 
 
685
        if (!data) return false;
 
686
 
 
687
        if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
 
688
                return false;
 
689
        }
 
690
 
 
691
        for (num = 0; lssc[num]; num++) {
 
692
                if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
 
693
                        return false;
 
694
                }
 
695
                
 
696
                if (!asn1_write_OctetString(data, lssc[num]->attributeName, strlen(lssc[num]->attributeName))) {
 
697
                        return false;
 
698
                }
 
699
 
 
700
                if (lssc[num]->orderingRule) {
 
701
                        if (!asn1_write_OctetString(data, lssc[num]->orderingRule, strlen(lssc[num]->orderingRule))) {
 
702
                                return false;
 
703
                        }
 
704
                }
 
705
 
 
706
                if (lssc[num]->reverse) {
 
707
                        if (!asn1_write_BOOLEAN(data, lssc[num]->reverse)) {
 
708
                                return false;
 
709
                        }
 
710
                }
 
711
 
 
712
                if (!asn1_pop_tag(data)) {
 
713
                        return false;
 
714
                }
 
715
        }
 
716
 
 
717
        if (!asn1_pop_tag(data)) {
 
718
                return false;
 
719
        }
 
720
 
 
721
        *out = data_blob_talloc(mem_ctx, data->data, data->length);
 
722
        if (out->data == NULL) {
 
723
                return false;
 
724
        }
 
725
        talloc_free(data);
 
726
 
 
727
        return true;
 
728
}
 
729
 
 
730
static bool encode_extended_dn_request(void *mem_ctx, void *in, DATA_BLOB *out)
 
731
{
 
732
        struct ldb_extended_dn_control *ledc = talloc_get_type(in, struct ldb_extended_dn_control);
 
733
        struct asn1_data *data;
 
734
 
 
735
        if (!in) {
 
736
                *out = data_blob(NULL, 0);
 
737
                return true;
 
738
        }
 
739
 
 
740
        data = asn1_init(mem_ctx);
 
741
 
 
742
        if (!data) return false;
 
743
 
 
744
        if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
 
745
                return false;
 
746
        }
 
747
 
 
748
        if (!asn1_write_Integer(data, ledc->type)) {
 
749
                return false;
 
750
        }
 
751
 
 
752
        if (!asn1_pop_tag(data)) {
 
753
                return false;
 
754
        }
 
755
 
 
756
        *out = data_blob_talloc(mem_ctx, data->data, data->length);
 
757
        if (out->data == NULL) {
 
758
                return false;
 
759
        }
 
760
        talloc_free(data);
 
761
 
 
762
        return true;
 
763
}
 
764
 
 
765
static bool encode_sd_flags_request(void *mem_ctx, void *in, DATA_BLOB *out)
 
766
{
 
767
        struct ldb_sd_flags_control *lsdfc = talloc_get_type(in, struct ldb_sd_flags_control);
 
768
        struct asn1_data *data = asn1_init(mem_ctx);
 
769
 
 
770
        if (!data) return false;
 
771
 
 
772
        if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
 
773
                return false;
 
774
        }
 
775
 
 
776
        if (!asn1_write_Integer(data, lsdfc->secinfo_flags)) {
 
777
                return false;
 
778
        }
 
779
 
 
780
        if (!asn1_pop_tag(data)) {
 
781
                return false;
 
782
        }
 
783
 
 
784
        *out = data_blob_talloc(mem_ctx, data->data, data->length);
 
785
        if (out->data == NULL) {
 
786
                return false;
 
787
        }
 
788
        talloc_free(data);
 
789
 
 
790
        return true;
 
791
}
 
792
 
 
793
static bool encode_search_options_request(void *mem_ctx, void *in, DATA_BLOB *out)
 
794
{
 
795
        struct ldb_search_options_control *lsoc = talloc_get_type(in, struct ldb_search_options_control);
 
796
        struct asn1_data *data = asn1_init(mem_ctx);
 
797
 
 
798
        if (!data) return false;
 
799
 
 
800
        if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
 
801
                return false;
 
802
        }
 
803
 
 
804
        if (!asn1_write_Integer(data, lsoc->search_options)) {
 
805
                return false;
 
806
        }
 
807
 
 
808
        if (!asn1_pop_tag(data)) {
 
809
                return false;
 
810
        }
 
811
 
 
812
        *out = data_blob_talloc(mem_ctx, data->data, data->length);
 
813
        if (out->data == NULL) {
 
814
                return false;
 
815
        }
 
816
        talloc_free(data);
 
817
 
 
818
        return true;
 
819
}
 
820
 
 
821
static bool encode_paged_results_request(void *mem_ctx, void *in, DATA_BLOB *out)
 
822
{
 
823
        struct ldb_paged_control *lprc = talloc_get_type(in, struct ldb_paged_control);
 
824
        struct asn1_data *data = asn1_init(mem_ctx);
 
825
 
 
826
        if (!data) return false;
 
827
 
 
828
        if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
 
829
                return false;
 
830
        }
 
831
 
 
832
        if (!asn1_write_Integer(data, lprc->size)) {
 
833
                return false;
 
834
        }
 
835
 
 
836
        if (!asn1_write_OctetString(data, lprc->cookie, lprc->cookie_len)) {
 
837
                return false;
 
838
        }       
 
839
 
 
840
        if (!asn1_pop_tag(data)) {
 
841
                return false;
 
842
        }
 
843
 
 
844
        *out = data_blob_talloc(mem_ctx, data->data, data->length);
 
845
        if (out->data == NULL) {
 
846
                return false;
 
847
        }
 
848
        talloc_free(data);
 
849
 
 
850
        return true;
 
851
}
 
852
 
 
853
/* seem that this controls has 2 forms one in case it is used with
 
854
 * a Search Request and another when used ina Search Response
 
855
 */
 
856
static bool encode_asq_control(void *mem_ctx, void *in, DATA_BLOB *out)
 
857
{
 
858
        struct ldb_asq_control *lac = talloc_get_type(in, struct ldb_asq_control);
 
859
        struct asn1_data *data = asn1_init(mem_ctx);
 
860
 
 
861
        if (!data) return false;
 
862
 
 
863
        if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
 
864
                return false;
 
865
        }
 
866
 
 
867
        if (lac->request) {
 
868
 
 
869
                if (!asn1_write_OctetString(data, lac->source_attribute, lac->src_attr_len)) {
 
870
                        return false;
 
871
                }
 
872
        } else {
 
873
                if (!asn1_write_enumerated(data, lac->result)) {
 
874
                        return false;
 
875
                }
 
876
        }
 
877
 
 
878
        if (!asn1_pop_tag(data)) {
 
879
                return false;
 
880
        }
 
881
 
 
882
        *out = data_blob_talloc(mem_ctx, data->data, data->length);
 
883
        if (out->data == NULL) {
 
884
                return false;
 
885
        }
 
886
        talloc_free(data);
 
887
 
 
888
        return true;
 
889
}
 
890
 
 
891
static bool encode_dirsync_request(void *mem_ctx, void *in, DATA_BLOB *out)
 
892
{
 
893
        struct ldb_dirsync_control *ldc = talloc_get_type(in, struct ldb_dirsync_control);
 
894
        struct asn1_data *data = asn1_init(mem_ctx);
 
895
 
 
896
        if (!data) return false;
 
897
 
 
898
        if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
 
899
                return false;
 
900
        }
 
901
 
 
902
        if (!asn1_write_Integer(data, ldc->flags)) {
 
903
                return false;
 
904
        }
 
905
 
 
906
        if (!asn1_write_Integer(data, ldc->max_attributes)) {
 
907
                return false;
 
908
        }
 
909
 
 
910
        if (!asn1_write_OctetString(data, ldc->cookie, ldc->cookie_len)) {
 
911
                return false;
 
912
        }       
 
913
 
 
914
        if (!asn1_pop_tag(data)) {
 
915
                return false;
 
916
        }
 
917
 
 
918
        *out = data_blob_talloc(mem_ctx, data->data, data->length);
 
919
        if (out->data == NULL) {
 
920
                return false;
 
921
        }
 
922
        talloc_free(data);
 
923
 
 
924
        return true;
 
925
}
 
926
 
 
927
static bool encode_domain_scope_request(void *mem_ctx, void *in, DATA_BLOB *out)
 
928
{
 
929
        if (in) {
 
930
                return false;
 
931
        }
 
932
 
 
933
        *out = data_blob(NULL, 0);
 
934
        return true;
 
935
}
 
936
 
 
937
static bool encode_notification_request(void *mem_ctx, void *in, DATA_BLOB *out)
 
938
{
 
939
        if (in) {
 
940
                return false;
 
941
        }
 
942
 
 
943
        *out = data_blob(NULL, 0);
 
944
        return true;
 
945
}
 
946
 
 
947
static bool encode_show_deleted_request(void *mem_ctx, void *in, DATA_BLOB *out)
 
948
{
 
949
        if (in) {
 
950
                return false;
 
951
        }
 
952
 
 
953
        *out = data_blob(NULL, 0);
 
954
        return true;
 
955
}
 
956
 
 
957
static bool encode_permissive_modify_request(void *mem_ctx, void *in, DATA_BLOB *out)
 
958
{
 
959
        if (in) {
 
960
                return false;
 
961
        }
 
962
 
 
963
        *out = data_blob(NULL, 0);
 
964
        return true;
 
965
}
 
966
 
 
967
static bool encode_manageDSAIT_request(void *mem_ctx, void *in, DATA_BLOB *out)
 
968
{
 
969
        if (in) {
 
970
                return false;
 
971
        }
 
972
 
 
973
        *out = data_blob(NULL, 0);
 
974
        return true;
 
975
}
 
976
 
 
977
static bool encode_vlv_request(void *mem_ctx, void *in, DATA_BLOB *out)
 
978
{
 
979
        struct ldb_vlv_req_control *lvrc = talloc_get_type(in, struct ldb_vlv_req_control);
 
980
        struct asn1_data *data = asn1_init(mem_ctx);
 
981
 
 
982
        if (!data) return false;
 
983
 
 
984
        if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
 
985
                return false;
 
986
        }
 
987
 
 
988
        if (!asn1_write_Integer(data, lvrc->beforeCount)) {
 
989
                return false;
 
990
        }
 
991
 
 
992
        if (!asn1_write_Integer(data, lvrc->afterCount)) {
 
993
                return false;
 
994
        }
 
995
 
 
996
        if (lvrc->type == 0) {
 
997
                if (!asn1_push_tag(data, ASN1_CONTEXT(0))) {
 
998
                        return false;
 
999
                }
 
1000
                
 
1001
                if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
 
1002
                        return false;
 
1003
                }
 
1004
                
 
1005
                if (!asn1_write_Integer(data, lvrc->match.byOffset.offset)) {
 
1006
                        return false;
 
1007
                }
 
1008
 
 
1009
                if (!asn1_write_Integer(data, lvrc->match.byOffset.contentCount)) {
 
1010
                        return false;
 
1011
                }
 
1012
 
 
1013
                if (!asn1_pop_tag(data)) { /*SEQUENCE*/
 
1014
                        return false;
 
1015
                }
 
1016
 
 
1017
                if (!asn1_pop_tag(data)) { /*CONTEXT*/
 
1018
                        return false;
 
1019
                }
 
1020
        } else {
 
1021
                if (!asn1_push_tag(data, ASN1_CONTEXT(1))) {
 
1022
                        return false;
 
1023
                }
 
1024
                
 
1025
                if (!asn1_write_OctetString(data, lvrc->match.gtOrEq.value, lvrc->match.gtOrEq.value_len)) {
 
1026
                        return false;
 
1027
                }
 
1028
 
 
1029
                if (!asn1_pop_tag(data)) { /*CONTEXT*/
 
1030
                        return false;
 
1031
                }
 
1032
        }
 
1033
 
 
1034
        if (lvrc->ctxid_len) {
 
1035
                if (!asn1_write_OctetString(data, lvrc->contextId, lvrc->ctxid_len)) {
 
1036
                        return false;
 
1037
                }
 
1038
        }
 
1039
 
 
1040
        if (!asn1_pop_tag(data)) {
 
1041
                return false;
 
1042
        }
 
1043
 
 
1044
        *out = data_blob_talloc(mem_ctx, data->data, data->length);
 
1045
        if (out->data == NULL) {
 
1046
                return false;
 
1047
        }
 
1048
        talloc_free(data);
 
1049
 
 
1050
        return true;
 
1051
}
 
1052
 
 
1053
static bool encode_vlv_response(void *mem_ctx, void *in, DATA_BLOB *out)
 
1054
{
 
1055
        struct ldb_vlv_resp_control *lvrc = talloc_get_type(in, struct ldb_vlv_resp_control);
 
1056
        struct asn1_data *data = asn1_init(mem_ctx);
 
1057
 
 
1058
        if (!data) return false;
 
1059
 
 
1060
        if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
 
1061
                return false;
 
1062
        }
 
1063
 
 
1064
        if (!asn1_write_Integer(data, lvrc->targetPosition)) {
 
1065
                return false;
 
1066
        }
 
1067
 
 
1068
        if (!asn1_write_Integer(data, lvrc->contentCount)) {
 
1069
                return false;
 
1070
        }
 
1071
 
 
1072
        if (!asn1_write_enumerated(data, lvrc->vlv_result)) {
 
1073
                return false;
 
1074
        }
 
1075
 
 
1076
        if (lvrc->ctxid_len) {
 
1077
                if (!asn1_write_OctetString(data, lvrc->contextId, lvrc->ctxid_len)) {
 
1078
                        return false;
 
1079
                }
 
1080
        }
 
1081
 
 
1082
        if (!asn1_pop_tag(data)) {
 
1083
                return false;
 
1084
        }
 
1085
 
 
1086
        *out = data_blob_talloc(mem_ctx, data->data, data->length);
 
1087
        if (out->data == NULL) {
 
1088
                return false;
 
1089
        }
 
1090
        talloc_free(data);
 
1091
 
 
1092
        return true;
 
1093
}
 
1094
 
 
1095
static bool encode_openldap_dereference(void *mem_ctx, void *in, DATA_BLOB *out)
 
1096
{
 
1097
        struct dsdb_openldap_dereference_control *control = talloc_get_type(in, struct dsdb_openldap_dereference_control);
 
1098
        int i,j;
 
1099
        struct asn1_data *data = asn1_init(mem_ctx);
 
1100
 
 
1101
        if (!data) return false;
 
1102
        
 
1103
        if (!control) return false;
 
1104
        
 
1105
        if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
 
1106
                return false;
 
1107
        }
 
1108
        
 
1109
        for (i=0; control->dereference && control->dereference[i]; i++) {
 
1110
                if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
 
1111
                        return false;
 
1112
                }
 
1113
                if (!asn1_write_OctetString(data, control->dereference[i]->source_attribute, strlen(control->dereference[i]->source_attribute))) {
 
1114
                        return false;
 
1115
                }
 
1116
                if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
 
1117
                        return false;
 
1118
                }
 
1119
                for (j=0; control->dereference && control->dereference[i]->dereference_attribute[j]; j++) {
 
1120
                        if (!asn1_write_OctetString(data, control->dereference[i]->dereference_attribute[j], 
 
1121
                                                    strlen(control->dereference[i]->dereference_attribute[j]))) {
 
1122
                                return false;
 
1123
                        }
 
1124
                }
 
1125
                
 
1126
                asn1_pop_tag(data);
 
1127
                asn1_pop_tag(data);
 
1128
        }
 
1129
        asn1_pop_tag(data);
 
1130
 
 
1131
        *out = data_blob_talloc(mem_ctx, data->data, data->length);
 
1132
        if (out->data == NULL) {
 
1133
                return false;
 
1134
        }
 
1135
        talloc_free(data);
 
1136
        return true;
 
1137
}
 
1138
 
 
1139
static bool decode_openldap_dereference(void *mem_ctx, DATA_BLOB in, void *_out)
 
1140
{
 
1141
        void **out = (void **)_out;
 
1142
        struct asn1_data *data = asn1_init(mem_ctx);
 
1143
        struct dsdb_openldap_dereference_result_control *control;
 
1144
        struct dsdb_openldap_dereference_result **r = NULL;
 
1145
        int i = 0;
 
1146
        if (!data) return false;
 
1147
 
 
1148
        control = talloc(mem_ctx, struct dsdb_openldap_dereference_result_control);
 
1149
        if (!control) return false;
 
1150
 
 
1151
        if (!asn1_load(data, in)) {
 
1152
                return false;
 
1153
        }
 
1154
 
 
1155
        control = talloc(mem_ctx, struct dsdb_openldap_dereference_result_control);
 
1156
        if (!control) {
 
1157
                return false;
 
1158
        }
 
1159
 
 
1160
        if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
 
1161
                return false;
 
1162
        }
 
1163
 
 
1164
        while (asn1_tag_remaining(data) > 0) {                                  
 
1165
                r = talloc_realloc(control, r, struct dsdb_openldap_dereference_result *, i + 2);
 
1166
                if (!r) {
 
1167
                        return false;
 
1168
                }
 
1169
                r[i] = talloc_zero(r, struct dsdb_openldap_dereference_result);
 
1170
                if (!r[i]) {
 
1171
                        return false;
 
1172
                }
 
1173
 
 
1174
                if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
 
1175
                        return false;
 
1176
                }
 
1177
                
 
1178
                asn1_read_OctetString_talloc(r[i], data, &r[i]->source_attribute);
 
1179
                asn1_read_OctetString_talloc(r[i], data, &r[i]->dereferenced_dn);
 
1180
                if (asn1_peek_tag(data, ASN1_CONTEXT(0))) {
 
1181
                        if (!asn1_start_tag(data, ASN1_CONTEXT(0))) {
 
1182
                                return false;
 
1183
                        }
 
1184
                        
 
1185
                        ldap_decode_attribs_bare(r, data, &r[i]->attributes,
 
1186
                                                 &r[i]->num_attributes);
 
1187
                        
 
1188
                        if (!asn1_end_tag(data)) {
 
1189
                                return false;
 
1190
                        }
 
1191
                }
 
1192
                if (!asn1_end_tag(data)) {
 
1193
                        return false;
 
1194
                }
 
1195
                i++;
 
1196
                r[i] = NULL;
 
1197
        }
 
1198
 
 
1199
        if (!asn1_end_tag(data)) {
 
1200
                return false;
 
1201
        }
 
1202
 
 
1203
        control->attributes = r;
 
1204
        *out = control;
 
1205
 
 
1206
        return true;
 
1207
}
 
1208
 
 
1209
static const struct ldap_control_handler ldap_known_controls[] = {
 
1210
        { "1.2.840.113556.1.4.319", decode_paged_results_request, encode_paged_results_request },
 
1211
        { "1.2.840.113556.1.4.529", decode_extended_dn_request, encode_extended_dn_request },
 
1212
        { "1.2.840.113556.1.4.473", decode_server_sort_request, encode_server_sort_request },
 
1213
        { "1.2.840.113556.1.4.474", decode_server_sort_response, encode_server_sort_response },
 
1214
        { "1.2.840.113556.1.4.1504", decode_asq_control, encode_asq_control },
 
1215
        { "1.2.840.113556.1.4.841", decode_dirsync_request, encode_dirsync_request },
 
1216
        { "1.2.840.113556.1.4.528", decode_notification_request, encode_notification_request },
 
1217
        { "1.2.840.113556.1.4.417", decode_show_deleted_request, encode_show_deleted_request },
 
1218
        { "1.2.840.113556.1.4.1413", decode_permissive_modify_request, encode_permissive_modify_request },
 
1219
        { "1.2.840.113556.1.4.801", decode_sd_flags_request, encode_sd_flags_request },
 
1220
        { "1.2.840.113556.1.4.1339", decode_domain_scope_request, encode_domain_scope_request },
 
1221
        { "1.2.840.113556.1.4.1340", decode_search_options_request, encode_search_options_request },
 
1222
        { "2.16.840.1.113730.3.4.2", decode_manageDSAIT_request, encode_manageDSAIT_request },
 
1223
        { "2.16.840.1.113730.3.4.9", decode_vlv_request, encode_vlv_request },
 
1224
        { "2.16.840.1.113730.3.4.10", decode_vlv_response, encode_vlv_response },
 
1225
/* DSDB_CONTROL_CURRENT_PARTITION_OID is internal only, and has no network representation */
 
1226
        { "1.3.6.1.4.1.7165.4.3.2", NULL, NULL },
 
1227
/* DSDB_EXTENDED_REPLICATED_OBJECTS_OID is internal only, and has no network representation */
 
1228
        { "1.3.6.1.4.1.7165.4.4.1", NULL, NULL },
 
1229
        { DSDB_OPENLDAP_DEREFERENCE_CONTROL, decode_openldap_dereference, encode_openldap_dereference},
 
1230
        { NULL, NULL, NULL }
 
1231
};
 
1232
 
 
1233
const struct ldap_control_handler *samba_ldap_control_handlers(void)
 
1234
{
 
1235
        return ldap_known_controls;
 
1236
}
 
1237