NTSTATUS cli_tcon_andx_recv(struct tevent_req *req);
NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
const char *dev, const char *pass, int passlen);
-bool cli_tdis(struct cli_state *cli);
+struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct cli_state *cli);
+NTSTATUS cli_tdis_recv(struct tevent_req *req);
+NTSTATUS cli_tdis(struct cli_state *cli);
void cli_negprot_sendsync(struct cli_state *cli);
NTSTATUS cli_negprot(struct cli_state *cli);
struct tevent_req *cli_negprot_send(TALLOC_CTX *mem_ctx,
Send a tree disconnect.
****************************************************************************/
-bool cli_tdis(struct cli_state *cli)
+struct cli_tdis_state {
+ struct cli_state *cli;
+};
+
+static void cli_tdis_done(struct tevent_req *subreq);
+
+struct tevent_req *cli_tdis_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct cli_state *cli)
{
- memset(cli->outbuf,'\0',smb_size);
- cli_set_message(cli->outbuf,0,0,True);
- SCVAL(cli->outbuf,smb_com,SMBtdis);
- SSVAL(cli->outbuf,smb_tid,cli->cnum);
- cli_setup_packet(cli);
+ struct tevent_req *req, *subreq;
+ struct cli_tdis_state *state;
- cli_send_smb(cli);
- if (!cli_receive_smb(cli))
- return False;
+ req = tevent_req_create(mem_ctx, &state, struct cli_tdis_state);
+ if (req == NULL) {
+ return NULL;
+ }
+ state->cli = cli;
- if (cli_is_error(cli)) {
- return False;
+ subreq = cli_smb_send(state, ev, cli, SMBtdis, 0, 0, NULL, 0, NULL);
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
}
+ tevent_req_set_callback(subreq, cli_tdis_done, req);
+ return req;
+}
- cli->cnum = -1;
- return True;
+static void cli_tdis_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct cli_tdis_state *state = tevent_req_data(
+ req, struct cli_tdis_state);
+ NTSTATUS status;
+
+ status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return;
+ }
+ state->cli->cnum = -1;
+ tevent_req_done(req);
+}
+
+NTSTATUS cli_tdis_recv(struct tevent_req *req)
+{
+ return tevent_req_simple_recv_ntstatus(req);
+}
+
+NTSTATUS cli_tdis(struct cli_state *cli)
+{
+ 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_tdis_send(ev, ev, cli);
+ if (req == NULL) {
+ goto fail;
+ }
+ if (!tevent_req_poll_ntstatus(req, ev, &status)) {
+ goto fail;
+ }
+ status = cli_tdis_recv(req);
+fail:
+ TALLOC_FREE(ev);
+ if (!NT_STATUS_IS_OK(status)) {
+ cli_set_error(cli, status);
+ }
+ return status;
}
/****************************************************************************
bool res;
uint16 cnum;
char *newextrapath = NULL;
+ NTSTATUS status;
if (!cli || !sharename) {
return false;
}
if (force_encrypt) {
- NTSTATUS status = cli_cm_force_encryption(cli,
+ status = cli_cm_force_encryption(cli,
username,
password,
lp_workgroup(),
res = cli_dfs_get_referral(ctx, cli, fullpath, &refs, &num_refs, &consumed);
- if (!cli_tdis(cli)) {
+ status = cli_tdis(cli);
+ if (!NT_STATUS_IS_OK(status)) {
return false;
}
* attribute server connection) is cool.
*/
if (smbc_getOptionOneSharePerServer(context)) {
+ NTSTATUS status;
/*
* The currently connected share name
* doesn't match the requested share, so
* disconnect from the current share.
*/
- if (! cli_tdis(srv->server->cli)) {
+ status = cli_tdis(srv->server->cli);
+ if (!NT_STATUS_IS_OK(status)) {
/* Sigh. Couldn't disconnect. */
cli_shutdown(srv->server->cli);
srv->server->cli = NULL;
bool torture_close_connection(struct cli_state *c)
{
bool ret = True;
- if (!cli_tdis(c)) {
- printf("tdis failed (%s)\n", cli_errstr(c));
+ NTSTATUS status;
+
+ status = cli_tdis(c);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("tdis failed (%s)\n", nt_errstr(status));
ret = False;
}
cli->cnum = cnum2;
- if (!cli_tdis(cli)) {
- printf("secondary tdis failed (%s)\n", cli_errstr(cli));
+ status = cli_tdis(cli);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("secondary tdis failed (%s)\n", nt_errstr(status));
return False;
}
cli->vuid = 0;
/* This should succeed. */
- if (cli_tdis(cli)) {
+ status = cli_tdis(cli);
+
+ if (NT_STATUS_IS_OK(status)) {
printf("First tdis with invalid vuid should succeed.\n");
} else {
- printf("First tdis failed (%s)\n", cli_errstr(cli));
+ printf("First tdis failed (%s)\n", nt_errstr(status));
}
cli->vuid = old_vuid;
cli->cnum = old_cnum;
/* This should fail. */
- if (cli_tdis(cli)) {
+ status = cli_tdis(cli);
+ if (NT_STATUS_IS_OK(status)) {
printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
} else {
/* Should be bad tid. */
static bool check_share_availability(struct cli_state *cli, const char *netname)
{
- if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, netname, "A:", "", 0))) {
+ NTSTATUS status;
+
+ status = cli_tcon_andx(cli, netname, "A:", "", 0);
+ if (!NT_STATUS_IS_OK(status)) {
d_printf(_("skipping [%s]: not a file share.\n"), netname);
return false;
}
- if (!cli_tdis(cli))
+ status = cli_tdis(cli);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf(_("cli_tdis returned %s\n"), nt_errstr(status));
return false;
+ }
return true;
}