#include "includes.h"
-extern int Protocol;
+extern fstring remote_proto;
+extern enum protocol_types Protocol;
extern int max_recv;
+
BOOL global_encrypted_passwords_negotiated = False;
BOOL global_spnego_negotiated = False;
struct auth_context *negprot_global_auth_context = NULL;
SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
readbraw writebraw (possibly) */
SIVAL(outbuf,smb_vwv6,sys_getpid());
- SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
+ SSVAL(outbuf,smb_vwv10, set_server_zone_offset(t)/60);
- put_dos_date(outbuf,smb_vwv8,t);
+ srv_put_dos_date(outbuf,smb_vwv8,t);
return (smb_len(outbuf)+4);
}
SSVAL(outbuf,smb_vwv3,lp_maxmux());
SSVAL(outbuf,smb_vwv4,1);
SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
- SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
- put_dos_date(outbuf,smb_vwv8,t);
+ SSVAL(outbuf,smb_vwv10, set_server_zone_offset(t)/60);
+ srv_put_dos_date(outbuf,smb_vwv8,t);
return (smb_len(outbuf)+4);
}
Generate the spnego negprot reply blob. Return the number of bytes used.
****************************************************************************/
-static int negprot_spnego(char *p)
+static int negprot_spnego(char *p, uint8 *pkeylen)
{
DATA_BLOB blob;
- uint8 guid[17];
+ nstring dos_name;
+ fstring unix_name;
+ char guid[17];
const char *OIDs_krb5[] = {OID_KERBEROS5,
OID_KERBEROS5_OLD,
OID_NTLMSSP,
NULL};
- const char *OIDs_plain[] = {OID_NTLMSSP, NULL};
- char *principal;
int len;
global_spnego_negotiated = True;
ZERO_STRUCT(guid);
- safe_strcpy((char *)guid, global_myname(), sizeof(guid)-1);
- strlower((char *)guid);
-#if 0
+ safe_strcpy(unix_name, global_myname(), sizeof(unix_name)-1);
+ strlower_m(unix_name);
+ push_ascii_nstring(dos_name, 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);
+ }
+#endif
+
/* strangely enough, NT does not sent the single OID NTLMSSP when
not a ADS member, it sends no OIDs at all
- we can't do this until we teach our sesssion setup parser to know
- about raw NTLMSSP (clients send no ASN.1 wrapping if we do this)
+ OLD COMMENT : "we can't do this until we teach our sesssion setup parser to know
+ about raw NTLMSSP (clients send no ASN.1 wrapping if we do this)"
+
+ Our sessionsetup code now handles raw NTLMSSP connects, so we can go
+ back to doing what W2K3 does here. This is needed to make PocketPC 2003
+ CIFS connections work with SPNEGO. See bugzilla bugs #1828 and #3133
+ for details. JRA.
+
*/
- if (lp_security() != SEC_ADS) {
+
+ if (lp_security() != SEC_ADS && !lp_use_kerberos_keytab()) {
memcpy(p, guid, 16);
+ *pkeylen = 0;
return 16;
- }
-#endif
- if (lp_security() != SEC_ADS) {
- blob = spnego_gen_negTokenInit(guid, OIDs_plain, "NONE");
} else {
- asprintf(&principal, "%s$@%s", guid, lp_realm());
- blob = spnego_gen_negTokenInit(guid, OIDs_krb5, principal);
- free(principal);
+ fstring myname;
+ char *host_princ_s = NULL;
+ name_to_fqdn(myname, global_myname());
+ strlower_m(myname);
+ asprintf(&host_princ_s, "cifs/%s@%s", myname, lp_realm());
+ 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;
+ }
+ *pkeylen = len;
data_blob_free(&blob);
return len;
}
CAP_LEVEL_II_OPLOCKS;
int secword=0;
- time_t t = time(NULL);
char *p, *q;
BOOL negotiate_spnego = False;
+ time_t t = time(NULL);
global_encrypted_passwords_negotiated = lp_encrypted_passwords();
(SVAL(inbuf, smb_flg2) & FLAGS2_EXTENDED_SECURITY)) {
negotiate_spnego = True;
capabilities |= CAP_EXTENDED_SECURITY;
+ add_to_common_flags2(FLAGS2_EXTENDED_SECURITY);
+ /* Ensure FLAGS2_EXTENDED_SECURITY gets set in this reply (already
+ partially constructed. */
+ SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_EXTENDED_SECURITY);
}
- capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
+ capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS|CAP_UNICODE;
if (lp_unix_extensions()) {
capabilities |= CAP_UNIX;
if (lp_readraw() && lp_writeraw())
capabilities |= CAP_RAW_MODE;
- /* allow for disabling unicode */
- if (lp_unicode())
- capabilities |= CAP_UNICODE;
-
if (lp_nt_status_support())
capabilities |= CAP_STATUS32;
if (global_encrypted_passwords_negotiated)
secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
+ if (lp_server_signing()) {
+ if (lp_security() >= SEC_USER) {
+ secword |= NEGOTIATE_SECURITY_SIGNATURES_ENABLED;
+ /* No raw mode with smb signing. */
+ capabilities &= ~CAP_RAW_MODE;
+ if (lp_server_signing() == Required)
+ secword |=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED;
+ srv_set_signing_negotiated();
+ } 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.");
+ }
+ }
+ }
+
set_message(outbuf,17,0,True);
SCVAL(outbuf,smb_vwv1,secword);
SIVAL(outbuf,smb_vwv7+1,sys_getpid()); /* session key */
SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
put_long_date(outbuf+smb_vwv11+1,t);
- SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
+ SSVALS(outbuf,smb_vwv15+1,set_server_zone_offset(t)/60);
p = q = smb_buf(outbuf);
if (!negotiate_spnego) {
/* note that we do not send a challenge at all if
we are using plaintext */
get_challenge(p);
- SSVALS(outbuf,smb_vwv16+1,8);
+ SCVAL(outbuf,smb_vwv16+1,8);
p += 8;
}
p += srvstr_push(outbuf, p, lp_workgroup(), -1,
STR_UNICODE|STR_TERMINATE|STR_NOALIGN);
DEBUG(3,("not using SPNEGO\n"));
} else {
- int len = negprot_spnego(p);
+ uint8 keylen;
+ int len = negprot_spnego(p, &keylen);
- SSVALS(outbuf,smb_vwv16+1,len);
+ SCVAL(outbuf,smb_vwv16+1,keylen);
p += len;
DEBUG(3,("using SPNEGO\n"));
}
#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_ALL 0x3F
+#define ARCH_ALL 0x7F
/* List of supported protocols, most desired first */
static const struct {
} supported_protocols[] = {
{"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
{"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
+ {"POSIX 2", "NT1", reply_nt1, PROTOCOL_NT1},
+ {"LANMAN2.1", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
{"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
{"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
{"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
else if (strcsequal(p,"DOS LANMAN2.1"))
arch &= ( ARCH_WFWG | ARCH_WIN95 );
else if (strcsequal(p,"NT LM 0.12"))
- arch &= ( ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K );
+ arch &= ( ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K | ARCH_CIFSFS);
else if (strcsequal(p,"LANMAN2.1"))
arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
else if (strcsequal(p,"LM1.2X002"))
else if (strcsequal(p,"Samba")) {
arch = ARCH_SAMBA;
break;
+ } else if (strcsequal(p,"POSIX 2")) {
+ arch = ARCH_CIFSFS;
+ break;
}
p += strlen(p) + 2;
}
-
+
+ /* CIFSFS can send one arch only, NT LM 0.12. */
+ if (Index == 1 && (arch & ARCH_CIFSFS)) {
+ arch = ARCH_CIFSFS;
+ }
+
switch ( arch ) {
+ case ARCH_CIFSFS:
+ set_remote_arch(RA_CIFSFS);
+ break;
case ARCH_SAMBA:
set_remote_arch(RA_SAMBA);
break;
/* possibly reload - change of architecture */
reload_services(True);
+
+ /* moved from the netbios session setup code since we don't have that
+ 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);
/* Check for protocols, most desirable first */
for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
SSVAL(outbuf,smb_vwv0,choice);
if(choice != -1) {
- extern fstring remote_proto;
fstrcpy(remote_proto,supported_protocols[protocol].short_name);
reload_services(True);
outsize = supported_protocols[protocol].proto_reply_fn(inbuf, outbuf);
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");
+ }
+
END_PROFILE(SMBnegprot);
return(outsize);
}