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 <ob...@samba.org>
Date:   Sat Mar 3 17:01:38 2012 +0100

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

commit e6283801f44c2782ba7906fec25c7ee382499a14
Author: Michael Adam <ob...@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 <ob...@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 <me...@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 <ob...@samba.org>

commit 1451e5f66312e37b07d82e48a615b39fe63bd6e3
Author: Michael Adam <ob...@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 <ob...@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 <me...@samba.org>

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

    s4:libcli:smb2: allow max protocol 0x0224

commit a92b5f33de6d5d961725f34104a132be1a8dcf52
Author: Michael Adam <ob...@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 <ob...@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 <ob...@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 <ob...@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 <ob...@samba.org>
Date:   Fri Mar 2 22:01:01 2012 +0100

    libcli:smb: define SMB2_DHANDLE_FLAG_PERSISTENT

commit db632fdd2c5d14bcd05edc424ff66d7a3248dc2a
Author: Michael Adam <ob...@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 <ob...@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 <ob...@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 <ob...@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 <ob...@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 <ob...@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 <ob...@samba.org>
Date:   Wed Feb 29 22:59:35 2012 +0100

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

commit 4c92866fac5975434c54a8383e8c24e5dbf87e88
Author: Stefan Metzmacher <me...@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 <ob...@samba.org>

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

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

commit 79576df9f0492454a5d09ae59f4fb7ba7421c1ac
Author: Stefan Metzmacher <me...@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 <ob...@samba.org>

commit 579bb0a9342a3da4b1be3fb7b25233327f1e4f75
Author: Stefan Metzmacher <me...@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 <ob...@samba.org>

commit 87fc8c0f648826b1db0570ba0aa5f03697248569
Author: Michael Adam <ob...@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

Reply via email to