LCOV - code coverage report
Current view: top level - source3/smbd - smb2_negprot.c (source / functions) Hit Total Coverage
Test: coverage report for support-claim-type-attributes 6b5c566e Lines: 498 571 87.2 %
Date: 2023-11-21 12:31:41 Functions: 8 8 100.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    Core SMB2 server
       4             : 
       5             :    Copyright (C) Stefan Metzmacher 2009
       6             : 
       7             :    This program is free software; you can redistribute it and/or modify
       8             :    it under the terms of the GNU General Public License as published by
       9             :    the Free Software Foundation; either version 3 of the License, or
      10             :    (at your option) any later version.
      11             : 
      12             :    This program is distributed in the hope that it will be useful,
      13             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :    GNU General Public License for more details.
      16             : 
      17             :    You should have received a copy of the GNU General Public License
      18             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : #include "includes.h"
      22             : #include "smbd/smbd.h"
      23             : #include "smbd/globals.h"
      24             : #include "../libcli/smb/smb_common.h"
      25             : #include "../libcli/smb/smb2_negotiate_context.h"
      26             : #include "../lib/tsocket/tsocket.h"
      27             : #include "../librpc/ndr/libndr.h"
      28             : #include "../libcli/smb/smb_signing.h"
      29             : #include "auth.h"
      30             : #include "auth/gensec/gensec.h"
      31             : #include "lib/util/string_wrappers.h"
      32             : #include "source3/lib/substitute.h"
      33             : #ifdef HAVE_VALGRIND_CALLGRIND_H
      34             : #include <valgrind/callgrind.h>
      35             : #endif /* HAVE_VALGRIND_CALLGRIND_H */
      36             : 
      37             : #undef DBGC_CLASS
      38             : #define DBGC_CLASS DBGC_SMB2
      39             : 
      40             : /*
      41             :  * this is the entry point if SMB2 is selected via
      42             :  * the SMB negprot and the given dialect.
      43             :  */
      44       16259 : static NTSTATUS reply_smb20xx(struct smb_request *req, uint16_t dialect)
      45             : {
      46         390 :         uint8_t *smb2_inpdu;
      47         390 :         uint8_t *smb2_hdr;
      48         390 :         uint8_t *smb2_body;
      49         390 :         uint8_t *smb2_dyn;
      50       16259 :         size_t len = SMB2_HDR_BODY + 0x24 + 2;
      51             : 
      52       16259 :         smb2_inpdu = talloc_zero_array(talloc_tos(), uint8_t, len);
      53       16259 :         if (smb2_inpdu == NULL) {
      54           0 :                 DEBUG(0, ("Could not push spnego blob\n"));
      55           0 :                 reply_nterror(req, NT_STATUS_NO_MEMORY);
      56           0 :                 return NT_STATUS_NO_MEMORY;
      57             :         }
      58       16259 :         smb2_hdr = smb2_inpdu;
      59       16259 :         smb2_body = smb2_hdr + SMB2_HDR_BODY;
      60       16259 :         smb2_dyn = smb2_body + 0x24;
      61             : 
      62       16259 :         SIVAL(smb2_hdr, SMB2_HDR_PROTOCOL_ID,   SMB2_MAGIC);
      63       16259 :         SIVAL(smb2_hdr, SMB2_HDR_LENGTH,        SMB2_HDR_BODY);
      64             : 
      65       16259 :         SSVAL(smb2_body, 0x00, 0x0024); /* struct size */
      66       16259 :         SSVAL(smb2_body, 0x02, 0x0001); /* dialect count */
      67             : 
      68       16259 :         SSVAL(smb2_dyn,  0x00, dialect);
      69             : 
      70       16259 :         req->outbuf = NULL;
      71             : 
      72       16259 :         return smbd_smb2_process_negprot(req->xconn, 0, smb2_inpdu, len);
      73             : }
      74             : 
      75             : /*
      76             :  * this is the entry point if SMB2 is selected via
      77             :  * the SMB negprot and the "SMB 2.002" dialect.
      78             :  */
      79          36 : NTSTATUS reply_smb2002(struct smb_request *req, uint16_t choice)
      80             : {
      81          36 :         return reply_smb20xx(req, SMB2_DIALECT_REVISION_202);
      82             : }
      83             : 
      84             : /*
      85             :  * this is the entry point if SMB2 is selected via
      86             :  * the SMB negprot and the "SMB 2.???" dialect.
      87             :  */
      88       16223 : NTSTATUS reply_smb20ff(struct smb_request *req, uint16_t choice)
      89             : {
      90       16223 :         struct smbXsrv_connection *xconn = req->xconn;
      91       16223 :         xconn->smb2.allow_2ff = true;
      92       16223 :         return reply_smb20xx(req, SMB2_DIALECT_REVISION_2FF);
      93             : }
      94             : 
      95       44874 : enum protocol_types smbd_smb2_protocol_dialect_match(const uint8_t *indyn,
      96             :                                 const int dialect_count,
      97             :                                 uint16_t *dialect)
      98             : {
      99        1165 :         struct {
     100             :                 enum protocol_types proto;
     101             :                 uint16_t dialect;
     102       44874 :         } pd[] = {
     103             :                 { PROTOCOL_SMB3_11, SMB3_DIALECT_REVISION_311 },
     104             :                 { PROTOCOL_SMB3_02, SMB3_DIALECT_REVISION_302 },
     105             :                 { PROTOCOL_SMB3_00, SMB3_DIALECT_REVISION_300 },
     106             :                 { PROTOCOL_SMB2_10, SMB2_DIALECT_REVISION_210 },
     107             :                 { PROTOCOL_SMB2_02, SMB2_DIALECT_REVISION_202 },
     108             :         };
     109        1165 :         size_t i;
     110             : 
     111      141775 :         for (i = 0; i < ARRAY_SIZE(pd); i ++) {
     112      125552 :                 int c = 0;
     113             : 
     114      125552 :                 if (lp_server_max_protocol() < pd[i].proto) {
     115       18428 :                         continue;
     116             :                 }
     117      107124 :                 if (lp_server_min_protocol() > pd[i].proto) {
     118          11 :                         continue;
     119             :                 }
     120             : 
     121      279949 :                 for (c = 0; c < dialect_count; c++) {
     122      201487 :                         *dialect = SVAL(indyn, c*2);
     123      201487 :                         if (*dialect == pd[i].dialect) {
     124       28651 :                                 return pd[i].proto;
     125             :                         }
     126             :                 }
     127             :         }
     128             : 
     129       15833 :         return PROTOCOL_NONE;
     130             : }
     131             : 
     132             : struct smbd_smb2_request_process_negprot_state {
     133             :         struct smbd_smb2_request *req;
     134             :         DATA_BLOB outbody;
     135             :         DATA_BLOB outdyn;
     136             : };
     137             : 
     138             : static void smbd_smb2_request_process_negprot_mc_done(struct tevent_req *subreq);
     139             : 
     140       42200 : NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
     141             : {
     142       42200 :         struct smbd_smb2_request_process_negprot_state *state = NULL;
     143       42200 :         struct smbXsrv_connection *xconn = req->xconn;
     144       42200 :         struct tevent_req *subreq = NULL;
     145        1143 :         NTSTATUS status;
     146        1143 :         const uint8_t *inbody;
     147       42200 :         const uint8_t *indyn = NULL;
     148        1143 :         DATA_BLOB outbody;
     149        1143 :         DATA_BLOB outdyn;
     150        1143 :         DATA_BLOB negprot_spnego_blob;
     151        1143 :         uint16_t security_offset;
     152        1143 :         DATA_BLOB security_buffer;
     153       42200 :         size_t expected_dyn_size = 0;
     154        1143 :         size_t c;
     155        1143 :         uint16_t security_mode;
     156        1143 :         uint16_t dialect_count;
     157        1143 :         uint16_t in_security_mode;
     158        1143 :         uint32_t in_capabilities;
     159        1143 :         DATA_BLOB in_guid_blob;
     160        1143 :         struct GUID in_guid;
     161       42200 :         struct smb2_negotiate_contexts in_c = { .num_contexts = 0, };
     162       42200 :         struct smb2_negotiate_context *in_preauth = NULL;
     163       42200 :         struct smb2_negotiate_context *in_cipher = NULL;
     164       42200 :         struct smb2_negotiate_context *in_sign_algo = NULL;
     165       42200 :         struct smb2_negotiate_contexts out_c = { .num_contexts = 0, };
     166       42200 :         struct smb2_negotiate_context *in_posix = NULL;
     167        1143 :         const struct smb311_capabilities default_smb3_capabilities =
     168       42200 :                 smb311_capabilities_parse("server",
     169       42200 :                         lp_server_smb3_signing_algorithms(),
     170       42200 :                         lp_server_smb3_encryption_algorithms());
     171       42200 :         DATA_BLOB out_negotiate_context_blob = data_blob_null;
     172       42200 :         uint32_t out_negotiate_context_offset = 0;
     173       42200 :         uint16_t out_negotiate_context_count = 0;
     174       42200 :         uint16_t dialect = 0;
     175        1143 :         uint32_t capabilities;
     176        1143 :         DATA_BLOB out_guid_blob;
     177        1143 :         struct GUID out_guid;
     178       42200 :         enum protocol_types protocol = PROTOCOL_NONE;
     179        1143 :         uint32_t max_limit;
     180       42200 :         uint32_t max_trans = lp_smb2_max_trans();
     181       42200 :         uint32_t max_read = lp_smb2_max_read();
     182       42200 :         uint32_t max_write = lp_smb2_max_write();
     183       42200 :         NTTIME now = timeval_to_nttime(&req->request_time);
     184        1143 :         bool ok;
     185             : 
     186       42200 :         status = smbd_smb2_request_verify_sizes(req, 0x24);
     187       42200 :         if (!NT_STATUS_IS_OK(status)) {
     188           0 :                 return smbd_smb2_request_error(req, status);
     189             :         }
     190       42200 :         inbody = SMBD_SMB2_IN_BODY_PTR(req);
     191             : 
     192       42200 :         dialect_count = SVAL(inbody, 0x02);
     193             : 
     194       42200 :         in_security_mode = SVAL(inbody, 0x04);
     195       42200 :         in_capabilities = IVAL(inbody, 0x08);
     196       42200 :         in_guid_blob = data_blob_const(inbody + 0x0C, 16);
     197             : 
     198       42200 :         if (dialect_count == 0) {
     199           0 :                 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
     200             :         }
     201             : 
     202       42200 :         status = GUID_from_ndr_blob(&in_guid_blob, &in_guid);
     203       42200 :         if (!NT_STATUS_IS_OK(status)) {
     204           0 :                 return smbd_smb2_request_error(req, status);
     205             :         }
     206             : 
     207       42200 :         expected_dyn_size = dialect_count * 2;
     208       42200 :         if (SMBD_SMB2_IN_DYN_LEN(req) < expected_dyn_size) {
     209           0 :                 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
     210             :         }
     211       42200 :         indyn = SMBD_SMB2_IN_DYN_PTR(req);
     212             : 
     213       42200 :         protocol = smbd_smb2_protocol_dialect_match(indyn,
     214             :                                         dialect_count,
     215             :                                         &dialect);
     216             : 
     217       43343 :         for (c=0; protocol == PROTOCOL_NONE && c < dialect_count; c++) {
     218       16223 :                 if (lp_server_max_protocol() < PROTOCOL_SMB2_10) {
     219           0 :                         break;
     220             :                 }
     221             : 
     222       16223 :                 dialect = SVAL(indyn, c*2);
     223       16223 :                 if (dialect == SMB2_DIALECT_REVISION_2FF) {
     224       16223 :                         if (xconn->smb2.allow_2ff) {
     225       16223 :                                 xconn->smb2.allow_2ff = false;
     226       16223 :                                 protocol = PROTOCOL_SMB2_10;
     227       16223 :                                 break;
     228             :                         }
     229             :                 }
     230             :         }
     231             : 
     232       42200 :         if (protocol == PROTOCOL_NONE) {
     233           0 :                 return smbd_smb2_request_error(req, NT_STATUS_NOT_SUPPORTED);
     234             :         }
     235             : 
     236       42200 :         if (protocol >= PROTOCOL_SMB3_11) {
     237       23289 :                 uint32_t in_negotiate_context_offset = 0;
     238       23289 :                 uint16_t in_negotiate_context_count = 0;
     239       23289 :                 DATA_BLOB in_negotiate_context_blob = data_blob_null;
     240         705 :                 size_t ofs;
     241             : 
     242       23289 :                 in_negotiate_context_offset = IVAL(inbody, 0x1C);
     243       23289 :                 in_negotiate_context_count = SVAL(inbody, 0x20);
     244             : 
     245       23289 :                 ofs = SMB2_HDR_BODY;
     246       23289 :                 ofs += SMBD_SMB2_IN_BODY_LEN(req);
     247       23289 :                 ofs += expected_dyn_size;
     248       23289 :                 if ((ofs % 8) != 0) {
     249       23289 :                         ofs += 8 - (ofs % 8);
     250             :                 }
     251             : 
     252       23289 :                 if (in_negotiate_context_offset != ofs) {
     253           0 :                         return smbd_smb2_request_error(req,
     254             :                                         NT_STATUS_INVALID_PARAMETER);
     255             :                 }
     256             : 
     257       23289 :                 ofs -= SMB2_HDR_BODY;
     258       23289 :                 ofs -= SMBD_SMB2_IN_BODY_LEN(req);
     259             : 
     260       23289 :                 if (SMBD_SMB2_IN_DYN_LEN(req) < ofs) {
     261           0 :                         return smbd_smb2_request_error(req,
     262             :                                         NT_STATUS_INVALID_PARAMETER);
     263             :                 }
     264             : 
     265       23289 :                 in_negotiate_context_blob = data_blob_const(indyn,
     266       22584 :                                                 SMBD_SMB2_IN_DYN_LEN(req));
     267             : 
     268       23289 :                 in_negotiate_context_blob.data += ofs;
     269       23289 :                 in_negotiate_context_blob.length -= ofs;
     270             : 
     271       23289 :                 status = smb2_negotiate_context_parse(req,
     272             :                                                       in_negotiate_context_blob,
     273             :                                                       in_negotiate_context_count,
     274             :                                                       &in_c);
     275       23289 :                 if (!NT_STATUS_IS_OK(status)) {
     276           0 :                         return smbd_smb2_request_error(req, status);
     277             :                 }
     278             : 
     279       23289 :                 in_posix = smb2_negotiate_context_find(
     280             :                         &in_c,
     281             :                         SMB2_POSIX_EXTENSIONS_AVAILABLE);
     282             : 
     283       23289 :                 if (in_posix != NULL) {
     284        8037 :                         const uint8_t *inbuf = in_posix->data.data;
     285        8037 :                         size_t inbuflen = in_posix->data.length;
     286        8037 :                         bool posix_found = false;
     287             :                         /*
     288             :                          * For now the server only supports one variant.
     289             :                          * Check it's the right one.
     290             :                          */
     291        8037 :                         if ((inbuflen % 16) != 0) {
     292           2 :                                 return smbd_smb2_request_error(
     293             :                                         req,
     294             :                                         NT_STATUS_INVALID_PARAMETER);
     295             :                         }
     296             :                         SMB_ASSERT(strlen(SMB2_CREATE_TAG_POSIX) == 16);
     297        8037 :                         for (ofs = 0; ofs < inbuflen; ofs += 16) {
     298        8035 :                                 if (memcmp(inbuf + ofs,
     299             :                                            SMB2_CREATE_TAG_POSIX,
     300             :                                            16) == 0) {
     301        8033 :                                         posix_found = true;
     302        8033 :                                         break;
     303             :                                 }
     304             :                         }
     305        8035 :                         if (posix_found) {
     306        8033 :                                 DBG_DEBUG("Client requested SMB2 unix "
     307             :                                           "extensions\n");
     308             :                         } else {
     309           2 :                                 DBG_DEBUG("Client requested unknown "
     310             :                                           "SMB2 unix extensions:\n");
     311           2 :                                 dump_data(10, inbuf, inbuflen);
     312           2 :                                 in_posix = NULL;
     313             :                         }
     314             :                 }
     315             :         }
     316             : 
     317       42198 :         if ((dialect != SMB2_DIALECT_REVISION_2FF) &&
     318       25893 :             (protocol >= PROTOCOL_SMB2_10) &&
     319       25893 :             !GUID_all_zero(&in_guid))
     320             :         {
     321       25889 :                 ok = remote_arch_cache_update(&in_guid);
     322       25889 :                 if (!ok) {
     323           0 :                         return smbd_smb2_request_error(
     324             :                                 req, NT_STATUS_UNSUCCESSFUL);
     325             :                 }
     326             :         }
     327             : 
     328       42198 :         switch (get_remote_arch()) {
     329       17930 :         case RA_VISTA:
     330             :         case RA_SAMBA:
     331             :         case RA_CIFSFS:
     332             :         case RA_OSX:
     333       17930 :                 break;
     334       23816 :         default:
     335       23816 :                 set_remote_arch(RA_VISTA);
     336       23816 :                 break;
     337             :         }
     338             : 
     339             :         {
     340        1143 :                 fstring proto;
     341       42198 :                 fstr_sprintf(proto,
     342             :                              "SMB%X_%02X",
     343             :                              (dialect >> 8) & 0xFF, dialect & 0xFF);
     344       42198 :                 set_remote_proto(proto);
     345       42198 :                 DEBUG(3,("Selected protocol %s\n", proto));
     346             :         }
     347             : 
     348       42198 :         reload_services(req->sconn, conn_snum_used, true);
     349             : 
     350       42198 :         in_preauth = smb2_negotiate_context_find(&in_c,
     351             :                                         SMB2_PREAUTH_INTEGRITY_CAPABILITIES);
     352       42198 :         if (protocol >= PROTOCOL_SMB3_11 && in_preauth == NULL) {
     353           0 :                 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
     354             :         }
     355       42198 :         in_cipher = smb2_negotiate_context_find(&in_c,
     356             :                                         SMB2_ENCRYPTION_CAPABILITIES);
     357       42198 :         in_sign_algo = smb2_negotiate_context_find(&in_c,
     358             :                                         SMB2_SIGNING_CAPABILITIES);
     359             : 
     360             :         /* negprot_spnego() returns the server guid in the first 16 bytes */
     361       42198 :         negprot_spnego_blob = negprot_spnego(req, xconn);
     362       42198 :         if (negprot_spnego_blob.data == NULL) {
     363           0 :                 return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
     364             :         }
     365             : 
     366       42198 :         if (negprot_spnego_blob.length < 16) {
     367           0 :                 return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
     368             :         }
     369             : 
     370       42198 :         security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED;
     371       42198 :         if (xconn->smb2.signing_mandatory) {
     372       13924 :                 security_mode |= SMB2_NEGOTIATE_SIGNING_REQUIRED;
     373             :         }
     374             : 
     375       42198 :         capabilities = 0;
     376       42198 :         if (lp_host_msdfs()) {
     377       42198 :                 capabilities |= SMB2_CAP_DFS;
     378             :         }
     379             : 
     380       84314 :         if (protocol >= PROTOCOL_SMB2_10 &&
     381       74455 :             lp_smb2_leases() &&
     382       32339 :             lp_oplocks(GLOBAL_SECTION_SNUM) &&
     383       32339 :             !lp_kernel_oplocks(GLOBAL_SECTION_SNUM))
     384             :         {
     385       32339 :                 capabilities |= SMB2_CAP_LEASING;
     386             :         }
     387             : 
     388       65601 :         if ((protocol >= PROTOCOL_SMB3_00) &&
     389       23403 :             (lp_server_smb_encrypt(-1) != SMB_ENCRYPTION_OFF) &&
     390       23179 :             (in_capabilities & SMB2_CAP_ENCRYPTION)) {
     391       23179 :                 capabilities |= SMB2_CAP_ENCRYPTION;
     392             :         }
     393             : 
     394             :         /*
     395             :          * 0x10000 (65536) is the maximum allowed message size
     396             :          * for SMB 2.0
     397             :          */
     398       42198 :         max_limit = 0x10000;
     399             : 
     400       42198 :         if (protocol >= PROTOCOL_SMB2_10) {
     401       42116 :                 int p = 0;
     402             : 
     403       42116 :                 if (tsocket_address_is_inet(req->sconn->local_address, "ip")) {
     404       42116 :                         p = tsocket_address_inet_port(req->sconn->local_address);
     405             :                 }
     406             : 
     407             :                 /* largeMTU is not supported over NBT (tcp port 139) */
     408       42116 :                 if (p != NBT_SMB_PORT) {
     409       40533 :                         capabilities |= SMB2_CAP_LARGE_MTU;
     410       40533 :                         xconn->smb2.credits.multicredit = true;
     411             : 
     412             :                         /*
     413             :                          * We allow up to almost 16MB.
     414             :                          *
     415             :                          * The maximum PDU size is 0xFFFFFF (16776960)
     416             :                          * and we need some space for the header.
     417             :                          */
     418       40533 :                         max_limit = 0xFFFF00;
     419             :                 }
     420             :         }
     421             : 
     422             :         /*
     423             :          * the defaults are 8MB, but we'll limit this to max_limit based on
     424             :          * the dialect (64kb for SMB 2.0, 8MB for SMB >= 2.1 with LargeMTU)
     425             :          *
     426             :          * user configured values exceeding the limits will be overwritten,
     427             :          * only smaller values will be accepted
     428             :          */
     429             : 
     430       42198 :         max_trans = MIN(max_limit, lp_smb2_max_trans());
     431       42198 :         max_read = MIN(max_limit, lp_smb2_max_read());
     432       42198 :         max_write = MIN(max_limit, lp_smb2_max_write());
     433             : 
     434       42198 :         if (in_preauth != NULL) {
     435       23287 :                 size_t needed = 4;
     436         705 :                 uint16_t hash_count;
     437         705 :                 uint16_t salt_length;
     438       23287 :                 uint16_t selected_preauth = 0;
     439         705 :                 const uint8_t *p;
     440         705 :                 uint8_t buf[38];
     441         705 :                 size_t i;
     442             : 
     443       23287 :                 if (in_preauth->data.length < needed) {
     444           0 :                         return smbd_smb2_request_error(req,
     445             :                                         NT_STATUS_INVALID_PARAMETER);
     446             :                 }
     447             : 
     448       23287 :                 hash_count = SVAL(in_preauth->data.data, 0);
     449       23287 :                 salt_length = SVAL(in_preauth->data.data, 2);
     450             : 
     451       23287 :                 if (hash_count == 0) {
     452           0 :                         return smbd_smb2_request_error(req,
     453             :                                         NT_STATUS_INVALID_PARAMETER);
     454             :                 }
     455             : 
     456       23287 :                 p = in_preauth->data.data + needed;
     457       23287 :                 needed += hash_count * 2;
     458       23287 :                 needed += salt_length;
     459             : 
     460       23287 :                 if (in_preauth->data.length < needed) {
     461           0 :                         return smbd_smb2_request_error(req,
     462             :                                         NT_STATUS_INVALID_PARAMETER);
     463             :                 }
     464             : 
     465       23287 :                 for (i=0; i < hash_count; i++) {
     466         705 :                         uint16_t v;
     467             : 
     468       23287 :                         v = SVAL(p, 0);
     469       23287 :                         p += 2;
     470             : 
     471       23287 :                         if (v == SMB2_PREAUTH_INTEGRITY_SHA512) {
     472       22582 :                                 selected_preauth = v;
     473       22582 :                                 break;
     474             :                         }
     475             :                 }
     476             : 
     477       23287 :                 if (selected_preauth == 0) {
     478           0 :                         return smbd_smb2_request_error(req,
     479             :                                 NT_STATUS_SMB_NO_PREAUTH_INTEGRITY_HASH_OVERLAP);
     480             :                 }
     481             : 
     482       23287 :                 SSVAL(buf, 0,  1); /* HashAlgorithmCount */
     483       23287 :                 SSVAL(buf, 2, 32); /* SaltLength */
     484       23287 :                 SSVAL(buf, 4, selected_preauth);
     485       23287 :                 generate_random_buffer(buf + 6, 32);
     486             : 
     487       23287 :                 status = smb2_negotiate_context_add(
     488             :                         req,
     489             :                         &out_c,
     490             :                         SMB2_PREAUTH_INTEGRITY_CAPABILITIES,
     491             :                         buf,
     492             :                         sizeof(buf));
     493       23287 :                 if (!NT_STATUS_IS_OK(status)) {
     494           0 :                         return smbd_smb2_request_error(req, status);
     495             :                 }
     496             : 
     497       23287 :                 req->preauth = &req->xconn->smb2.preauth;
     498             :         }
     499             : 
     500       42198 :         if (protocol >= PROTOCOL_SMB3_00) {
     501       23403 :                 xconn->smb2.server.sign_algo = SMB2_SIGNING_AES128_CMAC;
     502             :         } else {
     503       18795 :                 xconn->smb2.server.sign_algo = SMB2_SIGNING_HMAC_SHA256;
     504             :         }
     505             : 
     506       42198 :         if ((capabilities & SMB2_CAP_ENCRYPTION) && (in_cipher != NULL)) {
     507       23075 :                 const struct smb3_encryption_capabilities *srv_ciphers =
     508             :                         &default_smb3_capabilities.encryption;
     509       23075 :                 uint16_t srv_preferred_idx = UINT16_MAX;
     510       23075 :                 size_t needed = 2;
     511         705 :                 uint16_t cipher_count;
     512         705 :                 const uint8_t *p;
     513         705 :                 uint8_t buf[4];
     514         705 :                 size_t i;
     515             : 
     516       23075 :                 capabilities &= ~SMB2_CAP_ENCRYPTION;
     517             : 
     518       23075 :                 if (in_cipher->data.length < needed) {
     519           0 :                         return smbd_smb2_request_error(req,
     520             :                                         NT_STATUS_INVALID_PARAMETER);
     521             :                 }
     522             : 
     523       23075 :                 cipher_count = SVAL(in_cipher->data.data, 0);
     524       23075 :                 if (cipher_count == 0) {
     525           0 :                         return smbd_smb2_request_error(req,
     526             :                                         NT_STATUS_INVALID_PARAMETER);
     527             :                 }
     528             : 
     529       23075 :                 p = in_cipher->data.data + needed;
     530       23075 :                 needed += cipher_count * 2;
     531             : 
     532       23075 :                 if (in_cipher->data.length < needed) {
     533           0 :                         return smbd_smb2_request_error(req,
     534             :                                         NT_STATUS_INVALID_PARAMETER);
     535             :                 }
     536             : 
     537      114331 :                 for (i=0; i < cipher_count; i++) {
     538        2646 :                         uint16_t si;
     539        2646 :                         uint16_t v;
     540             : 
     541       91256 :                         v = SVAL(p, 0);
     542       91256 :                         p += 2;
     543             : 
     544      227846 :                         for (si = 0; si < srv_ciphers->num_algos; si++) {
     545      227846 :                                 if (srv_ciphers->algos[si] != v) {
     546      136590 :                                         continue;
     547             :                                 }
     548             : 
     549             :                                 /*
     550             :                                  * The server ciphers are listed
     551             :                                  * with the lowest idx being preferred.
     552             :                                  */
     553       91256 :                                 if (si < srv_preferred_idx) {
     554       22370 :                                         srv_preferred_idx = si;
     555             :                                 }
     556       88610 :                                 break;
     557             :                         }
     558             :                 }
     559             : 
     560       23075 :                 if (srv_preferred_idx != UINT16_MAX) {
     561       23075 :                         xconn->smb2.server.cipher =
     562       23075 :                                 srv_ciphers->algos[srv_preferred_idx];
     563             :                 }
     564             : 
     565       23075 :                 SSVAL(buf, 0, 1); /* ChiperCount */
     566       23075 :                 SSVAL(buf, 2, xconn->smb2.server.cipher);
     567             : 
     568       23075 :                 status = smb2_negotiate_context_add(
     569             :                         req,
     570             :                         &out_c,
     571             :                         SMB2_ENCRYPTION_CAPABILITIES,
     572             :                         buf,
     573             :                         sizeof(buf));
     574       23075 :                 if (!NT_STATUS_IS_OK(status)) {
     575           0 :                         return smbd_smb2_request_error(req, status);
     576             :                 }
     577             :         }
     578             : 
     579       42198 :         if (capabilities & SMB2_CAP_ENCRYPTION) {
     580         104 :                 xconn->smb2.server.cipher = SMB2_ENCRYPTION_AES128_CCM;
     581             :         }
     582             : 
     583       42198 :         if (in_sign_algo != NULL) {
     584       23287 :                 const struct smb3_signing_capabilities *srv_sign_algos =
     585             :                         &default_smb3_capabilities.signing;
     586       23287 :                 uint16_t srv_preferred_idx = UINT16_MAX;
     587       23287 :                 size_t needed = 2;
     588         705 :                 uint16_t sign_algo_count;
     589         705 :                 const uint8_t *p;
     590         705 :                 size_t i;
     591             : 
     592       23287 :                 if (in_sign_algo->data.length < needed) {
     593           0 :                         return smbd_smb2_request_error(req,
     594             :                                         NT_STATUS_INVALID_PARAMETER);
     595             :                 }
     596             : 
     597       23287 :                 sign_algo_count = SVAL(in_sign_algo->data.data, 0);
     598       23287 :                 if (sign_algo_count == 0) {
     599           0 :                         return smbd_smb2_request_error(req,
     600             :                                         NT_STATUS_INVALID_PARAMETER);
     601             :                 }
     602             : 
     603       23287 :                 p = in_sign_algo->data.data + needed;
     604       23287 :                 needed += sign_algo_count * 2;
     605             : 
     606       23287 :                 if (in_sign_algo->data.length < needed) {
     607           0 :                         return smbd_smb2_request_error(req,
     608             :                                         NT_STATUS_INVALID_PARAMETER);
     609             :                 }
     610             : 
     611       91496 :                 for (i=0; i < sign_algo_count; i++) {
     612        1831 :                         uint16_t si;
     613        1831 :                         uint16_t v;
     614             : 
     615       68209 :                         v = SVAL(p, 0);
     616       68209 :                         p += 2;
     617             : 
     618      136248 :                         for (si = 0; si < srv_sign_algos->num_algos; si++) {
     619      136248 :                                 if (srv_sign_algos->algos[si] != v) {
     620       68039 :                                         continue;
     621             :                                 }
     622             : 
     623             :                                 /*
     624             :                                  * The server sign_algos are listed
     625             :                                  * with the lowest idx being preferred.
     626             :                                  */
     627       68209 :                                 if (si < srv_preferred_idx) {
     628       22582 :                                         srv_preferred_idx = si;
     629             :                                 }
     630       66378 :                                 break;
     631             :                         }
     632             :                 }
     633             : 
     634             :                 /*
     635             :                  * If we found a match announce it
     636             :                  * otherwise we'll keep the default
     637             :                  * of SMB2_SIGNING_AES128_CMAC
     638             :                  */
     639       23287 :                 if (srv_preferred_idx != UINT16_MAX) {
     640         705 :                         uint8_t buf[4];
     641             : 
     642       23287 :                         xconn->smb2.server.sign_algo =
     643       23287 :                                 srv_sign_algos->algos[srv_preferred_idx];
     644             : 
     645       23287 :                         SSVAL(buf, 0, 1); /* SigningAlgorithmCount */
     646       23287 :                         SSVAL(buf, 2, xconn->smb2.server.sign_algo);
     647             : 
     648       23287 :                         status = smb2_negotiate_context_add(
     649             :                                 req,
     650             :                                 &out_c,
     651             :                                 SMB2_SIGNING_CAPABILITIES,
     652             :                                 buf,
     653             :                                 sizeof(buf));
     654       23287 :                         if (!NT_STATUS_IS_OK(status)) {
     655           0 :                                 return smbd_smb2_request_error(req, status);
     656             :                         }
     657             :                 }
     658             :         }
     659             : 
     660       43341 :         status = smb311_capabilities_check(&default_smb3_capabilities,
     661             :                                            "smb2srv_negprot",
     662             :                                            DBGLVL_NOTICE,
     663       42198 :                                            NT_STATUS_INVALID_PARAMETER,
     664             :                                            "server",
     665             :                                            protocol,
     666       42198 :                                            xconn->smb2.server.sign_algo,
     667       42198 :                                            xconn->smb2.server.cipher);
     668       42198 :         if (!NT_STATUS_IS_OK(status)) {
     669           0 :                 return smbd_smb2_request_error(req, status);
     670             :         }
     671             : 
     672       42198 :         if (protocol >= PROTOCOL_SMB3_00 &&
     673       23403 :             xconn->client->server_multi_channel_enabled)
     674             :         {
     675       23403 :                 if (in_capabilities & SMB2_CAP_MULTI_CHANNEL) {
     676       23403 :                         capabilities |= SMB2_CAP_MULTI_CHANNEL;
     677             :                 }
     678             :         }
     679             : 
     680       42198 :         security_offset = SMB2_HDR_BODY + 0x40;
     681             : 
     682             : #if 1
     683             :         /* Try SPNEGO auth... */
     684       42198 :         security_buffer = data_blob_const(negprot_spnego_blob.data + 16,
     685       41055 :                                           negprot_spnego_blob.length - 16);
     686             : #else
     687             :         /* for now we want raw NTLMSSP */
     688             :         security_buffer = data_blob_const(NULL, 0);
     689             : #endif
     690             : 
     691       42198 :         if (in_posix != NULL) {
     692             :                 /* Client correctly negotiated SMB2 unix extensions. */
     693        8033 :                 const uint8_t *buf = (const uint8_t *)SMB2_CREATE_TAG_POSIX;
     694        8033 :                 status = smb2_negotiate_context_add(
     695             :                                 req,
     696             :                                 &out_c,
     697             :                                 SMB2_POSIX_EXTENSIONS_AVAILABLE,
     698             :                                 buf,
     699             :                                 16);
     700        8033 :                 if (!NT_STATUS_IS_OK(status)) {
     701           0 :                         return smbd_smb2_request_error(req, status);
     702             :                 }
     703        8033 :                 xconn->smb2.server.posix_extensions_negotiated = true;
     704             :         }
     705             : 
     706       42198 :         if (out_c.num_contexts != 0) {
     707       23287 :                 status = smb2_negotiate_context_push(req,
     708             :                                                 &out_negotiate_context_blob,
     709             :                                                 out_c);
     710       23287 :                 if (!NT_STATUS_IS_OK(status)) {
     711           0 :                         return smbd_smb2_request_error(req, status);
     712             :                 }
     713             :         }
     714             : 
     715       42198 :         if (out_negotiate_context_blob.length != 0) {
     716         705 :                 static const uint8_t zeros[8];
     717       23287 :                 size_t pad = 0;
     718         705 :                 size_t ofs;
     719             : 
     720       23287 :                 outdyn = data_blob_dup_talloc(req, security_buffer);
     721       23287 :                 if (outdyn.length != security_buffer.length) {
     722           0 :                         return smbd_smb2_request_error(req,
     723             :                                                 NT_STATUS_NO_MEMORY);
     724             :                 }
     725             : 
     726       23287 :                 ofs = security_offset + security_buffer.length;
     727       23287 :                 if ((ofs % 8) != 0) {
     728       15013 :                         pad = 8 - (ofs % 8);
     729             :                 }
     730       23287 :                 ofs += pad;
     731             : 
     732       23287 :                 ok = data_blob_append(req, &outdyn, zeros, pad);
     733       23287 :                 if (!ok) {
     734           0 :                         return smbd_smb2_request_error(req,
     735             :                                                 NT_STATUS_NO_MEMORY);
     736             :                 }
     737             : 
     738       23992 :                 ok = data_blob_append(req, &outdyn,
     739       23287 :                                       out_negotiate_context_blob.data,
     740             :                                       out_negotiate_context_blob.length);
     741       23287 :                 if (!ok) {
     742           0 :                         return smbd_smb2_request_error(req,
     743             :                                                 NT_STATUS_NO_MEMORY);
     744             :                 }
     745             : 
     746       23287 :                 out_negotiate_context_offset = ofs;
     747       23287 :                 out_negotiate_context_count = out_c.num_contexts;
     748             :         } else {
     749       18911 :                 outdyn = security_buffer;
     750             :         }
     751             : 
     752       42198 :         out_guid_blob = data_blob_const(negprot_spnego_blob.data, 16);
     753       42198 :         status = GUID_from_ndr_blob(&out_guid_blob, &out_guid);
     754       42198 :         if (!NT_STATUS_IS_OK(status)) {
     755           0 :                 return smbd_smb2_request_error(req, status);
     756             :         }
     757             : 
     758       42198 :         outbody = smbd_smb2_generate_outbody(req, 0x40);
     759       42198 :         if (outbody.data == NULL) {
     760           0 :                 return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
     761             :         }
     762             : 
     763       42198 :         SSVAL(outbody.data, 0x00, 0x40 + 1);    /* struct size */
     764       42198 :         SSVAL(outbody.data, 0x02,
     765             :               security_mode);                   /* security mode */
     766       42198 :         SSVAL(outbody.data, 0x04, dialect);     /* dialect revision */
     767       42198 :         SSVAL(outbody.data, 0x06,
     768             :               out_negotiate_context_count);     /* reserved/NegotiateContextCount */
     769       42198 :         memcpy(outbody.data + 0x08,
     770       42198 :                out_guid_blob.data, 16); /* server guid */
     771       42198 :         SIVAL(outbody.data, 0x18,
     772             :               capabilities);                    /* capabilities */
     773       42198 :         SIVAL(outbody.data, 0x1C, max_trans);   /* max transact size */
     774       42198 :         SIVAL(outbody.data, 0x20, max_read);    /* max read size */
     775       42198 :         SIVAL(outbody.data, 0x24, max_write);   /* max write size */
     776       42198 :         SBVAL(outbody.data, 0x28, now);         /* system time */
     777       42198 :         SBVAL(outbody.data, 0x30, 0);           /* server start time */
     778       42198 :         SSVAL(outbody.data, 0x38,
     779             :               security_offset);                 /* security buffer offset */
     780       42198 :         SSVAL(outbody.data, 0x3A,
     781             :               security_buffer.length);          /* security buffer length */
     782       42198 :         SIVAL(outbody.data, 0x3C,
     783             :               out_negotiate_context_offset);    /* reserved/NegotiateContextOffset */
     784             : 
     785       42198 :         req->sconn->using_smb2 = true;
     786             : 
     787       42198 :         if (dialect == SMB2_DIALECT_REVISION_2FF) {
     788       16223 :                 return smbd_smb2_request_done(req, outbody, &outdyn);
     789             :         }
     790             : 
     791       25975 :         status = smbXsrv_connection_init_tables(xconn, protocol);
     792       25975 :         if (!NT_STATUS_IS_OK(status)) {
     793           0 :                 return smbd_smb2_request_error(req, status);
     794             :         }
     795             : 
     796       25975 :         xconn->smb2.client.capabilities = in_capabilities;
     797       25975 :         xconn->smb2.client.security_mode = in_security_mode;
     798       25975 :         xconn->smb2.client.guid = in_guid;
     799       25975 :         xconn->smb2.client.num_dialects = dialect_count;
     800       25975 :         xconn->smb2.client.dialects = talloc_array(xconn,
     801             :                                                    uint16_t,
     802             :                                                    dialect_count);
     803       25975 :         if (xconn->smb2.client.dialects == NULL) {
     804           0 :                 return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
     805             :         }
     806      149663 :         for (c=0; c < dialect_count; c++) {
     807      123688 :                 xconn->smb2.client.dialects[c] = SVAL(indyn, c*2);
     808             :         }
     809             : 
     810       25975 :         xconn->smb2.server.capabilities = capabilities;
     811       25975 :         xconn->smb2.server.security_mode = security_mode;
     812       25975 :         xconn->smb2.server.guid = out_guid;
     813       25975 :         xconn->smb2.server.dialect = dialect;
     814       25975 :         xconn->smb2.server.max_trans = max_trans;
     815       25975 :         xconn->smb2.server.max_read  = max_read;
     816       25975 :         xconn->smb2.server.max_write = max_write;
     817             : 
     818       25975 :         if (xconn->protocol < PROTOCOL_SMB2_10) {
     819             :                 /*
     820             :                  * SMB2_02 doesn't support client guids
     821             :                  */
     822          82 :                 return smbd_smb2_request_done(req, outbody, &outdyn);
     823             :         }
     824             : 
     825       25893 :         if (!xconn->client->server_multi_channel_enabled) {
     826             :                 /*
     827             :                  * Only deal with the client guid database
     828             :                  * if multi-channel is enabled.
     829             :                  *
     830             :                  * But we still need to setup
     831             :                  * xconn->client->global->client_guid to
     832             :                  * the correct value.
     833             :                  */
     834           0 :                 xconn->client->global->client_guid =
     835             :                         xconn->smb2.client.guid;
     836           0 :                 return smbd_smb2_request_done(req, outbody, &outdyn);
     837             :         }
     838             : 
     839       25893 :         if (xconn->smb2.client.guid_verified) {
     840             :                 /*
     841             :                  * The connection was passed from another
     842             :                  * smbd process.
     843             :                  */
     844        1106 :                 return smbd_smb2_request_done(req, outbody, &outdyn);
     845             :         }
     846             : 
     847       24787 :         state = talloc_zero(req, struct smbd_smb2_request_process_negprot_state);
     848       24787 :         if (state == NULL) {
     849           0 :                 return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
     850             :         }
     851       24787 :         *state = (struct smbd_smb2_request_process_negprot_state) {
     852             :                 .req = req,
     853             :                 .outbody = outbody,
     854             :                 .outdyn = outdyn,
     855             :         };
     856             : 
     857       25484 :         subreq = smb2srv_client_mc_negprot_send(state,
     858       24787 :                                                 req->xconn->client->raw_ev_ctx,
     859             :                                                 req);
     860       24787 :         if (subreq == NULL) {
     861           0 :                 return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
     862             :         }
     863       24787 :         tevent_req_set_callback(subreq,
     864             :                                 smbd_smb2_request_process_negprot_mc_done,
     865             :                                 state);
     866       24787 :         return NT_STATUS_OK;
     867             : }
     868             : 
     869       24787 : static void smbd_smb2_request_process_negprot_mc_done(struct tevent_req *subreq)
     870             : {
     871         697 :         struct smbd_smb2_request_process_negprot_state *state =
     872       24787 :                 tevent_req_callback_data(subreq,
     873             :                 struct smbd_smb2_request_process_negprot_state);
     874       24787 :         struct smbd_smb2_request *req = state->req;
     875       24787 :         struct smbXsrv_connection *xconn = req->xconn;
     876         697 :         NTSTATUS status;
     877             : 
     878       24787 :         status = smb2srv_client_mc_negprot_recv(subreq);
     879       24787 :         TALLOC_FREE(subreq);
     880       24787 :         if (NT_STATUS_EQUAL(status, NT_STATUS_MESSAGE_RETRIEVED)) {
     881             :                 /*
     882             :                  * The connection was passed to another process
     883             :                  */
     884        1168 :                 smbd_server_connection_terminate(xconn,
     885             :                                                  "passed connection");
     886             :                 /*
     887             :                  * smbd_server_connection_terminate() should not return!
     888             :                  */
     889           0 :                 smb_panic(__location__);
     890             :                 return;
     891             :         }
     892       23619 :         if (!NT_STATUS_IS_OK(status)) {
     893           0 :                 status = smbd_smb2_request_error(req, status);
     894           0 :                 if (NT_STATUS_IS_OK(status)) {
     895           0 :                         return;
     896             :                 }
     897             : 
     898             :                 /*
     899             :                  * The connection was passed to another process
     900             :                  */
     901           0 :                 smbd_server_connection_terminate(xconn, nt_errstr(status));
     902             :                 /*
     903             :                  * smbd_server_connection_terminate() should not return!
     904             :                  */
     905           0 :                 smb_panic(__location__);
     906             :                 return;
     907             :         }
     908             : 
     909             :         /*
     910             :          * We're the first connection...
     911             :          */
     912       23619 :         status = smbd_smb2_request_done(req, state->outbody, &state->outdyn);
     913       23619 :         if (NT_STATUS_IS_OK(status)) {
     914             :                 /*
     915             :                  * This allows us to support starting smbd under
     916             :                  * callgrind and only start the overhead and
     917             :                  * instrumentation after the SMB2 negprot,
     918             :                  * this allows us to profile only useful
     919             :                  * stuff and not all the smbd startup, forking
     920             :                  * and multichannel handling.
     921             :                  *
     922             :                  * valgrind --tool=callgrind --instr-atstart=no smbd
     923             :                  */
     924             : #ifdef CALLGRIND_START_INSTRUMENTATION
     925             :                 CALLGRIND_START_INSTRUMENTATION;
     926             : #endif
     927       22974 :                 return;
     928             :         }
     929             : 
     930             :         /*
     931             :          * The connection was passed to another process
     932             :          */
     933           0 :         smbd_server_connection_terminate(xconn, nt_errstr(status));
     934             :         /*
     935             :          * smbd_server_connection_terminate() should not return!
     936             :          */
     937           0 :         smb_panic(__location__);
     938         645 :         return;
     939             : }
     940             : 
     941             : /****************************************************************************
     942             :  Generate the spnego negprot reply blob. Return the number of bytes used.
     943             : ****************************************************************************/
     944             : 
     945       47723 : DATA_BLOB negprot_spnego(TALLOC_CTX *ctx, struct smbXsrv_connection *xconn)
     946             : {
     947       47723 :         DATA_BLOB blob = data_blob_null;
     948       47723 :         DATA_BLOB blob_out = data_blob_null;
     949        1276 :         nstring dos_name;
     950        1276 :         fstring unix_name;
     951        1276 :         NTSTATUS status;
     952             : #ifdef DEVELOPER
     953        1276 :         size_t slen;
     954             : #endif
     955        1276 :         struct gensec_security *gensec_security;
     956             : 
     957             :         /* See if we can get an SPNEGO blob */
     958       47723 :         status = auth_generic_prepare(talloc_tos(),
     959             :                                       xconn->remote_address,
     960             :                                       xconn->local_address,
     961             :                                       "SMB",
     962             :                                       &gensec_security);
     963             : 
     964             :         /*
     965             :          * Despite including it above, there is no need to set a
     966             :          * remote address or similar as we are just interested in the
     967             :          * SPNEGO blob, we never keep this context.
     968             :          */
     969             : 
     970       47723 :         if (NT_STATUS_IS_OK(status)) {
     971       47723 :                 status = gensec_start_mech_by_oid(gensec_security, GENSEC_OID_SPNEGO);
     972       47723 :                 if (NT_STATUS_IS_OK(status)) {
     973       47723 :                         status = gensec_update(gensec_security, ctx,
     974             :                                                data_blob_null, &blob);
     975             :                         /* If we get the list of OIDs, the 'OK' answer
     976             :                          * is NT_STATUS_MORE_PROCESSING_REQUIRED */
     977       47723 :                         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
     978           0 :                                 DEBUG(0, ("Failed to start SPNEGO handler for negprot OID list!\n"));
     979           0 :                                 blob = data_blob_null;
     980             :                         }
     981             :                 }
     982       47723 :                 TALLOC_FREE(gensec_security);
     983             :         }
     984             : 
     985             : #if defined(WITH_SMB1SERVER)
     986       47723 :         xconn->smb1.negprot.spnego = true;
     987             : #endif
     988             : 
     989             :         /* strangely enough, NT does not sent the single OID NTLMSSP when
     990             :            not a ADS member, it sends no OIDs at all
     991             : 
     992             :            OLD COMMENT : "we can't do this until we teach our session setup parser to know
     993             :                    about raw NTLMSSP (clients send no ASN.1 wrapping if we do this)"
     994             : 
     995             :            Our sessionsetup code now handles raw NTLMSSP connects, so we can go
     996             :            back to doing what W2K3 does here. This is needed to make PocketPC 2003
     997             :            CIFS connections work with SPNEGO. See bugzilla bugs #1828 and #3133
     998             :            for details. JRA.
     999             : 
    1000             :         */
    1001             : 
    1002       47723 :         if (blob.length == 0 || blob.data == NULL) {
    1003           0 :                 return data_blob_null;
    1004             :         }
    1005             : 
    1006       47723 :         blob_out = data_blob_talloc(ctx, NULL, 16 + blob.length);
    1007       47723 :         if (blob_out.data == NULL) {
    1008           0 :                 data_blob_free(&blob);
    1009           0 :                 return data_blob_null;
    1010             :         }
    1011             : 
    1012       47723 :         memset(blob_out.data, '\0', 16);
    1013             : 
    1014       47723 :         checked_strlcpy(unix_name, lp_netbios_name(), sizeof(unix_name));
    1015       47723 :         (void)strlower_m(unix_name);
    1016       47723 :         push_ascii_nstring(dos_name, unix_name);
    1017       47723 :         strlcpy((char *)blob_out.data, dos_name, 17);
    1018             : 
    1019             : #ifdef DEVELOPER
    1020             :         /* Fix valgrind 'uninitialized bytes' issue. */
    1021       47723 :         slen = strlen(dos_name);
    1022       47723 :         if (slen < 16) {
    1023       47723 :                 memset(blob_out.data+slen, '\0', 16 - slen);
    1024             :         }
    1025             : #endif
    1026             : 
    1027       47723 :         memcpy(&blob_out.data[16], blob.data, blob.length);
    1028             : 
    1029       47723 :         data_blob_free(&blob);
    1030             : 
    1031       47723 :         return blob_out;
    1032             : }
    1033             : 
    1034             : /*
    1035             :  * MS-CIFS, 2.2.4.52.2 SMB_COM_NEGOTIATE Response:
    1036             :  * If the server does not support any of the listed dialects, it MUST return a
    1037             :  * DialectIndex of 0XFFFF
    1038             :  */
    1039             : #define NO_PROTOCOL_CHOSEN      0xffff
    1040             : 
    1041             : #define PROT_SMB_2_002                          0x1000
    1042             : #define PROT_SMB_2_FF                           0x2000
    1043             : 
    1044             : /* List of supported SMB1 protocols, most desired first.
    1045             :  * This is for enabling multi-protocol negotiation in SMB2 when SMB1
    1046             :  * is disabled.
    1047             :  */
    1048             : static const struct {
    1049             :         const char *proto_name;
    1050             :         const char *short_name;
    1051             :         NTSTATUS (*proto_reply_fn)(struct smb_request *req, uint16_t choice);
    1052             :         int protocol_level;
    1053             : } supported_protocols[] = {
    1054             :         {"SMB 2.???",               "SMB2_FF",  reply_smb20ff,  PROTOCOL_SMB2_10},
    1055             :         {"SMB 2.002",               "SMB2_02",  reply_smb2002,  PROTOCOL_SMB2_02},
    1056             :         {NULL,NULL,NULL,0},
    1057             : };
    1058             : 
    1059             : /****************************************************************************
    1060             :  Reply to a negprot.
    1061             :  conn POINTER CAN BE NULL HERE !
    1062             : ****************************************************************************/
    1063             : 
    1064       16402 : NTSTATUS smb2_multi_protocol_reply_negprot(struct smb_request *req)
    1065             : {
    1066       16402 :         size_t choice = 0;
    1067       16402 :         bool choice_set = false;
    1068         390 :         int protocol;
    1069         390 :         const char *p;
    1070         390 :         int num_cliprotos;
    1071         390 :         char **cliprotos;
    1072         390 :         size_t i;
    1073         390 :         size_t converted_size;
    1074       16402 :         struct smbXsrv_connection *xconn = req->xconn;
    1075       16402 :         struct smbd_server_connection *sconn = req->sconn;
    1076         390 :         int max_proto;
    1077         390 :         int min_proto;
    1078         390 :         NTSTATUS status;
    1079             : 
    1080       16402 :         START_PROFILE(SMBnegprot);
    1081             : 
    1082       16402 :         if (req->buflen == 0) {
    1083           0 :                 DEBUG(0, ("negprot got no protocols\n"));
    1084           0 :                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    1085           0 :                 END_PROFILE(SMBnegprot);
    1086           0 :                 return NT_STATUS_INVALID_PARAMETER;
    1087             :         }
    1088             : 
    1089       16402 :         if (req->buf[req->buflen-1] != '\0') {
    1090           2 :                 DEBUG(0, ("negprot protocols not 0-terminated\n"));
    1091           2 :                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
    1092           2 :                 END_PROFILE(SMBnegprot);
    1093           2 :                 return NT_STATUS_INVALID_PARAMETER;
    1094             :         }
    1095             : 
    1096       16400 :         p = (const char *)req->buf + 1;
    1097             : 
    1098       16400 :         num_cliprotos = 0;
    1099       16400 :         cliprotos = NULL;
    1100             : 
    1101      163100 :         while (smbreq_bufrem(req, p) > 0) {
    1102             : 
    1103        1608 :                 char **tmp;
    1104             : 
    1105      146700 :                 tmp = talloc_realloc(talloc_tos(), cliprotos, char *,
    1106             :                                            num_cliprotos+1);
    1107      146700 :                 if (tmp == NULL) {
    1108           0 :                         DEBUG(0, ("talloc failed\n"));
    1109           0 :                         TALLOC_FREE(cliprotos);
    1110           0 :                         reply_nterror(req, NT_STATUS_NO_MEMORY);
    1111           0 :                         END_PROFILE(SMBnegprot);
    1112           0 :                         return NT_STATUS_NO_MEMORY;
    1113             :                 }
    1114             : 
    1115      146700 :                 cliprotos = tmp;
    1116             : 
    1117      146700 :                 if (!pull_ascii_talloc(cliprotos, &cliprotos[num_cliprotos], p,
    1118             :                                        &converted_size)) {
    1119           0 :                         DEBUG(0, ("pull_ascii_talloc failed\n"));
    1120           0 :                         TALLOC_FREE(cliprotos);
    1121           0 :                         reply_nterror(req, NT_STATUS_NO_MEMORY);
    1122           0 :                         END_PROFILE(SMBnegprot);
    1123           0 :                         return NT_STATUS_NO_MEMORY;
    1124             :                 }
    1125             : 
    1126      146700 :                 DEBUG(3, ("Requested protocol [%s]\n",
    1127             :                           cliprotos[num_cliprotos]));
    1128             : 
    1129      146700 :                 num_cliprotos += 1;
    1130      146700 :                 p += strlen(p) + 2;
    1131             :         }
    1132             : 
    1133             :         /* possibly reload - change of architecture */
    1134       16400 :         reload_services(sconn, conn_snum_used, true);
    1135             : 
    1136             :         /*
    1137             :          * Anything higher than PROTOCOL_SMB2_10 still
    1138             :          * needs to go via "SMB 2.???", which is marked
    1139             :          * as PROTOCOL_SMB2_10.
    1140             :          *
    1141             :          * The real negotiation happens via reply_smb20ff()
    1142             :          * using SMB2 Negotiation.
    1143             :          */
    1144       16400 :         max_proto = lp_server_max_protocol();
    1145       16400 :         if (max_proto > PROTOCOL_SMB2_10) {
    1146       14570 :                 max_proto = PROTOCOL_SMB2_10;
    1147             :         }
    1148       16400 :         min_proto = lp_server_min_protocol();
    1149       16400 :         if (min_proto > PROTOCOL_SMB2_10) {
    1150           0 :                 min_proto = PROTOCOL_SMB2_10;
    1151             :         }
    1152             : 
    1153             :         /* Check for protocols, most desirable first */
    1154       17408 :         for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
    1155       16922 :                 i = 0;
    1156       16922 :                 if ((supported_protocols[protocol].protocol_level <= max_proto) &&
    1157       16472 :                     (supported_protocols[protocol].protocol_level >= min_proto))
    1158      168046 :                         while (i < num_cliprotos) {
    1159      151176 :                                 if (strequal(cliprotos[i],supported_protocols[protocol].proto_name)) {
    1160       15914 :                                         choice = i;
    1161       15914 :                                         choice_set = true;
    1162             :                                 }
    1163      151176 :                                 i++;
    1164             :                         }
    1165       16922 :                 if (choice_set) {
    1166       15532 :                         break;
    1167             :                 }
    1168             :         }
    1169             : 
    1170       16400 :         if (!choice_set) {
    1171           8 :                 bool ok;
    1172             : 
    1173         486 :                 DBG_NOTICE("No protocol supported !\n");
    1174         486 :                 reply_smb1_outbuf(req, 1, 0);
    1175         486 :                 SSVAL(req->outbuf, smb_vwv0, NO_PROTOCOL_CHOSEN);
    1176             : 
    1177         486 :                 ok = smb1_srv_send(xconn, (char *)req->outbuf, false, 0, false);
    1178         486 :                 if (!ok) {
    1179           0 :                         DBG_NOTICE("smb1_srv_send failed\n");
    1180             :                 }
    1181         486 :                 exit_server_cleanly("no protocol supported\n");
    1182             :         }
    1183             : 
    1184       15914 :         set_remote_proto(supported_protocols[protocol].short_name);
    1185       15914 :         reload_services(sconn, conn_snum_used, true);
    1186       15914 :         status = supported_protocols[protocol].proto_reply_fn(req, choice);
    1187       15914 :         if (!NT_STATUS_IS_OK(status)) {
    1188           0 :                 exit_server_cleanly("negprot function failed\n");
    1189             :         }
    1190             : 
    1191       15914 :         DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
    1192             : 
    1193       15914 :         DBG_INFO("negprot index=%zu\n", choice);
    1194             : 
    1195       15914 :         TALLOC_FREE(cliprotos);
    1196             : 
    1197       15914 :         END_PROFILE(SMBnegprot);
    1198       15914 :         return NT_STATUS_OK;
    1199             : }

Generated by: LCOV version 1.14