diff options
author | Volker Lendecke <vl@samba.org> | 2009-10-04 15:47:33 +0200 |
---|---|---|
committer | Volker Lendecke <vl@samba.org> | 2009-10-05 22:12:20 +0200 |
commit | 20a8ea91e10af167067cc794a251265aaf489e75 (patch) | |
tree | 688425cc91fd6497e43483e194f73a10f4295c63 | |
parent | 3fa1d7332c19d0521b8da9f2cd8162260f0ab660 (diff) | |
download | samba-20a8ea91e10af167067cc794a251265aaf489e75.tar.gz samba-20a8ea91e10af167067cc794a251265aaf489e75.tar.bz2 samba-20a8ea91e10af167067cc794a251265aaf489e75.zip |
s3: Attempt to fix machine password change
-rw-r--r-- | source3/include/client.h | 1 | ||||
-rw-r--r-- | source3/include/proto.h | 9 | ||||
-rw-r--r-- | source3/libnet/libnet_join.c | 9 | ||||
-rw-r--r-- | source3/libsmb/trusts_util.c | 8 | ||||
-rw-r--r-- | source3/rpc_client/cli_netlogon.c | 51 | ||||
-rw-r--r-- | source3/winbindd/winbindd_cm.c | 2 | ||||
-rw-r--r-- | source3/winbindd/winbindd_dual.c | 42 |
7 files changed, 85 insertions, 37 deletions
diff --git a/source3/include/client.h b/source3/include/client.h index 82d94b055f..ba3a4e782c 100644 --- a/source3/include/client.h +++ b/source3/include/client.h @@ -147,6 +147,7 @@ struct rpc_pipe_client { /* The following is only non-null on a netlogon client pipe. */ struct netlogon_creds_CredentialState *dc; + uint32_t auth_neg_flags; /* Used by internal rpc_pipe_client */ pipes_struct *pipes_struct; diff --git a/source3/include/proto.h b/source3/include/proto.h index c8e4fe1916..a9768ba256 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -5240,7 +5240,14 @@ NTSTATUS rpccli_netlogon_set_trust_password(struct rpc_pipe_client *cli, const unsigned char orig_trust_passwd_hash[16], const char *new_trust_pwd_cleartext, const unsigned char new_trust_passwd_hash[16], - uint32_t sec_channel_type); + uint32_t sec_channel_type, + uint32_t neg_flags); +NTSTATUS rpccli_netlogon_auth_set_trust_password(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + const unsigned char orig_trust_passwd_hash[16], + const char *new_trust_pwd_cleartext, + const unsigned char new_trust_passwd_hash[16], + uint32_t sec_channel_type); /* The following definitions come from rpc_client/cli_pipe.c */ diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c index 8c3030711b..70b28e3988 100644 --- a/source3/libnet/libnet_join.c +++ b/source3/libnet/libnet_join.c @@ -788,11 +788,10 @@ static NTSTATUS libnet_join_joindomain_rpc_unsecure(TALLOC_CTX *mem_ctx, E_md4hash(trust_passwd, orig_trust_passwd_hash); - status = rpccli_netlogon_set_trust_password(pipe_hnd, mem_ctx, - orig_trust_passwd_hash, - r->in.machine_password, - new_trust_passwd_hash, - r->in.secure_channel_type); + status = rpccli_netlogon_auth_set_trust_password( + pipe_hnd, mem_ctx, orig_trust_passwd_hash, + r->in.machine_password, new_trust_passwd_hash, + r->in.secure_channel_type); return status; } diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index adf1525812..d9b75704e3 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -46,11 +46,9 @@ NTSTATUS trust_pw_change_and_store_it(struct rpc_pipe_client *cli, TALLOC_CTX *m E_md4hash(new_trust_passwd, new_trust_passwd_hash); - nt_status = rpccli_netlogon_set_trust_password(cli, mem_ctx, - orig_trust_passwd_hash, - new_trust_passwd, - new_trust_passwd_hash, - sec_channel_type); + nt_status = rpccli_netlogon_auth_set_trust_password( + cli, mem_ctx, orig_trust_passwd_hash, new_trust_passwd, + new_trust_passwd_hash, sec_channel_type); if (NT_STATUS_IS_OK(nt_status)) { DEBUG(3,("%s : trust_pw_change_and_store_it: Changed password.\n", diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c index 911a50f393..db7d1357c7 100644 --- a/source3/rpc_client/cli_netlogon.c +++ b/source3/rpc_client/cli_netlogon.c @@ -512,27 +512,12 @@ NTSTATUS rpccli_netlogon_set_trust_password(struct rpc_pipe_client *cli, const unsigned char orig_trust_passwd_hash[16], const char *new_trust_pwd_cleartext, const unsigned char new_trust_passwd_hash[16], - uint32_t sec_channel_type) + uint32_t sec_channel_type, + uint32_t neg_flags) { NTSTATUS result; - uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; struct netr_Authenticator clnt_creds, srv_cred; - result = rpccli_netlogon_setup_creds(cli, - cli->desthost, /* server name */ - lp_workgroup(), /* domain */ - global_myname(), /* client name */ - global_myname(), /* machine account name */ - orig_trust_passwd_hash, - sec_channel_type, - &neg_flags); - - if (!NT_STATUS_IS_OK(result)) { - DEBUG(3,("rpccli_netlogon_set_trust_password: unable to setup creds (%s)!\n", - nt_errstr(result))); - return result; - } - netlogon_creds_client_authenticator(cli->dc, &clnt_creds); if (neg_flags & NETLOGON_NEG_PASSWORD_SET2) { @@ -586,3 +571,35 @@ NTSTATUS rpccli_netlogon_set_trust_password(struct rpc_pipe_client *cli, return result; } +NTSTATUS rpccli_netlogon_auth_set_trust_password(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, + const unsigned char orig_trust_passwd_hash[16], + const char *new_trust_pwd_cleartext, + const unsigned char new_trust_passwd_hash[16], + uint32_t sec_channel_type) +{ + NTSTATUS result; + uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; + + result = rpccli_netlogon_setup_creds(cli, + cli->desthost, /* server name */ + lp_workgroup(), /* domain */ + global_myname(), /* client name */ + global_myname(), /* machine account name */ + orig_trust_passwd_hash, + sec_channel_type, + &neg_flags); + + if (!NT_STATUS_IS_OK(result)) { + DEBUG(3,("rpccli_netlogon_set_trust_password: unable to setup creds (%s)!\n", + nt_errstr(result))); + return result; + } + + return rpccli_netlogon_set_trust_password(cli, mem_ctx, + orig_trust_passwd_hash, + new_trust_pwd_cleartext, + new_trust_passwd_hash, + sec_channel_type, + neg_flags); +} diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c index 9a788397a9..029a0210d1 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -2470,6 +2470,8 @@ NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain, return !NT_STATUS_IS_OK(result) ? result : NT_STATUS_PIPE_NOT_AVAILABLE; } + conn->netlogon_pipe->auth_neg_flags = neg_flags; + /* * Try NetSamLogonEx for AD domains */ diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c index edf784cc21..546f5f0131 100644 --- a/source3/winbindd/winbindd_dual.c +++ b/source3/winbindd/winbindd_dual.c @@ -30,6 +30,7 @@ #include "includes.h" #include "winbindd.h" #include "../../nsswitch/libwbclient/wbc_async.h" +#include "../libcli/auth/libcli_auth.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND @@ -1061,9 +1062,12 @@ static void machine_password_change_handler(struct event_context *ctx, struct winbindd_child *child = (struct winbindd_child *)private_data; struct rpc_pipe_client *netlogon_pipe = NULL; - TALLOC_CTX *frame; NTSTATUS result; struct timeval next_change; + uint8_t old_trust_passwd_hash[16]; + uint8_t new_trust_passwd_hash[16]; + char *new_trust_passwd; + uint32_t sec_channel_type = 0; DEBUG(10,("machine_password_change_handler called\n")); @@ -1089,22 +1093,42 @@ static void machine_password_change_handler(struct event_context *ctx, return; } - frame = talloc_stackframe(); + if (!secrets_fetch_trust_account_password( + child->domain->name, old_trust_passwd_hash, NULL, + &sec_channel_type)) { + DEBUG(0, ("could not fetch domain secrets for domain %s!\n", + child->domain->name)); + return; + } + + new_trust_passwd = generate_random_str( + talloc_tos(), DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH); + if (new_trust_passwd == NULL) { + DEBUG(0, ("talloc_strdup failed\n")); + return; + } - result = trust_pw_find_change_and_store_it(netlogon_pipe, - frame, - child->domain->name); - TALLOC_FREE(frame); + E_md4hash(new_trust_passwd, new_trust_passwd_hash); + + result = rpccli_netlogon_set_trust_password( + netlogon_pipe, talloc_tos(), old_trust_passwd_hash, + new_trust_passwd, new_trust_passwd_hash, sec_channel_type, + netlogon_pipe->auth_neg_flags); if (!NT_STATUS_IS_OK(result)) { DEBUG(10,("machine_password_change_handler: " "failed to change machine password: %s\n", nt_errstr(result))); - } else { - DEBUG(10,("machine_password_change_handler: " - "successfully changed machine password\n")); + /* + * Don't try a second time, this will very likely also + * fail. + */ + return; } + DEBUG(3,("machine_password_change_handler: Changed password at %s.\n", + current_timestring(debug_ctx(), False))); + child->machine_password_change_event = event_add_timed(winbind_event_context(), NULL, next_change, machine_password_change_handler, |