diff options
-rw-r--r-- | source3/client/client.c | 7 | ||||
-rw-r--r-- | source3/include/proto.h | 9 | ||||
-rw-r--r-- | source3/libsmb/clifsinfo.c | 116 | ||||
-rw-r--r-- | source3/torture/torture.c | 8 |
4 files changed, 96 insertions, 44 deletions
diff --git a/source3/client/client.c b/source3/client/client.c index f81762a563..6773e6d90a 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -2531,8 +2531,11 @@ static int cmd_posix(void) d_printf("Server supports CIFS capabilities %s\n", caps); - if (!cli_set_unix_extensions_capabilities(cli, major, minor, caplow, caphigh)) { - d_printf("Can't set UNIX CIFS extensions capabilities. %s.\n", cli_errstr(cli)); + status = cli_set_unix_extensions_capabilities(cli, major, minor, + caplow, caphigh); + if (!NT_STATUS_IS_OK(status)) { + d_printf("Can't set UNIX CIFS extensions capabilities. %s.\n", + nt_errstr(status)); return 1; } diff --git a/source3/include/proto.h b/source3/include/proto.h index aeb19d3c20..8c0a3e319d 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -2692,8 +2692,13 @@ NTSTATUS cli_unix_extensions_version_recv(struct tevent_req *req, NTSTATUS cli_unix_extensions_version(struct cli_state *cli, uint16 *pmajor, uint16 *pminor, uint32 *pcaplow, uint32 *pcaphigh); -bool cli_set_unix_extensions_capabilities(struct cli_state *cli, uint16 major, uint16 minor, - uint32 caplow, uint32 caphigh); +struct tevent_req *cli_set_unix_extensions_capabilities_send( + TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli, + uint16_t major, uint16_t minor, uint32_t caplow, uint32_t caphigh); +NTSTATUS cli_set_unix_extensions_capabilities_recv(struct tevent_req *req); +NTSTATUS cli_set_unix_extensions_capabilities(struct cli_state *cli, + uint16 major, uint16 minor, + uint32 caplow, uint32 caphigh); bool cli_get_fs_attr_info(struct cli_state *cli, uint32 *fs_attr); bool cli_get_fs_volume_info_old(struct cli_state *cli, fstring volume_name, uint32 *pserial_number); bool cli_get_fs_volume_info(struct cli_state *cli, fstring volume_name, uint32 *pserial_number, time_t *pdate); diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c index 03ec54ab8c..9e2177a0ed 100644 --- a/source3/libsmb/clifsinfo.c +++ b/source3/libsmb/clifsinfo.c @@ -161,53 +161,95 @@ NTSTATUS cli_unix_extensions_version(struct cli_state *cli, uint16 *pmajor, Set UNIX extensions capabilities. ****************************************************************************/ -bool cli_set_unix_extensions_capabilities(struct cli_state *cli, uint16 major, uint16 minor, - uint32 caplow, uint32 caphigh) +struct cli_set_unix_extensions_capabilities_state { + uint16_t setup[1]; + uint8_t param[4]; + uint8_t data[12]; +}; + +static void cli_set_unix_extensions_capabilities_done( + struct tevent_req *subreq); + +struct tevent_req *cli_set_unix_extensions_capabilities_send( + TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli, + uint16_t major, uint16_t minor, uint32_t caplow, uint32_t caphigh) { - bool ret = False; - uint16 setup; - char param[4]; - char data[12]; - char *rparam=NULL, *rdata=NULL; - unsigned int rparam_count=0, rdata_count=0; + struct tevent_req *req, *subreq; + struct cli_set_unix_extensions_capabilities_state *state; - setup = TRANSACT2_SETFSINFO; + req = tevent_req_create( + mem_ctx, &state, + struct cli_set_unix_extensions_capabilities_state); + if (req == NULL) { + return NULL; + } - SSVAL(param,0,0); - SSVAL(param,2,SMB_SET_CIFS_UNIX_INFO); + SSVAL(state->setup+0, 0, TRANSACT2_SETFSINFO); - SSVAL(data,0,major); - SSVAL(data,2,minor); - SIVAL(data,4,caplow); - SIVAL(data,8,caphigh); + SSVAL(state->param, 0, 0); + SSVAL(state->param, 2, SMB_SET_CIFS_UNIX_INFO); - if (!cli_send_trans(cli, SMBtrans2, - NULL, - 0, 0, - &setup, 1, 0, - param, 4, 0, - data, 12, 560)) { - goto cleanup; - } + SSVAL(state->data, 0, major); + SSVAL(state->data, 2, minor); + SIVAL(state->data, 4, caplow); + SIVAL(state->data, 8, caphigh); - if (!cli_receive_trans(cli, SMBtrans2, - &rparam, &rparam_count, - &rdata, &rdata_count)) { - goto cleanup; + subreq = cli_trans_send(state, ev, cli, SMBtrans2, + NULL, 0, 0, 0, + state->setup, 1, 0, + state->param, 4, 0, + state->data, 12, 560); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); } + tevent_req_set_callback( + subreq, cli_set_unix_extensions_capabilities_done, req); + return req; +} - if (cli_is_error(cli)) { - ret = False; - goto cleanup; - } else { - ret = True; - } +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)); +} -cleanup: - SAFE_FREE(rparam); - SAFE_FREE(rdata); +NTSTATUS cli_set_unix_extensions_capabilities_recv(struct tevent_req *req) +{ + return tevent_req_simple_recv_ntstatus(req); +} - return ret; +NTSTATUS cli_set_unix_extensions_capabilities(struct cli_state *cli, + uint16 major, uint16 minor, + uint32 caplow, uint32 caphigh) +{ + struct tevent_context *ev; + struct tevent_req *req; + NTSTATUS status = NT_STATUS_NO_MEMORY; + + if (cli_has_async_calls(cli)) { + return NT_STATUS_INVALID_PARAMETER; + } + ev = tevent_context_init(talloc_tos()); + if (ev == NULL) { + goto fail; + } + req = cli_set_unix_extensions_capabilities_send( + ev, ev, cli, major, minor, caplow, caphigh); + if (req == NULL) { + goto fail; + } + if (!tevent_req_poll_ntstatus(req, ev, &status)) { + goto fail; + } + status = cli_set_unix_extensions_capabilities_recv(req); +fail: + TALLOC_FREE(ev); + if (!NT_STATUS_IS_OK(status)) { + cli_set_error(cli, status); + } + return status; } bool cli_get_fs_attr_info(struct cli_state *cli, uint32 *fs_attr) diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 9abcabde89..840dc94256 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -4392,9 +4392,11 @@ static bool run_simple_posix_open_test(int dummy) return false; } - if (!cli_set_unix_extensions_capabilities(cli1, - major, minor, caplow, caphigh)) { - printf("Server doesn't support setting UNIX CIFS extensions.\n"); + status = cli_set_unix_extensions_capabilities(cli1, major, minor, + caplow, caphigh); + if (!NT_STATUS_IS_OK(status)) { + printf("Server doesn't support setting UNIX CIFS extensions: " + "%s.\n", nt_errstr(status)); return false; } |