LCOV - code coverage report
Current view: top level - source3/smbd - smb2_negprot.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 515 588 87.6 %
Date: 2024-04-21 15:09:00 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       16608 : 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       16608 :         size_t len = SMB2_HDR_BODY + 0x24 + 2;
      51             : 
      52       16608 :         smb2_inpdu = talloc_zero_array(talloc_tos(), uint8_t, len);
      53       16608 :         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       16608 :         smb2_hdr = smb2_inpdu;
      59       16608 :         smb2_body = smb2_hdr + SMB2_HDR_BODY;
      60       16608 :         smb2_dyn = smb2_body + 0x24;
      61             : 
      62       16608 :         SIVAL(smb2_hdr, SMB2_HDR_PROTOCOL_ID,   SMB2_MAGIC);
      63       16608 :         SIVAL(smb2_hdr, SMB2_HDR_LENGTH,        SMB2_HDR_BODY);
      64             : 
      65       16608 :         SSVAL(smb2_body, 0x00, 0x0024); /* struct size */
      66       16608 :         SSVAL(smb2_body, 0x02, 0x0001); /* dialect count */
      67             : 
      68       16608 :         SSVAL(smb2_dyn,  0x00, dialect);
      69             : 
      70       16608 :         req->outbuf = NULL;
      71             : 
      72       16608 :         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       16572 : NTSTATUS reply_smb20ff(struct smb_request *req, uint16_t choice)
      89             : {
      90       16572 :         struct smbXsrv_connection *xconn = req->xconn;
      91       16572 :         xconn->smb2.allow_2ff = true;
      92       16572 :         return reply_smb20xx(req, SMB2_DIALECT_REVISION_2FF);
      93             : }
      94             : 
      95       45446 : 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       45446 :         } 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      144164 :         for (i = 0; i < ARRAY_SIZE(pd); i ++) {
     112      127592 :                 int c = 0;
     113             : 
     114      127592 :                 if (lp_server_max_protocol() < pd[i].proto) {
     115       18500 :                         continue;
     116             :                 }
     117      109092 :                 if (lp_server_min_protocol() > pd[i].proto) {
     118          11 :                         continue;
     119             :                 }
     120             : 
     121      284486 :                 for (c = 0; c < dialect_count; c++) {
     122      204279 :                         *dialect = SVAL(indyn, c*2);
     123      204279 :                         if (*dialect == pd[i].dialect) {
     124       28874 :                                 return pd[i].proto;
     125             :                         }
     126             :                 }
     127             :         }
     128             : 
     129       16182 :         return PROTOCOL_NONE;
     130             : }
     131             : 
     132       23488 : static NTSTATUS smb2_negotiate_context_process_posix(
     133             :         const struct smb2_negotiate_contexts *in_c,
     134             :         bool *posix)
     135             : {
     136       23488 :         struct smb2_negotiate_context *in_posix = NULL;
     137       23488 :         const uint8_t *inbuf = NULL;
     138         705 :         size_t inbuflen;
     139       23488 :         bool posix_found = false;
     140         705 :         size_t ofs;
     141         705 :         int cmp;
     142             : 
     143       23488 :         *posix = false;
     144             : 
     145       23488 :         if (!lp_smb3_unix_extensions(GLOBAL_SECTION_SNUM)) {
     146       15460 :                 return NT_STATUS_OK;
     147             :         }
     148             : 
     149        8028 :         in_posix = smb2_negotiate_context_find(in_c,
     150             :                                                SMB2_POSIX_EXTENSIONS_AVAILABLE);
     151        8028 :         if (in_posix == NULL) {
     152        2380 :                 return NT_STATUS_OK;
     153             :         }
     154             : 
     155        5648 :         inbuf = in_posix->data.data;
     156        5648 :         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        5648 :         if ((inbuflen % 16) != 0) {
     163           2 :                 return NT_STATUS_INVALID_PARAMETER;
     164             :         }
     165             : 
     166             :         SMB_ASSERT(strlen(SMB2_CREATE_TAG_POSIX) == 16);
     167             : 
     168        5648 :         for (ofs = 0; ofs < inbuflen; ofs += 16) {
     169        5646 :                 cmp = memcmp(inbuf+ofs, SMB2_CREATE_TAG_POSIX, 16);
     170        5646 :                 if (cmp == 0) {
     171        5644 :                         posix_found = true;
     172        5644 :                         break;
     173             :                 }
     174             :         }
     175             : 
     176        5646 :         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        5644 :         DBG_DEBUG("Client requested SMB3 Unix extensions\n");
     183        5644 :         *posix = true;
     184        5644 :         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       42766 : NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
     196             : {
     197       42766 :         struct smbd_smb2_request_process_negprot_state *state = NULL;
     198       42766 :         struct smbXsrv_connection *xconn = req->xconn;
     199       42766 :         struct tevent_req *subreq = NULL;
     200        1143 :         NTSTATUS status;
     201        1143 :         const uint8_t *inbody;
     202       42766 :         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       42766 :         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       42766 :         struct smb2_negotiate_contexts in_c = { .num_contexts = 0, };
     217       42766 :         struct smb2_negotiate_context *in_preauth = NULL;
     218       42766 :         struct smb2_negotiate_context *in_cipher = NULL;
     219       42766 :         struct smb2_negotiate_context *in_sign_algo = NULL;
     220       42766 :         struct smb2_negotiate_contexts out_c = { .num_contexts = 0, };
     221        1143 :         const struct smb311_capabilities default_smb3_capabilities =
     222       42766 :                 smb311_capabilities_parse("server",
     223       42766 :                         lp_server_smb3_signing_algorithms(),
     224       42766 :                         lp_server_smb3_encryption_algorithms());
     225       42766 :         DATA_BLOB out_negotiate_context_blob = data_blob_null;
     226       42766 :         uint32_t out_negotiate_context_offset = 0;
     227       42766 :         uint16_t out_negotiate_context_count = 0;
     228       42766 :         uint16_t dialect = 0;
     229        1143 :         uint32_t capabilities;
     230        1143 :         DATA_BLOB out_guid_blob;
     231        1143 :         struct GUID out_guid;
     232       42766 :         enum protocol_types protocol = PROTOCOL_NONE;
     233        1143 :         uint32_t max_limit;
     234       42766 :         uint32_t max_trans = lp_smb2_max_trans();
     235       42766 :         uint32_t max_read = lp_smb2_max_read();
     236       42766 :         uint32_t max_write = lp_smb2_max_write();
     237       42766 :         NTTIME now = timeval_to_nttime(&req->request_time);
     238       42766 :         bool posix = false;
     239        1143 :         bool ok;
     240             : 
     241       42766 :         status = smbd_smb2_request_verify_sizes(req, 0x24);
     242       42766 :         if (!NT_STATUS_IS_OK(status)) {
     243           0 :                 return smbd_smb2_request_error(req, status);
     244             :         }
     245       42766 :         inbody = SMBD_SMB2_IN_BODY_PTR(req);
     246             : 
     247       42766 :         dialect_count = SVAL(inbody, 0x02);
     248             : 
     249       42766 :         in_security_mode = SVAL(inbody, 0x04);
     250       42766 :         in_capabilities = IVAL(inbody, 0x08);
     251       42766 :         in_guid_blob = data_blob_const(inbody + 0x0C, 16);
     252             : 
     253       42766 :         if (dialect_count == 0) {
     254           0 :                 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
     255             :         }
     256             : 
     257       42766 :         status = GUID_from_ndr_blob(&in_guid_blob, &in_guid);
     258       42766 :         if (!NT_STATUS_IS_OK(status)) {
     259           0 :                 return smbd_smb2_request_error(req, status);
     260             :         }
     261             : 
     262       42766 :         expected_dyn_size = dialect_count * 2;
     263       42766 :         if (SMBD_SMB2_IN_DYN_LEN(req) < expected_dyn_size) {
     264           0 :                 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
     265             :         }
     266       42766 :         indyn = SMBD_SMB2_IN_DYN_PTR(req);
     267             : 
     268       42766 :         protocol = smbd_smb2_protocol_dialect_match(indyn,
     269             :                                         dialect_count,
     270             :                                         &dialect);
     271             : 
     272       43909 :         for (c=0; protocol == PROTOCOL_NONE && c < dialect_count; c++) {
     273       16572 :                 if (lp_server_max_protocol() < PROTOCOL_SMB2_10) {
     274           0 :                         break;
     275             :                 }
     276             : 
     277       16572 :                 dialect = SVAL(indyn, c*2);
     278       16572 :                 if (dialect == SMB2_DIALECT_REVISION_2FF) {
     279       16572 :                         if (xconn->smb2.allow_2ff) {
     280       16572 :                                 xconn->smb2.allow_2ff = false;
     281       16572 :                                 protocol = PROTOCOL_SMB2_10;
     282       16572 :                                 break;
     283             :                         }
     284             :                 }
     285             :         }
     286             : 
     287       42766 :         if (protocol == PROTOCOL_NONE) {
     288           0 :                 return smbd_smb2_request_error(req, NT_STATUS_NOT_SUPPORTED);
     289             :         }
     290             : 
     291       42766 :         if (protocol >= PROTOCOL_SMB3_11) {
     292       23488 :                 uint32_t in_negotiate_context_offset = 0;
     293       23488 :                 uint16_t in_negotiate_context_count = 0;
     294       23488 :                 DATA_BLOB in_negotiate_context_blob = data_blob_null;
     295         705 :                 size_t ofs;
     296             : 
     297       23488 :                 in_negotiate_context_offset = IVAL(inbody, 0x1C);
     298       23488 :                 in_negotiate_context_count = SVAL(inbody, 0x20);
     299             : 
     300       23488 :                 ofs = SMB2_HDR_BODY;
     301       23488 :                 ofs += SMBD_SMB2_IN_BODY_LEN(req);
     302       23488 :                 ofs += expected_dyn_size;
     303       23488 :                 if ((ofs % 8) != 0) {
     304       23488 :                         ofs += 8 - (ofs % 8);
     305             :                 }
     306             : 
     307       23488 :                 if (in_negotiate_context_offset != ofs) {
     308           0 :                         return smbd_smb2_request_error(req,
     309             :                                         NT_STATUS_INVALID_PARAMETER);
     310             :                 }
     311             : 
     312       23488 :                 ofs -= SMB2_HDR_BODY;
     313       23488 :                 ofs -= SMBD_SMB2_IN_BODY_LEN(req);
     314             : 
     315       23488 :                 if (SMBD_SMB2_IN_DYN_LEN(req) < ofs) {
     316           0 :                         return smbd_smb2_request_error(req,
     317             :                                         NT_STATUS_INVALID_PARAMETER);
     318             :                 }
     319             : 
     320       23488 :                 in_negotiate_context_blob = data_blob_const(indyn,
     321       22783 :                                                 SMBD_SMB2_IN_DYN_LEN(req));
     322             : 
     323       23488 :                 in_negotiate_context_blob.data += ofs;
     324       23488 :                 in_negotiate_context_blob.length -= ofs;
     325             : 
     326       23488 :                 status = smb2_negotiate_context_parse(req,
     327             :                                                       in_negotiate_context_blob,
     328             :                                                       in_negotiate_context_count,
     329             :                                                       &in_c);
     330       23488 :                 if (!NT_STATUS_IS_OK(status)) {
     331           0 :                         return smbd_smb2_request_error(req, status);
     332             :                 }
     333             : 
     334       23488 :                 status = smb2_negotiate_context_process_posix(&in_c, &posix);
     335       23488 :                 if (!NT_STATUS_IS_OK(status)) {
     336           2 :                         return smbd_smb2_request_error(req, status);
     337             :                 }
     338             :         }
     339             : 
     340       42764 :         if ((dialect != SMB2_DIALECT_REVISION_2FF) &&
     341       26110 :             (protocol >= PROTOCOL_SMB2_10) &&
     342       26110 :             !GUID_all_zero(&in_guid))
     343             :         {
     344       26106 :                 ok = remote_arch_cache_update(&in_guid);
     345       26106 :                 if (!ok) {
     346           0 :                         return smbd_smb2_request_error(
     347             :                                 req, NT_STATUS_UNSUCCESSFUL);
     348             :                 }
     349             :         }
     350             : 
     351       42764 :         switch (get_remote_arch()) {
     352       18264 :         case RA_VISTA:
     353             :         case RA_SAMBA:
     354             :         case RA_CIFSFS:
     355             :         case RA_OSX:
     356       18264 :                 break;
     357       24048 :         default:
     358       24048 :                 set_remote_arch(RA_VISTA);
     359       24048 :                 break;
     360             :         }
     361             : 
     362             :         {
     363        1143 :                 fstring proto;
     364       42764 :                 fstr_sprintf(proto,
     365             :                              "SMB%X_%02X",
     366             :                              (dialect >> 8) & 0xFF, dialect & 0xFF);
     367       42764 :                 set_remote_proto(proto);
     368       42764 :                 DEBUG(3,("Selected protocol %s\n", proto));
     369             :         }
     370             : 
     371       42764 :         reload_services(req->sconn, conn_snum_used, true);
     372             : 
     373       42764 :         in_preauth = smb2_negotiate_context_find(&in_c,
     374             :                                         SMB2_PREAUTH_INTEGRITY_CAPABILITIES);
     375       42764 :         if (protocol >= PROTOCOL_SMB3_11 && in_preauth == NULL) {
     376           0 :                 return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
     377             :         }
     378       42764 :         in_cipher = smb2_negotiate_context_find(&in_c,
     379             :                                         SMB2_ENCRYPTION_CAPABILITIES);
     380       42764 :         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       42764 :         negprot_spnego_blob = negprot_spnego(req, xconn);
     385       42764 :         if (negprot_spnego_blob.data == NULL) {
     386           0 :                 return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
     387             :         }
     388             : 
     389       42764 :         if (negprot_spnego_blob.length < 16) {
     390           0 :                 return smbd_smb2_request_error(req, NT_STATUS_INTERNAL_ERROR);
     391             :         }
     392             : 
     393       42764 :         security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED;
     394       42764 :         if (xconn->smb2.signing_mandatory) {
     395       14164 :                 security_mode |= SMB2_NEGOTIATE_SIGNING_REQUIRED;
     396             :         }
     397             : 
     398       42764 :         capabilities = 0;
     399       42764 :         if (lp_host_msdfs()) {
     400       42764 :                 capabilities |= SMB2_CAP_DFS;
     401             :         }
     402             : 
     403       85446 :         if (protocol >= PROTOCOL_SMB2_10 &&
     404       75365 :             lp_smb2_leases() &&
     405       32683 :             lp_oplocks(GLOBAL_SECTION_SNUM) &&
     406       32683 :             !lp_kernel_oplocks(GLOBAL_SECTION_SNUM))
     407             :         {
     408       32683 :                 capabilities |= SMB2_CAP_LEASING;
     409             :         }
     410             : 
     411       66366 :         if ((protocol >= PROTOCOL_SMB3_00) &&
     412       23602 :             (lp_server_smb_encrypt(-1) != SMB_ENCRYPTION_OFF) &&
     413       23378 :             (in_capabilities & SMB2_CAP_ENCRYPTION)) {
     414       23378 :                 capabilities |= SMB2_CAP_ENCRYPTION;
     415             :         }
     416             : 
     417             :         /*
     418             :          * 0x10000 (65536) is the maximum allowed message size
     419             :          * for SMB 2.0
     420             :          */
     421       42764 :         max_limit = 0x10000;
     422             : 
     423       42764 :         if (protocol >= PROTOCOL_SMB2_10) {
     424       42682 :                 int p = 0;
     425             : 
     426       42682 :                 if (tsocket_address_is_inet(req->sconn->local_address, "ip")) {
     427       42682 :                         p = tsocket_address_inet_port(req->sconn->local_address);
     428             :                 }
     429             : 
     430             :                 /* largeMTU is not supported over NBT (tcp port 139) */
     431       42682 :                 if (p != NBT_SMB_PORT) {
     432       41100 :                         capabilities |= SMB2_CAP_LARGE_MTU;
     433       41100 :                         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       41100 :                         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       42764 :         max_trans = MIN(max_limit, lp_smb2_max_trans());
     454       42764 :         max_read = MIN(max_limit, lp_smb2_max_read());
     455       42764 :         max_write = MIN(max_limit, lp_smb2_max_write());
     456             : 
     457       42764 :         if (in_preauth != NULL) {
     458       23486 :                 size_t needed = 4;
     459         705 :                 uint16_t hash_count;
     460         705 :                 uint16_t salt_length;
     461       23486 :                 uint16_t selected_preauth = 0;
     462         705 :                 const uint8_t *p;
     463         705 :                 uint8_t buf[38];
     464         705 :                 size_t i;
     465             : 
     466       23486 :                 if (in_preauth->data.length < needed) {
     467           0 :                         return smbd_smb2_request_error(req,
     468             :                                         NT_STATUS_INVALID_PARAMETER);
     469             :                 }
     470             : 
     471       23486 :                 hash_count = SVAL(in_preauth->data.data, 0);
     472       23486 :                 salt_length = SVAL(in_preauth->data.data, 2);
     473             : 
     474       23486 :                 if (hash_count == 0) {
     475           0 :                         return smbd_smb2_request_error(req,
     476             :                                         NT_STATUS_INVALID_PARAMETER);
     477             :                 }
     478             : 
     479       23486 :                 p = in_preauth->data.data + needed;
     480       23486 :                 needed += hash_count * 2;
     481       23486 :                 needed += salt_length;
     482             : 
     483       23486 :                 if (in_preauth->data.length < needed) {
     484           0 :                         return smbd_smb2_request_error(req,
     485             :                                         NT_STATUS_INVALID_PARAMETER);
     486             :                 }
     487             : 
     488       23486 :                 for (i=0; i < hash_count; i++) {
     489         705 :                         uint16_t v;
     490             : 
     491       23486 :                         v = SVAL(p, 0);
     492       23486 :                         p += 2;
     493             : 
     494       23486 :                         if (v == SMB2_PREAUTH_INTEGRITY_SHA512) {
     495       22781 :                                 selected_preauth = v;
     496       22781 :                                 break;
     497             :                         }
     498             :                 }
     499             : 
     500       23486 :                 if (selected_preauth == 0) {
     501           0 :                         return smbd_smb2_request_error(req,
     502             :                                 NT_STATUS_SMB_NO_PREAUTH_INTEGRITY_HASH_OVERLAP);
     503             :                 }
     504             : 
     505       23486 :                 SSVAL(buf, 0,  1); /* HashAlgorithmCount */
     506       23486 :                 SSVAL(buf, 2, 32); /* SaltLength */
     507       23486 :                 SSVAL(buf, 4, selected_preauth);
     508       23486 :                 generate_random_buffer(buf + 6, 32);
     509             : 
     510       23486 :                 status = smb2_negotiate_context_add(
     511             :                         req,
     512             :                         &out_c,
     513             :                         SMB2_PREAUTH_INTEGRITY_CAPABILITIES,
     514             :                         buf,
     515             :                         sizeof(buf));
     516       23486 :                 if (!NT_STATUS_IS_OK(status)) {
     517           0 :                         return smbd_smb2_request_error(req, status);
     518             :                 }
     519             : 
     520       23486 :                 req->preauth = &req->xconn->smb2.preauth;
     521             :         }
     522             : 
     523       42764 :         if (protocol >= PROTOCOL_SMB3_00) {
     524       23602 :                 xconn->smb2.server.sign_algo = SMB2_SIGNING_AES128_CMAC;
     525             :         } else {
     526       19162 :                 xconn->smb2.server.sign_algo = SMB2_SIGNING_HMAC_SHA256;
     527             :         }
     528             : 
     529       42764 :         if ((capabilities & SMB2_CAP_ENCRYPTION) && (in_cipher != NULL)) {
     530       23274 :                 const struct smb3_encryption_capabilities *srv_ciphers =
     531             :                         &default_smb3_capabilities.encryption;
     532       23274 :                 uint16_t srv_preferred_idx = UINT16_MAX;
     533       23274 :                 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       23274 :                 capabilities &= ~SMB2_CAP_ENCRYPTION;
     540             : 
     541       23274 :                 if (in_cipher->data.length < needed) {
     542           0 :                         return smbd_smb2_request_error(req,
     543             :                                         NT_STATUS_INVALID_PARAMETER);
     544             :                 }
     545             : 
     546       23274 :                 cipher_count = SVAL(in_cipher->data.data, 0);
     547       23274 :                 if (cipher_count == 0) {
     548           0 :                         return smbd_smb2_request_error(req,
     549             :                                         NT_STATUS_INVALID_PARAMETER);
     550             :                 }
     551             : 
     552       23274 :                 p = in_cipher->data.data + needed;
     553       23274 :                 needed += cipher_count * 2;
     554             : 
     555       23274 :                 if (in_cipher->data.length < needed) {
     556           0 :                         return smbd_smb2_request_error(req,
     557             :                                         NT_STATUS_INVALID_PARAMETER);
     558             :                 }
     559             : 
     560      115326 :                 for (i=0; i < cipher_count; i++) {
     561        2646 :                         uint16_t si;
     562        2646 :                         uint16_t v;
     563             : 
     564       92052 :                         v = SVAL(p, 0);
     565       92052 :                         p += 2;
     566             : 
     567      229836 :                         for (si = 0; si < srv_ciphers->num_algos; si++) {
     568      229836 :                                 if (srv_ciphers->algos[si] != v) {
     569      137784 :                                         continue;
     570             :                                 }
     571             : 
     572             :                                 /*
     573             :                                  * The server ciphers are listed
     574             :                                  * with the lowest idx being preferred.
     575             :                                  */
     576       92052 :                                 if (si < srv_preferred_idx) {
     577       22569 :                                         srv_preferred_idx = si;
     578             :                                 }
     579       89406 :                                 break;
     580             :                         }
     581             :                 }
     582             : 
     583       23274 :                 if (srv_preferred_idx != UINT16_MAX) {
     584       23274 :                         xconn->smb2.server.cipher =
     585       23274 :                                 srv_ciphers->algos[srv_preferred_idx];
     586             :                 }
     587             : 
     588       23274 :                 SSVAL(buf, 0, 1); /* ChiperCount */
     589       23274 :                 SSVAL(buf, 2, xconn->smb2.server.cipher);
     590             : 
     591       23274 :                 status = smb2_negotiate_context_add(
     592             :                         req,
     593             :                         &out_c,
     594             :                         SMB2_ENCRYPTION_CAPABILITIES,
     595             :                         buf,
     596             :                         sizeof(buf));
     597       23274 :                 if (!NT_STATUS_IS_OK(status)) {
     598           0 :                         return smbd_smb2_request_error(req, status);
     599             :                 }
     600             :         }
     601             : 
     602       42764 :         if (capabilities & SMB2_CAP_ENCRYPTION) {
     603         104 :                 xconn->smb2.server.cipher = SMB2_ENCRYPTION_AES128_CCM;
     604             :         }
     605             : 
     606       42764 :         if (in_sign_algo != NULL) {
     607       23486 :                 const struct smb3_signing_capabilities *srv_sign_algos =
     608             :                         &default_smb3_capabilities.signing;
     609       23486 :                 uint16_t srv_preferred_idx = UINT16_MAX;
     610       23486 :                 size_t needed = 2;
     611         705 :                 uint16_t sign_algo_count;
     612         705 :                 const uint8_t *p;
     613         705 :                 size_t i;
     614             : 
     615       23486 :                 if (in_sign_algo->data.length < needed) {
     616           0 :                         return smbd_smb2_request_error(req,
     617             :                                         NT_STATUS_INVALID_PARAMETER);
     618             :                 }
     619             : 
     620       23486 :                 sign_algo_count = SVAL(in_sign_algo->data.data, 0);
     621       23486 :                 if (sign_algo_count == 0) {
     622           0 :                         return smbd_smb2_request_error(req,
     623             :                                         NT_STATUS_INVALID_PARAMETER);
     624             :                 }
     625             : 
     626       23486 :                 p = in_sign_algo->data.data + needed;
     627       23486 :                 needed += sign_algo_count * 2;
     628             : 
     629       23486 :                 if (in_sign_algo->data.length < needed) {
     630           0 :                         return smbd_smb2_request_error(req,
     631             :                                         NT_STATUS_INVALID_PARAMETER);
     632             :                 }
     633             : 
     634       92292 :                 for (i=0; i < sign_algo_count; i++) {
     635        1831 :                         uint16_t si;
     636        1831 :                         uint16_t v;
     637             : 
     638       68806 :                         v = SVAL(p, 0);
     639       68806 :                         p += 2;
     640             : 
     641      137442 :                         for (si = 0; si < srv_sign_algos->num_algos; si++) {
     642      137442 :                                 if (srv_sign_algos->algos[si] != v) {
     643       68636 :                                         continue;
     644             :                                 }
     645             : 
     646             :                                 /*
     647             :                                  * The server sign_algos are listed
     648             :                                  * with the lowest idx being preferred.
     649             :                                  */
     650       68806 :                                 if (si < srv_preferred_idx) {
     651       22781 :                                         srv_preferred_idx = si;
     652             :                                 }
     653       66975 :                                 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       23486 :                 if (srv_preferred_idx != UINT16_MAX) {
     663         705 :                         uint8_t buf[4];
     664             : 
     665       23486 :                         xconn->smb2.server.sign_algo =
     666       23486 :                                 srv_sign_algos->algos[srv_preferred_idx];
     667             : 
     668       23486 :                         SSVAL(buf, 0, 1); /* SigningAlgorithmCount */
     669       23486 :                         SSVAL(buf, 2, xconn->smb2.server.sign_algo);
     670             : 
     671       23486 :                         status = smb2_negotiate_context_add(
     672             :                                 req,
     673             :                                 &out_c,
     674             :                                 SMB2_SIGNING_CAPABILITIES,
     675             :                                 buf,
     676             :                                 sizeof(buf));
     677       23486 :                         if (!NT_STATUS_IS_OK(status)) {
     678           0 :                                 return smbd_smb2_request_error(req, status);
     679             :                         }
     680             :                 }
     681             :         }
     682             : 
     683       43907 :         status = smb311_capabilities_check(&default_smb3_capabilities,
     684             :                                            "smb2srv_negprot",
     685             :                                            DBGLVL_NOTICE,
     686       42764 :                                            NT_STATUS_INVALID_PARAMETER,
     687             :                                            "server",
     688             :                                            protocol,
     689       42764 :                                            xconn->smb2.server.sign_algo,
     690       42764 :                                            xconn->smb2.server.cipher);
     691       42764 :         if (!NT_STATUS_IS_OK(status)) {
     692           0 :                 return smbd_smb2_request_error(req, status);
     693             :         }
     694             : 
     695       42764 :         if (protocol >= PROTOCOL_SMB3_00 &&
     696       23602 :             xconn->client->server_multi_channel_enabled)
     697             :         {
     698       23602 :                 if (in_capabilities & SMB2_CAP_MULTI_CHANNEL) {
     699       23602 :                         capabilities |= SMB2_CAP_MULTI_CHANNEL;
     700             :                 }
     701             :         }
     702             : 
     703       42764 :         security_offset = SMB2_HDR_BODY + 0x40;
     704             : 
     705             : #if 1
     706             :         /* Try SPNEGO auth... */
     707       42764 :         security_buffer = data_blob_const(negprot_spnego_blob.data + 16,
     708       41621 :                                           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       42764 :         if (posix) {
     715             :                 /* Client correctly negotiated SMB2 unix extensions. */
     716        5644 :                 const uint8_t *buf = (const uint8_t *)SMB2_CREATE_TAG_POSIX;
     717        5644 :                 status = smb2_negotiate_context_add(
     718             :                                 req,
     719             :                                 &out_c,
     720             :                                 SMB2_POSIX_EXTENSIONS_AVAILABLE,
     721             :                                 buf,
     722             :                                 16);
     723        5644 :                 if (!NT_STATUS_IS_OK(status)) {
     724           0 :                         return smbd_smb2_request_error(req, status);
     725             :                 }
     726        5644 :                 xconn->smb2.server.posix_extensions_negotiated = true;
     727             :         }
     728             : 
     729       42764 :         if (out_c.num_contexts != 0) {
     730       23486 :                 status = smb2_negotiate_context_push(req,
     731             :                                                 &out_negotiate_context_blob,
     732             :                                                 out_c);
     733       23486 :                 if (!NT_STATUS_IS_OK(status)) {
     734           0 :                         return smbd_smb2_request_error(req, status);
     735             :                 }
     736             :         }
     737             : 
     738       42764 :         if (out_negotiate_context_blob.length != 0) {
     739         705 :                 static const uint8_t zeros[8];
     740       23486 :                 size_t pad = 0;
     741         705 :                 size_t ofs;
     742             : 
     743       23486 :                 outdyn = data_blob_dup_talloc(req, security_buffer);
     744       23486 :                 if (outdyn.length != security_buffer.length) {
     745           0 :                         return smbd_smb2_request_error(req,
     746             :                                                 NT_STATUS_NO_MEMORY);
     747             :                 }
     748             : 
     749       23486 :                 ofs = security_offset + security_buffer.length;
     750       23486 :                 if ((ofs % 8) != 0) {
     751       15171 :                         pad = 8 - (ofs % 8);
     752             :                 }
     753       23486 :                 ofs += pad;
     754             : 
     755       23486 :                 ok = data_blob_append(req, &outdyn, zeros, pad);
     756       23486 :                 if (!ok) {
     757           0 :                         return smbd_smb2_request_error(req,
     758             :                                                 NT_STATUS_NO_MEMORY);
     759             :                 }
     760             : 
     761       24191 :                 ok = data_blob_append(req, &outdyn,
     762       23486 :                                       out_negotiate_context_blob.data,
     763             :                                       out_negotiate_context_blob.length);
     764       23486 :                 if (!ok) {
     765           0 :                         return smbd_smb2_request_error(req,
     766             :                                                 NT_STATUS_NO_MEMORY);
     767             :                 }
     768             : 
     769       23486 :                 out_negotiate_context_offset = ofs;
     770       23486 :                 out_negotiate_context_count = out_c.num_contexts;
     771             :         } else {
     772       19278 :                 outdyn = security_buffer;
     773             :         }
     774             : 
     775       42764 :         out_guid_blob = data_blob_const(negprot_spnego_blob.data, 16);
     776       42764 :         status = GUID_from_ndr_blob(&out_guid_blob, &out_guid);
     777       42764 :         if (!NT_STATUS_IS_OK(status)) {
     778           0 :                 return smbd_smb2_request_error(req, status);
     779             :         }
     780             : 
     781       42764 :         outbody = smbd_smb2_generate_outbody(req, 0x40);
     782       42764 :         if (outbody.data == NULL) {
     783           0 :                 return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
     784             :         }
     785             : 
     786       42764 :         SSVAL(outbody.data, 0x00, 0x40 + 1);    /* struct size */
     787       42764 :         SSVAL(outbody.data, 0x02,
     788             :               security_mode);                   /* security mode */
     789       42764 :         SSVAL(outbody.data, 0x04, dialect);     /* dialect revision */
     790       42764 :         SSVAL(outbody.data, 0x06,
     791             :               out_negotiate_context_count);     /* reserved/NegotiateContextCount */
     792       42764 :         memcpy(outbody.data + 0x08,
     793       42764 :                out_guid_blob.data, 16); /* server guid */
     794       42764 :         SIVAL(outbody.data, 0x18,
     795             :               capabilities);                    /* capabilities */
     796       42764 :         SIVAL(outbody.data, 0x1C, max_trans);   /* max transact size */
     797       42764 :         SIVAL(outbody.data, 0x20, max_read);    /* max read size */
     798       42764 :         SIVAL(outbody.data, 0x24, max_write);   /* max write size */
     799       42764 :         SBVAL(outbody.data, 0x28, now);         /* system time */
     800       42764 :         SBVAL(outbody.data, 0x30, 0);           /* server start time */
     801       42764 :         SSVAL(outbody.data, 0x38,
     802             :               security_offset);                 /* security buffer offset */
     803       42764 :         SSVAL(outbody.data, 0x3A,
     804             :               security_buffer.length);          /* security buffer length */
     805       42764 :         SIVAL(outbody.data, 0x3C,
     806             :               out_negotiate_context_offset);    /* reserved/NegotiateContextOffset */
     807             : 
     808       42764 :         if (dialect == SMB2_DIALECT_REVISION_2FF) {
     809       16572 :                 return smbd_smb2_request_done(req, outbody, &outdyn);
     810             :         }
     811             : 
     812       26192 :         status = smbXsrv_connection_init_tables(xconn, protocol);
     813       26192 :         if (!NT_STATUS_IS_OK(status)) {
     814           0 :                 return smbd_smb2_request_error(req, status);
     815             :         }
     816             : 
     817       26192 :         xconn->smb2.client.capabilities = in_capabilities;
     818       26192 :         xconn->smb2.client.security_mode = in_security_mode;
     819       26192 :         xconn->smb2.client.guid = in_guid;
     820       26192 :         xconn->smb2.client.num_dialects = dialect_count;
     821       26192 :         xconn->smb2.client.dialects = talloc_array(xconn,
     822             :                                                    uint16_t,
     823             :                                                    dialect_count);
     824       26192 :         if (xconn->smb2.client.dialects == NULL) {
     825           0 :                 return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
     826             :         }
     827      150969 :         for (c=0; c < dialect_count; c++) {
     828      124777 :                 xconn->smb2.client.dialects[c] = SVAL(indyn, c*2);
     829             :         }
     830             : 
     831       26192 :         xconn->smb2.server.capabilities = capabilities;
     832       26192 :         xconn->smb2.server.security_mode = security_mode;
     833       26192 :         xconn->smb2.server.guid = out_guid;
     834       26192 :         xconn->smb2.server.dialect = dialect;
     835       26192 :         xconn->smb2.server.max_trans = max_trans;
     836       26192 :         xconn->smb2.server.max_read  = max_read;
     837       26192 :         xconn->smb2.server.max_write = max_write;
     838             : 
     839       26192 :         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       26110 :         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       26110 :         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       25004 :         state = talloc_zero(req, struct smbd_smb2_request_process_negprot_state);
     869       25004 :         if (state == NULL) {
     870           0 :                 return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
     871             :         }
     872       25004 :         *state = (struct smbd_smb2_request_process_negprot_state) {
     873             :                 .req = req,
     874             :                 .outbody = outbody,
     875             :                 .outdyn = outdyn,
     876             :         };
     877             : 
     878       25701 :         subreq = smb2srv_client_mc_negprot_send(state,
     879       25004 :                                                 req->xconn->client->raw_ev_ctx,
     880             :                                                 req);
     881       25004 :         if (subreq == NULL) {
     882           0 :                 return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY);
     883             :         }
     884       25004 :         tevent_req_set_callback(subreq,
     885             :                                 smbd_smb2_request_process_negprot_mc_done,
     886             :                                 state);
     887       25004 :         return NT_STATUS_OK;
     888             : }
     889             : 
     890       25004 : static void smbd_smb2_request_process_negprot_mc_done(struct tevent_req *subreq)
     891             : {
     892         697 :         struct smbd_smb2_request_process_negprot_state *state =
     893       25004 :                 tevent_req_callback_data(subreq,
     894             :                 struct smbd_smb2_request_process_negprot_state);
     895       25004 :         struct smbd_smb2_request *req = state->req;
     896       25004 :         struct smbXsrv_connection *xconn = req->xconn;
     897         697 :         NTSTATUS status;
     898             : 
     899       25004 :         status = smb2srv_client_mc_negprot_recv(subreq);
     900       25004 :         TALLOC_FREE(subreq);
     901       25004 :         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       23836 :         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       23836 :         status = smbd_smb2_request_done(req, state->outbody, &state->outdyn);
     941       23836 :         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       23191 :                 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         645 :         return;
     967             : }
     968             : 
     969             : /****************************************************************************
     970             :  Generate the spnego negprot reply blob. Return the number of bytes used.
     971             : ****************************************************************************/
     972             : 
     973       48443 : DATA_BLOB negprot_spnego(TALLOC_CTX *ctx, struct smbXsrv_connection *xconn)
     974             : {
     975       48443 :         DATA_BLOB blob = data_blob_null;
     976       48443 :         DATA_BLOB blob_out = data_blob_null;
     977        1276 :         nstring dos_name;
     978        1276 :         fstring unix_name;
     979        1276 :         NTSTATUS status;
     980             : #ifdef DEVELOPER
     981        1276 :         size_t slen;
     982             : #endif
     983        1276 :         struct gensec_security *gensec_security;
     984             : 
     985             :         /* See if we can get an SPNEGO blob */
     986       48443 :         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       48443 :         if (NT_STATUS_IS_OK(status)) {
     999       48443 :                 status = gensec_start_mech_by_oid(gensec_security, GENSEC_OID_SPNEGO);
    1000       48443 :                 if (NT_STATUS_IS_OK(status)) {
    1001       48443 :                         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       48443 :                         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       48443 :                 TALLOC_FREE(gensec_security);
    1011             :         }
    1012             : 
    1013             : #if defined(WITH_SMB1SERVER)
    1014       48443 :         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       48443 :         if (blob.length == 0 || blob.data == NULL) {
    1031           0 :                 return data_blob_null;
    1032             :         }
    1033             : 
    1034       48443 :         blob_out = data_blob_talloc(ctx, NULL, 16 + blob.length);
    1035       48443 :         if (blob_out.data == NULL) {
    1036           0 :                 data_blob_free(&blob);
    1037           0 :                 return data_blob_null;
    1038             :         }
    1039             : 
    1040       48443 :         memset(blob_out.data, '\0', 16);
    1041             : 
    1042       48443 :         checked_strlcpy(unix_name, lp_netbios_name(), sizeof(unix_name));
    1043       48443 :         (void)strlower_m(unix_name);
    1044       48443 :         push_ascii_nstring(dos_name, unix_name);
    1045       48443 :         strlcpy((char *)blob_out.data, dos_name, 17);
    1046             : 
    1047             : #ifdef DEVELOPER
    1048             :         /* Fix valgrind 'uninitialized bytes' issue. */
    1049       48443 :         slen = strlen(dos_name);
    1050       48443 :         if (slen < 16) {
    1051       48443 :                 memset(blob_out.data+slen, '\0', 16 - slen);
    1052             :         }
    1053             : #endif
    1054             : 
    1055       48443 :         memcpy(&blob_out.data[16], blob.data, blob.length);
    1056             : 
    1057       48443 :         data_blob_free(&blob);
    1058             : 
    1059       48443 :         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       16757 : NTSTATUS smb2_multi_protocol_reply_negprot(struct smb_request *req)
    1093             : {
    1094       16757 :         size_t choice = 0;
    1095       16757 :         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       16757 :         struct smbXsrv_connection *xconn = req->xconn;
    1103       16757 :         struct smbd_server_connection *sconn = req->sconn;
    1104         390 :         int max_proto;
    1105         390 :         int min_proto;
    1106         390 :         NTSTATUS status;
    1107             : 
    1108       16757 :         START_PROFILE(SMBnegprot);
    1109             : 
    1110       16757 :         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       16757 :         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       16755 :         p = (const char *)req->buf + 1;
    1125             : 
    1126       16755 :         num_cliprotos = 0;
    1127       16755 :         cliprotos = NULL;
    1128             : 
    1129      166195 :         while (smbreq_bufrem(req, p) > 0) {
    1130             : 
    1131        1608 :                 char **tmp;
    1132             : 
    1133      149440 :                 tmp = talloc_realloc(talloc_tos(), cliprotos, char *,
    1134             :                                            num_cliprotos+1);
    1135      149440 :                 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      149440 :                 cliprotos = tmp;
    1144             : 
    1145      149440 :                 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      149440 :                 DEBUG(3, ("Requested protocol [%s]\n",
    1155             :                           cliprotos[num_cliprotos]));
    1156             : 
    1157      149440 :                 num_cliprotos += 1;
    1158      149440 :                 p += strlen(p) + 2;
    1159             :         }
    1160             : 
    1161             :         /* possibly reload - change of architecture */
    1162       16755 :         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       16755 :         max_proto = lp_server_max_protocol();
    1173       16755 :         if (max_proto > PROTOCOL_SMB2_10) {
    1174       14927 :                 max_proto = PROTOCOL_SMB2_10;
    1175             :         }
    1176       16755 :         min_proto = lp_server_min_protocol();
    1177       16755 :         if (min_proto > PROTOCOL_SMB2_10) {
    1178           0 :                 min_proto = PROTOCOL_SMB2_10;
    1179             :         }
    1180             : 
    1181             :         /* Check for protocols, most desirable first */
    1182       17771 :         for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
    1183       17281 :                 i = 0;
    1184       17281 :                 if ((supported_protocols[protocol].protocol_level <= max_proto) &&
    1185       16833 :                     (supported_protocols[protocol].protocol_level >= min_proto))
    1186      171159 :                         while (i < num_cliprotos) {
    1187      153928 :                                 if (strequal(cliprotos[i],supported_protocols[protocol].proto_name)) {
    1188       16265 :                                         choice = i;
    1189       16265 :                                         choice_set = true;
    1190             :                                 }
    1191      153928 :                                 i++;
    1192             :                         }
    1193       17281 :                 if (choice_set) {
    1194       15883 :                         break;
    1195             :                 }
    1196             :         }
    1197             : 
    1198       16755 :         if (!choice_set) {
    1199           8 :                 bool ok;
    1200             : 
    1201         490 :                 DBG_NOTICE("No protocol supported !\n");
    1202         490 :                 reply_smb1_outbuf(req, 1, 0);
    1203         490 :                 SSVAL(req->outbuf, smb_vwv0, NO_PROTOCOL_CHOSEN);
    1204             : 
    1205         490 :                 ok = smb1_srv_send(xconn, (char *)req->outbuf, false, 0, false);
    1206         490 :                 if (!ok) {
    1207           0 :                         DBG_NOTICE("smb1_srv_send failed\n");
    1208             :                 }
    1209         490 :                 exit_server_cleanly("no protocol supported\n");
    1210             :         }
    1211             : 
    1212       16265 :         set_remote_proto(supported_protocols[protocol].short_name);
    1213       16265 :         reload_services(sconn, conn_snum_used, true);
    1214       16265 :         status = supported_protocols[protocol].proto_reply_fn(req, choice);
    1215       16265 :         if (!NT_STATUS_IS_OK(status)) {
    1216           0 :                 exit_server_cleanly("negprot function failed\n");
    1217             :         }
    1218             : 
    1219       16265 :         DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
    1220             : 
    1221       16265 :         DBG_INFO("negprot index=%zu\n", choice);
    1222             : 
    1223       16265 :         TALLOC_FREE(cliprotos);
    1224             : 
    1225       16265 :         END_PROFILE(SMBnegprot);
    1226       16265 :         return NT_STATUS_OK;
    1227             : }

Generated by: LCOV version 1.14