s4:libcli: do the nbss session request within smbcli_sock_connect_*()
authorStefan Metzmacher <metze@samba.org>
Wed, 30 Nov 2011 07:50:11 +0000 (08:50 +0100)
committerStefan Metzmacher <metze@samba.org>
Wed, 30 Nov 2011 12:41:09 +0000 (13:41 +0100)
metze

source4/libcli/cliconnect.c
source4/libcli/raw/clisocket.c
source4/libcli/smb2/connect.c
source4/libcli/smb_composite/connect.c

index 4047d36369c9bdfcf6afaa454c88f789fac8bdd7..a8e86a04888e573e073580bde4db11c16aba3e98 100644 (file)
@@ -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;
index 6a305fe223b4c7cb643f8e3cb6bf85af61440998..258fe8b09153ebf70192dc3b133f8598a10aa4cb 100644 (file)
@@ -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);
 }
 
index 0d97691a440582bf2dd66dbdc7cf747f392be614..6b980f2e0ef3b75c4aa4d5f39cd69474c037c0ca 100644 (file)
@@ -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);
index 306b96c1679717df9cddddde2ad7f3c5cd79970c..0f66f2873d0feb8c4511e6c89e72e106c1f8c13f 100644 (file)
@@ -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;