#include "includes.h"
#include "smbd/smbd.h"
#include "smbd/globals.h"
-#include "../libcli/auth/spnego.h"
#include "serverid.h"
#include "auth.h"
#include "messages.h"
extern fstring remote_proto;
-static void get_challenge(struct smbd_server_connection *sconn, uint8 buff[8])
+static void get_challenge(struct smbXsrv_connection *xconn, uint8_t buff[8])
{
NTSTATUS nt_status;
/* We might be called more than once, multiple negprots are
* permitted */
- if (sconn->smb1.negprot.auth_context) {
+ if (xconn->smb1.negprot.auth_context) {
DEBUG(3, ("get challenge: is this a secondary negprot? "
"sconn->negprot.auth_context is non-NULL!\n"));
- TALLOC_FREE(sconn->smb1.negprot.auth_context);
+ TALLOC_FREE(xconn->smb1.negprot.auth_context);
}
DEBUG(10, ("get challenge: creating negprot_global_auth_context\n"));
- nt_status = make_auth_context_subsystem(
- sconn, &sconn->smb1.negprot.auth_context);
+ nt_status = make_auth4_context(
+ xconn, &xconn->smb1.negprot.auth_context);
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(0, ("make_auth_context_subsystem returned %s",
nt_errstr(nt_status)));
smb_panic("cannot make_negprot_global_auth_context!");
}
DEBUG(10, ("get challenge: getting challenge\n"));
- sconn->smb1.negprot.auth_context->get_ntlm_challenge(
- sconn->smb1.negprot.auth_context, buff);
-}
-
-/****************************************************************************
- Reply for the core protocol.
-****************************************************************************/
-
-static void reply_corep(struct smb_request *req, uint16 choice)
-{
- reply_outbuf(req, 1, 0);
- SSVAL(req->outbuf, smb_vwv0, choice);
-
- set_Protocol(PROTOCOL_CORE);
-}
-
-/****************************************************************************
- Reply for the coreplus protocol.
-****************************************************************************/
-
-static void reply_coreplus(struct smb_request *req, uint16 choice)
-{
- int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
-
- reply_outbuf(req, 13, 0);
-
- SSVAL(req->outbuf,smb_vwv0,choice);
- SSVAL(req->outbuf,smb_vwv5,raw); /* tell redirector we support
- readbraw and writebraw (possibly) */
- /* Reply, SMBlockread, SMBwritelock supported. */
- SCVAL(req->outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
- SSVAL(req->outbuf,smb_vwv1,0x1); /* user level security, don't
- * encrypt */
- set_Protocol(PROTOCOL_COREPLUS);
+ xconn->smb1.negprot.auth_context->get_ntlm_challenge(
+ xconn->smb1.negprot.auth_context, buff);
}
/****************************************************************************
Reply for the lanman 1.0 protocol.
****************************************************************************/
-static void reply_lanman1(struct smb_request *req, uint16 choice)
+static void reply_lanman1(struct smb_request *req, uint16_t choice)
{
- int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
int secword=0;
time_t t = time(NULL);
- struct smbd_server_connection *sconn = req->sconn;
+ struct smbXsrv_connection *xconn = req->xconn;
+ uint16_t raw;
+ if (lp_async_smb_echo_handler()) {
+ raw = 0;
+ } else {
+ raw = (lp_read_raw()?1:0) | (lp_write_raw()?2:0);
+ }
- sconn->smb1.negprot.encrypted_passwords = lp_encrypted_passwords();
+ xconn->smb1.negprot.encrypted_passwords = lp_encrypt_passwords();
- if (lp_security()>=SEC_USER) {
- secword |= NEGOTIATE_SECURITY_USER_LEVEL;
- }
- if (sconn->smb1.negprot.encrypted_passwords) {
+ secword |= NEGOTIATE_SECURITY_USER_LEVEL;
+ if (xconn->smb1.negprot.encrypted_passwords) {
secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
}
- reply_outbuf(req, 13, sconn->smb1.negprot.encrypted_passwords?8:0);
+ reply_outbuf(req, 13, xconn->smb1.negprot.encrypted_passwords?8:0);
SSVAL(req->outbuf,smb_vwv0,choice);
SSVAL(req->outbuf,smb_vwv1,secword);
/* Create a token value and add it to the outgoing packet. */
- if (sconn->smb1.negprot.encrypted_passwords) {
- get_challenge(sconn, (uint8 *)smb_buf(req->outbuf));
+ if (xconn->smb1.negprot.encrypted_passwords) {
+ get_challenge(xconn, (uint8_t *)smb_buf(req->outbuf));
SSVAL(req->outbuf,smb_vwv11, 8);
}
- set_Protocol(PROTOCOL_LANMAN1);
+ smbXsrv_connection_init_tables(xconn, PROTOCOL_LANMAN1);
/* Reply, SMBlockread, SMBwritelock supported. */
- SCVAL(req->outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
- SSVAL(req->outbuf,smb_vwv2,sconn->smb1.negprot.max_recv);
- SSVAL(req->outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
- SSVAL(req->outbuf,smb_vwv4,1);
- SSVAL(req->outbuf,smb_vwv5,raw); /* tell redirector we support
+ SCVAL(req->outbuf,smb_flg, FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
+ SSVAL(req->outbuf,smb_vwv2, xconn->smb1.negprot.max_recv);
+ SSVAL(req->outbuf,smb_vwv3, lp_max_mux()); /* maxmux */
+ SSVAL(req->outbuf,smb_vwv4, 1);
+ SSVAL(req->outbuf,smb_vwv5, raw); /* tell redirector we support
readbraw writebraw (possibly) */
- SIVAL(req->outbuf,smb_vwv6,sys_getpid());
+ SIVAL(req->outbuf,smb_vwv6, getpid());
SSVAL(req->outbuf,smb_vwv10, set_server_zone_offset(t)/60);
srv_put_dos_date((char *)req->outbuf,smb_vwv8,t);
Reply for the lanman 2.0 protocol.
****************************************************************************/
-static void reply_lanman2(struct smb_request *req, uint16 choice)
+static void reply_lanman2(struct smb_request *req, uint16_t choice)
{
- int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
int secword=0;
time_t t = time(NULL);
- struct smbd_server_connection *sconn = req->sconn;
+ struct smbXsrv_connection *xconn = req->xconn;
+ uint16_t raw;
+ if (lp_async_smb_echo_handler()) {
+ raw = 0;
+ } else {
+ raw = (lp_read_raw()?1:0) | (lp_write_raw()?2:0);
+ }
- sconn->smb1.negprot.encrypted_passwords = lp_encrypted_passwords();
+ xconn->smb1.negprot.encrypted_passwords = lp_encrypt_passwords();
- if (lp_security()>=SEC_USER) {
- secword |= NEGOTIATE_SECURITY_USER_LEVEL;
- }
- if (sconn->smb1.negprot.encrypted_passwords) {
+ secword |= NEGOTIATE_SECURITY_USER_LEVEL;
+ if (xconn->smb1.negprot.encrypted_passwords) {
secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
}
- reply_outbuf(req, 13, sconn->smb1.negprot.encrypted_passwords?8:0);
+ reply_outbuf(req, 13, xconn->smb1.negprot.encrypted_passwords?8:0);
- SSVAL(req->outbuf,smb_vwv0,choice);
- SSVAL(req->outbuf,smb_vwv1,secword);
- SIVAL(req->outbuf,smb_vwv6,sys_getpid());
+ SSVAL(req->outbuf,smb_vwv0, choice);
+ SSVAL(req->outbuf,smb_vwv1, secword);
+ SIVAL(req->outbuf,smb_vwv6, getpid());
/* Create a token value and add it to the outgoing packet. */
- if (sconn->smb1.negprot.encrypted_passwords) {
- get_challenge(sconn, (uint8 *)smb_buf(req->outbuf));
+ if (xconn->smb1.negprot.encrypted_passwords) {
+ get_challenge(xconn, (uint8_t *)smb_buf(req->outbuf));
SSVAL(req->outbuf,smb_vwv11, 8);
}
- set_Protocol(PROTOCOL_LANMAN2);
+ smbXsrv_connection_init_tables(xconn, PROTOCOL_LANMAN2);
/* Reply, SMBlockread, SMBwritelock supported. */
SCVAL(req->outbuf,smb_flg,FLAG_REPLY|FLAG_SUPPORT_LOCKREAD);
- SSVAL(req->outbuf,smb_vwv2,sconn->smb1.negprot.max_recv);
- SSVAL(req->outbuf,smb_vwv3,lp_maxmux());
+ SSVAL(req->outbuf,smb_vwv2,xconn->smb1.negprot.max_recv);
+ SSVAL(req->outbuf,smb_vwv3,lp_max_mux());
SSVAL(req->outbuf,smb_vwv4,1);
SSVAL(req->outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
SSVAL(req->outbuf,smb_vwv10, set_server_zone_offset(t)/60);
Generate the spnego negprot reply blob. Return the number of bytes used.
****************************************************************************/
-DATA_BLOB negprot_spnego(TALLOC_CTX *ctx, struct smbd_server_connection *sconn)
+DATA_BLOB negprot_spnego(TALLOC_CTX *ctx, struct smbXsrv_connection *xconn)
{
DATA_BLOB blob = data_blob_null;
DATA_BLOB blob_out = data_blob_null;
/* See if we can get an SPNEGO blob */
status = auth_generic_prepare(talloc_tos(),
- sconn->remote_address,
+ xconn->remote_address,
&gensec_security);
if (NT_STATUS_IS_OK(status)) {
status = gensec_start_mech_by_oid(gensec_security, GENSEC_OID_SPNEGO);
if (NT_STATUS_IS_OK(status)) {
status = gensec_update(gensec_security, ctx,
- NULL, data_blob_null, &blob);
+ data_blob_null, &blob);
/* If we get the list of OIDs, the 'OK' answer
* is NT_STATUS_MORE_PROCESSING_REQUIRED */
if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
TALLOC_FREE(gensec_security);
}
- sconn->smb1.negprot.spnego = true;
+ xconn->smb1.negprot.spnego = true;
/* strangely enough, NT does not sent the single OID NTLMSSP when
not a ADS member, it sends no OIDs at all
memset(blob_out.data, '\0', 16);
checked_strlcpy(unix_name, lp_netbios_name(), sizeof(unix_name));
- strlower_m(unix_name);
+ (void)strlower_m(unix_name);
push_ascii_nstring(dos_name, unix_name);
strlcpy((char *)blob_out.data, dos_name, 17);
Reply for the nt protocol.
****************************************************************************/
-static void reply_nt1(struct smb_request *req, uint16 choice)
+static void reply_nt1(struct smb_request *req, uint16_t choice)
{
/* dual names + lock_and_read + nt SMBs + remote API calls */
int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|
bool negotiate_spnego = False;
struct timespec ts;
ssize_t ret;
- struct smbd_server_connection *sconn = req->sconn;
- bool signing_enabled = false;
+ struct smbXsrv_connection *xconn = req->xconn;
+ bool signing_desired = false;
bool signing_required = false;
- sconn->smb1.negprot.encrypted_passwords = lp_encrypted_passwords();
+ xconn->smb1.negprot.encrypted_passwords = lp_encrypt_passwords();
/* Check the flags field to see if this is Vista.
WinXP sets it and Vista does not. But we have to
if ( (req->flags2 & FLAGS2_EXTENDED_SECURITY) &&
((req->flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED) == 0) )
{
- if (get_remote_arch() != RA_SAMBA) {
+ if ((get_remote_arch() != RA_SAMBA) &&
+ (get_remote_arch() != RA_CIFSFS)) {
set_remote_arch( RA_VISTA );
}
}
/* do spnego in user level security if the client
supports it and we can do encrypted passwords */
- if (sconn->smb1.negprot.encrypted_passwords &&
- (lp_security() != SEC_SHARE) &&
+ if (xconn->smb1.negprot.encrypted_passwords &&
lp_use_spnego() &&
(req->flags2 & FLAGS2_EXTENDED_SECURITY)) {
negotiate_spnego = True;
req->flags2 | FLAGS2_EXTENDED_SECURITY);
}
- capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS|CAP_UNICODE;
+ capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
+
+ if (lp_unicode()) {
+ capabilities |= CAP_UNICODE;
+ }
if (lp_unix_extensions()) {
capabilities |= CAP_UNIX;
}
- if (lp_large_readwrite() && (SMB_OFF_T_BITS == 64))
+ if (lp_large_readwrite())
capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_W2K_SMBS;
- if (SMB_OFF_T_BITS == 64)
- capabilities |= CAP_LARGE_FILES;
+ capabilities |= CAP_LARGE_FILES;
- if (lp_readraw() && lp_writeraw())
+ if (!lp_async_smb_echo_handler() && lp_read_raw() && lp_write_raw())
capabilities |= CAP_RAW_MODE;
if (lp_nt_status_support())
if (lp_host_msdfs())
capabilities |= CAP_DFS;
- if (lp_security() >= SEC_USER) {
- secword |= NEGOTIATE_SECURITY_USER_LEVEL;
- }
- if (sconn->smb1.negprot.encrypted_passwords) {
+ secword |= NEGOTIATE_SECURITY_USER_LEVEL;
+ if (xconn->smb1.negprot.encrypted_passwords) {
secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
}
- signing_enabled = smb_signing_is_allowed(req->sconn->smb1.signing_state);
- signing_required = smb_signing_is_mandatory(req->sconn->smb1.signing_state);
+ signing_desired = smb_signing_is_desired(xconn->smb1.signing_state);
+ signing_required = smb_signing_is_mandatory(xconn->smb1.signing_state);
- if (signing_enabled) {
- if (lp_security() >= SEC_USER) {
- secword |= NEGOTIATE_SECURITY_SIGNATURES_ENABLED;
- /* No raw mode with smb signing. */
- capabilities &= ~CAP_RAW_MODE;
- if (signing_required) {
- secword |=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED;
- }
- } else {
- DEBUG(0,("reply_nt1: smb signing is incompatible with share level security !\n"));
- if (signing_required) {
- exit_server_cleanly("reply_nt1: smb signing required and share level security selected.");
- }
+ if (signing_desired) {
+ secword |= NEGOTIATE_SECURITY_SIGNATURES_ENABLED;
+ /* No raw mode with smb signing. */
+ capabilities &= ~CAP_RAW_MODE;
+ if (signing_required) {
+ secword |=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED;
}
}
SSVAL(req->outbuf,smb_vwv0,choice);
SCVAL(req->outbuf,smb_vwv1,secword);
- set_Protocol(PROTOCOL_NT1);
+ smbXsrv_connection_init_tables(xconn, PROTOCOL_NT1);
- SSVAL(req->outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
- SSVAL(req->outbuf,smb_vwv2+1,1); /* num vcs */
+ SSVAL(req->outbuf,smb_vwv1+1, lp_max_mux()); /* maxmpx */
+ SSVAL(req->outbuf,smb_vwv2+1, 1); /* num vcs */
SIVAL(req->outbuf,smb_vwv3+1,
- sconn->smb1.negprot.max_recv); /* max buffer. LOTS! */
- SIVAL(req->outbuf,smb_vwv5+1,0x10000); /* raw size. full 64k */
- SIVAL(req->outbuf,smb_vwv7+1,sys_getpid()); /* session key */
- SIVAL(req->outbuf,smb_vwv9+1,capabilities); /* capabilities */
+ xconn->smb1.negprot.max_recv); /* max buffer. LOTS! */
+ SIVAL(req->outbuf,smb_vwv5+1, 0x10000); /* raw size. full 64k */
+ SIVAL(req->outbuf,smb_vwv7+1, getpid()); /* session key */
+ SIVAL(req->outbuf,smb_vwv9+1, capabilities); /* capabilities */
clock_gettime(CLOCK_REALTIME,&ts);
put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER,(char *)req->outbuf+smb_vwv11+1,ts);
SSVALS(req->outbuf,smb_vwv15+1,set_server_zone_offset(ts.tv_sec)/60);
if (!negotiate_spnego) {
/* Create a token value and add it to the outgoing packet. */
- if (sconn->smb1.negprot.encrypted_passwords) {
- uint8 chal[8];
+ if (xconn->smb1.negprot.encrypted_passwords) {
+ uint8_t chal[8];
/* note that we do not send a challenge at all if
we are using plaintext */
- get_challenge(sconn, chal);
+ get_challenge(xconn, chal);
ret = message_push_blob(
&req->outbuf, data_blob_const(chal, sizeof(chal)));
if (ret == -1) {
}
DEBUG(3,("not using SPNEGO\n"));
} else {
- DATA_BLOB spnego_blob = negprot_spnego(req, req->sconn);
+ DATA_BLOB spnego_blob = negprot_spnego(req, xconn);
if (spnego_blob.data == NULL) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
protocol [LANMAN1.0]
protocol [LM1.2X002]
protocol [LANMAN2.1]
+
+OSX:
+protocol [NT LM 0.12]
+protocol [SMB 2.002]
+protocol [SMB 2.???]
*/
/*
* Modified to recognize the architecture of the remote machine better.
*
* This appears to be the matrix of which protocol is used by which
- * MS product.
- Protocol WfWg Win95 WinNT Win2K OS/2 Vista
- PC NETWORK PROGRAM 1.0 1 1 1 1 1 1
- XENIX CORE 2 2
- MICROSOFT NETWORKS 3.0 2 2
- DOS LM1.2X002 3 3
- MICROSOFT NETWORKS 1.03 3
- DOS LANMAN2.1 4 4
- LANMAN1.0 4 2 3 2
- Windows for Workgroups 3.1a 5 5 5 3 3
- LM1.2X002 6 4 4 4
- LANMAN2.1 7 5 5 5
- NT LM 0.12 6 8 6 6
- SMB 2.001 7
+ * product.
+ Protocol WfWg Win95 WinNT Win2K OS/2 Vista OSX
+ PC NETWORK PROGRAM 1.0 1 1 1 1 1 1
+ XENIX CORE 2 2
+ MICROSOFT NETWORKS 3.0 2 2
+ DOS LM1.2X002 3 3
+ MICROSOFT NETWORKS 1.03 3
+ DOS LANMAN2.1 4 4
+ LANMAN1.0 4 2 3 2
+ Windows for Workgroups 3.1a 5 5 5 3 3
+ LM1.2X002 6 4 4 4
+ LANMAN2.1 7 5 5 5
+ NT LM 0.12 6 8 6 6 6 1
+ SMB 2.001 7
+ SMB 2.002 2
+ SMB 2.??? 3
*
* tim@fsg.com 09/29/95
* Win2K added by matty 17/7/99
*/
-#define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
-#define ARCH_WIN95 0x2
-#define ARCH_WINNT 0x4
-#define ARCH_WIN2K 0xC /* Win2K is like NT */
-#define ARCH_OS2 0x14 /* Again OS/2 is like NT */
-#define ARCH_SAMBA 0x20
-#define ARCH_CIFSFS 0x40
-#define ARCH_VISTA 0x8C /* Vista is like XP/2K */
-
-#define ARCH_ALL 0x7F
+#define PROT_PC_NETWORK_PROGRAM_1_0 0x0001
+#define PROT_XENIX_CORE 0x0002
+#define PROT_MICROSOFT_NETWORKS_3_0 0x0004
+#define PROT_DOS_LM1_2X002 0x0008
+#define PROT_MICROSOFT_NETWORKS_1_03 0x0010
+#define PROT_DOS_LANMAN2_1 0x0020
+#define PROT_LANMAN1_0 0x0040
+#define PROT_WFWG 0x0080
+#define PROT_LM1_2X002 0x0100
+#define PROT_LANMAN2_1 0x0200
+#define PROT_NT_LM_0_12 0x0400
+#define PROT_SMB_2_001 0x0800
+#define PROT_SMB_2_002 0x1000
+#define PROT_SMB_2_FF 0x2000
+#define PROT_SAMBA 0x4000
+#define PROT_POSIX_2 0x8000
+
+#define ARCH_WFWG ( PROT_PC_NETWORK_PROGRAM_1_0 | PROT_MICROSOFT_NETWORKS_3_0 | \
+ PROT_DOS_LM1_2X002 | PROT_DOS_LANMAN2_1 | PROT_WFWG )
+#define ARCH_WIN95 ( ARCH_WFWG | PROT_NT_LM_0_12 )
+#define ARCH_WINNT ( PROT_PC_NETWORK_PROGRAM_1_0 | PROT_XENIX_CORE | \
+ PROT_MICROSOFT_NETWORKS_1_03 | PROT_LANMAN1_0 | PROT_WFWG | \
+ PROT_LM1_2X002 | PROT_LANMAN2_1 | PROT_NT_LM_0_12 )
+#define ARCH_WIN2K ( ARCH_WINNT & ~(PROT_XENIX_CORE | PROT_MICROSOFT_NETWORKS_1_03) )
+#define ARCH_OS2 ( ARCH_WINNT & ~(PROT_MICROSOFT_NETWORKS_1_03 | PROT_WFWG) )
+#define ARCH_VISTA ( ARCH_WIN2K | PROT_SMB_2_001 )
+#define ARCH_SAMBA ( PROT_SAMBA )
+#define ARCH_CIFSFS ( PROT_POSIX_2 )
+#define ARCH_OSX ( PROT_NT_LM_0_12 | PROT_SMB_2_002 | PROT_SMB_2_FF )
/* List of supported protocols, most desired first */
static const struct {
const char *proto_name;
const char *short_name;
- void (*proto_reply_fn)(struct smb_request *req, uint16 choice);
+ void (*proto_reply_fn)(struct smb_request *req, uint16_t choice);
int protocol_level;
} supported_protocols[] = {
{"SMB 2.???", "SMB2_FF", reply_smb20ff, PROTOCOL_SMB2_10},
{"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
{"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
{"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
- {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
- {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
{NULL,NULL,NULL,0},
};
void reply_negprot(struct smb_request *req)
{
int choice= -1;
+ int chosen_level = -1;
int protocol;
const char *p;
- int arch = ARCH_ALL;
+ int protocols = 0;
int num_cliprotos;
char **cliprotos;
int i;
size_t converted_size;
+ struct smbXsrv_connection *xconn = req->xconn;
struct smbd_server_connection *sconn = req->sconn;
+ bool signing_required = true;
START_PROFILE(SMBnegprot);
- if (sconn->smb1.negprot.done) {
+ if (xconn->smb1.negprot.done) {
END_PROFILE(SMBnegprot);
exit_server_cleanly("multiple negprot's are not permitted");
}
- sconn->smb1.negprot.done = true;
+ xconn->smb1.negprot.done = true;
if (req->buflen == 0) {
DEBUG(0, ("negprot got no protocols\n"));
}
for (i=0; i<num_cliprotos; i++) {
- if (strcsequal(cliprotos[i], "Windows for Workgroups 3.1a"))
- arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT
- | ARCH_WIN2K );
- else if (strcsequal(cliprotos[i], "DOS LM1.2X002"))
- arch &= ( ARCH_WFWG | ARCH_WIN95 );
- else if (strcsequal(cliprotos[i], "DOS LANMAN2.1"))
- arch &= ( ARCH_WFWG | ARCH_WIN95 );
- else if (strcsequal(cliprotos[i], "NT LM 0.12"))
- arch &= ( ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K
- | ARCH_CIFSFS);
- else if (strcsequal(cliprotos[i], "SMB 2.001"))
- arch = ARCH_VISTA;
- else if (strcsequal(cliprotos[i], "LANMAN2.1"))
- arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
- else if (strcsequal(cliprotos[i], "LM1.2X002"))
- arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
- else if (strcsequal(cliprotos[i], "MICROSOFT NETWORKS 1.03"))
- arch &= ARCH_WINNT;
- else if (strcsequal(cliprotos[i], "XENIX CORE"))
- arch &= ( ARCH_WINNT | ARCH_OS2 );
- else if (strcsequal(cliprotos[i], "Samba")) {
- arch = ARCH_SAMBA;
+ if (strcsequal(cliprotos[i], "Windows for Workgroups 3.1a")) {
+ protocols |= PROT_WFWG;
+ } else if (strcsequal(cliprotos[i], "DOS LM1.2X002")) {
+ protocols |= PROT_DOS_LM1_2X002;
+ } else if (strcsequal(cliprotos[i], "DOS LANMAN2.1")) {
+ protocols |= PROT_DOS_LANMAN2_1;
+ } else if (strcsequal(cliprotos[i], "LANMAN1.0")) {
+ protocols |= PROT_LANMAN1_0;
+ } else if (strcsequal(cliprotos[i], "NT LM 0.12")) {
+ protocols |= PROT_NT_LM_0_12;
+ } else if (strcsequal(cliprotos[i], "SMB 2.001")) {
+ protocols |= PROT_SMB_2_001;
+ } else if (strcsequal(cliprotos[i], "SMB 2.002")) {
+ protocols |= PROT_SMB_2_002;
+ } else if (strcsequal(cliprotos[i], "SMB 2.???")) {
+ protocols |= PROT_SMB_2_FF;
+ } else if (strcsequal(cliprotos[i], "LANMAN2.1")) {
+ protocols |= PROT_LANMAN2_1;
+ } else if (strcsequal(cliprotos[i], "LM1.2X002")) {
+ protocols |= PROT_LM1_2X002;
+ } else if (strcsequal(cliprotos[i], "MICROSOFT NETWORKS 1.03")) {
+ protocols |= PROT_MICROSOFT_NETWORKS_1_03;
+ } else if (strcsequal(cliprotos[i], "MICROSOFT NETWORKS 3.0")) {
+ protocols |= PROT_MICROSOFT_NETWORKS_3_0;
+ } else if (strcsequal(cliprotos[i], "PC NETWORK PROGRAM 1.0")) {
+ protocols |= PROT_PC_NETWORK_PROGRAM_1_0;
+ } else if (strcsequal(cliprotos[i], "XENIX CORE")) {
+ protocols |= PROT_XENIX_CORE;
+ } else if (strcsequal(cliprotos[i], "Samba")) {
+ protocols = PROT_SAMBA;
break;
} else if (strcsequal(cliprotos[i], "POSIX 2")) {
- arch = ARCH_CIFSFS;
+ protocols = PROT_POSIX_2;
break;
}
}
- /* CIFSFS can send one arch only, NT LM 0.12. */
- if (i == 1 && (arch & ARCH_CIFSFS)) {
- arch = ARCH_CIFSFS;
- }
-
- switch ( arch ) {
+ switch ( protocols ) {
+ /* Old CIFSFS can send one arch only, NT LM 0.12. */
+ case PROT_NT_LM_0_12:
case ARCH_CIFSFS:
set_remote_arch(RA_CIFSFS);
break;
set_remote_arch(RA_WIN95);
break;
case ARCH_WINNT:
- if(req->flags2 == FLAGS2_WIN2K_SIGNATURE)
- set_remote_arch(RA_WIN2K);
- else
- set_remote_arch(RA_WINNT);
+ set_remote_arch(RA_WINNT);
break;
case ARCH_WIN2K:
- /* Vista may have been set in the negprot so don't
- override it here */
- if ( get_remote_arch() != RA_VISTA )
- set_remote_arch(RA_WIN2K);
+ set_remote_arch(RA_WIN2K);
break;
case ARCH_VISTA:
set_remote_arch(RA_VISTA);
case ARCH_OS2:
set_remote_arch(RA_OS2);
break;
+ case ARCH_OSX:
+ set_remote_arch(RA_OSX);
+ break;
default:
set_remote_arch(RA_UNKNOWN);
break;
/* Check for protocols, most desirable first */
for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
i = 0;
- if ((supported_protocols[protocol].protocol_level <= lp_srv_maxprotocol()) &&
- (supported_protocols[protocol].protocol_level >= lp_srv_minprotocol()))
+ if ((supported_protocols[protocol].protocol_level <= lp_server_max_protocol()) &&
+ (supported_protocols[protocol].protocol_level >= lp_server_min_protocol()))
while (i < num_cliprotos) {
- if (strequal(cliprotos[i],supported_protocols[protocol].proto_name))
+ if (strequal(cliprotos[i],supported_protocols[protocol].proto_name)) {
choice = i;
+ chosen_level = supported_protocols[protocol].protocol_level;
+ }
i++;
}
if(choice != -1)
DEBUG( 5, ( "negprot index=%d\n", choice ) );
- if ((lp_server_signing() == SMB_SIGNING_REQUIRED)
- && (get_Protocol() < PROTOCOL_NT1)) {
+ /* We always have xconn->smb1.signing_state also for >= SMB2_02 */
+ signing_required = smb_signing_is_mandatory(xconn->smb1.signing_state);
+ if (signing_required && (chosen_level < PROTOCOL_NT1)) {
exit_server_cleanly("SMB signing is required and "
"client negotiated a downlevel protocol");
}
TALLOC_FREE(cliprotos);
- if (lp_async_smb_echo_handler() && (get_Protocol() < PROTOCOL_SMB2_02) &&
- !fork_echo_handler(sconn)) {
+ if (lp_async_smb_echo_handler() && (chosen_level < PROTOCOL_SMB2_02) &&
+ !fork_echo_handler(xconn)) {
exit_server("Failed to fork echo handler");
}