s3:smbd: allow GetInfo responses with STATUS_BUFFER_OVERFLOW to return partial, but...
authorRalph Wuerthner <ralph.wuerthner@de.ibm.com>
Fri, 5 Jul 2013 09:03:16 +0000 (11:03 +0200)
committerKarolin Seeger <kseeger@samba.org>
Fri, 6 Sep 2013 08:49:49 +0000 (10:49 +0200)
Reviewed-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Volker Lendecke <Volker.Lendecke@SerNet.DE>
(cherry picked from commit a91d2b05bab329a8a9772c2c79a3b1e02933182e)

source3/smbd/smb2_getinfo.c

index 30daaadd302cc7c2ea3aa7fbdf7ddaac09550357..2a74f3056a1d71dab6e0dcf354fbd5cd2795b76d 100644 (file)
@@ -148,7 +148,10 @@ static void smbd_smb2_request_getinfo_done(struct tevent_req *subreq)
                return;
        }
 
-       if (!NT_STATUS_IS_OK(call_status)) {
+       /* some GetInfo responses set STATUS_BUFFER_OVERFLOW and return partial,
+          but valid data */
+       if (!(NT_STATUS_IS_OK(call_status) ||
+             NT_STATUS_EQUAL(call_status, STATUS_BUFFER_OVERFLOW))) {
                /* Return a specific error with data. */
                error = smbd_smb2_request_error_ex(req,
                                                call_status,
@@ -185,7 +188,7 @@ static void smbd_smb2_request_getinfo_done(struct tevent_req *subreq)
 
        outdyn = out_output_buffer;
 
-       error = smbd_smb2_request_done(req, outbody, &outdyn);
+       error = smbd_smb2_request_done_ex(req, call_status, outbody, &outdyn, __location__);
        if (!NT_STATUS_IS_OK(error)) {
                smbd_server_connection_terminate(req->sconn,
                                                 nt_errstr(error));
@@ -407,7 +410,10 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx,
                                         fsp->fsp_name,
                                         &data,
                                         &data_size);
-               if (!NT_STATUS_IS_OK(status)) {
+               /* some responses set STATUS_BUFFER_OVERFLOW and return
+                  partial, but valid data */
+               if (!(NT_STATUS_IS_OK(status) ||
+                     NT_STATUS_EQUAL(status, STATUS_BUFFER_OVERFLOW))) {
                        SAFE_FREE(data);
                        if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_LEVEL)) {
                                status = NT_STATUS_INVALID_INFO_CLASS;
@@ -490,6 +496,7 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx,
                return tevent_req_post(req, ev);
        }
 
+       state->status = status;
        tevent_req_done(req);
        return tevent_req_post(req, ev);
 }