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