[SCM] Samba Shared Repository - branch master updated - 0cf717512659469a9b293685ba2a6db4742dcff7

Andrew Tridgell tridge at samba.org
Thu Sep 25 03:24:33 GMT 2008


The branch, master has been updated
       via  0cf717512659469a9b293685ba2a6db4742dcff7 (commit)
       via  bda97661ffd230a9b58527faebdc79f37bb8352b (commit)
       via  d2bdb8fb1685d7ab2f23a4c4169bcc2e5c97f675 (commit)
       via  eb5b3f50d17dfca198304d636033ad93410d570f (commit)
       via  5a5e2df5694c5dc1be2692e8547370bcdfc58ad0 (commit)
       via  742a99e046313760a281da67eb3ba6e7fcfa8fa6 (commit)
       via  63685c7d02f2364344fd8d4a3307ee36716e4a66 (commit)
       via  59847fd6b6c208377f8b1bcb32347d7c4ab16911 (commit)
       via  49c80cea0bc00a88336fc9bd4bb332a7a399afd5 (commit)
       via  a3536c4c06d9725b2e96b9a3ddc1ab14e47f472c (commit)
       via  7e57626d1d5a4497ecf5b4c741b8486e7ab97733 (commit)
       via  d3c6c71ff2d5499be152785a49ad128641330b40 (commit)
       via  4904882fed1e3b72ba45052323c95c0fda301d64 (commit)
       via  b1f17b23fe58acba924ce11bb8ec700cd2a1bd7e (commit)
       via  9cf3d82d6366e11d1ffee89d405083b7a577c6d6 (commit)
       via  38e70dc47aae6b3bd7ddbcda61e0989f8d659f2b (commit)
       via  9a50009430e2da70d3753c36d66e4168c27029d9 (commit)
       via  76835f103ec65bb00ff3ca11015176ea2f5ecb06 (commit)
       via  094afe614b6282eae47c31ee6ad015a4b0ed80ba (commit)
       via  9fcafbb42cbe759711db4a47c2969bd34229e4a0 (commit)
       via  71ae732669d641cf8b3fd7f6fa73ead4634178f1 (commit)
       via  ff542275c3e2bf432bcc303e95124374ada03675 (commit)
      from  a78ac8a46be3e7c1cf3004b85aa1ec4d0330e5d2 (commit)

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


- Log -----------------------------------------------------------------
commit 0cf717512659469a9b293685ba2a6db4742dcff7
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Sep 24 18:58:38 2008 -0700

    we need different error handling for truncated packets in NETPROT and
    other SMB2 operations.

commit bda97661ffd230a9b58527faebdc79f37bb8352b
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Sep 24 18:28:58 2008 -0700

    fixed expansion of $USERNAME in signing tests

commit d2bdb8fb1685d7ab2f23a4c4169bcc2e5c97f675
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Sep 24 17:58:15 2008 -0700

    empty access mask is only denied on SMB2

commit eb5b3f50d17dfca198304d636033ad93410d570f
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Sep 24 17:45:48 2008 -0700

    we should terminate the connection on a bad negprot packet size

commit 5a5e2df5694c5dc1be2692e8547370bcdfc58ad0
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Sep 24 17:41:36 2008 -0700

    for use in python we need to use global_loadparm

commit 742a99e046313760a281da67eb3ba6e7fcfa8fa6
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Sep 24 17:36:24 2008 -0700

    - add reserved field in basic_information level
    
    - use INVALID_PARAMETER for info length mismatch to match windows
      behaviour
    
    - added parsing of LINK_INFORMATION level

commit 63685c7d02f2364344fd8d4a3307ee36716e4a66
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Sep 24 17:34:58 2008 -0700

    record highest seq number in SMB2 to check for seqnum going backwards

commit 59847fd6b6c208377f8b1bcb32347d7c4ab16911
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Sep 24 17:34:35 2008 -0700

    log stream termination

commit 49c80cea0bc00a88336fc9bd4bb332a7a399afd5
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Sep 24 17:34:04 2008 -0700

    cope with body_size zero in SMB2 receive

commit a3536c4c06d9725b2e96b9a3ddc1ab14e47f472c
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Sep 24 17:33:15 2008 -0700

    check for a 0 byte in the buffer in SMB2 read

