LCOV - code coverage report
Current view: top level - source3/smbd - negprot.c (source / functions) Hit Total Coverage
Test: coverage report for master 6248eab5 Lines: 217 347 62.5 %
Date: 2021-08-25 13:27:56 Functions: 4 6 66.7 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    negprot reply code
       4             :    Copyright (C) Andrew Tridgell 1992-1998
       5             :    Copyright (C) Volker Lendecke 2007
       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 "serverid.h"
      25             : #include "auth.h"
      26             : #include "messages.h"
      27             : #include "smbprofile.h"
      28             : #include "auth/gensec/gensec.h"
      29             : #include "../libcli/smb/smb_signing.h"
      30             : #include "lib/util/string_wrappers.h"
      31             : 
      32             : /*
      33             :  * MS-CIFS, 2.2.4.52.2 SMB_COM_NEGOTIATE Response:
      34             :  * If the server does not support any of the listed dialects, it MUST return a
      35             :  * DialectIndex of 0XFFFF
      36             :  */
      37             : #define NO_PROTOCOL_CHOSEN      0xffff
      38             : 
      39             : extern fstring remote_proto;
      40             : 
      41          67 : static void get_challenge(struct smbXsrv_connection *xconn, uint8_t buff[8])
      42             : {
      43             :         NTSTATUS nt_status;
      44             : 
      45             :         /* We might be called more than once, multiple negprots are
      46             :          * permitted */
      47          67 :         if (xconn->smb1.negprot.auth_context) {
      48           0 :                 DEBUG(3, ("get challenge: is this a secondary negprot? "
      49             :                           "sconn->negprot.auth_context is non-NULL!\n"));
      50           0 :                 TALLOC_FREE(xconn->smb1.negprot.auth_context);
      51             :         }
      52             : 
      53          67 :         DEBUG(10, ("get challenge: creating negprot_global_auth_context\n"));
      54          67 :         nt_status = make_auth4_context(
      55             :                 xconn, &xconn->smb1.negprot.auth_context);
      56          67 :         if (!NT_STATUS_IS_OK(nt_status)) {
      57           0 :                 DEBUG(0, ("make_auth_context_subsystem returned %s",
      58             :                           nt_errstr(nt_status)));
      59           0 :                 smb_panic("cannot make_negprot_global_auth_context!");
      60             :         }
      61          67 :         DEBUG(10, ("get challenge: getting challenge\n"));
      62          67 :         xconn->smb1.negprot.auth_context->get_ntlm_challenge(
      63             :                 xconn->smb1.negprot.auth_context, buff);
      64          67 : }
      65             : 
      66             : /****************************************************************************
      67             :  Reply for the lanman 1.0 protocol.
      68             : ****************************************************************************/
      69             : 
      70           0 : static NTSTATUS reply_lanman1(struct smb_request *req, uint16_t choice)
      71             : {
      72           0 :         int secword=0;
      73           0 :         time_t t = time(NULL);
      74           0 :         struct smbXsrv_connection *xconn = req->xconn;
      75             :         uint16_t raw;
      76             :         NTSTATUS status;
      77             : 
      78           0 :         if (lp_async_smb_echo_handler()) {
      79           0 :                 raw = 0;
      80             :         } else {
      81           0 :                 raw = (lp_read_raw()?1:0) | (lp_write_raw()?2:0);
      82             :         }
      83             : 
      84           0 :         xconn->smb1.negprot.encrypted_passwords = lp_encrypt_passwords();
      85             : 
      86           0 :         secword |= NEGOTIATE_SECURITY_USER_LEVEL;
      87           0 :         if (xconn->smb1.negprot.encrypted_passwords) {
      88           0 :                 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
      89             :         }
      90             : 
      91           0 :         reply_outbuf(req, 13, xconn->smb1.negprot.encrypted_passwords?8:0);
      92             : 
      93           0 :         SSVAL(req->outbuf,smb_vwv0,choice);
      94           0 :         SSVAL(req->outbuf,smb_vwv1,secword);
      95             :         /* Create a token value and add it to the outgoing packet. */
      96           0 :         if (xconn->smb1.negprot.encrypted_passwords) {
      97           0 :                 get_challenge(xconn, (uint8_t *)smb_buf(req->outbuf));
      98           0 :                 SSVAL(req->outbuf,smb_vwv11, 8);
      99             :         }
     100             : 
     101           0 :         status = smbXsrv_connection_init_tables(xconn, PROTOCOL_LANMAN1);
     102           0 :         if (!NT_STATUS_IS_OK(status)) {
     103           0 :                 reply_nterror(req, status);
     104           0 :                 return status;
     105             :         }
     106             : 
     107             :         /* Reply, SMBlockread, SMBwritelock supported. */
     108           0 :         SCVAL(req->outbuf,smb_flg, FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
     109           0 :         SSVAL(req->outbuf,smb_vwv2, xconn->smb1.negprot.max_recv);
     110           0 :         SSVAL(req->outbuf,smb_vwv3, lp_max_mux()); /* maxmux */
     111           0 :         SSVAL(req->outbuf,smb_vwv4, 1);
     112           0 :         SSVAL(req->outbuf,smb_vwv5, raw); /* tell redirector we support
     113             :                 readbraw writebraw (possibly) */
     114           0 :         SIVAL(req->outbuf,smb_vwv6, getpid());
     115           0 :         SSVAL(req->outbuf,smb_vwv10, set_server_zone_offset(t)/60);
     116             : 
     117           0 :         srv_put_dos_date((char *)req->outbuf,smb_vwv8,t);
     118             : 
     119           0 :         return NT_STATUS_OK;
     120             : }
     121             : 
     122             : /****************************************************************************
     123             :  Reply for the lanman 2.0 protocol.
     124             : ****************************************************************************/
     125             : 
     126           0 : static NTSTATUS reply_lanman2(struct smb_request *req, uint16_t choice)
     127             : {
     128           0 :         int secword=0;
     129           0 :         time_t t = time(NULL);
     130           0 :         struct smbXsrv_connection *xconn = req->xconn;
     131             :         uint16_t raw;
     132             :         NTSTATUS status;
     133             : 
     134           0 :         if (lp_async_smb_echo_handler()) {
     135           0 :                 raw = 0;
     136             :         } else {
     137           0 :                 raw = (lp_read_raw()?1:0) | (lp_write_raw()?2:0);
     138             :         }
     139             : 
     140           0 :         xconn->smb1.negprot.encrypted_passwords = lp_encrypt_passwords();
     141             : 
     142           0 :         secword |= NEGOTIATE_SECURITY_USER_LEVEL;
     143           0 :         if (xconn->smb1.negprot.encrypted_passwords) {
     144           0 :                 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
     145             :         }
     146             : 
     147           0 :         reply_outbuf(req, 13, xconn->smb1.negprot.encrypted_passwords?8:0);
     148             : 
     149           0 :         SSVAL(req->outbuf,smb_vwv0, choice);
     150           0 :         SSVAL(req->outbuf,smb_vwv1, secword);
     151           0 :         SIVAL(req->outbuf,smb_vwv6, getpid());
     152             : 
     153             :         /* Create a token value and add it to the outgoing packet. */
     154           0 :         if (xconn->smb1.negprot.encrypted_passwords) {
     155           0 :                 get_challenge(xconn, (uint8_t *)smb_buf(req->outbuf));
     156           0 :                 SSVAL(req->outbuf,smb_vwv11, 8);
     157             :         }
     158             : 
     159           0 :         status = smbXsrv_connection_init_tables(xconn, PROTOCOL_LANMAN2);
     160           0 :         if (!NT_STATUS_IS_OK(status)) {
     161           0 :                 reply_nterror(req, status);
     162           0 :                 return status;
     163             :         }
     164             : 
     165             :         /* Reply, SMBlockread, SMBwritelock supported. */
     166           0 :         SCVAL(req->outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
     167           0 :         SSVAL(req->outbuf,smb_vwv2,xconn->smb1.negprot.max_recv);
     168           0 :         SSVAL(req->outbuf,smb_vwv3,lp_max_mux());
     169           0 :         SSVAL(req->outbuf,smb_vwv4,1);
     170           0 :         SSVAL(req->outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
     171           0 :         SSVAL(req->outbuf,smb_vwv10, set_server_zone_offset(t)/60);
     172           0 :         srv_put_dos_date((char *)req->outbuf,smb_vwv8,t);
     173           0 :         return NT_STATUS_OK;
     174             : }
     175             : 
     176             : /****************************************************************************
     177             :  Generate the spnego negprot reply blob. Return the number of bytes used.
     178             : ****************************************************************************/
     179             : 
     180       42536 : DATA_BLOB negprot_spnego(TALLOC_CTX *ctx, struct smbXsrv_connection *xconn)
     181             : {
     182       42536 :         DATA_BLOB blob = data_blob_null;
     183       42536 :         DATA_BLOB blob_out = data_blob_null;
     184             :         nstring dos_name;
     185             :         fstring unix_name;
     186             :         NTSTATUS status;
     187             : #ifdef DEVELOPER
     188             :         size_t slen;
     189             : #endif
     190             :         struct gensec_security *gensec_security;
     191             : 
     192             :         /* See if we can get an SPNEGO blob */
     193       42536 :         status = auth_generic_prepare(talloc_tos(),
     194             :                                       xconn->remote_address,
     195             :                                       xconn->local_address,
     196             :                                       "SMB",
     197             :                                       &gensec_security);
     198             : 
     199             :         /*
     200             :          * Despite including it above, there is no need to set a
     201             :          * remote address or similar as we are just interested in the
     202             :          * SPNEGO blob, we never keep this context.
     203             :          */
     204             : 
     205       42536 :         if (NT_STATUS_IS_OK(status)) {
     206       42536 :                 status = gensec_start_mech_by_oid(gensec_security, GENSEC_OID_SPNEGO);
     207       42536 :                 if (NT_STATUS_IS_OK(status)) {
     208       42536 :                         status = gensec_update(gensec_security, ctx,
     209             :                                                data_blob_null, &blob);
     210             :                         /* If we get the list of OIDs, the 'OK' answer
     211             :                          * is NT_STATUS_MORE_PROCESSING_REQUIRED */
     212       42536 :                         if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
     213           0 :                                 DEBUG(0, ("Failed to start SPNEGO handler for negprot OID list!\n"));
     214           0 :                                 blob = data_blob_null;
     215             :                         }
     216             :                 }
     217       42536 :                 TALLOC_FREE(gensec_security);
     218             :         }
     219             : 
     220       42536 :         xconn->smb1.negprot.spnego = true;
     221             : 
     222             :         /* strangely enough, NT does not sent the single OID NTLMSSP when
     223             :            not a ADS member, it sends no OIDs at all
     224             : 
     225             :            OLD COMMENT : "we can't do this until we teach our sesssion setup parser to know
     226             :                    about raw NTLMSSP (clients send no ASN.1 wrapping if we do this)"
     227             : 
     228             :            Our sessionsetup code now handles raw NTLMSSP connects, so we can go
     229             :            back to doing what W2K3 does here. This is needed to make PocketPC 2003
     230             :            CIFS connections work with SPNEGO. See bugzilla bugs #1828 and #3133
     231             :            for details. JRA.
     232             : 
     233             :         */
     234             : 
     235       42536 :         if (blob.length == 0 || blob.data == NULL) {
     236           0 :                 return data_blob_null;
     237             :         }
     238             : 
     239       42536 :         blob_out = data_blob_talloc(ctx, NULL, 16 + blob.length);
     240       42536 :         if (blob_out.data == NULL) {
     241           0 :                 data_blob_free(&blob);
     242           0 :                 return data_blob_null;
     243             :         }
     244             : 
     245       43448 :         memset(blob_out.data, '\0', 16);
     246             : 
     247       42536 :         checked_strlcpy(unix_name, lp_netbios_name(), sizeof(unix_name));
     248       42536 :         (void)strlower_m(unix_name);
     249       42536 :         push_ascii_nstring(dos_name, unix_name);
     250       42536 :         strlcpy((char *)blob_out.data, dos_name, 17);
     251             : 
     252             : #ifdef DEVELOPER
     253             :         /* Fix valgrind 'uninitialized bytes' issue. */
     254       42536 :         slen = strlen(dos_name);
     255       42536 :         if (slen < 16) {
     256       42536 :                 memset(blob_out.data+slen, '\0', 16 - slen);
     257             :         }
     258             : #endif
     259             : 
     260       43448 :         memcpy(&blob_out.data[16], blob.data, blob.length);
     261             : 
     262       42536 :         data_blob_free(&blob);
     263             : 
     264       42536 :         return blob_out;
     265             : }
     266             : 
     267             : /****************************************************************************
     268             :  Reply for the nt protocol.
     269             : ****************************************************************************/
     270             : 
     271        4856 : static NTSTATUS reply_nt1(struct smb_request *req, uint16_t choice)
     272             : {
     273             :         /* dual names + lock_and_read + nt SMBs + remote API calls */
     274        4856 :         int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|
     275             :                 CAP_LEVEL_II_OPLOCKS;
     276             : 
     277        4856 :         int secword=0;
     278        4856 :         bool negotiate_spnego = False;
     279             :         struct timespec ts;
     280             :         ssize_t ret;
     281        4856 :         struct smbXsrv_connection *xconn = req->xconn;
     282        4856 :         bool signing_desired = false;
     283        4856 :         bool signing_required = false;
     284             :         NTSTATUS status;
     285             : 
     286        4856 :         xconn->smb1.negprot.encrypted_passwords = lp_encrypt_passwords();
     287             : 
     288             :         /* Check the flags field to see if this is Vista.
     289             :            WinXP sets it and Vista does not. But we have to 
     290             :            distinguish from NT which doesn't set it either. */
     291             : 
     292        9513 :         if ( (req->flags2 & FLAGS2_EXTENDED_SECURITY) &&
     293        4657 :                 ((req->flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED) == 0) )
     294             :         {
     295        4838 :                 if ((get_remote_arch() != RA_SAMBA) &&
     296          49 :                                 (get_remote_arch() != RA_CIFSFS)) {
     297           0 :                         set_remote_arch( RA_VISTA );
     298             :                 }
     299             :         }
     300             : 
     301        4856 :         reply_outbuf(req,17,0);
     302             : 
     303             :         /* do spnego in user level security if the client
     304             :            supports it and we can do encrypted passwords */
     305             : 
     306        9712 :         if (xconn->smb1.negprot.encrypted_passwords &&
     307        4856 :             (req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
     308        4789 :                 negotiate_spnego = True;
     309        4789 :                 capabilities |= CAP_EXTENDED_SECURITY;
     310        4789 :                 add_to_common_flags2(FLAGS2_EXTENDED_SECURITY);
     311             :                 /* Ensure FLAGS2_EXTENDED_SECURITY gets set in this reply
     312             :                    (already partially constructed. */
     313        4789 :                 SSVAL(req->outbuf, smb_flg2,
     314             :                       req->flags2 | FLAGS2_EXTENDED_SECURITY);
     315             :         }
     316             : 
     317        4856 :         capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
     318             : 
     319        4856 :         if (lp_unicode()) {
     320        4856 :                 capabilities |= CAP_UNICODE;
     321             :         }
     322             : 
     323        4856 :         if (lp_unix_extensions()) {
     324        4856 :                 capabilities |= CAP_UNIX;
     325             :         }
     326             : 
     327        4856 :         if (lp_large_readwrite())
     328        4856 :                 capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_W2K_SMBS;
     329             : 
     330        4856 :         capabilities |= CAP_LARGE_FILES;
     331             : 
     332        4856 :         if (!lp_async_smb_echo_handler() && lp_read_raw() && lp_write_raw())
     333        4856 :                 capabilities |= CAP_RAW_MODE;
     334             : 
     335        4856 :         if (lp_nt_status_support())
     336        4856 :                 capabilities |= CAP_STATUS32;
     337             : 
     338        4856 :         if (lp_host_msdfs())
     339        4856 :                 capabilities |= CAP_DFS;
     340             : 
     341        4856 :         secword |= NEGOTIATE_SECURITY_USER_LEVEL;
     342        4856 :         if (xconn->smb1.negprot.encrypted_passwords) {
     343        4856 :                 secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
     344             :         }
     345             : 
     346        4856 :         signing_desired = smb_signing_is_desired(xconn->smb1.signing_state);
     347        4856 :         signing_required = smb_signing_is_mandatory(xconn->smb1.signing_state);
     348             : 
     349        4856 :         if (signing_desired) {
     350         805 :                 secword |= NEGOTIATE_SECURITY_SIGNATURES_ENABLED;
     351             :                 /* No raw mode with smb signing. */
     352         805 :                 capabilities &= ~CAP_RAW_MODE;
     353         805 :                 if (signing_required) {
     354         805 :                         secword |=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED;
     355             :                 }
     356             :         }
     357             : 
     358        4856 :         SSVAL(req->outbuf,smb_vwv0,choice);
     359        4856 :         SCVAL(req->outbuf,smb_vwv1,secword);
     360             : 
     361        4856 :         status = smbXsrv_connection_init_tables(xconn, PROTOCOL_NT1);
     362        4856 :         if (!NT_STATUS_IS_OK(status)) {
     363           0 :                 reply_nterror(req, status);
     364           0 :                 return status;
     365             :         }
     366             : 
     367        4856 :         SSVAL(req->outbuf,smb_vwv1+1, lp_max_mux()); /* maxmpx */
     368        4856 :         SSVAL(req->outbuf,smb_vwv2+1, 1); /* num vcs */
     369        4856 :         SIVAL(req->outbuf,smb_vwv3+1,
     370             :               xconn->smb1.negprot.max_recv); /* max buffer. LOTS! */
     371        4856 :         SIVAL(req->outbuf,smb_vwv5+1, 0x10000); /* raw size. full 64k */
     372        4856 :         SIVAL(req->outbuf,smb_vwv7+1, getpid()); /* session key */
     373        4856 :         SIVAL(req->outbuf,smb_vwv9+1, capabilities); /* capabilities */
     374        4856 :         clock_gettime(CLOCK_REALTIME,&ts);
     375        4856 :         put_long_date_full_timespec(TIMESTAMP_SET_NT_OR_BETTER,(char *)req->outbuf+smb_vwv11+1,&ts);
     376        4856 :         SSVALS(req->outbuf,smb_vwv15+1,set_server_zone_offset(ts.tv_sec)/60);
     377             : 
     378        4856 :         if (!negotiate_spnego) {
     379             :                 /* Create a token value and add it to the outgoing packet. */
     380          67 :                 if (xconn->smb1.negprot.encrypted_passwords) {
     381             :                         uint8_t chal[8];
     382             :                         /* note that we do not send a challenge at all if
     383             :                            we are using plaintext */
     384          67 :                         get_challenge(xconn, chal);
     385          67 :                         ret = message_push_blob(
     386             :                                 &req->outbuf, data_blob_const(chal, sizeof(chal)));
     387          67 :                         if (ret == -1) {
     388           0 :                                 DEBUG(0, ("Could not push challenge\n"));
     389           0 :                                 reply_nterror(req, NT_STATUS_NO_MEMORY);
     390           0 :                                 return NT_STATUS_NO_MEMORY;
     391             :                         }
     392          67 :                         SCVAL(req->outbuf, smb_vwv16+1, ret);
     393             :                 }
     394          67 :                 ret = message_push_string(&req->outbuf, lp_workgroup(),
     395             :                                           STR_UNICODE|STR_TERMINATE
     396             :                                           |STR_NOALIGN);
     397          67 :                 if (ret == -1) {
     398           0 :                         DEBUG(0, ("Could not push workgroup string\n"));
     399           0 :                         reply_nterror(req, NT_STATUS_NO_MEMORY);
     400           0 :                         return NT_STATUS_NO_MEMORY;
     401             :                 }
     402          67 :                 ret = message_push_string(&req->outbuf, lp_netbios_name(),
     403             :                                           STR_UNICODE|STR_TERMINATE
     404             :                                           |STR_NOALIGN);
     405          67 :                 if (ret == -1) {
     406           0 :                         DEBUG(0, ("Could not push netbios name string\n"));
     407           0 :                         reply_nterror(req, NT_STATUS_NO_MEMORY);
     408           0 :                         return NT_STATUS_NO_MEMORY;
     409             :                 }
     410          67 :                 DEBUG(3,("not using SPNEGO\n"));
     411             :         } else {
     412        4789 :                 DATA_BLOB spnego_blob = negprot_spnego(req, xconn);
     413             : 
     414        4789 :                 if (spnego_blob.data == NULL) {
     415           0 :                         reply_nterror(req, NT_STATUS_NO_MEMORY);
     416           0 :                         return NT_STATUS_NO_MEMORY;
     417             :                 }
     418             : 
     419        4789 :                 ret = message_push_blob(&req->outbuf, spnego_blob);
     420        4789 :                 if (ret == -1) {
     421           0 :                         DEBUG(0, ("Could not push spnego blob\n"));
     422           0 :                         reply_nterror(req, NT_STATUS_NO_MEMORY);
     423           0 :                         return NT_STATUS_NO_MEMORY;
     424             :                 }
     425        4789 :                 data_blob_free(&spnego_blob);
     426             : 
     427        4789 :                 SCVAL(req->outbuf,smb_vwv16+1, 0);
     428        4789 :                 DEBUG(3,("using SPNEGO\n"));
     429             :         }
     430             : 
     431        4856 :         return NT_STATUS_OK;
     432             : }
     433             : 
     434             : /* these are the protocol lists used for auto architecture detection:
     435             : 
     436             : WinNT 3.51:
     437             : protocol [PC NETWORK PROGRAM 1.0]
     438             : protocol [XENIX CORE]
     439             : protocol [MICROSOFT NETWORKS 1.03]
     440             : protocol [LANMAN1.0]
     441             : protocol [Windows for Workgroups 3.1a]
     442             : protocol [LM1.2X002]
     443             : protocol [LANMAN2.1]
     444             : protocol [NT LM 0.12]
     445             : 
     446             : Win95:
     447             : protocol [PC NETWORK PROGRAM 1.0]
     448             : protocol [XENIX CORE]
     449             : protocol [MICROSOFT NETWORKS 1.03]
     450             : protocol [LANMAN1.0]
     451             : protocol [Windows for Workgroups 3.1a]
     452             : protocol [LM1.2X002]
     453             : protocol [LANMAN2.1]
     454             : protocol [NT LM 0.12]
     455             : 
     456             : Win2K:
     457             : protocol [PC NETWORK PROGRAM 1.0]
     458             : protocol [LANMAN1.0]
     459             : protocol [Windows for Workgroups 3.1a]
     460             : protocol [LM1.2X002]
     461             : protocol [LANMAN2.1]
     462             : protocol [NT LM 0.12]
     463             : 
     464             : Vista:
     465             : protocol [PC NETWORK PROGRAM 1.0]
     466             : protocol [LANMAN1.0]
     467             : protocol [Windows for Workgroups 3.1a]
     468             : protocol [LM1.2X002]
     469             : protocol [LANMAN2.1]
     470             : protocol [NT LM 0.12]
     471             : protocol [SMB 2.001]
     472             : 
     473             : OS/2:
     474             : protocol [PC NETWORK PROGRAM 1.0]
     475             : protocol [XENIX CORE]
     476             : protocol [LANMAN1.0]
     477             : protocol [LM1.2X002]
     478             : protocol [LANMAN2.1]
     479             : 
     480             : OSX:
     481             : protocol [NT LM 0.12]
     482             : protocol [SMB 2.002]
     483             : protocol [SMB 2.???]
     484             : */
     485             : 
     486             : /*
     487             :   * Modified to recognize the architecture of the remote machine better.
     488             :   *
     489             :   * This appears to be the matrix of which protocol is used by which
     490             :   * product.
     491             :        Protocol                       WfWg Win95 WinNT Win2K OS/2 Vista OSX
     492             :        PC NETWORK PROGRAM 1.0          1     1     1     1     1    1
     493             :        XENIX CORE                                  2           2
     494             :        MICROSOFT NETWORKS 3.0          2     2
     495             :        DOS LM1.2X002                   3     3
     496             :        MICROSOFT NETWORKS 1.03                     3
     497             :        DOS LANMAN2.1                   4     4
     498             :        LANMAN1.0                                   4     2     3    2
     499             :        Windows for Workgroups 3.1a     5     5     5     3          3
     500             :        LM1.2X002                                   6     4     4    4
     501             :        LANMAN2.1                                   7     5     5    5
     502             :        NT LM 0.12                            6     8     6     6    6    1
     503             :        SMB 2.001                                                    7
     504             :        SMB 2.002                                                         2
     505             :        SMB 2.???                                                         3
     506             :   *
     507             :   *  tim@fsg.com 09/29/95
     508             :   *  Win2K added by matty 17/7/99
     509             :   */
     510             : 
     511             : #define PROT_PC_NETWORK_PROGRAM_1_0             0x0001
     512             : #define PROT_XENIX_CORE                         0x0002
     513             : #define PROT_MICROSOFT_NETWORKS_3_0             0x0004
     514             : #define PROT_DOS_LM1_2X002                      0x0008
     515             : #define PROT_MICROSOFT_NETWORKS_1_03            0x0010
     516             : #define PROT_DOS_LANMAN2_1                      0x0020
     517             : #define PROT_LANMAN1_0                          0x0040
     518             : #define PROT_WFWG                               0x0080
     519             : #define PROT_LM1_2X002                          0x0100
     520             : #define PROT_LANMAN2_1                          0x0200
     521             : #define PROT_NT_LM_0_12                         0x0400
     522             : #define PROT_SMB_2_001                          0x0800
     523             : #define PROT_SMB_2_002                          0x1000
     524             : #define PROT_SMB_2_FF                           0x2000
     525             : #define PROT_SAMBA                              0x4000
     526             : #define PROT_POSIX_2                            0x8000
     527             : 
     528             : #define ARCH_WFWG     ( PROT_PC_NETWORK_PROGRAM_1_0 | PROT_MICROSOFT_NETWORKS_3_0 | \
     529             :                         PROT_DOS_LM1_2X002 | PROT_DOS_LANMAN2_1 | PROT_WFWG )
     530             : #define ARCH_WIN95    ( ARCH_WFWG | PROT_NT_LM_0_12 )
     531             : #define ARCH_WINNT    ( PROT_PC_NETWORK_PROGRAM_1_0 | PROT_XENIX_CORE | \
     532             :                         PROT_MICROSOFT_NETWORKS_1_03 | PROT_LANMAN1_0 | PROT_WFWG | \
     533             :                         PROT_LM1_2X002 | PROT_LANMAN2_1 | PROT_NT_LM_0_12 )
     534             : #define ARCH_WIN2K    ( ARCH_WINNT & ~(PROT_XENIX_CORE | PROT_MICROSOFT_NETWORKS_1_03) )
     535             : #define ARCH_OS2      ( ARCH_WINNT & ~(PROT_MICROSOFT_NETWORKS_1_03 | PROT_WFWG) )
     536             : #define ARCH_VISTA    ( ARCH_WIN2K | PROT_SMB_2_001 )
     537             : #define ARCH_SAMBA    ( PROT_SAMBA )
     538             : #define ARCH_CIFSFS   ( PROT_POSIX_2 )
     539             : #define ARCH_OSX      ( PROT_NT_LM_0_12 | PROT_SMB_2_002 | PROT_SMB_2_FF )
     540             : 
     541             : /* List of supported protocols, most desired first */
     542             : static const struct {
     543             :         const char *proto_name;
     544             :         const char *short_name;
     545             :         NTSTATUS (*proto_reply_fn)(struct smb_request *req, uint16_t choice);
     546             :         int protocol_level;
     547             : } supported_protocols[] = {
     548             :         {"SMB 2.???",               "SMB2_FF",  reply_smb20ff,  PROTOCOL_SMB2_10},
     549             :         {"SMB 2.002",               "SMB2_02",  reply_smb2002,  PROTOCOL_SMB2_02},
     550             :         {"NT LANMAN 1.0",           "NT1",      reply_nt1,      PROTOCOL_NT1},
     551             :         {"NT LM 0.12",              "NT1",      reply_nt1,      PROTOCOL_NT1},
     552             :         {"POSIX 2",                 "NT1",      reply_nt1,      PROTOCOL_NT1},
     553             :         {"LANMAN2.1",               "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
     554             :         {"LM1.2X002",               "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
     555             :         {"Samba",                   "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
     556             :         {"DOS LM1.2X002",           "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},
     557             :         {"LANMAN1.0",               "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
     558             :         {"MICROSOFT NETWORKS 3.0",  "LANMAN1",  reply_lanman1,  PROTOCOL_LANMAN1},
     559             :         {NULL,NULL,NULL,0},
     560             : };
     561             : 
     562             : /****************************************************************************
     563             :  Reply to a negprot.
     564             :  conn POINTER CAN BE NULL HERE !
     565             : ****************************************************************************/
     566             : 
     567       20103 : void reply_negprot(struct smb_request *req)
     568             : {
     569       20103 :         size_t choice = 0;
     570       20103 :         int chosen_level = -1;
     571       20103 :         bool choice_set = false;
     572             :         int protocol;
     573             :         const char *p;
     574       20103 :         int protocols = 0;
     575             :         int num_cliprotos;
     576             :         char **cliprotos;
     577             :         size_t i;
     578             :         size_t converted_size;
     579       20103 :         struct smbXsrv_connection *xconn = req->xconn;
     580       20103 :         struct smbd_server_connection *sconn = req->sconn;
     581       20103 :         bool signing_required = true;
     582             :         int max_proto;
     583             :         int min_proto;
     584             :         NTSTATUS status;
     585             : 
     586       20103 :         START_PROFILE(SMBnegprot);
     587             : 
     588       20103 :         if (xconn->smb1.negprot.done) {
     589           4 :                 END_PROFILE(SMBnegprot);
     590           4 :                 exit_server_cleanly("multiple negprot's are not permitted");
     591             :         }
     592             : 
     593       20099 :         if (req->buflen == 0) {
     594           0 :                 DEBUG(0, ("negprot got no protocols\n"));
     595           0 :                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
     596           0 :                 END_PROFILE(SMBnegprot);
     597           0 :                 return;
     598             :         }
     599             : 
     600       20099 :         if (req->buf[req->buflen-1] != '\0') {
     601           2 :                 DEBUG(0, ("negprot protocols not 0-terminated\n"));
     602           2 :                 reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
     603           2 :                 END_PROFILE(SMBnegprot);
     604           2 :                 return;
     605             :         }
     606             : 
     607       20097 :         p = (const char *)req->buf + 1;
     608             : 
     609       20097 :         num_cliprotos = 0;
     610       20097 :         cliprotos = NULL;
     611             : 
     612      219972 :         while (smbreq_bufrem(req, p) > 0) {
     613             : 
     614             :                 char **tmp;
     615             : 
     616      179778 :                 tmp = talloc_realloc(talloc_tos(), cliprotos, char *,
     617             :                                            num_cliprotos+1);
     618      179778 :                 if (tmp == NULL) {
     619           0 :                         DEBUG(0, ("talloc failed\n"));
     620           0 :                         TALLOC_FREE(cliprotos);
     621           0 :                         reply_nterror(req, NT_STATUS_NO_MEMORY);
     622           0 :                         END_PROFILE(SMBnegprot);
     623           0 :                         return;
     624             :                 }
     625             : 
     626      179778 :                 cliprotos = tmp;
     627             : 
     628      179778 :                 if (!pull_ascii_talloc(cliprotos, &cliprotos[num_cliprotos], p,
     629             :                                        &converted_size)) {
     630           0 :                         DEBUG(0, ("pull_ascii_talloc failed\n"));
     631           0 :                         TALLOC_FREE(cliprotos);
     632           0 :                         reply_nterror(req, NT_STATUS_NO_MEMORY);
     633           0 :                         END_PROFILE(SMBnegprot);
     634           0 :                         return;
     635             :                 }
     636             : 
     637      179778 :                 DEBUG(3, ("Requested protocol [%s]\n",
     638             :                           cliprotos[num_cliprotos]));
     639             : 
     640      179778 :                 num_cliprotos += 1;
     641      179778 :                 p += strlen(p) + 2;
     642             :         }
     643             : 
     644      141016 :         for (i=0; i<num_cliprotos; i++) {
     645      135198 :                 if (strcsequal(cliprotos[i], "Windows for Workgroups 3.1a")) {
     646           0 :                         protocols |= PROT_WFWG;
     647      135198 :                 } else if (strcsequal(cliprotos[i], "DOS LM1.2X002")) {
     648           0 :                         protocols |= PROT_DOS_LM1_2X002;
     649      135198 :                 } else if (strcsequal(cliprotos[i], "DOS LANMAN2.1")) {
     650       13749 :                         protocols |= PROT_DOS_LANMAN2_1;
     651      121449 :                 } else if (strcsequal(cliprotos[i], "LANMAN1.0")) {
     652       13749 :                         protocols |= PROT_LANMAN1_0;
     653      107700 :                 } else if (strcsequal(cliprotos[i], "NT LM 0.12")) {
     654        6346 :                         protocols |= PROT_NT_LM_0_12;
     655      101354 :                 } else if (strcsequal(cliprotos[i], "SMB 2.001")) {
     656           0 :                         protocols |= PROT_SMB_2_001;
     657      101354 :                 } else if (strcsequal(cliprotos[i], "SMB 2.002")) {
     658        6256 :                         protocols |= PROT_SMB_2_002;
     659       95098 :                 } else if (strcsequal(cliprotos[i], "SMB 2.???")) {
     660        6256 :                         protocols |= PROT_SMB_2_FF;
     661       88842 :                 } else if (strcsequal(cliprotos[i], "LANMAN2.1")) {
     662       13749 :                         protocols |= PROT_LANMAN2_1;
     663       75093 :                 } else if (strcsequal(cliprotos[i], "LM1.2X002")) {
     664       13749 :                         protocols |= PROT_LM1_2X002;
     665       61344 :                 } else if (strcsequal(cliprotos[i], "MICROSOFT NETWORKS 1.03")) {
     666       13749 :                         protocols |= PROT_MICROSOFT_NETWORKS_1_03;
     667       47595 :                 } else if (strcsequal(cliprotos[i], "MICROSOFT NETWORKS 3.0")) {
     668       13749 :                         protocols |= PROT_MICROSOFT_NETWORKS_3_0;
     669       33846 :                 } else if (strcsequal(cliprotos[i], "PC NETWORK PROGRAM 1.0")) {
     670       13751 :                         protocols |= PROT_PC_NETWORK_PROGRAM_1_0;
     671       20095 :                 } else if (strcsequal(cliprotos[i], "XENIX CORE")) {
     672           0 :                         protocols |= PROT_XENIX_CORE;
     673       20095 :                 } else if (strcsequal(cliprotos[i], "Samba")) {
     674       13609 :                         protocols = PROT_SAMBA;
     675       13609 :                         break;
     676        6346 :                 } else if (strcsequal(cliprotos[i], "POSIX 2")) {
     677           0 :                         protocols = PROT_POSIX_2;
     678           0 :                         break;
     679             :                 }
     680             :         }
     681             : 
     682       20097 :         switch ( protocols ) {
     683             :                 /* Old CIFSFS can send one arch only, NT LM 0.12. */
     684          90 :                 case PROT_NT_LM_0_12:
     685             :                 case ARCH_CIFSFS:
     686          90 :                         set_remote_arch(RA_CIFSFS);
     687          90 :                         break;
     688       13749 :                 case ARCH_SAMBA:
     689       13749 :                         set_remote_arch(RA_SAMBA);
     690       13749 :                         break;
     691           0 :                 case ARCH_WFWG:
     692           0 :                         set_remote_arch(RA_WFWG);
     693           0 :                         break;
     694           0 :                 case ARCH_WIN95:
     695           0 :                         set_remote_arch(RA_WIN95);
     696           0 :                         break;
     697           0 :                 case ARCH_WINNT:
     698           0 :                         set_remote_arch(RA_WINNT);
     699           0 :                         break;
     700           0 :                 case ARCH_WIN2K:
     701           0 :                         set_remote_arch(RA_WIN2K);
     702           0 :                         break;
     703           0 :                 case ARCH_VISTA:
     704           0 :                         set_remote_arch(RA_VISTA);
     705           0 :                         break;
     706           0 :                 case ARCH_OS2:
     707           0 :                         set_remote_arch(RA_OS2);
     708           0 :                         break;
     709        6256 :                 case ARCH_OSX:
     710        6256 :                         set_remote_arch(RA_OSX);
     711        6256 :                         break;
     712           2 :                 default:
     713           2 :                         set_remote_arch(RA_UNKNOWN);
     714           2 :                 break;
     715             :         }
     716             : 
     717             :         /* possibly reload - change of architecture */
     718       20097 :         reload_services(sconn, conn_snum_used, true);
     719             : 
     720             :         /*
     721             :          * Anything higher than PROTOCOL_SMB2_10 still
     722             :          * needs to go via "SMB 2.???", which is marked
     723             :          * as PROTOCOL_SMB2_10.
     724             :          *
     725             :          * The real negotiation happens via reply_smb20ff()
     726             :          * using SMB2 Negotiation.
     727             :          */
     728       20097 :         max_proto = lp_server_max_protocol();
     729       20097 :         if (max_proto > PROTOCOL_SMB2_10) {
     730       18483 :                 max_proto = PROTOCOL_SMB2_10;
     731             :         }
     732       20097 :         min_proto = lp_server_min_protocol();
     733       20097 :         if (min_proto > PROTOCOL_SMB2_10) {
     734           0 :                 min_proto = PROTOCOL_SMB2_10;
     735             :         }
     736             : 
     737             :         /* Check for protocols, most desirable first */
     738       34685 :         for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
     739       34245 :                 i = 0;
     740       67564 :                 if ((supported_protocols[protocol].protocol_level <= max_proto) &&
     741       33319 :                     (supported_protocols[protocol].protocol_level >= min_proto))
     742      339758 :                         while (i < num_cliprotos) {
     743      280058 :                                 if (strequal(cliprotos[i],supported_protocols[protocol].proto_name)) {
     744       19657 :                                         choice = i;
     745       19657 :                                         chosen_level = supported_protocols[protocol].protocol_level;
     746       19657 :                                         choice_set = true;
     747             :                                 }
     748      280058 :                                 i++;
     749             :                         }
     750       34245 :                 if (choice_set) {
     751       19135 :                         break;
     752             :                 }
     753             :         }
     754             : 
     755       20097 :         if (!choice_set) {
     756             :                 bool ok;
     757             : 
     758         440 :                 DBG_NOTICE("No protocol supported !\n");
     759         440 :                 reply_outbuf(req, 1, 0);
     760         440 :                 SSVAL(req->outbuf, smb_vwv0, NO_PROTOCOL_CHOSEN);
     761             : 
     762         440 :                 ok = srv_send_smb(xconn, (char *)req->outbuf,
     763             :                                   false, 0, false, NULL);
     764         440 :                 if (!ok) {
     765           0 :                         DBG_NOTICE("srv_send_smb failed\n");
     766             :                 }
     767         440 :                 exit_server_cleanly("no protocol supported\n");
     768             :         }
     769             : 
     770       19657 :         fstrcpy(remote_proto,supported_protocols[protocol].short_name);
     771       19657 :         reload_services(sconn, conn_snum_used, true);
     772       19657 :         status = supported_protocols[protocol].proto_reply_fn(req, choice);
     773       19657 :         if (!NT_STATUS_IS_OK(status)) {
     774           0 :                 exit_server_cleanly("negprot function failed\n");
     775             :         }
     776             : 
     777       19657 :         DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
     778             : 
     779       19657 :         DBG_INFO("negprot index=%zu\n", choice);
     780             : 
     781       19657 :         xconn->smb1.negprot.done = true;
     782             : 
     783             :         /* We always have xconn->smb1.signing_state also for >= SMB2_02 */
     784       19657 :         signing_required = smb_signing_is_mandatory(xconn->smb1.signing_state);
     785       19657 :         if (signing_required && (chosen_level < PROTOCOL_NT1)) {
     786           0 :                 exit_server_cleanly("SMB signing is required and "
     787             :                         "client negotiated a downlevel protocol");
     788             :         }
     789             : 
     790       19657 :         TALLOC_FREE(cliprotos);
     791             : 
     792       19657 :         if (lp_async_smb_echo_handler() && (chosen_level < PROTOCOL_SMB2_02) &&
     793           0 :             !fork_echo_handler(xconn)) {
     794           0 :                 exit_server("Failed to fork echo handler");
     795             :         }
     796             : 
     797       19657 :         END_PROFILE(SMBnegprot);
     798       19135 :         return;
     799             : }

Generated by: LCOV version 1.13