s3:smb2_server: FLAG_CHAINED means we always use the last session_id and tid
authorStefan Metzmacher <metze@samba.org>
Tue, 1 Nov 2011 17:55:17 +0000 (10:55 -0700)
committerKarolin Seeger <kseeger@samba.org>
Wed, 9 Nov 2011 18:48:36 +0000 (19:48 +0100)
Based on master commit 91648aeb6409787c7766943225f5c7a9c695aa0b.

metze

The last 4 patches address bug #8560 (SMB2 doesn't handle compound request
headers in the same way as Windows).

source3/smbd/globals.h
source3/smbd/smb2_server.c
source3/smbd/smb2_sesssetup.c
source3/smbd/smb2_tcon.c

index 9304a43cdd3078c0cb4f5f18c4ad954efd2b5050..663daa4b640cae0101c2d4dbc00c78c679570d1c 100644 (file)
@@ -353,9 +353,11 @@ struct smbd_smb2_request {
 
        /* the session the request operates on, maybe NULL */
        struct smbd_smb2_session *session;
+       uint64_t last_session_id;
 
        /* the tcon the request operates on, maybe NULL */
        struct smbd_smb2_tcon *tcon;
+       uint32_t last_tid;
 
        int current_idx;
        bool do_signing;
index c1fa45483a54729f97c72693461409bc70eabee5..4da1e15eea02521ff6cdacb16e1ff6ee932853e6 100644 (file)
@@ -206,6 +206,9 @@ static struct smbd_smb2_request *smbd_smb2_request_allocate(TALLOC_CTX *mem_ctx)
        req->mem_pool   = mem_pool;
        req->parent     = parent;
 
+       req->last_session_id = UINT64_MAX;
+       req->last_tid = UINT32_MAX;
+
        talloc_set_destructor(parent, smbd_smb2_request_parent_destructor);
        talloc_set_destructor(req, smbd_smb2_request_destructor);
 
index 14f9654798a292ae5178968d42665fc9331226de..a081290170a80ea3184bd5b5c8edaf5793e5bd3a 100644 (file)
@@ -813,32 +813,22 @@ static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *smb2req,
 NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req)
 {
        const uint8_t *inhdr;
-       const uint8_t *outhdr;
        int i = req->current_idx;
+       uint32_t in_flags;
        uint64_t in_session_id;
        void *p;
        struct smbd_smb2_session *session;
 
+       req->session = NULL;
+       req->tcon = NULL;
+
        inhdr = (const uint8_t *)req->in.vector[i+0].iov_base;
 
+       in_flags = IVAL(inhdr, SMB2_HDR_FLAGS);
        in_session_id = BVAL(inhdr, SMB2_HDR_SESSION_ID);
 
-       if (in_session_id == (0xFFFFFFFFFFFFFFFFLL)) {
-               if (req->async) {
-                       /*
-                        * async request - fill in session_id from
-                        * already setup request out.vector[].iov_base.
-                        */
-                       outhdr = (const uint8_t *)req->out.vector[i].iov_base;
-                       in_session_id = BVAL(outhdr, SMB2_HDR_SESSION_ID);
-               } else if (i > 2) {
-                       /*
-                        * Chained request - fill in session_id from
-                        * the previous request out.vector[].iov_base.
-                        */
-                       outhdr = (const uint8_t *)req->out.vector[i-3].iov_base;
-                       in_session_id = BVAL(outhdr, SMB2_HDR_SESSION_ID);
-               }
+       if (in_flags & SMB2_HDR_FLAG_CHAINED) {
+               in_session_id = req->last_session_id;
        }
 
        /* lookup an existing session */
@@ -857,6 +847,7 @@ NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req)
                              session->session_info->info3->base.domain.string);
 
        req->session = session;
+       req->last_session_id = in_session_id;
 
        return NT_STATUS_OK;
 }
index 8d2aae7410a50bac8f99f756d5b85eccdc72daaf..f1f03e890432bf3c11ac94a4a54f4d6042fadb72 100644 (file)
@@ -281,32 +281,21 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req,
 NTSTATUS smbd_smb2_request_check_tcon(struct smbd_smb2_request *req)
 {
        const uint8_t *inhdr;
-       const uint8_t *outhdr;
        int i = req->current_idx;
+       uint32_t in_flags;
        uint32_t in_tid;
        void *p;
        struct smbd_smb2_tcon *tcon;
 
+       req->tcon = NULL;
+
        inhdr = (const uint8_t *)req->in.vector[i+0].iov_base;
 
+       in_flags = IVAL(inhdr, SMB2_HDR_FLAGS);
        in_tid = IVAL(inhdr, SMB2_HDR_TID);
 
-       if (in_tid == (0xFFFFFFFF)) {
-               if (req->async) {
-                       /*
-                        * async request - fill in tid from
-                        * already setup out.vector[].iov_base.
-                        */
-                       outhdr = (const uint8_t *)req->out.vector[i].iov_base;
-                       in_tid = IVAL(outhdr, SMB2_HDR_TID);
-               } else if (i > 2) {
-                       /*
-                        * Chained request - fill in tid from
-                        * the previous request out.vector[].iov_base.
-                        */
-                       outhdr = (const uint8_t *)req->out.vector[i-3].iov_base;
-                       in_tid = IVAL(outhdr, SMB2_HDR_TID);
-               }
+       if (in_flags & SMB2_HDR_FLAG_CHAINED) {
+               in_tid = req->last_tid;
        }
 
        /* lookup an existing session */
@@ -326,6 +315,7 @@ NTSTATUS smbd_smb2_request_check_tcon(struct smbd_smb2_request *req)
        }
 
        req->tcon = tcon;
+       req->last_tid = in_tid;
 
        return NT_STATUS_OK;
 }