diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c index 667a2fac2de..81304764a8c 100644 --- a/libcli/auth/credentials.c +++ b/libcli/auth/credentials.c @@ -24,6 +24,7 @@ #include "system/time.h" #include "../lib/crypto/crypto.h" #include "libcli/auth/libcli_auth.h" +#include "../libcli/security/dom_sid.h" static void netlogon_creds_step_crypt(struct netlogon_creds_CredentialState *creds, const struct netr_Credential *in, @@ -202,7 +203,7 @@ struct netlogon_creds_CredentialState *netlogon_creds_client_init(TALLOC_CTX *me struct netr_Credential *initial_credential, uint32_t negotiate_flags) { - struct netlogon_creds_CredentialState *creds = talloc(mem_ctx, struct netlogon_creds_CredentialState); + struct netlogon_creds_CredentialState *creds = talloc_zero(mem_ctx, struct netlogon_creds_CredentialState); if (!creds) { return NULL; @@ -454,3 +455,46 @@ void netlogon_creds_decrypt_samlogon(struct netlogon_creds_CredentialState *cred } } +/* + copy a netlogon_creds_CredentialState struct +*/ + +struct netlogon_creds_CredentialState *netlogon_creds_copy(TALLOC_CTX *mem_ctx, + struct netlogon_creds_CredentialState *creds_in) +{ + struct netlogon_creds_CredentialState *creds = talloc_zero(mem_ctx, struct netlogon_creds_CredentialState); + + if (!creds) { + return NULL; + } + + creds->sequence = creds_in->sequence; + creds->negotiate_flags = creds_in->negotiate_flags; + creds->secure_channel_type = creds_in->secure_channel_type; + + creds->computer_name = talloc_strdup(creds, creds_in->computer_name); + if (!creds->computer_name) { + talloc_free(creds); + return NULL; + } + creds->account_name = talloc_strdup(creds, creds_in->account_name); + if (!creds->account_name) { + talloc_free(creds); + return NULL; + } + + if (creds_in->sid) { + creds->sid = dom_sid_dup(creds, creds_in->sid); + if (!creds->sid) { + talloc_free(creds); + return NULL; + } + } + + memcpy(creds->session_key, creds_in->session_key, sizeof(creds->session_key)); + memcpy(creds->seed.data, creds_in->seed.data, sizeof(creds->seed.data)); + memcpy(creds->client.data, creds_in->client.data, sizeof(creds->client.data)); + memcpy(creds->server.data, creds_in->server.data, sizeof(creds->server.data)); + + return creds; +} diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h index 2734db06169..34a0052f7a4 100644 --- a/libcli/auth/proto.h +++ b/libcli/auth/proto.h @@ -35,6 +35,8 @@ void netlogon_creds_client_authenticator(struct netlogon_creds_CredentialState * struct netr_Authenticator *next); bool netlogon_creds_client_check(struct netlogon_creds_CredentialState *creds, const struct netr_Credential *received_credentials); +struct netlogon_creds_CredentialState *netlogon_creds_copy(TALLOC_CTX *mem_ctx, + struct netlogon_creds_CredentialState *creds_in); /***************************************************************** The above functions are common to the client and server interface diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index c9b1ef65a04..d57bc0af60c 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2383,7 +2383,7 @@ NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain, result->a_u.schannel_auth->state = SCHANNEL_STATE_START; result->a_u.schannel_auth->seq_num = 0; result->a_u.schannel_auth->initiator = true; - result->a_u.schannel_auth->creds = creds; + result->a_u.schannel_auth->creds = netlogon_creds_copy(result, creds); *presult = result; return NT_STATUS_OK; @@ -3048,9 +3048,13 @@ NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli, /* * The credentials on a new netlogon pipe are the ones we are passed - * in - reference them in + * in - copy them over */ - result->dc = talloc_move(result, pdc); + result->dc = netlogon_creds_copy(result, *pdc); + if (result->dc == NULL) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s " "for domain %s and bound using schannel.\n",