On compound requests, MS-SMB2 says clients MAY use 0xFFFFFFFF for compound tid and...
authorJeremy Allison <jra@samba.org>
Wed, 7 Apr 2010 17:32:01 +0000 (10:32 -0700)
committerJeremy Allison <jra@samba.org>
Wed, 7 Apr 2010 17:32:01 +0000 (10:32 -0700)
Jeremy.

source3/smbd/smb2_sesssetup.c
source3/smbd/smb2_tcon.c

index 0df4bd6c564fff5e0415f7398e6b2b4d1d1e0cfe..b3ea3fae9f892c77e1d9ce87a8e2313522146c3e 100644 (file)
@@ -338,15 +338,29 @@ static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *req,
 NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req)
 {
        const uint8_t *inhdr;
+       const uint8_t *outhdr;
        int i = req->current_idx;
        uint64_t in_session_id;
        void *p;
        struct smbd_smb2_session *session;
+       bool chained_fixup = false;
 
        inhdr = (const uint8_t *)req->in.vector[i+0].iov_base;
 
        in_session_id = BVAL(inhdr, SMB2_HDR_SESSION_ID);
 
+       if (i > 2 && in_session_id == (0xFFFFFFFFFFFFFFFFLL)) {
+               /*
+                * Chained request - fill in session_id from
+                * the previous request out.vector[].iov_base.
+                * We can't modify the inhdr here as we have
+                * yet to check signing.
+                */
+               outhdr = (const uint8_t *)req->out.vector[i-3].iov_base;
+               in_session_id = BVAL(outhdr, SMB2_HDR_SESSION_ID);
+               chained_fixup = true;
+       }
+
        /* lookup an existing session */
        p = idr_find(req->sconn->smb2.sessions.idtree, in_session_id);
        if (p == NULL) {
@@ -363,6 +377,12 @@ NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req)
                              pdb_get_domain(session->server_info->sam_account));
 
        req->session = session;
+
+       if (chained_fixup) {
+               /* Fix up our own outhdr. */
+               outhdr = (const uint8_t *)req->out.vector[i].iov_base;
+               SBVAL(outhdr, SMB2_HDR_SESSION_ID, in_session_id);
+       }
        return NT_STATUS_OK;
 }
 
index bd33007c18a58715c9a1a2d7e346de19173795d4..3eb9da29a02ce1483e92ac203a5d28b2ad656e1b 100644 (file)
@@ -220,15 +220,27 @@ 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_tid;
        void *p;
        struct smbd_smb2_tcon *tcon;
+       bool chained_fixup = false;
 
        inhdr = (const uint8_t *)req->in.vector[i+0].iov_base;
 
        in_tid = IVAL(inhdr, SMB2_HDR_TID);
 
+       if (i > 2 && in_tid == (0xFFFFFFFF)) {
+               /*
+                * 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);
+                chained_fixup = true;
+        }
+
        /* lookup an existing session */
        p = idr_find(req->session->tcons.idtree, in_tid);
        if (p == NULL) {
@@ -246,6 +258,13 @@ NTSTATUS smbd_smb2_request_check_tcon(struct smbd_smb2_request *req)
        }
 
        req->tcon = tcon;
+
+       if (chained_fixup) {
+               /* Fix up our own outhdr. */
+               outhdr = (const uint8_t *)req->out.vector[i].iov_base;
+               SIVAL(outhdr, SMB2_HDR_TID, in_tid);
+       }
+
        return NT_STATUS_OK;
 }