Coverage Report

Created: 2026-01-16 06:47

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/libcli/ldap/ldap_message.c
Line
Count
Source
1
/* 
2
   Unix SMB/CIFS implementation.
3
   LDAP protocol helper functions for SAMBA
4
   
5
   Copyright (C) Andrew Tridgell  2004
6
   Copyright (C) Volker Lendecke 2004
7
   Copyright (C) Stefan Metzmacher 2004
8
   Copyright (C) Simo Sorce 2004
9
    
10
   This program is free software; you can redistribute it and/or modify
11
   it under the terms of the GNU General Public License as published by
12
   the Free Software Foundation; either version 3 of the License, or
13
   (at your option) any later version.
14
   
15
   This program 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
18
   GNU General Public License for more details.
19
   
20
   You should have received a copy of the GNU General Public License
21
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
   
23
*/
24
25
#include "includes.h"
26
#include "../lib/util/asn1.h"
27
#include "../libcli/ldap/ldap_message.h"
28
29
_PUBLIC_ struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx)
30
0
{
31
0
  return talloc_zero(mem_ctx, struct ldap_message);
32
0
}
33
34
35
static bool add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value,
36
        struct ldb_message_element *attrib)
37
45.4k
{
38
45.4k
  attrib->values = talloc_realloc(mem_ctx,
39
45.4k
          attrib->values,
40
45.4k
          DATA_BLOB,
41
45.4k
          attrib->num_values+1);
42
45.4k
  if (attrib->values == NULL)
43
0
    return false;
44
45
45.4k
  attrib->values[attrib->num_values].data = talloc_steal(attrib->values,
46
45.4k
                     value->data);
47
45.4k
  attrib->values[attrib->num_values].length = value->length;
48
45.4k
  attrib->num_values += 1;
49
45.4k
  return true;
50
45.4k
}
51
52
static bool add_attrib_to_array_talloc(TALLOC_CTX *mem_ctx,
53
               const struct ldb_message_element *attrib,
54
               struct ldb_message_element **attribs,
55
               int *num_attribs)
56
100
{
57
100
  *attribs = talloc_realloc(mem_ctx,
58
100
          *attribs,
59
100
          struct ldb_message_element,
60
100
          *num_attribs+1);
61
62
100
  if (*attribs == NULL)
63
0
    return false;
64
65
100
  (*attribs)[*num_attribs] = *attrib;
66
100
  talloc_steal(*attribs, attrib->values);
67
100
  talloc_steal(*attribs, attrib->name);
68
100
  *num_attribs += 1;
69
100
  return true;
70
100
}
71
72
static bool add_mod_to_array_talloc(TALLOC_CTX *mem_ctx,
73
            struct ldap_mod *mod,
74
            struct ldap_mod **mods,
75
            int *num_mods)
76
44
{
77
44
  *mods = talloc_realloc(mem_ctx, *mods, struct ldap_mod, (*num_mods)+1);
78
79
44
  if (*mods == NULL)
80
0
    return false;
81
82
44
  (*mods)[*num_mods] = *mod;
83
44
  *num_mods += 1;
84
44
  return true;
85
44
}
86
87
static bool ldap_decode_control_value(void *mem_ctx, DATA_BLOB value,
88
              const struct ldap_control_handler *handlers,
89
              struct ldb_control *ctrl)
90
1.69k
{
91
1.69k
  int i;
92
93
1.69k
  if (!handlers) {
94
0
    return true;
95
0
  }
96
97
53.6k
  for (i = 0; handlers[i].oid != NULL; i++) {
98
53.1k
    if (strcmp(handlers[i].oid, ctrl->oid) == 0) {
99
1.16k
      if (!handlers[i].decode || !handlers[i].decode(mem_ctx, value, &ctrl->data)) {
100
955
        return false;
101
955
      }
102
207
      break;
103
1.16k
    }
104
53.1k
  }
105
742
  if (handlers[i].oid == NULL) {
106
535
    return false;
107
535
  }
108
109
207
  return true;
110
742
}
111
112
static bool ldap_decode_control_wrapper(void *mem_ctx, struct asn1_data *data,
113
          struct ldb_control *ctrl, DATA_BLOB *value)
114
1.76k
{
115
1.76k
  DATA_BLOB oid;
116
117
1.76k
  if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
118
35
    return false;
119
35
  }
120
121
1.72k
  if (!asn1_read_OctetString(data, mem_ctx, &oid)) {
122
14
    return false;
123
14
  }
124
1.71k
  ctrl->oid = talloc_strndup(mem_ctx, (char *)oid.data, oid.length);
125
1.71k
  if (!ctrl->oid) {
126
0
    return false;
127
0
  }
128
129
1.71k
  if (asn1_peek_tag(data, ASN1_BOOLEAN)) {
130
135
    bool critical;
131
135
    if (!asn1_read_BOOLEAN(data, &critical)) {
132
8
      return false;
133
8
    }
134
127
    ctrl->critical = critical;
135
1.58k
  } else {
136
1.58k
    ctrl->critical = false;
137
1.58k
  }
138
139
1.70k
  ctrl->data = NULL;
140
141
1.70k
  if (!asn1_peek_tag(data, ASN1_OCTET_STRING)) {
142
670
    *value = data_blob(NULL, 0);
143
670
    goto end_tag;
144
670
  }
145
146
1.03k
  if (!asn1_read_OctetString(data, mem_ctx, value)) {
147
3
    return false;
148
3
  }
149
150
1.70k
end_tag:
151
1.70k
  if (!asn1_end_tag(data)) {
152
7
    return false;
153
7
  }
154
155
1.69k
  return true;
156
1.70k
}
157
158
static bool ldap_encode_control(void *mem_ctx, struct asn1_data *data,
159
        const struct ldap_control_handler *handlers,
160
        struct ldb_control *ctrl)
161
0
{
162
0
  DATA_BLOB value;
163
0
  int i;
164
165
0
  if (!handlers) {
166
0
    return false;
167
0
  }
168
169
0
  for (i = 0; handlers[i].oid != NULL; i++) {
170
0
    if (!ctrl->oid) {
171
      /* not encoding this control, the OID has been
172
       * set to NULL indicating it isn't really
173
       * here */
174
0
      return true;
175
0
    }
176
0
    if (strcmp(handlers[i].oid, ctrl->oid) == 0) {
177
0
      if (!handlers[i].encode) {
178
0
        if (ctrl->critical) {
179
0
          return false;
180
0
        } else {
181
          /* not encoding this control */
182
0
          return true;
183
0
        }
184
0
      }
185
0
      if (!handlers[i].encode(mem_ctx, ctrl->data, &value)) {
186
0
        return false;
187
0
      }
188
0
      break;
189
0
    }
190
0
  }
191
0
  if (handlers[i].oid == NULL) {
192
0
    return false;
193
0
  }
194
195
0
  if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
196
0
    return false;
197
0
  }
198
199
0
  if (!asn1_write_OctetString(data, ctrl->oid, strlen(ctrl->oid))) {
200
0
    return false;
201
0
  }
202
203
0
  if (ctrl->critical) {
204
0
    if (!asn1_write_BOOLEAN(data, ctrl->critical)) {
205
0
      return false;
206
0
    }
207
0
  }
208
209
0
  if (!ctrl->data) {
210
0
    goto pop_tag;
211
0
  }
212
213
0
  if (!asn1_write_OctetString(data, value.data, value.length)) {
214
0
    return false;
215
0
  }
216
217
0
pop_tag:
218
0
  if (!asn1_pop_tag(data)) {
219
0
    return false;
220
0
  }
221
222
0
  return true;
223
0
}
224
225
static bool ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree)
226
0
{
227
0
  int i;
228
229
0
  switch (tree->operation) {
230
0
  case LDB_OP_AND:
231
0
  case LDB_OP_OR:
232
0
    if (!asn1_push_tag(data, ASN1_CONTEXT(tree->operation==LDB_OP_AND?0:1))) return false;
233
0
    for (i=0; i<tree->u.list.num_elements; i++) {
234
0
      if (!ldap_push_filter(data, tree->u.list.elements[i])) {
235
0
        return false;
236
0
      }
237
0
    }
238
0
    if (!asn1_pop_tag(data)) return false;
239
0
    break;
240
241
0
  case LDB_OP_NOT:
242
0
    if (!asn1_push_tag(data, ASN1_CONTEXT(2))) return false;
243
0
    if (!ldap_push_filter(data, tree->u.isnot.child)) {
244
0
      return false;
245
0
    }
246
0
    if (!asn1_pop_tag(data)) return false;
247
0
    break;
248
249
0
  case LDB_OP_EQUALITY:
250
    /* equality test */
251
0
    if (!asn1_push_tag(data, ASN1_CONTEXT(3))) return false;
252
0
    if (!asn1_write_OctetString(data, tree->u.equality.attr,
253
0
              strlen(tree->u.equality.attr))) return false;
254
0
    if (!asn1_write_OctetString(data, tree->u.equality.value.data,
255
0
              tree->u.equality.value.length)) return false;
256
0
    if (!asn1_pop_tag(data)) return false;
257
0
    break;
258
259
0
  case LDB_OP_SUBSTRING:
260
    /*
261
      SubstringFilter ::= SEQUENCE {
262
        type            AttributeDescription,
263
        -- at least one must be present
264
        substrings      SEQUENCE OF CHOICE {
265
          initial [0] LDAPString,
266
          any     [1] LDAPString,
267
          final   [2] LDAPString } }
268
    */
269
0
    if (!asn1_push_tag(data, ASN1_CONTEXT(4))) return false;
270
0
    if (!asn1_write_OctetString(data, tree->u.substring.attr, strlen(tree->u.substring.attr))) return false;
271
0
    if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) return false;
272
273
0
    if (tree->u.substring.chunks && tree->u.substring.chunks[0]) {
274
0
      i = 0;
275
0
      if (!tree->u.substring.start_with_wildcard) {
276
0
        if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0))) return false;
