mirror of
https://github.com/samba-team/samba.git
synced 2025-08-26 01:49:31 +03:00
s4:libcli: do the nbss session request within smbcli_sock_connect_*()
metze
This commit is contained in:
@ -39,8 +39,7 @@ bool smbcli_socket_connect(struct smbcli_state *cli, const char *server,
|
||||
struct nbt_name *calling,
|
||||
struct nbt_name *called)
|
||||
{
|
||||
struct smbcli_socket *sock;
|
||||
uint32_t timeout_msec = options->request_timeout * 1000;
|
||||
struct smbcli_socket *sock = NULL;
|
||||
NTSTATUS status;
|
||||
|
||||
status = smbcli_sock_connect(cli,
|
||||
@ -50,18 +49,13 @@ bool smbcli_socket_connect(struct smbcli_state *cli, const char *server,
|
||||
resolve_ctx,
|
||||
ev_ctx,
|
||||
socket_options,
|
||||
calling,
|
||||
called,
|
||||
&sock);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
status = smbcli_transport_connect(sock,
|
||||
timeout_msec,
|
||||
calling, called);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
cli->transport = smbcli_transport_init(sock, cli, true, options);
|
||||
if (!cli->transport) {
|
||||
return false;
|
||||
|
@ -35,7 +35,7 @@
|
||||
|
||||
struct smbcli_transport_connect_state {
|
||||
struct tevent_context *ev;
|
||||
struct smbcli_socket *sock;
|
||||
struct socket_context *sock;
|
||||
uint8_t *request;
|
||||
struct iovec iov;
|
||||
uint8_t *response;
|
||||
@ -44,9 +44,10 @@ struct smbcli_transport_connect_state {
|
||||
static void smbcli_transport_connect_writev_done(struct tevent_req *subreq);
|
||||
static void smbcli_transport_connect_read_smb_done(struct tevent_req *subreq);
|
||||
|
||||
struct tevent_req *smbcli_transport_connect_send(TALLOC_CTX *mem_ctx,
|
||||
static struct tevent_req *smbcli_transport_connect_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct smbcli_socket *sock,
|
||||
struct socket_context *sock,
|
||||
uint16_t port,
|
||||
uint32_t timeout_msec,
|
||||
struct nbt_name *calling,
|
||||
struct nbt_name *called)
|
||||
@ -66,7 +67,7 @@ struct tevent_req *smbcli_transport_connect_send(TALLOC_CTX *mem_ctx,
|
||||
state->ev = ev;
|
||||
state->sock = sock;
|
||||
|
||||
if (sock->port != 139) {
|
||||
if (port != 139) {
|
||||
tevent_req_done(req);
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
@ -105,7 +106,7 @@ struct tevent_req *smbcli_transport_connect_send(TALLOC_CTX *mem_ctx,
|
||||
state->iov.iov_base = (void *)state->request;
|
||||
|
||||
subreq = writev_send(state, ev, NULL,
|
||||
sock->sock->fd,
|
||||
sock->fd,
|
||||
true, /* err_on_readability */
|
||||
&state->iov, 1);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
@ -143,15 +144,15 @@ static void smbcli_transport_connect_writev_done(struct tevent_req *subreq)
|
||||
if (ret == -1) {
|
||||
NTSTATUS status = map_nt_error_from_unix_common(err);
|
||||
|
||||
close(state->sock->sock->fd);
|
||||
state->sock->sock->fd = -1;
|
||||
close(state->sock->fd);
|
||||
state->sock->fd = -1;
|
||||
|
||||
tevent_req_nterror(req, status);
|
||||
return;
|
||||
}
|
||||
|
||||
subreq = read_smb_send(state, state->ev,
|
||||
state->sock->sock->fd);
|
||||
state->sock->fd);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return;
|
||||
}
|
||||
@ -178,16 +179,16 @@ static void smbcli_transport_connect_read_smb_done(struct tevent_req *subreq)
|
||||
if (ret == -1) {
|
||||
status = map_nt_error_from_unix_common(err);
|
||||
|
||||
close(state->sock->sock->fd);
|
||||
state->sock->sock->fd = -1;
|
||||
close(state->sock->fd);
|
||||
state->sock->fd = -1;
|
||||
|
||||
tevent_req_nterror(req, status);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ret < 4) {
|
||||
close(state->sock->sock->fd);
|
||||
state->sock->sock->fd = -1;
|
||||
close(state->sock->fd);
|
||||
state->sock->fd = -1;
|
||||
|
||||
tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
|
||||
return;
|
||||
@ -200,8 +201,8 @@ static void smbcli_transport_connect_read_smb_done(struct tevent_req *subreq)
|
||||
|
||||
case NBSSnegative:
|
||||
if (ret < 5) {
|
||||
close(state->sock->sock->fd);
|
||||
state->sock->sock->fd = -1;
|
||||
close(state->sock->fd);
|
||||
state->sock->fd = -1;
|
||||
|
||||
tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
|
||||
return;
|
||||
@ -235,49 +236,17 @@ static void smbcli_transport_connect_read_smb_done(struct tevent_req *subreq)
|
||||
break;
|
||||
}
|
||||
|
||||
close(state->sock->sock->fd);
|
||||
state->sock->sock->fd = -1;
|
||||
close(state->sock->fd);
|
||||
state->sock->fd = -1;
|
||||
|
||||
tevent_req_nterror(req, status);
|
||||
}
|
||||
|
||||
NTSTATUS smbcli_transport_connect_recv(struct tevent_req *req)
|
||||
static NTSTATUS smbcli_transport_connect_recv(struct tevent_req *req)
|
||||
{
|
||||
return tevent_req_simple_recv_ntstatus(req);
|
||||
}
|
||||
|
||||
NTSTATUS smbcli_transport_connect(struct smbcli_socket *sock,
|
||||
uint32_t timeout_msec,
|
||||
struct nbt_name *calling,
|
||||
struct nbt_name *called)
|
||||
{
|
||||
TALLOC_CTX *frame = talloc_stackframe();
|
||||
struct tevent_context *ev;
|
||||
struct tevent_req *req;
|
||||
NTSTATUS status = NT_STATUS_NO_MEMORY;
|
||||
bool ok;
|
||||
|
||||
ev = tevent_context_init(frame);
|
||||
if (ev == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
req = smbcli_transport_connect_send(frame, ev, sock,
|
||||
timeout_msec,
|
||||
calling, called);
|
||||
if (req == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
ok = tevent_req_poll(req, ev);
|
||||
if (!ok) {
|
||||
status = map_nt_error_from_unix_common(errno);
|
||||
goto fail;
|
||||
}
|
||||
status = smbcli_transport_connect_recv(req);
|
||||
fail:
|
||||
TALLOC_FREE(frame);
|
||||
return status;
|
||||
}
|
||||
|
||||
struct sock_connect_state {
|
||||
struct composite_context *ctx;
|
||||
const char *host_name;
|
||||
@ -285,6 +254,9 @@ struct sock_connect_state {
|
||||
uint16_t *ports;
|
||||
const char *socket_options;
|
||||
struct smbcli_socket *result;
|
||||
struct socket_connect_multi_ex multi_ex;
|
||||
struct nbt_name calling;
|
||||
struct nbt_name called;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -292,6 +264,31 @@ struct sock_connect_state {
|
||||
if port is 0 then choose 445 then 139
|
||||
*/
|
||||
|
||||
static struct tevent_req *smbcli_sock_establish_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct socket_context *sock,
|
||||
struct socket_address *addr,
|
||||
void *private_data)
|
||||
{
|
||||
struct sock_connect_state *state =
|
||||
talloc_get_type_abort(private_data,
|
||||
struct sock_connect_state);
|
||||
uint32_t timeout_msec = 15 * 1000;
|
||||
|
||||
return smbcli_transport_connect_send(state,
|
||||
ev,
|
||||
sock,
|
||||
addr->port,
|
||||
timeout_msec,
|
||||
&state->calling,
|
||||
&state->called);
|
||||
}
|
||||
|
||||
static NTSTATUS smbcli_sock_establish_recv(struct tevent_req *req)
|
||||
{
|
||||
return smbcli_transport_connect_recv(req);
|
||||
}
|
||||
|
||||
static void smbcli_sock_connect_recv_conn(struct composite_context *ctx);
|
||||
|
||||
struct composite_context *smbcli_sock_connect_send(TALLOC_CTX *mem_ctx,
|
||||
@ -300,10 +297,13 @@ struct composite_context *smbcli_sock_connect_send(TALLOC_CTX *mem_ctx,
|
||||
const char *host_name,
|
||||
struct resolve_context *resolve_ctx,
|
||||
struct tevent_context *event_ctx,
|
||||
const char *socket_options)
|
||||
const char *socket_options,
|
||||
struct nbt_name *calling,
|
||||
struct nbt_name *called)
|
||||
{
|
||||
struct composite_context *result, *ctx;
|
||||
struct sock_connect_state *state;
|
||||
NTSTATUS status;
|
||||
int i;
|
||||
|
||||
result = talloc_zero(mem_ctx, struct composite_context);
|
||||
@ -333,10 +333,24 @@ struct composite_context *smbcli_sock_connect_send(TALLOC_CTX *mem_ctx,
|
||||
host_addr = host_name;
|
||||
}
|
||||
|
||||
ctx = socket_connect_multi_send(state, host_addr,
|
||||
state->num_ports, state->ports,
|
||||
resolve_ctx,
|
||||
state->ctx->event_ctx);
|
||||
state->multi_ex.private_data = state;
|
||||
state->multi_ex.establish_send = smbcli_sock_establish_send;
|
||||
state->multi_ex.establish_recv = smbcli_sock_establish_recv;
|
||||
|
||||
status = nbt_name_dup(state, calling, &state->calling);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
goto failed;
|
||||
}
|
||||
status = nbt_name_dup(state, called, &state->called);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
ctx = socket_connect_multi_ex_send(state, host_addr,
|
||||
state->num_ports, state->ports,
|
||||
resolve_ctx,
|
||||
state->ctx->event_ctx,
|
||||
&state->multi_ex);
|
||||
if (ctx == NULL) goto failed;
|
||||
ctx->async.fn = smbcli_sock_connect_recv_conn;
|
||||
ctx->async.private_data = state;
|
||||
@ -355,8 +369,8 @@ static void smbcli_sock_connect_recv_conn(struct composite_context *ctx)
|
||||
struct socket_context *sock;
|
||||
uint16_t port;
|
||||
|
||||
state->ctx->status = socket_connect_multi_recv(ctx, state, &sock,
|
||||
&port);
|
||||
state->ctx->status = socket_connect_multi_ex_recv(ctx, state, &sock,
|
||||
&port);
|
||||
if (!composite_is_ok(state->ctx)) return;
|
||||
|
||||
state->ctx->status =
|
||||
@ -406,13 +420,16 @@ NTSTATUS smbcli_sock_connect(TALLOC_CTX *mem_ctx,
|
||||
const char *host_name,
|
||||
struct resolve_context *resolve_ctx,
|
||||
struct tevent_context *event_ctx,
|
||||
const char *socket_options,
|
||||
const char *socket_options,
|
||||
struct nbt_name *calling,
|
||||
struct nbt_name *called,
|
||||
struct smbcli_socket **result)
|
||||
{
|
||||
struct composite_context *c =
|
||||
smbcli_sock_connect_send(mem_ctx, host_addr, ports, host_name,
|
||||
resolve_ctx,
|
||||
event_ctx, socket_options);
|
||||
event_ctx, socket_options,
|
||||
calling, called);
|
||||
return smbcli_sock_connect_recv(c, mem_ctx, result);
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "libcli/composite/composite.h"
|
||||
#include "libcli/resolve/resolve.h"
|
||||
#include "param/param.h"
|
||||
#include "auth/credentials/credentials.h"
|
||||
#include "../libcli/smb/smbXcli_base.h"
|
||||
|
||||
struct smb2_connect_state {
|
||||
@ -39,6 +40,7 @@ struct smb2_connect_state {
|
||||
const char *share;
|
||||
const char **ports;
|
||||
const char *socket_options;
|
||||
struct nbt_name calling, called;
|
||||
struct gensec_settings *gensec_settings;
|
||||
struct smbcli_options options;
|
||||
struct smb2_transport *transport;
|
||||
@ -47,7 +49,7 @@ struct smb2_connect_state {
|
||||
struct smb2_tree *tree;
|
||||
};
|
||||
|
||||
static void smb2_connect_resolve_done(struct composite_context *creq);
|
||||
static void smb2_connect_socket_done(struct composite_context *creq);
|
||||
|
||||
/*
|
||||
a composite function that does a full negprot/sesssetup/tcon, returning
|
||||
@ -66,8 +68,8 @@ struct tevent_req *smb2_connect_send(TALLOC_CTX *mem_ctx,
|
||||
{
|
||||
struct tevent_req *req;
|
||||
struct smb2_connect_state *state;
|
||||
struct nbt_name name;
|
||||
struct composite_context *creq;
|
||||
static const char *default_ports[] = { "445", "139", NULL };
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state,
|
||||
struct smb2_connect_state);
|
||||
@ -85,52 +87,28 @@ struct tevent_req *smb2_connect_send(TALLOC_CTX *mem_ctx,
|
||||
state->socket_options = socket_options;
|
||||
state->gensec_settings = gensec_settings;
|
||||
|
||||
ZERO_STRUCT(name);
|
||||
name.name = host;
|
||||
if (state->ports == NULL) {
|
||||
state->ports = default_ports;
|
||||
}
|
||||
|
||||
creq = resolve_name_send(resolve_ctx, state, &name, ev);
|
||||
make_nbt_name_client(&state->calling,
|
||||
cli_credentials_get_workstation(credentials));
|
||||
|
||||
nbt_choose_called_name(state, &state->called,
|
||||
host, NBT_NAME_SERVER);
|
||||
|
||||
creq = smbcli_sock_connect_send(state, NULL, state->ports,
|
||||
state->host, state->resolve_ctx,
|
||||
state->ev, state->socket_options,
|
||||
&state->calling,
|
||||
&state->called);
|
||||
if (tevent_req_nomem(creq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
creq->async.fn = smb2_connect_resolve_done;
|
||||
creq->async.private_data = req;
|
||||
return req;
|
||||
}
|
||||
|
||||
static void smb2_connect_socket_done(struct composite_context *creq);
|
||||
|
||||
static void smb2_connect_resolve_done(struct composite_context *creq)
|
||||
{
|
||||
struct tevent_req *req =
|
||||
talloc_get_type_abort(creq->async.private_data,
|
||||
struct tevent_req);
|
||||
struct smb2_connect_state *state =
|
||||
tevent_req_data(req,
|
||||
struct smb2_connect_state);
|
||||
NTSTATUS status;
|
||||
const char *addr;
|
||||
const char **ports;
|
||||
const char *default_ports[] = { "445", NULL };
|
||||
|
||||
status = resolve_name_recv(creq, state, &addr);
|
||||
if (tevent_req_nterror(req, status)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (state->ports == NULL) {
|
||||
ports = default_ports;
|
||||
} else {
|
||||
ports = state->ports;
|
||||
}
|
||||
|
||||
creq = smbcli_sock_connect_send(state, addr, ports,
|
||||
state->host, state->resolve_ctx,
|
||||
state->ev, state->socket_options);
|
||||
if (tevent_req_nomem(creq, req)) {
|
||||
return;
|
||||
}
|
||||
creq->async.fn = smb2_connect_socket_done;
|
||||
creq->async.private_data = req;
|
||||
|
||||
return req;
|
||||
}
|
||||
|
||||
static void smb2_connect_negprot_done(struct tevent_req *subreq);
|
||||
|
@ -34,7 +34,6 @@
|
||||
|
||||
/* the stages of this call */
|
||||
enum connect_stage {CONNECT_SOCKET,
|
||||
CONNECT_SESSION_REQUEST,
|
||||
CONNECT_NEGPROT,
|
||||
CONNECT_SESSION_SETUP,
|
||||
CONNECT_SESSION_SETUP_ANON,
|
||||
@ -53,6 +52,7 @@ struct connect_state {
|
||||
struct smbcli_request *req;
|
||||
struct composite_context *creq;
|
||||
struct tevent_req *subreq;
|
||||
struct nbt_name calling, called;
|
||||
};
|
||||
|
||||
|
||||
@ -293,24 +293,6 @@ static NTSTATUS connect_send_negprot(struct composite_context *c,
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
a session request operation has completed
|
||||
*/
|
||||
static NTSTATUS connect_session_request(struct composite_context *c,
|
||||
struct smb_composite_connect *io)
|
||||
{
|
||||
struct connect_state *state = talloc_get_type(c->private_data, struct connect_state);
|
||||
NTSTATUS status;
|
||||
|
||||
status = smbcli_transport_connect_recv(state->subreq);
|
||||
TALLOC_FREE(state->subreq);
|
||||
NT_STATUS_NOT_OK_RETURN(status);
|
||||
|
||||
/* next step is a negprot */
|
||||
return connect_send_negprot(c, io);
|
||||
}
|
||||
|
||||
/*
|
||||
a socket connection operation has completed
|
||||
*/
|
||||
@ -319,8 +301,6 @@ static NTSTATUS connect_socket(struct composite_context *c,
|
||||
{
|
||||
struct connect_state *state = talloc_get_type(c->private_data, struct connect_state);
|
||||
NTSTATUS status;
|
||||
struct nbt_name calling, called;
|
||||
uint32_t timeout_msec = io->in.options.request_timeout * 1000;
|
||||
|
||||
status = smbcli_sock_connect_recv(state->creq, state, &state->sock);
|
||||
NT_STATUS_NOT_OK_RETURN(status);
|
||||
@ -340,25 +320,12 @@ static NTSTATUS connect_socket(struct composite_context *c,
|
||||
NT_STATUS_HAVE_NO_MEMORY(state->sock->hostname);
|
||||
}
|
||||
|
||||
make_nbt_name_client(&calling, cli_credentials_get_workstation(io->in.credentials));
|
||||
|
||||
nbt_choose_called_name(state, &called, io->in.called_name, NBT_NAME_SERVER);
|
||||
|
||||
status = nbt_name_dup(state->transport, &called,
|
||||
status = nbt_name_dup(state->transport, &state->called,
|
||||
&state->transport->called);
|
||||
NT_STATUS_NOT_OK_RETURN(status);
|
||||
|
||||
state->subreq = smbcli_transport_connect_send(state,
|
||||
state->transport->ev,
|
||||
state->transport->socket,
|
||||
timeout_msec,
|
||||
&calling, &called);
|
||||
NT_STATUS_HAVE_NO_MEMORY(state->subreq);
|
||||
|
||||
tevent_req_set_callback(state->subreq, subreq_handler, c);
|
||||
state->stage = CONNECT_SESSION_REQUEST;
|
||||
|
||||
return NT_STATUS_OK;
|
||||
/* next step is a negprot */
|
||||
return connect_send_negprot(c, io);
|
||||
}
|
||||
|
||||
|
||||
@ -373,9 +340,6 @@ static void state_handler(struct composite_context *c)
|
||||
case CONNECT_SOCKET:
|
||||
c->status = connect_socket(c, state->io);
|
||||
break;
|
||||
case CONNECT_SESSION_REQUEST:
|
||||
c->status = connect_session_request(c, state->io);
|
||||
break;
|
||||
case CONNECT_NEGPROT:
|
||||
c->status = connect_negprot(c, state->io);
|
||||
break;
|
||||
@ -458,12 +422,20 @@ struct composite_context *smb_composite_connect_send(struct smb_composite_connec
|
||||
c->state = COMPOSITE_STATE_IN_PROGRESS;
|
||||
c->private_data = state;
|
||||
|
||||
make_nbt_name_client(&state->calling,
|
||||
cli_credentials_get_workstation(io->in.credentials));
|
||||
|
||||
nbt_choose_called_name(state, &state->called,
|
||||
io->in.called_name, NBT_NAME_SERVER);
|
||||
|
||||
state->creq = smbcli_sock_connect_send(state,
|
||||
NULL,
|
||||
io->in.dest_ports,
|
||||
io->in.dest_host,
|
||||
resolve_ctx, c->event_ctx,
|
||||
io->in.socket_options);
|
||||
io->in.socket_options,
|
||||
&state->calling,
|
||||
&state->called);
|
||||
if (state->creq == NULL) goto failed;
|
||||
|
||||
state->stage = CONNECT_SOCKET;
|
||||
|
Reference in New Issue
Block a user