[SCM] Samba Shared Repository - branch master updated

Michael Adam obnox at samba.org
Sat Mar 3 11:18:03 MST 2012


The branch, master has been updated
       via  58c26c2 selftest: more precisely skip durable-open, not durable.open
       via  e628380 s4:torture:smb2: start a testsuite for durable v2 handles: durable and persistent opens
       via  f6047af s4:libcli:smb2: set SMB2_CAP_ALL in the negprot
       via  8dc1873 s3:libsmb: pass smb2 capabilities and client guid in cli_state_create()
       via  1451e5f s4:libcli:smb2: store the share capabilites in the smb2_tree object
       via  ac43937 smbXcli: add the possiblilty to negotiate client capabilites in smb >= 2.2
       via  5a5f98d s4:libcli:smb2: allow max protocol 0x0224
       via  a92b5f3 s4:libcli:smb2: add support for parsing the durable handle v2 response in smb2_create_recv()
       via  dfbf55b s4:libcli:smb2: add support durable handle reconnect v2 blob in smb2_create_send
       via  b1a2ab1 s4:libcli:smb2: add support durable handle request v2 blob in smb2_create_send
       via  edeed15 s4:libcli:smb2: add durable handle v2 data to the smb2_create i/o structure
       via  76e6733 libcli:smb: define SMB2_DHANDLE_FLAG_PERSISTENT
       via  db632fd libcli:smb: add new SMB2 share flags
       via  6f86083 libcli:smb: upgrade SMB2_CAP_ALL to include the newly known caps
       via  8c5d288 libcli:smb: add defines for SMB2.2 share capabilities
       via  29eed63 libcli:smb: add defines for SMB2.2 global capabilities
       via  0bdd18e libcli:smb: define DH2Q and DH2C tags for smb2 extra create blobs
       via  57d99bc s4:torture:smb2: rename some of the durable-handle subtests more systematically
       via  72ab279 s4:torture:smb2:durable_open: update (C)
       via  4c92866 s4:torture:smb2:durable-open: skip the open-with-lease test on servers without lease support
       via  d276356 s4:torture:smb2: durable-open: make tables static
       via  79576df s4:test:smb2:durable_open: skip lease tests when the server does not support leases
       via  579bb0a s4:torture:smb2:durable_open: remove unused lease variables in the open-oplock test
       via  87fc8c0 s3:smbd:smb2_write: improve logging in the error case
      from  a66d0f3 s4:samba-tool domain level raise command - reference SAMDB object correctly

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


- Log -----------------------------------------------------------------
commit 58c26c2fd43051bb3910e8b7012ab37604da3ef5
Author: Michael Adam <obnox at samba.org>
Date:   Sat Mar 3 17:01:38 2012 +0100

    selftest: more precisely skip durable-open, not durable.open
    
    Autobuild-User: Michael Adam <obnox at samba.org>
    Autobuild-Date: Sat Mar  3 19:17:32 CET 2012 on sn-devel-104

commit e6283801f44c2782ba7906fec25c7ee382499a14
Author: Michael Adam <obnox at samba.org>
Date:   Mon Feb 27 22:56:37 2012 +0100

    s4:torture:smb2: start a testsuite for durable v2 handles: durable and persistent opens

commit f6047afb2dfd64fc5c636ecadd66f6c4185e100a
Author: Michael Adam <obnox at samba.org>
Date:   Thu Mar 1 02:22:36 2012 +0100

    s4:libcli:smb2: set SMB2_CAP_ALL in the negprot

commit 8dc1873ff530060850c48bd2bb3cff9ab86a6b95
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Mar 1 01:38:09 2012 +0100

    s3:libsmb: pass smb2 capabilities and client guid in cli_state_create()
    
    metze
    
    Signed-off-by: Michael Adam <obnox at samba.org>

commit 1451e5f66312e37b07d82e48a615b39fe63bd6e3
Author: Michael Adam <obnox at samba.org>
Date:   Thu Mar 1 00:29:51 2012 +0100

    s4:libcli:smb2: store the share capabilites in the smb2_tree object