277
0
        if (!asn1_write_DATA_BLOB_LDAPString(data, tree->u.substring.chunks[i])) return false;
278
0
        if (!asn1_pop_tag(data)) return false;
279
0
        i++;
280
0
      }
281
0
      while (tree->u.substring.chunks[i]) {
282
0
        int ctx;
283
284
0
        if (( ! tree->u.substring.chunks[i + 1]) &&
285
0
            (tree->u.substring.end_with_wildcard == 0)) {
286
0
          ctx = 2;
287
0
        } else {
288
0
          ctx = 1;
289
0
        }
290
0
        if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(ctx))) return false;
291
0
        if (!asn1_write_DATA_BLOB_LDAPString(data, tree->u.substring.chunks[i])) return false;
292
0
        if (!asn1_pop_tag(data)) return false;
293
0
        i++;
294
0
      }
295
0
    }
296
0
    if (!asn1_pop_tag(data)) return false;
297
0
    if (!asn1_pop_tag(data)) return false;
298
0
    break;
299
300
0
  case LDB_OP_GREATER:
301
    /* greaterOrEqual test */
302
0
    if (!asn1_push_tag(data, ASN1_CONTEXT(5))) return false;
303
0
    if (!asn1_write_OctetString(data, tree->u.comparison.attr,
304
0
              strlen(tree->u.comparison.attr))) return false;
305
0
    if (!asn1_write_OctetString(data, tree->u.comparison.value.data,
306
0
              tree->u.comparison.value.length)) return false;
307
0
    if (!asn1_pop_tag(data)) return false;
308
0
    break;
309
310
0
  case LDB_OP_LESS:
311
    /* lessOrEqual test */
312
0
    if (!asn1_push_tag(data, ASN1_CONTEXT(6))) return false;
313
0
    if (!asn1_write_OctetString(data, tree->u.comparison.attr,
314
0
              strlen(tree->u.comparison.attr))) return false;
315
0
    if (!asn1_write_OctetString(data, tree->u.comparison.value.data,
316
0
              tree->u.comparison.value.length)) return false;
317
0
    if (!asn1_pop_tag(data)) return false;
318
0
    break;
319
320
0
  case LDB_OP_PRESENT:
321
    /* present test */
322
0
    if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(7))) return false;
323
0
    if (!asn1_write_LDAPString(data, tree->u.present.attr)) return false;
324
0
    if (!asn1_pop_tag(data)) return false;
325
0
    return !asn1_has_error(data);
326
327
0
  case LDB_OP_APPROX:
328
    /* approx test */
329
0
    if (!asn1_push_tag(data, ASN1_CONTEXT(8))) return false;
330
0
    if (!asn1_write_OctetString(data, tree->u.comparison.attr,
331
0
              strlen(tree->u.comparison.attr))) return false;
332
0
    if (!asn1_write_OctetString(data, tree->u.comparison.value.data,
333
0
              tree->u.comparison.value.length)) return false;
334
0
    if (!asn1_pop_tag(data)) return false;
335
0
    break;
336
337
0
  case LDB_OP_EXTENDED:
338
    /*
339
      MatchingRuleAssertion ::= SEQUENCE {
340
      matchingRule    [1] MatchingRuleID OPTIONAL,
341
      type            [2] AttributeDescription OPTIONAL,
342
      matchValue      [3] AssertionValue,
343
      dnAttributes    [4] BOOLEAN DEFAULT FALSE
344
      }
345
    */
346
0
    if (!asn1_push_tag(data, ASN1_CONTEXT(9))) return false;
347
0
    if (tree->u.extended.rule_id) {
348
0
      if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1))) return false;
349
0
      if (!asn1_write_LDAPString(data, tree->u.extended.rule_id)) return false;
350
0
      if (!asn1_pop_tag(data)) return false;
351
0
    }
352
0
    if (tree->u.extended.attr) {
353
0
      if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(2))) return false;
354
0
      if (!asn1_write_LDAPString(data, tree->u.extended.attr)) return false;
355
0
      if (!asn1_pop_tag(data)) return false;
356
0
    }
357
0
    if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(3))) return false;
358
0
    if (!asn1_write_DATA_BLOB_LDAPString(data, &tree->u.extended.value)) return false;
359
0
    if (!asn1_pop_tag(data)) return false;
360
0
    if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(4))) return false;
361
0
    if (!asn1_write_uint8(data, tree->u.extended.dnAttributes)) return false;
362
0
    if (!asn1_pop_tag(data)) return false;
363
0
    if (!asn1_pop_tag(data)) return false;
364
0
    break;
365
366
0
  default:
367
0
    return false;
368
0
  }
369
0
  return !asn1_has_error(data);
370
0
}
371
372
static bool ldap_encode_response(struct asn1_data *data, struct ldap_Result *result)
373
0
{
374
0
  if (!asn1_write_enumerated(data, result->resultcode)) return false;
375
0
  if (!asn1_write_OctetString(data, result->dn,
376
0
             (result->dn) ? strlen(result->dn) : 0)) return false;
377
0
  if (!asn1_write_OctetString(data, result->errormessage,
378
0
             (result->errormessage) ?
379
0
             strlen(result->errormessage) : 0)) return false;
380
0
  if (result->referral) {
381
0
    if (!asn1_push_tag(data, ASN1_CONTEXT(3))) return false;
382
0
    if (!asn1_write_OctetString(data, result->referral,
383
0
               strlen(result->referral))) return false;
384
0
    if (!asn1_pop_tag(data)) return false;
385
0
  }
386
0
  return true;
387
0
}
388
389
_PUBLIC_ bool ldap_encode(struct ldap_message *msg,
390
        const struct ldap_control_handler *control_handlers,
391
        DATA_BLOB *result, TALLOC_CTX *mem_ctx)
392
0
{
393
0
  struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
394
0
  int i, j;
395
396
0
  if (!data) return false;
397
398
0
  if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
399
0
  if (!asn1_write_Integer(data, msg->messageid)) goto err;
400
401
0
  switch (msg->type) {
402
0
  case LDAP_TAG_BindRequest: {
403
0
    struct ldap_BindRequest *r = &msg->r.BindRequest;
404
0
    if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
405
0
    if (!asn1_write_Integer(data, r->version)) goto err;
406
0
    if (!asn1_write_OctetString(data, r->dn,
407
0
               (r->dn != NULL) ? strlen(r->dn) : 0)) goto err;
408
409
0
    switch (r->mechanism) {
410
0
    case LDAP_AUTH_MECH_SIMPLE:
411
      /* context, primitive */
412
0
      if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0))) goto err;
413
0
      if (!asn1_write(data, r->creds.password,
414
0
           strlen(r->creds.password))) goto err;
415
0
      if (!asn1_pop_tag(data)) goto err;
416
0
      break;
417
0
    case LDAP_AUTH_MECH_SASL:
418
      /* context, constructed */
419
0
      if (!asn1_push_tag(data, ASN1_CONTEXT(3))) goto err;
420
0
      if (!asn1_write_OctetString(data, r->creds.SASL.mechanism,
421
0
                 strlen(r->creds.SASL.mechanism))) goto err;
422
0
      if (r->creds.SASL.secblob) {
423
0
        if (!asn1_write_OctetString(data, r->creds.SASL.secblob->data,
424
0
                   r->creds.SASL.secblob->length)) goto err;
425
0
      }
426
0
      if (!asn1_pop_tag(data)) goto err;
427
0
      break;
428
0
    default:
429
0
      goto err;
430
0
    }
431
432
0
    if (!asn1_pop_tag(data)) goto err;
433
0
    break;
434
0
  }
435
0
  case LDAP_TAG_BindResponse: {
436
0
    struct ldap_BindResponse *r = &msg->r.BindResponse;
437
0
    if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
438
0
    if (!ldap_encode_response(data, &r->response)) goto err;
439
0
    if (r->SASL.secblob) {
440
0
      if (!asn1_write_ContextSimple(data, 7, r->SASL.secblob)) goto err;
441
0
    }
442
0
    if (!asn1_pop_tag(data)) goto err;
443
0
    break;
444
0
  }
445
0
  case LDAP_TAG_UnbindRequest: {
446
/*    struct ldap_UnbindRequest *r = &msg->r.UnbindRequest; */
447
0
    if (!asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type))) goto err;
448
0
    if (!asn1_pop_tag(data)) goto err;
449
0
    break;
450
0
  }
451
0
  case LDAP_TAG_SearchRequest: {
452
0
    struct ldap_SearchRequest *r = &msg->r.SearchRequest;
453
0
    if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
454
0
    if (!asn1_write_OctetString(data, r->basedn, strlen(r->basedn))) goto err;
455
0
    if (!asn1_write_enumerated(data, r->scope)) goto err;
456
0
    if (!asn1_write_enumerated(data, r->deref)) goto err;
457
0
    if (!asn1_write_Integer(data, r->sizelimit)) goto err;
458
0
    if (!asn1_write_Integer(data, r->timelimit)) goto err;
459
0
    if (!asn1_write_BOOLEAN(data, r->attributesonly)) goto err;
460
461
0
    if (!ldap_push_filter(data, r->tree)) {
462
0
      goto err;
463
0
    }
464
465
0
    if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
466
0
    for (i=0; i<r->num_attributes; i++) {
467
0
      if (!asn1_write_OctetString(data, r->attributes[i],
468
0
                 strlen(r->attributes[i]))) goto err;
469
0
    }
470
0
    if (!asn1_pop_tag(data)) goto err;
471
0
    if (!asn1_pop_tag(data)) goto err;
472
0
    break;
473
0
  }
