[PATCH 7/8] Bug 9395 - Samba fails the simple_nodelete test of smb2.rename tests from master.

Jeremy Allison jra at samba.org
Fri Nov 16 12:54:19 MST 2012


Change parent_dirname_compatible_open() to check the share mode
table for the parent directory and reject incompatible opens.

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 source3/smbd/reply.c |   52 ++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 42 insertions(+), 10 deletions(-)

diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 823637b..4108869 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -6156,8 +6156,12 @@ static NTSTATUS parent_dirname_compatible_open(connection_struct *conn,
 	char *parent_dir = NULL;
 	struct smb_filename smb_fname_parent;
 	struct file_id id;
-	files_struct *fsp = NULL;
 	int ret;
+	struct share_mode_lock *lck = NULL;
+	struct timespec *dummy = NULL;
+	NTSTATUS status;
+	uint32_t parent_name_hash = 0;
+	bool existed = false;
 
 	if (!parent_dirname(talloc_tos(), smb_fname_dst_in->base_name,
 			&parent_dir, NULL)) {
@@ -6171,19 +6175,47 @@ static NTSTATUS parent_dirname_compatible_open(connection_struct *conn,
 		return map_nt_error_from_unix(errno);
 	}
 
+	status = file_name_hash(conn,
+				smb_fname_parent.base_name,
+				&parent_name_hash);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
 	/*
-	 * We're only checking on this smbd here, mostly good
-	 * enough.. and will pass tests.
+	 * Windows does a CreateFile on the parent
+	 * directory in order to do a rename. We
+	 * don't need to do that, but we do need to
+	 * check the current open modes on the parent
+	 * directory in order to pass all the rename
+	 * tests in smbtorture.
 	 */
 
 	id = vfs_file_id_from_sbuf(conn, &smb_fname_parent.st);
-	for (fsp = file_find_di_first(conn->sconn, id); fsp;
-			fsp = file_find_di_next(fsp)) {
-		if (fsp->access_mask & DELETE_ACCESS) {
-			return NT_STATUS_SHARING_VIOLATION;
-                }
-        }
-	return NT_STATUS_OK;
+	lck = get_share_mode_lock(talloc_tos(),
+				id,
+				conn->connectpath,
+				&smb_fname_parent,
+				dummy);
+	if (!lck) {
+		return NT_STATUS_OK;
+	}
+
+	status = open_mode_check(conn,
+				lck,
+				parent_name_hash,
+				FILE_WRITE_DATA,
+				(FILE_SHARE_READ |
+					FILE_SHARE_WRITE),
+				0, /* create_options */
+				&existed);
+
+	DEBUG(10,("open_mode_check on %s returned %s\n",
+		smb_fname_str_dbg(&smb_fname_parent),
+		nt_errstr(status) ));
+
+	TALLOC_FREE(lck);
+	return status;
 }
 
 /****************************************************************************
-- 
1.7.7.3



More information about the samba-technical mailing list