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 472775 : _PUBLIC_ struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx)
30 : {
31 472775 : return talloc_zero(mem_ctx, struct ldap_message);
32 : }
33 :
34 :
35 3008174 : static bool add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value,
36 : struct ldb_message_element *attrib)
37 : {
38 3008174 : attrib->values = talloc_realloc(mem_ctx,
39 : attrib->values,
40 : DATA_BLOB,
41 : attrib->num_values+1);
42 3008174 : if (attrib->values == NULL)
43 0 : return false;
44 :
45 3008174 : attrib->values[attrib->num_values].data = talloc_steal(attrib->values,
46 : value->data);
47 3008174 : attrib->values[attrib->num_values].length = value->length;
48 3008174 : attrib->num_values += 1;
49 3008174 : return true;
50 : }
51 :
52 2494142 : 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 2494142 : *attribs = talloc_realloc(mem_ctx,
58 : *attribs,
59 : struct ldb_message_element,
60 : *num_attribs+1);
61 :
62 2494142 : if (*attribs == NULL)
63 0 : return false;
64 :
65 2494142 : (*attribs)[*num_attribs] = *attrib;
66 2494142 : talloc_steal(*attribs, attrib->values);
67 2494142 : talloc_steal(*attribs, attrib->name);
68 2494142 : *num_attribs += 1;
69 2494142 : return true;
70 : }
71 :
72 83254 : 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 83254 : *mods = talloc_realloc(mem_ctx, *mods, struct ldap_mod, (*num_mods)+1);
78 :
79 83254 : if (*mods == NULL)
80 0 : return false;
81 :
82 83254 : (*mods)[*num_mods] = *mod;
83 83254 : *num_mods += 1;
84 83254 : return true;
85 : }
86 :
87 344819 : 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 344819 : if (!handlers) {
94 0 : return true;
95 : }
96 :
97 2842508 : for (i = 0; handlers[i].oid != NULL; i++) {
98 2842508 : if (strcmp(handlers[i].oid, ctrl->oid) == 0) {
99 344819 : if (!handlers[i].decode || !handlers[i].decode(mem_ctx, value, &ctrl->data)) {
100 0 : return false;
101 : }
102 344819 : break;
103 : }
104 : }
105 344819 : if (handlers[i].oid == NULL) {
106 0 : return false;
107 : }
108 :
109 344819 : return true;
110 : }
111 :
112 344819 : 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 344819 : if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
118 0 : return false;
119 : }
120 :
121 344819 : if (!asn1_read_OctetString(data, mem_ctx, &oid)) {
122 0 : return false;
123 : }
124 344819 : ctrl->oid = talloc_strndup(mem_ctx, (char *)oid.data, oid.length);
125 344819 : if (!ctrl->oid) {
126 0 : return false;
127 : }
128 :
129 344819 : if (asn1_peek_tag(data, ASN1_BOOLEAN)) {
130 : bool critical;
131 227791 : if (!asn1_read_BOOLEAN(data, &critical)) {
132 0 : return false;
133 : }
134 227791 : ctrl->critical = critical;
135 : } else {
136 117028 : ctrl->critical = false;
137 : }
138 :
139 344819 : ctrl->data = NULL;
140 :
141 344819 : if (!asn1_peek_tag(data, ASN1_OCTET_STRING)) {
142 29178 : *value = data_blob(NULL, 0);
143 29178 : goto end_tag;
144 : }
145 :
146 315641 : if (!asn1_read_OctetString(data, mem_ctx, value)) {
147 0 : return false;
148 : }
149 :
150 633570 : end_tag:
151 344819 : if (!asn1_end_tag(data)) {
152 0 : return false;
153 : }
154 :
155 344819 : return true;
156 : }
157 :
158 344696 : 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 344696 : if (!handlers) {
166 0 : return false;
167 : }
168 :
169 2842477 : for (i = 0; handlers[i].oid != NULL; i++) {
170 2842477 : 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 2842477 : if (strcmp(handlers[i].oid, ctrl->oid) == 0) {
177 344696 : 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 344660 : if (!handlers[i].encode(mem_ctx, ctrl->data, &value)) {
186 0 : return false;
187 : }
188 344660 : break;
189 : }
190 : }
191 344660 : if (handlers[i].oid == NULL) {
192 0 : return false;
193 : }
194 :
195 344660 : if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
196 0 : return false;
197 : }
198 :
199 344660 : if (!asn1_write_OctetString(data, ctrl->oid, strlen(ctrl->oid))) {
200 0 : return false;
201 : }
202 :
203 344660 : if (ctrl->critical) {
204 227637 : if (!asn1_write_BOOLEAN(data, ctrl->critical)) {
205 0 : return false;
206 : }
207 : }
208 :
209 344660 : if (!ctrl->data) {
210 29124 : goto pop_tag;
211 : }
212 :
213 315536 : if (!asn1_write_OctetString(data, value.data, value.length)) {
214 0 : return false;
215 : }
216 :
217 315536 : pop_tag:
218 344660 : if (!asn1_pop_tag(data)) {
219 0 : return false;
220 : }
221 :
222 344660 : return true;
223 : }
224 :
225 800696 : static bool ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree)
226 : {
227 : int i;
228 :
229 800696 : switch (tree->operation) {
230 230300 : case LDB_OP_AND:
231 : case LDB_OP_OR:
232 230300 : if (!asn1_push_tag(data, ASN1_CONTEXT(tree->operation==LDB_OP_AND?0:1))) return false;
233 729207 : for (i=0; i<tree->u.list.num_elements; i++) {
234 498907 : if (!ldap_push_filter(data, tree->u.list.elements[i])) {
235 0 : return false;
236 : }
237 : }
238 230300 : if (!asn1_pop_tag(data)) return false;
239 230300 : break;
240 :
241 13062 : case LDB_OP_NOT:
242 13062 : if (!asn1_push_tag(data, ASN1_CONTEXT(2))) return false;
243 13062 : if (!ldap_push_filter(data, tree->u.isnot.child)) {
244 0 : return false;
245 : }
246 13062 : if (!asn1_pop_tag(data)) return false;
247 13062 : break;
248 :
249 112046 : case LDB_OP_EQUALITY:
250 : /* equality test */
251 112046 : if (!asn1_push_tag(data, ASN1_CONTEXT(3))) return false;
252 112046 : if (!asn1_write_OctetString(data, tree->u.equality.attr,
253 0 : strlen(tree->u.equality.attr))) return false;
254 112046 : if (!asn1_write_OctetString(data, tree->u.equality.value.data,
255 0 : tree->u.equality.value.length)) return false;
256 112046 : if (!asn1_pop_tag(data)) return false;
257 112046 : 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 38171 : while (tree->u.substring.chunks[i]) {
282 : int ctx;
283 :
284 19276 : 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 414726 : case LDB_OP_PRESENT:
321 : /* present test */
322 414726 : if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(7))) return false;
323 414726 : if (!asn1_write_LDAPString(data, tree->u.present.attr)) return false;
324 414726 : if (!asn1_pop_tag(data)) return false;
325 414726 : 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 15384 : 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 15384 : if (!asn1_push_tag(data, ASN1_CONTEXT(9))) return false;
347 15384 : if (tree->u.extended.rule_id) {
348 15384 : if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1))) return false;
349 15384 : if (!asn1_write_LDAPString(data, tree->u.extended.rule_id)) return false;
350 15384 : if (!asn1_pop_tag(data)) return false;
351 : }
352 15384 : if (tree->u.extended.attr) {
353 15384 : if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(2))) return false;
354 15384 : if (!asn1_write_LDAPString(data, tree->u.extended.attr)) return false;
355 15384 : if (!asn1_pop_tag(data)) return false;
356 : }
357 15384 : if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(3))) return false;
358 15384 : if (!asn1_write_DATA_BLOB_LDAPString(data, &tree->u.extended.value)) return false;
359 15384 : if (!asn1_pop_tag(data)) return false;
360 15384 : if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(4))) return false;
361 15384 : if (!asn1_write_uint8(data, tree->u.extended.dnAttributes)) return false;
362 15384 : if (!asn1_pop_tag(data)) return false;
363 15384 : if (!asn1_pop_tag(data)) return false;
364 15384 : break;
365 :
366 0 : default:
367 0 : return false;
368 : }
369 385970 : return !asn1_has_error(data);
370 : }
371 :
372 474866 : static bool ldap_encode_response(struct asn1_data *data, struct ldap_Result *result)
373 : {
374 474866 : if (!asn1_write_enumerated(data, result->resultcode)) return false;
375 474866 : if (!asn1_write_OctetString(data, result->dn,
376 474866 : (result->dn) ? strlen(result->dn) : 0)) return false;
377 592204 : if (!asn1_write_OctetString(data, result->errormessage,
378 474866 : (result->errormessage) ?
379 167383 : strlen(result->errormessage) : 0)) return false;
380 474866 : 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 474866 : return true;
387 : }
388 :
389 1585690 : _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 1585690 : struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
394 : int i, j;
395 :
396 1585690 : if (!data) return false;
397 :
398 1585690 : if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
399 1585690 : if (!asn1_write_Integer(data, msg->messageid)) goto err;
400 :
401 1585690 : switch (msg->type) {
402 26252 : case LDAP_TAG_BindRequest: {
403 26252 : struct ldap_BindRequest *r = &msg->r.BindRequest;
404 26252 : if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
405 26252 : if (!asn1_write_Integer(data, r->version)) goto err;
406 45828 : if (!asn1_write_OctetString(data, r->dn,
407 45828 : (r->dn != NULL) ? strlen(r->dn) : 0)) goto err;
408 :
409 26252 : 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 25876 : case LDAP_AUTH_MECH_SASL:
418 : /* context, constructed */
419 25876 : if (!asn1_push_tag(data, ASN1_CONTEXT(3))) goto err;
420 25876 : if (!asn1_write_OctetString(data, r->creds.SASL.mechanism,
421 0 : strlen(r->creds.SASL.mechanism))) goto err;
422 25876 : if (r->creds.SASL.secblob) {
423 25876 : if (!asn1_write_OctetString(data, r->creds.SASL.secblob->data,
424 25876 : r->creds.SASL.secblob->length)) goto err;
425 : }
426 25876 : if (!asn1_pop_tag(data)) goto err;
427 25876 : break;
428 0 : default:
429 0 : goto err;
430 : }
431 :
432 26252 : if (!asn1_pop_tag(data)) goto err;
433 26252 : break;
434 : }
435 26450 : case LDAP_TAG_BindResponse: {
436 26450 : struct ldap_BindResponse *r = &msg->r.BindResponse;
437 26450 : if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
438 26450 : if (!ldap_encode_response(data, &r->response)) goto err;
439 26450 : if (r->SASL.secblob) {
440 26071 : if (!asn1_write_ContextSimple(data, 7, r->SASL.secblob)) goto err;
441 : }
442 26450 : if (!asn1_pop_tag(data)) goto err;
443 26450 : 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 288727 : case LDAP_TAG_SearchRequest: {
452 288727 : struct ldap_SearchRequest *r = &msg->r.SearchRequest;
453 288727 : if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
454 288727 : if (!asn1_write_OctetString(data, r->basedn, strlen(r->basedn))) goto err;
455 288727 : if (!asn1_write_enumerated(data, r->scope)) goto err;
456 288727 : if (!asn1_write_enumerated(data, r->deref)) goto err;
457 288727 : if (!asn1_write_Integer(data, r->sizelimit)) goto err;
458 288727 : if (!asn1_write_Integer(data, r->timelimit)) goto err;
459 288727 : if (!asn1_write_BOOLEAN(data, r->attributesonly)) goto err;
460 :
461 288727 : if (!ldap_push_filter(data, r->tree)) {
462 0 : goto err;
463 : }
464 :
465 288727 : if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
466 800119 : for (i=0; i<r->num_attributes; i++) {
467 511392 : if (!asn1_write_OctetString(data, r->attributes[i],
468 511392 : strlen(r->attributes[i]))) goto err;
469 : }
470 288727 : if (!asn1_pop_tag(data)) goto err;
471 288727 : if (!asn1_pop_tag(data)) goto err;
472 288727 : break;
473 : }
474 547454 : case LDAP_TAG_SearchResultEntry: {
475 547454 : struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry;
476 547454 : if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
477 547454 : if (!asn1_write_OctetString(data, r->dn, strlen(r->dn))) goto err;
478 547454 : if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
479 2932014 : for (i=0; i<r->num_attributes; i++) {
480 2384560 : struct ldb_message_element *attr = &r->attributes[i];
481 2384560 : if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
482 2384560 : if (!asn1_write_OctetString(data, attr->name,
483 0 : strlen(attr->name))) goto err;
484 2384560 : if (!asn1_push_tag(data, ASN1_SEQUENCE(1))) goto err;
485 5193714 : for (j=0; j<attr->num_values; j++) {
486 5266035 : if (!asn1_write_OctetString(data,
487 2809154 : attr->values[j].data,
488 2809154 : attr->values[j].length)) goto err;
489 : }
490 2384560 : if (!asn1_pop_tag(data)) goto err;
491 2384560 : if (!asn1_pop_tag(data)) goto err;
492 : }
493 547454 : if (!asn1_pop_tag(data)) goto err;
494 547454 : if (!asn1_pop_tag(data)) goto err;
495 547454 : break;
496 : }
497 289438 : case LDAP_TAG_SearchResultDone: {
498 289438 : struct ldap_Result *r = &msg->r.SearchResultDone;
499 289438 : if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
500 289438 : if (!ldap_encode_response(data, r)) goto err;
501 289438 : if (!asn1_pop_tag(data)) goto err;
502 289438 : break;
503 : }
504 63815 : case LDAP_TAG_ModifyRequest: {
505 63815 : struct ldap_ModifyRequest *r = &msg->r.ModifyRequest;
506 63815 : if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
507 63815 : if (!asn1_write_OctetString(data, r->dn, strlen(r->dn))) goto err;
508 63815 : if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
509 :
510 146989 : for (i=0; i<r->num_mods; i++) {
511 83174 : struct ldb_message_element *attrib = &r->mods[i].attrib;
512 83174 : if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
513 83174 : if (!asn1_write_enumerated(data, r->mods[i].type)) goto err;
514 83174 : if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
515 83174 : if (!asn1_write_OctetString(data, attrib->name,
516 0 : strlen(attrib->name))) goto err;
517 83174 : if (!asn1_push_tag(data, ASN1_SET)) goto err;
518 168769 : for (j=0; j<attrib->num_values; j++) {
519 146161 : if (!asn1_write_OctetString(data,
520 85595 : attrib->values[j].data,
521 85595 : attrib->values[j].length)) goto err;
522 :
523 : }
524 83174 : if (!asn1_pop_tag(data)) goto err;
525 83174 : if (!asn1_pop_tag(data)) goto err;
526 83174 : if (!asn1_pop_tag(data)) goto err;
527 : }
528 :
529 63815 : if (!asn1_pop_tag(data)) goto err;
530 63815 : if (!asn1_pop_tag(data)) goto err;
531 63815 : break;
532 : }
533 63869 : case LDAP_TAG_ModifyResponse: {
534 63869 : struct ldap_Result *r = &msg->r.ModifyResponse;
535 63869 : if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
536 63869 : if (!ldap_encode_response(data, r)) goto err;
537 63869 : if (!asn1_pop_tag(data)) goto err;
538 63869 : break;
539 : }
540 43545 : case LDAP_TAG_AddRequest: {
541 43545 : struct ldap_AddRequest *r = &msg->r.AddRequest;
542 43545 : if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
543 43545 : if (!asn1_write_OctetString(data, r->dn, strlen(r->dn))) goto err;
544 43545 : if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
545 :
546 154548 : for (i=0; i<r->num_attributes; i++) {
547 111003 : struct ldb_message_element *attrib = &r->attributes[i];
548 111003 : if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
549 111003 : if (!asn1_write_OctetString(data, attrib->name,
550 0 : strlen(attrib->name))) goto err;
551 111003 : if (!asn1_push_tag(data, ASN1_SET)) goto err;
552 226684 : for (j=0; j<r->attributes[i].num_values; j++) {
553 209145 : if (!asn1_write_OctetString(data,
554 115681 : attrib->values[j].data,
555 115681 : attrib->values[j].length)) goto err;
556 : }
557 111003 : if (!asn1_pop_tag(data)) goto err;
558 111003 : if (!asn1_pop_tag(data)) goto err;
559 : }
560 43545 : if (!asn1_pop_tag(data)) goto err;
561 43545 : if (!asn1_pop_tag(data)) goto err;
562 43545 : break;
563 : }
564 43573 : case LDAP_TAG_AddResponse: {
565 43573 : struct ldap_Result *r = &msg->r.AddResponse;
566 43573 : if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
567 43573 : if (!ldap_encode_response(data, r)) goto err;
568 43573 : if (!asn1_pop_tag(data)) goto err;
569 43573 : break;
570 : }
571 51167 : case LDAP_TAG_DelRequest: {
572 51167 : struct ldap_DelRequest *r = &msg->r.DelRequest;
573 51167 : if (!asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type))) goto err;
574 51167 : if (!asn1_write(data, r->dn, strlen(r->dn))) goto err;
575 51167 : if (!asn1_pop_tag(data)) goto err;
576 51167 : break;
577 : }
578 51169 : case LDAP_TAG_DelResponse: {
579 51169 : struct ldap_Result *r = &msg->r.DelResponse;
580 51169 : if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
581 51169 : if (!ldap_encode_response(data, r)) goto err;
582 51169 : if (!asn1_pop_tag(data)) goto err;
583 51169 : 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 89471 : case LDAP_TAG_SearchResultReference: {
635 89471 : struct ldap_SearchResRef *r = &msg->r.SearchResultReference;
636 89471 : if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
637 89471 : if (!asn1_write_OctetString(data, r->referral, strlen(r->referral))) goto err;
638 89471 : if (!asn1_pop_tag(data)) goto err;
639 89471 : 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 1585690 : if (msg->controls != NULL) {
677 263098 : if (!asn1_push_tag(data, ASN1_CONTEXT(0))) goto err;
678 :
679 607794 : for (i = 0; msg->controls[i] != NULL; i++) {
680 344696 : if (!ldap_encode_control(mem_ctx, data,
681 : control_handlers,
682 344696 : 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 263098 : if (!asn1_pop_tag(data)) goto err;
690 : }
691 :
692 1585690 : if (!asn1_pop_tag(data)) goto err;
693 :
694 1585690 : if (!asn1_extract_blob(data, mem_ctx, result)) {
695 0 : goto err;
696 : }
697 :
698 1585690 : asn1_free(data);
699 :
700 1585690 : return true;
701 :
702 0 : err:
703 :
704 0 : asn1_free(data);
705 0 : return false;
706 : }
707 :
708 5240491 : static const char *blob2string_talloc(TALLOC_CTX *mem_ctx,
709 : DATA_BLOB blob)
710 : {
711 5240491 : char *result = talloc_array(mem_ctx, char, blob.length+1);
712 5240491 : if (result == NULL) {
713 0 : return NULL;
714 : }
715 5240491 : memcpy(result, blob.data, blob.length);
716 5240491 : result[blob.length] = '\0';
717 5240491 : return result;
718 : }
719 :
720 5240490 : bool asn1_read_OctetString_talloc(TALLOC_CTX *mem_ctx,
721 : struct asn1_data *data,
722 : const char **result)
723 : {
724 : DATA_BLOB string;
725 5240490 : if (!asn1_read_OctetString(data, mem_ctx, &string))
726 0 : return false;
727 5240490 : *result = blob2string_talloc(mem_ctx, string);
728 5240490 : data_blob_free(&string);
729 5240490 : return *result ? true : false;
730 : }
731 :
732 473849 : static bool ldap_decode_response(TALLOC_CTX *mem_ctx,
733 : struct asn1_data *data,
734 : struct ldap_Result *result)
735 : {
736 473849 : if (!asn1_read_enumerated(data, &result->resultcode)) return false;
737 473849 : if (!asn1_read_OctetString_talloc(mem_ctx, data, &result->dn)) return false;
738 473849 : if (!asn1_read_OctetString_talloc(mem_ctx, data, &result->errormessage)) return false;
739 473849 : 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 473841 : result->referral = NULL;
745 : }
746 473849 : 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 802433 : 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 802433 : if (!asn1_peek_uint8(data, &filter_tag)) {
784 0 : return NULL;
785 : }
786 :
787 802433 : filter_tag &= 0x1f; /* strip off the asn1 stuff */
788 :
789 802433 : ret = talloc(mem_ctx, struct ldb_parse_tree);
790 802433 : if (ret == NULL) return NULL;
791 :
792 802433 : switch(filter_tag) {
793 230623 : case 0:
794 : case 1:
795 : /* AND or OR of one or more filters */
796 230623 : ret->operation = (filter_tag == 0)?LDB_OP_AND:LDB_OP_OR;
797 230623 : ret->u.list.num_elements = 0;
798 230623 : ret->u.list.elements = NULL;
799 :
800 230623 : if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) {
801 0 : goto failed;
802 : }
803 :
804 913025 : while (asn1_tag_remaining(data) > 0) {
805 : struct ldb_parse_tree *subtree;
806 499893 : subtree = ldap_decode_filter_tree(ret, data);
807 499893 : if (subtree == NULL) {
808 0 : goto failed;
809 : }
810 499893 : ret->u.list.elements =
811 499893 : talloc_realloc(ret, ret->u.list.elements,
812 : struct ldb_parse_tree *,
813 : ret->u.list.num_elements+1);
814 499893 : if (ret->u.list.elements == NULL) {
815 0 : goto failed;
816 : }
817 499893 : talloc_steal(ret->u.list.elements, subtree);
818 499893 : ret->u.list.elements[ret->u.list.num_elements] = subtree;
819 499893 : ret->u.list.num_elements++;
820 : }
821 230623 : if (!asn1_end_tag(data)) {
822 0 : goto failed;
823 : }
824 230623 : break;
825 :
826 13072 : case 2:
827 : /* 'not' operation */
828 13072 : if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) {
829 0 : goto failed;
830 : }
831 :
832 13072 : ret->operation = LDB_OP_NOT;
833 13072 : ret->u.isnot.child = ldap_decode_filter_tree(ret, data);
834 13072 : if (ret->u.isnot.child == NULL) {
835 0 : goto failed;
836 : }
837 13072 : if (!asn1_end_tag(data)) {
838 0 : goto failed;
839 : }
840 13072 : break;
841 :
842 113096 : case 3: {
843 : /* equalityMatch */
844 : const char *attrib;
845 : DATA_BLOB value;
846 :
847 113096 : if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) goto failed;
848 113096 : if (!asn1_read_OctetString_talloc(mem_ctx, data, &attrib)) goto failed;
849 113096 : if (!asn1_read_OctetString(data, mem_ctx, &value)) goto failed;
850 113096 : if (!asn1_end_tag(data)) goto failed;
851 193783 : if (asn1_has_error(data) || (attrib == NULL) ||
852 113096 : (value.data == NULL)) {
853 0 : goto failed;
854 : }
855 :
856 113096 : ret->operation = LDB_OP_EQUALITY;
857 113096 : ret->u.equality.attr = talloc_steal(ret, attrib);
858 113096 : ret->u.equality.value.data = talloc_steal(ret, value.data);
859 113096 : ret->u.equality.value.length = value.length;
860 113096 : 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 42308 : 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 418 : 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 394 : 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 415060 : case 7: {
999 : /* Normal presence, "attribute=*" */
1000 : char *attr;
1001 :
1002 415060 : if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(filter_tag))) {
1003 0 : goto failed;
1004 : }
1005 415060 : if (!asn1_read_LDAPString(data, ret, &attr)) {
1006 0 : goto failed;
1007 : }
1008 :
1009 415060 : ret->operation = LDB_OP_PRESENT;
1010 415060 : ret->u.present.attr = talloc_steal(ret, attr);
1011 :
1012 415060 : if (!asn1_end_tag(data)) {
1013 0 : goto failed;
1014 : }
1015 415060 : 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 15404 : case 9: {
1038 15404 : char *oid = NULL, *attr = NULL, *value;
1039 : uint8_t dnAttributes;
1040 : /* an extended search */
1041 15404 : 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 15404 : if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { /* optional */
1049 15404 : if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(1))) goto failed;
1050 15404 : if (!asn1_read_LDAPString(data, ret, &oid)) goto failed;
1051 15404 : if (!asn1_end_tag(data)) goto failed;
1052 : }
1053 15404 : if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(2))) { /* optional */
1054 15404 : if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(2))) goto failed;
1055 15404 : if (!asn1_read_LDAPString(data, ret, &attr)) goto failed;
1056 15404 : if (!asn1_end_tag(data)) goto failed;
1057 : }
1058 15404 : if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(3))) goto failed;
1059 15404 : if (!asn1_read_LDAPString(data, ret, &value)) goto failed;
1060 15404 : 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 15404 : if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(4))) {
1068 15404 : if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(4))) goto failed;
1069 15404 : if (!asn1_read_uint8(data, &dnAttributes)) goto failed;
1070 15404 : if (!asn1_end_tag(data)) goto failed;
1071 : } else {
1072 0 : dnAttributes = 0;
1073 : }
1074 15404 : if ((oid == NULL && attr == NULL) || (value == NULL)) {
1075 0 : goto failed;
1076 : }
1077 :
1078 15404 : if (oid) {
1079 15404 : 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 15404 : if (attr) {
1086 15404 : 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 15404 : ret->u.extended.rule_id = talloc_steal(ret, oid);
1094 15404 : ret->u.extended.value.data = (uint8_t *)talloc_steal(ret, value);
1095 15404 : ret->u.extended.value.length = strlen(value);
1096 15404 : 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 15404 : if (!asn1_end_tag(data)) {
1104 0 : goto failed;
1105 : }
1106 15404 : break;
1107 : }
1108 :
1109 0 : default:
1110 0 : goto failed;
1111 : }
1112 :
1113 802433 : 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 2577396 : static bool ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data,
1122 : struct ldb_message_element *attrib)
1123 : {
1124 2577396 : if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) return false;
1125 2577396 : if (!asn1_read_OctetString_talloc(mem_ctx, data, &attrib->name)) return false;
1126 2577396 : if (!asn1_start_tag(data, ASN1_SET)) return false;
1127 7822954 : while (asn1_peek_tag(data, ASN1_OCTET_STRING)) {
1128 : DATA_BLOB blob;
1129 3008174 : if (!asn1_read_OctetString(data, mem_ctx, &blob)) return false;
1130 3008174 : add_value_to_attrib(mem_ctx, &blob, attrib);
1131 : }
1132 2577396 : if (!asn1_end_tag(data)) return false;
1133 2577396 : return asn1_end_tag(data);
1134 : }
1135 :
1136 : /* Decode a set of LDAP attributes, as found in the dereference control */
1137 592618 : 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 3602714 : while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) {
1142 : struct ldb_message_element attrib;
1143 2494142 : ZERO_STRUCT(attrib);
1144 2494142 : if (!ldap_decode_attrib(mem_ctx, data, &attrib)) return false;
1145 2494142 : add_attrib_to_array_talloc(mem_ctx, &attrib,
1146 : attributes, num_attributes);
1147 : }
1148 592618 : return true;
1149 : }
1150 :
1151 : /* Decode a set of LDAP attributes, as found in a search entry */
1152 592618 : 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 592618 : if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) return false;
1157 592618 : if (!ldap_decode_attribs_bare(mem_ctx, data,
1158 0 : attributes, num_attributes)) return false;
1159 592618 : return asn1_end_tag(data);
1160 : }
1161 :
1162 : /* This routine returns LDAP status codes */
1163 :
1164 1586961 : _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 1586961 : if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) goto prot_err;
1172 1586961 : if (!asn1_read_Integer(data, &msg->messageid)) goto prot_err;
1173 :
1174 1586961 : if (!asn1_peek_uint8(data, &tag)) goto prot_err;
1175 :
1176 1586961 : switch(tag) {
1177 :
1178 26450 : case ASN1_APPLICATION(LDAP_TAG_BindRequest): {
1179 26450 : struct ldap_BindRequest *r = &msg->r.BindRequest;
1180 26450 : msg->type = LDAP_TAG_BindRequest;
1181 26450 : if (!asn1_start_tag(data, tag)) goto prot_err;
1182 26450 : if (!asn1_read_Integer(data, &r->version)) goto prot_err;
1183 26450 : if (!asn1_read_OctetString_talloc(msg, data, &r->dn)) goto prot_err;
1184 26450 : 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 26071 : } else if (asn1_peek_tag(data, ASN1_CONTEXT(3))){
1204 26071 : if (!asn1_start_tag(data, ASN1_CONTEXT(3))) goto prot_err;
1205 26071 : r->mechanism = LDAP_AUTH_MECH_SASL;
1206 26071 : if (!asn1_read_OctetString_talloc(msg, data, &r->creds.SASL.mechanism)) goto prot_err;
1207 26071 : if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { /* optional */
1208 25977 : DATA_BLOB tmp_blob = data_blob(NULL, 0);
1209 25977 : if (!asn1_read_OctetString(data, msg, &tmp_blob)) goto prot_err;
1210 25977 : r->creds.SASL.secblob = talloc(msg, DATA_BLOB);
1211 25977 : if (!r->creds.SASL.secblob) {
1212 0 : return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR);
1213 : }
1214 25977 : *r->creds.SASL.secblob = data_blob_talloc(r->creds.SASL.secblob,
1215 : tmp_blob.data, tmp_blob.length);
1216 25977 : data_blob_free(&tmp_blob);
1217 : } else {
1218 94 : r->creds.SASL.secblob = NULL;
1219 : }
1220 26071 : if (!asn1_end_tag(data)) goto prot_err;
1221 : } else {
1222 : /* Neither Simple nor SASL bind */
1223 0 : goto prot_err;
1224 : }
1225 26450 : if (!asn1_end_tag(data)) goto prot_err;
1226 26450 : break;
1227 : }
1228 :
1229 26252 : case ASN1_APPLICATION(LDAP_TAG_BindResponse): {
1230 26252 : struct ldap_BindResponse *r = &msg->r.BindResponse;
1231 26252 : msg->type = LDAP_TAG_BindResponse;
1232 26252 : if (!asn1_start_tag(data, tag)) goto prot_err;
1233 26252 : if (!ldap_decode_response(msg, data, &r->response)) goto prot_err;
1234 26252 : if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(7))) {
1235 25876 : DATA_BLOB tmp_blob = data_blob(NULL, 0);
1236 25876 : if (!asn1_read_ContextSimple(data, msg, 7, &tmp_blob)) goto prot_err;
1237 25876 : r->SASL.secblob = talloc(msg, DATA_BLOB);
1238 25876 : if (!r->SASL.secblob) {
1239 0 : return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR);
1240 : }
1241 25876 : *r->SASL.secblob = data_blob_talloc(r->SASL.secblob,
1242 : tmp_blob.data, tmp_blob.length);
1243 25876 : data_blob_free(&tmp_blob);
1244 : } else {
1245 376 : r->SASL.secblob = NULL;
1246 : }
1247 26252 : if (!asn1_end_tag(data)) goto prot_err;
1248 26252 : 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 289468 : case ASN1_APPLICATION(LDAP_TAG_SearchRequest): {
1259 289468 : struct ldap_SearchRequest *r = &msg->r.SearchRequest;
1260 : int sizelimit, timelimit;
1261 289468 : const char **attrs = NULL;
1262 289468 : size_t request_size = asn1_get_length(data);
1263 289468 : msg->type = LDAP_TAG_SearchRequest;
1264 289468 : if (request_size > limits->max_search_size) {
1265 0 : goto prot_err;
1266 : }
1267 289468 : if (!asn1_start_tag(data, tag)) goto prot_err;
1268 289468 : if (!asn1_read_OctetString_talloc(msg, data, &r->basedn)) goto prot_err;
1269 289468 : if (!asn1_read_enumerated(data, (int *)(void *)&(r->scope))) goto prot_err;
1270 289468 : if (!asn1_read_enumerated(data, (int *)(void *)&(r->deref))) goto prot_err;
1271 289468 : if (!asn1_read_Integer(data, &sizelimit)) goto prot_err;
1272 289468 : r->sizelimit = sizelimit;
1273 289468 : if (!asn1_read_Integer(data, &timelimit)) goto prot_err;
1274 289468 : r->timelimit = timelimit;
1275 289468 : if (!asn1_read_BOOLEAN(data, &r->attributesonly)) goto prot_err;
1276 :
1277 289468 : r->tree = ldap_decode_filter_tree(msg, data);
1278 289468 : if (r->tree == NULL) {
1279 0 : goto prot_err;
1280 : }
1281 :
1282 289468 : if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) goto prot_err;
1283 :
1284 289468 : r->num_attributes = 0;
1285 289468 : r->attributes = NULL;
1286 :
1287 1035300 : while (asn1_tag_remaining(data) > 0) {
1288 :
1289 : const char *attr;
1290 513626 : if (!asn1_read_OctetString_talloc(msg, data,
1291 : &attr))
1292 0 : goto prot_err;
1293 513626 : if (!add_string_to_array(msg, attr,
1294 : &attrs,
1295 : &r->num_attributes))
1296 0 : goto prot_err;
1297 : }
1298 289468 : r->attributes = attrs;
1299 :
1300 289468 : if (!asn1_end_tag(data)) goto prot_err;
1301 289468 : if (!asn1_end_tag(data)) goto prot_err;
1302 289468 : break;
1303 : }
1304 :
1305 549045 : case ASN1_APPLICATION(LDAP_TAG_SearchResultEntry): {
1306 549045 : struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry;
1307 549045 : msg->type = LDAP_TAG_SearchResultEntry;
1308 549045 : r->attributes = NULL;
1309 549045 : r->num_attributes = 0;
1310 549045 : if (!asn1_start_tag(data, tag)) goto prot_err;
1311 549045 : if (!asn1_read_OctetString_talloc(msg, data, &r->dn)) goto prot_err;
1312 549045 : if (!ldap_decode_attribs(msg, data, &r->attributes,
1313 0 : &r->num_attributes)) goto prot_err;
1314 549045 : if (!asn1_end_tag(data)) goto prot_err;
1315 549045 : break;
1316 : }
1317 :
1318 288705 : case ASN1_APPLICATION(LDAP_TAG_SearchResultDone): {
1319 288705 : struct ldap_Result *r = &msg->r.SearchResultDone;
1320 288705 : msg->type = LDAP_TAG_SearchResultDone;
1321 288705 : if (!asn1_start_tag(data, tag)) goto prot_err;
1322 288705 : if (!ldap_decode_response(msg, data, r)) goto prot_err;
1323 288705 : if (!asn1_end_tag(data)) goto prot_err;
1324 288705 : break;
1325 : }
1326 :
1327 89056 : case ASN1_APPLICATION(LDAP_TAG_SearchResultReference): {
1328 89056 : struct ldap_SearchResRef *r = &msg->r.SearchResultReference;
1329 89056 : msg->type = LDAP_TAG_SearchResultReference;
1330 89056 : if (!asn1_start_tag(data, tag)) goto prot_err;
1331 89056 : if (!asn1_read_OctetString_talloc(msg, data, &r->referral)) goto prot_err;
1332 89056 : if (!asn1_end_tag(data)) goto prot_err;
1333 89056 : break;
1334 : }
1335 :
1336 63869 : case ASN1_APPLICATION(LDAP_TAG_ModifyRequest): {
1337 63869 : struct ldap_ModifyRequest *r = &msg->r.ModifyRequest;
1338 63869 : msg->type = LDAP_TAG_ModifyRequest;
1339 63869 : if (!asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_ModifyRequest))) goto prot_err;
1340 63869 : if (!asn1_read_OctetString_talloc(msg, data, &r->dn)) goto prot_err;
1341 63869 : if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) goto prot_err;
1342 :
1343 63869 : r->num_mods = 0;
1344 63869 : r->mods = NULL;
1345 :
1346 191020 : while (asn1_tag_remaining(data) > 0) {
1347 : struct ldap_mod mod;
1348 : int v;
1349 83254 : ZERO_STRUCT(mod);
1350 83254 : if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) goto prot_err;
1351 83254 : if (!asn1_read_enumerated(data, &v)) goto prot_err;
1352 83254 : mod.type = v;
1353 83254 : if (!ldap_decode_attrib(msg, data, &mod.attrib)) goto prot_err;
1354 83254 : if (!asn1_end_tag(data)) goto prot_err;
1355 83254 : 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 63869 : if (!asn1_end_tag(data)) goto prot_err;
1362 63869 : if (!asn1_end_tag(data)) goto prot_err;
1363 63869 : break;
1364 : }
1365 :
1366 63815 : case ASN1_APPLICATION(LDAP_TAG_ModifyResponse): {
1367 63815 : struct ldap_Result *r = &msg->r.ModifyResponse;
1368 63815 : msg->type = LDAP_TAG_ModifyResponse;
1369 63815 : if (!asn1_start_tag(data, tag)) goto prot_err;
1370 63815 : if (!ldap_decode_response(msg, data, r)) goto prot_err;
1371 63815 : if (!asn1_end_tag(data)) goto prot_err;
1372 63815 : break;
1373 : }
1374 :
1375 43573 : case ASN1_APPLICATION(LDAP_TAG_AddRequest): {
1376 43573 : struct ldap_AddRequest *r = &msg->r.AddRequest;
1377 43573 : msg->type = LDAP_TAG_AddRequest;
1378 43573 : if (!asn1_start_tag(data, tag)) goto prot_err;
1379 43573 : if (!asn1_read_OctetString_talloc(msg, data, &r->dn)) goto prot_err;
1380 :
1381 43573 : r->attributes = NULL;
1382 43573 : r->num_attributes = 0;
1383 43573 : if (!ldap_decode_attribs(msg, data, &r->attributes,
1384 0 : &r->num_attributes)) goto prot_err;
1385 :
1386 43573 : if (!asn1_end_tag(data)) goto prot_err;
1387 43573 : break;
1388 : }
1389 :
1390 43545 : case ASN1_APPLICATION(LDAP_TAG_AddResponse): {
1391 43545 : struct ldap_Result *r = &msg->r.AddResponse;
1392 43545 : msg->type = LDAP_TAG_AddResponse;
1393 43545 : if (!asn1_start_tag(data, tag)) goto prot_err;
1394 43545 : if (!ldap_decode_response(msg, data, r)) goto prot_err;
1395 43545 : if (!asn1_end_tag(data)) goto prot_err;
1396 43545 : break;
1397 : }
1398 :
1399 51169 : case ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest): {
1400 51169 : struct ldap_DelRequest *r = &msg->r.DelRequest;
1401 : int len;
1402 : char *dn;
1403 51169 : msg->type = LDAP_TAG_DelRequest;
1404 51169 : if (!asn1_start_tag(data,
1405 0 : ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest))) goto prot_err;
1406 51169 : len = asn1_tag_remaining(data);
1407 51169 : if (len == -1) {
1408 0 : goto prot_err;
1409 : }
1410 51169 : dn = talloc_array(msg, char, len+1);
1411 51169 : if (dn == NULL)
1412 0 : break;
1413 51169 : if (!asn1_read(data, dn, len)) goto prot_err;
1414 51169 : dn[len] = '\0';
1415 51169 : r->dn = dn;
1416 51169 : if (!asn1_end_tag(data)) goto prot_err;
1417 51169 : break;
1418 : }
1419 :
1420 51167 : case ASN1_APPLICATION(LDAP_TAG_DelResponse): {
1421 51167 : struct ldap_Result *r = &msg->r.DelResponse;
1422 51167 : msg->type = LDAP_TAG_DelResponse;
1423 51167 : if (!asn1_start_tag(data, tag)) goto prot_err;
1424 51167 : if (!ldap_decode_response(msg, data, r)) goto prot_err;
1425 51167 : if (!asn1_end_tag(data)) goto prot_err;
1426 51167 : 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 1586961 : msg->controls = NULL;
1575 1586961 : msg->controls_decoded = NULL;
1576 :
1577 1586961 : if (asn1_peek_tag(data, ASN1_CONTEXT(0))) {
1578 263152 : int i = 0;
1579 263152 : struct ldb_control **ctrl = NULL;
1580 263152 : bool *decoded = NULL;
1581 :
1582 263152 : if (!asn1_start_tag(data, ASN1_CONTEXT(0))) goto prot_err;
1583 :
1584 845162 : while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) {
1585 : DATA_BLOB value;
1586 : /* asn1_start_tag(data, ASN1_SEQUENCE(0)); */
1587 :
1588 344819 : ctrl = talloc_realloc(msg, ctrl, struct ldb_control *, i+2);
1589 344819 : if (!ctrl) {
1590 0 : return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR);
1591 : }
1592 :
1593 344819 : decoded = talloc_realloc(msg, decoded, bool, i+1);
1594 344819 : if (!decoded) {
1595 0 : return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR);
1596 : }
1597 :
1598 344819 : ctrl[i] = talloc(ctrl, struct ldb_control);
1599 344819 : if (!ctrl[i]) {
1600 0 : return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR);
1601 : }
1602 :
1603 344819 : if (!ldap_decode_control_wrapper(ctrl[i], data, ctrl[i], &value)) {
1604 0 : goto prot_err;
1605 : }
1606 :
1607 344819 : if (!ldap_decode_control_value(ctrl[i], value,
1608 : control_handlers,
1609 344819 : 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 344819 : decoded[i] = true;
1620 344819 : i++;
1621 : }
1622 : }
1623 :
1624 263152 : if (ctrl != NULL) {
1625 263152 : ctrl[i] = NULL;
1626 : }
1627 :
1628 263152 : msg->controls = ctrl;
1629 263152 : msg->controls_decoded = decoded;
1630 :
1631 263152 : if (!asn1_end_tag(data)) goto prot_err;
1632 : }
1633 :
1634 1586961 : if (!asn1_end_tag(data)) goto prot_err;
1635 1586961 : if (asn1_has_error(data) || asn1_has_nesting(data)) {
1636 0 : return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR);
1637 : }
1638 1586961 : 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 3164795 : NTSTATUS ldap_full_packet(void *private_data, DATA_BLOB blob, size_t *packet_size)
1651 : {
1652 : int ret;
1653 :
1654 3164795 : 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 3164795 : ret = asn1_peek_full_tag(blob, ASN1_SEQUENCE(0), packet_size);
1663 3164795 : if (ret != 0) {
1664 1582352 : return map_nt_error_from_unix_common(ret);
1665 : }
1666 1582443 : return NT_STATUS_OK;
1667 : }
|