[SCM] Samba Shared Repository - branch v4-0-test updated - release-4-0-0alpha3-1802-g8995c2f

Andrew Tridgell tridge at samba.org
Mon May 26 05:04:05 GMT 2008


The branch, v4-0-test has been updated
       via  8995c2f12174ebacc4a6b0864b6583665494a14b (commit)
       via  a7b5689a73adde59de28770aa3949660441291ea (commit)
       via  763c9d344fa55da7a24c250d29542837c3ae3971 (commit)
       via  400a3b39d5c151cf43e307af2fa702208d7cd472 (commit)
       via  8c0d756eb887477da867e069dbde3a7ad98d4ae0 (commit)
      from  6b1576f544e2ea2b5ea0b234b724c4989dd49cca (commit)

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


- Log -----------------------------------------------------------------
commit 8995c2f12174ebacc4a6b0864b6583665494a14b
Author: Andrew Tridgell <tridge at samba.org>
Date:   Mon May 26 15:03:51 2008 +1000

    remove temporary test code

commit a7b5689a73adde59de28770aa3949660441291ea
Author: Andrew Tridgell <tridge at samba.org>
Date:   Mon May 26 15:02:43 2008 +1000

    stricter checks for valid inputs in SMB2 open and lock

commit 763c9d344fa55da7a24c250d29542837c3ae3971
Author: Andrew Tridgell <tridge at samba.org>
Date:   Mon May 26 15:00:56 2008 +1000

    check use of mincnt past EOF in SMB

commit 400a3b39d5c151cf43e307af2fa702208d7cd472
Author: Andrew Tridgell <tridge at samba.org>
Date:   Mon May 26 15:00:27 2008 +1000

    fill in reserved field on SMB2 flush

commit 8c0d756eb887477da867e069dbde3a7ad98d4ae0
Author: Andrew Tridgell <tridge at samba.org>
Date:   Mon May 26 14:59:58 2008 +1000

    allow larger streams using the TDB backend

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

Summary of changes:
 source/libcli/raw/interfaces.h    |    1 +
 source/libcli/raw/smb.h           |    9 ++++++-
 source/librpc/idl/xattr.idl       |    3 +-
 source/ntvfs/ntvfs_generic.c      |   18 +++++++++++++++-
 source/ntvfs/posix/pvfs_flush.c   |    1 +
 source/ntvfs/posix/pvfs_open.c    |   38 ++++++++++++++++++++++++++----------
 source/ntvfs/posix/pvfs_streams.c |   13 ++++++++---
 source/smb_server/smb/reply.c     |    5 ++++
 source/torture/gentest_smb2.c     |    2 +-
 source/torture/raw/read.c         |   17 ++++++++++++++++
 10 files changed, 86 insertions(+), 21 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/libcli/raw/interfaces.h b/source/libcli/raw/interfaces.h
index bae0e67..36d8c3a 100644
--- a/source/libcli/raw/interfaces.h
+++ b/source/libcli/raw/interfaces.h
@@ -1919,6 +1919,7 @@ union smb_lock {
 #define SMB2_LOCK_FLAG_EXCLUSIVE	0x00000002
 #define SMB2_LOCK_FLAG_UNLOCK		0x00000004
 #define SMB2_LOCK_FLAG_FAIL_IMMEDIATELY	0x00000010
+#define SMB2_LOCK_FLAG_ALL_MASK		0x00000017
 				uint32_t flags;
 				uint32_t reserved;
 			} *locks;
diff --git a/source/libcli/raw/smb.h b/source/libcli/raw/smb.h
index 74869e8..5a92b99 100644
--- a/source/libcli/raw/smb.h
+++ b/source/libcli/raw/smb.h
@@ -133,6 +133,7 @@
 #define NTCREATEX_SHARE_ACCESS_READ   1
 #define NTCREATEX_SHARE_ACCESS_WRITE  2
 #define NTCREATEX_SHARE_ACCESS_DELETE 4
+#define NTCREATEX_SHARE_ACCESS_MASK   7
 
 /* ntcreatex open_disposition field */
 #define NTCREATEX_DISP_SUPERSEDE 0     /* supersede existing file (if it exists) */
@@ -154,14 +155,18 @@
 #define NTCREATEX_OPTIONS_RANDOM_ACCESS            0x0800
 #define NTCREATEX_OPTIONS_DELETE_ON_CLOSE          0x1000
 #define NTCREATEX_OPTIONS_OPEN_BY_FILE_ID          0x2000
-#define NTCREATEX_OPTIONS_UNKNOWN_400000           0x400000
-
+#define NTCREATEX_OPTIONS_BACKUP_INTENT            0x4000
+#define NTCREATEX_OPTIONS_REPARSE_POINT          0x200000
+#define NTCREATEX_OPTIONS_UNKNOWN_400000         0x400000
 /* create options these bits are for private use by backends, they are
    not valid on the wire */
 #define NTCREATEX_OPTIONS_PRIVATE_MASK         0xFF000000
 #define NTCREATEX_OPTIONS_PRIVATE_DENY_DOS     0x01000000
 #define NTCREATEX_OPTIONS_PRIVATE_DENY_FCB     0x02000000
 