474
0
  case LDAP_TAG_SearchResultEntry: {
475
0
    struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry;
476
0
    if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
477
0
    if (!asn1_write_OctetString(data, r->dn, strlen(r->dn))) goto err;
478
0
    if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
479
0
    for (i=0; i<r->num_attributes; i++) {
480
0
      struct ldb_message_element *attr = &r->attributes[i];
481
0
      if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
482
0
      if (!asn1_write_OctetString(data, attr->name,
483
0
                 strlen(attr->name))) goto err;
484
0
      if (!asn1_push_tag(data, ASN1_SEQUENCE(1))) goto err;
485
0
      for (j=0; j<attr->num_values; j++) {
486
0
        if (!asn1_write_OctetString(data,
487
0
                   attr->values[j].data,
488
0
                   attr->values[j].length)) goto err;
489
0
      }
490
0
      if (!asn1_pop_tag(data)) goto err;
491
0
      if (!asn1_pop_tag(data)) goto err;
492
0
    }
493
0
    if (!asn1_pop_tag(data)) goto err;
494
0
    if (!asn1_pop_tag(data)) goto err;
495
0
    break;
496
0
  }
497
0
  case LDAP_TAG_SearchResultDone: {
498
0
    struct ldap_Result *r = &msg->r.SearchResultDone;
499
0
    if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
500
0
    if (!ldap_encode_response(data, r)) goto err;
501
0
    if (!asn1_pop_tag(data)) goto err;
502
0
    break;
503
0
  }
504
0
  case LDAP_TAG_ModifyRequest: {
505
0
    struct ldap_ModifyRequest *r = &msg->r.ModifyRequest;
506
0
    if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
507
0
    if (!asn1_write_OctetString(data, r->dn, strlen(r->dn))) goto err;
508
0
    if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
509
510
0
    for (i=0; i<r->num_mods; i++) {
511
0
      struct ldb_message_element *attrib = &r->mods[i].attrib;
512
0
      if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
513
0
      if (!asn1_write_enumerated(data, r->mods[i].type)) goto err;
514
0
      if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
515
0
      if (!asn1_write_OctetString(data, attrib->name,
516
0
                 strlen(attrib->name))) goto err;
517
0
      if (!asn1_push_tag(data, ASN1_SET)) goto err;
518
0
      for (j=0; j<attrib->num_values; j++) {
519
0
        if (!asn1_write_OctetString(data,
520
0
                   attrib->values[j].data,
521
0
                   attrib->values[j].length)) goto err;
522
  
523
0
      }
524
0
      if (!asn1_pop_tag(data)) goto err;
525
0
      if (!asn1_pop_tag(data)) goto err;
526
0
      if (!asn1_pop_tag(data)) goto err;
527
0
    }
528
    
529
0
    if (!asn1_pop_tag(data)) goto err;
530
0
    if (!asn1_pop_tag(data)) goto err;
531
0
    break;
532
0
  }
533
0
  case LDAP_TAG_ModifyResponse: {
534
0
    struct ldap_Result *r = &msg->r.ModifyResponse;
535
0
    if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
536
0
    if (!ldap_encode_response(data, r)) goto err;
537
0
    if (!asn1_pop_tag(data)) goto err;
538
0
    break;
539
0
  }
540
0
  case LDAP_TAG_AddRequest: {
541
0
    struct ldap_AddRequest *r = &msg->r.AddRequest;
542
0
    if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
543
0
    if (!asn1_write_OctetString(data, r->dn, strlen(r->dn))) goto err;
544
0
    if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
545
546
0
    for (i=0; i<r->num_attributes; i++) {
547
0
      struct ldb_message_element *attrib = &r->attributes[i];
548
0
      if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
549
0
      if (attrib->name == NULL) {
550
0
        goto err;
551
0
      }
552
0
      if (!asn1_write_OctetString(data, attrib->name,
553
0
                 strlen(attrib->name))) goto err;
554
0
      if (!asn1_push_tag(data, ASN1_SET)) goto err;
555
0
      for (j=0; j<r->attributes[i].num_values; j++) {
556
0
        if (!asn1_write_OctetString(data,
557
0
                   attrib->values[j].data,
558
0
                   attrib->values[j].length)) goto err;
559
0
      }
560
0
      if (!asn1_pop_tag(data)) goto err;
561
0
      if (!asn1_pop_tag(data)) goto err;
562
0
    }
563
0
    if (!asn1_pop_tag(data)) goto err;
564
0
    if (!asn1_pop_tag(data)) goto err;
565
0
    break;
566
0
  }
567
0
  case LDAP_TAG_AddResponse: {
568
0
    struct ldap_Result *r = &msg->r.AddResponse;
569
0
    if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
570
0
    if (!ldap_encode_response(data, r)) goto err;
571
0
    if (!asn1_pop_tag(data)) goto err;
572
0
    break;
573
0
  }
574
0
  case LDAP_TAG_DelRequest: {
575
0
    struct ldap_DelRequest *r = &msg->r.DelRequest;
576
0
    if (!asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type))) goto err;
577
0
    if (!asn1_write(data, r->dn, strlen(r->dn))) goto err;
578
0
    if (!asn1_pop_tag(data)) goto err;
579
0
    break;
580
0
  }
581
0
  case LDAP_TAG_DelResponse: {
582
0
    struct ldap_Result *r = &msg->r.DelResponse;
583
0
    if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
584
0
    if (!ldap_encode_response(data, r)) goto err;
585
0
    if (!asn1_pop_tag(data)) goto err;
586
0
    break;
587
0
  }
588
0
  case LDAP_TAG_ModifyDNRequest: {
589
0
    struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest;
590
0
    if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
591
0
    if (!asn1_write_OctetString(data, r->dn, strlen(r->dn))) goto err;
592
0
    if (!asn1_write_OctetString(data, r->newrdn, strlen(r->newrdn))) goto err;
593
0
    if (!asn1_write_BOOLEAN(data, r->deleteolddn)) goto err;
594
0
    if (r->newsuperior) {
595
0
      if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0))) goto err;
596
0
      if (!asn1_write(data, r->newsuperior,
597
0
           strlen(r->newsuperior))) goto err;
598
0
      if (!asn1_pop_tag(data)) goto err;
599
0
    }
600
0
    if (!asn1_pop_tag(data)) goto err;
601
0
    break;
602
0
  }
603
0
  case LDAP_TAG_ModifyDNResponse: {
604
0
    struct ldap_Result *r = &msg->r.ModifyDNResponse;
605
0
    if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
606
0
    if (!ldap_encode_response(data, r)) goto err;
607
0
    if (!asn1_pop_tag(data)) goto err;
608
0
    break;
609
0
  }
610
0
  case LDAP_TAG_CompareRequest: {
611
0
    struct ldap_CompareRequest *r = &msg->r.CompareRequest;
612
0
    if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
613
0
    if (!asn1_write_OctetString(data, r->dn, strlen(r->dn))) goto err;
614
0
    if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
615
0
    if (!asn1_write_OctetString(data, r->attribute,
616
0
               strlen(r->attribute))) goto err;
617
0
    if (!asn1_write_OctetString(data, r->value.data,
618
0
               r->value.length)) goto err;
619
0
    if (!asn1_pop_tag(data)) goto err;
620
0
    if (!asn1_pop_tag(data)) goto err;
621
0
    break;
622
0
  }
623
0
  case LDAP_TAG_CompareResponse: {
624
0
    struct ldap_Result *r = &msg->r.ModifyDNResponse;
625
0
    if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
626
0
    if (!ldap_encode_response(data, r)) goto err;
627
0
    if (!asn1_pop_tag(data)) goto err;
628
0
    break;
629
0
  }
630
0
  case LDAP_TAG_AbandonRequest: {
631
0
    struct ldap_AbandonRequest *r = &msg->r.AbandonRequest;
632
0
    if (!asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type))) goto err;
633
0
    if (!asn1_write_implicit_Integer(data, r->messageid)) goto err;
634
0
    if (!asn1_pop_tag(data)) goto err;
635
0
    break;
636
0
  }
637
0
  case LDAP_TAG_SearchResultReference: {
638
0
    struct ldap_SearchResRef *r = &msg->r.SearchResultReference;
639
0
    if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
640
0
    if (!asn1_write_OctetString(data, r->referral, strlen(r->referral))) goto err;
641
0
    if (!asn1_pop_tag(data)) goto err;
642
0
    break;
643
0
  }
644
0
  case LDAP_TAG_ExtendedRequest: {
645
0
    struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest;
646
0
    if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
647
0
    if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(0))) goto err;
648
0
    if (!asn1_write(data, r->oid, strlen(r->oid))) goto err;
649
0
    if (!asn1_pop_tag(data)) goto err;
650
0
    if (r->value) {
651
0
      if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1))) goto err;
652
0
      if (!asn1_write(data, r->value->data, r->value->length)) goto err;
653
0
      if (!asn1_pop_tag(data)) goto err;
654
0
    }
655
0
    if (!asn1_pop_tag(data)) goto err;
