[SCM] Samba Shared Repository - branch v4-0-test updated - release-4-0-0alpha3-1917-g7245e62

Andrew Tridgell tridge at samba.org
Wed May 28 07:00:41 GMT 2008


The branch, v4-0-test has been updated
       via  7245e62f08e2bda96471318cac612b25697bc3e9 (commit)
       via  72902c1d0f85048adf3088b4f90bbc34858b8658 (commit)
       via  b3f638581689946084148b241f9fd7c0b938ade2 (commit)
       via  a6cc89fffe8c149b540f2125cea57f31331d5460 (commit)
       via  a48cbec6b90c6ba9db870fc33eed06b36612d8ff (commit)
       via  9fc70e2ed6a54f6d9a0530f4d37c0f8acadb6778 (commit)
       via  f5985a0490e4105a9b0208f6b7b19e635db324f9 (commit)
       via  597b38e97b01d2137e6ac96ca07cd56fadb2c09e (commit)
      from  a529c377ae7a4a70a99d60b7817a751ab4fdd551 (commit)

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


- Log -----------------------------------------------------------------
commit 7245e62f08e2bda96471318cac612b25697bc3e9
Merge: 72902c1d0f85048adf3088b4f90bbc34858b8658 a529c377ae7a4a70a99d60b7817a751ab4fdd551
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed May 28 17:00:21 2008 +1000

    Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into v4-0-test

commit 72902c1d0f85048adf3088b4f90bbc34858b8658
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed May 28 16:59:12 2008 +1000

    test unknown tags and bad tag lengths

commit b3f638581689946084148b241f9fd7c0b938ade2
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed May 28 16:58:57 2008 +1000

    added some of the new SMB2 create tags to gentest_smb2

commit a6cc89fffe8c149b540f2125cea57f31331d5460
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed May 28 16:58:34 2008 +1000

    ensure we don't change the incoming blobs in a SMB2 create

commit a48cbec6b90c6ba9db870fc33eed06b36612d8ff
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed May 28 16:28:50 2008 +1000

    added testing of SMB2 create blobs

commit 9fc70e2ed6a54f6d9a0530f4d37c0f8acadb6778
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed May 28 16:28:37 2008 +1000

    implement the documented SMB2 create blobs in the server
    
    Not all of them are honoured yet, but they are all parsed and the ones
    that have SMB equivalents are honoured

commit f5985a0490e4105a9b0208f6b7b19e635db324f9
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed May 28 16:27:38 2008 +1000

    expose a function for pushing all SMB2 create blobs

commit 597b38e97b01d2137e6ac96ca07cd56fadb2c09e
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed May 28 15:27:50 2008 +1000

    added support for all of the known SMB2 create tags in our client
    library

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

Summary of changes:
 source/libcli/raw/interfaces.h  |   20 +++-
 source/libcli/smb2/create.c     |  242 ++++++++++++++++++++++++++++++++++++---
 source/ntvfs/ipc/vfs_ipc.c      |    2 +-
 source/ntvfs/ntvfs_generic.c    |   14 ++-
 source/ntvfs/posix/pvfs_open.c  |    3 +
 source/smb_server/smb2/fileio.c |   76 +++++++++++-
 source/torture/gentest_smb2.c   |   18 +++-
 source/torture/smb2/create.c    |  121 +++++++++++++++++++-
 8 files changed, 460 insertions(+), 36 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/libcli/raw/interfaces.h b/source/libcli/raw/interfaces.h