commit ac43937ce4d5100a82df9d76d50d72b97daaedd3
Author: Michael Adam <obnox at samba.org>
Date:   Wed Feb 29 02:02:29 2012 +0100

    smbXcli: add the possiblilty to negotiate client capabilites in smb >= 2.2
    
    Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>

commit 5a5f98dc70bcca088af061473b8cb465e5aa6ff0
Author: Michael Adam <obnox at samba.org>
Date:   Mon Feb 27 20:27:46 2012 +0100

    s4:libcli:smb2: allow max protocol 0x0224

commit a92b5f33de6d5d961725f34104a132be1a8dcf52
Author: Michael Adam <obnox at samba.org>
Date:   Mon Feb 27 20:15:18 2012 +0100

    s4:libcli:smb2: add support for parsing the durable handle v2 response in smb2_create_recv()

commit dfbf55bb36e2f5cc798079b3fea2b34cd727e1b3
Author: Michael Adam <obnox at samba.org>
Date:   Mon Feb 27 20:15:01 2012 +0100

    s4:libcli:smb2: add support durable handle reconnect v2 blob in smb2_create_send

commit b1a2ab1fa9222f794217e5917aea193ecf591e3e
Author: Michael Adam <obnox at samba.org>
Date:   Mon Feb 27 20:15:01 2012 +0100

    s4:libcli:smb2: add support durable handle request v2 blob in smb2_create_send

commit edeed1552d437b82e88288395d8e1db44ac2999a
Author: Michael Adam <obnox at samba.org>
Date:   Mon Feb 27 02:35:24 2012 +0100

    s4:libcli:smb2: add durable handle v2 data to the smb2_create i/o structure

commit 76e6733344dc4d85a96ff108ca05279f44ffc79e
Author: Michael Adam <obnox at samba.org>
Date:   Fri Mar 2 22:01:01 2012 +0100

    libcli:smb: define SMB2_DHANDLE_FLAG_PERSISTENT

commit db632fdd2c5d14bcd05edc424ff66d7a3248dc2a
Author: Michael Adam <obnox at samba.org>
Date:   Fri Mar 2 19:01:50 2012 +0100

    libcli:smb: add new SMB2 share flags
    
    * FORCE_LEVELII_OPLOCKS
    * ENABLE_HASH_V1
    * ENABLE_HASH_V2
    * ENCRYPT_DATA

commit 6f860837e59a65eef82550944c8caca67ef7ff45
Author: Michael Adam <obnox at samba.org>
Date:   Thu Mar 1 00:59:54 2012 +0100

    libcli:smb: upgrade SMB2_CAP_ALL to include the newly known caps

commit 8c5d288ecf1c7ff1badba046f52038b91fa7adc0
Author: Michael Adam <obnox at samba.org>
Date:   Tue Feb 28 15:48:46 2012 +0100

    libcli:smb: add defines for SMB2.2 share capabilities
    
    * continuous avaliability
    * cluster
    * scaleout

commit 29eed6359ad83f631f2c6019a7e36524d18fe670
Author: Michael Adam <obnox at samba.org>
Date:   Tue Feb 28 15:47:05 2012 +0100

    libcli:smb: add defines for SMB2.2 global capabilities
    
    * multi channel
    * persistent handles
    * directory leasing
    * encryption

commit 0bdd18efc91a926a270cb9661c8a2b743e123a63
Author: Michael Adam <obnox at samba.org>
Date:   Mon Feb 27 02:17:20 2012 +0100

    libcli:smb: define DH2Q and DH2C tags for smb2 extra create blobs
    
    These are the tags for the SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2
    and SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2, the second version
    of the SMB2_CREATE_DURABLE_HANDLE_REQUEST (DHnQ) and
    SMB2_CREATE_DURABLE_HANDLE_RECONNECT (DHnC), which are only
    available for SMB 2.2 (and newer).

commit 57d99bc14a8fa7a47533cefcbba053b1b1881d03
Author: Michael Adam <obnox at samba.org>
Date:   Wed Feb 29 23:19:59 2012 +0100

    s4:torture:smb2: rename some of the durable-handle subtests more systematically

