From f5302af621d91536a72b437ae2b80f9dedb46920 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 4 Sep 1997 20:26:07 +0000 Subject: Fixed up determination of client type for PROTOCOL_NT1. Uses client capabilities bits in session_setup_and_X to decide. Made remote_arch an enum as well as a string, for easier use. Jeremy (jallison@whistle.com) (This used to be commit 99080705a2d0adcb25e1eecbe517a2fac2779baa) --- source3/include/proto.h | 2 ++ source3/include/smb.h | 2 ++ source3/lib/util.c | 39 +++++++++++++++++++++++++++++++++++++++ source3/script/mkproto.awk | 2 +- source3/smbd/reply.c | 16 ++++++++++++++++ source3/smbd/server.c | 22 ++++++++++------------ 6 files changed, 70 insertions(+), 13 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index d1b28c860dc..15c9fa590b4 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 f0390230e53..b55c180f361 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 3b4453dd5b4..7f922def7e3 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 88d81a62cd9..f2b76f20c97 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 58b509ecec3..773063131af 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 a65ffdd81c1..e2fe14b0b82 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; } -- cgit