index 17c8513..d170006 100644
--- a/source/libcli/raw/interfaces.h
+++ b/source/libcli/raw/interfaces.h
@@ -1586,9 +1586,17 @@ union smb_open {
 			/* dynamic body */
 			const char *fname;
 
-			/* optional list of extended attributes */
+			/* now some optional parameters - encoded as tagged blobs */
 			struct smb_ea_list eas;
-
+			uint64_t alloc_size;
+			struct security_descriptor *sec_desc;
+			bool   durable_open;
+			struct smb2_handle *durable_handle;
+			bool   query_maximal_access;
+			NTTIME timewarp;
+			bool   query_on_disk_id;
+			
+			/* and any additional blobs the caller wants */
 			struct smb2_create_blobs {
 				uint32_t num_blobs;
 				struct smb2_create_blob {
@@ -1617,8 +1625,12 @@ union smb_open {
 			/* uint32_t blob_ofs; */
 			/* uint32_t blob_size; */
 
-			/* dynamic body */
-			DATA_BLOB blob;
+			/* optional return values matching tagged values in the call */
+			uint32_t maximal_access;
+			uint8_t on_disk_id[32];
+
+			/* tagged blobs in the reply */
+			struct smb2_create_blobs blobs;
 		} out;
 	} smb2;
 };
diff --git a/source/libcli/smb2/create.c b/source/libcli/smb2/create.c
index 1901cb4..bff0a15 100644
--- a/source/libcli/smb2/create.c
+++ b/source/libcli/smb2/create.c
@@ -24,6 +24,75 @@
 #include "libcli/raw/raw_proto.h"
 #include "libcli/smb2/smb2.h"
 #include "libcli/smb2/smb2_calls.h"
+#include "librpc/gen_ndr/ndr_security.h"
+
+
+/*
+  parse a set of SMB2 create blobs
+*/
+NTSTATUS smb2_create_blob_parse(TALLOC_CTX *mem_ctx, const DATA_BLOB buffer,
+				struct smb2_create_blobs *blobs)
+{
+	const uint8_t *data = buffer.data;
+	uint32_t remaining = buffer.length;
+
+	while (remaining > 0) {
+		uint32_t next;
+		uint32_t name_offset, name_length;
+		uint32_t reserved, data_offset;
+		uint32_t data_length;
+		char *tag;
+		DATA_BLOB b;
+		NTSTATUS status;
+
+		if (remaining < 16) {
+			return NT_STATUS_INVALID_PARAMETER;
+		}
+		next        = IVAL(data, 0);
+		name_offset = SVAL(data, 4);
+		name_length = SVAL(data, 6);
+		reserved    = SVAL(data, 8);
+		data_offset = SVAL(data, 10);
+		data_length = IVAL(data, 12);
+
+		if ((next & 0x7) != 0 ||
+		    next > remaining ||
+		    name_offset < 16 ||
+		    name_offset > remaining ||
+		    name_length != 4 || /* windows enforces this */
+		    name_offset + name_length > remaining ||
+		    data_offset < name_offset + name_length ||
+		    data_offset > remaining ||
+		    data_offset + (uint64_t)data_length > remaining) {
+			return NT_STATUS_INVALID_PARAMETER;
+		}
+
+		tag = talloc_strndup(mem_ctx, (const char *)data + name_offset, name_length);
+		if (tag == NULL) {
+			return NT_STATUS_NO_MEMORY;
+		}
+
+		b = data_blob_const(data+data_offset, data_length);
+		status = smb2_create_blob_add(mem_ctx, blobs, tag, b);
+		if (!NT_STATUS_IS_OK(status)) {
+			return status;
+		}
+
+		talloc_free(tag);
+
+		if (next == 0) break;
+
+		remaining -= next;
+		data += next;
+
+		if (remaining < 16) {
+			return NT_STATUS_INVALID_PARAMETER;
+		}
+	}
+
+	return NT_STATUS_OK;
+}
+
 
 /*
   add a blob to a smb2_create attribute blob
@@ -57,6 +126,35 @@ static NTSTATUS smb2_create_blob_push_one(TALLOC_CTX *mem_ctx, DATA_BLOB *buffer
 	return NT_STATUS_OK;
 }
 
+
+/*
+  create a buffer of a set of create blobs
+*/
+NTSTATUS smb2_create_blob_push(TALLOC_CTX *mem_ctx, DATA_BLOB *buffer,
+			       const struct smb2_create_blobs blobs)
+{
+	int i;
+	NTSTATUS status;
+
+	*buffer = data_blob(NULL, 0);
+	for (i=0; i < blobs.num_blobs; i++) {
+		bool last = false;
+		const struct smb2_create_blob *c;
+
+		if ((i + 1) == blobs.num_blobs) {
+			last = true;
+		}
+
+		c = &blobs.blobs[i];
+		status = smb2_create_blob_push_one(mem_ctx, buffer, c, last);
+		if (!NT_STATUS_IS_OK(status)) {
+			return status;
+		}
+	}
+	return NT_STATUS_OK;
+}
+
+
 NTSTATUS smb2_create_blob_add(TALLOC_CTX *mem_ctx, struct smb2_create_blobs *b,
 			      const char *tag, DATA_BLOB data)
 {
@@ -92,9 +190,11 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create
 {
 	struct smb2_request *req;
 	NTSTATUS status;
-	DATA_BLOB blob = data_blob(NULL, 0);
-	uint32_t i;
-	struct smb2_create_blobs blobs = io->in.blobs;
+	DATA_BLOB blob;
+	struct smb2_create_blobs blobs;
+	int i;
+
+	ZERO_STRUCT(blobs);
 
 	req = smb2_request_init_tree(tree, SMB2_OP_CREATE, 0x38, true, 0);
 	if (req == NULL) return NULL;
@@ -116,6 +216,7 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create
 		return NULL;
 	}
 
+	/* now add all the optional blobs */
 	if (io->in.eas.num_eas != 0) {
 		DATA_BLOB b = data_blob_talloc(req, NULL, 
 					       ea_list_size_chained(io->in.eas.num_eas, io->in.eas.eas, 4));
@@ -131,36 +232,112 @@ 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, &blobs,
-				      SMB2_CREATE_TAG_MXAC, data_blob(NULL, 0));
-	if (!NT_STATUS_IS_OK(status)) {
-		talloc_free(req);
-		return NULL;
+	if (io->in.query_maximal_access) {
+		/* TODO: MS-SMB2 2.2.13.2.5 says this can contain a timestamp? What to do
+		   with that if it doesn't match? */
+		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 < blobs.num_blobs; i++) {
-		bool last = false;
-		const struct smb2_create_blob *c;
+	if (io->in.alloc_size != 0) {
+		uint8_t data[8];
+		SBVAL(data, 0, io->in.alloc_size);
+		status = smb2_create_blob_add(req, &blobs,
+					      SMB2_CREATE_TAG_ALSI, data_blob_const(data, 8));
+		if (!NT_STATUS_IS_OK(status)) {
+			talloc_free(req);
+			return NULL;
+		}
+	}
 
-		if ((i + 1) == blobs.num_blobs) {
-			last = true;
+	if (io->in.durable_open) {
+		status = smb2_create_blob_add(req, &blobs,
+					      SMB2_CREATE_TAG_DHNQ, data_blob_talloc_zero(req, 16));
+		if (!NT_STATUS_IS_OK(status)) {
+			talloc_free(req);
+			return NULL;
 		}
+	}
 
-		c = &blobs.blobs[i];
-		status = smb2_create_blob_push_one(req, &blob,
-						   c, last);
+	if (io->in.durable_handle) {
+		uint8_t data[16];
+		smb2_push_handle(data, io->in.durable_handle);
+		status = smb2_create_blob_add(req, &blobs,
+					      SMB2_CREATE_TAG_DHNC, data_blob_const(data, 16));
+		if (!NT_STATUS_IS_OK(status)) {
+			talloc_free(req);
+			return NULL;
+		}
+	}
+
+	if (io->in.timewarp) {
+		uint8_t data[8];
+		SBVAL(data, 0, io->in.timewarp);		
+		status = smb2_create_blob_add(req, &blobs,
+					      SMB2_CREATE_TAG_TWRP, data_blob_const(data, 8));
+		if (!NT_STATUS_IS_OK(status)) {
+			talloc_free(req);
+			return NULL;
+		}
+	}
+
+	if (io->in.sec_desc) {
+		enum ndr_err_code ndr_err;
+		DATA_BLOB sd_blob;
+		ndr_err = ndr_push_struct_blob(&sd_blob, req, NULL,
+					       io->in.sec_desc,
+					       (ndr_push_flags_fn_t)ndr_push_security_descriptor);
+		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+			talloc_free(req);
+			return NULL;
+		}
+		status = smb2_create_blob_add(req, &blobs,
+					      SMB2_CREATE_TAG_SECD, sd_blob);
+		if (!NT_STATUS_IS_OK(status)) {
+			talloc_free(req);
+			return NULL;
+		}
+	}
+
+	if (io->in.query_on_disk_id) {
+		status = smb2_create_blob_add(req, &blobs,
+					      SMB2_CREATE_TAG_QFID, data_blob(NULL, 0));
 		if (!NT_STATUS_IS_OK(status)) {
 			talloc_free(req);
 			return NULL;
 		}
 	}
 
+	/* and any custom blobs */
+	for (i=0;i<io->in.blobs.num_blobs;i++) {
+		status = smb2_create_blob_add(req, &blobs,
+					      io->in.blobs.blobs[i].tag, 
+					      io->in.blobs.blobs[i].data);
+		if (!NT_STATUS_IS_OK(status)) {
+			talloc_free(req);
+			return NULL;
+		}
+	}
+
+
+	status = smb2_create_blob_push(req, &blob, blobs);
+	if (!NT_STATUS_IS_OK(status)) {
+		talloc_free(req);
+		return NULL;
+	}
+
 	status = smb2_push_o32s32_blob(&req->out, 0x30, blob);
 	if (!NT_STATUS_IS_OK(status)) {
 		talloc_free(req);
 		return NULL;
 	}
 
+	data_blob_free(&blob);
+
 	smb2_transport_send(req);
 
 	return req;
@@ -173,6 +350,8 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create
 NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct smb2_create *io)
 {
 	NTSTATUS status;
+	DATA_BLOB blob;
+	int i;
 
 	if (!smb2_request_receive(req) || 
 	    !smb2_request_is_ok(req)) {
@@ -180,7 +359,7 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct
 	}
 
 	SMB2_CHECK_PACKET_RECV(req, 0x58, true);
-
+	ZERO_STRUCT(io->out);
 	io->out.oplock_level   = CVAL(req->in.body, 0x02);
 	io->out.reserved       = CVAL(req->in.body, 0x03);
 	io->out.create_action  = IVAL(req->in.body, 0x04);
@@ -193,12 +372,39 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct
 	io->out.file_attr      = IVAL(req->in.body, 0x38);
 	io->out.reserved2      = IVAL(req->in.body, 0x3C);
 	smb2_pull_handle(req->in.body+0x40, &io->out.file.handle);
-	status = smb2_pull_o32s32_blob(&req->in, mem_ctx, req->in.body+0x50, &io->out.blob);
+	status = smb2_pull_o32s32_blob(&req->in, mem_ctx, req->in.body+0x50, &blob);
 	if (!NT_STATUS_IS_OK(status)) {
 		smb2_request_destroy(req);
 		return status;
 	}
 
+	status = smb2_create_blob_parse(mem_ctx, blob, &io->out.blobs);
+	if (!NT_STATUS_IS_OK(status)) {
+		smb2_request_destroy(req);
+		return status;
+	}
+
+	/* pull out the parsed blobs */
+	for (i=0;i<io->out.blobs.num_blobs;i++) {
+		if (strcmp(io->out.blobs.blobs[i].tag, SMB2_CREATE_TAG_MXAC) == 0) {
+			/* why 8 bytes not 4?? */
+			if (io->out.blobs.blobs[i].data.length != 8) {
+				smb2_request_destroy(req);
+				return NT_STATUS_INVALID_NETWORK_RESPONSE;
+			}
+			io->out.maximal_access = IVAL(io->out.blobs.blobs[i].data.data, 0);
+		}
+		if (strcmp(io->out.blobs.blobs[i].tag, SMB2_CREATE_TAG_QFID) == 0) {
+			if (io->out.blobs.blobs[i].data.length != 32) {
+				smb2_request_destroy(req);
+				return NT_STATUS_INVALID_NETWORK_RESPONSE;
+			}
+			memcpy(io->out.on_disk_id, io->out.blobs.blobs[i].data.data, 32);
+		}
+	}
+
+	data_blob_free(&blob);
+
 	return smb2_request_destroy(req);
 }
 
diff --git a/source/ntvfs/ipc/vfs_ipc.c b/source/ntvfs/ipc/vfs_ipc.c
index ea7b54a..8ac7ac7 100644
--- a/source/ntvfs/ipc/vfs_ipc.c
+++ b/source/ntvfs/ipc/vfs_ipc.c
@@ -321,6 +321,7 @@ static NTSTATUS ipc_open_smb2(struct ntvfs_module_context *ntvfs,
 	status = ipc_open_generic(ntvfs, req, oi->smb2.in.fname, &p);
 	NT_STATUS_NOT_OK_RETURN(status);
 
+	ZERO_STRUCT(oi->smb2.out);
 	oi->smb2.out.file.ntvfs		= p->handle;
 	oi->smb2.out.oplock_level	= oi->smb2.in.oplock_level;
 	oi->smb2.out.create_action	= NTCREATEX_ACTION_EXISTED;
@@ -332,7 +333,6 @@ static NTSTATUS ipc_open_smb2(struct ntvfs_module_context *ntvfs,
 	oi->smb2.out.size		= 0;
 	oi->smb2.out.file_attr		= FILE_ATTRIBUTE_NORMAL;
 	oi->smb2.out.reserved2		= 0;
-	oi->smb2.out.blob		= data_blob(NULL, 0);
 
 	return status;
 }
diff --git a/source/ntvfs/ntvfs_generic.c b/source/ntvfs/ntvfs_generic.c
index 06d89a7..9227295 100644
--- a/source/ntvfs/ntvfs_generic.c
+++ b/source/ntvfs/ntvfs_generic.c
@@ -207,6 +207,7 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs,
 		break;
 
 	case RAW_OPEN_SMB2:
+		ZERO_STRUCT(io->smb2.out);
 		io->smb2.out.file.ntvfs		= io2->generic.out.file.ntvfs;
 		switch (io2->generic.out.oplock_level) {
 		case BATCH_OPLOCK_RETURN:
@@ -232,7 +233,6 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs,
 		io->smb2.out.size		= io2->generic.out.size;
 		io->smb2.out.file_attr		= io2->generic.out.attrib;
 		io->smb2.out.reserved2		= 0;
-		io->smb2.out.blob		= data_blob(NULL, 0);
 		break;
 
 	default:
@@ -512,7 +512,7 @@ NTSTATUS ntvfs_map_open(struct ntvfs_module_context *ntvfs,
 		}
 		io2->generic.in.root_fid	= 0;
 		io2->generic.in.access_mask	= io->smb2.in.desired_access;
-		io2->generic.in.alloc_size	= 0;
+		io2->generic.in.alloc_size	= io->smb2.in.alloc_size;
 		io2->generic.in.file_attr	= io->smb2.in.file_attributes;
 		io2->generic.in.share_access	= io->smb2.in.share_access;
 		io2->generic.in.open_disposition= io->smb2.in.create_disposition;
@@ -520,8 +520,14 @@ NTSTATUS ntvfs_map_open(struct ntvfs_module_context *ntvfs,
 		io2->generic.in.impersonation	= io->smb2.in.impersonation_level;
 		io2->generic.in.security_flags	= 0;
 		io2->generic.in.fname		= io->smb2.in.fname;
-		io2->generic.in.sec_desc	= NULL;
-		io2->generic.in.ea_list		= NULL;
+		io2->generic.in.sec_desc	= io->smb2.in.sec_desc;
+		io2->generic.in.ea_list		= &io->smb2.in.eas;
+
+		/* we don't support timewarp yet */
+		if (io->smb2.in.timewarp != 0) {
+			status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+			break;
+		}
 
 		/* we need to check these bits before we check the private mask */
 		if (io2->generic.in.create_options & NTCREATEX_OPTIONS_NOT_SUPPORTED_MASK) {
diff --git a/source/ntvfs/posix/pvfs_open.c b/source/ntvfs/posix/pvfs_open.c
index 4971080..0f08136 100644
--- a/source/ntvfs/posix/pvfs_open.c
+++ b/source/ntvfs/posix/pvfs_open.c
@@ -634,6 +634,8 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs,
 		return status;
 	}
 
+	/* support initial alloc sizes */
+	name->dos.alloc_size = io->ntcreatex.in.alloc_size;
 	name->dos.attrib = attrib;
 	status = pvfs_dosattrib_save(pvfs, name, fd);
 	if (!NT_STATUS_IS_OK(status)) {
@@ -1464,6 +1466,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
 			talloc_free(lck);
 			return pvfs_map_errno(pvfs, errno);
 		}
+		name->dos.alloc_size = io->ntcreatex.in.alloc_size;
 		name->dos.attrib = attrib;
 		status = pvfs_dosattrib_save(pvfs, name, fd);
 		if (!NT_STATUS_IS_OK(status)) {
diff --git a/source/smb_server/smb2/fileio.c b/source/smb_server/smb2/fileio.c
index 5ab217b..086ddc6 100644
--- a/source/smb_server/smb2/fileio.c
+++ b/source/smb_server/smb2/fileio.c
@@ -25,14 +25,19 @@
 #include "smb_server/smb2/smb2_server.h"
 #include "ntvfs/ntvfs.h"
 #include "param/param.h"
+#include "libcli/raw/libcliraw.h"
+#include "libcli/raw/raw_proto.h"
+#include "librpc/gen_ndr/ndr_security.h"
 
 static void smb2srv_create_send(struct ntvfs_request *ntvfs)
 {
 	struct smb2srv_request *req;
 	union smb_open *io;
+	DATA_BLOB blob;
 
 	SMB2SRV_CHECK_ASYNC_STATUS(io, union smb_open);
-	SMB2SRV_CHECK(smb2srv_setup_reply(req, 0x58, true, io->smb2.out.blob.length));
+	SMB2SRV_CHECK(smb2_create_blob_push(req, &blob, io->smb2.out.blobs));
+	SMB2SRV_CHECK(smb2srv_setup_reply(req, 0x58, true, blob.length));
 
 	SCVAL(req->out.body,	0x02,	io->smb2.out.oplock_level);
 	SCVAL(req->out.body,	0x03,	io->smb2.out.reserved);
@@ -46,7 +51,7 @@ static void smb2srv_create_send(struct ntvfs_request *ntvfs)
 	SIVAL(req->out.body,	0x38,	io->smb2.out.file_attr);
 	SIVAL(req->out.body,	0x3C,	io->smb2.out.reserved2);
 	smb2srv_push_handle(req->out.body, 0x40, io->smb2.out.file.ntvfs);
-	SMB2SRV_CHECK(smb2_push_o32s32_blob(&req->out, 0x50, io->smb2.out.blob));
+	SMB2SRV_CHECK(smb2_push_o32s32_blob(&req->out, 0x50, blob));
 
 	/* also setup the chained file handle */
 	req->chained_file_handle = req->_chained_file_handle;
@@ -59,11 +64,13 @@ void smb2srv_create_recv(struct smb2srv_request *req)
 {
 	union smb_open *io;
 	DATA_BLOB blob;
+	int i;
 
 	SMB2SRV_CHECK_BODY_SIZE(req, 0x38, true);
 	SMB2SRV_TALLOC_IO_PTR(io, union smb_open);
 	SMB2SRV_SETUP_NTVFS_REQUEST(smb2srv_create_send, NTVFS_ASYNC_STATE_MAY_ASYNC);
 
+	ZERO_STRUCT(io->smb2.in);
 	io->smb2.level			= RAW_OPEN_SMB2;
 	io->smb2.in.security_flags	= CVAL(req->in.body, 0x02);
 	io->smb2.in.oplock_level	= CVAL(req->in.body, 0x03);
@@ -77,10 +84,67 @@ void smb2srv_create_recv(struct smb2srv_request *req)
 	io->smb2.in.create_options	= IVAL(req->in.body, 0x28);


-- 
Samba Shared Repository


More information about the samba-cvs mailing list