s3: Add min_setup, min_param and min_data to cli_trans_recv
authorVolker Lendecke <vl@samba.org>
Sat, 14 Nov 2009 10:12:50 +0000 (11:12 +0100)
committerVolker Lendecke <vl@samba.org>
Sat, 14 Nov 2009 11:20:12 +0000 (12:20 +0100)
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.

source3/include/proto.h
source3/libsmb/clifile.c
source3/libsmb/clifsinfo.c
source3/libsmb/clirap.c
source3/libsmb/clisecdesc.c
source3/libsmb/clitrans.c
source3/rpc_client/rpc_transport_np.c

index d4e0ac55c5ea12ab8b362a3356f57492ea593317..86f6626a697567a4fb678d6a0c742f5614b0fe8b 100644 (file)
@@ -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  */
 
index 5eb8bd471be1bbb50a7e7efd1f5d1bcea7bf6202..1a09c4168059357f93cc12b1d7b9978e8608a0a1 100644 (file)
@@ -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)));
index 9e2177a0ede22c27401ca48d0079ea5e88e653c2..6e23dbc689e7bed9b977683edc818433ac6c17c2 100644 (file)
@@ -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)
index c3ec82bd3ee3db7748ac8ce8c8243d81d5fc4068..13e16b26df8e581f21c2f065eeb04fb668fce395 100644 (file)
@@ -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;
 }
 
index 1c87eabafed90706c5ff012780143948c304dc6a..f4f7c545e14e47084cfd14ca092936346f939ff9 100644 (file)
@@ -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;
index 98c09ed6e7346c7ad3c84b1f9d0a644221b37afc..ec63bc3b9daefac9bc1ca0e1dfdbd88cf7417fd9 100644 (file)
@@ -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)) {
index c28664d007bfa8789ceb6c019ea8a9822fbac68c..de748d9bbcfc57cb13d298b9ebd42f73367bef8b 100644 (file)
@@ -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);