commit 72ab279316b4174a803770c2b0e90c366c14aef7
Author: Michael Adam <obnox at samba.org>
Date:   Wed Feb 29 22:59:35 2012 +0100

    s4:torture:smb2:durable_open: update (C)

commit 4c92866fac5975434c54a8383e8c24e5dbf87e88
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Feb 23 09:16:55 2012 +0100

    s4:torture:smb2:durable-open: skip the open-with-lease test on servers without lease support
    
    Signed-off-by: Michael Adam <obnox at samba.org>

commit d2763561686d562f52a7d6739526bfd9ee277e3a
Author: Michael Adam <obnox at samba.org>
Date:   Tue Feb 28 03:07:51 2012 +0100

    s4:torture:smb2: durable-open: make tables static

commit 79576df9f0492454a5d09ae59f4fb7ba7421c1ac
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Feb 23 09:16:55 2012 +0100

    s4:test:smb2:durable_open: skip lease tests when the server does not support leases
    
    Signed-off-by: Michael Adam <obnox at samba.org>

commit 579bb0a9342a3da4b1be3fb7b25233327f1e4f75
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Feb 23 09:16:37 2012 +0100

    s4:torture:smb2:durable_open: remove unused lease variables in the open-oplock test
    
    Signed-off-by: Michael Adam <obnox at samba.org>

commit 87fc8c0f648826b1db0570ba0aa5f03697248569
Author: Michael Adam <obnox at samba.org>
Date:   Sat Mar 3 07:14:35 2012 +0100

    s3:smbd:smb2_write: improve logging in the error case

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

Summary of changes:
 libcli/smb/smb2_constants.h            |   40 ++-
 libcli/smb/smbXcli_base.c              |   11 +-
 libcli/smb/smbXcli_base.h              |    3 +-
 selftest/skip                          |    3 +-
 source3/libsmb/clientgen.c             |    8 +-
 source3/smbd/smb2_write.c              |   18 +-
 source4/libcli/raw/clitransport.c      |    3 +-
 source4/libcli/raw/interfaces.h        |   13 +
 source4/libcli/smb2/connect.c          |    3 +-
 source4/libcli/smb2/create.c           |   74 +++++
 source4/libcli/smb2/smb2.h             |    1 +
 source4/libcli/smb2/transport.c        |    7 +-
 source4/torture/smb2/durable_open.c    |  108 ++++---
 source4/torture/smb2/durable_v2_open.c |  551 ++++++++++++++++++++++++++++++++
 source4/torture/smb2/smb2.c            |    1 +
 source4/torture/smb2/util.c            |    1 +
 source4/torture/smb2/wscript_build     |    5 +-
 17 files changed, 790 insertions(+), 60 deletions(-)
 create mode 100644 source4/torture/smb2/durable_v2_open.c


Changeset truncated at 500 lines:

diff --git a/libcli/smb/smb2_constants.h b/libcli/smb/smb2_constants.h
index b8180ce..23c505d 100644
--- a/libcli/smb/smb2_constants.h
+++ b/libcli/smb/smb2_constants.h
@@ -84,12 +84,24 @@
 #define SMB2_NEGOTIATE_SIGNING_ENABLED   0x01
 #define SMB2_NEGOTIATE_SIGNING_REQUIRED  0x02
 
-/* SMB2 capabilities - only 1 so far. I'm sure more will be added */
-#define SMB2_CAP_DFS                     0x00000001
-#define SMB2_CAP_LEASING                 0x00000002 /* only in dialect 0x210 */
-#define SMB2_CAP_LARGE_MTU		 0x00000004 /* only in dialect 0x210 */
+/* SMB2 global capabilities */
+#define SMB2_CAP_DFS			0x00000001
+#define SMB2_CAP_LEASING		0x00000002 /* only in dialect >= 0x210 */
+#define SMB2_CAP_LARGE_MTU		0x00000004 /* only in dialect >= 0x210 */
+#define SMB2_CAP_MULTI_CHANNEL		0x00000008 /* only in dialect >= 0x222 */
+#define SMB2_CAP_PERSISTENT_HANDLES	0x00000010 /* only in dialect >= 0x222 */
+#define SMB2_CAP_DIRECTORY_LEASING	0x00000020 /* only in dialect >= 0x222 */
+#define SMB2_CAP_ENCRYPTION		0x00000040 /* only in dialect >= 0x222 */
+
 /* so we can spot new caps as added */