commit 7e57626d1d5a4497ecf5b4c741b8486e7ab97733
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Sep 24 17:32:47 2008 -0700

    the offset is 16 bits in SMB2 fileinfo

commit d3c6c71ff2d5499be152785a49ad128641330b40
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Sep 24 17:31:57 2008 -0700

    zero access mask should give ACCESS_DENIED

commit 4904882fed1e3b72ba45052323c95c0fda301d64
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Sep 24 17:28:58 2008 -0700

    - SMB2 uses INVALID_PARAMETER not BUFFER_TOO_SMALL for buffer size
    errors
    
    - added a s32o16 buffer function

commit b1f17b23fe58acba924ce11bb8ec700cd2a1bd7e
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Sep 24 17:26:42 2008 -0700

    - use the current dialect first, for servers that only look at the
    first dialect
    
    - allow override of SMB2 port in client code

commit 9cf3d82d6366e11d1ffee89d405083b7a577c6d6
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Sep 24 17:20:28 2008 -0700

    added the structure for LINK_INFORMATION setfileinfo call

commit 38e70dc47aae6b3bd7ddbcda61e0989f8d659f2b
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Sep 24 17:19:36 2008 -0700

    be friendlier in smb2_deltree to some of the SMB2 implementations that
    don't handle SEC_FLAG_MAXIMUM_ALLOWED

commit 9a50009430e2da70d3753c36d66e4168c27029d9
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Sep 24 17:18:29 2008 -0700

    check error code for zero desired_access in SMB2 create

commit 76835f103ec65bb00ff3ca11015176ea2f5ecb06
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Sep 24 17:17:41 2008 -0700

    fixed setpathinfo in gentest to not zero the filename/handle

commit 094afe614b6282eae47c31ee6ad015a4b0ed80ba
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Sep 24 15:40:55 2008 -0700

    fixed uninitialised variable bug

commit 9fcafbb42cbe759711db4a47c2969bd34229e4a0
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Sep 24 11:28:58 2008 -0700

    support NT_STATUS_XX:NT_STATUS_YY syntax in ignore files

commit 71ae732669d641cf8b3fd7f6fa73ead4634178f1
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Sep 24 08:58:16 2008 -0700

    fixed error code for bad keepalive

commit ff542275c3e2bf432bcc303e95124374ada03675
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Sep 23 20:01:06 2008 -0700

    stricter checking of SMB2 echo body (per the spec)
    
    thanks to the bluearc test suite

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

Summary of changes:
 source4/libcli/clideltree.c           |    1 +
 source4/libcli/raw/interfaces.h       |   13 ++++++++
 source4/libcli/smb2/connect.c         |   13 ++++++--
 source4/libcli/smb2/request.c         |   54 +++++++++++++++++++++++---------
 source4/libcli/smb2/smb2.h            |    1 +
 source4/libcli/smb2/util.c            |    2 +-
 source4/ntvfs/posix/pvfs_acl.c        |    6 ++++
 source4/selftest/samba4_tests.sh      |    2 +-
 source4/smb_server/blob.c             |   28 +++++++++++++++--
 source4/smb_server/smb2/fileinfo.c    |    2 +-
 source4/smb_server/smb2/fileio.c      |    6 ++++
 source4/smb_server/smb2/keepalive.c   |    9 ++++-
 source4/smb_server/smb2/negprot.c     |    4 +-
 source4/smb_server/smb2/receive.c     |   41 +++++++++++++++++++++++-
 source4/smb_server/smb2/smb2_server.h |    3 +-
 source4/smb_server/smb_server.h       |    2 +
 source4/smbd/service_stream.c         |    2 +
 source4/torture/gentest.c             |   21 ++++++++++---
 source4/torture/smb2/create.c         |    7 ++++
 19 files changed, 181 insertions(+), 36 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/libcli/clideltree.c b/source4/libcli/clideltree.c
index d59a03f..28563d9 100644
--- a/source4/libcli/clideltree.c
+++ b/source4/libcli/clideltree.c
@@ -91,6 +91,7 @@ int smbcli_deltree(struct smbcli_tree *tree, const char *dname)
 	dstate.failed = false;
 
 	/* it might be a file */
+	status = smbcli_unlink(tree, dname);
 	if (NT_STATUS_IS_OK(smbcli_unlink(tree, dname))) {
 		return 1;
 	}
diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h
index 20ed441..c2269cb 100644
--- a/source4/libcli/raw/interfaces.h
+++ b/source4/libcli/raw/interfaces.h
@@ -904,6 +904,7 @@ enum smb_setfileinfo_level {
 	RAW_SFILEINFO_UNIX_HLINK	      = SMB_SFILEINFO_UNIX_HLINK,
 	RAW_SFILEINFO_BASIC_INFORMATION       = SMB_SFILEINFO_BASIC_INFORMATION,
 	RAW_SFILEINFO_RENAME_INFORMATION      = SMB_SFILEINFO_RENAME_INFORMATION,
+	RAW_SFILEINFO_LINK_INFORMATION        = SMB_SFILEINFO_LINK_INFORMATION,
 	RAW_SFILEINFO_DISPOSITION_INFORMATION = SMB_SFILEINFO_DISPOSITION_INFORMATION,
 	RAW_SFILEINFO_POSITION_INFORMATION    = SMB_SFILEINFO_POSITION_INFORMATION,
 	RAW_SFILEINFO_FULL_EA_INFORMATION     = SMB_SFILEINFO_FULL_EA_INFORMATION,
@@ -984,6 +985,7 @@ union smb_setfileinfo {
 			NTTIME write_time;
 			NTTIME change_time;
 			uint32_t attrib;
+			uint32_t reserved;
 		} in;
 	} basic_info;
 
@@ -1029,6 +1031,17 @@ union smb_setfileinfo {
 		} in;
 	} rename_information;
 