656
0
    break;
657
0
  }
658
0
  case LDAP_TAG_ExtendedResponse: {
659
0
    struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse;
660
0
    if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
661
0
    if (!ldap_encode_response(data, &r->response)) goto err;
662
0
    if (r->oid) {
663
0
      if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(10))) goto err;
664
0
      if (!asn1_write(data, r->oid, strlen(r->oid))) goto err;
665
0
      if (!asn1_pop_tag(data)) goto err;
666
0
    }
667
0
    if (r->value) {
668
0
      if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(11))) goto err;
669
0
      if (!asn1_write(data, r->value->data, r->value->length)) goto err;
670
0
      if (!asn1_pop_tag(data)) goto err;
671
0
    }
672
0
    if (!asn1_pop_tag(data)) goto err;
673
0
    break;
674
0
  }
675
0
  default:
676
0
    goto err;
677
0
  }
678
679
0
  if (msg->controls != NULL) {
680
0
    if (!asn1_push_tag(data, ASN1_CONTEXT(0))) goto err;
681
    
682
0
    for (i = 0; msg->controls[i] != NULL; i++) {
683
0
      if (!ldap_encode_control(mem_ctx, data,
684
0
             control_handlers,
685
0
             msg->controls[i])) {
686
0
        DEBUG(0,("Unable to encode control %s\n",
687
0
           msg->controls[i]->oid));
688
0
        goto err;
689
0
      }
690
0
    }
691
692
0
    if (!asn1_pop_tag(data)) goto err;
693
0
  }
694
695
0
  if (!asn1_pop_tag(data)) goto err;
696
697
0
  if (!asn1_extract_blob(data, mem_ctx, result)) {
698
0
    goto err;
699
0
  }
700
701
0
  asn1_free(data);
702
703
0
  return true;
704
705
0
  err:
706
707
0
  asn1_free(data);
708
0
  return false;
709
0
}
710
711
static const char *blob2string_talloc(TALLOC_CTX *mem_ctx,
712
              DATA_BLOB blob)
713
8.57k
{
714
8.57k
  char *result = talloc_array(mem_ctx, char, blob.length+1);
715
8.57k
  if (result == NULL) {
716
0
    return NULL;
717
0
  }
718
8.57k
  memcpy(result, blob.data, blob.length);
719
8.57k
  result[blob.length] = '\0';
720
8.57k
  return result;
721
8.57k
}
722
723
bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx,
724
          struct asn1_data *data,
725
          const char **result)
726
8.61k
{
727
8.61k
  DATA_BLOB string;
728
8.61k
  if (!asn1_read_OctetString(data, mem_ctx, &string))
729
150
    return false;
730
8.46k
  *result = blob2string_talloc(mem_ctx, string);
731
8.46k
  data_blob_free(&string);
732
8.46k
  return *result ? true : false;
733
8.61k
}
734
735
static bool ldap_decode_response(TALLOC_CTX *mem_ctx,
736
         struct asn1_data *data,
737
         struct ldap_Result *result)
738
174
{
739
174
  if (!asn1_read_enumerated(data, &result->resultcode)) return false;
740
106
  if (!asn1_read_OctetString_talloc(mem_ctx, data, &result->dn)) return false;
741
68
  if (!asn1_read_OctetString_talloc(mem_ctx, data, &result->errormessage)) return false;
742
42
  if (asn1_peek_tag(data, ASN1_CONTEXT(3))) {
743
5
    if (!asn1_start_tag(data, ASN1_CONTEXT(3))) return false;
744
4
    if (!asn1_read_OctetString_talloc(mem_ctx, data, &result->referral)) return false;
745
3
    if (!asn1_end_tag(data)) return false;
746
37
  } else {
747
37
    result->referral = NULL;
748
37
  }
749
39
  return true;
750
42
}
751
752
static struct ldb_val **ldap_decode_substring(TALLOC_CTX *mem_ctx, struct ldb_val **chunks, int chunk_num, char *value)
753
2.41k
{
754
755
2.41k
  chunks = talloc_realloc(mem_ctx, chunks, struct ldb_val *, chunk_num + 2);
756
2.41k
  if (chunks == NULL) {
757
0
    return NULL;
758
0
  }
759
760
2.41k
  chunks[chunk_num] = talloc(mem_ctx, struct ldb_val);
761
2.41k
  if (chunks[chunk_num] == NULL) {
762
0
    return NULL;
763
0
  }
764
765
2.41k
  chunks[chunk_num]->data = (uint8_t *)talloc_strdup(mem_ctx, value);
766
2.41k
  if (chunks[chunk_num]->data == NULL) {
767
0
    return NULL;
768
0
  }
769
2.41k
  chunks[chunk_num]->length = strlen(value);
770
771
2.41k
  chunks[chunk_num + 1] = NULL;
772
773
2.41k
  return chunks;
774
2.41k
}
775
776
777
/*
778
  parse the ASN.1 formatted search string into a ldb_parse_tree
779
*/
780
static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, 
781
                  struct asn1_data *data)
782
42.6k
{
783
42.6k
  uint8_t filter_tag;
784
42.6k
  struct ldb_parse_tree *ret;
785
786
42.6k
  if (!asn1_peek_uint8(data, &filter_tag)) {
787
20
    return NULL;
788
20
  }
789
790
42.6k
  filter_tag &= 0x1f; /* strip off the asn1 stuff */
791
792
42.6k
  ret = talloc(mem_ctx, struct ldb_parse_tree);
793
42.6k
  if (ret == NULL) return NULL;
794
795
42.6k
  switch(filter_tag) {
796
7.40k
  case 0:
797
8.89k
  case 1:
798
    /* AND or OR of one or more filters */
799
8.89k
    ret->operation = (filter_tag == 0)?LDB_OP_AND:LDB_OP_OR;
800
8.89k
    ret->u.list.num_elements = 0;
801
8.89k
    ret->u.list.elements = NULL;
802
803
8.89k
    if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) {
804
61
      goto failed;
805
61
    }
806
807
38.4k
    while (asn1_tag_remaining(data) > 0) {
808
36.8k
      struct ldb_parse_tree *subtree;
809
36.8k
      subtree = ldap_decode_filter_tree(ret, data);
810
36.8k
      if (subtree == NULL) {
811
7.31k
        goto failed;
812
7.31k
      }
813
29.5k
      ret->u.list.elements = 
814
29.5k
        talloc_realloc(ret, ret->u.list.elements, 
815
29.5k
                 struct ldb_parse_tree *, 
816
29.5k
                 ret->u.list.num_elements+1);
817
29.5k
      if (ret->u.list.elements == NULL) {
818
0
        goto failed;
819
0
      }
820
29.5k
      talloc_steal(ret->u.list.elements, subtree);
821
29.5k
      ret->u.list.elements[ret->u.list.num_elements] = subtree;
822
29.5k
      ret->u.list.num_elements++;
823
29.5k
    }
824
1.51k
    if (!asn1_end_tag(data)) {
825
102
      goto failed;
826
102
    }
827
1.41k
    break;
828
829
5.24k
  case 2:
830
    /* 'not' operation */
831
5.24k
    if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) {
832
32
      goto failed;
833
32
    }
834
835
5.21k
    ret->operation = LDB_OP_NOT;
836
5.21k
    ret->u.isnot.child = ldap_decode_filter_tree(ret, data);
837
5.21k
    if (ret->u.isnot.child == NULL) {
838
5.01k
      goto failed;
839
5.01k
    }
840
198
    if (!asn1_end_tag(data)) {
841
3
      goto failed;
842
3
    }
843
195
    break;
844
845
374
  case 3: {
846
    /* equalityMatch */
847
374
    const char *attrib;
848
374
    DATA_BLOB value;
849
850
374
    if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) goto failed;
851
370
    if (!asn1_read_OctetString_talloc(mem_ctx, data, &attrib)) goto failed;
852
368
    if (!asn1_read_OctetString(data, mem_ctx, &value)) goto failed;
853
364
    if (!asn1_end_tag(data)) goto failed;
854
363
    if (asn1_has_error(data) || (attrib == NULL) ||
855
363
        (value.data == NULL)) {
856
0
      goto failed;
857
0
    }
858
859
363
    ret->operation = LDB_OP_EQUALITY;
860
363
    ret->u.equality.attr = talloc_steal(ret, attrib);
861
363
    ret->u.equality.value.data = talloc_steal(ret, value.data);
862
363
    ret->u.equality.value.length = value.length;
863
363
    break;
864
363
  }
865
2.70k
  case 4: {
866
    /* substrings */
867
2.70k
    DATA_BLOB attr;
868
2.70k
    uint8_t subs_tag;
869
2.70k
    char *value;
870
2.70k
    int chunk_num = 0;
871
872
2.70k
    if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) {
873
10
      goto failed;
874
10
    }
875
2.69k
    if (!asn1_read_OctetString(data, mem_ctx, &attr)) {
876
3
      goto failed;
877
3
    }
878
879
2.69k
    ret->operation = LDB_OP_SUBSTRING;
880
2.69k
    ret->u.substring.attr = talloc_strndup(ret, (char *)attr.data, attr.length);
881
2.69k
    if (ret->u.substring.attr == NULL) {
882
0
      goto failed;
883
0
    }
884
2.69k
    ret->u.substring.chunks = NULL;
885
2.69k
    ret->u.substring.start_with_wildcard = 1;
886
2.69k
    ret->u.substring.end_with_wildcard = 1;
887
888
2.69k
    if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
889
8
      goto failed;
