The branch, master has been updated
       via  1b487ad s3:selftest: add some tests against a share the requires 
encryption
       via  45471f4 s3:smb2_negprot: annouce/negotiate SMB3 encryption support
       via  9397d67 s3:smb2_server: add SMB3 encryption support
       via  9f1dfd8 s3:smbd: don't disconnect the client when a share has "smb 
encrypt = required"
       via  e5d4e8d s3:smbd: lp_smb_encrypt() returns SMB_SIGNING_* values
       via  8b3da9a s3:smbd: make use of ENCRYPTION_REQUIRED()
       via  abf018e libcli/smb: make sure the SMB2_TRANSFORM pdu is complete
       via  e2b07c0 s4:libcli/smb2: reset trsnport->compound.related when a 
compound chain is finished
      from  6ce362a build: Ensure -Werror=format works with -Wformat=2 on NULL 
format strings

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 1b487ad3d7f709b0a100ccdc6fc30dcf7d0b778c
Author: Stefan Metzmacher <me...@samba.org>
Date:   Fri Aug 17 08:50:21 2012 +0200

    s3:selftest: add some tests against a share the requires encryption
    
    metze
    
    Autobuild-User(master): Stefan Metzmacher <me...@samba.org>
    Autobuild-Date(master): Fri Aug 17 16:34:26 CEST 2012 on sn-devel-104

commit 45471f4d8f80d80c01197536bcf47d932dcd38e0
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Aug 8 07:07:53 2012 +0200

    s3:smb2_negprot: annouce/negotiate SMB3 encryption support
    
    metze

commit 9397d6709f79f2e8837401d32cd7ac584b6c5b24
Author: Stefan Metzmacher <me...@samba.org>
Date:   Wed Aug 8 07:07:03 2012 +0200

    s3:smb2_server: add SMB3 encryption support
    
    metze

commit 9f1dfd8facaa59370afd93e89cc729de5cc3d9ba
Author: Stefan Metzmacher <me...@samba.org>
Date:   Fri Aug 17 09:42:27 2012 +0200

    s3:smbd: don't disconnect the client when a share has "smb encrypt = 
required"
    
    It's not the client fault, if he doesn't know that encryption is required.
    We should just return ACCESS_DENIED and let the client work on other
    shares and open files on the current SMB connection.
    
    metze

commit e5d4e8df6b8186b71aa72dd7817f5579b44fee2f
Author: Stefan Metzmacher <me...@samba.org>
Date:   Fri Aug 17 09:40:52 2012 +0200

    s3:smbd: lp_smb_encrypt() returns SMB_SIGNING_* values
    
    metze

commit 8b3da9a1f400040eef14b63ed0b7884a9e82d907
Author: Stefan Metzmacher <me...@samba.org>
Date:   Fri Aug 17 09:41:42 2012 +0200

    s3:smbd: make use of ENCRYPTION_REQUIRED()
    
    metze

commit abf018e8b64b237aa029978c20bd418524fff3d0
Author: Stefan Metzmacher <me...@samba.org>
Date:   Fri Aug 17 08:31:52 2012 +0200

    libcli/smb: make sure the SMB2_TRANSFORM pdu is complete
    
    metze

commit e2b07c0adca680d73f20744fd8dbbcb8be818ca3
Author: Stefan Metzmacher <me...@samba.org>
Date:   Fri Aug 17 08:25:08 2012 +0200

    s4:libcli/smb2: reset trsnport->compound.related when a compound chain is 
finished
    
    metze

-----------------------------------------------------------------------

Summary of changes:
 libcli/smb/smbXcli_base.c       |   15 ++-
 selftest/knownfail              |    5 +
 selftest/target/Samba3.pm       |    4 +
 selftest/target/Samba4.pm       |    4 +
 source3/include/smb_macros.h    |    2 +-
 source3/param/loadparm.c        |    2 +-
 source3/selftest/tests.py       |    9 +-
 source3/smbd/globals.h          |   52 ++++--
 source3/smbd/process.c          |   10 +-
 source3/smbd/smb2_negprot.c     |    8 +
 source3/smbd/smb2_server.c      |  350 +++++++++++++++++++++++++++++++++++----
 source3/smbd/trans2.c           |   20 +--
 source4/libcli/smb2/transport.c |    1 +
 13 files changed, 412 insertions(+), 70 deletions(-)


Changeset truncated at 500 lines:

diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c
index a9adcbb..02d0227 100644
--- a/libcli/smb/smbXcli_base.c
+++ b/libcli/smb/smbXcli_base.c
@@ -3041,6 +3041,7 @@ static NTSTATUS smb2cli_inbuf_parse_compound(struct 
smbXcli_conn *conn,
                        struct smbXcli_session *s;
                        uint64_t uid;
                        struct iovec tf_iov[2];
+                       size_t enc_len;
                        NTSTATUS status;
 
                        if (len < SMB2_TF_HDR_SIZE) {
@@ -3053,9 +3054,16 @@ static NTSTATUS smb2cli_inbuf_parse_compound(struct 
smbXcli_conn *conn,
                        taken += tf_len;
 
                        hdr = first_hdr + taken;
-                       len = IVAL(tf, SMB2_TF_MSG_SIZE);
+                       enc_len = IVAL(tf, SMB2_TF_MSG_SIZE);
                        uid = BVAL(tf, SMB2_TF_SESSION_ID);
 
+                       if (len < SMB2_TF_HDR_SIZE + enc_len) {
+                               DEBUG(10, ("%d bytes left, expected at least 
%d\n",
+                                          (int)len,
+                                          (int)(SMB2_TF_HDR_SIZE + enc_len)));
+                               goto inval;
+                       }
+
                        s = conn->sessions;
                        for (; s; s = s->next) {
                                if (s->smb2->session_id != uid) {
@@ -3073,7 +3081,7 @@ static NTSTATUS smb2cli_inbuf_parse_compound(struct 
smbXcli_conn *conn,
                        tf_iov[0].iov_base = (void *)tf;
                        tf_iov[0].iov_len = tf_len;
                        tf_iov[1].iov_base = (void *)hdr;
-                       tf_iov[1].iov_len = len;
+                       tf_iov[1].iov_len = enc_len;
 
                        status = 
smb2_signing_decrypt_pdu(s->smb2->decryption_key,
                                                          conn->protocol,
@@ -3083,7 +3091,8 @@ static NTSTATUS smb2cli_inbuf_parse_compound(struct 
smbXcli_conn *conn,
                                return status;
                        }
 
-                       verified_buflen = taken + len;
+                       verified_buflen = taken + enc_len;
+                       len = enc_len;
                }
 
                /*
diff --git a/selftest/knownfail b/selftest/knownfail
index da3d93c..9376264 100644
--- a/selftest/knownfail
+++ b/selftest/knownfail
@@ -21,6 +21,11 @@
 ^samba3.smbtorture_s3.plain\(dc\).BAD-NBT-SESSION # Fails against the s4 ntvfs 
server
 ^samba3.smbtorture_s3.plain\(dc\).SMB2-SESSION-REAUTH # Fails against the s4 
ntvfs server
 ^samba3.smbtorture_s3.plain\(dc\).SMB2-SESSION-RECONNECT # Fails against the 
s4 ntvfs server
+ ^samba3.smbtorture_s3.crypt_server\(s3dc\).SMB2-SESSION-REAUTH # expected to 
give ACCESS_DENIED SMB2.1 doesn't have encryption
+^samba3.smbtorture_s3.crypt_server\(s3dc\).SMB2-SESSION-RECONNECT # expected 
to give CONNECTION_DISCONNECTED, we need to fix the test
+^samba3.smb2.session enc.reconnect # expected to give CONNECTION_DISCONNECTED, 
we need to fix the test
+^samba3.raw.session enc # expected to give ACCESS_DENIED as SMB1 encryption 
isn't used
+^samba3.smbtorture_s3.crypt_server # expected to give ACCESS_DENIED as SMB1 
encryption isn't used
 ^samba3.nbt.dgram.*netlogon2\(s3dc\)
 ^samba3.*rap.sam.*.useradd # Not provided by Samba 3
 ^samba3.*rap.sam.*.userdelete # Not provided by Samba 3
diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
index 149a31e..72b9c19 100755
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -939,6 +939,10 @@ sub provision($$$$$$)
 [tmp]
        path = $shrdir
         comment = smb username is [%U]
+[tmpenc]
+       path = $shrdir
+       comment = encrypt smb username is [%U]
+       smb encrypt = required
 [tmpguest]
        path = $shrdir
         guest ok = yes
diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
index b1998a6..17afab2 100644
--- a/selftest/target/Samba4.pm
+++ b/selftest/target/Samba4.pm
@@ -1385,6 +1385,10 @@ sub provision_plugin_s4_dc($$)
 
        my $extra_smbconf_shares = "
 
+[tmpenc]
+       copy = tmp
+       smb encrypt = required
+
 [tmpcase]
        copy = tmp
        case sensitive = yes
diff --git a/source3/include/smb_macros.h b/source3/include/smb_macros.h
index 73f8fb3..8b9d941 100644
--- a/source3/include/smb_macros.h
+++ b/source3/include/smb_macros.h
@@ -139,7 +139,7 @@
 #define smb_len_large(buf) smb_len_tcp(buf)
 #define _smb_setlen_large(buf, len) _smb_setlen_tcp(buf, len)
 
-#define ENCRYPTION_REQUIRED(conn) ((conn) ? ((conn)->encrypt_level == 
Required) : false)
+#define ENCRYPTION_REQUIRED(conn) ((conn) ? ((conn)->encrypt_level == 
SMB_SIGNING_REQUIRED) : false)
 #define IS_CONN_ENCRYPTED(conn) ((conn) ? (conn)->encrypted_tid : false)
 
 /****************************************************************************
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index d7141ae..bce1c5b 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -281,7 +281,7 @@ static struct loadparm_service sDefault =
 #else
        .iDirectoryNameCacheSize = 100,
 #endif
-       .ismb_encrypt = Auto,
+       .ismb_encrypt = SMB_SIGNING_DEFAULT,
        .param_opt = NULL,
        .dummy = ""
 };
diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py
index 00ecd6c..f9f2e22 100755
--- a/source3/selftest/tests.py
+++ b/source3/selftest/tests.py
@@ -95,7 +95,11 @@ tests=[ "FDPASS", "LOCK1", "LOCK2", "LOCK3", "LOCK4", 
"LOCK5", "LOCK6", "LOCK7",
 
 for t in tests:
     plantestsuite("samba3.smbtorture_s3.plain(s3dc).%s" % t, "s3dc", 
[os.path.join(samba3srcdir, "script/tests/test_smbtorture_s3.sh"), t, 
'//$SERVER_IP/tmp', '$USERNAME', '$PASSWORD', smbtorture3, "", "-l 
$LOCAL_PATH"])
-    plantestsuite("samba3.smbtorture_s3.crypt(s3dc).%s" % t, "s3dc", 
[os.path.join(samba3srcdir, "script/tests/test_smbtorture_s3.sh"), t, 
'//$SERVER_IP/tmp', '$USERNAME', '$PASSWORD', smbtorture3, "-e", "-l 
$LOCAL_PATH"])
+    plantestsuite("samba3.smbtorture_s3.crypt_client(s3dc).%s" % t, "s3dc", 
[os.path.join(samba3srcdir, "script/tests/test_smbtorture_s3.sh"), t, 
'//$SERVER_IP/tmp', '$USERNAME', '$PASSWORD', smbtorture3, "-e", "-l 
$LOCAL_PATH"])
+    if t == "TORTURE":
+        # this is a negative test to verify that the server rejects
+        # access without encryption
+        plantestsuite("samba3.smbtorture_s3.crypt_server(s3dc).%s" % t, 
"s3dc", [os.path.join(samba3srcdir, "script/tests/test_smbtorture_s3.sh"), t, 
'//$SERVER_IP/tmpenc', '$USERNAME', '$PASSWORD', smbtorture3, "", "-l 
$LOCAL_PATH"])
     plantestsuite("samba3.smbtorture_s3.plain(dc).%s" % t, "dc", 
[os.path.join(samba3srcdir, "script/tests/test_smbtorture_s3.sh"), t, 
'//$SERVER_IP/tmp', '$USERNAME', '$PASSWORD', smbtorture3, "", "-l 
$LOCAL_PATH"])
 
 posix_tests=[ "POSIX", "POSIX-APPEND"]
@@ -333,7 +337,8 @@ for t in tests:
         plansmbtorturetestsuite(t, "secshare", '//$SERVER_IP/tmp 
-U$USERNAME%$PASSWORD')
         plansmbtorturetestsuite(t, "plugin_s4_dc", '//$SERVER/tmp 
-U$USERNAME%$PASSWORD')
     elif t == "raw.session" or t == "smb2.session":
-        plansmbtorturetestsuite(t, "s3dc", '//$SERVER_IP/tmp 
-U$USERNAME%$PASSWORD')
+        plansmbtorturetestsuite(t, "s3dc", '//$SERVER_IP/tmp 
-U$USERNAME%$PASSWORD', 'plain')
+        plansmbtorturetestsuite(t, "s3dc", '//$SERVER_IP/tmpenc 
-U$USERNAME%$PASSWORD', 'enc')
         plansmbtorturetestsuite(t, "plugin_s4_dc", '//$SERVER/tmp -k no 
-U$USERNAME%$PASSWORD', 'ntlm')
         plansmbtorturetestsuite(t, "plugin_s4_dc", '//$SERVER/tmp -k yes 
-U$USERNAME%$PASSWORD', 'krb5')
     elif t == "rpc.lsa":
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index ac8a1b2..b024fb3 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -462,7 +462,12 @@ struct smbd_smb2_request {
        bool compound_related;
 
        /*
-        * the signing/encryption key for the last
+        * the encryption key for the whole
+        * compound chain
+        */
+       DATA_BLOB first_key;
+       /*
+        * the signing key for the last
         * request/response of a compound chain
         */
        DATA_BLOB last_key;
@@ -481,15 +486,18 @@ struct smbd_smb2_request {
         */
        struct tevent_req *subreq;
 
-#define SMBD_SMB2_HDR_IOV_OFS 0
-#define SMBD_SMB2_BODY_IOV_OFS 1
-#define SMBD_SMB2_DYN_IOV_OFS 2
+#define SMBD_SMB2_TF_IOV_OFS 0
+#define SMBD_SMB2_HDR_IOV_OFS 1
+#define SMBD_SMB2_BODY_IOV_OFS 2
+#define SMBD_SMB2_DYN_IOV_OFS 3
 
-#define SMBD_SMB2_NUM_IOV_PER_REQ 3
+#define SMBD_SMB2_NUM_IOV_PER_REQ 4
 
 #define SMBD_SMB2_IOV_IDX_OFS(req,dir,idx,ofs) \
        (&req->dir.vector[(idx)+(ofs)])
 
+#define SMBD_SMB2_IDX_TF_IOV(req,dir,idx) \
+       SMBD_SMB2_IOV_IDX_OFS(req,dir,idx,SMBD_SMB2_TF_IOV_OFS)
 #define SMBD_SMB2_IDX_HDR_IOV(req,dir,idx) \
        SMBD_SMB2_IOV_IDX_OFS(req,dir,idx,SMBD_SMB2_HDR_IOV_OFS)
 #define SMBD_SMB2_IDX_BODY_IOV(req,dir,idx) \
@@ -497,6 +505,8 @@ struct smbd_smb2_request {
 #define SMBD_SMB2_IDX_DYN_IOV(req,dir,idx) \
        SMBD_SMB2_IOV_IDX_OFS(req,dir,idx,SMBD_SMB2_DYN_IOV_OFS)
 
+#define SMBD_SMB2_IN_TF_IOV(req)    
SMBD_SMB2_IDX_TF_IOV(req,in,req->current_idx)
+#define SMBD_SMB2_IN_TF_PTR(req)    (uint8_t 
*)(SMBD_SMB2_IN_TF_IOV(req)->iov_base)
 #define SMBD_SMB2_IN_HDR_IOV(req)    
SMBD_SMB2_IDX_HDR_IOV(req,in,req->current_idx)
 #define SMBD_SMB2_IN_HDR_PTR(req)    (uint8_t 
*)(SMBD_SMB2_IN_HDR_IOV(req)->iov_base)
 #define SMBD_SMB2_IN_BODY_IOV(req)   
SMBD_SMB2_IDX_BODY_IOV(req,in,req->current_idx)
@@ -506,6 +516,8 @@ struct smbd_smb2_request {
 #define SMBD_SMB2_IN_DYN_PTR(req)    (uint8_t 
*)(SMBD_SMB2_IN_DYN_IOV(req)->iov_base)
 #define SMBD_SMB2_IN_DYN_LEN(req)    (SMBD_SMB2_IN_DYN_IOV(req)->iov_len)
 
+#define SMBD_SMB2_OUT_TF_IOV(req)   
SMBD_SMB2_IDX_TF_IOV(req,out,req->current_idx)
+#define SMBD_SMB2_OUT_TF_PTR(req)   (uint8_t 
*)(SMBD_SMB2_OUT_TF_IOV(req)->iov_base)
 #define SMBD_SMB2_OUT_HDR_IOV(req)   
SMBD_SMB2_IDX_HDR_IOV(req,out,req->current_idx)
 #define SMBD_SMB2_OUT_HDR_PTR(req)   (uint8_t 
*)(SMBD_SMB2_OUT_HDR_IOV(req)->iov_base)
 #define SMBD_SMB2_OUT_BODY_IOV(req)  
SMBD_SMB2_IDX_BODY_IOV(req,out,req->current_idx)
@@ -517,17 +529,19 @@ struct smbd_smb2_request {
 
        struct {
                /*
-                * vector[0] TRANSPORT HEADER
+                * vector[0] TRANSPORT HEADER (empty)
                 * .
-                * vector[1] SMB2
-                * vector[2] fixed body
-                * vector[3] dynamic body
+                * vector[1] SMB2_TRANSFORM (optional)
+                * vector[2] SMB2
+                * vector[3] fixed body
+                * vector[4] dynamic body
                 * .
                 * .
                 * .
-                * vector[4] SMB2
-                * vector[5] fixed body
-                * vector[6] dynamic body
+                * vector[5] SMB2_TRANSFORM (optional)
+                * vector[6] SMB2
+                * vector[7] fixed body
+                * vector[8] dynamic body
                 * .
                 * .
                 * .
@@ -541,15 +555,17 @@ struct smbd_smb2_request {
                /*
                 * vector[0] TRANSPORT HEADER
                 * .
-                * vector[1] SMB2
-                * vector[2] fixed body
-                * vector[3] dynamic body
+                * vector[1] SMB2_TRANSFORM (optional)
+                * vector[2] SMB2
+                * vector[3] fixed body
+                * vector[4] dynamic body
                 * .
                 * .
                 * .
-                * vector[4] SMB2
-                * vector[5] fixed body
-                * vector[6] dynamic body
+                * vector[5] SMB2_TRANSFORM (empty)
+                * vector[6] SMB2
+                * vector[7] fixed body
+                * vector[8] dynamic body
                 * .
                 * .
                 * .
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index dd26a27..fd2c6a4 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -1492,11 +1492,15 @@ static connection_struct *switch_message(uint8 type, 
struct smb_request *req)
                if (req->encrypted) {
                        conn->encrypted_tid = true;
                        /* encrypted required from now on. */
-                       conn->encrypt_level = Required;
+                       conn->encrypt_level = SMB_SIGNING_REQUIRED;
                } else if (ENCRYPTION_REQUIRED(conn)) {
                        if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
-                               exit_server_cleanly("encryption required "
-                                       "on connection");
+                               DEBUG(1,("service[%s] requires encryption"
+                                       "%s ACCESS_DENIED. mid=%llu\n",
+                                       lp_servicename(talloc_tos(), 
SNUM(conn)),
+                                       smb_fn_name(type),
+                                       (unsigned long long)req->mid));
+                               reply_nterror(req, NT_STATUS_ACCESS_DENIED);
                                return conn;
                        }
                }
diff --git a/source3/smbd/smb2_negprot.c b/source3/smbd/smb2_negprot.c
index d086566..11ec2a5 100644
--- a/source3/smbd/smb2_negprot.c
+++ b/source3/smbd/smb2_negprot.c
@@ -254,6 +254,14 @@ NTSTATUS smbd_smb2_request_process_negprot(struct 
smbd_smb2_request *req)
                capabilities |= SMB2_CAP_DFS;
        }
 
+       if ((protocol >= PROTOCOL_SMB2_24) &&
+           (lp_smb_encrypt(-1) != SMB_SIGNING_OFF))
+       {
+               if (in_capabilities & SMB2_CAP_ENCRYPTION) {
+                       capabilities |= SMB2_CAP_ENCRYPTION;
+               }
+       }
+
        /*
         * 0x10000 (65536) is the maximum allowed message size
         * for SMB 2.0
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index ff4ee60..106e6ac 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -256,6 +256,7 @@ static void smb2_setup_nbt_length(struct iovec *vector, int 
count)
 
 static int smbd_smb2_request_destructor(struct smbd_smb2_request *req)
 {
+       data_blob_clear_free(&req->first_key);
        data_blob_clear_free(&req->last_key);
        return 0;
 }
@@ -303,6 +304,9 @@ static NTSTATUS smbd_smb2_inbuf_parse_compound(struct 
smbXsrv_connection *conn,
        int num_iov = 1;
        size_t taken = 0;
        uint8_t *first_hdr = buf;
+       size_t verified_buflen = 0;
+       uint8_t *tf = NULL;
+       size_t tf_len = 0;
 
        /*
         * Note: index '0' is reserved for the transport protocol
@@ -324,6 +328,87 @@ static NTSTATUS smbd_smb2_inbuf_parse_compound(struct 
smbXsrv_connection *conn,
                uint8_t *dyn = NULL;
                struct iovec *iov_tmp;
 
+               if (verified_buflen > taken) {
+                       len = verified_buflen - taken;
+               } else {
+                       tf = NULL;
+                       tf_len = 0;
+               }
+
+               if (len < 4) {
+                       DEBUG(10, ("%d bytes left, expected at least %d\n",
+                                  (int)len, 4));
+                       goto inval;
+               }
+               if (IVAL(hdr, 0) == SMB2_TF_MAGIC) {
+                       struct smbXsrv_session *s = NULL;
+                       uint64_t uid;
+                       struct iovec tf_iov[2];
+                       NTSTATUS status;
+                       size_t enc_len;
+
+                       if (conn->protocol < PROTOCOL_SMB2_24) {
+                               DEBUG(10, ("Got SMB2_TRANSFORM header, "
+                                          "but dialect[0x%04X] is used\n",
+                                          conn->smb2.server.dialect));
+                               goto inval;
+                       }
+
+                       if (!(conn->smb2.server.capabilities & 
SMB2_CAP_ENCRYPTION)) {
+                               DEBUG(10, ("Got SMB2_TRANSFORM header, "
+                                          "but not negotiated "
+                                          "client[0x%08X] server[0x%08X]\n",
+                                          conn->smb2.client.capabilities,
+                                          conn->smb2.server.capabilities));
+                               goto inval;
+                       }
+
+                       if (len < SMB2_TF_HDR_SIZE) {
+                               DEBUG(1, ("%d bytes left, expected at least 
%d\n",
+                                          (int)len, SMB2_TF_HDR_SIZE));
+                               goto inval;
+                       }
+                       tf = hdr;
+                       tf_len = SMB2_TF_HDR_SIZE;
+                       taken += tf_len;
+
+                       hdr = first_hdr + taken;
+                       enc_len = IVAL(tf, SMB2_TF_MSG_SIZE);
+                       uid = BVAL(tf, SMB2_TF_SESSION_ID);
+
+                       if (len < SMB2_TF_HDR_SIZE + enc_len) {
+                               DEBUG(1, ("%d bytes left, expected at least 
%d\n",
+                                          (int)len,
+                                          (int)(SMB2_TF_HDR_SIZE + enc_len)));
+                               goto inval;
+                       }
+
+                       status = smb2srv_session_lookup(conn, uid, now, &s);
+                       if (s == NULL) {
+                               DEBUG(1, ("invalid session[%llu] in "
+                                         "SMB2_TRANSFORM header\n",
+                                          (unsigned long long)uid));
+                               TALLOC_FREE(iov);
+                               return NT_STATUS_USER_SESSION_DELETED;
+                       }
+
+                       tf_iov[0].iov_base = (void *)tf;
+                       tf_iov[0].iov_len = tf_len;
+                       tf_iov[1].iov_base = (void *)hdr;
+                       tf_iov[1].iov_len = enc_len;
+
+                       status = 
smb2_signing_decrypt_pdu(s->global->decryption_key,
+                                                         conn->protocol,
+                                                         tf_iov, 2);
+                       if (!NT_STATUS_IS_OK(status)) {
+                               TALLOC_FREE(iov);
+                               return status;
+                       }
+
+                       verified_buflen = taken + enc_len;
+                       len = enc_len;
+               }
+
                /*
                 * We need the header plus the body length field
                 */
@@ -382,6 +467,8 @@ static NTSTATUS smbd_smb2_inbuf_parse_compound(struct 
smbXsrv_connection *conn,
                cur = &iov[num_iov];
                num_iov += SMBD_SMB2_NUM_IOV_PER_REQ;
 
+               cur[SMBD_SMB2_TF_IOV_OFS].iov_base   = tf;
+               cur[SMBD_SMB2_TF_IOV_OFS].iov_len    = tf_len;
                cur[SMBD_SMB2_HDR_IOV_OFS].iov_base  = hdr;
                cur[SMBD_SMB2_HDR_IOV_OFS].iov_len   = SMB2_HDR_BODY;
                cur[SMBD_SMB2_BODY_IOV_OFS].iov_base = body;
@@ -891,6 +978,12 @@ static NTSTATUS smbd_smb2_request_setup_out(struct 
smbd_smb2_request *req)
 
                outbody = outhdr + SMB2_HDR_BODY;
 
+               /*
+                * SMBD_SMB2_TF_IOV_OFS might be used later
+                */
+               current[SMBD_SMB2_TF_IOV_OFS].iov_base   = NULL;
+               current[SMBD_SMB2_TF_IOV_OFS].iov_len    = 0;
+
                current[SMBD_SMB2_HDR_IOV_OFS].iov_base  = (void *)outhdr;
                current[SMBD_SMB2_HDR_IOV_OFS].iov_len   = SMB2_HDR_BODY;
 
@@ -949,10 +1042,12 @@ void smbd_server_connection_terminate_ex(struct 
smbd_server_connection *sconn,
        exit_server_cleanly(reason);
 }
 
-static bool dup_smb2_vec3(TALLOC_CTX *ctx,
+static bool dup_smb2_vec4(TALLOC_CTX *ctx,
                        struct iovec *outvec,
                        const struct iovec *srcvec)
 {
+       const uint8_t *srctf;
+       size_t srctf_len;
        const uint8_t *srchdr;
        size_t srchdr_len;
        const uint8_t *srcbody;
@@ -961,10 +1056,13 @@ static bool dup_smb2_vec3(TALLOC_CTX *ctx,
        const uint8_t *srcdyn;
        size_t srcdyn_len;
        const uint8_t *expected_srcdyn;
+       uint8_t *dsttf;
        uint8_t *dsthdr;
        uint8_t *dstbody;
        uint8_t *dstdyn;
 
+       srctf  = (const uint8_t *)srcvec[SMBD_SMB2_TF_IOV_OFS].iov_base;
+       srctf_len = srcvec[SMBD_SMB2_TF_IOV_OFS].iov_len;
        srchdr  = (const uint8_t *)srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_base;
        srchdr_len = srcvec[SMBD_SMB2_HDR_IOV_OFS].iov_len;
        srcbody = (const uint8_t *)srcvec[SMBD_SMB2_BODY_IOV_OFS].iov_base;
@@ -974,10 +1072,25 @@ static bool dup_smb2_vec3(TALLOC_CTX *ctx,
        srcdyn_len = srcvec[SMBD_SMB2_DYN_IOV_OFS].iov_len;
        expected_srcdyn = srcbody + 8;
 
+       if ((srctf_len != SMB2_TF_HDR_SIZE) && (srctf_len != 0)) {
+               return false;
+       }
+
        if (srchdr_len != SMB2_HDR_BODY) {
                return false;
        }
 
+       if (srctf_len == SMB2_TF_HDR_SIZE) {
+               dsttf = talloc_memdup(ctx, srctf, SMB2_TF_HDR_SIZE);
+               if (dsttf == NULL) {
+                       return false;
+               }
+       } else {
+               dsttf = NULL;
+       }
+       outvec[SMBD_SMB2_TF_IOV_OFS].iov_base = (void *)dsttf;
+       outvec[SMBD_SMB2_TF_IOV_OFS].iov_len = srctf_len;
+
        /* vec[SMBD_SMB2_HDR_IOV_OFS] is always boilerplate and must
         * be allocated with size OUTVEC_ALLOC_SIZE. */
 
@@ -1061,7 +1174,7 @@ static struct smbd_smb2_request *dup_smb2_req(const 
struct smbd_smb2_request *re
 
        /* Setup the vectors identically to the ones in req. */
        for (i = 1; i < count; i += SMBD_SMB2_NUM_IOV_PER_REQ) {
-               if (!dup_smb2_vec3(outvec, &outvec[i], &req->out.vector[i])) {
+               if (!dup_smb2_vec4(outvec, &outvec[i], &req->out.vector[i])) {
                        break;
                }
        }
@@ -1083,6 +1196,8 @@ static void smbd_smb2_request_writev_done(struct 
tevent_req *subreq);
 static NTSTATUS smb2_send_async_interim_response(const struct 
smbd_smb2_request *req)
 {
        struct smbXsrv_connection *conn = req->sconn->conn;
+       int first_idx = 1;


-- 
Samba Shared Repository

Reply via email to