r1165: fixed handling of SMBtrans replies that should return STATUS_BUFFER_OVERFLOW...
authorAndrew Tridgell <tridge@samba.org>
Wed, 16 Jun 2004 06:49:24 +0000 (06:49 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:56:42 +0000 (12:56 -0500)
source/ntvfs/ipc/vfs_ipc.c
source/rpc_server/dcerpc_server.c
source/rpc_server/dcerpc_tcp.c
source/smb_server/request.c
source/smb_server/trans2.c

index 9279e0e85a17c255dcf22fbd1d30afdc99c2ec09..5b61c9285e75d4a867e33e2e86c0ad7d8d5a3ca7 100644 (file)
@@ -401,7 +401,7 @@ static NTSTATUS ipc_read(struct request_context *req, union smb_read *rd)
        }
 
        status = dcesrv_output_blob(p->dce_conn, &data);
-       if (!NT_STATUS_IS_OK(status)) {
+       if (NT_STATUS_IS_ERR(status)) {
                return status;
        }
 
@@ -418,7 +418,7 @@ static NTSTATUS ipc_read(struct request_context *req, union smb_read *rd)
                return NT_STATUS_NOT_SUPPORTED;
        }
 
-       return NT_STATUS_OK;
+       return status;
 }
 
 /*
@@ -624,7 +624,7 @@ static NTSTATUS ipc_dcerpc_cmd(struct request_context *req, struct smb_trans2 *t
          the error is encoded at the dcerpc level
        */
        status = dcesrv_output_blob(p->dce_conn, &trans->out.data);
