s4:libcli/smb2: add support for SMB2 LEASES v2
authorStefan Metzmacher <metze@samba.org>
Wed, 31 Oct 2012 07:37:13 +0000 (08:37 +0100)
committerVolker Lendecke <vl@samba.org>
Thu, 18 Apr 2013 13:11:48 +0000 (15:11 +0200)
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
source4/libcli/raw/interfaces.h
source4/libcli/smb2/create.c

index c13475b4406f7af95050e7889dd7ac9f046b1c4d..fb73f26a42611144df1fce414b13524368bc0dac 100644 (file)
@@ -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 */
index db9abbee6981db0121878d410ff97bfc3f8312d0..6047a85d878d6f92b37670d2a9fb83ccb4767efe 100644 (file)
@@ -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) {