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

Generated by: LCOV version 1.13