+	/* RAW_SFILEINFO_LINK_INFORMATION interface */
+	struct {
+		enum smb_setfileinfo_level level;
+		struct {
+			union smb_handle_or_path file;
+			uint8_t overwrite;
+			uint64_t root_fid;
+			const char *new_name;
+		} in;
+	} link_information;
+
 	/* RAW_SFILEINFO_POSITION_INFORMATION interface */
 	struct {
 		enum smb_setfileinfo_level level;
diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c
index 4315194..db2f97b 100644
--- a/source4/libcli/smb2/connect.c
+++ b/source4/libcli/smb2/connect.c
@@ -27,6 +27,7 @@
 #include "libcli/composite/composite.h"
 #include "libcli/resolve/resolve.h"
 #include "param/param.h"
+#include "lib/cmdline/popt_common.h"
 
 struct smb2_connect_state {
 	struct cli_credentials *credentials;
@@ -184,8 +185,8 @@ static void continue_socket(struct composite_context *creq)
 	}
 	state->negprot.in.capabilities  = 0;
 	unix_to_nt_time(&state->negprot.in.start_time, time(NULL));
-	dialects[0] = 0;
-	dialects[1] = SMB2_DIALECT_REVISION;
+	dialects[0] = SMB2_DIALECT_REVISION;
+	dialects[1] = 0;
 	state->negprot.in.dialects = dialects;
 
 	req = smb2_negprot_send(transport, &state->negprot);
@@ -206,7 +207,13 @@ static void continue_resolve(struct composite_context *creq)
 	struct smb2_connect_state *state = talloc_get_type(c->private_data, 
 							   struct smb2_connect_state);
 	const char *addr;
-	const char *ports[2] = { "445", NULL };
+	const char **ports;
+	const char *default_ports[] = { "445", NULL };
+
+	ports = lp_parm_string_list(state, global_loadparm, NULL, "smb2", "ports", NULL);
+	if (ports == NULL) {
+		ports = default_ports;
+	}
 
 	c->status = resolve_name_recv(creq, state, &addr);
 	if (!composite_is_ok(c)) return;
diff --git a/source4/libcli/smb2/request.c b/source4/libcli/smb2/request.c
index 64d427f..137e2f2 100644
--- a/source4/libcli/smb2/request.c
+++ b/source4/libcli/smb2/request.c
@@ -279,7 +279,7 @@ NTSTATUS smb2_pull_o16s16_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_
 {
 	uint16_t ofs, size;
 	if (smb2_oob(buf, ptr, 4)) {
-		return NT_STATUS_BUFFER_TOO_SMALL;
+		return NT_STATUS_INVALID_PARAMETER;
 	}
 	ofs  = SVAL(ptr, 0);
 	size = SVAL(ptr, 2);
@@ -288,7 +288,7 @@ NTSTATUS smb2_pull_o16s16_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_
 		return NT_STATUS_OK;
 	}
 	if (smb2_oob(buf, buf->hdr + ofs, size)) {
-		return NT_STATUS_BUFFER_TOO_SMALL;
+		return NT_STATUS_INVALID_PARAMETER;
 	}
 	*blob = data_blob_talloc(mem_ctx, buf->hdr + ofs, size);
 	NT_STATUS_HAVE_NO_MEMORY(blob->data);
@@ -315,12 +315,12 @@ NTSTATUS smb2_push_o16s16_blob(struct smb2_request_buffer *buf,
 
 	/* we have only 16 bit for the size */
 	if (blob.length > 0xFFFF) {
-		return NT_STATUS_BUFFER_TOO_SMALL;
+		return NT_STATUS_INVALID_PARAMETER;
 	}
 
 	/* check if there're enough room for ofs and size */
 	if (smb2_oob(buf, ptr, 4)) {
-		return NT_STATUS_BUFFER_TOO_SMALL;
+		return NT_STATUS_INVALID_PARAMETER;
 	}
 
 	if (blob.data == NULL) {
@@ -376,7 +376,7 @@ NTSTATUS smb2_push_o16s32_blob(struct smb2_request_buffer *buf,
 
 	/* check if there're enough room for ofs and size */
 	if (smb2_oob(buf, ptr, 6)) {
-		return NT_STATUS_BUFFER_TOO_SMALL;
+		return NT_STATUS_INVALID_PARAMETER;
 	}
 
 	if (blob.data == NULL) {
@@ -432,7 +432,7 @@ NTSTATUS smb2_push_o32s32_blob(struct smb2_request_buffer *buf,
 
 	/* check if there're enough room for ofs and size */
 	if (smb2_oob(buf, ptr, 8)) {
-		return NT_STATUS_BUFFER_TOO_SMALL;
+		return NT_STATUS_INVALID_PARAMETER;
 	}
 
 	if (blob.data == NULL) {
@@ -488,7 +488,7 @@ NTSTATUS smb2_push_s32o32_blob(struct smb2_request_buffer *buf,
 
 	/* check if there're enough room for ofs and size */
 	if (smb2_oob(buf, ptr, 8)) {
-		return NT_STATUS_BUFFER_TOO_SMALL;
+		return NT_STATUS_INVALID_PARAMETER;
 	}
 
 	if (blob.data == NULL) {
@@ -533,7 +533,7 @@ NTSTATUS smb2_pull_o16s32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_
 	uint32_t size;
 
 	if (smb2_oob(buf, ptr, 6)) {
-		return NT_STATUS_BUFFER_TOO_SMALL;
+		return NT_STATUS_INVALID_PARAMETER;
 	}
 	ofs  = SVAL(ptr, 0);
 	size = IVAL(ptr, 2);
@@ -542,7 +542,7 @@ NTSTATUS smb2_pull_o16s32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_
 		return NT_STATUS_OK;
 	}
 	if (smb2_oob(buf, buf->hdr + ofs, size)) {
-		return NT_STATUS_BUFFER_TOO_SMALL;
+		return NT_STATUS_INVALID_PARAMETER;
 	}
 	*blob = data_blob_talloc(mem_ctx, buf->hdr + ofs, size);
 	NT_STATUS_HAVE_NO_MEMORY(blob->data);
@@ -557,7 +557,7 @@ NTSTATUS smb2_pull_o32s32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_
 {
 	uint32_t ofs, size;
 	if (smb2_oob(buf, ptr, 8)) {
-		return NT_STATUS_BUFFER_TOO_SMALL;
+		return NT_STATUS_INVALID_PARAMETER;
 	}
 	ofs  = IVAL(ptr, 0);
 	size = IVAL(ptr, 4);
@@ -566,7 +566,7 @@ NTSTATUS smb2_pull_o32s32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_
 		return NT_STATUS_OK;
 	}
 	if (smb2_oob(buf, buf->hdr + ofs, size)) {
-		return NT_STATUS_BUFFER_TOO_SMALL;
+		return NT_STATUS_INVALID_PARAMETER;
 	}
 	*blob = data_blob_talloc(mem_ctx, buf->hdr + ofs, size);
 	NT_STATUS_HAVE_NO_MEMORY(blob->data);
@@ -584,7 +584,7 @@ NTSTATUS smb2_pull_o16As32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem
 {
 	uint32_t ofs, size;
 	if (smb2_oob(buf, ptr, 8)) {
-		return NT_STATUS_BUFFER_TOO_SMALL;
+		return NT_STATUS_INVALID_PARAMETER;
 	}
 	ofs  = SVAL(ptr, 0);
 	size = IVAL(ptr, 4);
@@ -593,7 +593,7 @@ NTSTATUS smb2_pull_o16As32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem
 		return NT_STATUS_OK;
 	}
 	if (smb2_oob(buf, buf->hdr + ofs, size)) {
-		return NT_STATUS_BUFFER_TOO_SMALL;
+		return NT_STATUS_INVALID_PARAMETER;
 	}
 	*blob = data_blob_talloc(mem_ctx, buf->hdr + ofs, size);
 	NT_STATUS_HAVE_NO_MEMORY(blob->data);
@@ -608,7 +608,7 @@ NTSTATUS smb2_pull_s32o32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_
 {
 	uint32_t ofs, size;
 	if (smb2_oob(buf, ptr, 8)) {
-		return NT_STATUS_BUFFER_TOO_SMALL;
+		return NT_STATUS_INVALID_PARAMETER;
 	}
 	size = IVAL(ptr, 0);
 	ofs  = IVAL(ptr, 4);
@@ -617,7 +617,31 @@ NTSTATUS smb2_pull_s32o32_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_
 		return NT_STATUS_OK;
 	}
 	if (smb2_oob(buf, buf->hdr + ofs, size)) {
-		return NT_STATUS_BUFFER_TOO_SMALL;
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+	*blob = data_blob_talloc(mem_ctx, buf->hdr + ofs, size);
+	NT_STATUS_HAVE_NO_MEMORY(blob->data);
+	return NT_STATUS_OK;
+}
+
+/*
+  pull a uint32_t length/ uint16_t ofs/blob triple from a data blob
+  the ptr points to the start of the offset/length pair
+*/
+NTSTATUS smb2_pull_s32o16_blob(struct smb2_request_buffer *buf, TALLOC_CTX *mem_ctx, uint8_t *ptr, DATA_BLOB *blob)
+{
+	uint32_t ofs, size;
+	if (smb2_oob(buf, ptr, 8)) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+	size = IVAL(ptr, 0);
+	ofs  = SVAL(ptr, 4);
+	if (ofs == 0) {
+		*blob = data_blob(NULL, 0);
+		return NT_STATUS_OK;
+	}
+	if (smb2_oob(buf, buf->hdr + ofs, size)) {
+		return NT_STATUS_INVALID_PARAMETER;
 	}
 	*blob = data_blob_talloc(mem_ctx, buf->hdr + ofs, size);
 	NT_STATUS_HAVE_NO_MEMORY(blob->data);
diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h
index f00107d..9d63a4a 100644
--- a/source4/libcli/smb2/smb2.h
+++ b/source4/libcli/smb2/smb2.h
@@ -178,6 +178,7 @@ struct smb2_request {
 
 
 #define SMB2_MIN_SIZE 0x42
+#define SMB2_MIN_SIZE_NO_BODY 0x40
 
 /* offsets into header elements for a sync SMB2 request */
 #define SMB2_HDR_PROTOCOL_ID    0x00
diff --git a/source4/libcli/smb2/util.c b/source4/libcli/smb2/util.c
index b149b3d..a360d8f 100644
--- a/source4/libcli/smb2/util.c
+++ b/source4/libcli/smb2/util.c
@@ -138,7 +138,7 @@ int smb2_deltree(struct smb2_tree *tree, const char *dname)
 	}
 
 	ZERO_STRUCT(create_parm);
-	create_parm.in.desired_access = SEC_FLAG_MAXIMUM_ALLOWED;
+	create_parm.in.desired_access = SEC_FILE_READ_DATA;
 	create_parm.in.share_access = 
 		NTCREATEX_SHARE_ACCESS_READ|
 		NTCREATEX_SHARE_ACCESS_WRITE;
diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c
index 57a463a..d479f1e 100644
--- a/source4/ntvfs/posix/pvfs_acl.c
+++ b/source4/ntvfs/posix/pvfs_acl.c
@@ -511,6 +511,12 @@ NTSTATUS pvfs_access_check(struct pvfs_state *pvfs,
 	NTSTATUS status;
 	struct security_descriptor *sd;
 
+	/* on SMB2 a blank access mask is always denied */
+	if (pvfs->ntvfs->ctx->protocol == PROTOCOL_SMB2 &&
+	    *access_mask == 0) {
+		return NT_STATUS_ACCESS_DENIED;
+	}
+
 	if (pvfs_read_only(pvfs, *access_mask)) {
 		return NT_STATUS_ACCESS_DENIED;
 	}
diff --git a/source4/selftest/samba4_tests.sh b/source4/selftest/samba4_tests.sh
index 36d52ff..667b219 100755
--- a/source4/selftest/samba4_tests.sh
+++ b/source4/selftest/samba4_tests.sh
@@ -326,7 +326,7 @@ for mech in \
 	"-k no --option=gensec:spengo=no"; do
 	signoptions="$mech --signing=off"
 	name="smb.signing on with $signoptions"
-	plantest "$name local-creds" member $VALGRIND $smb4torture //"\$NETBIOSNAME"/tmp $signoptions -U"\$NETBIOSNAME\\\\\$USERNAME"%"\$PASSWORD" BASE-XCOPY "$*"
+	plantest "$name local-creds" member $VALGRIND $smb4torture //"\$NETBIOSNAME"/tmp $signoptions -U"\$NETBIOSNAME/\$USERNAME"%"\$PASSWORD" BASE-XCOPY "$*"
 done
 plantest "--signing=yes anon" dc $VALGRIND $smb4torture //"\$NETBIOSNAME"/tmp -k no --signing=yes -U% BASE-XCOPY "$*"
 plantest "--signing=required anon" dc $VALGRIND $smb4torture //"\$NETBIOSNAME"/tmp -k no --signing=required -U% BASE-XCOPY "$*"
diff --git a/source4/smb_server/blob.c b/source4/smb_server/blob.c
index 368b81d..4f018a5 100644
--- a/source4/smb_server/blob.c
+++ b/source4/smb_server/blob.c
@@ -35,7 +35,7 @@
 
 #define BLOB_CHECK_MIN_SIZE(blob, size) do { \
 	if ((blob)->length < (size)) { \
-		return NT_STATUS_INFO_LENGTH_MISMATCH; \
+		return NT_STATUS_INVALID_PARAMETER; \
 	} \
 } while (0)
 
@@ -530,13 +530,14 @@ NTSTATUS smbsrv_pull_passthru_sfileinfo(TALLOC_CTX *mem_ctx,
 
 	switch (level) {
 	case SMB_SFILEINFO_BASIC_INFORMATION:
-		BLOB_CHECK_MIN_SIZE(blob, 36);
+		BLOB_CHECK_MIN_SIZE(blob, 40);
 
 		st->basic_info.in.create_time = pull_nttime(blob->data,  0);
 		st->basic_info.in.access_time = pull_nttime(blob->data,  8);
 		st->basic_info.in.write_time =  pull_nttime(blob->data, 16);
 		st->basic_info.in.change_time = pull_nttime(blob->data, 24);
-		st->basic_info.in.attrib =      IVAL(blob->data,        32);
+		st->basic_info.in.attrib      = IVAL(blob->data,        32);
+		st->basic_info.in.reserved    = IVAL(blob->data,        36);
 
 		return NT_STATUS_OK;
 
@@ -581,6 +582,27 @@ NTSTATUS smbsrv_pull_passthru_sfileinfo(TALLOC_CTX *mem_ctx,
 
 		return NT_STATUS_OK;
 
+
+	case RAW_SFILEINFO_LINK_INFORMATION:
+		if (!bufinfo) {
+			return NT_STATUS_INTERNAL_ERROR;
+		}
+		BLOB_CHECK_MIN_SIZE(blob, 20);
+		st->link_information.in.overwrite = CVAL(blob->data, 0);
+		st->link_information.in.root_fid  = IVAL(blob->data, 8);
+		len                                 = IVAL(blob->data, 16);
+		ofs                                 = 20;
+		str_blob = *blob;
+		str_blob.length = MIN(str_blob.length, ofs+len);
+		smbsrv_blob_pull_string(bufinfo, &str_blob, ofs,
+					&st->link_information.in.new_name,
+					STR_UNICODE);
+		if (st->link_information.in.new_name == NULL) {
+			return NT_STATUS_FOOBAR;
+		}
+
+		return NT_STATUS_OK;
+
 	case RAW_SFILEINFO_RENAME_INFORMATION_SMB2:
 		/* SMB2 uses a different format for rename information */
 		if (!bufinfo) {
diff --git a/source4/smb_server/smb2/fileinfo.c b/source4/smb_server/smb2/fileinfo.c
index 6c4b8f3..82b006c 100644
--- a/source4/smb_server/smb2/fileinfo.c
+++ b/source4/smb_server/smb2/fileinfo.c
@@ -369,7 +369,7 @@ void smb2srv_setinfo_recv(struct smb2srv_request *req)
 	SMB2SRV_SETUP_NTVFS_REQUEST(smb2srv_setinfo_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
 	info->in.level			= SVAL(req->in.body, 0x02);
-	SMB2SRV_CHECK(smb2_pull_s32o32_blob(&req->in, info, req->in.body+0x04, &info->in.blob));
+	SMB2SRV_CHECK(smb2_pull_s32o16_blob(&req->in, info, req->in.body+0x04, &info->in.blob));
 	info->in.flags			= IVAL(req->in.body, 0x0C);
 	info->in.file.ntvfs		= smb2srv_pull_handle(req, req->in.body, 0x10);
 
diff --git a/source4/smb_server/smb2/fileio.c b/source4/smb_server/smb2/fileio.c
index 2c322ea..4f4402b 100644
--- a/source4/smb_server/smb2/fileio.c
+++ b/source4/smb_server/smb2/fileio.c
@@ -254,6 +254,12 @@ void smb2srv_read_recv(struct smb2srv_request *req)
 	union smb_read *io;
 
 	SMB2SRV_CHECK_BODY_SIZE(req, 0x30, true);
+
+	/* MS-SMB2 2.2.19 read must have a single byte of zero */
+	if (req->in.body_size - req->in.body_fixed < 1) {
+		smb2srv_send_error(req,  NT_STATUS_INVALID_PARAMETER);
+		return;
+	}
 	SMB2SRV_TALLOC_IO_PTR(io, union smb_read);
 	SMB2SRV_SETUP_NTVFS_REQUEST(smb2srv_read_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
diff --git a/source4/smb_server/smb2/keepalive.c b/source4/smb_server/smb2/keepalive.c
index f40bcc4..ff47d59 100644
--- a/source4/smb_server/smb2/keepalive.c
+++ b/source4/smb_server/smb2/keepalive.c
@@ -54,8 +54,13 @@ void smb2srv_keepalive_recv(struct smb2srv_request *req)
 {
 	uint16_t _pad;
 
-	if (req->in.body_size < 0x04) {
-		smb2srv_send_error(req,  NT_STATUS_FOOBAR);
+	if (req->in.body_size != 0x04) {
+		smb2srv_send_error(req,  NT_STATUS_INVALID_PARAMETER);
+		return;
+	}
+
+	if (SVAL(req->in.body, 0x00) != 0x04) {
+		smb2srv_send_error(req,  NT_STATUS_INVALID_PARAMETER);
 		return;
 	}
 
diff --git a/source4/smb_server/smb2/negprot.c b/source4/smb_server/smb2/negprot.c
index d64b36d..49a2d12 100644
--- a/source4/smb_server/smb2/negprot.c
+++ b/source4/smb_server/smb2/negprot.c
@@ -192,7 +192,7 @@ void smb2srv_negprot_recv(struct smb2srv_request *req)
 	enum ndr_err_code ndr_err;
 
 	if (req->in.body_size < 0x26) {
-		smb2srv_send_error(req,  NT_STATUS_FOOBAR);
+		smbsrv_terminate_connection(req->smb_conn, "Bad body size in SMB2 negprot");
 		return;
 	}
 
@@ -209,7 +209,7 @@ void smb2srv_negprot_recv(struct smb2srv_request *req)
 	io->in.capabilities  = IVAL(req->in.body, 0x08);
 	ndr_err = smbcli_pull_guid(req->in.body, 0xC, &io->in.client_guid);
 	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-		smbsrv_terminate_connection(req->smb_conn, nt_errstr(NT_STATUS_FOOBAR));
+		smbsrv_terminate_connection(req->smb_conn, "Bad GUID in SMB2 negprot");
 		talloc_free(req);
 		return;
 	}
diff --git a/source4/smb_server/smb2/receive.c b/source4/smb_server/smb2/receive.c
index 1fe6f0b..c3607f0 100644
--- a/source4/smb_server/smb2/receive.c
+++ b/source4/smb_server/smb2/receive.c
@@ -153,7 +153,7 @@ static void smb2srv_chain_reply(struct smb2srv_request *p_req)
 	chain_offset = p_req->chain_offset;
 	p_req->chain_offset = 0;
 
-	if (p_req->in.size < (NBT_HDR_SIZE + chain_offset + SMB2_MIN_SIZE)) {
+	if (p_req->in.size < (NBT_HDR_SIZE + chain_offset + SMB2_MIN_SIZE_NO_BODY)) {
 		DEBUG(2,("Invalid SMB2 chained packet at offset 0x%X\n",
 			chain_offset));
 		smbsrv_terminate_connection(p_req->smb_conn, "Invalid SMB2 chained packet");
@@ -184,6 +184,19 @@ static void smb2srv_chain_reply(struct smb2srv_request *p_req)
 	req->in.body_size	= req->in.size	- (NBT_HDR_SIZE+ chain_offset + SMB2_HDR_BODY);
 	req->in.dynamic 	= NULL;
 
+	req->seqnum		= BVAL(req->in.hdr, SMB2_HDR_MESSAGE_ID);
+
+	if (req->in.body_size < 2) {
+		/* error handling for this is different for negprot to 
+		   other packet types */
+		uint16_t opcode	= SVAL(req->in.hdr, SMB2_HDR_OPCODE);
+		if (opcode == SMB2_OP_NEGPROT) {
+			smbsrv_terminate_connection(req->smb_conn, "Bad body size in SMB2 negprot");			
+		} else {
+			smb2srv_send_error(req, NT_STATUS_INVALID_PARAMETER);
+		}
+	}
+
 	buffer_code		= SVAL(req->in.body, 0);
 	req->in.body_fixed	= (buffer_code & ~1);
 	dynamic_size		= req->in.body_size - req->in.body_fixed;
@@ -290,6 +303,10 @@ static NTSTATUS smb2srv_reply(struct smb2srv_request *req)
 	uint64_t uid;
 	uint32_t flags;
 
+	if (SVAL(req->in.hdr, SMB2_HDR_LENGTH) != SMB2_HDR_BODY) {
+		smbsrv_terminate_connection(req->smb_conn, "Invalid SMB2 header length");
+		return NT_STATUS_INVALID_PARAMETER;
+	}
 	opcode			= SVAL(req->in.hdr, SMB2_HDR_OPCODE);
 	req->chain_offset	= IVAL(req->in.hdr, SMB2_HDR_NEXT_COMMAND);
 	req->seqnum		= BVAL(req->in.hdr, SMB2_HDR_MESSAGE_ID);
@@ -297,6 +314,13 @@ static NTSTATUS smb2srv_reply(struct smb2srv_request *req)
 	uid			= BVAL(req->in.hdr, SMB2_HDR_SESSION_ID);
 	flags			= IVAL(req->in.hdr, SMB2_HDR_FLAGS);
 
+	if (req->smb_conn->highest_smb2_seqnum != 0 &&
+	    req->seqnum <= req->smb_conn->highest_smb2_seqnum) {
+		smbsrv_terminate_connection(req->smb_conn, "Invalid SMB2 sequence number");
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+	req->smb_conn->highest_smb2_seqnum = req->seqnum;
+	
 	req->session	= smbsrv_session_find(req->smb_conn, uid, req->request_time);
 	req->tcon	= smbsrv_smb2_tcon_find(req->session, tid, req->request_time);
 
@@ -443,7 +467,7 @@ NTSTATUS smbsrv_recv_smb2_request(void *private, DATA_BLOB blob)
 		return NT_STATUS_OK;
 	}
 
-	if (blob.length < (NBT_HDR_SIZE + SMB2_MIN_SIZE)) {
+	if (blob.length < (NBT_HDR_SIZE + SMB2_MIN_SIZE_NO_BODY)) {
 		DEBUG(2,("Invalid SMB2 packet length count %ld\n", (long)blob.length));
 		smbsrv_terminate_connection(smb_conn, "Invalid SMB2 packet");
 		return NT_STATUS_OK;


-- 
Samba Shared Repository


More information about the samba-cvs mailing list