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

Generated by: LCOV version 1.14