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