890
8
    }
891
892
5.09k
    while (asn1_tag_remaining(data) > 0) {
893
2.44k
      if (!asn1_peek_uint8(data, &subs_tag)) goto failed;
894
2.44k
      subs_tag &= 0x1f; /* strip off the asn1 stuff */
895
2.44k
      if (subs_tag > 2) goto failed;
896
897
2.42k
      if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(subs_tag))) goto failed;
898
2.41k
      if (!asn1_read_LDAPString(data, mem_ctx, &value)) goto failed;
899
2.41k
      if (!asn1_end_tag(data)) goto failed;
900
901
2.41k
      switch (subs_tag) {
902
775
      case 0:
903
775
        if (ret->u.substring.chunks != NULL) {
904
          /* initial value found in the middle */
905
1
          goto failed;
906
1
        }
907
908
774
        ret->u.substring.chunks = ldap_decode_substring(ret, NULL, 0, value);
909
774
        if (ret->u.substring.chunks == NULL) {
910
0
          goto failed;
911
0
        }
912
913
774
        ret->u.substring.start_with_wildcard = 0;
914
774
        chunk_num = 1;
915
774
        break;
916
917
812
      case 1:
918
812
        if (ret->u.substring.end_with_wildcard == 0) {
919
          /* "any" value found after a "final" value */
920
2
          goto failed;
921
2
        }
922
923
810
        ret->u.substring.chunks = ldap_decode_substring(ret,
924
810
                    ret->u.substring.chunks,
925
810
                    chunk_num,
926
810
                    value);
927
810
        if (ret->u.substring.chunks == NULL) {
928
0
          goto failed;
929
0
        }
930
931
810
        chunk_num++;
932
810
        break;
933
934
828
      case 2:
935
828
        ret->u.substring.chunks = ldap_decode_substring(ret,
936
828
                    ret->u.substring.chunks,
937
828
                    chunk_num,
938
828
                    value);
939
828
        if (ret->u.substring.chunks == NULL) {
940
0
          goto failed;
941
0
        }
942
943
828
        ret->u.substring.end_with_wildcard = 0;
944
828
        break;
945
946
0
      default:
947
0
        goto failed;
948
2.41k
      }
949
950
2.41k
    }
951
952
2.65k
    if (!asn1_end_tag(data)) { /* SEQUENCE */
953
10
      goto failed;
954
10
    }
955
956
2.64k
    if (!asn1_end_tag(data)) {
957
9
      goto failed;
958
9
    }
959
2.63k
    break;
960
2.64k
  }
961
2.63k
  case 5: {
962
    /* greaterOrEqual */
963
218
    const char *attrib;
964
218
    DATA_BLOB value;
965
966
218
    if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) goto failed;
967
214
    if (!asn1_read_OctetString_talloc(mem_ctx, data, &attrib)) goto failed;
968
204
    if (!asn1_read_OctetString(data, mem_ctx, &value)) goto failed;
969
200
    if (!asn1_end_tag(data)) goto failed;
970
199
    if (asn1_has_error(data) || (attrib == NULL) ||
971
199
        (value.data == NULL)) {
972
0
      goto failed;
973
0
    }
974
975
199
    ret->operation = LDB_OP_GREATER;
976
199
    ret->u.comparison.attr = talloc_steal(ret, attrib);
977
199
    ret->u.comparison.value.data = talloc_steal(ret, value.data);
978
199
    ret->u.comparison.value.length = value.length;
979
199
    break;
980
199
  }
981
225
  case 6: {
982
    /* lessOrEqual */
983
225
    const char *attrib;
984
225
    DATA_BLOB value;
985
986
225
    if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) goto failed;
987
223
    if (!asn1_read_OctetString_talloc(mem_ctx, data, &attrib)) goto failed;
988
217
    if (!asn1_read_OctetString(data, mem_ctx, &value)) goto failed;
989
216
    if (!asn1_end_tag(data)) goto failed;
990
215
    if (asn1_has_error(data) || (attrib == NULL) ||
991
215
        (value.data == NULL)) {
992
0
      goto failed;
993
0
    }
994
995
215
    ret->operation = LDB_OP_LESS;
996
215
    ret->u.comparison.attr = talloc_steal(ret, attrib);
997
215
    ret->u.comparison.value.data = talloc_steal(ret, value.data);
998
215
    ret->u.comparison.value.length = value.length;
999
215
    break;
1000
215
  }
1001
16.3k
  case 7: {
1002
    /* Normal presence, "attribute=*" */
1003
16.3k
    char *attr;
1004
1005
16.3k
    if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(filter_tag))) {
1006
2
      goto failed;
1007
2
    }
1008
16.3k
    if (!asn1_read_LDAPString(data, ret, &attr)) {
1009
0
      goto failed;
1010
0
    }
1011
1012
16.3k
    ret->operation = LDB_OP_PRESENT;
1013
16.3k
    ret->u.present.attr = talloc_steal(ret, attr);
1014
1015
16.3k
    if (!asn1_end_tag(data)) {
1016
0
      goto failed;
1017
0
    }
1018
16.3k
    break;
1019
16.3k
  }
1020
16.3k
  case 8: {
1021
    /* approx */
1022
339
    const char *attrib;
1023
339
    DATA_BLOB value;
1024
1025
339
    if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) goto failed;
1026
337
    if (!asn1_read_OctetString_talloc(mem_ctx, data, &attrib)) goto failed;
1027
335
    if (!asn1_read_OctetString(data, mem_ctx, &value)) goto failed;
1028
332
    if (!asn1_end_tag(data)) goto failed;
1029
330
    if (asn1_has_error(data) || (attrib == NULL) ||
1030
330
        (value.data == NULL)) {
1031
0
      goto failed;
1032
0
    }
1033
1034
330
    ret->operation = LDB_OP_APPROX;
1035
330
    ret->u.comparison.attr = talloc_steal(ret, attrib);
1036
330
    ret->u.comparison.value.data = talloc_steal(ret, value.data);
1037
330
    ret->u.comparison.value.length = value.length;
1038
330
    break;
1039
330
  }
1040
8.22k
  case 9: {
1041
8.22k
    char *oid = NULL, *attr = NULL, *value;
1042
8.22k
    uint8_t dnAttributes;
1043
    /* an extended search */
1044
8.22k
    if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) {
1045
4
      goto failed;
1046
4
    }
1047
1048
    /* FIXME: read carefully rfc2251.txt there are a number of 'MUST's
1049
       we need to check we properly implement --SSS */ 
1050
    /* either oid or type must be defined */
1051
8.21k
    if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { /* optional */
1052
7.76k
      if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(1))) goto failed;
1053
7.76k
      if (!asn1_read_LDAPString(data, ret, &oid)) goto failed;
1054
7.76k
      if (!asn1_end_tag(data)) goto failed;
1055
7.76k
    }
1056
8.21k
    if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(2))) { /* optional  */
1057
811
      if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(2))) goto failed;
1058
809
      if (!asn1_read_LDAPString(data, ret, &attr)) goto failed;
1059
809
      if (!asn1_end_tag(data)) goto failed;
1060
809
    }
1061
8.20k
    if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(3))) goto failed;
1062
8.17k
    if (!asn1_read_LDAPString(data, ret, &value)) goto failed;
1063
8.17k
    if (!asn1_end_tag(data)) goto failed;
1064
    /* dnAttributes is marked as BOOLEAN DEFAULT FALSE
1065
       it is not marked as OPTIONAL but openldap tools
1066
       do not set this unless it is to be set as TRUE
1067
       NOTE: openldap tools do not work with AD as it
1068
       seems that AD always requires the dnAttributes
1069
       boolean value to be set */
1070
8.17k
    if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(4))) {
1071
3.14k
      if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(4))) goto failed;
1072
3.14k
      if (!asn1_read_uint8(data, &dnAttributes)) goto failed;
1073
3.14k
      if (!asn1_end_tag(data)) goto failed;
1074
5.02k
    } else {
1075
5.02k
      dnAttributes = 0;
1076
5.02k
    }
1077
8.16k
    if ((oid == NULL && attr == NULL) || (value == NULL)) {
1078
12
      goto failed;
1079
12
    }
1080
1081
8.15k
    if (oid) {
1082
7.73k
      ret->operation               = LDB_OP_EXTENDED;
1083
1084
      /* From the RFC2251: If the type field is
1085
         absent and matchingRule is present, the matchValue is compared
1086
         against all attributes in an entry which support that matchingRule
1087
      */
1088
7.73k
      if (attr) {
1089
384
        ret->u.extended.attr = talloc_steal(ret, attr);
1090
7.35k
      } else {
1091
7.35k
        ret->u.extended.attr = talloc_strdup(ret, "*");
1092
7.35k
        if (ret->u.extended.attr == NULL) {
1093
0
          goto failed;
1094
0
        }
1095
7.35k
      }
1096
7.73k
      ret->u.extended.rule_id      = talloc_steal(ret, oid);
1097
7.73k
      ret->u.extended.value.data   = (uint8_t *)talloc_steal(ret, value);
1098
7.73k
      ret->u.extended.value.length = strlen(value);
1099
7.73k
      ret->u.extended.dnAttributes = dnAttributes;
1100
7.73k
    } else {
1101
417
      ret->operation               = LDB_OP_EQUALITY;
1102
417
      ret->u.equality.attr         = talloc_steal(ret, attr);
1103
417
      ret->u.equality.value.data   = (uint8_t *)talloc_steal(ret, value);
1104
417
      ret->u.equality.value.length = strlen(value);
1105
417
    }
