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

Generated by: LCOV version 1.14