diff options
author | Andrew Tridgell <tridge@samba.org> | 2002-02-26 05:45:33 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2002-02-26 05:45:33 +0000 |
commit | 97d96862ca84f599ee6fed0910389e07d46ee91d (patch) | |
tree | 4ef2e394a48e731c1b7701db0ed9a449b6d2ee4a | |
parent | 2ff93902451a234e78490a1b18c2fae43d997b01 (diff) | |
download | samba-97d96862ca84f599ee6fed0910389e07d46ee91d.tar.gz samba-97d96862ca84f599ee6fed0910389e07d46ee91d.tar.bz2 samba-97d96862ca84f599ee6fed0910389e07d46ee91d.zip |
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 used to be commit d09ae0c667a94fcf870c0fc7f97119266a650d45)
-rw-r--r-- | source3/smbd/nttrans.c | 10 | ||||
-rw-r--r-- | source3/smbd/open.c | 59 |
2 files changed, 53 insertions, 16 deletions
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 694cfb92a3..501f0e9ab0 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -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) { diff --git a/source3/smbd/open.c b/source3/smbd/open.c index aab7b5079e..7396233c26 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -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 */ @@ -609,6 +625,19 @@ files_struct *open_file_shared(connection_struct *conn,char *fname, SMB_STRUCT_S 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; int deny_mode = GET_DENY_MODE(share_mode); @@ -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); |