r11812: Convert winbind to the async bind routines. Also remove tridge's hack for the
authorVolker Lendecke <vlendec@samba.org>
Sun, 20 Nov 2005 17:34:56 +0000 (17:34 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:46:32 +0000 (13:46 -0500)
winbind "bug" :-)

Volker
(This used to be commit fb9a3c7ef376f289288c71bc47d67f548ddb7194)

source4/libcli/raw/clitransport.c
source4/librpc/rpc/dcerpc_auth.c
source4/winbind/wb_async_helpers.c
source4/winbind/wb_connect_lsa.c
source4/winbind/wb_connect_sam.c
source4/winbind/wb_init_domain.c

index 83b73f2e302d0bf599bf4017923e15bed753c14a..1cd0a3046e0f81034f7a096ca0b0c92423b42e43 100644 (file)
@@ -122,11 +122,7 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock,
                                                    transport);
 
        packet_set_fde(transport->packet, transport->socket->event.fde);
-#if 0
-       /* winbind relies on non-serialised connections for dcerpc bind. Once that is
-          fixed we can go back to serialised connections */
        packet_set_serialise(transport->packet);
-#endif
        talloc_set_destructor(transport, transport_destructor);
 
        return transport;
index 29ab80da7ab11bf35e0f20c1a5c8165026f3b590..c0d4c5583583dd510171712eb2983099b256d58f 100644 (file)
@@ -149,12 +149,12 @@ static void bind_auth_recv_bindreply(struct composite_context *creq)
        bind_auth_next_step(c);
 }
 