-#define SMB2_CAP_ALL                     SMB2_CAP_DFS
+#define SMB2_CAP_ALL (\
+		SMB2_CAP_DFS | \
+		SMB2_CAP_LEASING | \
+		SMB2_CAP_LARGE_MTU | \
+		SMB2_CAP_MULTI_CHANNEL | \
+		SMB2_CAP_PERSISTENT_HANDLES | \
+		SMB2_CAP_ENCRYPTION)
+
 
 /* SMB2 session flags */
 #define SMB2_SESSION_FLAG_IS_GUEST       0x0001
@@ -111,10 +123,17 @@
 #define SMB2_SHAREFLAG_FORCE_SHARED_DELETE               0x0200
 #define SMB2_SHAREFLAG_ALLOW_NAMESPACE_CACHING           0x0400
 #define SMB2_SHAREFLAG_ACCESS_BASED_DIRECTORY_ENUM       0x0800
-#define SMB2_SHAREFLAG_ALL                               0x0F33
+#define SMB2_SHAREFLAG_FORCE_LEVELII_OPLOCKS             0x1000
+#define SMB2_SHAREFLAG_ENABLE_HASH_V1                    0x2000
+#define SMB2_SHAREFLAG_ENABLE_HASH_V2                    0x4000
+#define SMB2_SHAREFLAG_ENCRYPT_DATA                      0x8000
+#define SMB2_SHAREFLAG_ALL                               0xFF33
 
 /* SMB2 share capabilities */
-#define SMB2_SHARE_CAP_DFS		0x8
+#define SMB2_SHARE_CAP_DFS			0x8
+#define SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY	0x10 /* in dialect >= 0x222 */
+#define SMB2_SHARE_CAP_SCALEOUT			0x20 /* in dialect >= 0x222 */
+#define SMB2_SHARE_CAP_CLUSTER			0x40 /* in dialect >= 0x222 */
 
 /* SMB2 create security flags */
 #define SMB2_SECURITY_DYNAMIC_TRACKING                   0x01
@@ -160,6 +179,8 @@
 #define SMB2_CREATE_TAG_TWRP "TWrp"
 #define SMB2_CREATE_TAG_QFID "QFid"
 #define SMB2_CREATE_TAG_RQLS "RqLs"
+#define SMB2_CREATE_TAG_DH2Q "DH2Q"
+#define SMB2_CREATE_TAG_DH2C "DH2C"
 
 /* SMB2 notify flags */
 #define SMB2_WATCH_TREE 0x0001
@@ -194,4 +215,9 @@
 
 #define SMB2_WRITEFLAG_WRITE_THROUGH	0x00000001
 
+/*
+ * Flags for durable handle v2 requests
+ */
+#define SMB2_DHANDLE_FLAG_PERSISTENT 0x00000002
+
 #endif
diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c
index bdb6e48..b54d7e4 100644
--- a/libcli/smb/smbXcli_base.c
+++ b/libcli/smb/smbXcli_base.c
@@ -102,6 +102,7 @@ struct smbXcli_conn {
 
 	struct {
 		struct {
+			uint32_t capabilities;
 			uint16_t security_mode;
 			struct GUID guid;
 		} client;
@@ -225,7 +226,8 @@ struct smbXcli_conn *smbXcli_conn_create(TALLOC_CTX *mem_ctx,
 					 const char *remote_name,
 					 enum smb_signing_setting signing_state,
 					 uint32_t smb1_capabilities,
-					 struct GUID *client_guid)
+					 struct GUID *client_guid,
+					 uint32_t smb2_capabilities)
 {
 	struct smbXcli_conn *conn = NULL;
 	void *ss = NULL;
@@ -319,6 +321,7 @@ struct smbXcli_conn *smbXcli_conn_create(TALLOC_CTX *mem_ctx,
 	if (client_guid) {
 		conn->smb2.client.guid = *client_guid;
 	}
+	conn->smb2.client.capabilities = smb2_capabilities;
 
 	conn->smb2.cur_credits = 1;
 	conn->smb2.max_credits = 0;
@@ -3796,7 +3799,11 @@ static struct tevent_req *smbXcli_negprot_smb2_subreq(struct smbXcli_negprot_sta
 	SSVAL(buf, 2, dialect_count);
 	SSVAL(buf, 4, state->conn->smb2.client.security_mode);
 	SSVAL(buf, 6, 0);	/* Reserved */
-	SSVAL(buf, 8, 0); 	/* Capabilities */
+	if (state->max_protocol >= PROTOCOL_SMB2_22) {
+		SIVAL(buf, 8, state->conn->smb2.client.capabilities);
+	} else {
+		SIVAL(buf, 8, 0); 	/* Capabilities */
+	}
 	if (state->max_protocol >= PROTOCOL_SMB2_10) {
 		NTSTATUS status;
 		DATA_BLOB blob;
diff --git a/libcli/smb/smbXcli_base.h b/libcli/smb/smbXcli_base.h
index 27f3425..dafd836 100644
--- a/libcli/smb/smbXcli_base.h
+++ b/libcli/smb/smbXcli_base.h
@@ -31,7 +31,8 @@ struct smbXcli_conn *smbXcli_conn_create(TALLOC_CTX *mem_ctx,
 					 const char *remote_name,
 					 enum smb_signing_setting signing_state,
 					 uint32_t smb1_capabilities,
-					 struct GUID *client_guid);
+					 struct GUID *client_guid,
+					 uint32_t smb2_capabilities);
 
 bool smbXcli_conn_is_connected(struct smbXcli_conn *conn);
 void smbXcli_conn_disconnect(struct smbXcli_conn *conn, NTSTATUS status);
diff --git a/selftest/skip b/selftest/skip
index 0630512..5b7de62 100644
--- a/selftest/skip
+++ b/selftest/skip
@@ -54,7 +54,8 @@
 ^samba4.smb2.notify
 ^samba4.smb2.scan
 ^samba4.smb2.lease
-^samba4.smb2.durable.open
+^samba4.smb2.durable-open
+^samba4.smb2.durable-v2-open
 ^samba4.smb2.dir
 ^samba4.smb2.session
 ^samba4.ntvfs.cifs.*.base.charset
diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c
index 29a26d2..26fbd19 100644
--- a/source3/libsmb/clientgen.c
+++ b/source3/libsmb/clientgen.c
@@ -25,6 +25,7 @@
 #include "../libcli/smb/smb_seal.h"
 #include "async_smb.h"
 #include "../libcli/smb/smbXcli_base.h"
+#include "../librpc/ndr/libndr.h"
 
 /*******************************************************************
  Setup the word count and byte count for a client smb message.
@@ -150,6 +151,8 @@ struct cli_state *cli_state_create(TALLOC_CTX *mem_ctx,
 	bool force_ascii = false;
 	bool use_level_II_oplocks = false;
 	uint32_t smb1_capabilities = 0;
+	uint32_t smb2_capabilities = 0;
+	struct GUID client_guid = GUID_random();
 
 	/* Check the effective uid - make sure we are not setuid */
 	if (is_setuid_root()) {
@@ -250,6 +253,8 @@ struct cli_state *cli_state_create(TALLOC_CTX *mem_ctx,
 		smb1_capabilities |= CAP_LEVEL_II_OPLOCKS;
 	}
 
+	smb2_capabilities = SMB2_CAP_ALL;
+
 	if (remote_realm) {
 		cli->remote_realm = talloc_strdup(cli, remote_realm);
 		if (cli->remote_realm == NULL) {
@@ -260,7 +265,8 @@ struct cli_state *cli_state_create(TALLOC_CTX *mem_ctx,
 	cli->conn = smbXcli_conn_create(cli, fd, remote_name,
 					signing_state,
 					smb1_capabilities,
-					NULL); /* client_guid */
+					&client_guid,
+					smb2_capabilities);
 	if (cli->conn == NULL) {
 		goto error;
 	}
diff --git a/source3/smbd/smb2_write.c b/source3/smbd/smb2_write.c
index 49a77e6..b0ffd44 100644
--- a/source3/smbd/smb2_write.c
+++ b/source3/smbd/smb2_write.c
@@ -178,6 +178,20 @@ NTSTATUS smb2_write_complete(struct tevent_req *req, ssize_t nwritten, int err)
 					struct smbd_smb2_write_state);
 	files_struct *fsp = state->fsp;
 
+	if (nwritten == -1) {
+		status = map_nt_error_from_unix(err);
+
+		DEBUG(2, ("smb2_write failed: fnum=[%d/%s] "
+			  "length=%lu offset=%lu nwritten=-1: %s\n",
+			  fsp->fnum,
+			  fsp_str_dbg(fsp),
+			  (unsigned long)state->in_length,
+			  (unsigned long)state->in_offset,
+			  nt_errstr(status)));
+
+		return status;
+	}
+
 	DEBUG(3,("smb2: fnum=[%d/%s] "
 		"length=%lu offset=%lu wrote=%lu\n",
 		fsp->fnum,
@@ -186,10 +200,6 @@ NTSTATUS smb2_write_complete(struct tevent_req *req, ssize_t nwritten, int err)
 		(unsigned long)state->in_offset,
 		(unsigned long)nwritten));
 
-	if (nwritten == -1) {
-		return map_nt_error_from_unix(err);
-	}
-
 	if ((nwritten == 0) && (state->in_length != 0)) {
 		DEBUG(5,("smb2: write [%s] disk full\n",
 			fsp_str_dbg(fsp)));
diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c
index a9ff8f3..f9759b1 100644
--- a/source4/libcli/raw/clitransport.c
+++ b/source4/libcli/raw/clitransport.c
@@ -90,7 +90,8 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock,
 					      sock->hostname,
 					      options->signing,
 					      smb1_capabilities,
-					      NULL); /* client_guid */
+					      NULL, /* client_guid */
+					      0); /* smb2_capabilities */
 	if (transport->conn == NULL) {
 		TALLOC_FREE(sock);
 		TALLOC_FREE(transport);
diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h
index 7aba48b..695c13f 100644
--- a/source4/libcli/raw/interfaces.h
+++ b/source4/libcli/raw/interfaces.h
@@ -1709,6 +1709,14 @@ union smb_open {
 			struct security_descriptor *sec_desc;
 			bool   durable_open;
 			struct smb2_handle *durable_handle;
+
+			/* data for durable handle v2 */
+			bool durable_open_v2;
+			struct GUID create_guid;
+			bool persistent_open;
+			uint32_t timeout;
+			struct smb2_handle *durable_handle_v2;
+
 			bool   query_maximal_access;
 			NTTIME timewarp;
 			bool   query_on_disk_id;
@@ -1743,6 +1751,11 @@ union smb_open {
 			struct smb2_lease lease_response;
 			bool durable_open;
 
+			/* durable handle v2 */
+			bool durable_open_v2;
+			bool persistent_open;
+			uint32_t timeout;
+
 			/* tagged blobs in the reply */
 			struct smb2_create_blobs blobs;
 		} out;
diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c
index c743b90..b2657f2 100644
--- a/source4/libcli/smb2/connect.c
+++ b/source4/libcli/smb2/connect.c
@@ -143,7 +143,7 @@ static void smb2_connect_socket_done(struct composite_context *creq)
 
 	subreq = smbXcli_negprot_send(state, state->ev,
 				      state->transport->conn, timeout_msec,
-				      PROTOCOL_SMB2_02, PROTOCOL_SMB2_22);
+				      PROTOCOL_SMB2_02, PROTOCOL_SMB2_24);
 	if (tevent_req_nomem(subreq, req)) {
 		return;
 	}
@@ -242,6 +242,7 @@ static void smb2_connect_tcon_done(struct smb2_request *smb2req)
 	}
 
 	state->tree->tid = state->tcon.out.tid;
+	state->tree->capabilities = state->tcon.out.capabilities;
 
 	tevent_req_done(req);
 }
diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c
index 438651f..c8424dc 100644
--- a/source4/libcli/smb2/create.c
+++ b/source4/libcli/smb2/create.c
@@ -106,6 +106,34 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create
 		}
 	}
 
+	if (io->in.durable_open_v2) {
+		uint8_t data[32];
+		uint32_t flags = 0;
+		DATA_BLOB guid_blob;
+
+		SIVAL(data, 0, io->in.timeout);
+		if (io->in.persistent_open) {
+			flags = SMB2_DHANDLE_FLAG_PERSISTENT;
+		}
+		SIVAL(data, 4, flags);
+		SBVAL(data, 8, 0x0); /* reserved */
+		status = GUID_to_ndr_blob(&io->in.create_guid, req, /* TALLOC_CTX */
+					  &guid_blob);
+		if (!NT_STATUS_IS_OK(status)) {
+			talloc_free(req);
+			return NULL;
+		}
+		memcpy(data+16, guid_blob.data, 16);
+
+		status = smb2_create_blob_add(req, &blobs,
+					      SMB2_CREATE_TAG_DH2Q,
+					      data_blob_const(data, 32));
+		if (!NT_STATUS_IS_OK(status)) {
+			talloc_free(req);
+			return NULL;
+		}
+	}
+
 	if (io->in.durable_handle) {
 		uint8_t data[16];
 		smb2_push_handle(data, io->in.durable_handle);
@@ -117,6 +145,33 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create
 		}
 	}
 
+	if (io->in.durable_handle_v2) {
+		uint8_t data[36];
+		DATA_BLOB guid_blob;
+		uint32_t flags = 0;
+
+		smb2_push_handle(data, io->in.durable_handle_v2);
+		status = GUID_to_ndr_blob(&io->in.create_guid, req, /* TALLOC_CTX */
+					  &guid_blob);
+		if (!NT_STATUS_IS_OK(status)) {
+			talloc_free(req);
+			return NULL;
+		}
+		memcpy(data+16, guid_blob.data, 16);
+		if (io->in.persistent_open) {
+			flags = SMB2_DHANDLE_FLAG_PERSISTENT;
+		}
+		SIVAL(data, 32, flags);
+
+		status = smb2_create_blob_add(req, &blobs,
+					      SMB2_CREATE_TAG_DH2C,
+					      data_blob_const(data, 36));
+		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);		
@@ -281,6 +336,25 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct
 			}
 			io->out.durable_open = true;
 		}
