summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2005-10-27 22:35:08 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 11:05:13 -0500
commit533da83852b13c2e008938a026f99937ef320f3c (patch)
tree82cbb895a2d1152d6b3a2377445994e33f67587c /source3/smbd
parent7aecd20c00b81aa2b7a20e75e9cc653ae243500b (diff)
downloadsamba-533da83852b13c2e008938a026f99937ef320f3c.tar.gz
samba-533da83852b13c2e008938a026f99937ef320f3c.tar.bz2
samba-533da83852b13c2e008938a026f99937ef320f3c.zip
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)
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/close.c38
-rw-r--r--source3/smbd/open.c37
2 files changed, 68 insertions, 7 deletions
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index becca003b6..44ab168a3a 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; i<lck->num_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 70687ff580..42e1da839f 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);