summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2012-10-31 08:37:13 +0100
committerVolker Lendecke <vl@samba.org>2013-04-18 15:11:48 +0200
commit6c81893b342786d5f63aaa89e855e9378def50c3 (patch)
tree6efb3c0358392bef4ccf3f0bdcde1e15ae0f5e99
parentf367d07f521b26cfb5813dd679a4e4883b69752f (diff)
downloadsamba-6c81893b342786d5f63aaa89e855e9378def50c3.tar.gz
samba-6c81893b342786d5f63aaa89e855e9378def50c3.tar.bz2
samba-6c81893b342786d5f63aaa89e855e9378def50c3.zip
s4:libcli/smb2: add support for SMB2 LEASES v2
Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Volker Lendecke <vl@samba.org>
-rw-r--r--source4/libcli/raw/interfaces.h7
-rw-r--r--source4/libcli/smb2/create.c48
2 files changed, 49 insertions, 6 deletions
diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h
index c13475b440..fb73f26a42 100644
--- a/source4/libcli/raw/interfaces.h
+++ b/source4/libcli/raw/interfaces.h
@@ -64,8 +64,11 @@ struct smb2_lease_key {
struct smb2_lease {
struct smb2_lease_key lease_key;
uint32_t lease_state;
- uint32_t lease_flags; /* should be 0 */
+ uint32_t lease_flags;
uint64_t lease_duration; /* should be 0 */
+ /* only for v2 */
+ struct smb2_lease_key parent_lease_key;
+ uint16_t lease_epoch;
};
struct smb2_lease_break {
@@ -1743,6 +1746,7 @@ union smb_open {
NTTIME timewarp;
bool query_on_disk_id;
struct smb2_lease *lease_request;
+ struct smb2_lease *lease_request_v2;
struct GUID *app_instance_id;
@@ -1773,6 +1777,7 @@ union smb_open {
uint32_t maximal_access;
uint8_t on_disk_id[32];
struct smb2_lease lease_response;
+ struct smb2_lease lease_response_v2;
bool durable_open;
/* durable handle v2 */
diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c
index db9abbee69..6047a85d87 100644
--- a/source4/libcli/smb2/create.c
+++ b/source4/libcli/smb2/create.c
@@ -226,6 +226,27 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create
}
}
+ if (io->in.lease_request_v2) {
+ struct smb2_lease *ls = &io->in.lease_request_v2;
+ uint8_t data[52];
+
+ memcpy(&data[0], &ls->lease_key, 16);
+ SIVAL(data, 16, ls->lease_state);
+ SIVAL(data, 20, ls->lease_flags);
+ SBVAL(data, 24, ls->lease_duration);
+ memcpy(&data[32], &ls->parent_lease_key, 16);
+ SSVAL(data, 48, ls->lease_epoch);
+ SSVAL(data, 50, 0); /* reserved */
+
+ status = smb2_create_blob_add(req, &blobs,
+ SMB2_CREATE_TAG_RQLS,
+ data_blob_const(data, 52));
+ if (!NT_STATUS_IS_OK(status)) {
+ talloc_free(req);
+ return NULL;
+ }
+ }
+
if (io->in.app_instance_id) {
uint8_t data[20];
DATA_BLOB guid_blob;
@@ -342,17 +363,34 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct
memcpy(io->out.on_disk_id, io->out.blobs.blobs[i].data.data, 32);
}
if (strcmp(io->out.blobs.blobs[i].tag, SMB2_CREATE_TAG_RQLS) == 0) {
+ struct smb2_lease *ls = NULL;
uint8_t *data;
- if (io->out.blobs.blobs[i].data.length != 32) {
+
+ ZERO_STRUCT(io->out.lease_response);
+ ZERO_STRUCT(io->out.lease_response_v2);
+
+ switch (io->out.blobs.blobs[i].data.length) {
+ case 32:
+ ls = &io->out.lease_response;
+ break;
+ case 52:
+ ls = &io->out.lease_response_v2;
+ break;
+ default:
smb2_request_destroy(req);
return NT_STATUS_INVALID_NETWORK_RESPONSE;
}
data = io->out.blobs.blobs[i].data.data;
- memcpy(&io->out.lease_response.lease_key, data, 16);
- io->out.lease_response.lease_state = IVAL(data, 16);
- io->out.lease_response.lease_flags = IVAL(data, 20);
- io->out.lease_response.lease_duration = BVAL(data, 24);
+ memcpy(&ls->lease_key, data, 16);
+ ls->lease_state = IVAL(data, 16);
+ ls->lease_flags = IVAL(data, 20);
+ ls->lease_duration = BVAL(data, 24);
+
+ if (io->out.blobs.blobs[i].data.length == 52) {
+ memcpy(&ls->parent_lease_key, data+32, 16);
+ ls->lease_epoch = SVAL(data, 48);
+ }
}
if (strcmp(io->out.blobs.blobs[i].tag, SMB2_CREATE_TAG_DHNQ) == 0) {
if (io->out.blobs.blobs[i].data.length != 8) {