From 2ff2dae3d035af6cb0c131573cfd983fc9a58eee Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Nov 2005 16:28:39 +0000 Subject: [PATCH] r11809: Make dcerpc_bind_auth async. This also removes dcerpc_bind_auth_password, the only user of dcerpc_bind_auth. And this was not only passwords anyway. Andrew Bartlett, as usual: Please take a close look. Thanks, Volker --- source/librpc/rpc/dcerpc.c | 9 +- source/librpc/rpc/dcerpc_auth.c | 538 ++++++++++++++++++++---------------- source/librpc/rpc/dcerpc_schannel.c | 6 +- source/librpc/rpc/dcerpc_util.c | 6 +- source/torture/rpc/schannel.c | 20 +- source/winbind/wb_connect_lsa.c | 11 +- source/winbind/wb_connect_sam.c | 11 +- source/winbind/wb_init_domain.c | 12 +- 8 files changed, 332 insertions(+), 281 deletions(-) rewrite source/librpc/rpc/dcerpc_auth.c (70%) diff --git a/source/librpc/rpc/dcerpc.c b/source/librpc/rpc/dcerpc.c index c7f337de995..ee06d6e2bef 100644 --- a/source/librpc/rpc/dcerpc.c +++ b/source/librpc/rpc/dcerpc.c @@ -743,10 +743,9 @@ NTSTATUS dcerpc_auth3(struct dcerpc_connection *c, } -NTSTATUS dcerpc_init_syntaxes(const char *uuid, +NTSTATUS dcerpc_init_syntaxes(const char *uuid, uint_t version, struct dcerpc_syntax_id *syntax, - struct dcerpc_syntax_id *transfer_syntax, - uint_t version) + struct dcerpc_syntax_id *transfer_syntax) { NTSTATUS status; @@ -772,8 +771,8 @@ NTSTATUS dcerpc_bind_byuuid(struct dcerpc_pipe *p, struct dcerpc_syntax_id transfer_syntax; NTSTATUS status; - status = dcerpc_init_syntaxes(uuid, &syntax, &transfer_syntax, - version); + status = dcerpc_init_syntaxes(uuid, version, + &syntax, &transfer_syntax); if (!NT_STATUS_IS_OK(status)) { DEBUG(2,("Invalid uuid string in dcerpc_bind_byuuid\n")); return status; diff --git a/source/librpc/rpc/dcerpc_auth.c b/source/librpc/rpc/dcerpc_auth.c dissimilarity index 70% index 117112c197c..29ab80da7ab 100644 --- a/source/librpc/rpc/dcerpc_auth.c +++ b/source/librpc/rpc/dcerpc_auth.c @@ -1,242 +1,296 @@ -/* - Unix SMB/CIFS implementation. - - Generic Authentication Interface - - Copyright (C) Andrew Tridgell 2003 - Copyright (C) Andrew Bartlett 2004-2005 - Copyright (C) Stefan Metzmacher 2004 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" -#include "libcli/composite/composite.h" - -/* - do a non-athenticated dcerpc bind -*/ - -struct composite_context *dcerpc_bind_auth_none_send(TALLOC_CTX *mem_ctx, - struct dcerpc_pipe *p, - const char *uuid, - uint_t version) -{ - struct dcerpc_syntax_id syntax; - struct dcerpc_syntax_id transfer_syntax; - - struct composite_context *c; - - c = talloc_zero(mem_ctx, struct composite_context); - if (c == NULL) return NULL; - - c->status = dcerpc_init_syntaxes(uuid, &syntax, &transfer_syntax, - version); - if (!NT_STATUS_IS_OK(c->status)) { - DEBUG(2,("Invalid uuid string in " - "dcerpc_bind_auth_none_send\n")); - composite_trigger_error(c); - return c; - } - - /* c was only allocated as a container for a possible error */ - talloc_free(c); - - return dcerpc_bind_send(p, mem_ctx, &syntax, &transfer_syntax); -} - -NTSTATUS dcerpc_bind_auth_none_recv(struct composite_context *ctx) -{ - return dcerpc_bind_recv(ctx); -} - -NTSTATUS dcerpc_bind_auth_none(struct dcerpc_pipe *p, - const char *uuid, uint_t version) -{ - struct composite_context *ctx; - ctx = dcerpc_bind_auth_none_send(p, p, uuid, version); - return dcerpc_bind_auth_none_recv(ctx); -} - -/* - perform a multi-part authenticated bind -*/ -static NTSTATUS dcerpc_bind_auth(struct dcerpc_pipe *p, uint8_t auth_type, uint8_t auth_level, - const char *uuid, uint_t version) -{ - NTSTATUS status; - TALLOC_CTX *tmp_ctx = talloc_new(p); - DATA_BLOB credentials; - DATA_BLOB null_data_blob = data_blob(NULL, 0); - - int num_passes = 0; - - if (!p->conn->security_state.generic_state) { - status = gensec_client_start(p, &p->conn->security_state.generic_state, - p->conn->event_ctx); - if (!NT_STATUS_IS_OK(status)) goto done; - - status = gensec_start_mech_by_authtype(p->conn->security_state.generic_state, - auth_type, auth_level); - if (!NT_STATUS_IS_OK(status)) goto done; - } - - p->conn->security_state.auth_info = talloc(p, struct dcerpc_auth); - if (!p->conn->security_state.auth_info) { - status = NT_STATUS_NO_MEMORY; - goto done; - } - - p->conn->security_state.auth_info->auth_type = auth_type; - p->conn->security_state.auth_info->auth_level = auth_level; - p->conn->security_state.auth_info->auth_pad_length = 0; - p->conn->security_state.auth_info->auth_reserved = 0; - p->conn->security_state.auth_info->auth_context_id = random(); - p->conn->security_state.auth_info->credentials = null_data_blob; - - while (1) { - num_passes++; - status = gensec_update(p->conn->security_state.generic_state, tmp_ctx, - p->conn->security_state.auth_info->credentials, - &credentials); - - /* The status value here, from GENSEC is vital to the security - * of the system. Even if the other end accepts, if GENSEC - * claims 'MORE_PROCESSING_REQUIRED' then you must keep - * feeding it blobs, or else the remote host/attacker might - * avoid mutal authentication requirements. - * - * Likewise, you must not feed GENSEC too much (after the OK), - * it doesn't like that either - */ - - if (!NT_STATUS_IS_OK(status) - && !NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - DEBUG(1, ("Failed DCERPC client gensec_update with mechanism %s: %s\n", - gensec_get_name_by_authtype(auth_type), nt_errstr(status))); - - break; - } - - if (!credentials.length) { - break; - } - - p->conn->security_state.auth_info->credentials = credentials; - - if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - if (num_passes == 1) { - status = dcerpc_bind_byuuid(p, tmp_ctx, uuid, version); - } else { - /* We are demanding a reply, so use a request that will get us one */ - status = dcerpc_alter_context(p, tmp_ctx, &p->syntax, &p->transfer_syntax); - } - if (!NT_STATUS_IS_OK(status)) { - break; - } - } else if (NT_STATUS_IS_OK(status)) { - /* NO reply expected, so just send it */ - if (num_passes == 1) { - status = dcerpc_bind_byuuid(p, tmp_ctx, uuid, version); - } else { - status = dcerpc_auth3(p->conn, tmp_ctx); - } - break; - } else { - break; - } - }; - -done: - talloc_free(tmp_ctx); - - if (!NT_STATUS_IS_OK(status)) { - talloc_free(p->conn->security_state.generic_state); - ZERO_STRUCT(p->conn->security_state); - } else { - /* Authenticated connections use the generic session key */ - p->conn->security_state.session_key = dcerpc_generic_session_key; - } - - return status; -} - -/* - setup GENSEC on a DCE-RPC pipe -*/ -NTSTATUS dcerpc_bind_auth_password(struct dcerpc_pipe *p, - const char *uuid, uint_t version, - struct cli_credentials *credentials, - uint8_t auth_type, - const char *service) -{ - NTSTATUS status; - - if (!(p->conn->flags & (DCERPC_SIGN | DCERPC_SEAL))) { - p->conn->flags |= DCERPC_CONNECT; - } - - status = gensec_client_start(p, &p->conn->security_state.generic_state, - p->conn->event_ctx); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start GENSEC client mode: %s\n", nt_errstr(status))); - return status; - } - - status = gensec_set_credentials(p->conn->security_state.generic_state, - credentials); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC client credentails: %s\n", - nt_errstr(status))); - return status; - } - - status = gensec_set_target_hostname(p->conn->security_state.generic_state, - p->conn->transport.peer_name(p->conn)); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC target hostname: %s\n", - nt_errstr(status))); - return status; - } - - if (service) { - status = gensec_set_target_service(p->conn->security_state.generic_state, service); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC target service: %s\n", - nt_errstr(status))); - return status; - } - } - - status = gensec_start_mech_by_authtype(p->conn->security_state.generic_state, - auth_type, - dcerpc_auth_level(p->conn)); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to start set GENSEC client mechanism %s: %s\n", - gensec_get_name_by_authtype(auth_type), nt_errstr(status))); - return status; - } - - status = dcerpc_bind_auth(p, auth_type, - dcerpc_auth_level(p->conn), - uuid, version); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(2, ("Failed to bind to pipe with %s: %s\n", - gensec_get_name_by_authtype(auth_type), nt_errstr(status))); - return status; - } - - return status; -} +/* + Unix SMB/CIFS implementation. + + Generic Authentication Interface + + Copyright (C) Andrew Tridgell 2003 + Copyright (C) Andrew Bartlett 2004-2005 + Copyright (C) Stefan Metzmacher 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "libcli/composite/composite.h" + +/* + do a non-athenticated dcerpc bind +*/ + +struct composite_context *dcerpc_bind_auth_none_send(TALLOC_CTX *mem_ctx, + struct dcerpc_pipe *p, + const char *uuid, + uint_t version) +{ + struct dcerpc_syntax_id syntax; + struct dcerpc_syntax_id transfer_syntax; + + struct composite_context *c; + + c = talloc_zero(mem_ctx, struct composite_context); + if (c == NULL) return NULL; + + c->status = dcerpc_init_syntaxes(uuid, version, + &syntax, &transfer_syntax); + if (!NT_STATUS_IS_OK(c->status)) { + DEBUG(2,("Invalid uuid string in " + "dcerpc_bind_auth_none_send\n")); + composite_trigger_error(c); + return c; + } + + /* c was only allocated as a container for a possible error */ + talloc_free(c); + + return dcerpc_bind_send(p, mem_ctx, &syntax, &transfer_syntax); +} + +NTSTATUS dcerpc_bind_auth_none_recv(struct composite_context *ctx) +{ + return dcerpc_bind_recv(ctx); +} + +NTSTATUS dcerpc_bind_auth_none(struct dcerpc_pipe *p, + const char *uuid, uint_t version) +{ + struct composite_context *ctx; + ctx = dcerpc_bind_auth_none_send(p, p, uuid, version); + return dcerpc_bind_auth_none_recv(ctx); +} + +struct bind_auth_state { + struct dcerpc_pipe *pipe; + DATA_BLOB credentials; + BOOL more_processing; +}; + +static void bind_auth_recv_alter(struct composite_context *creq); + +static void bind_auth_next_step(struct composite_context *c) +{ + struct bind_auth_state *state = + talloc_get_type(c->private_data, struct bind_auth_state); + struct dcerpc_security *sec = &state->pipe->conn->security_state; + struct composite_context *creq; + BOOL more_processing = False; + + c->status = gensec_update(sec->generic_state, state, + sec->auth_info->credentials, + &state->credentials); + + if (NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + more_processing = True; + c->status = NT_STATUS_OK; + } + + if (!composite_is_ok(c)) return; + + if (state->credentials.length == 0) { + composite_done(c); + return; + } + + sec->auth_info->credentials = state->credentials; + + if (!more_processing) { + /* NO reply expected, so just send it */ + c->status = dcerpc_auth3(state->pipe->conn, state); + if (!composite_is_ok(c)) return; + composite_done(c); + return; + } + + creq = dcerpc_alter_context_send(state->pipe, state, + &state->pipe->syntax, + &state->pipe->transfer_syntax); + composite_continue(c, creq, bind_auth_recv_alter, c); +} + +static void bind_auth_recv_alter(struct composite_context *creq) +{ + struct composite_context *c = + talloc_get_type(creq->async.private_data, + struct composite_context); + + c->status = dcerpc_alter_context_recv(creq); + if (!composite_is_ok(c)) return; + + bind_auth_next_step(c); +} + +static void bind_auth_recv_bindreply(struct composite_context *creq) +{ + struct composite_context *c = + talloc_get_type(creq->async.private_data, + struct composite_context); + struct bind_auth_state *state = + talloc_get_type(c->private_data, struct bind_auth_state); + + c->status = dcerpc_bind_recv(creq); + if (!composite_is_ok(c)) return; + + if (!state->more_processing) { + composite_done(c); + return; + } + + 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 *c, *creq; + struct bind_auth_state *state; + struct dcerpc_security *sec; + + struct dcerpc_syntax_id syntax, transfer_syntax; + + c = talloc_zero(mem_ctx, struct composite_context); + if (c == NULL) return NULL; + + state = talloc(c, struct bind_auth_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 = p->conn->event_ctx; + + state->pipe = p; + + c->status = dcerpc_init_syntaxes(uuid, version, + &syntax, + &transfer_syntax); + if (!NT_STATUS_IS_OK(c->status)) goto failed; + + sec = &p->conn->security_state; + + c->status = gensec_client_start(p, &sec->generic_state, + p->conn->event_ctx); + if (!NT_STATUS_IS_OK(c->status)) { + DEBUG(1, ("Failed to start GENSEC client mode: %s\n", + nt_errstr(c->status))); + goto failed; + } + + c->status = gensec_set_credentials(sec->generic_state, credentials); + if (!NT_STATUS_IS_OK(c->status)) { + DEBUG(1, ("Failed to set GENSEC client credentails: %s\n", + nt_errstr(c->status))); + goto failed; + } + + c->status = gensec_set_target_hostname( + sec->generic_state, p->conn->transport.peer_name(p->conn)); + if (!NT_STATUS_IS_OK(c->status)) { + DEBUG(1, ("Failed to set GENSEC target hostname: %s\n", + nt_errstr(c->status))); + goto failed; + } + + if (service != NULL) { + c->status = gensec_set_target_service(sec->generic_state, + service); + if (!NT_STATUS_IS_OK(c->status)) { + DEBUG(1, ("Failed to set GENSEC target service: %s\n", + nt_errstr(c->status))); + goto failed; + } + } + + c->status = gensec_start_mech_by_authtype(sec->generic_state, + auth_type, + dcerpc_auth_level(p->conn)); + if (!NT_STATUS_IS_OK(c->status)) { + DEBUG(1, ("Failed to start GENSEC client mechanism %s: %s\n", + gensec_get_name_by_authtype(auth_type), + nt_errstr(c->status))); + goto failed; + } + + sec->auth_info = talloc(p, struct dcerpc_auth); + if (sec->auth_info == NULL) { + c->status = NT_STATUS_NO_MEMORY; + goto failed; + } + + sec->auth_info->auth_type = auth_type; + sec->auth_info->auth_level = dcerpc_auth_level(p->conn); + sec->auth_info->auth_pad_length = 0; + sec->auth_info->auth_reserved = 0; + sec->auth_info->auth_context_id = random(); + sec->auth_info->credentials = data_blob(NULL, 0); + + c->status = gensec_update(sec->generic_state, state, + sec->auth_info->credentials, + &state->credentials); + if (!NT_STATUS_IS_OK(c->status) && + !NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + goto failed; + } + + state->more_processing = + NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED); + + if (state->credentials.length == 0) { + composite_trigger_done(c); + return c; + } + + sec->auth_info->credentials = state->credentials; + + creq = dcerpc_bind_send(p, state, &syntax, &transfer_syntax); + if (creq == NULL) { + c->status = NT_STATUS_NO_MEMORY; + goto failed; + } + + creq->async.fn = bind_auth_recv_bindreply; + creq->async.private_data = c; + return c; + + failed: + composite_trigger_error(c); + return c; +} + +static NTSTATUS dcerpc_bind_auth_recv(struct composite_context *creq) +{ + NTSTATUS result = composite_wait(creq); + talloc_free(creq); + return result; +} + +/* + setup GENSEC on a DCE-RPC pipe +*/ +NTSTATUS dcerpc_bind_auth(struct dcerpc_pipe *p, + const char *uuid, uint_t version, + struct cli_credentials *credentials, + uint8_t auth_type, + const char *service) +{ + struct composite_context *creq; + creq = dcerpc_bind_auth_send(p, p, uuid, version, credentials, + auth_type, service); + return dcerpc_bind_auth_recv(creq); +} diff --git a/source/librpc/rpc/dcerpc_schannel.c b/source/librpc/rpc/dcerpc_schannel.c index ae4ce942692..e9e31f294f5 100644 --- a/source/librpc/rpc/dcerpc_schannel.c +++ b/source/librpc/rpc/dcerpc_schannel.c @@ -158,8 +158,8 @@ NTSTATUS dcerpc_bind_auth_schannel(TALLOC_CTX *tmp_ctx, return status; } - return dcerpc_bind_auth_password(p, uuid, version, - credentials, DCERPC_AUTH_TYPE_SCHANNEL, - NULL); + return dcerpc_bind_auth(p, uuid, version, + credentials, DCERPC_AUTH_TYPE_SCHANNEL, + NULL); } diff --git a/source/librpc/rpc/dcerpc_util.c b/source/librpc/rpc/dcerpc_util.c index ef510f4afcf..400a8b5e216 100644 --- a/source/librpc/rpc/dcerpc_util.c +++ b/source/librpc/rpc/dcerpc_util.c @@ -985,9 +985,9 @@ NTSTATUS dcerpc_pipe_auth(struct dcerpc_pipe *p, auth_type = DCERPC_AUTH_TYPE_NTLMSSP; } - status = dcerpc_bind_auth_password(p, pipe_uuid, pipe_version, - credentials, auth_type, - binding->authservice); + status = dcerpc_bind_auth(p, pipe_uuid, pipe_version, + credentials, auth_type, + binding->authservice); } else { status = dcerpc_bind_auth_none(p, pipe_uuid, pipe_version); } diff --git a/source/torture/rpc/schannel.c b/source/torture/rpc/schannel.c index 4b9c4a82357..338a71d27b1 100644 --- a/source/torture/rpc/schannel.c +++ b/source/torture/rpc/schannel.c @@ -214,11 +214,11 @@ static BOOL test_schannel(TALLOC_CTX *mem_ctx, goto failed; } - status = dcerpc_bind_auth_password(p_netlogon, - DCERPC_NETLOGON_UUID, - DCERPC_NETLOGON_VERSION, - credentials, DCERPC_AUTH_TYPE_SCHANNEL, - NULL); + status = dcerpc_bind_auth(p_netlogon, + DCERPC_NETLOGON_UUID, + DCERPC_NETLOGON_VERSION, + credentials, DCERPC_AUTH_TYPE_SCHANNEL, + NULL); if (!NT_STATUS_IS_OK(status)) { goto failed; @@ -249,11 +249,11 @@ static BOOL test_schannel(TALLOC_CTX *mem_ctx, goto failed; } - status = dcerpc_bind_auth_password(p_lsa, - DCERPC_LSARPC_UUID, - DCERPC_LSARPC_VERSION, - credentials, DCERPC_AUTH_TYPE_SCHANNEL, - NULL); + status = dcerpc_bind_auth(p_lsa, + DCERPC_LSARPC_UUID, + DCERPC_LSARPC_VERSION, + credentials, DCERPC_AUTH_TYPE_SCHANNEL, + NULL); if (!NT_STATUS_IS_OK(status)) { goto failed; diff --git a/source/winbind/wb_connect_lsa.c b/source/winbind/wb_connect_lsa.c index 779bcb60a2c..d5222a68546 100644 --- a/source/winbind/wb_connect_lsa.c +++ b/source/winbind/wb_connect_lsa.c @@ -106,12 +106,11 @@ static void init_lsa_recv_pipe(struct composite_context *ctx) } state->lsa_pipe->conn->flags |= (DCERPC_SIGN | DCERPC_SEAL); state->ctx->status = - dcerpc_bind_auth_password(state->lsa_pipe, - DCERPC_LSARPC_UUID, - DCERPC_LSARPC_VERSION, - state->creds, - state->auth_type, - NULL); + dcerpc_bind_auth(state->lsa_pipe, + DCERPC_LSARPC_UUID, + DCERPC_LSARPC_VERSION, + state->creds, state->auth_type, + NULL); break; default: state->ctx->status = NT_STATUS_INTERNAL_ERROR; diff --git a/source/winbind/wb_connect_sam.c b/source/winbind/wb_connect_sam.c index 2ce189a5c7f..c806a6688b7 100644 --- a/source/winbind/wb_connect_sam.c +++ b/source/winbind/wb_connect_sam.c @@ -113,12 +113,11 @@ static void connect_samr_recv_pipe(struct composite_context *ctx) } state->samr_pipe->conn->flags |= (DCERPC_SIGN | DCERPC_SEAL); state->ctx->status = - dcerpc_bind_auth_password(state->samr_pipe, - DCERPC_SAMR_UUID, - DCERPC_SAMR_VERSION, - state->creds, - state->auth_type, - NULL); + dcerpc_bind_auth(state->samr_pipe, + DCERPC_SAMR_UUID, + DCERPC_SAMR_VERSION, + state->creds, state->auth_type, + NULL); break; default: state->ctx->status = NT_STATUS_INTERNAL_ERROR; diff --git a/source/winbind/wb_init_domain.c b/source/winbind/wb_init_domain.c index 21ea668043b..fff3212cd93 100644 --- a/source/winbind/wb_init_domain.c +++ b/source/winbind/wb_init_domain.c @@ -215,12 +215,12 @@ 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_password(state->domain->netlogon_pipe, - DCERPC_NETLOGON_UUID, - DCERPC_NETLOGON_VERSION, - state->domain->schannel_creds, - DCERPC_AUTH_TYPE_SCHANNEL, - NULL); + dcerpc_bind_auth(state->domain->netlogon_pipe, + DCERPC_NETLOGON_UUID, + DCERPC_NETLOGON_VERSION, + state->domain->schannel_creds, + DCERPC_AUTH_TYPE_SCHANNEL, + NULL); if (!composite_is_ok(state->ctx)) return; ctx = wb_connect_lsa_send(state, state->conn.out.tree, -- 2.11.4.GIT