summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2004-06-16 06:49:24 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:56:42 -0500
commitb00103dac1bf9e559e132c62e768dba9408b94eb (patch)
tree34673c3c65854992a7bc16b95e9e6d1d976b2979
parenteca6982a951b7f7051d6386a58cf35caedc84f3b (diff)
downloadsamba-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.c8
-rw-r--r--source4/rpc_server/dcerpc_server.c8
-rw-r--r--source4/rpc_server/dcerpc_tcp.c2
-rw-r--r--source4/smb_server/request.c33
-rw-r--r--source4/smb_server/trans2.c6
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);