TODO smbd: Fix bug 10839
authorVolker Lendecke <vl@samba.org>
Fri, 6 Feb 2015 15:11:13 +0000 (16:11 +0100)
committerStefan Metzmacher <metze@samba.org>
Fri, 11 Oct 2019 12:25:28 +0000 (14:25 +0200)
Signed-off-by: Volker Lendecke <vl@samba.org>
WAS: commit 65ddcda67b6c684277420e0b4af95ce1354b2af4

source3/smbd/globals.h
source3/smbd/smb2_getinfo.c
source3/smbd/smb2_negprot.c
source3/smbd/smb2_notify.c
source3/smbd/smb2_setinfo.c

index 1e4cfc1e4667768c5b63d2f3e027129ddcb3cd8b..7c5cff06a0fbd7e59b1c474b048cb2b077524f24 100644 (file)
@@ -488,6 +488,23 @@ struct smbXsrv_connection {
                         */
                        struct bitmap *bitmap;
                        bool multicredit;
+
+                       /*
+                        * See Samba bug 10839.
+                        *
+                        * According to [MS-SMB2] 3.2.4.1.5 Sending
+                        * Multi-Credit Requests:
+                        *
+                        * > For all other requests, the client MUST set
+                        * > CreditCharge to 1, even if the payload size of a
+                        * > request or the anticipated response is greater
+                        * > than 65536
+                        *
+                        * For notify, getinfo and setinfo we can only check
+                        * for 1 credit and ignore in_output_buffer_length
+                        * here.
+                        */
+                       bool ignore_broken_multicredit;
                } credits;
 
                bool allow_2ff;
index 01aedbf8e2e2e0961f0da4160e8cf731f9d68f97..de30a031c35b695121e23838ad8e12ceb191bdc1 100644 (file)
@@ -64,6 +64,7 @@ NTSTATUS smbd_smb2_request_process_getinfo(struct smbd_smb2_request *req)
        uint64_t in_file_id_volatile;
        struct files_struct *in_fsp;
        struct tevent_req *subreq;
+       uint32_t credit_charge;
 
        status = smbd_smb2_request_verify_sizes(req, 0x29);
        if (!NT_STATUS_IS_OK(status)) {
@@ -111,8 +112,16 @@ NTSTATUS smbd_smb2_request_process_getinfo(struct smbd_smb2_request *req)
                return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
        }
 
-       status = smbd_smb2_request_verify_creditcharge(req,
-                       MAX(in_input_buffer.length,in_output_buffer_length));
+       credit_charge = MAX(in_input_buffer.length, in_output_buffer_length);
+       if (xconn->smb2.credits.ignore_broken_multicredit) {
+               /*
+                * see comment in globals.h where ignore_broken_multicredit
+                * is defined
+                */
+               credit_charge = 65536;
+       }
+
+       status = smbd_smb2_request_verify_creditcharge(req, credit_charge);
        if (!NT_STATUS_IS_OK(status)) {
                return smbd_smb2_request_error(req, status);
        }
index 6e7201b1cd8270501435495bc10e969ae9a0d70d..1b513415af40855952400b6901a7919ccdad19a4 100644 (file)
@@ -647,6 +647,10 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
        xconn->smb2.server.max_read  = max_read;
        xconn->smb2.server.max_write = max_write;
 
+       xconn->smb2.credits.ignore_broken_multicredit =
+               lp_parm_bool(-1, "smbd", "ignore broken multicredit",
+                            false);
+
        if (xconn->protocol < PROTOCOL_SMB2_10) {
                /*
                 * SMB2_02 doesn't support client guids
index 68429b7b766a324f61ac45047aec6d238a81a2e7..101adc5914e938a1e6b4110f3792e73ebebcf4e1 100644 (file)
@@ -61,6 +61,7 @@ NTSTATUS smbd_smb2_request_process_notify(struct smbd_smb2_request *req)
        struct files_struct *in_fsp;
        uint64_t in_completion_filter;
        struct tevent_req *subreq;
+       uint32_t credit_charge;
 
        status = smbd_smb2_request_verify_sizes(req, 0x20);
        if (!NT_STATUS_IS_OK(status)) {
@@ -82,9 +83,16 @@ NTSTATUS smbd_smb2_request_process_notify(struct smbd_smb2_request *req)
                return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
        }
 
-       status = smbd_smb2_request_verify_creditcharge(req,
-                                               in_output_buffer_length);
+       credit_charge = in_output_buffer_length;
+       if (xconn->smb2.credits.ignore_broken_multicredit) {
+               /*
+                * see comment in globals.h where ignore_broken_multicredit
+                * is defined
+                */
+               credit_charge = 65536;
+       }
 
+       status = smbd_smb2_request_verify_creditcharge(req, credit_charge);
        if (!NT_STATUS_IS_OK(status)) {
                return smbd_smb2_request_error(req, status);
        }
index cfb49fb8d14bcc74dfc782764337c8a4e3f46540..a9dd66d515934f050320f94ca86dc1e774231cac 100644 (file)
@@ -59,6 +59,7 @@ NTSTATUS smbd_smb2_request_process_setinfo(struct smbd_smb2_request *req)
        uint64_t in_file_id_volatile;
        struct files_struct *in_fsp;
        struct tevent_req *subreq;
+       uint32_t credit_charge;
 
        status = smbd_smb2_request_verify_sizes(req, 0x21);
        if (!NT_STATUS_IS_OK(status)) {
@@ -97,8 +98,20 @@ NTSTATUS smbd_smb2_request_process_setinfo(struct smbd_smb2_request *req)
                return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
        }
 
-       status = smbd_smb2_request_verify_creditcharge(req,
-                                               in_input_buffer.length);
+       credit_charge = in_input_buffer.length;
+       if (xconn->smb2.credits.ignore_broken_multicredit) {
+               /*
+                * see comment in globals.h where ignore_broken_multicredit
+                * is defined
+                */
+               credit_charge = 65536;
+       }
+
+       status = smbd_smb2_request_verify_creditcharge(req, credit_charge);
+       if (!NT_STATUS_IS_OK(status)) {
+               return smbd_smb2_request_error(req, status);
+       }
+
        if (!NT_STATUS_IS_OK(status)) {
                return smbd_smb2_request_error(req, status);
        }