From 533da83852b13c2e008938a026f99937ef320f3c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 27 Oct 2005 22:35:08 +0000 Subject: [PATCH] r11341: Put directory opens into the share mode db so we can treat them similarly to file opens (delete on close, share mode violations etc.). This fixes bug #3216 I will up the default hash size on the locking db in a later commit as this means more entries. Jeremy. (This used to be commit 1134abbbb3fd8e8b88e1a5817aae106476a4c126) --- source3/locking/locking.c | 3 ++- source3/smbd/close.c | 38 ++++++++++++++++++++++++++++++++++---- source3/smbd/open.c | 37 ++++++++++++++++++++++++++++++++++--- 3 files changed, 70 insertions(+), 8 deletions(-) diff --git a/source3/locking/locking.c b/source3/locking/locking.c index e3131e26a2a..aad254f276c 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -960,8 +960,9 @@ BOOL set_delete_on_close(files_struct *fsp, BOOL delete_on_close) delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name )); - if (fsp->is_directory || fsp->is_stat) + if (fsp->is_stat) { return True; + } lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL); if (lck == NULL) { diff --git a/source3/smbd/close.c b/source3/smbd/close.c index becca003b64..44ab168a3af 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -195,12 +195,12 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close) lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, fsp->fsp_name); if (lck == NULL) { - DEBUG(0, ("Could not get share mode lock\n")); + DEBUG(0, ("close_file: Could not get share mode lock for file %s\n", fsp->fsp_name)); return EINVAL; } if (!del_share_mode(lck, fsp)) { - DEBUG(0, ("Could not delete share entry\n")); + DEBUG(0, ("close_file: Could not delete share entry for file %s\n", fsp->fsp_name)); } delete_file = lck->delete_on_close; @@ -297,6 +297,9 @@ with error %s\n", fsp->fsp_name, strerror(errno) )); static int close_directory(files_struct *fsp, BOOL normal_close) { + struct share_mode_lock *lck = 0; + BOOL delete_dir = False; + remove_pending_change_notify_requests_by_fid(fsp); /* @@ -304,8 +307,33 @@ static int close_directory(files_struct *fsp, BOOL normal_close) * reference to a directory also. */ - if (normal_close && - get_delete_on_close_flag(fsp->dev, fsp->inode, fsp->fsp_name)) { + lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, fsp->fsp_name); + + if (lck == NULL) { + DEBUG(0, ("close_directory: Could not get share mode lock for %s\n", fsp->fsp_name)); + return EINVAL; + } + + if (!del_share_mode(lck, fsp)) { + DEBUG(0, ("close_directory: Could not delete share entry for %s\n", fsp->fsp_name)); + } + + delete_dir = lck->delete_on_close; + + if (delete_dir) { + int i; + /* See if others still have the file open. If this is the + * case, then don't delete */ + for (i=0; inum_share_modes; i++) { + if (is_valid_share_mode_entry(&lck->share_modes[i])) { + delete_dir = False; + break; + } + } + } + + + if (normal_close && delete_dir) { BOOL ok = rmdir_internals(fsp->conn, fsp->fsp_name); DEBUG(5,("close_directory: %s. Delete on close was set - deleting directory %s.\n", fsp->fsp_name, ok ? "succeeded" : "failed" )); @@ -321,6 +349,8 @@ static int close_directory(files_struct *fsp, BOOL normal_close) process_pending_change_notify_queue((time_t)0); } + talloc_free(lck); + /* * Do the code common to files and directories. */ diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 70687ff5805..42e1da839fb 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -1536,7 +1536,7 @@ files_struct *open_file_ntcreate(connection_struct *conn, lck = get_share_mode_lock(NULL, dev, inode, fname); if (lck == NULL) { - DEBUG(0, ("Coult not get share mode lock\n")); + DEBUG(0, ("open_file_ntcreate: Could not get share mode lock for %s\n", fname)); fd_close(conn, fsp); file_free(fsp); set_saved_ntstatus(NT_STATUS_SHARING_VIOLATION); @@ -1801,6 +1801,8 @@ files_struct *open_directory(connection_struct *conn, files_struct *fsp = NULL; BOOL dir_existed = VALID_STAT(*psbuf) ? True : False; BOOL create_dir = False; + struct share_mode_lock *lck = NULL; + NTSTATUS status; int info = 0; DEBUG(5,("open_directory: opening directory %s, access_mask = 0x%x, " @@ -1883,7 +1885,7 @@ files_struct *open_directory(connection_struct *conn, /* We know bad_path is false as it's caught earlier. */ - NTSTATUS status = mkdir_internal(conn, fname, False); + status = mkdir_internal(conn, fname, False); if (!NT_STATUS_IS_OK(status)) { DEBUG(2,("open_directory: unable to create %s. " @@ -1938,14 +1940,43 @@ files_struct *open_directory(connection_struct *conn, fsp->is_stat = False; string_set(&fsp->fsp_name,fname); + lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, fname); + + if (lck == NULL) { + DEBUG(0, ("open_directory: Could not get share mode lock for %s\n", fname)); + file_free(fsp); + set_saved_ntstatus(NT_STATUS_SHARING_VIOLATION); + return NULL; + } + + status = open_mode_check(conn, fname, lck, + access_mask, share_access, + create_options, &dir_existed); + + if (!NT_STATUS_IS_OK(status)) { + set_saved_ntstatus(status); + talloc_free(lck); + file_free(fsp); + return NULL; + } + + set_share_mode(lck, fsp, 0, NO_OPLOCK); + if (create_options & FILE_DELETE_ON_CLOSE) { - NTSTATUS status = can_set_delete_on_close(fsp, True, 0); + status = can_set_delete_on_close(fsp, True, 0); if (!NT_STATUS_IS_OK(status)) { + set_saved_ntstatus(status); + talloc_free(lck); file_free(fsp); return NULL; } + + lck->delete_on_close = True; + lck->modified = True; } + talloc_free(lck); + /* Change the owner if required. */ if ((info == FILE_WAS_CREATED) && lp_inherit_owner(SNUM(conn))) { change_owner_to_parent(conn, fsp, fsp->fsp_name, psbuf); -- 2.34.1