-static struct composite_context *dcerpc_bind_auth_send(struct dcerpc_pipe *p,
-                                                      TALLOC_CTX *mem_ctx,
-                                                      const char *uuid, uint_t version,
-                                                      struct cli_credentials *credentials,
-                                                      uint8_t auth_type,
-                                                      const char *service)
+struct composite_context *dcerpc_bind_auth_send(TALLOC_CTX *mem_ctx,
+                                               struct dcerpc_pipe *p,
+                                               const char *uuid, uint_t version,
+                                               struct cli_credentials *credentials,
+                                               uint8_t auth_type,
+                                               const char *service)
 {
        struct composite_context *c, *creq;
        struct bind_auth_state *state;
@@ -273,7 +273,7 @@ static struct composite_context *dcerpc_bind_auth_send(struct dcerpc_pipe *p,
        return c;
 }
 
-static NTSTATUS dcerpc_bind_auth_recv(struct composite_context *creq)
+NTSTATUS dcerpc_bind_auth_recv(struct composite_context *creq)
 {
        NTSTATUS result = composite_wait(creq);
        talloc_free(creq);
index 51907c13501083a1a2dc425458da8099675a6598..cfbfe5f74fb7215ba844cd257fc2cbe0f4542683 100644 (file)
@@ -175,7 +175,6 @@ NTSTATUS wb_finddcs(TALLOC_CTX *mem_ctx,
 }
 
 struct get_schannel_creds_state {
-       struct composite_context *ctx;
        struct cli_credentials *wks_creds;
        struct dcerpc_pipe *p;
        struct netr_ServerReqChallenge r;
@@ -186,6 +185,7 @@ struct get_schannel_creds_state {
        struct netr_ServerAuthenticate2 a;
 };
 
+static void get_schannel_creds_recv_anonbind(struct composite_context *creq);
 static void get_schannel_creds_recv_auth(struct rpc_request *req);
 static void get_schannel_creds_recv_chal(struct rpc_request *req);
 static void get_schannel_creds_recv_pipe(struct composite_context *ctx);
@@ -195,90 +195,117 @@ struct composite_context *wb_get_schannel_creds_send(TALLOC_CTX *mem_ctx,
                                                     struct smbcli_tree *tree,
                                                     struct event_context *ev)
 {
-       struct composite_context *result, *ctx;
+       struct composite_context *c, *creq;
        struct get_schannel_creds_state *state;
 
-       result = talloc(mem_ctx, struct composite_context);
-       if (result == NULL) goto failed;
-       result->state = COMPOSITE_STATE_IN_PROGRESS;
-       result->async.fn = NULL;
-       result->event_ctx = ev;
+       c = talloc_zero(mem_ctx, struct composite_context);
+       if (c == NULL) return NULL;
 
-       state = talloc(result, struct get_schannel_creds_state);
-       if (state == NULL) goto failed;
-       result->private_data = state;
-       state->ctx = result;
+       state = talloc(c, struct get_schannel_creds_state);
+       if (state == NULL) {
+               c->status = NT_STATUS_NO_MEMORY;
+               goto failed;
+       }
+
+       c->state = COMPOSITE_STATE_IN_PROGRESS;
+       c->private_data = state;
+       c->event_ctx = ev;
 
        state->wks_creds = wks_creds;
 
        state->p = dcerpc_pipe_init(state, ev);
-       if (state->p == NULL) goto failed;
+       if (state->p == NULL) {
+               c->status = NT_STATUS_NO_MEMORY;
+               goto failed;
+       }
 
-       ctx = dcerpc_pipe_open_smb_send(state->p->conn, tree, "\\netlogon");
-       if (ctx == NULL) goto failed;
+       creq = dcerpc_pipe_open_smb_send(state->p->conn, tree, "\\netlogon");
+       if (creq == NULL) {
+               c->status = NT_STATUS_NO_MEMORY;
+               goto failed;
+       }
 
-       ctx->async.fn = get_schannel_creds_recv_pipe;
-       ctx->async.private_data = state;
-       return result;
+       creq->async.fn = get_schannel_creds_recv_pipe;
+       creq->async.private_data = c;
+
+       return c;
 
  failed:
-       talloc_free(result);
-       return NULL;
+       composite_trigger_error(c);
+       return c;
 }
 
-static void get_schannel_creds_recv_pipe(struct composite_context *ctx)
+static void get_schannel_creds_recv_pipe(struct composite_context *creq)
 {
+       struct composite_context *c =
+               talloc_get_type(creq->async.private_data,
+                               struct composite_context);
        struct get_schannel_creds_state *state =
-               talloc_get_type(ctx->async.private_data,
+               talloc_get_type(c->private_data,
                                struct get_schannel_creds_state);
-       struct rpc_request *req;
 
-       state->ctx->status = dcerpc_pipe_open_smb_recv(ctx);
-       if (!composite_is_ok(state->ctx)) return;
+       c->status = dcerpc_pipe_open_smb_recv(creq);
+       if (!composite_is_ok(c)) return;
 
-       state->ctx->status = dcerpc_bind_auth_none(state->p,
-                                                  DCERPC_NETLOGON_UUID,
-                                                  DCERPC_NETLOGON_VERSION);
-       if (!composite_is_ok(state->ctx)) return;
+       creq = dcerpc_bind_auth_none_send(state, state->p,
+                                         DCERPC_NETLOGON_UUID,
+                                         DCERPC_NETLOGON_VERSION);
+       composite_continue(c, creq, get_schannel_creds_recv_anonbind, c);
+}
+
+static void get_schannel_creds_recv_anonbind(struct composite_context *creq)
+{
+       struct composite_context *c =
+               talloc_get_type(creq->async.private_data,
+                               struct composite_context);
+       struct get_schannel_creds_state *state =
+               talloc_get_type(c->private_data,
+                               struct get_schannel_creds_state);
+       struct rpc_request *req;
+
+       c->status = dcerpc_bind_auth_none_recv(creq);
+       if (!composite_is_ok(c)) return;
 
        state->r.in.computer_name =
                cli_credentials_get_workstation(state->wks_creds);
        state->r.in.server_name =
                talloc_asprintf(state, "\\\\%s",
                                dcerpc_server_name(state->p));
-       if (composite_nomem(state->r.in.server_name, state->ctx)) return;
+       if (composite_nomem(state->r.in.server_name, c)) return;
 
        state->r.in.credentials = talloc(state, struct netr_Credential);
-       if (composite_nomem(state->r.in.credentials, state->ctx)) return;
+       if (composite_nomem(state->r.in.credentials, c)) return;
 
        state->r.out.credentials = talloc(state, struct netr_Credential);
-       if (composite_nomem(state->r.out.credentials, state->ctx)) return;
+       if (composite_nomem(state->r.out.credentials, c)) return;
 
        generate_random_buffer(state->r.in.credentials->data,
                               sizeof(state->r.in.credentials->data));
 
        req = dcerpc_netr_ServerReqChallenge_send(state->p, state, &state->r);
-       composite_continue_rpc(state->ctx, req,
-                              get_schannel_creds_recv_chal, state);
+       composite_continue_rpc(c, req, get_schannel_creds_recv_chal, c);
 }
 
 static void get_schannel_creds_recv_chal(struct rpc_request *req)
 {
-       struct get_schannel_creds_state *state =
+       struct composite_context *c =
                talloc_get_type(req->async.private,
+                               struct composite_context);
+       struct get_schannel_creds_state *state =
+               talloc_get_type(c->private_data,
                                struct get_schannel_creds_state);
        const struct samr_Password *mach_pwd;
 
-       state->ctx->status = dcerpc_ndr_request_recv(req);
-       if (!composite_is_ok(state->ctx)) return;
-       state->ctx->status = state->r.out.result;
-       if (!composite_is_ok(state->ctx)) return;
+       c->status = dcerpc_ndr_request_recv(req);
+       if (!composite_is_ok(c)) return;
+       c->status = state->r.out.result;
+       if (!composite_is_ok(c)) return;
 
        state->creds_state = talloc(state, struct creds_CredentialState);
-       if (composite_nomem(state->creds_state, state->ctx)) return;
+       if (composite_nomem(state->creds_state, c)) return;
 
        mach_pwd = cli_credentials_get_nt_hash(state->wks_creds, state);
-       if (composite_nomem(mach_pwd, state->ctx)) return;
+       if (composite_nomem(mach_pwd, c)) return;
 
        state->negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS;
 
@@ -300,32 +327,34 @@ static void get_schannel_creds_recv_chal(struct rpc_request *req)
        state->a.out.credentials = &state->netr_cred;
 
        req = dcerpc_netr_ServerAuthenticate2_send(state->p, state, &state->a);
-       composite_continue_rpc(state->ctx, req,
-                              get_schannel_creds_recv_auth, state);
+       composite_continue_rpc(c, req, get_schannel_creds_recv_auth, c);
 }
 
 static void get_schannel_creds_recv_auth(struct rpc_request *req)
 {
-       struct get_schannel_creds_state *state =
+       struct composite_context *c =
                talloc_get_type(req->async.private,
+                               struct composite_context);
+       struct get_schannel_creds_state *state =
+               talloc_get_type(c->private_data,
                                struct get_schannel_creds_state);
 
-       state->ctx->status = dcerpc_ndr_request_recv(req);
-       if (!composite_is_ok(state->ctx)) return;
-       state->ctx->status = state->a.out.result;
-       if (!composite_is_ok(state->ctx)) return;
+       c->status = dcerpc_ndr_request_recv(req);
+       if (!composite_is_ok(c)) return;
+       c->status = state->a.out.result;
+       if (!composite_is_ok(c)) return;
 
        if (!creds_client_check(state->creds_state,
                                state->a.out.credentials)) {
                DEBUG(5, ("Server got us invalid creds\n"));
-               composite_error(state->ctx, NT_STATUS_UNSUCCESSFUL);
+               composite_error(c, NT_STATUS_UNSUCCESSFUL);
                return;
        }
 
        cli_credentials_set_netlogon_creds(state->wks_creds,
                                           state->creds_state);
 
-       composite_done(state->ctx);
+       composite_done(c);
 }
 
 NTSTATUS wb_get_schannel_creds_recv(struct composite_context *c,
index d5222a685460dff5bc66821b061f1e35594e5261..9443ef0dc7cd53110e1c1e4cff46777444714868 100644 (file)
@@ -43,6 +43,8 @@ struct init_lsa_state {
 };
 
 static void init_lsa_recv_pipe(struct composite_context *ctx);
+static void init_lsa_recv_anon_bind(struct composite_context *ctx);
+static void init_lsa_recv_auth_bind(struct composite_context *ctx);
 static void init_lsa_recv_openpol(struct rpc_request *req);
 
 struct composite_context *wb_init_lsa_send(TALLOC_CTX *mem_ctx,
@@ -86,17 +88,17 @@ static void init_lsa_recv_pipe(struct composite_context *ctx)
        struct init_lsa_state *state =
                talloc_get_type(ctx->async.private_data,
                                struct init_lsa_state);
-       struct rpc_request *req;
 
        state->ctx->status = dcerpc_pipe_open_smb_recv(ctx);
        if (!composite_is_ok(state->ctx)) return;
 
        switch (state->auth_type) {
        case DCERPC_AUTH_TYPE_NONE:
-               state->ctx->status =
-                       dcerpc_bind_auth_none(state->lsa_pipe,
-                                             DCERPC_LSARPC_UUID,
-                                             DCERPC_LSARPC_VERSION);
+               ctx = dcerpc_bind_auth_none_send(state, state->lsa_pipe,
+                                                DCERPC_LSARPC_UUID,
+                                                DCERPC_LSARPC_VERSION);
+               composite_continue(state->ctx, ctx, init_lsa_recv_anon_bind,
+                                  state);
                break;
        case DCERPC_AUTH_TYPE_NTLMSSP:
        case DCERPC_AUTH_TYPE_SCHANNEL:
@@ -105,17 +107,54 @@ static void init_lsa_recv_pipe(struct composite_context *ctx)
                        return;
                }
                state->lsa_pipe->conn->flags |= (DCERPC_SIGN | DCERPC_SEAL);
-               state->ctx->status =
-                       dcerpc_bind_auth(state->lsa_pipe,
-                                        DCERPC_LSARPC_UUID,
-                                        DCERPC_LSARPC_VERSION,
-                                        state->creds, state->auth_type,
-                                        NULL);
+               ctx = dcerpc_bind_auth_send(state, state->lsa_pipe,
+                                           DCERPC_LSARPC_UUID,
+                                           DCERPC_LSARPC_VERSION,
+                                           state->creds, state->auth_type,
+                                           NULL);
+               composite_continue(state->ctx, ctx, init_lsa_recv_auth_bind,
+                                  state);
                break;
        default:
-               state->ctx->status = NT_STATUS_INTERNAL_ERROR;
-               
+               composite_error(state->ctx, NT_STATUS_INTERNAL_ERROR);
        }
+}
+
+static void init_lsa_recv_anon_bind(struct composite_context *ctx)
+{
+       struct init_lsa_state *state =
+               talloc_get_type(ctx->async.private_data,
+                               struct init_lsa_state);
+       struct rpc_request *req;
+
+       state->ctx->status = dcerpc_bind_auth_none_recv(ctx);
+       if (!composite_is_ok(state->ctx)) return;
+                       
+       state->handle = talloc(state, struct policy_handle);
+       if (composite_nomem(state->handle, state->ctx)) return;
+
+       state->openpolicy.in.system_name =
+               talloc_asprintf(state, "\\\\%s",
+                               dcerpc_server_name(state->lsa_pipe));
+       ZERO_STRUCT(state->objectattr);
+       state->openpolicy.in.attr = &state->objectattr;
+       state->openpolicy.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+       state->openpolicy.out.handle = state->handle;
+
+       req = dcerpc_lsa_OpenPolicy2_send(state->lsa_pipe, state,
+                                         &state->openpolicy);
+       composite_continue_rpc(state->ctx, req, init_lsa_recv_openpol, state);
+}
+
+static void init_lsa_recv_auth_bind(struct composite_context *ctx)
+{
+       struct init_lsa_state *state =
+               talloc_get_type(ctx->async.private_data,
+                               struct init_lsa_state);
+       struct rpc_request *req;
+
+       state->ctx->status = dcerpc_bind_auth_recv(ctx);
+       if (!composite_is_ok(state->ctx)) return;
                        
        state->handle = talloc(state, struct policy_handle);
        if (composite_nomem(state->handle, state->ctx)) return;
index c806a6688b71d5aee1bc5a95a353f9e71cb1db03..b5511a1a1227e01a70aaa2c2825a4fd577bc1fa3 100644 (file)
@@ -46,6 +46,8 @@ struct connect_samr_state {
 };
 
 static void connect_samr_recv_pipe(struct composite_context *ctx);
+static void connect_samr_recv_anon_bind(struct composite_context *ctx);
+static void connect_samr_recv_auth_bind(struct composite_context *ctx);
 static void connect_samr_recv_conn(struct rpc_request *req);
 static void connect_samr_recv_open(struct rpc_request *req);
 
@@ -93,17 +95,17 @@ static void connect_samr_recv_pipe(struct composite_context *ctx)
        struct connect_samr_state *state =
                talloc_get_type(ctx->async.private_data,
                                struct connect_samr_state);
-       struct rpc_request *req;
 
        state->ctx->status = dcerpc_pipe_open_smb_recv(ctx);
        if (!composite_is_ok(state->ctx)) return;
 
        switch (state->auth_type) {
        case DCERPC_AUTH_TYPE_NONE:
-               state->ctx->status =
-                       dcerpc_bind_auth_none(state->samr_pipe,
-                                             DCERPC_SAMR_UUID,
-                                             DCERPC_SAMR_VERSION);
+               ctx = dcerpc_bind_auth_none_send(state, state->samr_pipe,
+                                                DCERPC_SAMR_UUID,
+                                                DCERPC_SAMR_VERSION);
+               composite_continue(state->ctx, ctx,
+                                  connect_samr_recv_anon_bind, state);
                break;
        case DCERPC_AUTH_TYPE_NTLMSSP:
        case DCERPC_AUTH_TYPE_SCHANNEL:
@@ -112,17 +114,51 @@ static void connect_samr_recv_pipe(struct composite_context *ctx)
                        return;
                }
                state->samr_pipe->conn->flags |= (DCERPC_SIGN | DCERPC_SEAL);
-               state->ctx->status =
-                       dcerpc_bind_auth(state->samr_pipe,
-                                        DCERPC_SAMR_UUID,
-                                        DCERPC_SAMR_VERSION,
-                                        state->creds, state->auth_type,
-                                        NULL);
+               ctx = dcerpc_bind_auth_send(state, state->samr_pipe,
+                                           DCERPC_SAMR_UUID,
+                                           DCERPC_SAMR_VERSION,
+                                           state->creds, state->auth_type,
+                                           NULL);
+               composite_continue(state->ctx, ctx,
+                                  connect_samr_recv_auth_bind, state);
                break;
        default:
-               state->ctx->status = NT_STATUS_INTERNAL_ERROR;
-               
+               composite_error(state->ctx, NT_STATUS_INTERNAL_ERROR);
        }
+}
+
+static void connect_samr_recv_anon_bind(struct composite_context *ctx)
+{
+       struct connect_samr_state *state =
+               talloc_get_type(ctx->async.private_data,
+                               struct connect_samr_state);
+       struct rpc_request *req;
+
+       state->ctx->status = dcerpc_bind_auth_none_recv(ctx);
+       if (!composite_is_ok(state->ctx)) return;
+                       
+       state->connect_handle = talloc(state, struct policy_handle);
+       if (composite_nomem(state->connect_handle, state->ctx)) return;
+
+       state->c.in.system_name =
+               talloc_asprintf(state, "\\\\%s",
+                               dcerpc_server_name(state->samr_pipe));
+       state->c.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+       state->c.out.connect_handle = state->connect_handle;
+
+       req = dcerpc_samr_Connect2_send(state->samr_pipe, state, &state->c);
+       composite_continue_rpc(state->ctx, req, connect_samr_recv_conn, state);
+}
+
+static void connect_samr_recv_auth_bind(struct composite_context *ctx)
+{
+       struct connect_samr_state *state =
+               talloc_get_type(ctx->async.private_data,
+                               struct connect_samr_state);
+       struct rpc_request *req;
+
+       state->ctx->status = dcerpc_bind_auth_recv(ctx);
+       if (!composite_is_ok(state->ctx)) return;
                        
        state->connect_handle = talloc(state, struct policy_handle);
        if (composite_nomem(state->connect_handle, state->ctx)) return;
index fff3212cd93badef6268eb3e8a3c09a43a6a7048..07126dd04f9ad290a25ae54f89445e46df03e261 100644 (file)
@@ -77,6 +77,7 @@ struct init_domain_state {
 static void init_domain_recv_tree(struct composite_context *ctx);
 static void init_domain_recv_netlogoncreds(struct composite_context *ctx);
 static void init_domain_recv_netlogonpipe(struct composite_context *ctx);
+static void init_domain_recv_schannel(struct composite_context *ctx);
 static void init_domain_recv_lsa(struct composite_context *ctx);
 static void init_domain_recv_queryinfo(struct rpc_request *req);
 static void init_domain_recv_ldapconn(struct composite_context *ctx);
@@ -214,13 +215,22 @@ static void init_domain_recv_netlogonpipe(struct composite_context *ctx)
 
        state->domain->netlogon_pipe->conn->flags |=
                (DCERPC_SIGN | DCERPC_SEAL);
-       state->ctx->status =
-               dcerpc_bind_auth(state->domain->netlogon_pipe,
-                                DCERPC_NETLOGON_UUID,
-                                DCERPC_NETLOGON_VERSION, 
-                                state->domain->schannel_creds,
-                                DCERPC_AUTH_TYPE_SCHANNEL,
-                                NULL);
+       ctx = dcerpc_bind_auth_send(state, state->domain->netlogon_pipe,
+                                   DCERPC_NETLOGON_UUID,
+                                   DCERPC_NETLOGON_VERSION, 
+                                   state->domain->schannel_creds,
+                                   DCERPC_AUTH_TYPE_SCHANNEL,
+                                   NULL);
+       composite_continue(state->ctx, ctx, init_domain_recv_schannel, state);
+}
+
+static void init_domain_recv_schannel(struct composite_context *ctx)
+{
+       struct init_domain_state *state =
+               talloc_get_type(ctx->async.private_data,
+                               struct init_domain_state);
+
+       state->ctx->status = dcerpc_bind_auth_recv(ctx);
        if (!composite_is_ok(state->ctx)) return;
 
        ctx = wb_connect_lsa_send(state, state->conn.out.tree,