diff options
Diffstat (limited to 'source3')
| -rw-r--r-- | source3/client/client.c | 16 | ||||
| -rw-r--r-- | source3/include/client.h | 1 | ||||
| -rw-r--r-- | source3/include/smb.h | 3 | ||||
| -rw-r--r-- | source3/libsmb/clientgen.c | 19 | ||||
| -rw-r--r-- | source3/param/loadparm.c | 26 | ||||
| -rw-r--r-- | source3/smbd/blocking.c | 2 | ||||
| -rw-r--r-- | source3/smbd/conn.c | 2 | ||||
| -rw-r--r-- | source3/smbd/negprot.c | 19 | ||||
| -rw-r--r-- | source3/smbd/notify_hash.c | 2 | ||||
| -rw-r--r-- | source3/smbd/process.c | 2 | ||||
| -rw-r--r-- | source3/smbd/server.c | 10 | ||||
| -rw-r--r-- | source3/smbd/service.c | 27 | ||||
| -rw-r--r-- | source3/torture/vfstest.c | 2 | 
13 files changed, 98 insertions, 33 deletions
| diff --git a/source3/client/client.c b/source3/client/client.c index 63d73c2d4c..ea8ec93f97 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -1869,6 +1869,21 @@ static int cmd_lowercase(void)  }  /**************************************************************************** + Toggle the case sensitive flag. +****************************************************************************/ + +static int cmd_setcase(void) +{ +	BOOL orig_case_sensitive = cli_set_case_sensitive(cli, False); + +	cli_set_case_sensitive(cli, !orig_case_sensitive); +	DEBUG(2,("filename case sensitivity is now %s\n",!orig_case_sensitive ? +		"on":"off")); + +	return 0; +} + +/****************************************************************************   Toggle the recurse flag.  ****************************************************************************/ @@ -2179,6 +2194,7 @@ static struct    {"archive",cmd_archive,"<level>\n0=ignore archive bit\n1=only get archive files\n2=only get archive files and reset archive bit\n3=get all files and reset archive bit",{COMPL_NONE,COMPL_NONE}},    {"blocksize",cmd_block,"blocksize <number> (default 20)",{COMPL_NONE,COMPL_NONE}},    {"cancel",cmd_cancel,"<jobid> cancel a print queue entry",{COMPL_NONE,COMPL_NONE}}, +  {"case_sensitive",cmd_setcase,"toggle the case sensitive flag to server",{COMPL_NONE,COMPL_NONE}},    {"cd",cmd_cd,"[directory] change/report the remote directory",{COMPL_REMOTE,COMPL_NONE}},    {"chmod",cmd_chmod,"<src> <mode> chmod a file using UNIX permission",{COMPL_REMOTE,COMPL_REMOTE}},    {"chown",cmd_chown,"<src> <uid> <gid> chown a file using UNIX uids and gids",{COMPL_REMOTE,COMPL_REMOTE}}, diff --git a/source3/include/client.h b/source3/include/client.h index 968b73f0b4..52a6c76299 100644 --- a/source3/include/client.h +++ b/source3/include/client.h @@ -153,6 +153,7 @@ struct cli_state {  	BOOL (*oplock_handler)(struct cli_state *cli, int fnum, unsigned char level);  	BOOL force_dos_errors; +	BOOL case_sensitive; /* False by default. */  	/* was this structure allocated by cli_initialise? If so, then             free in cli_shutdown() */ diff --git a/source3/include/smb.h b/source3/include/smb.h index 9100701e21..a802e96226 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -1349,7 +1349,8 @@ enum ldap_ssl_types {LDAP_SSL_ON, LDAP_SSL_OFF, LDAP_SSL_START_TLS};  enum ldap_passwd_sync_types {LDAP_PASSWD_SYNC_ON, LDAP_PASSWD_SYNC_OFF, LDAP_PASSWD_SYNC_ONLY};  /* Remote architectures we know about. */ -enum remote_arch_types {RA_UNKNOWN, RA_WFWG, RA_OS2, RA_WIN95, RA_WINNT, RA_WIN2K, RA_WINXP, RA_WIN2K3, RA_SAMBA}; +enum remote_arch_types {RA_UNKNOWN, RA_WFWG, RA_OS2, RA_WIN95, RA_WINNT, +			RA_WIN2K, RA_WINXP, RA_WIN2K3, RA_SAMBA, RA_CIFSFS};  /* case handling */  enum case_handling {CASE_LOWER,CASE_UPPER}; diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index b75d6be0a6..281ee3af84 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -176,7 +176,12 @@ void cli_setup_packet(struct cli_state *cli)  	SSVAL(cli->outbuf,smb_mid,cli->mid);  	if (cli->protocol > PROTOCOL_CORE) {  		uint16 flags2; -		SCVAL(cli->outbuf,smb_flg,0x8); +		if (cli->case_sensitive) { +			SCVAL(cli->outbuf,smb_flg,0x0); +		} else { +			/* Default setting, case insensitive. */ +			SCVAL(cli->outbuf,smb_flg,0x8); +		}  		flags2 = FLAGS2_LONG_PATH_COMPONENTS;  		if (cli->capabilities & CAP_UNICODE)  			flags2 |= FLAGS2_UNICODE_STRINGS; @@ -273,6 +278,7 @@ struct cli_state *cli_initialise(struct cli_state *cli)  	cli->outbuf = (char *)malloc(cli->bufsize+SAFETY_MARGIN);  	cli->inbuf = (char *)malloc(cli->bufsize+SAFETY_MARGIN);  	cli->oplock_handler = cli_oplock_ack; +	cli->case_sensitive = False;  	cli->use_spnego = lp_client_use_spnego(); @@ -441,6 +447,17 @@ uint16 cli_setpid(struct cli_state *cli, uint16 pid)  }  /**************************************************************************** + Set the case sensitivity flag on the packets. Returns old state. +****************************************************************************/ + +BOOL cli_set_case_sensitive(struct cli_state *cli, BOOL case_sensitive) +{ +	BOOL ret = cli->case_sensitive; +	cli->case_sensitive = case_sensitive; +	return ret; +} + +/****************************************************************************  Send a keepalive packet to the server  ****************************************************************************/  BOOL cli_send_keepalive(struct cli_state *cli) diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 03b86a9c18..5e959dbba3 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -364,7 +364,7 @@ typedef struct  	int iBlock_size;  	BOOL bPreexecClose;  	BOOL bRootpreexecClose; -	BOOL bCaseSensitive; +	int  iCaseSensitive;  	BOOL bCasePreserve;  	BOOL bShortCasePreserve;  	BOOL bHideDotFiles; @@ -487,7 +487,7 @@ static service sDefault = {  	1024,           /* iBlock_size */  	False,			/* bPreexecClose */  	False,			/* bRootpreexecClose */ -	False,			/* case sensitive */ +	Auto,			/* case sensitive */  	True,			/* case preserve */  	True,			/* short case preserve */  	True,			/* bHideDotFiles */ @@ -980,8 +980,8 @@ static struct parm_struct parm_table[] = {  	{"mangle prefix", P_INTEGER, P_GLOBAL, &Globals.mangle_prefix, NULL, NULL, FLAG_ADVANCED},   	{"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, FLAG_ADVANCED | FLAG_SHARE},  -	{"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},  -	{"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, FLAG_HIDE},  +	{"case sensitive", P_ENUM, P_LOCAL, &sDefault.iCaseSensitive, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},  +	{"casesignames", P_ENUM, P_LOCAL, &sDefault.iCaseSensitive, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE},   	{"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},   	{"short preserve case", P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},   	{"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},  @@ -1836,7 +1836,7 @@ FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)  FN_LOCAL_BOOL(lp_autoloaded, autoloaded)  FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)  FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose) -FN_LOCAL_BOOL(lp_casesensitive, bCaseSensitive) +FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)  FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)  FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)  FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles) @@ -2997,10 +2997,8 @@ static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue  {  	int i; -	for (i = 0; parm->enum_list[i].name; i++)  -	{ -		if ( strequal(pszParmValue, parm->enum_list[i].name))  -		{ +	for (i = 0; parm->enum_list[i].name; i++) { +		if ( strequal(pszParmValue, parm->enum_list[i].name)) {  			*ptr = parm->enum_list[i].value;  			break;  		} @@ -3870,11 +3868,12 @@ BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults,  	/* get the username for substituion -- preference to the current_user_info */ -	if ( strlen( current_user_info.smb_name ) != 0 ) +	if ( strlen( current_user_info.smb_name ) != 0 ) {  		username = current_user_info.smb_name; -	else +	} else {  		username = sub_get_smb_name(); -		 +	} +  	standard_sub_basic( username, n2,sizeof(n2) );  	add_to_file_list(pszFname, n2); @@ -3889,8 +3888,7 @@ BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults,  	init_globals();  	debug_init(); -	if (save_defaults) -	{ +	if (save_defaults) {  		init_locals();  		lp_save_defaults();  	} diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index c0512d5539..3983a4cbdf 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -680,7 +680,7 @@ void process_blocking_lock_queue(time_t t)  			continue;  		} -		if(!set_current_service(conn,True)) { +		if(!set_current_service(conn,SVAL(blr->inbuf,smb_flg),True)) {  			DEBUG(0,("process_blocking_lock_queue: Unable to become service Error was %s.\n", strerror(errno) ));  			/*  			 * Remove the entry and return an error to the client. diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c index e083e14426..34e19a3ca6 100644 --- a/source3/smbd/conn.c +++ b/source3/smbd/conn.c @@ -161,7 +161,7 @@ void conn_close_all(void)  	connection_struct *conn, *next;  	for (conn=Connections;conn;conn=next) {  		next=conn->next; -		set_current_service(conn, True); +		set_current_service(conn, 0, True);  		close_cnum(conn, conn->vuid);  	}  } diff --git a/source3/smbd/negprot.c b/source3/smbd/negprot.c index 1843c174bb..5ff53f6300 100644 --- a/source3/smbd/negprot.c +++ b/source3/smbd/negprot.c @@ -401,8 +401,9 @@ protocol [LANMAN2.1]  #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 { @@ -413,6 +414,7 @@ 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},  	{"LM1.2X002",               "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},  	{"Samba",                   "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2},  	{"DOS LM1.2X002",           "LANMAN2",  reply_lanman2,  PROTOCOL_LANMAN2}, @@ -460,7 +462,7 @@ int reply_negprot(connection_struct *conn,  		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")) @@ -472,12 +474,23 @@ int reply_negprot(connection_struct *conn,  		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; diff --git a/source3/smbd/notify_hash.c b/source3/smbd/notify_hash.c index ec414454f9..843580f6ed 100644 --- a/source3/smbd/notify_hash.c +++ b/source3/smbd/notify_hash.c @@ -164,7 +164,7 @@ static BOOL hash_check_notify(connection_struct *conn, uint16 vuid, char *path,  	if (!change_to_user(conn,vuid))  		return True; -	if (!set_current_service(conn,True)) { +	if (!set_current_service(conn,FLAG_CASELESS_PATHNAMES,True)) {  		change_to_root_user();  		return True;  	} diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 05e4d0b1d9..72a604811b 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -934,7 +934,7 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize  			return(ERROR_DOS(ERRSRV,ERRaccess));	      		/* load service specific parameters */ -		if (conn && !set_current_service(conn,(flags & (AS_USER|DO_CHDIR)?True:False))) +		if (conn && !set_current_service(conn,SVAL(inbuf,smb_flg),(flags & (AS_USER|DO_CHDIR)?True:False)))  			return(ERROR_DOS(ERRSRV,ERRaccess));  		/* does this protocol need to be run as guest? */ diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 343a835be8..c3e0da542e 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -494,18 +494,16 @@ BOOL reload_services(BOOL test)  	load_interfaces(); -	{ -		if (smbd_server_fd() != -1) {       -			set_socket_options(smbd_server_fd(),"SO_KEEPALIVE"); -			set_socket_options(smbd_server_fd(), user_socket_options); -		} +	if (smbd_server_fd() != -1) {       +		set_socket_options(smbd_server_fd(),"SO_KEEPALIVE"); +		set_socket_options(smbd_server_fd(), user_socket_options);  	}  	mangle_reset_cache();  	reset_stat_cache();  	/* this forces service parameters to be flushed */ -	set_current_service(NULL,True); +	set_current_service(NULL,0,True);  	return(ret);  } diff --git a/source3/smbd/service.c b/source3/smbd/service.c index 192a043bf5..3b499d5cc1 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -28,10 +28,11 @@ extern userdom_struct current_user_info;   Load parameters specific to a connection/service.  ****************************************************************************/ -BOOL set_current_service(connection_struct *conn,BOOL do_chdir) +BOOL set_current_service(connection_struct *conn, uint16 flags, BOOL do_chdir)  {  	extern char magic_char;  	static connection_struct *last_conn; +	static uint16 last_flags;  	int snum;  	if (!conn)  { @@ -51,10 +52,24 @@ BOOL set_current_service(connection_struct *conn,BOOL do_chdir)  		return(False);  	} -	if (conn == last_conn) +	if ((conn == last_conn) && (last_flags == flags)) {  		return(True); +	}  	last_conn = conn; +	last_flags = flags; +	 +	/* Obey the client case sensitivity requests - only for clients that support it. */ +	if (lp_casesensitive(snum) == Auto) { +		/* We need this uglyness due to DOS/Win9x clients that lie about case insensitivity. */ +		enum remote_arch_types ra_type = get_remote_arch(); +		if ((ra_type != RA_SAMBA) && (ra_type != RA_CIFSFS)) { +			/* Client can't support per-packet case sensitive pathnames. */ +			conn->case_sensitive = False; +		} else { +			conn->case_sensitive = !(flags & FLAG_CASELESS_PATHNAMES); +		} +	}  	magic_char = lp_magicchar(snum);  	return(True); @@ -347,7 +362,13 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser,  	conn->dirptr = NULL;  	/* Case options for the share. */ -	conn->case_sensitive = lp_casesensitive(snum); +	if (lp_casesensitive(snum) == Auto) { +		/* We will be setting this per packet. Set to be case insensitive for now. */ +		conn->case_sensitive = False; +	} else { +		conn->case_sensitive = (BOOL)lp_casesensitive(snum); +	} +  	conn->case_preserve = lp_preservecase(snum);  	conn->short_case_preserve = lp_shortpreservecase(snum); diff --git a/source3/torture/vfstest.c b/source3/torture/vfstest.c index 88fe348649..48556aa257 100644 --- a/source3/torture/vfstest.c +++ b/source3/torture/vfstest.c @@ -466,7 +466,7 @@ BOOL reload_services(BOOL test)  	reset_stat_cache();  	/* this forces service parameters to be flushed */ -	set_current_service(NULL,True); +	set_current_service(NULL,0,True);  	return (ret);  } | 
