summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/libcli/raw/clitransport.c4
-rw-r--r--source4/librpc/rpc/dcerpc_auth.c14
-rw-r--r--source4/winbind/wb_async_helpers.c127
-rw-r--r--source4/winbind/wb_connect_lsa.c65
-rw-r--r--source4/winbind/wb_connect_sam.c62
-rw-r--r--source4/winbind/wb_init_domain.c24
6 files changed, 203 insertions, 93 deletions
diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c
index 83b73f2e30..1cd0a3046e 100644
--- a/source4/libcli/raw/clitransport.c
+++ b/source4/libcli/raw/clitransport.c
@@ -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;
diff --git a/source4/librpc/rpc/dcerpc_auth.c b/source4/librpc/rpc/dcerpc_auth.c
index 29ab80da7a..c0d4c55835 100644
--- a/source4/librpc/rpc/dcerpc_auth.c
+++ b/source4/librpc/rpc/dcerpc_auth.c
@@ -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);
diff --git a/source4/winbind/wb_async_helpers.c b/source4/winbind/wb_async_helpers.c
index 51907c1350..cfbfe5f74f 100644
--- a/source4/winbind/wb_async_helpers.c
+++ b/source4/winbind/wb_async_helpers.c
@@ -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,
diff --git a/source4/winbind/wb_connect_lsa.c b/source4/winbind/wb_connect_lsa.c
index d5222a6854..9443ef0dc7 100644
--- a/source4/winbind/wb_connect_lsa.c
+++ b/source4/winbind/wb_connect_lsa.c
@@ -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;
diff --git a/source4/winbind/wb_connect_sam.c b/source4/winbind/wb_connect_sam.c
index c806a6688b..b5511a1a12 100644
--- a/source4/winbind/wb_connect_sam.c
+++ b/source4/winbind/wb_connect_sam.c
@@ -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;
diff --git a/source4/winbind/wb_init_domain.c b/source4/winbind/wb_init_domain.c
index fff3212cd9..07126dd04f 100644
--- a/source4/winbind/wb_init_domain.c
+++ b/source4/winbind/wb_init_domain.c
@@ -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,