+		if (strcmp(io->out.blobs.blobs[i].tag, SMB2_CREATE_TAG_DH2Q) == 0) {
+			uint32_t flags;
+			uint8_t *data;
+
+			if (io->out.blobs.blobs[i].data.length != 8) {
+				smb2_request_destroy(req);
+				return NT_STATUS_INVALID_NETWORK_RESPONSE;
+			}
+
+			io->out.durable_open = false;
+			io->out.durable_open_v2 = true;
+
+			data = io->out.blobs.blobs[i].data.data;
+			io->out.timeout = IVAL(data, 0);
+			flags = IVAL(data, 4);
+			if ((flags & SMB2_DHANDLE_FLAG_PERSISTENT) != 0) {
+				io->out.persistent_open = true;
+			}
+		}
 	}
 
 	data_blob_free(&blob);
diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h
index 1cff5ea..c4dc000 100644
--- a/source4/libcli/smb2/smb2.h
+++ b/source4/libcli/smb2/smb2.h
@@ -107,6 +107,7 @@ struct smb2_transport {
 struct smb2_tree {
 	struct smb2_session *session;
 	uint32_t tid;
+	uint32_t capabilities;
 };
 
 /*
diff --git a/source4/libcli/smb2/transport.c b/source4/libcli/smb2/transport.c
index 14d1fc5..ac563da 100644
--- a/source4/libcli/smb2/transport.c
+++ b/source4/libcli/smb2/transport.c
@@ -50,6 +50,7 @@ struct smb2_transport *smb2_transport_init(struct smbcli_socket *sock,
 {
 	struct smb2_transport *transport;
 	struct GUID client_guid;
+	uint32_t smb2_capabilities = 0;
 
 	transport = talloc_zero(parent_ctx, struct smb2_transport);
 	if (!transport) return NULL;
@@ -62,12 +63,16 @@ struct smb2_transport *smb2_transport_init(struct smbcli_socket *sock,
 
 	client_guid = GUID_random();
 
+	/* TODO: hand this in via the options? */
+	smb2_capabilities = SMB2_CAP_ALL;
+
 	transport->conn = smbXcli_conn_create(transport,
 					      sock->sock->fd,
 					      sock->hostname,
 					      options->signing,
 					      0, /* smb1_capabilities */
-					      &client_guid);
+					      &client_guid,
+					      smb2_capabilities);
 	if (transport->conn == NULL) {
 		talloc_free(transport);
 		return NULL;
diff --git a/source4/torture/smb2/durable_open.c b/source4/torture/smb2/durable_open.c
index d667861..0c20f77 100644
--- a/source4/torture/smb2/durable_open.c
+++ b/source4/torture/smb2/durable_open.c
@@ -4,6 +4,7 @@
    test suite for SMB2 durable opens
 
    Copyright (C) Stefan Metzmacher 2008
+   Copyright (C) Michael Adam 2011-2012
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -22,6 +23,7 @@
 #include "includes.h"
 #include "libcli/smb2/smb2.h"
 #include "libcli/smb2/smb2_calls.h"
+#include "../libcli/smb/smbXcli_base.h"
 #include "torture/torture.h"
 #include "torture/smb2/proto.h"
 #include "../libcli/smb/smbXcli_base.h"
@@ -68,7 +70,7 @@ struct durable_open_vs_oplock {
 #define NUM_OPLOCK_TYPES 4
 #define NUM_SHARE_MODES 8
 #define NUM_OPLOCK_OPEN_TESTS ( NUM_OPLOCK_TYPES * NUM_SHARE_MODES )
-struct durable_open_vs_oplock durable_open_vs_oplock_table[NUM_OPLOCK_OPEN_TESTS] =
+static struct durable_open_vs_oplock durable_open_vs_oplock_table[NUM_OPLOCK_OPEN_TESTS] =
 {
 	{ "", "", false },
 	{ "", "R", false },
@@ -107,10 +109,10 @@ struct durable_open_vs_oplock durable_open_vs_oplock_table[NUM_OPLOCK_OPEN_TESTS
 	{ "b", "RWD", true },
 };
 
-static bool test_one_durable_open_open1(struct torture_context *tctx,
-					struct smb2_tree *tree,
-					const char *fname,
-					struct durable_open_vs_oplock test)
+static bool test_one_durable_open_open_oplock(struct torture_context *tctx,
+					      struct smb2_tree *tree,
+					      const char *fname,
+					      struct durable_open_vs_oplock test)
 {
 	NTSTATUS status;
 	TALLOC_CTX *mem_ctx = talloc_new(tctx);
@@ -144,8 +146,8 @@ done:
 	return ret;
 }
 
-bool test_durable_open_open1(struct torture_context *tctx,
-			     struct smb2_tree *tree)
+bool test_durable_open_open_oplock(struct torture_context *tctx,
+				   struct smb2_tree *tree)
 {
 	TALLOC_CTX *mem_ctx = talloc_new(tctx);
 	char fname[256];
@@ -153,17 +155,17 @@ bool test_durable_open_open1(struct torture_context *tctx,
 	int i;
 
 	/* Choose a random name in case the state is left a little funky. */
-	snprintf(fname, 256, "durable_open_open1_%s.dat", generate_random_str(tctx, 8));
+	snprintf(fname, 256, "durable_open_open_oplock_%s.dat", generate_random_str(tctx, 8));
 
 	smb2_util_unlink(tree, fname);
 
 	/* test various oplock levels with durable open */
 
 	for (i = 0; i < NUM_OPLOCK_OPEN_TESTS; i++) {
-		ret = test_one_durable_open_open1(tctx,
-						  tree,
-						  fname,
-						  durable_open_vs_oplock_table[i]);
+		ret = test_one_durable_open_open_oplock(tctx,
+							tree,


-- 
Samba Shared Repository


More information about the samba-cvs mailing list