summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2002-02-26 05:45:33 +0000
committerAndrew Tridgell <tridge@samba.org>2002-02-26 05:45:33 +0000
commit97d96862ca84f599ee6fed0910389e07d46ee91d (patch)
tree4ef2e394a48e731c1b7701db0ed9a449b6d2ee4a
parent2ff93902451a234e78490a1b18c2fae43d997b01 (diff)
downloadsamba-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.c10
-rw-r--r--source3/smbd/open.c59
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);