1106
8.15k
    if (!asn1_end_tag(data)) {
1107
8
      goto failed;
1108
8
    }
1109
8.14k
    break;
1110
8.15k
  }
1111
1112
8.14k
  default:
1113
16
    goto failed;
1114
42.6k
  }
1115
  
1116
29.8k
  return ret;
1117
1118
12.7k
failed:
1119
12.7k
  talloc_free(ret);
1120
12.7k
  return NULL; 
1121
42.6k
}
1122
1123
/* Decode a single LDAP attribute, possibly containing multiple values */
1124
static bool ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data,
1125
             struct ldb_message_element *attrib)
1126
237
{
1127
237
  if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) return false;
1128
217
  if (!asn1_read_OctetString_talloc(mem_ctx, data, &attrib->name)) return false;
1129
205
  if (!asn1_start_tag(data, ASN1_SET)) return false;
1130
45.6k
  while (asn1_peek_tag(data, ASN1_OCTET_STRING)) {
1131
45.4k
    DATA_BLOB blob;
1132
45.4k
    if (!asn1_read_OctetString(data, mem_ctx, &blob)) return false;
1133
45.4k
    add_value_to_attrib(mem_ctx, &blob, attrib);
1134
45.4k
  }
1135
178
  if (!asn1_end_tag(data)) return false;
1136
150
  return asn1_end_tag(data);
1137
178
}
1138
1139
/* Decode a set of LDAP attributes, as found in the dereference control */
1140
bool ldap_decode_attribs_bare(TALLOC_CTX *mem_ctx, struct asn1_data *data,
1141
            struct ldb_message_element **attributes,
1142
            int *num_attributes)
1143
137
{
1144
237
  while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) {
1145
172
    struct ldb_message_element attrib;
1146
172
    ZERO_STRUCT(attrib);
1147
172
    if (!ldap_decode_attrib(mem_ctx, data, &attrib)) return false;
1148
100
    add_attrib_to_array_talloc(mem_ctx, &attrib,
1149
100
             attributes, num_attributes);
1150
100
  }
1151
65
  return true;
1152
137
}
1153
1154
/* Decode a set of LDAP attributes, as found in a search entry */
1155
static bool ldap_decode_attribs(TALLOC_CTX *mem_ctx, struct asn1_data *data,
1156
        struct ldb_message_element **attributes,
1157
        int *num_attributes)
1158
78
{
1159
78
  if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) return false;
1160
70
  if (!ldap_decode_attribs_bare(mem_ctx, data,
1161
70
         attributes, num_attributes)) return false;
1162
30
  return asn1_end_tag(data);
1163
70
}
1164
1165
/* This routine returns LDAP status codes */
1166
1167
_PUBLIC_ NTSTATUS ldap_decode(struct asn1_data *data,
1168
            const struct ldap_request_limits *limits,
1169
            const struct ldap_control_handler *control_handlers,
1170
            struct ldap_message *msg)
1171
2.46k
{
1172
2.46k
  uint8_t tag;
1173
1174
2.46k
  if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) goto prot_err;
1175
2.27k
  if (!asn1_read_Integer(data, &msg->messageid)) goto prot_err;
1176
1177
2.26k
  if (!asn1_peek_uint8(data, &tag)) goto prot_err;
1178
1179
2.21k
  switch(tag) {
1180
1181
42
  case ASN1_APPLICATION(LDAP_TAG_BindRequest): {
1182
42
    struct ldap_BindRequest *r = &msg->r.BindRequest;
1183
42
    msg->type = LDAP_TAG_BindRequest;
1184
42
    if (!asn1_start_tag(data, tag)) goto prot_err;
1185
41
    if (!asn1_read_Integer(data, &r->version)) goto prot_err;
1186
39
    if (!asn1_read_OctetString_talloc(msg, data, &r->dn)) goto prot_err;
1187
35
    if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(0))) {
1188
20
      int pwlen;
1189
20
      r->creds.password = "";
1190
20
      r->mechanism = LDAP_AUTH_MECH_SIMPLE;
1191
20
      if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0))) goto prot_err;
1192
19
      pwlen = asn1_tag_remaining(data);
1193
19
      if (pwlen == -1) {
1194
0
        goto prot_err;
1195
0
      }
1196
19
      if (pwlen != 0) {
1197
17
        char *pw = talloc_array(msg, char, pwlen+1);
1198
17
        if (!pw) {
1199
0
          return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR);
1200
0
        }
1201
17
        if (!asn1_read(data, pw, pwlen)) goto prot_err;
1202
17
        pw[pwlen] = '\0';
1203
17
        r->creds.password = pw;
1204
17
      }
1205
19
      if (!asn1_end_tag(data)) goto prot_err;
1206
19
    } else if (asn1_peek_tag(data, ASN1_CONTEXT(3))){
1207
14
      if (!asn1_start_tag(data, ASN1_CONTEXT(3))) goto prot_err;
1208
13
      r->mechanism = LDAP_AUTH_MECH_SASL;
1209
13
      if (!asn1_read_OctetString_talloc(msg, data, &r->creds.SASL.mechanism)) goto prot_err;
1210
12
      if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { /* optional */
1211
10
        DATA_BLOB tmp_blob = {};
1212
10
        if (!asn1_read_OctetString(data, msg, &tmp_blob)) goto prot_err;
1213
9
        r->creds.SASL.secblob = talloc(msg, DATA_BLOB);
1214
9
        if (!r->creds.SASL.secblob) {
1215
0
          data_blob_free(&tmp_blob);
1216
0
          return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR);
1217
0
        }
1218
9
        *r->creds.SASL.secblob = data_blob_talloc(r->creds.SASL.secblob,
1219
9
                    tmp_blob.data, tmp_blob.length);
1220
9
        if ((tmp_blob.length != 0) &&
1221
8
            (r->creds.SASL.secblob->data == NULL)) {
1222
0
          data_blob_free(&tmp_blob);
1223
0
          return NT_STATUS_LDAP(
1224
0
            LDAP_OPERATIONS_ERROR);
1225
0
        }
1226
9
        data_blob_free(&tmp_blob);
1227
9
      } else {
1228
2
        r->creds.SASL.secblob = NULL;
1229
2
      }
1230
11
      if (!asn1_end_tag(data)) goto prot_err;
1231
11
    } else {
1232
      /* Neither Simple nor SASL bind */
1233
1
      goto prot_err;
1234
1
    }
1235
22
    if (!asn1_end_tag(data)) goto prot_err;
1236
2
    break;
1237
22
  }
1238
1239
34
  case ASN1_APPLICATION(LDAP_TAG_BindResponse): {
1240
34
    struct ldap_BindResponse *r = &msg->r.BindResponse;
1241
34
    msg->type = LDAP_TAG_BindResponse;
1242
34
    if (!asn1_start_tag(data, tag)) goto prot_err;
1243
33
    if (!ldap_decode_response(msg, data, &r->response)) goto prot_err;
1244
7
    if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(7))) {
1245
5
      DATA_BLOB tmp_blob = {};
1246
5
      if (!asn1_read_ContextSimple(data, msg, 7, &tmp_blob)) goto prot_err;
1247
4
      r->SASL.secblob = talloc(msg, DATA_BLOB);
1248
4
      if (!r->SASL.secblob) {
1249
0
        data_blob_free(&tmp_blob);
1250
0
        return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR);
1251
0
      }
1252
4
      *r->SASL.secblob = data_blob_talloc(r->SASL.secblob,
1253
4
                  tmp_blob.data, tmp_blob.length);
1254
4
      if ((tmp_blob.length != 0) &&
1255
2
          (r->SASL.secblob->data == NULL)) {
1256
0
        data_blob_free(&tmp_blob);
1257
0
        return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR);
1258
0
      }
1259
4
      data_blob_free(&tmp_blob);
1260
4
    } else {
1261
2
      r->SASL.secblob = NULL;
1262
2
    }
1263
6
    if (!asn1_end_tag(data)) goto prot_err;
1264
1
    break;
1265
6
  }
1266
1267
109
  case ASN1_APPLICATION_SIMPLE(LDAP_TAG_UnbindRequest): {
1268
109
    msg->type = LDAP_TAG_UnbindRequest;
1269
109
    if (!asn1_start_tag(data, tag)) goto prot_err;
1270
107
    if (!asn1_end_tag(data)) goto prot_err;
1271
89
    break;
1272
107
  }
1273
1274
631
  case ASN1_APPLICATION(LDAP_TAG_SearchRequest): {
1275
631
    struct ldap_SearchRequest *r = &msg->r.SearchRequest;
1276
631
    int sizelimit, timelimit;
1277
631
    const char **attrs = NULL;
1278
631
    size_t request_size = asn1_get_length(data);
1279
631
    msg->type = LDAP_TAG_SearchRequest;
1280
631
    if (request_size > limits->max_search_size) {
1281
19
      goto prot_err;
1282
19
    }
1283
612
    if (!asn1_start_tag(data, tag)) goto prot_err;
1284
608
    if (!asn1_read_OctetString_talloc(msg, data, &r->basedn)) goto prot_err;
1285
606
    if (!asn1_read_enumerated(data, (int *)(void *)&(r->scope))) goto prot_err;
1286
569
    if (!asn1_read_enumerated(data, (int *)(void *)&(r->deref))) goto prot_err;
1287
561
    if (!asn1_read_Integer(data, &sizelimit)) goto prot_err;
1288
556
    r->sizelimit = sizelimit;
1289
556
    if (!asn1_read_Integer(data, &timelimit)) goto prot_err;
1290
551
    r->timelimit = timelimit;
1291
551
    if (!asn1_read_BOOLEAN(data, &r->attributesonly)) goto prot_err;
1292
1293
531
    r->tree = ldap_decode_filter_tree(msg, data);
1294
531
    if (r->tree == NULL) {
1295
434
      goto prot_err;
1296
434
    }
1297
1298
97
    if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) goto prot_err;
