[SCM] Samba Shared Repository - branch master updated - release-4-0-0alpha8-861-g457191e

Tim Prouty tprouty at samba.org
Thu Aug 6 19:01:25 MDT 2009


The branch, master has been updated
       via  457191e9f396898b8a511cf860f24986f36fd879 (commit)
       via  09e9904f18634b135944f466c48c4be1a43b4272 (commit)
      from  890dfe003c91f8df737e5e2e4e440e1a9f416ae8 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 457191e9f396898b8a511cf860f24986f36fd879
Author: Tim Prouty <tprouty at samba.org>
Date:   Thu Aug 6 15:53:33 2009 -0700

    s3: Fix a bug in renames of directories
    
    Recently code was added to match windows semantics of denying the
    rename of a directory if there are open files underneath it.  This
    does partly match windows semantics, but it turns out the rename
    should be allowed if the open file handle is for the directory being
    renamed, or for a stream on the directory being renamed.  This patch
    refines the check to better follow these rename semantics.

commit 09e9904f18634b135944f466c48c4be1a43b4272
Author: Tim Prouty <tprouty at samba.org>
Date:   Thu Aug 6 11:23:23 2009 -0700

    s4 torture: Extend the RAW-RENAME test to more fully test directory renames.
    
    The existing test was only covering files opened underneath the
    directory that was being renamed.  It is not uncommon for windows
    clients to actually hold a read-only handle to a directory open across
    the rename, which it turns out doesn't return NT_STATUS_ACCESS_DENIED.
    Additionally, holding a handle open to a stream on the directory is
    also allowed.

-----------------------------------------------------------------------

Summary of changes:
 source3/smbd/files.c         |   25 ++++++++++++++++-----
 source4/torture/raw/rename.c |   50 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 69 insertions(+), 6 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/smbd/files.c b/source3/smbd/files.c
index a170f77..146d809 100644
--- a/source3/smbd/files.c
+++ b/source3/smbd/files.c
@@ -404,14 +404,15 @@ bool file_find_subpath(files_struct *dir_fsp)
 {
 	files_struct *fsp;
 	size_t dlen;
-	char *d_fullname;
+	char *d_fullname = NULL;
+	bool ret = false;
 
 	d_fullname = talloc_asprintf(talloc_tos(), "%s/%s",
 				     dir_fsp->conn->connectpath,
 				     dir_fsp->fsp_name->base_name);
 
 	if (!d_fullname) {
-		return false;
+		goto out;
 	}
 
 	dlen = strlen(d_fullname);
@@ -429,15 +430,27 @@ bool file_find_subpath(files_struct *dir_fsp)
 					fsp->fsp_name->base_name);
 
 		if (strnequal(d_fullname, d1_fullname, dlen)) {
-			TALLOC_FREE(d_fullname);
+			int d1_len = strlen(d1_fullname);
+
+			/*
+			 * If the open file is a second file handle to the
+			 * same name or is a stream on the original file, then
+			 * don't return true.
+			 */
+			if (d1_len == dlen) {
+				TALLOC_FREE(d1_fullname);
+				continue;
+			}
+
 			TALLOC_FREE(d1_fullname);
-			return true;
+			ret = true;
+			goto out;
 		}
 		TALLOC_FREE(d1_fullname);
 	} 
-
+ out:
 	TALLOC_FREE(d_fullname);
-	return false;
+	return ret;
 }
 
 /****************************************************************************
diff --git a/source4/torture/raw/rename.c b/source4/torture/raw/rename.c
index e91c3b2..15fed0e 100644
--- a/source4/torture/raw/rename.c
+++ b/source4/torture/raw/rename.c
@@ -529,6 +529,7 @@ static bool test_dir_rename(struct torture_context *tctx, struct smbcli_state *c
         const char *dname1 = BASEDIR "\\dir_for_rename";
         const char *dname2 = BASEDIR "\\renamed_dir";
         const char *fname = BASEDIR "\\dir_for_rename\\file.txt";
+	const char *sname = BASEDIR "\\dir_for_rename:a stream:$DATA";
 	bool ret = true;
 	int fnum = -1;
 
@@ -593,6 +594,55 @@ static bool test_dir_rename(struct torture_context *tctx, struct smbcli_state *c
 	status = smb_raw_rename(cli->tree, &ren_io);
 	CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
 
+	/* Close the file and try the rename. */
+	smbcli_close(cli->tree, fnum);
+
+	status = smb_raw_rename(cli->tree, &ren_io);
+	CHECK_STATUS(status, NT_STATUS_OK);
+
+	/*
+	 * Now try just holding a second handle on the directory and holding
+	 * it open across a rename.  This should be allowed.
+	 */
+	io.ntcreatex.in.fname = dname2;
+	io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
+
+	io.ntcreatex.in.access_mask = SEC_STD_READ_CONTROL |
+	    SEC_FILE_READ_ATTRIBUTE | SEC_FILE_READ_EA | SEC_FILE_READ_DATA;
+
+	status = smb_raw_open(cli->tree, tctx, &io);
+        CHECK_STATUS(status, NT_STATUS_OK);
+        fnum = io.ntcreatex.out.file.fnum;
+
+	ren_io.generic.level = RAW_RENAME_RENAME;
+	ren_io.rename.in.pattern1 = dname2;
+	ren_io.rename.in.pattern2 = dname1;
+	ren_io.rename.in.attrib = 0;
+
+	status = smb_raw_rename(cli->tree, &ren_io);
+	CHECK_STATUS(status, NT_STATUS_OK);
+
+	/* close our handle to the directory. */
+	smbcli_close(cli->tree, fnum);
+
+	/*
+	 * Now try opening a stream on the directory and holding it open
+	 * across a rename.  This should be allowed.
+	 */
+	io.ntcreatex.in.fname = sname;
+
+	status = smb_raw_open(cli->tree, tctx, &io);
+        CHECK_STATUS(status, NT_STATUS_OK);
+        fnum = io.ntcreatex.out.file.fnum;
+
+	ren_io.generic.level = RAW_RENAME_RENAME;
+	ren_io.rename.in.pattern1 = dname1;
+	ren_io.rename.in.pattern2 = dname2;
+	ren_io.rename.in.attrib = 0;
+
+	status = smb_raw_rename(cli->tree, &ren_io);
+	CHECK_STATUS(status, NT_STATUS_OK);
+
 done:
 	
 	if (fnum != -1) {


-- 
Samba Shared Repository


More information about the samba-cvs mailing list