1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-29 21:47:30 +03:00

This is a nasty hack to fix "xcopy /o" from win2000 on a Samba share

The hack passes the true ntcreate desired_access down to open_file_shared1()
from the ntcreatex function. This is used to determine if share modes
should be used in denying this open.

This hack will become unnecessary when we redo open.c to use the proper
NTCreateX semantics rather than trying to jam the ntcreate semantics into
openX semantics.
This commit is contained in:
Andrew Tridgell -
parent 28d4e7a3e2
commit d09ae0c667
2 changed files with 53 additions and 16 deletions

View File

@ -717,8 +717,11 @@ int reply_ntcreate_and_X(connection_struct *conn,
* before issuing an oplock break request to
* our client. JRA. */
fsp = open_file_shared(conn,fname,&sbuf,smb_open_mode,
smb_ofun,unixmode, oplock_request,&rmode,&smb_action);
fsp = open_file_shared1(conn,fname,&sbuf,
desired_access,
smb_open_mode,
smb_ofun,unixmode, oplock_request,
&rmode,&smb_action);
if (!fsp) {
/* We cheat here. There are two cases we
@ -1213,7 +1216,8 @@ static int call_nt_transact_create(connection_struct *conn,
* Ordinary file case.
*/
fsp = open_file_shared(conn,fname,&sbuf,smb_open_mode,smb_ofun,unixmode,
fsp = open_file_shared1(conn,fname,&sbuf,desired_access,
smb_open_mode,smb_ofun,unixmode,
oplock_request,&rmode,&smb_action);
if (!fsp) {

View File

@ -437,8 +437,10 @@ static BOOL check_share_mode(connection_struct *conn, share_mode_entry *share, i
****************************************************************************/
static int open_mode_check(connection_struct *conn, const char *fname, SMB_DEV_T dev,
SMB_INO_T inode, int share_mode, int *p_flags, int *p_oplock_request,
BOOL *p_all_current_opens_are_level_II)
SMB_INO_T inode,
uint32 desired_access,
int share_mode, int *p_flags, int *p_oplock_request,
BOOL *p_all_current_opens_are_level_II)
{
int i;
int num_share_modes;
@ -510,13 +512,27 @@ dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (dou
*p_all_current_opens_are_level_II = False;
}
/* someone else has a share lock on it, check to see
if we can too */
if(check_share_mode(conn, share_entry, share_mode, fname, fcbopen, p_flags) == False) {
SAFE_FREE(old_shares);
errno = EACCES;
return -1;
/* this is a nasty hack, but necessary until we rewrite our open
handling to use a NTCreateX call as the basic call.
NT may open a file with neither read nor write access, and in
this case it expects the open not to conflict with any
existing deny modes. This happens (for example) during a
"xcopy /o" where the second file descriptor is used for
ACL sets
This code should be removed once we have a propoer ntcreateX
open functions
(tridge)
*/
if (desired_access == 0 ||
(desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE))) {
/* someone else has a share lock on it, check to see
if we can too */
if (!check_share_mode(conn, share_entry, share_mode,
fname, fcbopen, p_flags)) {
SAFE_FREE(old_shares);
errno = EACCES;
return -1;
}
}
} /* end for */
@ -608,6 +624,19 @@ static void kernel_flock(files_struct *fsp, int deny_mode)
files_struct *open_file_shared(connection_struct *conn,char *fname, SMB_STRUCT_STAT *psbuf,
int share_mode,int ofun, mode_t mode,int oplock_request,
int *Access,int *action)
{
return open_file_shared1(conn, fname, psbuf, 0, share_mode, ofun, mode,
oplock_request, Access, action);
}
/****************************************************************************
Open a file with a share mode. On output from this open we are guarenteeing
that
****************************************************************************/
files_struct *open_file_shared1(connection_struct *conn,char *fname, SMB_STRUCT_STAT *psbuf,
uint32 desired_access,
int share_mode,int ofun, mode_t mode,int oplock_request,
int *Access,int *action)
{
int flags=0;
int flags2=0;
@ -736,8 +765,10 @@ files_struct *open_file_shared(connection_struct *conn,char *fname, SMB_STRUCT_S
lock_share_entry(conn, dev, inode);
num_share_modes = open_mode_check(conn, fname, dev, inode, share_mode,
&flags, &oplock_request, &all_current_opens_are_level_II);
num_share_modes = open_mode_check(conn, fname, dev, inode,
desired_access,
share_mode,
&flags, &oplock_request, &all_current_opens_are_level_II);
if(num_share_modes == -1) {
/*
@ -801,8 +832,10 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n",
lock_share_entry_fsp(fsp);
num_share_modes = open_mode_check(conn, fname, dev, inode, share_mode,
&flags, &oplock_request, &all_current_opens_are_level_II);
num_share_modes = open_mode_check(conn, fname, dev, inode,
desired_access,
share_mode,
&flags, &oplock_request, &all_current_opens_are_level_II);
if(num_share_modes == -1) {
unlock_share_entry_fsp(fsp);