diff options
author | Andrew Tridgell <tridge@samba.org> | 2004-06-16 06:49:24 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 12:56:42 -0500 |
commit | b00103dac1bf9e559e132c62e768dba9408b94eb (patch) | |
tree | 34673c3c65854992a7bc16b95e9e6d1d976b2979 | |
parent | eca6982a951b7f7051d6386a58cf35caedc84f3b (diff) | |
download | samba-b00103dac1bf9e559e132c62e768dba9408b94eb.tar.gz samba-b00103dac1bf9e559e132c62e768dba9408b94eb.tar.bz2 samba-b00103dac1bf9e559e132c62e768dba9408b94eb.zip |
r1165: fixed handling of SMBtrans replies that should return STATUS_BUFFER_OVERFLOW when more data is present.
(This used to be commit 0e557fe85748558affd20a58455c4b75fee69e27)
-rw-r--r-- | source4/ntvfs/ipc/vfs_ipc.c | 8 | ||||
-rw-r--r-- | source4/rpc_server/dcerpc_server.c | 8 | ||||
-rw-r--r-- | source4/rpc_server/dcerpc_tcp.c | 2 | ||||
-rw-r--r-- | source4/smb_server/request.c | 33 | ||||
-rw-r--r-- | source4/smb_server/trans2.c | 6 |
5 files changed, 37 insertions, 20 deletions
diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 9279e0e85a..5b61c9285e 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -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; } diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index d5d291dab5..b6584f812f 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -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; } diff --git a/source4/rpc_server/dcerpc_tcp.c b/source4/rpc_server/dcerpc_tcp.c index 81f1631c19..83a9140dd1 100644 --- a/source4/rpc_server/dcerpc_tcp.c +++ b/source4/rpc_server/dcerpc_tcp.c @@ -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? */ } diff --git a/source4/smb_server/request.c b/source4/smb_server/request.c index b1e3b5f66e..8f545e8f59 100644 --- a/source4/smb_server/request.c +++ b/source4/smb_server/request.c @@ -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); } diff --git a/source4/smb_server/trans2.c b/source4/smb_server/trans2.c index b755c6dd7c..6985e0a4d1 100644 --- a/source4/smb_server/trans2.c +++ b/source4/smb_server/trans2.c @@ -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); |