summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2009-11-14 11:12:50 +0100
committerVolker Lendecke <vl@samba.org>2009-11-14 12:20:12 +0100
commitf4cf1c56a20916018c9a6513754b0b08c24c9d04 (patch)
tree959d0658b45497e77b0a3b9071f5c8761dff5e51
parent4a777ec4d709d2fce2378b7b4d740aa73c32e73b (diff)
downloadsamba-f4cf1c56a20916018c9a6513754b0b08c24c9d04.tar.gz
samba-f4cf1c56a20916018c9a6513754b0b08c24c9d04.tar.bz2
samba-f4cf1c56a20916018c9a6513754b0b08c24c9d04.zip
s3: Add min_setup, min_param and min_data to cli_trans_recv
Every caller that expects to receive something needs to check if enough was sent. Make this check mandatory for everyone. Yes, this makes the parameter list for cli_trans a bit silly, but that's just the way it is: A silly protocol request :-) While there, convert some _done functions to tevent_req_simple_finish_ntstatus.
-rw-r--r--source3/include/proto.h15
-rw-r--r--source3/libsmb/clifile.c113
-rw-r--r--source3/libsmb/clifsinfo.c12
-rw-r--r--source3/libsmb/clirap.c20
-rw-r--r--source3/libsmb/clisecdesc.c11
-rw-r--r--source3/libsmb/clitrans.c26
-rw-r--r--source3/rpc_client/rpc_transport_np.c4
7 files changed, 72 insertions, 129 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index d4e0ac55c5..86f6626a69 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -3040,9 +3040,12 @@ struct tevent_req *cli_trans_send(
uint8_t *param, uint32_t num_param, uint32_t max_param,
uint8_t *data, uint32_t num_data, uint32_t max_data);
NTSTATUS cli_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
- uint16_t **setup, uint8_t *num_setup,
- uint8_t **param, uint32_t *num_param,
- uint8_t **data, uint32_t *num_data);
+ uint16_t **setup, uint8_t min_setup,
+ uint8_t *num_setup,
+ uint8_t **param, uint32_t min_param,
+ uint32_t *num_param,
+ uint8_t **data, uint32_t min_data,
+ uint32_t *num_data);
NTSTATUS cli_trans(TALLOC_CTX *mem_ctx, struct cli_state *cli,
uint8_t trans_cmd,
const char *pipe_name, uint16_t fid, uint16_t function,
@@ -3050,9 +3053,9 @@ NTSTATUS cli_trans(TALLOC_CTX *mem_ctx, struct cli_state *cli,
uint16_t *setup, uint8_t num_setup, uint8_t max_setup,
uint8_t *param, uint32_t num_param, uint32_t max_param,
uint8_t *data, uint32_t num_data, uint32_t max_data,
- uint16_t **rsetup, uint8_t *num_rsetup,
- uint8_t **rparam, uint32_t *num_rparam,
- uint8_t **rdata, uint32_t *num_rdata);
+ uint16_t **rsetup, uint8_t min_rsetup, uint8_t *num_rsetup,
+ uint8_t **rparam, uint32_t min_rparam, uint32_t *num_rparam,
+ uint8_t **rdata, uint32_t min_rdata, uint32_t *num_rdata);
/* The following definitions come from libsmb/conncache.c */
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 5eb8bd471b..1a09c41680 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -119,18 +119,9 @@ struct link_state {
static void cli_posix_link_internal_done(struct tevent_req *subreq)
{
- struct tevent_req *req = tevent_req_callback_data(
- subreq, struct tevent_req);
- struct link_state *state = tevent_req_data(req, struct link_state);
- NTSTATUS status;
-
- status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, NULL, NULL);
- TALLOC_FREE(subreq);
- if (!NT_STATUS_IS_OK(status)) {
- tevent_req_nterror(req, status);
- return;
- }
- tevent_req_done(req);
+ return tevent_req_simple_finish_ntstatus(
+ subreq, cli_trans_recv(subreq, NULL, NULL, 0, NULL,
+ NULL, 0, NULL, NULL, 0, NULL));
}
static struct tevent_req *cli_posix_link_internal_send(TALLOC_CTX *mem_ctx,
@@ -289,8 +280,8 @@ static void cli_posix_readlink_done(struct tevent_req *subreq)
struct readlink_state *state = tevent_req_data(req, struct readlink_state);
NTSTATUS status;
- status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL,
- &state->data, &state->num_data);
+ status = cli_trans_recv(subreq, state, NULL, 0, NULL, NULL, 0, NULL,
+ &state->data, 0, &state->num_data);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
tevent_req_nterror(req, status);
@@ -637,8 +628,8 @@ static void cli_posix_getfacl_done(struct tevent_req *subreq)
struct getfacl_state *state = tevent_req_data(req, struct getfacl_state);
NTSTATUS status;
- status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL,
- &state->data, &state->num_data);
+ status = cli_trans_recv(subreq, state, NULL, 0, NULL, NULL, 0, NULL,
+ &state->data, 0, &state->num_data);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
tevent_req_nterror(req, status);
@@ -786,8 +777,8 @@ static void cli_posix_stat_done(struct tevent_req *subreq)
struct stat_state *state = tevent_req_data(req, struct stat_state);
NTSTATUS status;
- status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL,
- &state->data, &state->num_data);
+ status = cli_trans_recv(subreq, state, NULL, 0, NULL, NULL, 0, NULL,
+ &state->data, 96, &state->num_data);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
tevent_req_nterror(req, status);
@@ -954,18 +945,9 @@ struct ch_state {
static void cli_posix_chown_chmod_internal_done(struct tevent_req *subreq)
{
- struct tevent_req *req = tevent_req_callback_data(
- subreq, struct tevent_req);
- struct ch_state *state = tevent_req_data(req, struct ch_state);
- NTSTATUS status;
-
- status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, NULL, NULL);
- TALLOC_FREE(subreq);
- if (!NT_STATUS_IS_OK(status)) {
- tevent_req_nterror(req, status);
- return;
- }
- tevent_req_done(req);
+ return tevent_req_simple_finish_ntstatus(
+ subreq, cli_trans_recv(subreq, NULL, NULL, 0, NULL,
+ NULL, 0, NULL, NULL, 0, NULL));
}
static struct tevent_req *cli_posix_chown_chmod_internal_send(TALLOC_CTX *mem_ctx,
@@ -1861,18 +1843,9 @@ struct doc_state {
static void cli_nt_delete_on_close_done(struct tevent_req *subreq)
{
- struct tevent_req *req = tevent_req_callback_data(
- subreq, struct tevent_req);
- struct doc_state *state = tevent_req_data(req, struct doc_state);
- NTSTATUS status;
-
- status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, NULL, NULL);
- TALLOC_FREE(subreq);
- if (!NT_STATUS_IS_OK(status)) {
- tevent_req_nterror(req, status);
- return;
- }
- tevent_req_done(req);
+ return tevent_req_simple_finish_ntstatus(
+ subreq, cli_trans_recv(subreq, NULL, NULL, 0, NULL,
+ NULL, 0, NULL, NULL, 0, NULL));
}
struct tevent_req *cli_nt_delete_on_close_send(TALLOC_CTX *mem_ctx,
@@ -2476,18 +2449,9 @@ struct ftrunc_state {
static void cli_ftruncate_done(struct tevent_req *subreq)
{
- struct tevent_req *req = tevent_req_callback_data(
- subreq, struct tevent_req);
- struct ftrunc_state *state = tevent_req_data(req, struct ftrunc_state);
- NTSTATUS status;
-
- status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, NULL, NULL);
- TALLOC_FREE(subreq);
- if (!NT_STATUS_IS_OK(status)) {
- tevent_req_nterror(req, status);
- return;
- }
- tevent_req_done(req);
+ return tevent_req_simple_finish_ntstatus(
+ subreq, cli_trans_recv(subreq, NULL, NULL, 0, NULL,
+ NULL, 0, NULL, NULL, 0, NULL));
}
struct tevent_req *cli_ftruncate_send(TALLOC_CTX *mem_ctx,
@@ -3010,18 +2974,9 @@ struct posix_lock_state {
static void cli_posix_unlock_internal_done(struct tevent_req *subreq)
{
- struct tevent_req *req = tevent_req_callback_data(
- subreq, struct tevent_req);
- struct posix_lock_state *state = tevent_req_data(req, struct posix_lock_state);
- NTSTATUS status;
-
- status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, NULL, NULL);
- TALLOC_FREE(subreq);
- if (!NT_STATUS_IS_OK(status)) {
- tevent_req_nterror(req, status);
- return;
- }
- tevent_req_done(req);
+ return tevent_req_simple_finish_ntstatus(
+ subreq, cli_trans_recv(subreq, NULL, NULL, 0, NULL,
+ NULL, 0, NULL, NULL, 0, NULL));
}
static struct tevent_req *cli_posix_lock_internal_send(TALLOC_CTX *mem_ctx,
@@ -4579,16 +4534,13 @@ static void cli_posix_open_internal_done(struct tevent_req *subreq)
uint8_t *data;
uint32_t num_data;
- status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, &data, &num_data);
+ status = cli_trans_recv(subreq, state, NULL, 0, NULL, NULL, 0, NULL,
+ &data, 12, &num_data);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
tevent_req_nterror(req, status);
return;
}
- if (num_data < 12) {
- tevent_req_nterror(req, status);
- return;
- }
state->fnum = SVAL(data,2);
tevent_req_done(req);
}
@@ -4818,18 +4770,9 @@ struct unlink_state {
static void cli_posix_unlink_internal_done(struct tevent_req *subreq)
{
- struct tevent_req *req = tevent_req_callback_data(
- subreq, struct tevent_req);
- struct unlink_state *state = tevent_req_data(req, struct unlink_state);
- NTSTATUS status;
-
- status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, NULL, NULL);
- TALLOC_FREE(subreq);
- if (!NT_STATUS_IS_OK(status)) {
- tevent_req_nterror(req, status);
- return;
- }
- tevent_req_done(req);
+ return tevent_req_simple_finish_ntstatus(
+ subreq, cli_trans_recv(subreq, NULL, NULL, 0, NULL,
+ NULL, 0, NULL, NULL, 0, NULL));
}
static struct tevent_req *cli_posix_unlink_internal_send(TALLOC_CTX *mem_ctx,
@@ -5094,8 +5037,8 @@ static void cli_notify_done(struct tevent_req *subreq)
uint8_t *params;
uint32_t i, ofs, num_params;
- status = cli_trans_recv(subreq, talloc_tos(), NULL, NULL,
- &params, &num_params, NULL, NULL);
+ status = cli_trans_recv(subreq, talloc_tos(), NULL, 0, NULL,
+ &params, 0, &num_params, NULL, 0, NULL);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10, ("cli_trans_recv returned %s\n", nt_errstr(status)));
diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c
index 9e2177a0ed..6e23dbc689 100644
--- a/source3/libsmb/clifsinfo.c
+++ b/source3/libsmb/clifsinfo.c
@@ -71,17 +71,13 @@ static void cli_unix_extensions_version_done(struct tevent_req *subreq)
uint32_t num_data;
NTSTATUS status;
- status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL,
- &data, &num_data);
+ status = cli_trans_recv(subreq, state, NULL, 0, NULL, NULL, 0, NULL,
+ &data, 12, &num_data);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
tevent_req_nterror(req, status);
return;
}
- if (num_data < 12) {
- tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
- return;
- }
state->major = SVAL(data, 0);
state->minor = SVAL(data, 2);
@@ -211,8 +207,8 @@ static void cli_set_unix_extensions_capabilities_done(
struct tevent_req *subreq)
{
return tevent_req_simple_finish_ntstatus(
- subreq, cli_trans_recv(subreq, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL));
+ subreq, cli_trans_recv(subreq, NULL, NULL, 0, NULL,
+ NULL, 0, NULL, NULL, 0, NULL));
}
NTSTATUS cli_set_unix_extensions_capabilities_recv(struct tevent_req *req)
diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c
index c3ec82bd3e..13e16b26df 100644
--- a/source3/libsmb/clirap.c
+++ b/source3/libsmb/clirap.c
@@ -974,19 +974,16 @@ bool cli_qfileinfo(struct cli_state *cli, uint16_t fnum,
struct timespec *change_time,
SMB_INO_T *ino)
{
- unsigned int data_len = 0;
- unsigned int param_len = 0;
+ uint32_t data_len = 0;
uint16 setup;
uint8_t param[4];
- uint8_t *rparam=NULL, *rdata=NULL;
+ uint8_t *rdata=NULL;
NTSTATUS status;
/* if its a win95 server then fail this - win95 totally screws it
up */
if (cli->win95) return False;
- param_len = 4;
-
SSVAL(param, 0, fnum);
SSVAL(param, 2, SMB_QUERY_FILE_ALL_INFO);
@@ -995,20 +992,16 @@ bool cli_qfileinfo(struct cli_state *cli, uint16_t fnum,
status = cli_trans(talloc_tos(), cli, SMBtrans2,
NULL, -1, 0, 0, /* name, fid, function, flags */
&setup, 1, 0, /* setup, length, max */
- param, param_len, 2, /* param, length, max */
+ param, 4, 2, /* param, length, max */
NULL, 0, MIN(cli->max_xmit, 0xffff), /* data, length, max */
- NULL, NULL, /* rsetup, length */
- &rparam, &param_len, /* rparam, length */
- &rdata, &data_len);
+ NULL, 0, NULL, /* rsetup, length */
+ NULL, 0, NULL, /* rparam, length */
+ &rdata, 68, &data_len);
if (!NT_STATUS_IS_OK(status)) {
return false;
}
- if (!rdata || data_len < 68) {
- return False;
- }
-
if (create_time) {
*create_time = interpret_long_date((char *)rdata+0);
}
@@ -1032,7 +1025,6 @@ bool cli_qfileinfo(struct cli_state *cli, uint16_t fnum,
}
TALLOC_FREE(rdata);
- TALLOC_FREE(rparam);
return True;
}
diff --git a/source3/libsmb/clisecdesc.c b/source3/libsmb/clisecdesc.c
index 1c87eabafe..f4f7c545e1 100644
--- a/source3/libsmb/clisecdesc.c
+++ b/source3/libsmb/clisecdesc.c
@@ -26,8 +26,8 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli, uint16_t fnum,
TALLOC_CTX *mem_ctx)
{
uint8_t param[8];
- uint8_t *rparam=NULL, *rdata=NULL;
- unsigned int rparam_count=0, rdata_count=0;
+ uint8_t *rdata=NULL;
+ uint32_t rdata_count=0;
SEC_DESC *psd = NULL;
NTSTATUS status;
@@ -40,9 +40,9 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli, uint16_t fnum,
NULL, 0, 0, /* setup, length, max */
param, 8, 4, /* param, length, max */
NULL, 0, 0x10000, /* data, length, max */
- NULL, NULL, /* rsetup, length */
- &rparam, &rparam_count,
- &rdata, &rdata_count);
+ NULL, 0, NULL, /* rsetup, length */
+ NULL, 0, NULL,
+ &rdata, 0, &rdata_count);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("NT_TRANSACT_QUERY_SECURITY_DESC failed: %s\n",
@@ -61,7 +61,6 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli, uint16_t fnum,
cleanup:
- TALLOC_FREE(rparam);
TALLOC_FREE(rdata);
return psd;
diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c
index 98c09ed6e7..ec63bc3b9d 100644
--- a/source3/libsmb/clitrans.c
+++ b/source3/libsmb/clitrans.c
@@ -1204,9 +1204,12 @@ static void cli_trans_done(struct tevent_req *subreq)
}
NTSTATUS cli_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
- uint16_t **setup, uint8_t *num_setup,
- uint8_t **param, uint32_t *num_param,
- uint8_t **data, uint32_t *num_data)
+ uint16_t **setup, uint8_t min_setup,
+ uint8_t *num_setup,
+ uint8_t **param, uint32_t min_param,
+ uint32_t *num_param,
+ uint8_t **data, uint32_t min_data,
+ uint32_t *num_data)
{
struct cli_trans_state *state = tevent_req_data(
req, struct cli_trans_state);
@@ -1216,6 +1219,12 @@ NTSTATUS cli_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
return status;
}
+ if ((state->num_rsetup < min_setup)
+ || (state->rparam.total < min_param)
+ || (state->rdata.total < min_data)) {
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ }
+
if (setup != NULL) {
*setup = talloc_move(mem_ctx, &state->rsetup);
*num_setup = state->num_rsetup;
@@ -1247,9 +1256,9 @@ NTSTATUS cli_trans(TALLOC_CTX *mem_ctx, struct cli_state *cli,
uint16_t *setup, uint8_t num_setup, uint8_t max_setup,
uint8_t *param, uint32_t num_param, uint32_t max_param,
uint8_t *data, uint32_t num_data, uint32_t max_data,
- uint16_t **rsetup, uint8_t *num_rsetup,
- uint8_t **rparam, uint32_t *num_rparam,
- uint8_t **rdata, uint32_t *num_rdata)
+ uint16_t **rsetup, uint8_t min_rsetup, uint8_t *num_rsetup,
+ uint8_t **rparam, uint32_t min_rparam, uint32_t *num_rparam,
+ uint8_t **rdata, uint32_t min_rdata, uint32_t *num_rdata)
{
TALLOC_CTX *frame = talloc_stackframe();
struct event_context *ev;
@@ -1285,8 +1294,9 @@ NTSTATUS cli_trans(TALLOC_CTX *mem_ctx, struct cli_state *cli,
goto fail;
}
- status = cli_trans_recv(req, mem_ctx, rsetup, num_rsetup,
- rparam, num_rparam, rdata, num_rdata);
+ status = cli_trans_recv(req, mem_ctx, rsetup, min_rsetup, num_rsetup,
+ rparam, min_rparam, num_rparam,
+ rdata, min_rdata, num_rdata);
fail:
TALLOC_FREE(frame);
if (!NT_STATUS_IS_OK(status)) {
diff --git a/source3/rpc_client/rpc_transport_np.c b/source3/rpc_client/rpc_transport_np.c
index c28664d007..de748d9bbc 100644
--- a/source3/rpc_client/rpc_transport_np.c
+++ b/source3/rpc_client/rpc_transport_np.c
@@ -244,8 +244,8 @@ static void rpc_np_trans_done(struct tevent_req *subreq)
req, struct rpc_np_trans_state);
NTSTATUS status;
- status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL,
- &state->rdata, &state->rdata_len);
+ status = cli_trans_recv(subreq, state, NULL, 0, NULL, NULL, 0, NULL,
+ &state->rdata, 0, &state->rdata_len);
TALLOC_FREE(subreq);
if (!NT_STATUS_IS_OK(status)) {
tevent_req_nterror(req, status);