+#define NTCREATEX_OPTIONS_NOT_SUPPORTED_MASK   0x00DFA188 
+
+
 
 /* ntcreatex impersonation field */
 #define NTCREATEX_IMPERSONATION_ANONYMOUS      0
diff --git a/source/librpc/idl/xattr.idl b/source/librpc/idl/xattr.idl
index 2010d51..520341e 100644
--- a/source/librpc/idl/xattr.idl
+++ b/source/librpc/idl/xattr.idl
@@ -86,7 +86,8 @@ interface xattr
 	/* stream data is stored in attributes with the given prefix */
 	const char *XATTR_DOSSTREAM_PREFIX = "user.DosStream.";
 
-	const int XATTR_MAX_STREAM_SIZE = 0x4000;
+	const int XATTR_MAX_STREAM_SIZE     = 0x4000;
+	const int XATTR_MAX_STREAM_SIZE_TDB = 0x100000;
 
 	typedef struct {
 		uint32     flags;
diff --git a/source/ntvfs/ntvfs_generic.c b/source/ntvfs/ntvfs_generic.c
index 62a1427..9b4f235 100644
--- a/source/ntvfs/ntvfs_generic.c
+++ b/source/ntvfs/ntvfs_generic.c
@@ -522,6 +522,12 @@ NTSTATUS ntvfs_map_open(struct ntvfs_module_context *ntvfs,
 		io2->generic.in.fname		= io->smb2.in.fname;
 		io2->generic.in.sec_desc	= NULL;
 		io2->generic.in.ea_list		= NULL;
+
+		/* 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 = ntvfs->ops->open(ntvfs, req, io2);		
 		break;
 
@@ -1031,6 +1037,9 @@ 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) {
+				return NT_STATUS_INVALID_PARAMETER;
+			}
 			if (lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_UNLOCK) {
 				int j = lck2->generic.in.ulock_cnt;
 				lck2->generic.in.ulock_cnt++;
@@ -1277,10 +1286,15 @@ static NTSTATUS ntvfs_map_read_finish(struct ntvfs_module_context *ntvfs,
 		rd->smb2.out.remaining	= 0;
 		rd->smb2.out.reserved	= 0;
 		if (NT_STATUS_IS_OK(status) &&
-		    rd->smb2.out.data.length == 0 &&
-		    rd->smb2.in.length != 0) {
+		    rd->smb2.out.data.length == 0) {
 			status = NT_STATUS_END_OF_FILE;
 		}
+		/* SMB2 does honor the min_count field, SMB does not */
+		if (NT_STATUS_IS_OK(status) && 
+		    rd->smb2.in.min_count > rd->smb2.out.data.length) {
+			rd->smb2.out.data.length = 0;
+			status = NT_STATUS_END_OF_FILE;			
+		}
 		break;
 	default:
 		return NT_STATUS_INVALID_LEVEL;
diff --git a/source/ntvfs/posix/pvfs_flush.c b/source/ntvfs/posix/pvfs_flush.c
index 61e73ce..6e09c1f 100644
--- a/source/ntvfs/posix/pvfs_flush.c
+++ b/source/ntvfs/posix/pvfs_flush.c
@@ -54,6 +54,7 @@ NTSTATUS pvfs_flush(struct ntvfs_module_context *ntvfs,
 			return NT_STATUS_INVALID_HANDLE;
 		}
 		pvfs_flush_file(pvfs, f);
+		io->smb2.out.reserved = 0;
 		return NT_STATUS_OK;
 
 	case RAW_FLUSH_ALL:
diff --git a/source/ntvfs/posix/pvfs_open.c b/source/ntvfs/posix/pvfs_open.c
index 926c99d..59b42fe 100644
--- a/source/ntvfs/posix/pvfs_open.c
+++ b/source/ntvfs/posix/pvfs_open.c
@@ -203,6 +203,13 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
 		return NT_STATUS_NOT_A_DIRECTORY;
 	}
 
+	/* found with gentest */
+	if (io->ntcreatex.in.access_mask == SEC_FLAG_MAXIMUM_ALLOWED &&
+	    (io->ntcreatex.in.create_options & NTCREATEX_OPTIONS_DIRECTORY) &&
+	    (io->ntcreatex.in.create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+	
 	switch (io->generic.in.open_disposition) {
 	case NTCREATEX_DISP_OPEN_IF:
 		break;
@@ -563,7 +570,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
 	    (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) {
 		return NT_STATUS_CANNOT_DELETE;
 	}
-	
+
 	status = pvfs_access_check_create(pvfs, req, name, &access_mask);
 	NT_STATUS_NOT_OK_RETURN(status);
 
@@ -1121,6 +1128,25 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
 		return ntvfs_map_open(ntvfs, req, io);
 	}
 
+	create_options = io->generic.in.create_options;
+	share_access   = io->generic.in.share_access;
+	access_mask    = io->generic.in.access_mask;
+
+	if (share_access & ~NTCREATEX_SHARE_ACCESS_MASK) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	/* some create options are not supported */
+	if (create_options & NTCREATEX_OPTIONS_NOT_SUPPORTED_MASK) {
+		return NT_STATUS_NOT_SUPPORTED;
+	}
+
+	/* other create options are not allowed */
+	if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) &&
+	    !(access_mask & SEC_STD_DELETE)) {
+		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);
@@ -1152,16 +1178,6 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
 	   open doesn't match */
 	io->generic.in.file_attr &= ~FILE_ATTRIBUTE_DIRECTORY;
 
-	create_options = io->generic.in.create_options;
-	share_access   = io->generic.in.share_access;
-	access_mask    = io->generic.in.access_mask;
-
-	/* certain create options are not allowed */
-	if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) &&
-	    !(access_mask & SEC_STD_DELETE)) {
-		return NT_STATUS_INVALID_PARAMETER;
-	}
-
 	flags = 0;
 
 	switch (io->generic.in.open_disposition) {
diff --git a/source/ntvfs/posix/pvfs_streams.c b/source/ntvfs/posix/pvfs_streams.c
index 3cd9952..30d7ce2 100644
--- a/source/ntvfs/posix/pvfs_streams.c
+++ b/source/ntvfs/posix/pvfs_streams.c
@@ -276,9 +276,12 @@ ssize_t pvfs_stream_write(struct pvfs_state *pvfs,
 	if (count == 0) {
 		return 0;
 	}
-	if (offset > XATTR_MAX_STREAM_SIZE) {
-		errno = ENOSPC;
-		return -1;
+
+	if (count+offset > XATTR_MAX_STREAM_SIZE) {
+		if (!pvfs->ea_db || count+offset > XATTR_MAX_STREAM_SIZE_TDB) {
+			errno = ENOSPC;
+			return -1;
+		}
 	}
 
 	/* we have to load the existing stream, then modify, then save */
@@ -332,7 +335,9 @@ NTSTATUS pvfs_stream_truncate(struct pvfs_state *pvfs,
 	DATA_BLOB blob;
 
 	if (length > XATTR_MAX_STREAM_SIZE) {
-		return NT_STATUS_DISK_FULL;
+		if (!pvfs->ea_db || length > XATTR_MAX_STREAM_SIZE_TDB) {
+			return NT_STATUS_DISK_FULL;
+		}
 	}
 
 	/* we have to load the existing stream, then modify, then save */
diff --git a/source/smb_server/smb/reply.c b/source/smb_server/smb/reply.c
index 40cad91..d28f4b6 100644
--- a/source/smb_server/smb/reply.c
+++ b/source/smb_server/smb/reply.c
@@ -2193,6 +2193,11 @@ void smbsrv_reply_ntcreate_and_X(struct smbsrv_request *req)
 	io->ntcreatex.in.ea_list          = NULL;
 	io->ntcreatex.in.sec_desc         = NULL;
 
+	/* we use a couple of bits of the create options internally */
+	if (io->ntcreatex.in.create_options & NTCREATEX_OPTIONS_PRIVATE_MASK) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
 	/* we need a neater way to handle this alignment */
 	if ((req->flags2 & FLAGS2_UNICODE_STRINGS) && 
 	    ucs2_align(req->in.buffer, req->in.data, STR_TERMINATE|STR_UNICODE)) {
diff --git a/source/torture/gentest_smb2.c b/source/torture/gentest_smb2.c
index 6546ba6..4654569 100644
--- a/source/torture/gentest_smb2.c
+++ b/source/torture/gentest_smb2.c
@@ -1026,7 +1026,7 @@ static bool handler_create(int instance)
 		/* mask out oplocks */
 		parm[0].in.oplock_level = 0;
 	}
-	
+
 	GEN_COPY_PARM;
 	GEN_CALL(smb2_create(tree, current_op.mem_ctx, &parm[i]));
 
diff --git a/source/torture/raw/read.c b/source/torture/raw/read.c
index c8420c2..ada9b1f 100644
--- a/source/torture/raw/read.c
+++ b/source/torture/raw/read.c
@@ -460,6 +460,23 @@ static bool test_readx(struct torture_context *tctx, struct smbcli_state *cli)
 		CHECK_VALUE(io.readx.out.compaction_mode, 0);
 	}
 
+	printf("Trying mincnt past EOF\n");
+	memset(buf, 0, maxsize);
+	io.readx.in.offset = 0;
+	io.readx.in.mincnt = 100;
+	io.readx.in.maxcnt = 110;
+	status = smb_raw_read(cli->tree, &io);
+	CHECK_STATUS(status, NT_STATUS_OK);
+	CHECK_VALUE(io.readx.out.remaining, 0xFFFF);
+	CHECK_VALUE(io.readx.out.compaction_mode, 0);
+	CHECK_VALUE(io.readx.out.nread, strlen(test_data));
+	if (memcmp(buf, test_data, strlen(test_data)) != 0) {
+		ret = false;
+		printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf);
+		goto done;
+	}
+
+
 	setup_buffer(buf, seed, maxsize);
 	smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize);
 	memset(buf, 0, maxsize);


-- 
Samba Shared Repository


More information about the samba-cvs mailing list