summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/proto.h2
-rw-r--r--source3/include/smb.h2
-rw-r--r--source3/lib/util.c39
-rw-r--r--source3/script/mkproto.awk2
-rw-r--r--source3/smbd/reply.c16
-rw-r--r--source3/smbd/server.c22
6 files changed, 70 insertions, 13 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index d1b28c860d..15c9fa590b 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -986,6 +986,8 @@ BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type);
int file_lock(char *name,int timeout);
void file_unlock(int fd);
BOOL is_myname(const char *s);
+void set_remote_arch(enum remote_arch_types type);
+enum remote_arch_types get_remote_arch();
/*The following definitions come from vt_mode.c */
diff --git a/source3/include/smb.h b/source3/include/smb.h
index f0390230e5..b55c180f36 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -880,6 +880,8 @@ enum security_types {SEC_SHARE,SEC_USER,SEC_SERVER};
enum printing_types {PRINT_BSD,PRINT_SYSV,PRINT_AIX,PRINT_HPUX,
PRINT_QNX,PRINT_PLP,PRINT_LPRNG};
+/* Remote architectures we know about. */
+enum remote_arch_types {RA_UNKNOWN, RA_WFWG, RA_OS2, RA_WIN95, RA_WINNT, RA_SAMBA};
/* case handling */
enum case_handling {CASE_LOWER,CASE_UPPER};
diff --git a/source3/lib/util.c b/source3/lib/util.c
index 3b4453dd5b..7f922def7e 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -68,6 +68,7 @@ BOOL case_mangle;
fstring remote_machine="";
fstring local_machine="";
fstring remote_arch="UNKNOWN";
+static enum remote_arch_types ra_type = RA_UNKNOWN;
fstring remote_proto="UNKNOWN";
pstring myhostname="";
pstring user_socket_options="";
@@ -3868,3 +3869,41 @@ BOOL is_myname(const char *s)
DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
return(ret);
}
+
+/*******************************************************************
+set the horrid remote_arch string based on an enum.
+********************************************************************/
+void set_remote_arch(enum remote_arch_types type)
+{
+ ra_type = type;
+ switch( type )
+ {
+ case RA_WFWG:
+ strcpy(remote_arch, "WfWg");
+ return;
+ case RA_OS2:
+ strcpy(remote_arch, "OS2");
+ return;
+ case RA_WIN95:
+ strcpy(remote_arch, "Win95");
+ return;
+ case RA_WINNT:
+ strcpy(remote_arch, "WinNT");
+ return;
+ case RA_SAMBA:
+ strcpy(remote_arch,"Samba");
+ return;
+ default:
+ ra_type = RA_UNKNOWN;
+ strcpy(remote_arch, "UNKNOWN");
+ break;
+ }
+}
+
+/*******************************************************************
+ Get the remote_arch type.
+********************************************************************/
+enum remote_arch_types get_remote_arch()
+{
+ return ra_type;
+}
diff --git a/source3/script/mkproto.awk b/source3/script/mkproto.awk
index 88d81a62cd..f2b76f20c9 100644
--- a/source3/script/mkproto.awk
+++ b/source3/script/mkproto.awk
@@ -64,7 +64,7 @@ BEGIN {
next;
}
-!/^unsigned|^mode_t|^DIR|^user|^int|^char|^uint|^struct|^BOOL|^void|^time|^smb_shm_offset_t|^shm_offset_t/ {
+!/^unsigned|^mode_t|^DIR|^user|^int|^char|^uint|^struct|^BOOL|^void|^time|^smb_shm_offset_t|^shm_offset_t|^enum remote_arch_types/ {
next;
}
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 58b509ecec..773063131a 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -367,8 +367,24 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
} else {
uint16 passlen1 = SVAL(inbuf,smb_vwv7);
uint16 passlen2 = SVAL(inbuf,smb_vwv8);
+ uint32 client_caps = IVAL(inbuf,smb_vwv11);
+ enum remote_arch_types ra_type = get_remote_arch();
+
char *p = smb_buf(inbuf);
+ /* client_caps is used as final determination if client is NT or Win95.
+ This is needed to return the correct error codes in some
+ circumstances.
+ */
+
+ if(ra_type == RA_WINNT || ra_type == RA_WIN95)
+ {
+ if(client_caps & (CAP_NT_SMBS | CAP_STATUS32))
+ set_remote_arch( RA_WINNT);
+ else
+ set_remote_arch( RA_WIN95);
+ }
+
if (passlen1 != 24 && passlen2 != 24)
doencrypt = False;
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index a65ffdd81c..e2fe14b0b8 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -1985,10 +1985,10 @@ struct
int new_smb_error;
int old_smb_error;
int protocol_level;
- char *valid_remote_arch;
+ enum remote_arch_types valid_ra_type;
} old_client_errmap[] =
{
- {ERRbaddirectory, ERRbadpath, (int)PROTOCOL_NT1, "WinNT"},
+ {ERRbaddirectory, ERRbadpath, (int)PROTOCOL_NT1, RA_WINNT},
{0,0,0}
};
@@ -1997,7 +1997,6 @@ struct
****************************************************************************/
int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line)
{
- extern fstring remote_arch;
int eclass=def_class;
int ecode=def_code;
int i=0;
@@ -2030,7 +2029,7 @@ int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int
for apps to work correctly, Win95 will break if
these error codes are returned. But they both
negotiate the *same* protocol. So we need to use
- the revolting 'remote_arch' string to tie break.
+ the revolting 'remote_arch' enum to tie break.
There must be a better way of doing this...
*/
@@ -2038,7 +2037,7 @@ int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int
for(i = 0; old_client_errmap[i].new_smb_error != 0; i++)
{
if(((Protocol < old_client_errmap[i].protocol_level) ||
- !strcsequal( old_client_errmap[i].valid_remote_arch, remote_arch)) &&
+ (old_client_errmap[i].valid_ra_type != get_remote_arch())) &&
(old_client_errmap[i].new_smb_error == ecode))
{
ecode = old_client_errmap[i].old_smb_error;
@@ -3062,7 +3061,6 @@ struct {
****************************************************************************/
static int reply_negprot(char *inbuf,char *outbuf)
{
- extern fstring remote_arch;
int outsize = set_message(outbuf,1,0,True);
int Index=0;
int choice= -1;
@@ -3102,22 +3100,22 @@ static int reply_negprot(char *inbuf,char *outbuf)
switch ( arch ) {
case ARCH_SAMBA:
- strcpy(remote_arch,"Samba");
+ set_remote_arch(RA_SAMBA);
break;
case ARCH_WFWG:
- strcpy(remote_arch,"WfWg");
+ set_remote_arch(RA_WFWG);
break;
case ARCH_WIN95:
- strcpy(remote_arch,"Win95");
+ set_remote_arch(RA_WIN95);
break;
case ARCH_WINNT:
- strcpy(remote_arch,"WinNT");
+ set_remote_arch(RA_WINNT);
break;
case ARCH_OS2:
- strcpy(remote_arch,"OS2");
+ set_remote_arch(RA_OS2);
break;
default:
- strcpy(remote_arch,"UNKNOWN");
+ set_remote_arch(RA_UNKNOWN);
break;
}