*/
#include "includes.h"
+#include "../libcli/auth/libcli_auth.h"
static const struct {
int prot;
{
DATA_BLOB session_key = data_blob_null;
DATA_BLOB lm_response = data_blob_null;
+ NTSTATUS status;
fstring pword;
char *p;
/* use the returned vuid from now on */
cli->vuid = SVAL(cli->inbuf,smb_uid);
- fstrcpy(cli->user_name, user);
+ status = cli_set_username(cli, user);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
if (session_key.data) {
/* Have plaintext orginal */
Do a NT1 guest session setup.
****************************************************************************/
-struct async_req *cli_session_setup_guest_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- struct cli_state *cli)
+struct cli_session_setup_guest_state {
+ struct cli_state *cli;
+ uint16_t vwv[16];
+ struct iovec bytes;
+};
+
+static void cli_session_setup_guest_done(struct tevent_req *subreq);
+
+struct tevent_req *cli_session_setup_guest_create(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ struct tevent_req **psmbreq)
{
- struct async_req *result;
- uint16_t vwv[13];
+ struct tevent_req *req, *subreq;
+ struct cli_session_setup_guest_state *state;
+ uint16_t *vwv;
uint8_t *bytes;
+ req = tevent_req_create(mem_ctx, &state,
+ struct cli_session_setup_guest_state);
+ if (req == NULL) {
+ return NULL;
+ }
+ state->cli = cli;
+ vwv = state->vwv;
+
SCVAL(vwv+0, 0, 0xFF);
SCVAL(vwv+0, 1, 0);
SSVAL(vwv+1, 0, 0);
SSVAL(vwv+10, 0, 0);
SIVAL(vwv+11, 0, cli_session_setup_capabilities(cli));
- bytes = talloc_array(talloc_tos(), uint8_t, 0);
+ bytes = talloc_array(state, uint8_t, 0);
bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "", 1, /* username */
NULL);
bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), "Samba", 6, NULL);
if (bytes == NULL) {
+ TALLOC_FREE(req);
return NULL;
}
- result = cli_request_send(mem_ctx, ev, cli, SMBsesssetupX, 0,
- 13, vwv, 0, talloc_get_size(bytes), bytes);
- TALLOC_FREE(bytes);
- return result;
+ state->bytes.iov_base = bytes;
+ state->bytes.iov_len = talloc_get_size(bytes);
+
+ subreq = cli_smb_req_create(state, ev, cli, SMBsesssetupX, 0, 13, vwv,
+ 1, &state->bytes);
+ if (subreq == NULL) {
+ TALLOC_FREE(req);
+ return NULL;
+ }
+ tevent_req_set_callback(subreq, cli_session_setup_guest_done, req);
+ *psmbreq = subreq;
+ return req;
}
-NTSTATUS cli_session_setup_guest_recv(struct async_req *req)
+struct tevent_req *cli_session_setup_guest_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli)
{
- 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;
+ struct tevent_req *req, *subreq;
+
+ req = cli_session_setup_guest_create(mem_ctx, ev, cli, &subreq);
+ if ((req == NULL) || !cli_smb_req_send(subreq)) {
+ TALLOC_FREE(req);
+ return NULL;
+ }
+ return req;
+}
+
+static void cli_session_setup_guest_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct cli_session_setup_guest_state *state = tevent_req_data(
+ req, struct cli_session_setup_guest_state);
+ struct cli_state *cli = state->cli;
+ uint32_t num_bytes;
+ char *inbuf;
uint8_t *bytes;
uint8_t *p;
NTSTATUS status;
- if (async_req_is_nterror(req, &status)) {
- return status;
- }
-
- status = cli_pull_reply(req, &wct, &vwv, &num_bytes, &bytes);
+ status = cli_smb_recv(subreq, 0, NULL, NULL, &num_bytes, &bytes);
if (!NT_STATUS_IS_OK(status)) {
- return status;
+ TALLOC_FREE(subreq);
+ tevent_req_nterror(req, status);
+ return;
}
+ inbuf = (char *)cli_smb_inbuf(subreq);
p = bytes;
- cli->vuid = SVAL(cli_req->inbuf, smb_uid);
+ cli->vuid = SVAL(inbuf, smb_uid);
- p += clistr_pull(cli_req->inbuf, cli->server_os, (char *)p,
- sizeof(fstring), bytes+num_bytes-p, STR_TERMINATE);
- p += clistr_pull(cli_req->inbuf, cli->server_type, (char *)p,
- sizeof(fstring), bytes+num_bytes-p, STR_TERMINATE);
- p += clistr_pull(cli_req->inbuf, cli->server_domain, (char *)p,
- sizeof(fstring), bytes+num_bytes-p, STR_TERMINATE);
+ p += clistr_pull(inbuf, cli->server_os, (char *)p, sizeof(fstring),
+ bytes+num_bytes-p, STR_TERMINATE);
+ p += clistr_pull(inbuf, cli->server_type, (char *)p, sizeof(fstring),
+ bytes+num_bytes-p, STR_TERMINATE);
+ p += clistr_pull(inbuf, cli->server_domain, (char *)p, sizeof(fstring),
+ bytes+num_bytes-p, STR_TERMINATE);
if (strstr(cli->server_type, "Samba")) {
cli->is_samba = True;
}
- fstrcpy(cli->user_name, "");
+ TALLOC_FREE(subreq);
- return NT_STATUS_OK;
+ status = cli_set_username(cli, "");
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, status);
+ return;
+ }
+ tevent_req_done(req);
+}
+
+NTSTATUS cli_session_setup_guest_recv(struct tevent_req *req)
+{
+ return tevent_req_simple_recv_ntstatus(req);
}
static NTSTATUS cli_session_setup_guest(struct cli_state *cli)
{
TALLOC_CTX *frame = talloc_stackframe();
struct event_context *ev;
- struct async_req *req;
- NTSTATUS status;
+ struct tevent_req *req;
+ NTSTATUS status = NT_STATUS_OK;
- if (cli->fd_event != NULL) {
+ if (cli_has_async_calls(cli)) {
/*
* Can't use sync call while an async call is in flight
*/
goto fail;
}
- while (req->state < ASYNC_REQ_DONE) {
- event_loop_once(ev);
+ if (!tevent_req_poll(req, ev)) {
+ status = map_nt_error_from_unix(errno);
+ goto fail;
}
status = cli_session_setup_guest_recv(req);
fail:
TALLOC_FREE(frame);
+ if (!NT_STATUS_IS_OK(status)) {
+ cli_set_error(cli, status);
+ }
return status;
}
{
uint32 capabilities = cli_session_setup_capabilities(cli);
char *p;
+ NTSTATUS status;
fstring lanman;
fstr_sprintf( lanman, "Samba %s", samba_version_string());
-1, STR_TERMINATE);
p += clistr_pull(cli->inbuf, cli->server_domain, p, sizeof(fstring),
-1, STR_TERMINATE);
- fstrcpy(cli->user_name, user);
-
+ status = cli_set_username(cli, user);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
if (strstr(cli->server_type, "Samba")) {
cli->is_samba = True;
}
DATA_BLOB session_key = data_blob_null;
NTSTATUS result;
char *p;
+ bool ok;
if (passlen == 0) {
/* do nothing - guest login */
the server's domain at this point. The 'server name' is also
dodgy...
*/
- names_blob = NTLMv2_generate_names_blob(cli->called.name, workgroup);
+ names_blob = NTLMv2_generate_names_blob(NULL, cli->called.name, workgroup);
- if (!SMBNTLMv2encrypt(user, workgroup, pass, &server_chal,
+ if (!SMBNTLMv2encrypt(NULL, user, workgroup, pass, &server_chal,
&names_blob,
- &lm_response, &nt_response, &session_key)) {
+ &lm_response, &nt_response, NULL, &session_key)) {
data_blob_free(&names_blob);
data_blob_free(&server_chal);
return NT_STATUS_ACCESS_DENIED;
E_deshash(pass, session_key.data);
memset(&session_key.data[8], '\0', 8);
#else
- SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data);
+ SMBsesskeygen_ntv1(nt_hash, session_key.data);
#endif
}
-#ifdef LANMAN_ONLY
- cli_simple_set_signing(cli, session_key, lm_response);
-#else
- cli_simple_set_signing(cli, session_key, nt_response);
-#endif
+ cli_temp_set_signing(cli);
} else {
/* pre-encrypted password supplied. Only used for
security=server, can't do
goto end;
}
+#ifdef LANMAN_ONLY
+ ok = cli_simple_set_signing(cli, session_key, lm_response);
+#else
+ ok = cli_simple_set_signing(cli, session_key, nt_response);
+#endif
+ if (ok) {
+ if (!cli_check_sign_mac(cli, cli->inbuf, 1)) {
+ result = NT_STATUS_ACCESS_DENIED;
+ goto end;
+ }
+ }
+
/* use the returned vuid from now on */
cli->vuid = SVAL(cli->inbuf,smb_uid);
cli->is_samba = True;
}
- fstrcpy(cli->user_name, user);
+ result = cli_set_username(cli, user);
+ if (!NT_STATUS_IS_OK(result)) {
+ goto end;
+ }
if (session_key.data) {
/* Have plaintext orginal */
if (cli_simple_set_signing(
cli, session_key_krb5, data_blob_null)) {
- /* 'resign' the last message, so we get the right sequence numbers
- for checking the first reply from the server */
- cli_calculate_sign_mac(cli, cli->outbuf);
-
- if (!cli_check_sign_mac(cli, cli->inbuf)) {
+ if (!cli_check_sign_mac(cli, cli->inbuf, 1)) {
nt_status = NT_STATUS_ACCESS_DENIED;
goto nt_error;
}
if (cli_simple_set_signing(
cli, ntlmssp_state->session_key, data_blob_null)) {
- /* 'resign' the last message, so we get the right sequence numbers
- for checking the first reply from the server */
- cli_calculate_sign_mac(cli, cli->outbuf);
-
- if (!cli_check_sign_mac(cli, cli->inbuf)) {
+ if (!cli_check_sign_mac(cli, cli->inbuf, 1)) {
nt_status = NT_STATUS_ACCESS_DENIED;
}
}
DATA_BLOB blob;
const char *p = NULL;
char *account = NULL;
+ NTSTATUS status;
DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length));
DEBUG(3,("got principal=%s\n", principal ? principal : "<null>"));
- fstrcpy(cli->user_name, user);
+ status = cli_set_username(cli, user);
+ if (!NT_STATUS_IS_OK(status)) {
+ return ADS_ERROR_NT(status);
+ }
#ifdef HAVE_KRB5
/* If password is set we reauthenticate to kerberos server
return False;
}
- cli->cnum = -1;
+ cli->vuid = -1;
return True;
}
Send a tconX.
****************************************************************************/
-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)
+struct cli_tcon_andx_state {
+ struct cli_state *cli;
+ uint16_t vwv[4];
+ struct iovec bytes;
+};
+
+static void cli_tcon_andx_done(struct tevent_req *subreq);
+
+struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli,
+ const char *share, const char *dev,
+ const char *pass, int passlen,
+ struct tevent_req **psmbreq)
{
+ struct tevent_req *req, *subreq;
+ struct cli_tcon_andx_state *state;
fstring pword;
+ uint16_t *vwv;
char *tmp = NULL;
- struct async_req *result;
- uint16_t vwv[4];
uint8_t *bytes;
+ req = tevent_req_create(mem_ctx, &state, struct cli_tcon_andx_state);
+ if (req == NULL) {
+ return NULL;
+ }
+ state->cli = cli;
+ vwv = state->vwv;
+
fstrcpy(cli->share, share);
/* in user level security don't send a password now */
SSVAL(vwv+3, 0, passlen);
if (passlen) {
- bytes = (uint8_t *)talloc_memdup(talloc_tos(), pword, passlen);
+ bytes = (uint8_t *)talloc_memdup(state, pword, passlen);
} else {
- bytes = talloc_array(talloc_tos(), uint8_t, 0);
+ bytes = talloc_array(state, uint8_t, 0);
}
/*
tmp = talloc_asprintf_strupper_m(talloc_tos(), "\\\\%s\\%s",
cli->desthost, share);
if (tmp == NULL) {
- TALLOC_FREE(bytes);
+ TALLOC_FREE(req);
return NULL;
}
bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), tmp, strlen(tmp)+1,
*/
tmp = talloc_strdup_upper(talloc_tos(), dev);
if (tmp == NULL) {
- TALLOC_FREE(bytes);
+ TALLOC_FREE(req);
return NULL;
}
bytes = smb_bytes_push_str(bytes, false, tmp, strlen(tmp)+1, NULL);
TALLOC_FREE(tmp);
if (bytes == NULL) {
+ TALLOC_FREE(req);
return NULL;
}
- result = cli_request_send(mem_ctx, ev, cli, SMBtconX, 0,
- 4, vwv, 0, talloc_get_size(bytes), bytes);
- TALLOC_FREE(bytes);
- return result;
+ state->bytes.iov_base = bytes;
+ state->bytes.iov_len = talloc_get_size(bytes);
+
+ subreq = cli_smb_req_create(state, ev, cli, SMBtconX, 0, 4, vwv,
+ 1, &state->bytes);
+ if (subreq == NULL) {
+ TALLOC_FREE(req);
+ return NULL;
+ }
+ tevent_req_set_callback(subreq, cli_tcon_andx_done, req);
+ *psmbreq = subreq;
+ return req;
access_denied:
- result = async_req_new(mem_ctx);
- if (async_post_ntstatus(result, ev, NT_STATUS_ACCESS_DENIED)) {
- return result;
+ tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
+ return tevent_req_post(req, ev);
+}
+
+struct tevent_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)
+{
+ struct tevent_req *req, *subreq;
+
+ req = cli_tcon_andx_create(mem_ctx, ev, cli, share, dev, pass, passlen,
+ &subreq);
+ if ((req == NULL) || !cli_smb_req_send(subreq)) {
+ TALLOC_FREE(req);
+ return NULL;
}
- TALLOC_FREE(result);
- return NULL;
+ return req;
}
-NTSTATUS cli_tcon_andx_recv(struct async_req *req)
+static void cli_tcon_andx_done(struct tevent_req *subreq)
{
- struct cli_request *cli_req = talloc_get_type_abort(
- req->private_data, struct cli_request);
- struct cli_state *cli = cli_req->cli;
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct cli_tcon_andx_state *state = tevent_req_data(
+ req, struct cli_tcon_andx_state);
+ struct cli_state *cli = state->cli;
+ char *inbuf = (char *)cli_smb_inbuf(subreq);
uint8_t wct;
uint16_t *vwv;
- uint16_t num_bytes;
+ uint32_t num_bytes;
uint8_t *bytes;
NTSTATUS status;
- if (async_req_is_nterror(req, &status)) {
- return status;
- }
-
- status = cli_pull_reply(req, &wct, &vwv, &num_bytes, &bytes);
+ status = cli_smb_recv(subreq, 0, &wct, &vwv, &num_bytes, &bytes);
if (!NT_STATUS_IS_OK(status)) {
- return status;
+ TALLOC_FREE(subreq);
+ tevent_req_nterror(req, status);
+ return;
}
- clistr_pull(cli_req->inbuf, cli->dev, bytes, sizeof(fstring),
- num_bytes, STR_TERMINATE|STR_ASCII);
+ clistr_pull(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->dfsroot = ((SVAL(vwv+2, 0) & SMB_SHARE_IN_DFS) != 0);
}
- cli->cnum = SVAL(cli_req->inbuf,smb_tid);
- return NT_STATUS_OK;
+ cli->cnum = SVAL(inbuf,smb_tid);
+ tevent_req_done(req);
+}
+
+NTSTATUS cli_tcon_andx_recv(struct tevent_req *req)
+{
+ return tevent_req_simple_recv_ntstatus(req);
}
NTSTATUS cli_tcon_andx(struct cli_state *cli, const char *share,
{
TALLOC_CTX *frame = talloc_stackframe();
struct event_context *ev;
- struct async_req *req;
- NTSTATUS status;
+ struct tevent_req *req;
+ NTSTATUS status = NT_STATUS_OK;
- if (cli->fd_event != NULL) {
+ if (cli_has_async_calls(cli)) {
/*
* Can't use sync call while an async call is in flight
*/
goto fail;
}
- while (req->state < ASYNC_REQ_DONE) {
- event_loop_once(ev);
+ if (!tevent_req_poll(req, ev)) {
+ status = map_nt_error_from_unix(errno);
+ goto fail;
}
status = cli_tcon_andx_recv(req);
fail:
TALLOC_FREE(frame);
+ if (!NT_STATUS_IS_OK(status)) {
+ cli_set_error(cli, status);
+ }
return status;
}
Send a negprot command.
****************************************************************************/
-struct async_req *cli_negprot_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- struct cli_state *cli)
+struct cli_negprot_state {
+ struct cli_state *cli;
+};
+
+static void cli_negprot_done(struct tevent_req *subreq);
+
+struct tevent_req *cli_negprot_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct cli_state *cli)
{
- struct async_req *result;
+ struct tevent_req *req, *subreq;
+ struct cli_negprot_state *state;
uint8_t *bytes = NULL;
int numprots;
+ req = tevent_req_create(mem_ctx, &state, struct cli_negprot_state);
+ if (req == NULL) {
+ return NULL;
+ }
+ state->cli = cli;
+
if (cli->protocol < PROTOCOL_NT1)
cli->use_spnego = False;
break;
}
bytes = (uint8_t *)talloc_append_blob(
- talloc_tos(), bytes, data_blob_const(&c, sizeof(c)));
- if (bytes == NULL) {
- return NULL;
+ state, bytes, data_blob_const(&c, sizeof(c)));
+ if (tevent_req_nomem(bytes, req)) {
+ return tevent_req_post(req, ev);
}
bytes = smb_bytes_push_str(bytes, false,
prots[numprots].name,
strlen(prots[numprots].name)+1,
NULL);
- if (bytes == NULL) {
- return NULL;
+ if (tevent_req_nomem(bytes, req)) {
+ return tevent_req_post(req, ev);
}
}
- result = cli_request_send(mem_ctx, ev, cli, SMBnegprot, 0, 0, NULL, 0,
- talloc_get_size(bytes), bytes);
- TALLOC_FREE(bytes);
- return result;
+ subreq = cli_smb_send(state, ev, cli, SMBnegprot, 0, 0, NULL,
+ talloc_get_size(bytes), bytes);
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
+ }
+ tevent_req_set_callback(subreq, cli_negprot_done, req);
+ return req;
}
-NTSTATUS cli_negprot_recv(struct async_req *req)
+static void cli_negprot_done(struct tevent_req *subreq)
{
- struct cli_request *cli_req = talloc_get_type_abort(
- req->private_data, struct cli_request);
- struct cli_state *cli = cli_req->cli;
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct cli_negprot_state *state = tevent_req_data(
+ req, struct cli_negprot_state);
+ struct cli_state *cli = state->cli;
uint8_t wct;
uint16_t *vwv;
- uint16_t num_bytes;
+ uint32_t num_bytes;
uint8_t *bytes;
NTSTATUS status;
uint16_t protnum;
- if (async_req_is_nterror(req, &status)) {
- return status;
- }
-
- status = cli_pull_reply(req, &wct, &vwv, &num_bytes, &bytes);
+ status = cli_smb_recv(subreq, 1, &wct, &vwv, &num_bytes, &bytes);
if (!NT_STATUS_IS_OK(status)) {
- return status;
+ TALLOC_FREE(subreq);
+ return;
}
protnum = SVAL(vwv, 0);
if ((protnum >= ARRAY_SIZE(prots))
- || (prots[protnum].prot > cli_req->cli->protocol)) {
- return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ || (prots[protnum].prot > cli->protocol)) {
+ tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
+ return;
}
cli->protocol = prots[protnum].prot;
- if ((cli->protocol < PROTOCOL_NT1) && cli->sign_info.mandatory_signing) {
+ if ((cli->protocol < PROTOCOL_NT1) &&
+ client_is_signing_mandatory(cli)) {
DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n"));
- return NT_STATUS_ACCESS_DENIED;
+ tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
+ return;
}
if (cli->protocol >= PROTOCOL_NT1) {
struct timespec ts;
+ bool negotiated_smb_signing = false;
+
/* NT protocol */
cli->sec_mode = CVAL(vwv + 1, 0);
cli->max_mux = SVAL(vwv + 1, 1);
if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) {
/* Fail if server says signing is mandatory and we don't want to support it. */
- if (!cli->sign_info.allow_smb_signing) {
+ if (!client_is_signing_allowed(cli)) {
DEBUG(0,("cli_negprot: SMB signing is mandatory and we have disabled it.\n"));
- return NT_STATUS_ACCESS_DENIED;
+ tevent_req_nterror(req,
+ NT_STATUS_ACCESS_DENIED);
+ return;
}
- cli->sign_info.negotiated_smb_signing = True;
- cli->sign_info.mandatory_signing = True;
- } else if (cli->sign_info.mandatory_signing && cli->sign_info.allow_smb_signing) {
+ negotiated_smb_signing = true;
+ } else if (client_is_signing_mandatory(cli) && client_is_signing_allowed(cli)) {
/* Fail if client says signing is mandatory and the server doesn't support it. */
if (!(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) {
DEBUG(1,("cli_negprot: SMB signing is mandatory and the server doesn't support it.\n"));
- return NT_STATUS_ACCESS_DENIED;
+ tevent_req_nterror(req,
+ NT_STATUS_ACCESS_DENIED);
+ return;
}
- cli->sign_info.negotiated_smb_signing = True;
- cli->sign_info.mandatory_signing = True;
+ negotiated_smb_signing = true;
} else if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) {
- cli->sign_info.negotiated_smb_signing = True;
+ negotiated_smb_signing = true;
+ }
+
+ if (negotiated_smb_signing) {
+ cli_set_signing_negotiated(cli);
}
if (cli->capabilities & (CAP_LARGE_READX|CAP_LARGE_WRITEX)) {
if (getenv("CLI_FORCE_ASCII"))
cli->capabilities &= ~CAP_UNICODE;
- return NT_STATUS_OK;
+ tevent_req_done(req);
+}
+
+NTSTATUS cli_negprot_recv(struct tevent_req *req)
+{
+ return tevent_req_simple_recv_ntstatus(req);
}
NTSTATUS cli_negprot(struct cli_state *cli)
{
TALLOC_CTX *frame = talloc_stackframe();
struct event_context *ev;
- struct async_req *req;
- NTSTATUS status = NT_STATUS_NO_MEMORY;
+ struct tevent_req *req;
+ NTSTATUS status = NT_STATUS_OK;
- if (cli->fd_event != NULL) {
+ if (cli_has_async_calls(cli)) {
/*
* Can't use sync call while an async call is in flight
*/
- cli_set_error(cli, NT_STATUS_INVALID_PARAMETER);
+ status = NT_STATUS_INVALID_PARAMETER;
goto fail;
}
ev = event_context_init(frame);
if (ev == NULL) {
+ status = NT_STATUS_NO_MEMORY;
goto fail;
}
req = cli_negprot_send(frame, ev, cli);
if (req == NULL) {
+ status = NT_STATUS_NO_MEMORY;
goto fail;
}
- while (req->state < ASYNC_REQ_DONE) {
- event_loop_once(ev);
+ if (!tevent_req_poll(req, ev)) {
+ status = map_nt_error_from_unix(errno);
+ goto fail;
}
status = cli_negprot_recv(req);
fail:
TALLOC_FREE(frame);
+ if (!NT_STATUS_IS_OK(status)) {
+ cli_set_error(cli, status);
+ }
return status;
}
return(True);
}
-static void smb_sock_connected(struct async_req *req)
+struct fd_struct {
+ int fd;
+};
+
+static void smb_sock_connected(struct tevent_req *req)
{
- int *pfd = (int *)req->async.priv;
+ struct fd_struct *pfd = tevent_req_callback_data(
+ req, struct fd_struct);
int fd;
NTSTATUS status;
status = open_socket_out_defer_recv(req, &fd);
if (NT_STATUS_IS_OK(status)) {
- *pfd = fd;
+ pfd->fd = fd;
}
}
uint16_t *port, int timeout, int *pfd)
{
struct event_context *ev;
- struct async_req *r139, *r445;
- int fd139 = -1;
- int fd445 = -1;
- NTSTATUS status;
+ struct tevent_req *r139, *r445;
+ struct fd_struct *fd139, *fd445;
+ NTSTATUS status = NT_STATUS_NO_MEMORY;
if (*port != 0) {
return open_socket_out(pss, *port, timeout, pfd);
return NT_STATUS_NO_MEMORY;
}
+ fd139 = talloc(ev, struct fd_struct);
+ if (fd139 == NULL) {
+ goto done;
+ }
+ fd139->fd = -1;
+
+ fd445 = talloc(ev, struct fd_struct);
+ if (fd445 == NULL) {
+ goto done;
+ }
+ fd445->fd = -1;
+
r445 = open_socket_out_defer_send(ev, ev, timeval_set(0, 0),
pss, 445, timeout);
r139 = open_socket_out_defer_send(ev, ev, timeval_set(0, 3000),
pss, 139, timeout);
if ((r445 == NULL) || (r139 == NULL)) {
- status = NT_STATUS_NO_MEMORY;
goto done;
}
- r445->async.fn = smb_sock_connected;
- r445->async.priv = &fd445;
- r139->async.fn = smb_sock_connected;
- r139->async.priv = &fd139;
+ tevent_req_set_callback(r445, smb_sock_connected, fd445);
+ tevent_req_set_callback(r139, smb_sock_connected, fd139);
- while ((fd139 == -1) && (r139->state < ASYNC_REQ_DONE)
- && (fd445 == -1) && (r445->state < ASYNC_REQ_DONE)) {
+ while ((fd445->fd == -1) && (fd139->fd == -1)
+ && (tevent_req_is_in_progress(r139)
+ || tevent_req_is_in_progress(r445))) {
event_loop_once(ev);
}
- if ((fd139 != -1) && (fd445 != -1)) {
- close(fd139);
- fd139 = -1;
+ if ((fd139->fd != -1) && (fd445->fd != -1)) {
+ close(fd139->fd);
+ fd139->fd = -1;
}
- if (fd445 != -1) {
+ if (fd445->fd != -1) {
*port = 445;
- *pfd = fd445;
+ *pfd = fd445->fd;
status = NT_STATUS_OK;
goto done;
}
- if (fd139 != -1) {
+ if (fd139->fd != -1) {
*port = 139;
- *pfd = fd139;
+ *pfd = fd139->fd;
status = NT_STATUS_OK;
goto done;
}
- status = open_socket_out_defer_recv(r445, &fd445);
+ status = open_socket_out_defer_recv(r445, &fd445->fd);
done:
TALLOC_FREE(ev);
return status;
if (!my_name)
my_name = global_myname();
- if (!(cli = cli_initialise())) {
+ if (!(cli = cli_initialise_ex(signing_state))) {
return NT_STATUS_NO_MEMORY;
}
return NT_STATUS_BAD_NETWORK_NAME;
}
- cli_setup_signing_state(cli, signing_state);
-
if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO)
cli->use_spnego = False;
else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS)
return nt_status;
}
+ cli->use_oplocks = ((flags & CLI_FULL_CONNECTION_OPLOCKS) != 0);
+ cli->use_level_II_oplocks =
+ ((flags & CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS) != 0);
+
nt_status = cli_session_setup(cli, user, password, pw_len, password,
pw_len, domain);
if (!NT_STATUS_IS_OK(nt_status)) {
}
}
- cli_init_creds(cli, user, domain, password);
+ nt_status = cli_init_creds(cli, user, domain, password);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ cli_shutdown(cli);
+ return nt_status;
+ }
*output_cli = cli;
return NT_STATUS_OK;