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