return NULL;
}
- if (!cli_send_tconX(cli, share, "?????", password, strlen(password) + 1)) {
- fprintf(stderr, "ERROR: Tree connect failed (%s)\n", cli_errstr(cli));
+ nt_status = cli_tcon_andx(cli, share, "?????", password,
+ strlen(password) + 1);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ fprintf(stderr, "ERROR: Tree connect failed (%s)\n",
+ nt_errstr(nt_status));
- if (get_exit_code(cli, cli_nt_error(cli)) == 2) {
+ if (get_exit_code(cli, nt_status) == 2) {
*need_auth = true;
}
struct cli_state *cli);
NTSTATUS cli_session_setup_guest_recv(struct async_req *req);
bool cli_ulogoff(struct cli_state *cli);
-bool cli_send_tconX(struct cli_state *cli,
- const char *share, const char *dev, const char *pass, int passlen);
+struct async_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ const char *share, const char *dev,
+ const char *pass, int passlen);
+NTSTATUS cli_tcon_andx_recv(struct async_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);
void cli_negprot_sendsync(struct cli_state *cli);
NTSTATUS cli_negprot(struct cli_state *cli);
Send a tconX.
****************************************************************************/
-bool cli_send_tconX(struct cli_state *cli,
- const char *share, const char *dev, const char *pass, int passlen)
+struct async_req *cli_tcon_andx_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ const char *share, const char *dev,
+ const char *pass, int passlen)
{
- fstring fullshare, pword;
- char *p;
- memset(cli->outbuf,'\0',smb_size);
- memset(cli->inbuf,'\0',smb_size);
+ fstring pword;
+ char *tmp = NULL;
+ struct async_req *result;
+ uint16_t vwv[4];
+ uint8_t *bytes;
fstrcpy(cli->share, share);
if (cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) {
passlen = 1;
pass = "";
- } else if (!pass) {
- DEBUG(1, ("Server not using user level security and no password supplied.\n"));
- return False;
+ } else if (pass == NULL) {
+ DEBUG(1, ("Server not using user level security and no "
+ "password supplied.\n"));
+ goto access_denied;
}
if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) &&
DEBUG(1, ("Server requested LANMAN password "
"(share-level security) but "
"'client lanman auth' is disabled\n"));
- return False;
+ goto access_denied;
}
/*
- * Non-encrypted passwords - convert to DOS codepage before encryption.
+ * Non-encrypted passwords - convert to DOS codepage before
+ * encryption.
*/
passlen = 24;
- SMBencrypt(pass,cli->secblob.data,(uchar *)pword);
+ SMBencrypt(pass, cli->secblob.data, (uchar *)pword);
} else {
- if((cli->sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL|NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)) == 0) {
+ if((cli->sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL
+ |NEGOTIATE_SECURITY_CHALLENGE_RESPONSE))
+ == 0) {
if (!lp_client_plaintext_auth() && (*pass)) {
DEBUG(1, ("Server requested plaintext "
"password but 'client plaintext "
"auth' is disabled\n"));
- return False;
+ goto access_denied;
}
/*
- * Non-encrypted passwords - convert to DOS codepage before using.
+ * Non-encrypted passwords - convert to DOS codepage
+ * before using.
*/
- passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE);
-
+ passlen = clistr_push(cli, pword, pass, sizeof(pword),
+ STR_TERMINATE);
} else {
if (passlen) {
memcpy(pword, pass, passlen);
}
}
- slprintf(fullshare, sizeof(fullshare)-1,
- "\\\\%s\\%s", cli->desthost, share);
+ SCVAL(vwv+0, 0, 0xFF);
+ SCVAL(vwv+0, 1, 0);
+ SSVAL(vwv+1, 0, 0);
+ SSVAL(vwv+2, 0, TCONX_FLAG_EXTENDED_RESPONSE);
+ SSVAL(vwv+3, 0, passlen);
- cli_set_message(cli->outbuf,4, 0, True);
- SCVAL(cli->outbuf,smb_com,SMBtconX);
- cli_setup_packet(cli);
+ if (passlen) {
+ bytes = (uint8_t *)talloc_memdup(talloc_tos(), pword, passlen);
+ } else {
+ bytes = talloc_array(talloc_tos(), uint8_t, 0);
+ }
- SSVAL(cli->outbuf,smb_vwv0,0xFF);
- SSVAL(cli->outbuf,smb_vwv2,TCONX_FLAG_EXTENDED_RESPONSE);
- SSVAL(cli->outbuf,smb_vwv3,passlen);
+ /*
+ * Add the sharename
+ */
+ tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
+ cli->desthost, share);
+ if (tmp == NULL) {
+ TALLOC_FREE(bytes);
+ return NULL;
+ }
+ bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1,
+ NULL);
+ TALLOC_FREE(tmp);
- p = smb_buf(cli->outbuf);
- if (passlen) {
- memcpy(p,pword,passlen);
+ /*
+ * Add the devicetype
+ */
+ tmp = talloc_strdup_upper(talloc_tos(), dev);
+ if (tmp == NULL) {
+ TALLOC_FREE(bytes);
+ return NULL;
}
- p += passlen;
- p += clistr_push(cli, p, fullshare, -1, STR_TERMINATE |STR_UPPER);
- p += clistr_push(cli, p, dev, -1, STR_TERMINATE |STR_UPPER | STR_ASCII);
+ bytes = smb_bytes_push_str(bytes, false, tmp, strlen(tmp)+1, NULL);
+ TALLOC_FREE(tmp);
- cli_setup_bcc(cli, p);
+ if (bytes == NULL) {
+ return NULL;
+ }
- cli_send_smb(cli);
- if (!cli_receive_smb(cli))
- return False;
+ result = cli_request_send(mem_ctx, ev, cli, SMBtconX, 0,
+ 4, vwv, 0, talloc_get_size(bytes), bytes);
+ TALLOC_FREE(bytes);
+ return result;
- if (cli_is_error(cli))
- return False;
+ access_denied:
+ result = async_req_new(mem_ctx);
+ if (async_post_status(result, ev, NT_STATUS_ACCESS_DENIED)) {
+ return result;
+ }
+ TALLOC_FREE(result);
+ return NULL;
+}
- clistr_pull(cli->inbuf, cli->dev, smb_buf(cli->inbuf), sizeof(fstring),
- -1, STR_TERMINATE|STR_ASCII);
+NTSTATUS cli_tcon_andx_recv(struct async_req *req)
+{
+ struct cli_request *cli_req = talloc_get_type_abort(
+ req->private_data, struct cli_request);
+ struct cli_state *cli = cli_req->cli;
+ uint8_t wct;
+ uint16_t *vwv;
+ uint16_t num_bytes;
+ uint8_t *bytes;
+ NTSTATUS status;
- if (cli->protocol >= PROTOCOL_NT1 &&
- smb_buflen(cli->inbuf) == 3) {
+ if (async_req_is_error(req, &status)) {
+ return status;
+ }
+
+ status = cli_pull_reply(req, &wct, &vwv, &num_bytes, &bytes);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ clistr_pull(cli_req->inbuf, cli->dev, bytes, sizeof(fstring),
+ num_bytes, STR_TERMINATE|STR_ASCII);
+
+ if ((cli->protocol >= PROTOCOL_NT1) && (num_bytes == 3)) {
/* almost certainly win95 - enable bug fixes */
cli->win95 = True;
}
- /* Make sure that we have the optional support 16-bit field. WCT > 2 */
- /* Avoids issues when connecting to Win9x boxes sharing files */
+ /*
+ * Make sure that we have the optional support 16-bit field. WCT > 2.
+ * Avoids issues when connecting to Win9x boxes sharing files
+ */
- cli->dfsroot = False;
- if ( (CVAL(cli->inbuf, smb_wct))>2 && cli->protocol >= PROTOCOL_LANMAN2 )
- cli->dfsroot = (SVAL( cli->inbuf, smb_vwv2 ) & SMB_SHARE_IN_DFS) ? True : False;
+ cli->dfsroot = false;
- cli->cnum = SVAL(cli->inbuf,smb_tid);
- return True;
+ if ((wct > 2) && (cli->protocol >= PROTOCOL_LANMAN2)) {
+ cli->dfsroot = ((SVAL(vwv+2, 0) & SMB_SHARE_IN_DFS) != 0);
+ }
+
+ cli->cnum = SVAL(cli_req->inbuf,smb_tid);
+ return NT_STATUS_OK;
+}
+
+NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
+ const char *dev, const char *pass, int passlen)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct event_context *ev;
+ struct async_req *req;
+ NTSTATUS status;
+
+ if (cli->fd_event != NULL) {
+ /*
+ * Can't use sync call while an async call is in flight
+ */
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto fail;
+ }
+
+ ev = event_context_init(frame);
+ if (ev == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ req = cli_tcon_andx_send(frame, ev, cli, share, dev, pass, passlen);
+ if (req == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto fail;
+ }
+
+ while (req->state < ASYNC_REQ_DONE) {
+ event_loop_once(ev);
+ }
+
+ status = cli_tcon_andx_recv(req);
+ fail:
+ TALLOC_FREE(frame);
+ return status;
}
/****************************************************************************
}
if (service) {
- if (!cli_send_tconX(cli, service, service_type, password, pw_len)) {
- nt_status = cli_nt_error(cli);
+ nt_status = cli_tcon_andx(cli, service, service_type, password,
+ pw_len);
+ if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status)));
cli_shutdown(cli);
if (NT_STATUS_IS_OK(nt_status)) {
/* must be a normal share */
- if (!cli_send_tconX(c, sharename, "?????",
- password, strlen(password)+1)) {
- d_printf("tree connect failed: %s\n", cli_errstr(c));
+ status = cli_tcon_andx(c, sharename, "?????",
+ password, strlen(password)+1);
+ if (!NT_STATUS_IS_OK(status)) {
+ d_printf("tree connect failed: %s\n", nt_errstr(status));
cli_shutdown(c);
return NULL;
}
/* check for the referral */
- if (!cli_send_tconX(cli, "IPC$", "IPC", NULL, 0)) {
+ if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, "IPC$", "IPC", NULL, 0))) {
return false;
}
* tid.
*/
- if (!cli_send_tconX(srv->cli, share, "?????",
- *pp_password,
- strlen(*pp_password)+1)) {
-
- errno = SMBC_errno(context, srv->cli);
+ status = cli_tcon_andx(srv->cli, share, "?????",
+ *pp_password,
+ strlen(*pp_password)+1);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
cli_shutdown(srv->cli);
srv->cli = NULL;
smbc_getFunctionRemoveCachedServer(context)(context,
DEBUG(4,(" session setup ok\n"));
- if (!cli_send_tconX(c, share, "?????",
- *pp_password, strlen(*pp_password)+1)) {
- errno = SMBC_errno(context, c);
+ status = cli_tcon_andx(c, share, "?????", *pp_password,
+ strlen(*pp_password)+1);
+ if (!NT_STATUS_IS_OK(status)) {
+ errno = map_errno_from_nt_status(status);
cli_shutdown(c);
return NULL;
}
cli_init_creds(cli, user_name, "", old_passwd);
}
- if (!cli_send_tconX(cli, "IPC$", "IPC", "", 1)) {
- if (asprintf(err_str, "machine %s rejected the tconX on the IPC$ "
- "share. Error was : %s.\n",
- remote_machine, cli_errstr(cli)) == -1) {
+ result = cli_tcon_andx(cli, "IPC$", "IPC", "", 1);
+ if (!NT_STATUS_IS_OK(result)) {
+ if (asprintf(err_str, "machine %s rejected the tconX on the "
+ "IPC$ share. Error was : %s.\n",
+ remote_machine, nt_errstr(result))) {
*err_str = NULL;
}
- result = cli_nt_error(cli);
cli_shutdown(cli);
return result;
}
return;
}
- if (!cli_send_tconX(cli, "IPC$", "IPC", "", 1)) {
+ if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, "IPC$", "IPC", "", 1))) {
cli_shutdown(cli);
return;
}
DEBUG(4,(" session setup ok\n"));
- if (!cli_send_tconX(c, share, "?????",
- password[snum], strlen(password[snum])+1)) {
- DEBUG(0,("tree connect failed: %s\n", cli_errstr(c)));
+ status = cli_tcon_andx(c, share, "?????", password[snum],
+ strlen(password[snum])+1);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("tree connect failed: %s\n", nt_errstr(status)));
cli_shutdown(c);
return NULL;
}
DEBUG(4,(" session setup ok\n"));
- if (!cli_send_tconX(c, share, "?????",
- password, strlen(password)+1)) {
- DEBUG(0,("tree connect failed: %s\n", cli_errstr(c)));
+ status = cli_tcon_andx(c, share, "?????", password,
+ strlen(password)+1);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0,("tree connect failed: %s\n", nt_errstr(status)));
cli_shutdown(c);
return NULL;
}
uint16 vuid1, vuid2;
char buf[4];
bool ret = True;
+ NTSTATUS status;
memset(buf, '\0', sizeof(buf));
return False;
}
- if (!cli_send_tconX(cli, share, "?????",
- password, strlen(password)+1)) {
+ status = cli_tcon_andx(cli, share, "?????",
+ password, strlen(password)+1);
+ if (!NT_STATUS_IS_OK(status)) {
printf("%s refused 2nd tree connect (%s)\n", host,
- cli_errstr(cli));
+ nt_errstr(status));
cli_shutdown(cli);
return False;
}
const char *return_devtype,
NTSTATUS expected_error)
{
- bool status;
+ NTSTATUS status;
bool ret;
- status = cli_send_tconX(cli, myshare, devtype,
- password, strlen(password)+1);
+ status = cli_tcon_andx(cli, myshare, devtype,
+ password, strlen(password)+1);
if (NT_STATUS_IS_OK(expected_error)) {
- if (status) {
+ if (NT_STATUS_IS_OK(status)) {
if (strcmp(cli->dev, return_devtype) == 0) {
ret = True;
} else {
}
cli_tdis(cli);
} else {
- if (status) {
+ if (NT_STATUS_IS_OK(status)) {
printf("tconx to share %s with type %s "
"should have failed but succeeded\n",
myshare, devtype);
return False;
saved_cnum = cli->cnum;
- if (!cli_send_tconX(cli, share, "?????", "", 1))
+ if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
return False;
new_cnum = cli->cnum;
cli->cnum = saved_cnum;
static bool check_share_availability(struct cli_state *cli, const char *netname)
{
- if (!cli_send_tconX(cli, netname, "A:", "", 0)) {
+ if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, netname, "A:", "", 0))) {
d_printf("skipping [%s]: not a file share.\n", netname);
return false;
}
cnum = cli->cnum;
- if (!cli_send_tconX(cli, netname, "A:", "", 0)) {
+ if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, netname, "A:", "", 0))) {
return;
}
char **domains;
char **names;
- if (!cli_send_tconX(cli, "IPC$", "?????", "", 0)) {
- return cli_nt_error(cli);
+ status = cli_tcon_andx(cli, "IPC$", "?????", "", 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
DOM_SID *sids;
enum lsa_SidType *types;
- if (!cli_send_tconX(cli, "IPC$", "?????", "", 0)) {
- return cli_nt_error(cli);
+ status = cli_tcon_andx(cli, "IPC$", "?????", "", 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id,
winbindd_set_locator_kdc_envs(domain);
- if (!cli_send_tconX(*cli, "IPC$", "IPC", "", 0)) {
-
- result = cli_nt_error(*cli);
+ result = cli_tcon_andx(*cli, "IPC$", "IPC", "", 0);
+ if (!NT_STATUS_IS_OK(result)) {
DEBUG(1,("failed tcon_X with %s\n", nt_errstr(result)));
-
- if (NT_STATUS_IS_OK(result))
- result = NT_STATUS_UNSUCCESSFUL;
-
goto done;
}