From 99ef6a4bec1058b3649e5e72f8ea85f6df93a154 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 30 Nov 2011 08:50:11 +0100 Subject: s4:libcli: do the nbss session request within smbcli_sock_connect_*() metze --- source4/libcli/cliconnect.c | 12 +-- source4/libcli/raw/clisocket.c | 133 +++++++++++++++++++-------------- source4/libcli/smb2/connect.c | 56 +++++--------- source4/libcli/smb_composite/connect.c | 54 ++++--------- 4 files changed, 108 insertions(+), 147 deletions(-) diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index 4047d36369..a8e86a0488 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -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; diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index 6a305fe223..258fe8b091 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -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); } diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index 0d97691a44..6b980f2e0e 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -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; - - creq = resolve_name_send(resolve_ctx, state, &name, ev); - if (tevent_req_nomem(creq, req)) { - return tevent_req_post(req, ev); + if (state->ports == NULL) { + state->ports = default_ports; } - creq->async.fn = smb2_connect_resolve_done; - creq->async.private_data = req; - return req; -} -static void smb2_connect_socket_done(struct composite_context *creq); + make_nbt_name_client(&state->calling, + cli_credentials_get_workstation(credentials)); -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; - } + nbt_choose_called_name(state, &state->called, + host, NBT_NAME_SERVER); - if (state->ports == NULL) { - ports = default_ports; - } else { - ports = state->ports; - } - - creq = smbcli_sock_connect_send(state, addr, ports, + creq = smbcli_sock_connect_send(state, NULL, state->ports, state->host, state->resolve_ctx, - state->ev, state->socket_options); + state->ev, state->socket_options, + &state->calling, + &state->called); if (tevent_req_nomem(creq, req)) { - return; + return tevent_req_post(req, ev); } creq->async.fn = smb2_connect_socket_done; creq->async.private_data = req; + + return req; } static void smb2_connect_negprot_done(struct tevent_req *subreq); diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index 306b96c167..0f66f2873d 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -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; -- cgit