LCOV - code coverage report
Current view: top level - libcli/ldap - ldap_message.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 928 1084 85.6 %
Date: 2024-02-28 12:06:22 Functions: 20 20 100.0 %

          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      626801 : _PUBLIC_ struct ldap_message *new_ldap_message(TALLOC_CTX *mem_ctx)
      30             : {
      31      626801 :         return talloc_zero(mem_ctx, struct ldap_message);
      32             : }
      33             : 
      34             : 
      35     3856119 : static bool add_value_to_attrib(TALLOC_CTX *mem_ctx, struct ldb_val *value,
      36             :                                 struct ldb_message_element *attrib)
      37             : {
      38     3856119 :         attrib->values = talloc_realloc(mem_ctx,
      39             :                                         attrib->values,
      40             :                                         DATA_BLOB,
      41             :                                         attrib->num_values+1);
      42     3856119 :         if (attrib->values == NULL)
      43           0 :                 return false;
      44             : 
      45     3856119 :         attrib->values[attrib->num_values].data = talloc_steal(attrib->values,
      46             :                                                                value->data);
      47     3856119 :         attrib->values[attrib->num_values].length = value->length;
      48     3856119 :         attrib->num_values += 1;
      49     3856119 :         return true;
      50             : }
      51             : 
      52     3238131 : 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     3238131 :         *attribs = talloc_realloc(mem_ctx,
      58             :                                   *attribs,
      59             :                                   struct ldb_message_element,
      60             :                                   *num_attribs+1);
      61             : 
      62     3238131 :         if (*attribs == NULL)
      63           0 :                 return false;
      64             : 
      65     3238131 :         (*attribs)[*num_attribs] = *attrib;
      66     3238131 :         talloc_steal(*attribs, attrib->values);
      67     3238131 :         talloc_steal(*attribs, attrib->name);
      68     3238131 :         *num_attribs += 1;
      69     3238131 :         return true;
      70             : }
      71             : 
      72      112996 : 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      112996 :         *mods = talloc_realloc(mem_ctx, *mods, struct ldap_mod, (*num_mods)+1);
      78             : 
      79      112996 :         if (*mods == NULL)
      80           0 :                 return false;
      81             : 
      82      112996 :         (*mods)[*num_mods] = *mod;
      83      112996 :         *num_mods += 1;
      84      112996 :         return true;
      85             : }
      86             : 
      87      400748 : 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      400748 :         if (!handlers) {
      94           0 :                 return true;
      95             :         }
      96             : 
      97     3182080 :         for (i = 0; handlers[i].oid != NULL; i++) {
      98     3182080 :                 if (strcmp(handlers[i].oid, ctrl->oid) == 0) {
      99      400748 :                         if (!handlers[i].decode || !handlers[i].decode(mem_ctx, value, &ctrl->data)) {
     100           0 :                                 return false;
     101             :                         }
     102      400748 :                         break;
     103             :                 }
     104             :         }
     105      400748 :         if (handlers[i].oid == NULL) {
     106           0 :                 return false;
     107             :         }
     108             : 
     109      400748 :         return true;
     110             : }
     111             : 
     112      400748 : 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      400748 :         if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) {
     118           0 :                 return false;
     119             :         }
     120             : 
     121      400748 :         if (!asn1_read_OctetString(data, mem_ctx, &oid)) {
     122           0 :                 return false;
     123             :         }
     124      400748 :         ctrl->oid = talloc_strndup(mem_ctx, (char *)oid.data, oid.length);
     125      400748 :         if (!ctrl->oid) {
     126           0 :                 return false;
     127             :         }
     128             : 
     129      400748 :         if (asn1_peek_tag(data, ASN1_BOOLEAN)) {
     130           0 :                 bool critical;
     131      263879 :                 if (!asn1_read_BOOLEAN(data, &critical)) {
     132           0 :                         return false;
     133             :                 }
     134      263879 :                 ctrl->critical = critical;
     135             :         } else {
     136      136869 :                 ctrl->critical = false;
     137             :         }
     138             : 
     139      400748 :         ctrl->data = NULL;
     140             : 
     141      400748 :         if (!asn1_peek_tag(data, ASN1_OCTET_STRING)) {
     142       67544 :                 *value = data_blob(NULL, 0);
     143       67544 :                 goto end_tag;
     144             :         }
     145             : 
     146      333204 :         if (!asn1_read_OctetString(data, mem_ctx, value)) {
     147           0 :                 return false;
     148             :         }
     149             : 
     150      333204 : end_tag:
     151      400748 :         if (!asn1_end_tag(data)) {
     152           0 :                 return false;
     153             :         }
     154             : 
     155      400748 :         return true;
     156             : }
     157             : 
     158      400599 : 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      400599 :         if (!handlers) {
     166           0 :                 return false;
     167             :         }
     168             : 
     169     3186531 :         for (i = 0; handlers[i].oid != NULL; i++) {
     170     3186531 :                 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     3186531 :                 if (strcmp(handlers[i].oid, ctrl->oid) == 0) {
     177      400599 :                         if (!handlers[i].encode) {
     178         190 :                                 if (ctrl->critical) {
     179           0 :                                         return false;
     180             :                                 } else {
     181             :                                         /* not encoding this control */
     182         190 :                                         return true;
     183             :                                 }
     184             :                         }
     185      400409 :                         if (!handlers[i].encode(mem_ctx, ctrl->data, &value)) {
     186           0 :                                 return false;
     187             :                         }
     188      400409 :                         break;
     189             :                 }
     190             :         }
     191      400409 :         if (handlers[i].oid == NULL) {
     192           0 :                 return false;
     193             :         }
     194             : 
     195      400409 :         if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) {
     196           0 :                 return false;
     197             :         }
     198             : 
     199      400409 :         if (!asn1_write_OctetString(data, ctrl->oid, strlen(ctrl->oid))) {
     200           0 :                 return false;
     201             :         }
     202             : 
     203      400409 :         if (ctrl->critical) {
     204      263466 :                 if (!asn1_write_BOOLEAN(data, ctrl->critical)) {
     205           0 :                         return false;
     206             :                 }
     207             :         }
     208             : 
     209      400409 :         if (!ctrl->data) {
     210       67360 :                 goto pop_tag;
     211             :         }
     212             : 
     213      333049 :         if (!asn1_write_OctetString(data, value.data, value.length)) {
     214           0 :                 return false;
     215             :         }
     216             : 
     217      333049 : pop_tag:
     218      400409 :         if (!asn1_pop_tag(data)) {
     219           0 :                 return false;
     220             :         }
     221             : 
     222      400409 :         return true;
     223             : }
     224             : 
     225     1001386 : static bool ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree)
     226             : {
     227         913 :         int i;
     228             : 
     229     1001386 :         switch (tree->operation) {
     230      287088 :         case LDB_OP_AND:
     231             :         case LDB_OP_OR:
     232      287124 :                 if (!asn1_push_tag(data, ASN1_CONTEXT(tree->operation==LDB_OP_AND?0:1))) return false;
     233      908930 :                 for (i=0; i<tree->u.list.num_elements; i++) {
     234      621842 :                         if (!ldap_push_filter(data, tree->u.list.elements[i])) {
     235           0 :                                 return false;
     236             :                         }
     237             :                 }
     238      287088 :                 if (!asn1_pop_tag(data)) return false;
     239      286817 :                 break;
     240             : 
     241       14993 :         case LDB_OP_NOT:
     242       14993 :                 if (!asn1_push_tag(data, ASN1_CONTEXT(2))) return false;
     243       14993 :                 if (!ldap_push_filter(data, tree->u.isnot.child)) {
     244           0 :                         return false;
     245             :                 }
     246       14993 :                 if (!asn1_pop_tag(data)) return false;
     247       14993 :                 break;
     248             : 
     249      159134 :         case LDB_OP_EQUALITY:
     250             :                 /* equality test */
     251      159134 :                 if (!asn1_push_tag(data, ASN1_CONTEXT(3))) return false;
     252      159134 :                 if (!asn1_write_OctetString(data, tree->u.equality.attr,
     253           0 :                                       strlen(tree->u.equality.attr))) return false;
     254      159134 :                 if (!asn1_write_OctetString(data, tree->u.equality.value.data,
     255           0 :                                       tree->u.equality.value.length)) return false;
     256      159134 :                 if (!asn1_pop_tag(data)) return false;
     257      159086 :                 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         241 :         case LDB_OP_LESS:
     311             :                 /* lessOrEqual test */
     312         241 :                 if (!asn1_push_tag(data, ASN1_CONTEXT(6))) return false;
     313         241 :                 if (!asn1_write_OctetString(data, tree->u.comparison.attr,
     314           0 :                                       strlen(tree->u.comparison.attr))) return false;
     315         241 :                 if (!asn1_write_OctetString(data, tree->u.comparison.value.data,
     316           0 :                                       tree->u.comparison.value.length)) return false;
     317         241 :                 if (!asn1_pop_tag(data)) return false;
     318         241 :                 break;
     319             : 
     320      506897 :         case LDB_OP_PRESENT:
     321             :                 /* present test */
     322      506897 :                 if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(7))) return false;
     323      506897 :                 if (!asn1_write_LDAPString(data, tree->u.present.attr)) return false;
     324      506897 :                 if (!asn1_pop_tag(data)) return false;
     325      506897 :                 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       17782 :         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       17782 :                 if (!asn1_push_tag(data, ASN1_CONTEXT(9))) return false;
     347       17782 :                 if (tree->u.extended.rule_id) {
     348       17782 :                         if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(1))) return false;
     349       17782 :                         if (!asn1_write_LDAPString(data, tree->u.extended.rule_id)) return false;
     350       17782 :                         if (!asn1_pop_tag(data)) return false;
     351             :                 }
     352       17782 :                 if (tree->u.extended.attr) {
     353       17782 :                         if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(2))) return false;
     354       17782 :                         if (!asn1_write_LDAPString(data, tree->u.extended.attr)) return false;
     355       17782 :                         if (!asn1_pop_tag(data)) return false;
     356             :                 }
     357       17782 :                 if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(3))) return false;
     358       17782 :                 if (!asn1_write_DATA_BLOB_LDAPString(data, &tree->u.extended.value)) return false;
     359       17782 :                 if (!asn1_pop_tag(data)) return false;
     360       17782 :                 if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(4))) return false;
     361       17782 :                 if (!asn1_write_uint8(data, tree->u.extended.dnAttributes)) return false;
     362       17782 :                 if (!asn1_pop_tag(data)) return false;
     363       17782 :                 if (!asn1_pop_tag(data)) return false;
     364       17782 :                 break;
     365             : 
     366           0 :         default:
     367           0 :                 return false;
     368             :         }
     369      494489 :         return !asn1_has_error(data);
     370             : }
     371             : 
     372      632591 : static bool ldap_encode_response(struct asn1_data *data, struct ldap_Result *result)
     373             : {
     374      632591 :         if (!asn1_write_enumerated(data, result->resultcode)) return false;
     375      632591 :         if (!asn1_write_OctetString(data, result->dn,
     376      632591 :                                (result->dn) ? strlen(result->dn) : 0)) return false;
     377      632591 :         if (!asn1_write_OctetString(data, result->errormessage,
     378      632591 :                                (result->errormessage) ?
     379      238242 :                                strlen(result->errormessage) : 0)) return false;
     380      632591 :         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      631846 :         return true;
     387             : }
     388             : 
     389     2031622 : _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     2031622 :         struct asn1_data *data = asn1_init(mem_ctx, ASN1_MAX_TREE_DEPTH);
     394        1933 :         int i, j;
     395             : 
     396     2031622 :         if (!data) return false;
     397             : 
     398     2031622 :         if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
     399     2031622 :         if (!asn1_write_Integer(data, msg->messageid)) goto err;
     400             : 
     401     2031622 :         switch (msg->type) {
     402       35226 :         case LDAP_TAG_BindRequest: {
     403       35226 :                 struct ldap_BindRequest *r = &msg->r.BindRequest;
     404       35226 :                 if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
     405       35226 :                 if (!asn1_write_Integer(data, r->version)) goto err;
     406       35226 :                 if (!asn1_write_OctetString(data, r->dn,
     407       35226 :                                        (r->dn != NULL) ? strlen(r->dn) : 0)) goto err;
     408             : 
     409       35226 :                 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       34782 :                 case LDAP_AUTH_MECH_SASL:
     418             :                         /* context, constructed */
     419       34782 :                         if (!asn1_push_tag(data, ASN1_CONTEXT(3))) goto err;
     420       34782 :                         if (!asn1_write_OctetString(data, r->creds.SASL.mechanism,
     421           0 :                                                strlen(r->creds.SASL.mechanism))) goto err;
     422       34782 :                         if (r->creds.SASL.secblob) {
     423       34782 :                                 if (!asn1_write_OctetString(data, r->creds.SASL.secblob->data,
     424       34660 :                                                        r->creds.SASL.secblob->length)) goto err;
     425             :                         }
     426       34782 :                         if (!asn1_pop_tag(data)) goto err;
     427       34660 :                         break;
     428           0 :                 default:
     429           0 :                         goto err;
     430             :                 }
     431             : 
     432       35226 :                 if (!asn1_pop_tag(data)) goto err;
     433       35104 :                 break;
     434             :         }
     435       36024 :         case LDAP_TAG_BindResponse: {
     436       36024 :                 struct ldap_BindResponse *r = &msg->r.BindResponse;
     437       36024 :                 if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
     438       36024 :                 if (!ldap_encode_response(data, &r->response)) goto err;
     439       36024 :                 if (r->SASL.secblob) {
     440       35553 :                         if (!asn1_write_ContextSimple(data, 7, r->SASL.secblob)) goto err;
     441             :                 }
     442       36024 :                 if (!asn1_pop_tag(data)) goto err;
     443       35902 :                 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      364551 :         case LDAP_TAG_SearchRequest: {
     452      364551 :                 struct ldap_SearchRequest *r = &msg->r.SearchRequest;
     453      364551 :                 if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
     454      364551 :                 if (!asn1_write_OctetString(data, r->basedn, strlen(r->basedn))) goto err;
     455      364551 :                 if (!asn1_write_enumerated(data, r->scope)) goto err;
     456      364551 :                 if (!asn1_write_enumerated(data, r->deref)) goto err;
     457      364551 :                 if (!asn1_write_Integer(data, r->sizelimit)) goto err;
     458      364551 :                 if (!asn1_write_Integer(data, r->timelimit)) goto err;
     459      364551 :                 if (!asn1_write_BOOLEAN(data, r->attributesonly)) goto err;
     460             : 
     461      364551 :                 if (!ldap_push_filter(data, r->tree)) {
     462           0 :                         goto err;
     463             :                 }
     464             : 
     465      364551 :                 if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
     466      984061 :                 for (i=0; i<r->num_attributes; i++) {
     467      619510 :                         if (!asn1_write_OctetString(data, r->attributes[i],
     468      619510 :                                                strlen(r->attributes[i]))) goto err;
     469             :                 }
     470      364551 :                 if (!asn1_pop_tag(data)) goto err;
     471      364551 :                 if (!asn1_pop_tag(data)) goto err;
     472      364144 :                 break;
     473             :         }
     474      636077 :         case LDAP_TAG_SearchResultEntry: {
     475      636077 :                 struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry;
     476      636077 :                 if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
     477      636077 :                 if (!asn1_write_OctetString(data, r->dn, strlen(r->dn))) goto err;
     478      636077 :                 if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
     479     3702583 :                 for (i=0; i<r->num_attributes; i++) {
     480     3066506 :                         struct ldb_message_element *attr = &r->attributes[i];
     481     3066506 :                         if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
     482     3066506 :                         if (!asn1_write_OctetString(data, attr->name,
     483           0 :                                                strlen(attr->name))) goto err;
     484     3066506 :                         if (!asn1_push_tag(data, ASN1_SEQUENCE(1))) goto err;
     485     6638024 :                         for (j=0; j<attr->num_values; j++) {
     486     3571518 :                                 if (!asn1_write_OctetString(data,
     487     3571518 :                                                        attr->values[j].data,
     488     3571518 :                                                        attr->values[j].length)) goto err;
     489             :                         }
     490     3066506 :                         if (!asn1_pop_tag(data)) goto err;
     491     3066506 :                         if (!asn1_pop_tag(data)) goto err;
     492             :                 }
     493      636077 :                 if (!asn1_pop_tag(data)) goto err;
     494      636077 :                 if (!asn1_pop_tag(data)) goto err;
     495      635670 :                 break;
     496             :         }
     497      367085 :         case LDAP_TAG_SearchResultDone: {
     498      367085 :                 struct ldap_Result *r = &msg->r.SearchResultDone;
     499      367085 :                 if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
     500      367085 :                 if (!ldap_encode_response(data, r)) goto err;
     501      367085 :                 if (!asn1_pop_tag(data)) goto err;
     502      366678 :                 break;
     503             :         }
     504       86369 :         case LDAP_TAG_ModifyRequest: {
     505       86369 :                 struct ldap_ModifyRequest *r = &msg->r.ModifyRequest;
     506       86369 :                 if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
     507       86369 :                 if (!asn1_write_OctetString(data, r->dn, strlen(r->dn))) goto err;
     508       86369 :                 if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
     509             : 
     510      199133 :                 for (i=0; i<r->num_mods; i++) {
     511      112764 :                         struct ldb_message_element *attrib = &r->mods[i].attrib;
     512      112764 :                         if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
     513      112764 :                         if (!asn1_write_enumerated(data, r->mods[i].type)) goto err;
     514      112764 :                         if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
     515      112764 :                         if (!asn1_write_OctetString(data, attrib->name,
     516           0 :                                                strlen(attrib->name))) goto err;
     517      112764 :                         if (!asn1_push_tag(data, ASN1_SET)) goto err;
     518      226802 :                         for (j=0; j<attrib->num_values; j++) {
     519      114038 :                                 if (!asn1_write_OctetString(data,
     520      114038 :                                                        attrib->values[j].data,
     521      114038 :                                                        attrib->values[j].length)) goto err;
     522             :         
     523             :                         }
     524      112764 :                         if (!asn1_pop_tag(data)) goto err;
     525      112764 :                         if (!asn1_pop_tag(data)) goto err;
     526      112764 :                         if (!asn1_pop_tag(data)) goto err;
     527             :                 }
     528             :                 
     529       86369 :                 if (!asn1_pop_tag(data)) goto err;
     530       86369 :                 if (!asn1_pop_tag(data)) goto err;
     531       86225 :                 break;
     532             :         }
     533       86521 :         case LDAP_TAG_ModifyResponse: {
     534       86521 :                 struct ldap_Result *r = &msg->r.ModifyResponse;
     535       86521 :                 if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
     536       86521 :                 if (!ldap_encode_response(data, r)) goto err;
     537       86521 :                 if (!asn1_pop_tag(data)) goto err;
     538       86377 :                 break;
     539             :         }
     540       67472 :         case LDAP_TAG_AddRequest: {
     541       67472 :                 struct ldap_AddRequest *r = &msg->r.AddRequest;
     542       67472 :                 if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
     543       67472 :                 if (!asn1_write_OctetString(data, r->dn, strlen(r->dn))) goto err;
     544       67472 :                 if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
     545             : 
     546      251920 :                 for (i=0; i<r->num_attributes; i++) {
     547      184448 :                         struct ldb_message_element *attrib = &r->attributes[i];
     548      184448 :                         if (!asn1_push_tag(data, ASN1_SEQUENCE(0))) goto err;
     549      184448 :                         if (attrib->name == NULL) {
     550           0 :                                 goto err;
     551             :                         }
     552      184448 :                         if (!asn1_write_OctetString(data, attrib->name,
     553           0 :                                                strlen(attrib->name))) goto err;
     554      184448 :                         if (!asn1_push_tag(data, ASN1_SET)) goto err;
     555      373937 :                         for (j=0; j<r->attributes[i].num_values; j++) {
     556      189489 :                                 if (!asn1_write_OctetString(data,
     557      189489 :                                                        attrib->values[j].data,
     558      189489 :                                                        attrib->values[j].length)) goto err;
     559             :                         }
     560      184448 :                         if (!asn1_pop_tag(data)) goto err;
     561      184448 :                         if (!asn1_pop_tag(data)) goto err;
     562             :                 }
     563       67472 :                 if (!asn1_pop_tag(data)) goto err;
     564       67472 :                 if (!asn1_pop_tag(data)) goto err;
     565       67436 :                 break;
     566             :         }
     567       67532 :         case LDAP_TAG_AddResponse: {
     568       67532 :                 struct ldap_Result *r = &msg->r.AddResponse;
     569       67532 :                 if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
     570       67532 :                 if (!ldap_encode_response(data, r)) goto err;
     571       67532 :                 if (!asn1_pop_tag(data)) goto err;
     572       67496 :                 break;
     573             :         }
     574       74681 :         case LDAP_TAG_DelRequest: {
     575       74681 :                 struct ldap_DelRequest *r = &msg->r.DelRequest;
     576       74681 :                 if (!asn1_push_tag(data, ASN1_APPLICATION_SIMPLE(msg->type))) goto err;
     577       74681 :                 if (!asn1_write(data, r->dn, strlen(r->dn))) goto err;
     578       74681 :                 if (!asn1_pop_tag(data)) goto err;
     579       74645 :                 break;
     580             :         }
     581       74721 :         case LDAP_TAG_DelResponse: {
     582       74721 :                 struct ldap_Result *r = &msg->r.DelResponse;
     583       74721 :                 if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
     584       74721 :                 if (!ldap_encode_response(data, r)) goto err;
     585       74721 :                 if (!asn1_pop_tag(data)) goto err;
     586       74685 :                 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      133869 :         case LDAP_TAG_SearchResultReference: {
     638      133869 :                 struct ldap_SearchResRef *r = &msg->r.SearchResultReference;
     639      133869 :                 if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
     640      133869 :                 if (!asn1_write_OctetString(data, r->referral, strlen(r->referral))) goto err;
     641      133869 :                 if (!asn1_pop_tag(data)) goto err;
     642      133833 :                 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         319 :         case LDAP_TAG_ExtendedResponse: {
     659         319 :                 struct ldap_ExtendedResponse *r = &msg->r.ExtendedResponse;
     660         319 :                 if (!asn1_push_tag(data, ASN1_APPLICATION(msg->type))) goto err;
     661         319 :                 if (!ldap_encode_response(data, &r->response)) goto err;
     662         319 :                 if (r->oid) {
     663         319 :                         if (!asn1_push_tag(data, ASN1_CONTEXT_SIMPLE(10))) goto err;
     664         319 :                         if (!asn1_write(data, r->oid, strlen(r->oid))) goto err;
     665         319 :                         if (!asn1_pop_tag(data)) goto err;
     666             :                 }
     667         319 :                 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         319 :                 if (!asn1_pop_tag(data)) goto err;
     673         319 :                 break;
     674             :         }
     675           0 :         default:
     676           0 :                 goto err;
     677             :         }
     678             : 
     679     2031622 :         if (msg->controls != NULL) {
     680      296561 :                 if (!asn1_push_tag(data, ASN1_CONTEXT(0))) goto err;
     681             :                 
     682      697160 :                 for (i = 0; msg->controls[i] != NULL; i++) {
     683      400599 :                         if (!ldap_encode_control(mem_ctx, data,
     684             :                                                  control_handlers,
     685      400599 :                                                  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      296561 :                 if (!asn1_pop_tag(data)) goto err;
     693             :         }
     694             : 
     695     2031622 :         if (!asn1_pop_tag(data)) goto err;
     696             : 
     697     2031622 :         if (!asn1_extract_blob(data, mem_ctx, result)) {
     698           0 :                 goto err;
     699             :         }
     700             : 
     701     2031622 :         asn1_free(data);
     702             : 
     703     2031622 :         return true;
     704             : 
     705           0 :   err:
     706             : 
     707           0 :         asn1_free(data);
     708           0 :         return false;
     709             : }
     710             : 
     711     6759827 : static const char *blob2string_talloc(TALLOC_CTX *mem_ctx,
     712             :                                       DATA_BLOB blob)
     713             : {
     714     6759827 :         char *result = talloc_array(mem_ctx, char, blob.length+1);
     715     6759827 :         if (result == NULL) {
     716           0 :                 return NULL;
     717             :         }
     718     6759827 :         memcpy(result, blob.data, blob.length);
     719     6759827 :         result[blob.length] = '\0';
     720     6759827 :         return result;
     721             : }
     722             : 
     723     6759193 : 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     6759193 :         if (!asn1_read_OctetString(data, mem_ctx, &string))
     729           0 :                 return false;
     730     6759193 :         *result = blob2string_talloc(mem_ctx, string);
     731     6759193 :         data_blob_free(&string);
     732     6759193 :         return *result ? true : false;
     733             : }
     734             : 
     735      628922 : static bool ldap_decode_response(TALLOC_CTX *mem_ctx,
     736             :                                  struct asn1_data *data,
     737             :                                  struct ldap_Result *result)
     738             : {
     739      628922 :         if (!asn1_read_enumerated(data, &result->resultcode)) return false;
     740      628922 :         if (!asn1_read_OctetString_talloc(mem_ctx, data, &result->dn)) return false;
     741      628922 :         if (!asn1_read_OctetString_talloc(mem_ctx, data, &result->errormessage)) return false;
     742      628922 :         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      628914 :                 result->referral = NULL;
     748             :         }
     749      628176 :         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     1006290 : 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     1006290 :         if (!asn1_peek_uint8(data, &filter_tag)) {
     787           0 :                 return NULL;
     788             :         }
     789             : 
     790     1006290 :         filter_tag &= 0x1f; /* strip off the asn1 stuff */
     791             : 
     792     1006290 :         ret = talloc(mem_ctx, struct ldb_parse_tree);
     793     1006290 :         if (ret == NULL) return NULL;
     794             : 
     795     1006290 :         switch(filter_tag) {
     796      288275 :         case 0:
     797             :         case 1:
     798             :                 /* AND or OR of one or more filters */
     799      288275 :                 ret->operation = (filter_tag == 0)?LDB_OP_AND:LDB_OP_OR;
     800      288275 :                 ret->u.list.num_elements = 0;
     801      288275 :                 ret->u.list.elements = NULL;
     802             : 
     803      288275 :                 if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) {
     804           1 :                         goto failed;
     805             :                 }
     806             : 
     807      911878 :                 while (asn1_tag_remaining(data) > 0) {
     808        1019 :                         struct ldb_parse_tree *subtree;
     809      624115 :                         subtree = ldap_decode_filter_tree(ret, data);
     810      624115 :                         if (subtree == NULL) {
     811         511 :                                 goto failed;
     812             :                         }
     813      624112 :                         ret->u.list.elements = 
     814      623604 :                                 talloc_realloc(ret, ret->u.list.elements, 
     815             :                                                struct ldb_parse_tree *, 
     816             :                                                ret->u.list.num_elements+1);
     817      623604 :                         if (ret->u.list.elements == NULL) {
     818           0 :                                 goto failed;
     819             :                         }
     820      623604 :                         talloc_steal(ret->u.list.elements, subtree);
     821      623604 :                         ret->u.list.elements[ret->u.list.num_elements] = subtree;
     822      623604 :                         ret->u.list.num_elements++;
     823             :                 }
     824      287763 :                 if (!asn1_end_tag(data)) {
     825           0 :                         goto failed;
     826             :                 }
     827      287491 :                 break;
     828             : 
     829       15005 :         case 2:
     830             :                 /* 'not' operation */
     831       15005 :                 if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) {
     832           0 :                         goto failed;
     833             :                 }
     834             : 
     835       15005 :                 ret->operation = LDB_OP_NOT;
     836       15005 :                 ret->u.isnot.child = ldap_decode_filter_tree(ret, data);
     837       15005 :                 if (ret->u.isnot.child == NULL) {
     838           0 :                         goto failed;
     839             :                 }
     840       15005 :                 if (!asn1_end_tag(data)) {
     841           0 :                         goto failed;
     842             :                 }
     843       15005 :                 break;
     844             : 
     845      161077 :         case 3: {
     846             :                 /* equalityMatch */
     847          48 :                 const char *attrib;
     848          48 :                 DATA_BLOB value;
     849             : 
     850      161077 :                 if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) goto failed;
     851      161077 :                 if (!asn1_read_OctetString_talloc(mem_ctx, data, &attrib)) goto failed;
     852      161077 :                 if (!asn1_read_OctetString(data, mem_ctx, &value)) goto failed;
     853      161077 :                 if (!asn1_end_tag(data)) goto failed;
     854      161077 :                 if (asn1_has_error(data) || (attrib == NULL) ||
     855      161077 :                     (value.data == NULL)) {
     856           0 :                         goto failed;
     857             :                 }
     858             : 
     859      161077 :                 ret->operation = LDB_OP_EQUALITY;
     860      161077 :                 ret->u.equality.attr = talloc_steal(ret, attrib);
     861      161077 :                 ret->u.equality.value.data = talloc_steal(ret, value.data);
     862      161077 :                 ret->u.equality.value.length = value.length;
     863      161077 :                 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         243 :         case 6: {
     982             :                 /* lessOrEqual */
     983           0 :                 const char *attrib;
     984           0 :                 DATA_BLOB value;
     985             : 
     986         243 :                 if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) goto failed;
     987         243 :                 if (!asn1_read_OctetString_talloc(mem_ctx, data, &attrib)) goto failed;
     988         243 :                 if (!asn1_read_OctetString(data, mem_ctx, &value)) goto failed;
     989         243 :                 if (!asn1_end_tag(data)) goto failed;
     990         243 :                 if (asn1_has_error(data) || (attrib == NULL) ||
     991         243 :                     (value.data == NULL)) {
     992           0 :                         goto failed;
     993             :                 }
     994             : 
     995         243 :                 ret->operation = LDB_OP_LESS;
     996         243 :                 ret->u.comparison.attr = talloc_steal(ret, attrib);
     997         243 :                 ret->u.comparison.value.data = talloc_steal(ret, value.data);
     998         243 :                 ret->u.comparison.value.length = value.length;
     999         243 :                 break;
    1000             :         }
    1001      508627 :         case 7: {
    1002             :                 /* Normal presence, "attribute=*" */
    1003         597 :                 char *attr;
    1004             : 
    1005      508627 :                 if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(filter_tag))) {
    1006           1 :                         goto failed;
    1007             :                 }
    1008      508626 :                 if (!asn1_read_LDAPString(data, ret, &attr)) {
    1009           0 :                         goto failed;
    1010             :                 }
    1011             : 
    1012      508626 :                 ret->operation = LDB_OP_PRESENT;
    1013      508626 :                 ret->u.present.attr = talloc_steal(ret, attr);
    1014             : 
    1015      508626 :                 if (!asn1_end_tag(data)) {
    1016           0 :                         goto failed;
    1017             :                 }
    1018      508626 :                 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       17804 :         case 9: {
    1041       17804 :                 char *oid = NULL, *attr = NULL, *value;
    1042           0 :                 uint8_t dnAttributes;
    1043             :                 /* an extended search */
    1044       17804 :                 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       17804 :                 if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { /* optional */
    1052       17802 :                         if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(1))) goto failed;
    1053       17802 :                         if (!asn1_read_LDAPString(data, ret, &oid)) goto failed;
    1054       17802 :                         if (!asn1_end_tag(data)) goto failed;
    1055             :                 }
    1056       17804 :                 if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(2))) {      /* optional  */
    1057       17802 :                         if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(2))) goto failed;
    1058       17802 :                         if (!asn1_read_LDAPString(data, ret, &attr)) goto failed;
    1059       17802 :                         if (!asn1_end_tag(data)) goto failed;
    1060             :                 }
    1061       17804 :                 if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(3))) goto failed;
    1062       17804 :                 if (!asn1_read_LDAPString(data, ret, &value)) goto failed;
    1063       17804 :                 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       17804 :                 if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(4))) {
    1071       17804 :                         if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(4))) goto failed;
    1072       17804 :                         if (!asn1_read_uint8(data, &dnAttributes)) goto failed;
    1073       17804 :                         if (!asn1_end_tag(data)) goto failed;
    1074             :                 } else {
    1075           0 :                         dnAttributes = 0;
    1076             :                 }
    1077       17804 :                 if ((oid == NULL && attr == NULL) || (value == NULL)) {
    1078           0 :                         goto failed;
    1079             :                 }
    1080             : 
    1081       17804 :                 if (oid) {
    1082       17802 :                         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       17802 :                         if (attr) {
    1089       17800 :                                 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       17802 :                         ret->u.extended.rule_id      = talloc_steal(ret, oid);
    1097       17802 :                         ret->u.extended.value.data   = (uint8_t *)talloc_steal(ret, value);
    1098       17802 :                         ret->u.extended.value.length = strlen(value);
    1099       17802 :                         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       17804 :                 if (!asn1_end_tag(data)) {
    1107           0 :                         goto failed;
    1108             :                 }
    1109       17804 :                 break;
    1110             :         }
    1111             : 
    1112           0 :         default:
    1113           0 :                 goto failed;
    1114             :         }
    1115             :         
    1116     1004861 :         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     3351127 : static bool ldap_decode_attrib(TALLOC_CTX *mem_ctx, struct asn1_data *data,
    1125             :                                struct ldb_message_element *attrib)
    1126             : {
    1127     3351127 :         if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) return false;
    1128     3351127 :         if (!asn1_read_OctetString_talloc(mem_ctx, data, &attrib->name)) return false;
    1129     3351127 :         if (!asn1_start_tag(data, ASN1_SET)) return false;
    1130     7207246 :         while (asn1_peek_tag(data, ASN1_OCTET_STRING)) {
    1131        1598 :                 DATA_BLOB blob;
    1132     3856119 :                 if (!asn1_read_OctetString(data, mem_ctx, &blob)) return false;
    1133     3856119 :                 add_value_to_attrib(mem_ctx, &blob, attrib);
    1134             :         }
    1135     3351127 :         if (!asn1_end_tag(data)) return false;
    1136     3351127 :         return asn1_end_tag(data);
    1137             : }
    1138             : 
    1139             : /* Decode a set of LDAP attributes, as found in the dereference control */
    1140      702432 : 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     3940563 :         while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) {
    1145        1052 :                 struct ldb_message_element attrib;
    1146     3238131 :                 ZERO_STRUCT(attrib);
    1147     3238131 :                 if (!ldap_decode_attrib(mem_ctx, data, &attrib)) return false;
    1148     3238131 :                 add_attrib_to_array_talloc(mem_ctx, &attrib,
    1149             :                                            attributes, num_attributes);
    1150             :         }
    1151      701953 :         return true;
    1152             : }
    1153             : 
    1154             : /* Decode a set of LDAP attributes, as found in a search entry */
    1155      702432 : 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      702432 :         if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) return false;
    1160      702432 :         if (!ldap_decode_attribs_bare(mem_ctx, data,
    1161           0 :                                  attributes, num_attributes)) return false;
    1162      702432 :         return asn1_end_tag(data);
    1163             : }
    1164             : 
    1165             : /* This routine returns LDAP status codes */
    1166             : 
    1167     2028114 : _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     2028114 :         if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) goto prot_err;
    1175     2028113 :         if (!asn1_read_Integer(data, &msg->messageid)) goto prot_err;
    1176             : 
    1177     2028113 :         if (!asn1_peek_uint8(data, &tag)) goto prot_err;
    1178             : 
    1179     2028113 :         switch(tag) {
    1180             : 
    1181       36024 :         case ASN1_APPLICATION(LDAP_TAG_BindRequest): {
    1182       36024 :                 struct ldap_BindRequest *r = &msg->r.BindRequest;
    1183       36024 :                 msg->type = LDAP_TAG_BindRequest;
    1184       36024 :                 if (!asn1_start_tag(data, tag)) goto prot_err;
    1185       36024 :                 if (!asn1_read_Integer(data, &r->version)) goto prot_err;
    1186       36024 :                 if (!asn1_read_OctetString_talloc(msg, data, &r->dn)) goto prot_err;
    1187       36024 :                 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       35553 :                 } else if (asn1_peek_tag(data, ASN1_CONTEXT(3))){
    1207       35553 :                         if (!asn1_start_tag(data, ASN1_CONTEXT(3))) goto prot_err;
    1208       35553 :                         r->mechanism = LDAP_AUTH_MECH_SASL;
    1209       35553 :                         if (!asn1_read_OctetString_talloc(msg, data, &r->creds.SASL.mechanism)) goto prot_err;
    1210       35553 :                         if (asn1_peek_tag(data, ASN1_OCTET_STRING)) { /* optional */
    1211       35231 :                                 DATA_BLOB tmp_blob = data_blob(NULL, 0);
    1212       35231 :                                 if (!asn1_read_OctetString(data, msg, &tmp_blob)) goto prot_err;
    1213       35231 :                                 r->creds.SASL.secblob = talloc(msg, DATA_BLOB);
    1214       35231 :                                 if (!r->creds.SASL.secblob) {
    1215           0 :                                         return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR);
    1216             :                                 }
    1217       35231 :                                 *r->creds.SASL.secblob = data_blob_talloc(r->creds.SASL.secblob,
    1218             :                                                                           tmp_blob.data, tmp_blob.length);
    1219       35231 :                                 data_blob_free(&tmp_blob);
    1220             :                         } else {
    1221         322 :                                 r->creds.SASL.secblob = NULL;
    1222             :                         }
    1223       35553 :                         if (!asn1_end_tag(data)) goto prot_err;
    1224             :                 } else {
    1225             :                         /* Neither Simple nor SASL bind */
    1226           0 :                         goto prot_err;
    1227             :                 }
    1228       36024 :                 if (!asn1_end_tag(data)) goto prot_err;
    1229       35902 :                 break;
    1230             :         }
    1231             : 
    1232       35226 :         case ASN1_APPLICATION(LDAP_TAG_BindResponse): {
    1233       35226 :                 struct ldap_BindResponse *r = &msg->r.BindResponse;
    1234       35226 :                 msg->type = LDAP_TAG_BindResponse;
    1235       35226 :                 if (!asn1_start_tag(data, tag)) goto prot_err;
    1236       35226 :                 if (!ldap_decode_response(msg, data, &r->response)) goto prot_err;
    1237       35226 :                 if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(7))) {
    1238       34782 :                         DATA_BLOB tmp_blob = data_blob(NULL, 0);
    1239       34782 :                         if (!asn1_read_ContextSimple(data, msg, 7, &tmp_blob)) goto prot_err;
    1240       34782 :                         r->SASL.secblob = talloc(msg, DATA_BLOB);
    1241       34782 :                         if (!r->SASL.secblob) {
    1242           0 :                                 return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR);
    1243             :                         }
    1244       34782 :                         *r->SASL.secblob = data_blob_talloc(r->SASL.secblob,
    1245             :                                                             tmp_blob.data, tmp_blob.length);
    1246       34782 :                         data_blob_free(&tmp_blob);
    1247             :                 } else {
    1248         444 :                         r->SASL.secblob = NULL;
    1249             :                 }
    1250       35226 :                 if (!asn1_end_tag(data)) goto prot_err;
    1251       35104 :                 break;
    1252             :         }
    1253             : 
    1254          18 :         case ASN1_APPLICATION_SIMPLE(LDAP_TAG_UnbindRequest): {
    1255          18 :                 msg->type = LDAP_TAG_UnbindRequest;
    1256          18 :                 if (!asn1_start_tag(data, tag)) goto prot_err;
    1257          18 :                 if (!asn1_end_tag(data)) goto prot_err;
    1258          18 :                 break;
    1259             :         }
    1260             : 
    1261      367174 :         case ASN1_APPLICATION(LDAP_TAG_SearchRequest): {
    1262      367174 :                 struct ldap_SearchRequest *r = &msg->r.SearchRequest;
    1263         410 :                 int sizelimit, timelimit;
    1264      367174 :                 const char **attrs = NULL;
    1265      367174 :                 size_t request_size = asn1_get_length(data);
    1266      367174 :                 msg->type = LDAP_TAG_SearchRequest;
    1267      367174 :                 if (request_size > limits->max_search_size) {
    1268           6 :                         goto prot_err;
    1269             :                 }
    1270      367170 :                 if (!asn1_start_tag(data, tag)) goto prot_err;
    1271      367170 :                 if (!asn1_read_OctetString_talloc(msg, data, &r->basedn)) goto prot_err;
    1272      367170 :                 if (!asn1_read_enumerated(data, (int *)(void *)&(r->scope))) goto prot_err;
    1273      367170 :                 if (!asn1_read_enumerated(data, (int *)(void *)&(r->deref))) goto prot_err;
    1274      367170 :                 if (!asn1_read_Integer(data, &sizelimit)) goto prot_err;
    1275      367170 :                 r->sizelimit = sizelimit;
    1276      367170 :                 if (!asn1_read_Integer(data, &timelimit)) goto prot_err;
    1277      367170 :                 r->timelimit = timelimit;
    1278      367170 :                 if (!asn1_read_BOOLEAN(data, &r->attributesonly)) goto prot_err;
    1279             : 
    1280      367170 :                 r->tree = ldap_decode_filter_tree(msg, data);
    1281      367170 :                 if (r->tree == NULL) {
    1282           2 :                         goto prot_err;
    1283             :                 }
    1284             : 
    1285      367168 :                 if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) goto prot_err;
    1286             : 
    1287      367168 :                 r->num_attributes = 0;
    1288      367168 :                 r->attributes = NULL;
    1289             : 
    1290      995793 :                 while (asn1_tag_remaining(data) > 0) {
    1291             : 
    1292        1036 :                         const char *attr;
    1293      628625 :                         if (!asn1_read_OctetString_talloc(msg, data,
    1294             :                                                           &attr))
    1295           0 :                                 goto prot_err;
    1296      628625 :                         if (!add_string_to_array(msg, attr,
    1297             :                                                  &attrs,
    1298             :                                                  &r->num_attributes))
    1299           0 :                                 goto prot_err;
    1300             :                 }
    1301      367168 :                 r->attributes = attrs;
    1302             : 
    1303      367168 :                 if (!asn1_end_tag(data)) goto prot_err;
    1304      367168 :                 if (!asn1_end_tag(data)) goto prot_err;
    1305      367168 :                 break;
    1306             :         }
    1307             : 
    1308      634900 :         case ASN1_APPLICATION(LDAP_TAG_SearchResultEntry): {
    1309      634900 :                 struct ldap_SearchResEntry *r = &msg->r.SearchResultEntry;
    1310      634900 :                 msg->type = LDAP_TAG_SearchResultEntry;
    1311      634900 :                 r->attributes = NULL;
    1312      634900 :                 r->num_attributes = 0;
    1313      634900 :                 if (!asn1_start_tag(data, tag)) goto prot_err;
    1314      634900 :                 if (!asn1_read_OctetString_talloc(msg, data, &r->dn)) goto prot_err;
    1315      634900 :                 if (!ldap_decode_attribs(msg, data, &r->attributes,
    1316           0 :                                     &r->num_attributes)) goto prot_err;
    1317      634900 :                 if (!asn1_end_tag(data)) goto prot_err;
    1318      634457 :                 break;
    1319             :         }
    1320             : 
    1321      364467 :         case ASN1_APPLICATION(LDAP_TAG_SearchResultDone): {
    1322      364467 :                 struct ldap_Result *r = &msg->r.SearchResultDone;
    1323      364467 :                 msg->type = LDAP_TAG_SearchResultDone;
    1324      364467 :                 if (!asn1_start_tag(data, tag)) goto prot_err;
    1325      364467 :                 if (!ldap_decode_response(msg, data, r)) goto prot_err;
    1326      364467 :                 if (!asn1_end_tag(data)) goto prot_err;
    1327      364060 :                 break;
    1328             :         }
    1329             : 
    1330      131516 :         case ASN1_APPLICATION(LDAP_TAG_SearchResultReference): {
    1331      131516 :                 struct ldap_SearchResRef *r = &msg->r.SearchResultReference;
    1332      131516 :                 msg->type = LDAP_TAG_SearchResultReference;
    1333      131516 :                 if (!asn1_start_tag(data, tag)) goto prot_err;
    1334      131516 :                 if (!asn1_read_OctetString_talloc(msg, data, &r->referral)) goto prot_err;
    1335      131516 :                 if (!asn1_end_tag(data)) goto prot_err;
    1336      131480 :                 break;
    1337             :         }
    1338             : 
    1339       86521 :         case ASN1_APPLICATION(LDAP_TAG_ModifyRequest): {
    1340       86521 :                 struct ldap_ModifyRequest *r = &msg->r.ModifyRequest;
    1341       86521 :                 msg->type = LDAP_TAG_ModifyRequest;
    1342       86521 :                 if (!asn1_start_tag(data, ASN1_APPLICATION(LDAP_TAG_ModifyRequest))) goto prot_err;
    1343       86521 :                 if (!asn1_read_OctetString_talloc(msg, data, &r->dn)) goto prot_err;
    1344       86521 :                 if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) goto prot_err;
    1345             : 
    1346       86521 :                 r->num_mods = 0;
    1347       86521 :                 r->mods = NULL;
    1348             : 
    1349      199517 :                 while (asn1_tag_remaining(data) > 0) {
    1350         216 :                         struct ldap_mod mod;
    1351         216 :                         int v;
    1352      112996 :                         ZERO_STRUCT(mod);
    1353      112996 :                         if (!asn1_start_tag(data, ASN1_SEQUENCE(0))) goto prot_err;
    1354      112996 :                         if (!asn1_read_enumerated(data, &v)) goto prot_err;
    1355      112996 :                         mod.type = v;
    1356      112996 :                         if (!ldap_decode_attrib(msg, data, &mod.attrib)) goto prot_err;
    1357      112996 :                         if (!asn1_end_tag(data)) goto prot_err;
    1358      112996 :                         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       86521 :                 if (!asn1_end_tag(data)) goto prot_err;
    1365       86521 :                 if (!asn1_end_tag(data)) goto prot_err;
    1366       86377 :                 break;
    1367             :         }
    1368             : 
    1369       86369 :         case ASN1_APPLICATION(LDAP_TAG_ModifyResponse): {
    1370       86369 :                 struct ldap_Result *r = &msg->r.ModifyResponse;
    1371       86369 :                 msg->type = LDAP_TAG_ModifyResponse;
    1372       86369 :                 if (!asn1_start_tag(data, tag)) goto prot_err;
    1373       86369 :                 if (!ldap_decode_response(msg, data, r)) goto prot_err;
    1374       86369 :                 if (!asn1_end_tag(data)) goto prot_err;
    1375       86225 :                 break;
    1376             :         }
    1377             : 
    1378       67532 :         case ASN1_APPLICATION(LDAP_TAG_AddRequest): {
    1379       67532 :                 struct ldap_AddRequest *r = &msg->r.AddRequest;
    1380       67532 :                 msg->type = LDAP_TAG_AddRequest;
    1381       67532 :                 if (!asn1_start_tag(data, tag)) goto prot_err;
    1382       67532 :                 if (!asn1_read_OctetString_talloc(msg, data, &r->dn)) goto prot_err;
    1383             : 
    1384       67532 :                 r->attributes = NULL;
    1385       67532 :                 r->num_attributes = 0;
    1386       67532 :                 if (!ldap_decode_attribs(msg, data, &r->attributes,
    1387           0 :                                     &r->num_attributes)) goto prot_err;
    1388             : 
    1389       67532 :                 if (!asn1_end_tag(data)) goto prot_err;
    1390       67496 :                 break;
    1391             :         }
    1392             : 
    1393       67472 :         case ASN1_APPLICATION(LDAP_TAG_AddResponse): {
    1394       67472 :                 struct ldap_Result *r = &msg->r.AddResponse;
    1395       67472 :                 msg->type = LDAP_TAG_AddResponse;
    1396       67472 :                 if (!asn1_start_tag(data, tag)) goto prot_err;
    1397       67472 :                 if (!ldap_decode_response(msg, data, r)) goto prot_err;
    1398       67472 :                 if (!asn1_end_tag(data)) goto prot_err;
    1399       67436 :                 break;
    1400             :         }
    1401             : 
    1402       74721 :         case ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest): {
    1403       74721 :                 struct ldap_DelRequest *r = &msg->r.DelRequest;
    1404          36 :                 int len;
    1405          36 :                 char *dn;
    1406       74721 :                 msg->type = LDAP_TAG_DelRequest;
    1407       74721 :                 if (!asn1_start_tag(data,
    1408           0 :                                ASN1_APPLICATION_SIMPLE(LDAP_TAG_DelRequest))) goto prot_err;
    1409       74721 :                 len = asn1_tag_remaining(data);
    1410       74721 :                 if (len == -1) {
    1411           0 :                         goto prot_err;
    1412             :                 }
    1413       74721 :                 dn = talloc_array(msg, char, len+1);
    1414       74721 :                 if (dn == NULL)
    1415           0 :                         break;
    1416       74721 :                 if (!asn1_read(data, dn, len)) goto prot_err;
    1417       74721 :                 dn[len] = '\0';
    1418       74721 :                 r->dn = dn;
    1419       74721 :                 if (!asn1_end_tag(data)) goto prot_err;
    1420       74685 :                 break;
    1421             :         }
    1422             : 
    1423       74681 :         case ASN1_APPLICATION(LDAP_TAG_DelResponse): {
    1424       74681 :                 struct ldap_Result *r = &msg->r.DelResponse;
    1425       74681 :                 msg->type = LDAP_TAG_DelResponse;
    1426       74681 :                 if (!asn1_start_tag(data, tag)) goto prot_err;
    1427       74681 :                 if (!ldap_decode_response(msg, data, r)) goto prot_err;
    1428       74681 :                 if (!asn1_end_tag(data)) goto prot_err;
    1429       74645 :                 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     2028107 :         msg->controls = NULL;
    1578     2028107 :         msg->controls_decoded = NULL;
    1579             : 
    1580     2028107 :         if (asn1_peek_tag(data, ASN1_CONTEXT(0))) {
    1581      296733 :                 int i = 0;
    1582      296733 :                 struct ldb_control **ctrl = NULL;
    1583      296733 :                 bool *decoded = NULL;
    1584             : 
    1585      296733 :                 if (!asn1_start_tag(data, ASN1_CONTEXT(0))) goto prot_err;
    1586             : 
    1587      697481 :                 while (asn1_peek_tag(data, ASN1_SEQUENCE(0))) {
    1588           0 :                         DATA_BLOB value;
    1589             :                         /* asn1_start_tag(data, ASN1_SEQUENCE(0)); */
    1590             : 
    1591      400748 :                         ctrl = talloc_realloc(msg, ctrl, struct ldb_control *, i+2);
    1592      400748 :                         if (!ctrl) {
    1593           0 :                                 return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR);
    1594             :                         }
    1595             : 
    1596      400748 :                         decoded = talloc_realloc(msg, decoded, bool, i+1);
    1597      400748 :                         if (!decoded) {
    1598           0 :                                 return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR);
    1599             :                         }
    1600             : 
    1601      400748 :                         ctrl[i] = talloc(ctrl, struct ldb_control);
    1602      400748 :                         if (!ctrl[i]) {
    1603           0 :                                 return NT_STATUS_LDAP(LDAP_OPERATIONS_ERROR);
    1604             :                         }
    1605             : 
    1606      400748 :                         if (!ldap_decode_control_wrapper(ctrl[i], data, ctrl[i], &value)) {
    1607           0 :                                 goto prot_err;
    1608             :                         }
    1609             : 
    1610      400748 :                         if (!ldap_decode_control_value(ctrl[i], value,
    1611             :                                                        control_handlers,
    1612      400748 :                                                        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      400748 :                                 decoded[i] = true;
    1623      400748 :                                 i++;
    1624             :                         }
    1625             :                 }
    1626             : 
    1627      296733 :                 if (ctrl != NULL) {
    1628      296733 :                         ctrl[i] = NULL;
    1629             :                 }
    1630             : 
    1631      296733 :                 msg->controls = ctrl;
    1632      296733 :                 msg->controls_decoded = decoded;
    1633             : 
    1634      296733 :                 if (!asn1_end_tag(data)) goto prot_err;
    1635             :         }
    1636             : 
    1637     2028107 :         if (!asn1_end_tag(data)) goto prot_err;
    1638     2028107 :         if (asn1_has_error(data) || asn1_has_nesting(data)) {
    1639           0 :                 return NT_STATUS_LDAP(LDAP_PROTOCOL_ERROR);
    1640             :         }
    1641     2028107 :         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     4038231 : 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     4038231 :         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     4038231 :         ret = asn1_peek_full_tag(blob, ASN1_SEQUENCE(0), packet_size);
    1669     4038231 :         if (ret != 0) {
    1670     2019106 :                 return map_nt_error_from_unix_common(ret);
    1671             :         }
    1672     2019125 :         return NT_STATUS_OK;
    1673             : }

Generated by: LCOV version 1.14