This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
NTSTATUS nt_status;
const uint8 *cryptkey;
- /* We might be called more than once, muliple negprots are premitted */
+ /* We might be called more than once, multiple negprots are
+ * permitted */
if (negprot_global_auth_context) {
DEBUG(3, ("get challenge: is this a secondary negprot? negprot_global_auth_context is non-NULL!\n"));
(negprot_global_auth_context->free)(&negprot_global_auth_context);
DEBUG(10, ("get challenge: creating negprot_global_auth_context\n"));
if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&negprot_global_auth_context))) {
DEBUG(0, ("make_auth_context_subsystem returned %s", nt_errstr(nt_status)));
- smb_panic("cannot make_negprot_global_auth_context!\n");
+ smb_panic("cannot make_negprot_global_auth_context!");
}
DEBUG(10, ("get challenge: getting challenge\n"));
cryptkey = negprot_global_auth_context->get_ntlm_challenge(negprot_global_auth_context);
static int reply_corep(char *inbuf, char *outbuf)
{
- int outsize = set_message(outbuf,1,0,True);
+ int outsize = set_message(inbuf,outbuf,1,0,True);
Protocol = PROTOCOL_CORE;
static int reply_coreplus(char *inbuf, char *outbuf)
{
int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
- int outsize = set_message(outbuf,13,0,True);
+ int outsize = set_message(inbuf,outbuf,13,0,True);
SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
readbraw and writebraw (possibly) */
/* Reply, SMBlockread, SMBwritelock supported. */
if (global_encrypted_passwords_negotiated)
secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
- set_message(outbuf,13,global_encrypted_passwords_negotiated?8:0,True);
+ set_message(inbuf,outbuf,13,global_encrypted_passwords_negotiated?8:0,True);
SSVAL(outbuf,smb_vwv1,secword);
/* Create a token value and add it to the outgoing packet. */
if (global_encrypted_passwords_negotiated) {
if (global_encrypted_passwords_negotiated)
secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
- set_message(outbuf,13,global_encrypted_passwords_negotiated?8:0,True);
+ set_message(inbuf,outbuf,13,global_encrypted_passwords_negotiated?8:0,True);
SSVAL(outbuf,smb_vwv1,secword);
SIVAL(outbuf,smb_vwv6,sys_getpid());
Generate the spnego negprot reply blob. Return the number of bytes used.
****************************************************************************/
-static int negprot_spnego(char *p, uint8 *pkeylen)
+static DATA_BLOB negprot_spnego(void)
{
DATA_BLOB blob;
nstring dos_name;
fstring unix_name;
+#ifdef DEVELOPER
+ size_t slen;
+#endif
char guid[17];
const char *OIDs_krb5[] = {OID_KERBEROS5,
OID_KERBEROS5_OLD,
OID_NTLMSSP,
NULL};
const char *OIDs_plain[] = {OID_NTLMSSP, NULL};
- int len;
global_spnego_negotiated = True;
- ZERO_STRUCT(guid);
+ memset(guid, '\0', sizeof(guid));
safe_strcpy(unix_name, global_myname(), sizeof(unix_name)-1);
strlower_m(unix_name);
safe_strcpy(guid, dos_name, sizeof(guid)-1);
#ifdef DEVELOPER
- /* valgrind fixer... */
- {
- size_t sl = strlen(guid);
- if (sizeof(guid)-sl)
- memset(&guid[sl], '\0', sizeof(guid)-sl);
+ /* Fix valgrind 'uninitialized bytes' issue. */
+ slen = strlen(dos_name);
+ if (slen < sizeof(guid)) {
+ memset(guid+slen, '\0', sizeof(guid) - slen);
}
#endif
name_to_fqdn(myname, global_myname());
strlower_m(myname);
asprintf(&host_princ_s, "cifs/%s@%s", myname, lp_realm());
+ if (host_princ_s == NULL) {
+ blob = data_blob_null;
+ return blob;
+ }
blob = spnego_gen_negTokenInit(guid, OIDs_krb5, host_princ_s);
SAFE_FREE(host_princ_s);
}
- memcpy(p, blob.data, blob.length);
- len = blob.length;
- if (len > 256) {
- DEBUG(0,("negprot_spnego: blob length too long (%d)\n", len));
- len = 255;
- }
- data_blob_free(&blob);
-
- if (lp_security() != SEC_ADS && !lp_use_kerberos_keytab()) {
- *pkeylen = 0;
- } else {
- *pkeylen = len;
- }
- return len;
+ return blob;
}
/****************************************************************************
global_encrypted_passwords_negotiated = lp_encrypted_passwords();
+ /* Check the flags field to see if this is Vista.
+ WinXP sets it and Vista does not. But we have to
+ distinguish from NT which doesn't set it either. */
+
+ if ( (SVAL(inbuf, smb_flg2) & FLAGS2_EXTENDED_SECURITY) &&
+ ((SVAL(inbuf, smb_flg2) & FLAGS2_UNKNOWN_BIT4) == 0) )
+ {
+ if (get_remote_arch() != RA_SAMBA) {
+ set_remote_arch( RA_VISTA );
+ }
+ }
+
/* do spnego in user level security if the client
supports it and we can do encrypted passwords */
} else {
DEBUG(0,("reply_nt1: smb signing is incompatible with share level security !\n"));
if (lp_server_signing() == Required) {
- exit_server("reply_nt1: smb signing required and share level security selected.");
+ exit_server_cleanly("reply_nt1: smb signing required and share level security selected.");
}
}
}
- set_message(outbuf,17,0,True);
+ set_message(inbuf,outbuf,17,0,True);
SCVAL(outbuf,smb_vwv1,secword);
STR_UNICODE|STR_TERMINATE|STR_NOALIGN);
DEBUG(3,("not using SPNEGO\n"));
} else {
- uint8 keylen;
- int len = negprot_spnego(p, &keylen);
-
- SCVAL(outbuf,smb_vwv16+1,keylen);
- p += len;
+ DATA_BLOB spnego_blob = negprot_spnego();
+
+ if (spnego_blob.data == NULL) {
+ return ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
+
+ memcpy(p, spnego_blob.data, spnego_blob.length);
+ p += spnego_blob.length;
+ data_blob_free(&spnego_blob);
+
+ SCVAL(outbuf,smb_vwv16+1, 0);
DEBUG(3,("using SPNEGO\n"));
}
SSVAL(outbuf,smb_vwv17, p - q); /* length of challenge+domain strings */
- set_message_end(outbuf, p);
+ set_message_end(inbuf,outbuf, p);
return (smb_len(outbuf)+4);
}
protocol [LANMAN2.1]
protocol [NT LM 0.12]
+Vista:
+protocol [PC NETWORK PROGRAM 1.0]
+protocol [LANMAN1.0]
+protocol [Windows for Workgroups 3.1a]
+protocol [LM1.2X002]
+protocol [LANMAN2.1]
+protocol [NT LM 0.12]
+protocol [SMB 2.001]
+
OS/2:
protocol [PC NETWORK PROGRAM 1.0]
protocol [XENIX CORE]
*
* This appears to be the matrix of which protocol is used by which
* MS product.
- Protocol WfWg Win95 WinNT Win2K OS/2
- PC NETWORK PROGRAM 1.0 1 1 1 1 1
+ 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
- Windows for Workgroups 3.1a 5 5 5 3
- LM1.2X002 6 4 4
- LANMAN2.1 7 5 5
- NT LM 0.12 6 8 6
+ 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
*
* tim@fsg.com 09/29/95
* Win2K added by matty 17/7/99
#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
/****************************************************************************
Reply to a negprot.
+ conn POINTER CAN BE NULL HERE !
****************************************************************************/
int reply_negprot(connection_struct *conn,
char *inbuf,char *outbuf, int dum_size,
int dum_buffsize)
{
- int outsize = set_message(outbuf,1,0,True);
+ int outsize = set_message(inbuf,outbuf,1,0,True);
int Index=0;
int choice= -1;
int protocol;
if (done_negprot) {
END_PROFILE(SMBnegprot);
- exit_server("multiple negprot's are not permitted");
+ exit_server_cleanly("multiple negprot's are not permitted");
}
done_negprot = True;
arch &= ( ARCH_WFWG | ARCH_WIN95 );
else if (strcsequal(p,"NT LM 0.12"))
arch &= ( ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K | ARCH_CIFSFS);
+ else if (strcsequal(p,"SMB 2.001"))
+ arch = ARCH_VISTA;
else if (strcsequal(p,"LANMAN2.1"))
arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
else if (strcsequal(p,"LM1.2X002"))
set_remote_arch(RA_WINNT);
break;
case ARCH_WIN2K:
- set_remote_arch(RA_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);
+ break;
+ case ARCH_VISTA:
+ set_remote_arch(RA_VISTA);
break;
case ARCH_OS2:
set_remote_arch(RA_OS2);
when the client connects to port 445. Of course there is a small
window where we are listening to messages -- jerry */
- claim_connection(NULL,"",0,True,FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
+ claim_connection(
+ NULL,"",FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
/* Check for protocols, most desirable first */
for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
DEBUG( 5, ( "negprot index=%d\n", choice ) );
if ((lp_server_signing() == Required) && (Protocol < PROTOCOL_NT1)) {
- exit_server("SMB signing is required and client negotiated a downlevel protocol");
+ exit_server_cleanly("SMB signing is required and "
+ "client negotiated a downlevel protocol");
}
END_PROFILE(SMBnegprot);