[SCM] Samba Shared Repository - branch v4-0-test updated - release-4-0-0alpha3-1858-g3bec932

Andrew Tridgell tridge at samba.org
Tue May 27 07:23:11 GMT 2008


The branch, v4-0-test has been updated
       via  3bec932a89006521ba74bde7943b8cd5b4a660d8 (commit)
       via  2633bc749792c224acc73a2e4ca723404331c19c (commit)
       via  2932fcb04646bb921fb1daa365dd4c86cadfe4c0 (commit)
       via  2ac27bfffa557d6c0f71c443b43a8d1967edb177 (commit)
       via  d1bde5830cd56042236d72598e5cfe9c7abc4c47 (commit)
       via  897f4582bee72e319874e8a2d064ba442415571d (commit)
       via  bb546ab3779b235c5276ef9a714d1ca57b6815c9 (commit)
       via  8c263f91bda97eb910c8589b6cd987ec4a62d770 (commit)
       via  067f1271adaa13d537bbc92b19fe8d633cbaaf50 (commit)
       via  71915128498674d9937780b9278fd2ac1eb06ba8 (commit)
       via  dcdaa9f5fd9150b16fb277213e864e5c39d831d6 (commit)
       via  f5068c6e50215f6ea7108d58d783394a315ff14f (commit)
       via  ccbf5238767605f020ede66c8027731487c8cf00 (commit)
       via  88a2c7b2f44f160836e477e460812df557204f51 (commit)
       via  c73dd078eaa20c7bf0b833e65b24c29aab738f25 (commit)
       via  73dbfb9b4148dbfdc30518c08db4658d189f4160 (commit)
       via  3b811a52fe9a8356337ad149d01a3498c09d900a (commit)
       via  16787e99f3de7255e315651c095486f90f65f2ca (commit)
      from  da3094d1ba86a8f4967ca1993383b0767439f79f (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v4-0-test


- Log -----------------------------------------------------------------
commit 3bec932a89006521ba74bde7943b8cd5b4a660d8
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue May 27 17:22:02 2008 +1000

    enforce lock ordering in SMB2

commit 2633bc749792c224acc73a2e4ca723404331c19c
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue May 27 16:43:36 2008 +1000

    added support for the output fields of SMB2 close

commit 2932fcb04646bb921fb1daa365dd4c86cadfe4c0
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue May 27 16:02:43 2008 +1000

    added some SMB2 locking tests from gentest

commit 2ac27bfffa557d6c0f71c443b43a8d1967edb177
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue May 27 16:02:27 2008 +1000

    another attempt at the damn SEC_STD_SYNCHRONIZE flag

commit d1bde5830cd56042236d72598e5cfe9c7abc4c47
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue May 27 16:02:10 2008 +1000

    it seems that lock flags are only validated when UNLOCK is set

commit 897f4582bee72e319874e8a2d064ba442415571d
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue May 27 15:27:25 2008 +1000

    disable the SEC_STD_SYNCHRONIZE test until we know what it means

commit bb546ab3779b235c5276ef9a714d1ca57b6815c9
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue May 27 15:00:05 2008 +1000

    another gentest derived test

commit 8c263f91bda97eb910c8589b6cd987ec4a62d770
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue May 27 14:59:55 2008 +1000

    make the SEC_STD_SYNCHRONIZE test more specific

commit 067f1271adaa13d537bbc92b19fe8d633cbaaf50
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue May 27 14:30:42 2008 +1000

    SEC_STD_SYNCHRONIZE is only invalid on SMB2

commit 71915128498674d9937780b9278fd2ac1eb06ba8
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue May 27 14:07:27 2008 +1000

    expanded the SMB2 create testing

commit dcdaa9f5fd9150b16fb277213e864e5c39d831d6
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue May 27 14:07:11 2008 +1000

    check for some more invalid bits in smb2 create

commit f5068c6e50215f6ea7108d58d783394a315ff14f
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue May 27 14:06:51 2008 +1000

    Vista returns ACCESS_DENIED here

commit ccbf5238767605f020ede66c8027731487c8cf00
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue May 27 14:06:38 2008 +1000

    add a mask of invalid security bits

commit 88a2c7b2f44f160836e477e460812df557204f51
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue May 27 14:06:27 2008 +1000

    cope better with read only files in smb2_deltree

commit c73dd078eaa20c7bf0b833e65b24c29aab738f25
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue May 27 12:43:10 2008 +1000

    cleanup some warnings and add --skip-cleanup

commit 73dbfb9b4148dbfdc30518c08db4658d189f4160
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue May 27 12:42:43 2008 +1000

    check invalid create options in the right order

commit 3b811a52fe9a8356337ad149d01a3498c09d900a
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue May 27 12:42:19 2008 +1000

    don't alter the in blobs in a SMB2 create, otherwise two calls in a
    row will fail

commit 16787e99f3de7255e315651c095486f90f65f2ca
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue May 27 12:41:50 2008 +1000

    the start of a SMB2 create test suite

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

Summary of changes:
 source/libcli/raw/interfaces.h |   31 +++++-
 source/libcli/smb2/create.c    |   11 +-
 source/libcli/smb2/util.c      |   10 ++
 source/librpc/idl/security.idl |    3 +
 source/ntvfs/cifs/vfs_cifs.c   |   10 ++
 source/ntvfs/ntvfs_generic.c   |  123 ++++++++++++++++-------
 source/ntvfs/posix/pvfs_acl.c  |    2 +-
 source/ntvfs/posix/pvfs_open.c |   49 ++++++++-
 source/torture/gentest_smb2.c  |  222 +++++++++++++++++++++++++++++++---------
 source/torture/smb2/config.mk  |    3 +-
 source/torture/smb2/connect.c  |    6 +-
 source/torture/smb2/create.c   |  201 ++++++++++++++++++++++++++++++++++++
 source/torture/smb2/lock.c     |  104 ++++++++++++++++++-
 source/torture/smb2/smb2.c     |    1 +
 14 files changed, 667 insertions(+), 109 deletions(-)
 create mode 100644 source/torture/smb2/create.c


Changeset truncated at 500 lines:

diff --git a/source/libcli/raw/interfaces.h b/source/libcli/raw/interfaces.h
index 36d8c3a..68ebc19 100644
--- a/source/libcli/raw/interfaces.h
+++ b/source/libcli/raw/interfaces.h
@@ -1950,23 +1950,43 @@ union smb_lock {
 enum smb_close_level {
 	RAW_CLOSE_CLOSE,
 	RAW_CLOSE_SPLCLOSE,
-	RAW_CLOSE_SMB2
+	RAW_CLOSE_SMB2,
+	RAW_CLOSE_GENERIC,
 };
 
-#define RAW_CLOSE_GENERIC RAW_CLOSE_CLOSE
-
 /*
   union for close() backend call
 */
 union smb_close {
-	/* SMBclose (and generic) interface */
+	/* generic interface */
 	struct {
 		enum smb_close_level level;
 		struct {
 			union smb_handle file;
 			time_t write_time;
+#define SMB2_CLOSE_FLAGS_FULL_INFORMATION (1<<0)
+			uint16_t flags; /* SMB2_CLOSE_FLAGS_* */
 		} in;
-	} close, generic;
+		struct {
+			uint16_t flags;
+			NTTIME   create_time;
+			NTTIME   access_time;
+			NTTIME   write_time;
+			NTTIME   change_time;
+			uint64_t alloc_size;
+			uint64_t size;
+			uint32_t file_attr;
+		} out;
+	} generic;
+
+	/* SMBclose interface */
+	struct {
+		enum smb_close_level level;
+		struct {
+			union smb_handle file;
+			time_t write_time;
+		} in;
+	} close;
 
 	/* SMBsplclose interface - empty! */
 	struct {
@@ -1984,7 +2004,6 @@ union smb_close {
 
 			/* static body buffer 24 (0x18) bytes */
 			/* uint16_t buffer_code;  0x18 */
-#define SMB2_CLOSE_FLAGS_FULL_INFORMATION (1<<0)
 			uint16_t flags; /* SMB2_CLOSE_FLAGS_* */
 			uint32_t _pad;
 		} in;
diff --git a/source/libcli/smb2/create.c b/source/libcli/smb2/create.c
index b1b8b0c..1901cb4 100644
--- a/source/libcli/smb2/create.c
+++ b/source/libcli/smb2/create.c
@@ -94,6 +94,7 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create
 	NTSTATUS status;
 	DATA_BLOB blob = data_blob(NULL, 0);
 	uint32_t i;
+	struct smb2_create_blobs blobs = io->in.blobs;
 
 	req = smb2_request_init_tree(tree, SMB2_OP_CREATE, 0x38, true, 0);
 	if (req == NULL) return NULL;
@@ -119,7 +120,7 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create
 		DATA_BLOB b = data_blob_talloc(req, NULL, 
 					       ea_list_size_chained(io->in.eas.num_eas, io->in.eas.eas, 4));
 		ea_put_list_chained(b.data, io->in.eas.num_eas, io->in.eas.eas, 4);
-		status = smb2_create_blob_add(req, &io->in.blobs,
+		status = smb2_create_blob_add(req, &blobs,
 					      SMB2_CREATE_TAG_EXTA, b);
 		if (!NT_STATUS_IS_OK(status)) {
 			talloc_free(req);
@@ -130,22 +131,22 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create
 
 	/* an empty MxAc tag seems to be used to ask the server to
 	   return the maximum access mask allowed on the file */
-	status = smb2_create_blob_add(req, &io->in.blobs,
+	status = smb2_create_blob_add(req, &blobs,
 				      SMB2_CREATE_TAG_MXAC, data_blob(NULL, 0));
 	if (!NT_STATUS_IS_OK(status)) {
 		talloc_free(req);
 		return NULL;
 	}
 
-	for (i=0; i < io->in.blobs.num_blobs; i++) {
+	for (i=0; i < blobs.num_blobs; i++) {
 		bool last = false;
 		const struct smb2_create_blob *c;
 
-		if ((i + 1) == io->in.blobs.num_blobs) {
+		if ((i + 1) == blobs.num_blobs) {
 			last = true;
 		}
 
-		c = &io->in.blobs.blobs[i];
+		c = &blobs.blobs[i];
 		status = smb2_create_blob_push_one(req, &blob,
 						   c, last);
 		if (!NT_STATUS_IS_OK(status)) {
diff --git a/source/libcli/smb2/util.c b/source/libcli/smb2/util.c
index 9eb344e..311cea9 100644
--- a/source/libcli/smb2/util.c
+++ b/source/libcli/smb2/util.c
@@ -127,6 +127,16 @@ int smb2_deltree(struct smb2_tree *tree, const char *dname)
 		return 0;
 	}
 
+	if (NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) {
+		/* it could be read-only */
+		status = smb2_util_setatr(tree, dname, FILE_ATTRIBUTE_NORMAL);
+		status = smb2_util_unlink(tree, dname);
+	}
+	if (NT_STATUS_IS_OK(status)) {
+		talloc_free(tmp_ctx);
+		return 1;
+	}
+
 	ZERO_STRUCT(create_parm);
 	create_parm.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
 	create_parm.in.share_access = 
diff --git a/source/librpc/idl/security.idl b/source/librpc/idl/security.idl
index 314846c..f8e9e9e 100644
--- a/source/librpc/idl/security.idl
+++ b/source/librpc/idl/security.idl
@@ -106,6 +106,9 @@ interface security
 	const int SEC_ADS_LIST_OBJECT      = 0x00000080;
 	const int SEC_ADS_CONTROL_ACCESS   = 0x00000100;
 
+	/* invalid bits */
+	const int SEC_MASK_INVALID         = 0x0ce0fe00;
+
 	/* generic->specific mappings for files */
 	const int SEC_RIGHTS_FILE_READ    = SEC_STD_READ_CONTROL | 
 	                                    SEC_STD_SYNCHRONIZE | 
diff --git a/source/ntvfs/cifs/vfs_cifs.c b/source/ntvfs/cifs/vfs_cifs.c
index 2b61268..844fa11 100644
--- a/source/ntvfs/cifs/vfs_cifs.c
+++ b/source/ntvfs/cifs/vfs_cifs.c
@@ -769,6 +769,7 @@ static NTSTATUS cvfs_close(struct ntvfs_module_context *ntvfs,
 	struct cvfs_private *private = ntvfs->private_data;
 	struct smbcli_request *c_req;
 	struct cvfs_file *f;
+	union smb_close io2;
 
 	SETUP_PID;
 
@@ -776,6 +777,15 @@ static NTSTATUS cvfs_close(struct ntvfs_module_context *ntvfs,
 	    private->map_generic) {
 		return ntvfs_map_close(ntvfs, req, io);
 	}
+
+	if (io->generic.level == RAW_CLOSE_GENERIC) {
+		ZERO_STRUCT(io2);
+		io2.close.level = RAW_CLOSE_CLOSE;
+		io2.close.in.file = io->generic.in.file;
+		io2.close.in.write_time = io->generic.in.write_time;
+		io = &io2;
+	}
+
 	SETUP_FILE_HERE(f);
 	/* Note, we aren't free-ing f, or it's h here. Should we?
 	   even if file-close fails, we'll remove it from the list,
diff --git a/source/ntvfs/ntvfs_generic.c b/source/ntvfs/ntvfs_generic.c
index 9b4f235..3d92c0b 100644
--- a/source/ntvfs/ntvfs_generic.c
+++ b/source/ntvfs/ntvfs_generic.c
@@ -523,9 +523,16 @@ NTSTATUS ntvfs_map_open(struct ntvfs_module_context *ntvfs,
 		io2->generic.in.sec_desc	= NULL;
 		io2->generic.in.ea_list		= NULL;
 
+		/* we need to check these bits before we check the private mask */
+		if (io2->generic.in.create_options & NTCREATEX_OPTIONS_NOT_SUPPORTED_MASK) {
+			status = NT_STATUS_NOT_SUPPORTED;
+			break;
+		}
+
 		/* we use a couple of bits of the create options internally */
 		if (io2->generic.in.create_options & NTCREATEX_OPTIONS_PRIVATE_MASK) {
-			return NT_STATUS_INVALID_PARAMETER;
+			status = NT_STATUS_INVALID_PARAMETER;
+			break;
 		}
 
 		status = ntvfs->ops->open(ntvfs, req, io2);		
@@ -1020,7 +1027,7 @@ NTSTATUS ntvfs_map_lock(struct ntvfs_module_context *ntvfs,
 	case RAW_LOCK_SMB2: {
 		/* this is only approximate! We need to change the
 		   generic structure to fix this properly */
-		int i;
+		int i, j;
 		if (lck->smb2.in.lock_count < 1) {
 			return NT_STATUS_INVALID_PARAMETER;
 		}
@@ -1037,33 +1044,36 @@ NTSTATUS ntvfs_map_lock(struct ntvfs_module_context *ntvfs,
 			return NT_STATUS_NO_MEMORY;
 		}
 		for (i=0;i<lck->smb2.in.lock_count;i++) {
-			if (lck->smb2.in.locks[i].flags & ~SMB2_LOCK_FLAG_ALL_MASK) {
+			if (!(lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_UNLOCK)) {
+				break;
+			}
+			j = lck2->generic.in.ulock_cnt;
+			if (lck->smb2.in.locks[i].flags & 
+			    (SMB2_LOCK_FLAG_SHARED|SMB2_LOCK_FLAG_EXCLUSIVE)) {
 				return NT_STATUS_INVALID_PARAMETER;
 			}
+			lck2->generic.in.ulock_cnt++;
+			lck2->generic.in.locks[j].pid = 0;
+			lck2->generic.in.locks[j].offset = lck->smb2.in.locks[i].offset;
+			lck2->generic.in.locks[j].count = lck->smb2.in.locks[i].length;
+			lck2->generic.in.locks[j].pid = 0;
+		}
+		for (;i<lck->smb2.in.lock_count;i++) {
 			if (lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_UNLOCK) {
-				int j = lck2->generic.in.ulock_cnt;
-				lck2->generic.in.ulock_cnt++;
-				lck2->generic.in.locks[j].pid = 0;
-				lck2->generic.in.locks[j].offset = lck->smb2.in.locks[i].offset;
-				lck2->generic.in.locks[j].count = lck->smb2.in.locks[i].length;
-				lck2->generic.in.locks[j].pid = 0;
+				/* w2008 requires unlocks to come first */
+				return NT_STATUS_INVALID_PARAMETER;
 			}
-		}
-		for (i=0;i<lck->smb2.in.lock_count;i++) {
-			if (!(lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_UNLOCK)) {
-				int j = lck2->generic.in.ulock_cnt + 
-					lck2->generic.in.lock_cnt;
-				lck2->generic.in.lock_cnt++;
-				lck2->generic.in.locks[j].pid = 0;
-				lck2->generic.in.locks[j].offset = lck->smb2.in.locks[i].offset;
-				lck2->generic.in.locks[j].count = lck->smb2.in.locks[i].length;
-				lck2->generic.in.locks[j].pid = 0;
-				if (!(lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_EXCLUSIVE)) {
-					lck2->generic.in.mode = LOCKING_ANDX_SHARED_LOCK;
-				}
-				if (lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_FAIL_IMMEDIATELY) {
-					lck2->generic.in.timeout = 0;
-				}
+			j = lck2->generic.in.ulock_cnt + lck2->generic.in.lock_cnt;
+			lck2->generic.in.lock_cnt++;
+			lck2->generic.in.locks[j].pid = 0;
+			lck2->generic.in.locks[j].offset = lck->smb2.in.locks[i].offset;
+			lck2->generic.in.locks[j].count = lck->smb2.in.locks[i].length;
+			lck2->generic.in.locks[j].pid = 0;
+			if (!(lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_EXCLUSIVE)) {
+				lck2->generic.in.mode = LOCKING_ANDX_SHARED_LOCK;
+			}
+			if (lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_FAIL_IMMEDIATELY) {
+				lck2->generic.in.timeout = 0;
 			}
 		}
 		/* initialize output value */
@@ -1402,11 +1412,42 @@ done:
 /* 
    NTVFS close generic to any mapper
 */
+static NTSTATUS ntvfs_map_close_finish(struct ntvfs_module_context *ntvfs,
+					struct ntvfs_request *req,
+					union smb_close *cl, 
+					union smb_close *cl2, 
+					NTSTATUS status)
+{
+	NT_STATUS_NOT_OK_RETURN(status);
+
+	switch (cl->generic.level) {
+	case RAW_CLOSE_SMB2:
+		cl->smb2.out.flags        = cl2->generic.out.flags;
+		cl->smb2.out._pad         = 0;
+		cl->smb2.out.create_time  = cl2->generic.out.create_time;
+		cl->smb2.out.access_time  = cl2->generic.out.access_time;
+		cl->smb2.out.write_time   = cl2->generic.out.write_time;
+		cl->smb2.out.change_time  = cl2->generic.out.change_time;
+		cl->smb2.out.alloc_size   = cl2->generic.out.alloc_size;
+		cl->smb2.out.size         = cl2->generic.out.size;
+		cl->smb2.out.file_attr    = cl2->generic.out.file_attr;
+		break;
+	default:
+		break;
+	}
+
+	return status;
+}
+
+/* 
+   NTVFS close generic to any mapper
+*/
 NTSTATUS ntvfs_map_close(struct ntvfs_module_context *ntvfs,
 				  struct ntvfs_request *req,
 				  union smb_close *cl)
 {
 	union smb_close *cl2;
+	NTSTATUS status;
 
 	cl2 = talloc(req, union smb_close);
 	if (cl2 == NULL) {
@@ -1414,30 +1455,38 @@ NTSTATUS ntvfs_map_close(struct ntvfs_module_context *ntvfs,
 	}
 
 	switch (cl->generic.level) {
-	case RAW_CLOSE_CLOSE:
+	case RAW_CLOSE_GENERIC:
 		return NT_STATUS_INVALID_LEVEL;
 
+	case RAW_CLOSE_CLOSE:
+		cl2->generic.level		= RAW_CLOSE_GENERIC;
+		cl2->generic.in.file		= cl->close.in.file;
+		cl2->generic.in.write_time	= cl->close.in.write_time;
+		cl2->generic.in.flags		= 0;
+		break;
+
 	case RAW_CLOSE_SPLCLOSE:
-		cl2->generic.level		= RAW_CLOSE_CLOSE;
-		cl2->generic.in.file.ntvfs	= cl->splclose.in.file.ntvfs;
+		cl2->generic.level		= RAW_CLOSE_GENERIC;
+		cl2->generic.in.file		= cl->splclose.in.file;
 		cl2->generic.in.write_time	= 0;
+		cl2->generic.in.flags		= 0;
 		break;
 
 	case RAW_CLOSE_SMB2:
-		cl2->generic.level		= RAW_CLOSE_CLOSE;
-		cl2->generic.in.file.ntvfs	= cl->smb2.in.file.ntvfs;
+		cl2->generic.level		= RAW_CLOSE_GENERIC;
+		cl2->generic.in.file		= cl->smb2.in.file;
 		cl2->generic.in.write_time	= 0;
-		/* SMB2 Close has output parameter, but we just zero them */
-		ZERO_STRUCT(cl->smb2.out);
+		cl2->generic.in.flags		= cl->smb2.in.flags;
 		break;
 	}
 
-	/* 
-	 * we don't need to call ntvfs_map_async_setup() here,
-	 * as close() doesn't have any output fields
-	 */
+	status = ntvfs_map_async_setup(ntvfs, req, cl, cl2, 
+				       (second_stage_t)ntvfs_map_close_finish);
+	NT_STATUS_NOT_OK_RETURN(status);
 
-	return ntvfs->ops->close(ntvfs, req, cl2);
+	status = ntvfs->ops->close(ntvfs, req, cl2);
+
+	return ntvfs_map_async_finish(req, status);
 }
 
 /* 
diff --git a/source/ntvfs/posix/pvfs_acl.c b/source/ntvfs/posix/pvfs_acl.c
index f1e469f..507c22f 100644
--- a/source/ntvfs/posix/pvfs_acl.c
+++ b/source/ntvfs/posix/pvfs_acl.c
@@ -457,7 +457,7 @@ NTSTATUS pvfs_access_check_unix(struct pvfs_state *pvfs,
 	}
 
 	if (uid != 0 && (*access_mask & SEC_FLAG_SYSTEM_SECURITY)) {
-		return NT_STATUS_PRIVILEGE_NOT_HELD;
+		return NT_STATUS_ACCESS_DENIED;
 	}
 
 	if (*access_mask & ~max_bits) {
diff --git a/source/ntvfs/posix/pvfs_open.c b/source/ntvfs/posix/pvfs_open.c
index 59b42fe..4971080 100644
--- a/source/ntvfs/posix/pvfs_open.c
+++ b/source/ntvfs/posix/pvfs_open.c
@@ -565,6 +565,10 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
 	if (io->ntcreatex.in.file_attr & ~FILE_ATTRIBUTE_ALL_MASK) {
 		return NT_STATUS_INVALID_PARAMETER;
 	}
+
+	if (io->ntcreatex.in.file_attr & FILE_ATTRIBUTE_ENCRYPTED) {
+		return NT_STATUS_ACCESS_DENIED;
+	}
 	    
 	if ((io->ntcreatex.in.file_attr & FILE_ATTRIBUTE_READONLY) &&
 	    (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) {
@@ -1147,6 +1151,22 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
 		return NT_STATUS_INVALID_PARAMETER;
 	}
 
+	if (access_mask & SEC_MASK_INVALID) {
+		return NT_STATUS_ACCESS_DENIED;
+	}
+
+	/* what does this bit really mean?? */
+	if (req->ctx->protocol == PROTOCOL_SMB2 &&
+	    access_mask == SEC_STD_SYNCHRONIZE) {
+		return NT_STATUS_ACCESS_DENIED;
+	}
+
+	if (io->ntcreatex.in.file_attr & (FILE_ATTRIBUTE_DEVICE|
+					  FILE_ATTRIBUTE_VOLUME| 
+					  (~FILE_ATTRIBUTE_ALL_MASK))) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
 	/* resolve the cifs name to a posix name */
 	status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname, 
 				   PVFS_RESOLVE_STREAMS, &name);
@@ -1494,21 +1514,44 @@ NTSTATUS pvfs_close(struct ntvfs_module_context *ntvfs,
 		return NT_STATUS_DOS(ERRSRV, ERRerror);
 	}
 
-	if (io->generic.level != RAW_CLOSE_CLOSE) {
+	if (io->generic.level != RAW_CLOSE_GENERIC) {
 		return ntvfs_map_close(ntvfs, req, io);
 	}
 
-	f = pvfs_find_fd(pvfs, req, io->close.in.file.ntvfs);
+	f = pvfs_find_fd(pvfs, req, io->generic.in.file.ntvfs);
 	if (!f) {
 		return NT_STATUS_INVALID_HANDLE;
 	}
 
-	if (!null_time(io->close.in.write_time)) {
+	if (!null_time(io->generic.in.write_time)) {
 		unix_times.actime = 0;
 		unix_times.modtime = io->close.in.write_time;
 		utime(f->handle->name->full_name, &unix_times);
 	}
 
+	if (io->generic.in.flags & SMB2_CLOSE_FLAGS_FULL_INFORMATION) {
+		struct pvfs_filename *name;
+		NTSTATUS status;
+		struct pvfs_file_handle *h = f->handle;
+
+		status = pvfs_resolve_name_handle(pvfs, h);
+		if (!NT_STATUS_IS_OK(status)) {
+			return status;
+		}
+		name = h->name;
+
+		io->generic.out.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION;
+		io->generic.out.create_time = name->dos.create_time;
+		io->generic.out.access_time = name->dos.access_time;
+		io->generic.out.write_time  = name->dos.write_time;
+		io->generic.out.change_time = name->dos.change_time;
+		io->generic.out.alloc_size  = name->dos.alloc_size;
+		io->generic.out.size        = name->st.st_size;
+		io->generic.out.file_attr   = name->dos.attrib;		
+	} else {
+		ZERO_STRUCT(io->generic.out);
+	}
+
 	talloc_free(f);
 
 	return NT_STATUS_OK;
diff --git a/source/torture/gentest_smb2.c b/source/torture/gentest_smb2.c
index 4654569..428f325 100644
--- a/source/torture/gentest_smb2.c
+++ b/source/torture/gentest_smb2.c
@@ -55,6 +55,7 @@ static struct gentest_options {
 	int fast_reconnect;
 	int mask_indexing;
 	int no_eas;
+	int skip_cleanup;
 } options;
 
 /* mapping between open handles on the server and local handles */
@@ -112,7 +113,8 @@ static struct smb2_handle bad_smb2_handle;
 
 #define BAD_HANDLE 0xFFFE
 
-static bool oplock_handler(struct smbcli_transport *transport, uint16_t tid, uint16_t fnum, uint8_t level, void *private);
+static bool oplock_handler(struct smb2_transport *transport, const struct smb2_handle *handle,
+			   uint8_t level, void *private_data);
 static void idle_func(struct smb2_transport *transport, void *private);
 
 /*
@@ -208,7 +210,8 @@ static bool connect_servers(struct event_context *ev,
 				return false;
 			}
 
-//			smb2_oplock_handler(servers[i].cli[j]->transport, oplock_handler, NULL);
+			servers[i].tree[j]->session->transport->oplock.handler = oplock_handler;
+			servers[i].tree[j]->session->transport->oplock.private_data = (void *)(uintptr_t)((i<<8)|j);
 			smb2_transport_idle_handler(servers[i].tree[j]->session->transport, idle_func, 50000, NULL);
 		}
 	}
@@ -512,24 +515,37 @@ static uint32_t gen_bits_mask2(uint32_t mask1, uint32_t mask2)
 }
 
 /*
-  generate a boolean
-*/
-static bool gen_bool(void)
+  generate reserved values
+ */
+static uint64_t gen_reserved8(void)
 {
-	return gen_bits_mask2(0x1, 0xFF);


-- 
Samba Shared Repository


More information about the samba-cvs mailing list