1299
1300
30
    r->num_attributes = 0;
1301
30
    r->attributes = NULL;
1302
1303
5.71k
    while (asn1_tag_remaining(data) > 0) {
1304
1305
5.69k
      const char *attr;
1306
5.69k
      if (!asn1_read_OctetString_talloc(msg, data,
1307
5.69k
                &attr))
1308
12
        goto prot_err;
1309
5.68k
      if (!add_string_to_array(msg, attr,
1310
5.68k
             &attrs,
1311
5.68k
             &r->num_attributes))
1312
0
        goto prot_err;
1313
5.68k
    }
1314
18
    r->attributes = attrs;
1315
1316
18
    if (!asn1_end_tag(data)) goto prot_err;
1317
12
    if (!asn1_end_tag(data)) goto prot_err;
1318
5
    break;
1319
12
  }
1320
1321
45
  case ASN1_APPLICATION(LDAP_TAG_SearchResultEntry): {
1322
45
    struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry;
1323
45
    msg->type = LDAP_TAG_SearchResultEntry;
1324
45
    r->attributes = NULL;
1325
45
    r->num_attributes = 0;
1326
45
    if (!asn1_start_tag(data, tag)) goto prot_err;
1327
43
    if (!asn1_read_OctetString_talloc(msg, data, &r->dn)) goto prot_err;
1328
42
    if (!ldap_decode_attribs(msg, data, &r->attributes,
1329
42
            &r->num_attributes)) goto prot_err;
1330
8
    if (!asn1_end_tag(data)) goto prot_err;
1331
1
    break;
1332
8
  }
1333
1334
51
  case ASN1_APPLICATION(LDAP_TAG_SearchResultDone): {
1335
51
    struct ldap_Result *r = &msg->r.SearchResultDone;
1336
51
    msg->type = LDAP_TAG_SearchResultDone;
1337
51
    if (!asn1_start_tag(data, tag)) goto prot_err;
1338
47
    if (!ldap_decode_response(msg, data, r)) goto prot_err;
1339
8
    if (!asn1_end_tag(data)) goto prot_err;
1340
1
    break;
1341
8
  }
1342
1343
13
  case ASN1_APPLICATION(LDAP_TAG_SearchResultReference): {
1344
13
    struct ldap_SearchResRef *r = &msg->r.SearchResultReference;
1345
13
    msg->type = LDAP_TAG_SearchResultReference;
1346
13
    if (!asn1_start_tag(data, tag)) goto prot_err;
1347
12
    if (!asn1_read_OctetString_talloc(msg, data, &r->referral)) goto prot_err;
1348
11
    if (!asn1_end_tag(data)) goto prot_err;
1349
9
    break;
1350
11
  }
1351
1352
39
  case ASN1_APPLICATION(LDAP_TAG_ModifyRequest): {
1353
39
    struct ldap_ModifyRequest *r = &msg->r.ModifyRequest;
1354
39
    msg->type = LDAP_TAG_ModifyRequest;
1355
39
    if (!asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_ModifyRequest))) goto prot_err;
1356
38
    if (!asn1_read_OctetString_talloc(msg, data, &r->dn)) goto prot_err;
1357
37
    if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) goto prot_err;
1358
1359
36
    r->num_mods = 0;
1360
36
    r->mods = NULL;
1361
1362
80
    while (asn1_tag_remaining(data) > 0) {
1363
72
      struct ldap_mod mod;
1364
72
      int v;
1365
72
      ZERO_STRUCT(mod);
1366
72
      if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) goto prot_err;
1367
68
      if (!asn1_read_enumerated(data, &v)) goto prot_err;
1368
65
      mod.type = v;
1369
65
      if (!ldap_decode_attrib(msg, data, &mod.attrib)) goto prot_err;
1370
45
      if (!asn1_end_tag(data)) goto prot_err;
1371
44
      if (!add_mod_to_array_talloc(msg, &mod,
1372
44
                 &r->mods, &r->num_mods)) {
1373
0
        return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR);
1374
0
      }
1375
44
    }
1376
1377
8
    if (!asn1_end_tag(data)) goto prot_err;
1378
3
    if (!asn1_end_tag(data)) goto prot_err;
1379
1
    break;
1380
3
  }
1381
1382
17
  case ASN1_APPLICATION(LDAP_TAG_ModifyResponse): {
1383
17
    struct ldap_Result *r = &msg->r.ModifyResponse;
1384
17
    msg->type = LDAP_TAG_ModifyResponse;
1385
17
    if (!asn1_start_tag(data, tag)) goto prot_err;
1386
16
    if (!ldap_decode_response(msg, data, r)) goto prot_err;
1387
2
    if (!asn1_end_tag(data)) goto prot_err;
1388
1
    break;
1389
2
  }
1390
1391
38
  case ASN1_APPLICATION(LDAP_TAG_AddRequest): {
1392
38
    struct ldap_AddRequest *r = &msg->r.AddRequest;
1393
38
    msg->type = LDAP_TAG_AddRequest;
1394
38
    if (!asn1_start_tag(data, tag)) goto prot_err;
1395
37
    if (!asn1_read_OctetString_talloc(msg, data, &r->dn)) goto prot_err;
1396
1397
36
    r->attributes = NULL;
1398
36
    r->num_attributes = 0;
1399
36
    if (!ldap_decode_attribs(msg, data, &r->attributes,
1400
36
            &r->num_attributes)) goto prot_err;
1401
1402
5
    if (!asn1_end_tag(data)) goto prot_err;
1403
1
    break;
1404
5
  }
1405
1406
32
  case ASN1_APPLICATION(LDAP_TAG_AddResponse): {
1407
32
    struct ldap_Result *r = &msg->r.AddResponse;
1408
32
    msg->type = LDAP_TAG_AddResponse;
1409
32
    if (!asn1_start_tag(data, tag)) goto prot_err;
1410
31
    if (!ldap_decode_response(msg, data, r)) goto prot_err;
1411
4
    if (!asn1_end_tag(data)) goto prot_err;
1412
1
    break;
1413
4
  }
1414
1415
501
  case ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest): {
1416
501
    struct ldap_DelRequest *r = &msg->r.DelRequest;
1417
501
    int len;
1418
501
    char *dn;
1419
501
    msg->type = LDAP_TAG_DelRequest;
1420
501
    if (!asn1_start_tag(data,
1421
501
             ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest))) goto prot_err;
1422
499
    len = asn1_tag_remaining(data);
1423
499
    if (len == -1) {
1424
0
      goto prot_err;
1425
0
    }
1426
499
    dn = talloc_array(msg, char, len+1);
1427
499
    if (dn == NULL)
1428
0
      break;
1429
499
    if (!asn1_read(data, dn, len)) goto prot_err;
1430
499
    dn[len] = '\0';
1431
499
    r->dn = dn;
1432
499
    if (!asn1_end_tag(data)) goto prot_err;
1433
499
    break;
1434
499
  }
1435
1436
499
  case ASN1_APPLICATION(LDAP_TAG_DelResponse): {
1437
10
    struct ldap_Result *r = &msg->r.DelResponse;
1438
10
    msg->type = LDAP_TAG_DelResponse;
1439
10
    if (!asn1_start_tag(data, tag)) goto prot_err;
1440
9
    if (!ldap_decode_response(msg, data, r)) goto prot_err;
1441
3
    if (!asn1_end_tag(data)) goto prot_err;
1442
2
    break;
1443
3
  }
1444
1445
133
  case ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest): {
1446
133
    struct ldap_ModifyDNRequest *r = &msg->r.ModifyDNRequest;
1447
133
    msg->type = LDAP_TAG_ModifyDNRequest;
1448
133
    if (!asn1_start_tag(data,
1449
133
             ASN1_APPLICATION(LDAP_TAG_ModifyDNRequest))) goto prot_err;
1450
132
    if (!asn1_read_OctetString_talloc(msg, data, &r->dn)) goto prot_err;
1451
131
    if (!asn1_read_OctetString_talloc(msg, data, &r->newrdn)) goto prot_err;
1452
126
    if (!asn1_read_BOOLEAN(data, &r->deleteolddn)) goto prot_err;
1453
69
    r->newsuperior = NULL;
1454
69
    if (asn1_tag_remaining(data) > 0) {
1455
36
      int len;
1456
36
      char *newsup;
1457
36
      if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(0))) goto prot_err;
1458
31
      len = asn1_tag_remaining(data);
1459
31
      if (len == -1) {
1460
0
        goto prot_err;
1461
0
      }
1462
31
      newsup = talloc_array(msg, char, len+1);
1463
31
      if (newsup == NULL) {
1464
0
        return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR);
1465
0
      }
1466
31
      if (!asn1_read(data, newsup, len)) goto prot_err;
1467
31
      newsup[len] = '\0';
1468
31
      r->newsuperior = newsup;
1469
31
      if (!asn1_end_tag(data)) goto prot_err;
1470
31
    }
1471
64
    if (!asn1_end_tag(data)) goto prot_err;
1472
9
    break;
1473
64
  }