-       if (!NT_STATUS_IS_OK(status)) {
+       if (NT_STATUS_IS_ERR(status)) {
                return status;
        }
 
@@ -632,7 +632,7 @@ static NTSTATUS ipc_dcerpc_cmd(struct request_context *req, struct smb_trans2 *t
        trans->out.setup = NULL;
        trans->out.params = data_blob(NULL, 0);
 
-       return NT_STATUS_OK;
+       return status;
 }
 
 
index d5d291dab55ce2f328e5dd2596521f85af0b87dd..b6584f812f5068c98c5fa53ac6f664536ea57cc1 100644 (file)
@@ -902,6 +902,9 @@ NTSTATUS dcesrv_input(struct dcesrv_connection *dce_conn, const DATA_BLOB *data)
   will be the number of bytes to be sent.
 
   write_fn() should return the number of bytes successfully written.
+
+  this will return STATUS_BUFFER_OVERFLOW if there is more to be read
+  from the current fragment
 */
 NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn, 
                       void *private,
@@ -910,6 +913,7 @@ NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn,
        struct dcesrv_call_state *call;
        struct dcesrv_call_reply *rep;
        ssize_t nwritten;
+       NTSTATUS status = NT_STATUS_OK;
 
        call = dce_conn->call_list;
        if (!call || !call->replies) {
@@ -930,6 +934,8 @@ NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn,
        if (rep->data.length == 0) {
                /* we're done with this section of the call */
                DLIST_REMOVE(call->replies, rep);
+       } else {
+               status = STATUS_BUFFER_OVERFLOW;
        }
 
        if (call->replies == NULL) {
@@ -938,7 +944,7 @@ NTSTATUS dcesrv_output(struct dcesrv_connection *dce_conn,
                talloc_destroy(call->mem_ctx);
        }
 
-       return NT_STATUS_OK;
+       return status;
 }
 
 
index 81f1631c19d27b1fb82259e63ca77203abb83dfe..83a9140dd162401b2f9ed07e38227f10f11162d2 100644 (file)
@@ -79,7 +79,7 @@ static void dcerpc_write_handler(struct event_context *ev, struct fd_event *fde,
        NTSTATUS status;
 
        status = dcesrv_output(r->dce_conn, fde, dcerpc_write_fn);
-       if (!NT_STATUS_IS_OK(status)) {
+       if (NT_STATUS_IS_ERR(status)) {
                /* TODO: destroy fd_event? */
        }
 
index b1e3b5f66e1df37ce450cac7e107a4a71067331a..8f545e8f599c593057ff586b6c3b0ed86eb2b9d1 100644 (file)
@@ -297,29 +297,23 @@ void req_reply_dos_error(struct request_context *req, uint8_t eclass, uint16_t e
 
        SCVAL(req->out.hdr, HDR_RCLS, eclass);
        SSVAL(req->out.hdr, HDR_ERR, ecode);
-
-       SSVAL(req->out.hdr, HDR_FLG2, SVAL(req->out.hdr, HDR_FLG2) & ~FLAGS2_32_BIT_ERROR_CODES);
-       
+       SSVAL(req->out.hdr, HDR_FLG2, SVAL(req->out.hdr, HDR_FLG2) & ~FLAGS2_32_BIT_ERROR_CODES);       
        req_send_reply(req);
 }
 
 /* 
-   construct and send an error packet, then destroy the request 
-   auto-converts to DOS error format when appropriate
+   setup the header of a reply to include an NTSTATUS code
 */
-void req_reply_error(struct request_context *req, NTSTATUS status)
+void req_setup_error(struct request_context *req, NTSTATUS status)
 {
-       req_setup_reply(req, 0, 0);
-
-       /* error returns never have any data */
-       req_grow_data(req, 0);
-
        if (!lp_nt_status_support() || !(req->smb->negotiate.client_caps & CAP_STATUS32)) {
                /* convert to DOS error codes */
                uint8_t eclass;
                uint32_t ecode;
                ntstatus_to_dos(status, &eclass, &ecode);
-               req_reply_dos_error(req, eclass, ecode);
+               SCVAL(req->out.hdr, HDR_RCLS, eclass);
+               SSVAL(req->out.hdr, HDR_ERR, ecode);
+               SSVAL(req->out.hdr, HDR_FLG2, SVAL(req->out.hdr, HDR_FLG2) & ~FLAGS2_32_BIT_ERROR_CODES);
                return;
        }
 
@@ -332,7 +326,20 @@ void req_reply_error(struct request_context *req, NTSTATUS status)
                SIVAL(req->out.hdr, HDR_RCLS, NT_STATUS_V(status));
                SSVAL(req->out.hdr, HDR_FLG2, SVAL(req->out.hdr, HDR_FLG2) | FLAGS2_32_BIT_ERROR_CODES);
        }
-       
+}
+
+/* 
+   construct and send an error packet, then destroy the request 
+   auto-converts to DOS error format when appropriate
+*/
+void req_reply_error(struct request_context *req, NTSTATUS status)
+{
+       req_setup_reply(req, 0, 0);
+
+       /* error returns never have any data */
+       req_grow_data(req, 0);
+
+       req_setup_error(req, status);
        req_send_reply(req);
 }
 
index b755c6dd7ccf1fdd74b7ea264148d017321bd3b2..6985e0a4d165bd787ad429db47599dbaf85e2347 100644 (file)
@@ -1307,7 +1307,7 @@ void reply_trans_generic(struct request_context *req, uint8_t command)
                status = trans2_backend(req, &trans);
        }
 
-       if (!NT_STATUS_IS_OK(status)) {
+       if (NT_STATUS_IS_ERR(status)) {
                req_reply_error(req, status);
                return;
        }
@@ -1326,6 +1326,10 @@ void reply_trans_generic(struct request_context *req, uint8_t command)
                uint_t align1 = 1, align2 = (params_left ? 2 : 0);
 
                req_setup_reply(req, 10 + trans.out.setup_count, 0);
+
+               if (!NT_STATUS_IS_OK(status)) {
+                       req_setup_error(req, status);
+               }
        
                max_bytes = req_max_data(req) - (align1 + align2);