1474
1475
9
  case ASN1_APPLICATION(LDAP_TAG_ModifyDNResponse): {
1476
6
    struct ldap_Result *r = &msg->r.ModifyDNResponse;
1477
6
    msg->type = LDAP_TAG_ModifyDNResponse;
1478
6
    if (!asn1_start_tag(data, tag)) goto prot_err;
1479
4
    if (!ldap_decode_response(msg, data, r)) goto prot_err;
1480
2
    if (!asn1_end_tag(data)) goto prot_err;
1481
1
    break;
1482
2
  }
1483
1484
18
  case ASN1_APPLICATION(LDAP_TAG_CompareRequest): {
1485
18
    struct ldap_CompareRequest *r = &msg->r.CompareRequest;
1486
18
    msg->type = LDAP_TAG_CompareRequest;
1487
18
    if (!asn1_start_tag(data,
1488
18
             ASN1_APPLICATION(LDAP_TAG_CompareRequest))) goto prot_err;
1489
17
    if (!asn1_read_OctetString_talloc(msg, data, &r->dn)) goto prot_err;
1490
16
    if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) goto prot_err;
1491
7
    if (!asn1_read_OctetString_talloc(msg, data, &r->attribute)) goto prot_err;
1492
6
    if (!asn1_read_OctetString(data, msg, &r->value)) goto prot_err;
1493
5
    if (r->value.data) {
1494
5
      talloc_steal(msg, r->value.data);
1495
5
    }
1496
5
    if (!asn1_end_tag(data)) goto prot_err;
1497
3
    if (!asn1_end_tag(data)) goto prot_err;
1498
2
    break;
1499
3
  }
1500
1501
15
  case ASN1_APPLICATION(LDAP_TAG_CompareResponse): {
1502
15
    struct ldap_Result *r = &msg->r.CompareResponse;
1503
15
    msg->type = LDAP_TAG_CompareResponse;
1504
15
    if (!asn1_start_tag(data, tag)) goto prot_err;
1505
14
    if (!ldap_decode_response(msg, data, r)) goto prot_err;
1506
2
    if (!asn1_end_tag(data)) goto prot_err;
1507
1
    break;
1508
2
  }
1509
1510
318
  case ASN1_APPLICATION_SIMPLE(LDAP_TAG_AbandonRequest): {
1511
318
    struct ldap_AbandonRequest *r = &msg->r.AbandonRequest;
1512
318
    msg->type = LDAP_TAG_AbandonRequest;
1513
318
    if (!asn1_start_tag(data, tag)) goto prot_err;
1514
314
    if (!asn1_read_implicit_Integer(data, &r->messageid)) goto prot_err;
1515
314
    if (!asn1_end_tag(data)) goto prot_err;
1516
314
    break;
1517
314
  }
1518
1519
314
  case ASN1_APPLICATION(LDAP_TAG_ExtendedRequest): {
1520
113
    struct ldap_ExtendedRequest *r = &msg->r.ExtendedRequest;
1521
113
    DATA_BLOB tmp_blob = {};
1522
1523
113
    msg->type = LDAP_TAG_ExtendedRequest;
1524
113
    if (!asn1_start_tag(data,tag)) goto prot_err;
1525
112
    if (!asn1_read_ContextSimple(data, msg, 0, &tmp_blob)) {
1526
1
      goto prot_err;
1527
1
    }
1528
111
    r->oid = blob2string_talloc(msg, tmp_blob);
1529
111
    data_blob_free(&tmp_blob);
1530
111
    if (!r->oid) {
1531
0
      return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR);
1532
0
    }
1533
1534
111
    if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) {
1535
53
      if (!asn1_read_ContextSimple(data, msg, 1, &tmp_blob)) goto prot_err;
1536
42
      r->value = talloc(msg, DATA_BLOB);
1537
42
      if (!r->value) {
1538
0
        return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR);
1539
0
      }
1540
42
      *r->value = data_blob_talloc(r->value, tmp_blob.data, tmp_blob.length);
1541
42
      data_blob_free(&tmp_blob);
1542
58
    } else {
1543
58
      r->value = NULL;
1544
58
    }
1545
1546
100
    if (!asn1_end_tag(data)) goto prot_err;
1547
7
    break;
1548
100
  }
1549
1550
21
  case ASN1_APPLICATION(LDAP_TAG_ExtendedResponse): {
1551
21
    struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse;
1552
21
    DATA_BLOB tmp_blob = {};
1553
1554
21
    msg->type = LDAP_TAG_ExtendedResponse;
1555
21
    if (!asn1_start_tag(data, tag)) goto prot_err;
1556
20
    if (!ldap_decode_response(msg, data, &r->response)) goto prot_err;
1557
1558
11
    if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(10))) {
1559
6
      if (!asn1_read_ContextSimple(data, msg, 10, &tmp_blob))
1560
2
        goto prot_err;
1561
4
      r->oid = blob2string_talloc(msg, tmp_blob);
1562
4
      data_blob_free(&tmp_blob);
1563
4
      if (!r->oid) {
1564
0
        return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR);
1565
0
      }
1566
5
    } else {
1567
5
      r->oid = NULL;
1568
5
    }
1569
1570
9
    if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(11))) {
1571
3
      if (!asn1_read_ContextSimple(data, msg, 11, &tmp_blob))
1572
1
        goto prot_err;
1573
2
      r->value = talloc(msg, DATA_BLOB);
1574
2
      if (!r->value) {
1575
0
        return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR);
1576
0
      }
1577
2
      *r->value = data_blob_talloc(r->value, tmp_blob.data, tmp_blob.length);
1578
2
      data_blob_free(&tmp_blob);
1579
6
    } else {
1580
6
      r->value = NULL;
1581
6
    }
1582
1583
8
    if (!asn1_end_tag(data)) goto prot_err;
1584
4
    break;
1585
8
  }
1586
27
  default:
1587
27
    goto prot_err;
1588
2.21k
  }
1589
1590
951
  msg->controls = NULL;
1591
951
  msg->controls_decoded = NULL;
1592
1593
951
  if (asn1_peek_tag(data, ASN1_CONTEXT(0))) {
1594
739
    int i = 0;
1595
739
    struct ldb_control **ctrl = NULL;
1596
739
    bool *decoded = NULL;
1597
1598
739
    if (!asn1_start_tag(data, ASN1_CONTEXT(0))) goto prot_err;
1599
1600
2.43k
    while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) {
1601
1.76k
      DATA_BLOB value;
1602
      /* asn1_start_tag(data, ASN1_SEQUENCE(0)); */
1603
1604
1.76k
      ctrl = talloc_realloc(msg, ctrl, struct ldb_control *, i+2);
1605
1.76k
      if (!ctrl) {
1606
0
        return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR);
1607
0
      }
1608
1609
1.76k
      decoded = talloc_realloc(msg, decoded, bool, i+1);
1610
1.76k
      if (!decoded) {
1611
0
        return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR);
1612
0
      }
1613
1614
1.76k
      ctrl[i] = talloc(ctrl, struct ldb_control);
1615
1.76k
      if (!ctrl[i]) {
1616
0
        return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR);
1617
0
      }
1618
1619
1.76k
      if (!ldap_decode_control_wrapper(ctrl[i], data, ctrl[i], &value)) {
1620
67
        goto prot_err;
1621
67
      }
1622
1623
1.69k
      if (!ldap_decode_control_value(ctrl[i], value,
1624
1.69k
                   control_handlers,
1625
1.69k
                   ctrl[i])) {
1626
1.49k
        if (ctrl[i]->critical) {
1627
92
          ctrl[i]->data = NULL;
1628
92
          decoded[i] = false;
1629
92
          i++;
1630
1.39k
        } else {
1631
1.39k
          talloc_free(ctrl[i]);
1632
1.39k
          ctrl[i] = NULL;
1633
1.39k
        }
1634
1.49k
      } else {
1635
207
        decoded[i] = true;
1636
207
        i++;
1637
207
      }
1638
1.69k
    }
1639
1640
669
    if (ctrl != NULL) {
1641
652
      ctrl[i] = NULL;
1642
652
    }
1643
1644
669
    msg->controls = ctrl;
1645
669
    msg->controls_decoded = decoded;
1646
1647
669
    if (!asn1_end_tag(data)) goto prot_err;
1648
669
  }
1649
1650
271
  if (!asn1_end_tag(data)) goto prot_err;
1651
9
  if (asn1_has_error(data) || asn1_has_nesting(data)) {
1652
0
    return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR);
1653
0
  }
1654
9
  return NT_STATUS_OK;
1655
1656
2.45k
  prot_err:
1657
1658
2.45k
  return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR);
1659
9
}
1660
1661
1662
/*
1663
  return NT_STATUS_OK if a blob has enough bytes in it to be a full
1664
  ldap packet. Set packet_size if true.
1665
*/
1666
NTSTATUS ldap_full_packet(struct tstream_context *stream,
1667
        void *private_data,
1668
        DATA_BLOB blob,
1669
        size_t *packet_size)
1670
0
{
1671
0
  int ret;
1672
1673
0
  if (blob.length < 6) {
1674
    /*
1675
     * We need at least 6 bytes to workout the length
1676
     * of the pdu.
1677
     */
1678
0
    return STATUS_MORE_ENTRIES;
1679
0
  }
1680
1681
0
  ret = asn1_peek_full_tag(blob, ASN1_SEQUENCE(0), packet_size);
1682
0
  if (ret != 0) {
1683
0
    return map_nt_error_from_unix_common(ret);
1684
0
  }
1685
0
  return NT_STATUS_OK;
1686
0
}