mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
s3: Sync machine account password in secrets_{prepare,finish}_password_change
BUG: https://bugzilla.samba.org/show_bug.cgi?id=6750 Signed-off-by: Pavel Filipenský <pfilipensky@samba.org> Reviewed-by: Stefan Metzmacher <metze@samba.org>
This commit is contained in:
parent
7c65aa8c7b
commit
683f6eec40
@ -129,7 +129,8 @@ NTSTATUS secrets_prepare_password_change(const char *domain, const char *dcname,
|
|||||||
const char *cleartext_unix,
|
const char *cleartext_unix,
|
||||||
TALLOC_CTX *mem_ctx,
|
TALLOC_CTX *mem_ctx,
|
||||||
struct secrets_domain_info1 **pinfo,
|
struct secrets_domain_info1 **pinfo,
|
||||||
struct secrets_domain_info1_change **pprev);
|
struct secrets_domain_info1_change **pprev,
|
||||||
|
NTSTATUS (*sync_pw2keytabs_fn)(void));
|
||||||
NTSTATUS secrets_failed_password_change(const char *change_server,
|
NTSTATUS secrets_failed_password_change(const char *change_server,
|
||||||
NTSTATUS local_status,
|
NTSTATUS local_status,
|
||||||
NTSTATUS remote_status,
|
NTSTATUS remote_status,
|
||||||
@ -140,7 +141,8 @@ NTSTATUS secrets_defer_password_change(const char *change_server,
|
|||||||
const struct secrets_domain_info1 *info);
|
const struct secrets_domain_info1 *info);
|
||||||
NTSTATUS secrets_finish_password_change(const char *change_server,
|
NTSTATUS secrets_finish_password_change(const char *change_server,
|
||||||
NTTIME change_time,
|
NTTIME change_time,
|
||||||
const struct secrets_domain_info1 *info);
|
const struct secrets_domain_info1 *info,
|
||||||
|
NTSTATUS (*sync_pw2keytabs_fn)(void));
|
||||||
bool secrets_delete_machine_password_ex(const char *domain, const char *realm);
|
bool secrets_delete_machine_password_ex(const char *domain, const char *realm);
|
||||||
bool secrets_delete_domain_sid(const char *domain);
|
bool secrets_delete_domain_sid(const char *domain);
|
||||||
char *secrets_fetch_prev_machine_password(const char *domain);
|
char *secrets_fetch_prev_machine_password(const char *domain);
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "../librpc/gen_ndr/ndr_netlogon.h"
|
#include "../librpc/gen_ndr/ndr_netlogon.h"
|
||||||
#include "librpc/gen_ndr/secrets.h"
|
#include "librpc/gen_ndr/secrets.h"
|
||||||
#include "secrets.h"
|
#include "secrets.h"
|
||||||
|
#include "ads.h"
|
||||||
#include "passdb.h"
|
#include "passdb.h"
|
||||||
#include "libsmb/libsmb.h"
|
#include "libsmb/libsmb.h"
|
||||||
#include "source3/include/messages.h"
|
#include "source3/include/messages.h"
|
||||||
@ -317,9 +318,17 @@ NTSTATUS trust_pw_change(struct netlogon_creds_cli_context *context,
|
|||||||
|
|
||||||
case SEC_CHAN_WKSTA:
|
case SEC_CHAN_WKSTA:
|
||||||
case SEC_CHAN_BDC:
|
case SEC_CHAN_BDC:
|
||||||
status = secrets_prepare_password_change(domain, dcname,
|
status = secrets_prepare_password_change(domain,
|
||||||
|
dcname,
|
||||||
new_trust_pw_str,
|
new_trust_pw_str,
|
||||||
frame, &info, &prev);
|
frame,
|
||||||
|
&info,
|
||||||
|
&prev,
|
||||||
|
#ifdef HAVE_ADS
|
||||||
|
sync_pw2keytabs);
|
||||||
|
#else
|
||||||
|
NULL);
|
||||||
|
#endif
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
DEBUG(0, ("secrets_prepare_password_change() failed for domain %s!\n",
|
DEBUG(0, ("secrets_prepare_password_change() failed for domain %s!\n",
|
||||||
domain));
|
domain));
|
||||||
@ -415,9 +424,15 @@ NTSTATUS trust_pw_change(struct netlogon_creds_cli_context *context,
|
|||||||
current_timestring(talloc_tos(), false),
|
current_timestring(talloc_tos(), false),
|
||||||
__func__, domain, context_name));
|
__func__, domain, context_name));
|
||||||
|
|
||||||
status = secrets_finish_password_change(prev->password->change_server,
|
status = secrets_finish_password_change(
|
||||||
prev->password->change_time,
|
prev->password->change_server,
|
||||||
info);
|
prev->password->change_time,
|
||||||
|
info,
|
||||||
|
#ifdef HAVE_ADS
|
||||||
|
sync_pw2keytabs);
|
||||||
|
#else
|
||||||
|
NULL);
|
||||||
|
#endif
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
DEBUG(0, ("secrets_prepare_password_change() failed for domain %s!\n",
|
DEBUG(0, ("secrets_prepare_password_change() failed for domain %s!\n",
|
||||||
domain));
|
domain));
|
||||||
@ -559,9 +574,14 @@ NTSTATUS trust_pw_change(struct netlogon_creds_cli_context *context,
|
|||||||
case SEC_CHAN_WKSTA:
|
case SEC_CHAN_WKSTA:
|
||||||
case SEC_CHAN_BDC:
|
case SEC_CHAN_BDC:
|
||||||
status = secrets_finish_password_change(
|
status = secrets_finish_password_change(
|
||||||
info->next_change->change_server,
|
info->next_change->change_server,
|
||||||
info->next_change->change_time,
|
info->next_change->change_time,
|
||||||
info);
|
info,
|
||||||
|
#ifdef HAVE_ADS
|
||||||
|
sync_pw2keytabs);
|
||||||
|
#else
|
||||||
|
NULL);
|
||||||
|
#endif
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
DEBUG(0, ("secrets_finish_password_change() failed for domain %s!\n",
|
DEBUG(0, ("secrets_finish_password_change() failed for domain %s!\n",
|
||||||
domain));
|
domain));
|
||||||
|
@ -56,7 +56,13 @@ ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_princip
|
|||||||
ads->auth.kdc_server,
|
ads->auth.kdc_server,
|
||||||
new_password,
|
new_password,
|
||||||
talloc_tos(),
|
talloc_tos(),
|
||||||
&info, &prev);
|
&info,
|
||||||
|
&prev,
|
||||||
|
#ifdef HAVE_ADS
|
||||||
|
sync_pw2keytabs);
|
||||||
|
#else
|
||||||
|
NULL);
|
||||||
|
#endif
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
return ADS_ERROR_NT(status);
|
return ADS_ERROR_NT(status);
|
||||||
}
|
}
|
||||||
@ -128,7 +134,14 @@ ADS_STATUS ads_change_trust_account_password(ADS_STRUCT *ads, char *host_princip
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = secrets_finish_password_change(ads->auth.kdc_server, now, info);
|
status = secrets_finish_password_change(ads->auth.kdc_server,
|
||||||
|
now,
|
||||||
|
info,
|
||||||
|
#ifdef HAVE_ADS
|
||||||
|
sync_pw2keytabs);
|
||||||
|
#else
|
||||||
|
NULL);
|
||||||
|
#endif
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
DEBUG(1,("Failed to save machine password\n"));
|
DEBUG(1,("Failed to save machine password\n"));
|
||||||
return ADS_ERROR_NT(status);
|
return ADS_ERROR_NT(status);
|
||||||
|
@ -1673,7 +1673,8 @@ NTSTATUS secrets_prepare_password_change(const char *domain, const char *dcname,
|
|||||||
const char *cleartext_unix,
|
const char *cleartext_unix,
|
||||||
TALLOC_CTX *mem_ctx,
|
TALLOC_CTX *mem_ctx,
|
||||||
struct secrets_domain_info1 **pinfo,
|
struct secrets_domain_info1 **pinfo,
|
||||||
struct secrets_domain_info1_change **pprev)
|
struct secrets_domain_info1_change **pprev,
|
||||||
|
NTSTATUS (*sync_pw2keytabs_fn)(void))
|
||||||
{
|
{
|
||||||
TALLOC_CTX *frame = talloc_stackframe();
|
TALLOC_CTX *frame = talloc_stackframe();
|
||||||
struct db_context *db = NULL;
|
struct db_context *db = NULL;
|
||||||
@ -1768,6 +1769,16 @@ NTSTATUS secrets_prepare_password_change(const char *domain, const char *dcname,
|
|||||||
return NT_STATUS_INTERNAL_DB_ERROR;
|
return NT_STATUS_INTERNAL_DB_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (prev == NULL && sync_pw2keytabs_fn != NULL) {
|
||||||
|
status = sync_pw2keytabs_fn();
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
DBG_ERR("Sync of machine password failed.\n");
|
||||||
|
dbwrap_transaction_cancel(db);
|
||||||
|
TALLOC_FREE(frame);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
*pinfo = talloc_move(mem_ctx, &info);
|
*pinfo = talloc_move(mem_ctx, &info);
|
||||||
if (prev != NULL) {
|
if (prev != NULL) {
|
||||||
*pprev = talloc_move(mem_ctx, &prev);
|
*pprev = talloc_move(mem_ctx, &prev);
|
||||||
@ -2011,7 +2022,8 @@ NTSTATUS secrets_defer_password_change(const char *change_server,
|
|||||||
|
|
||||||
NTSTATUS secrets_finish_password_change(const char *change_server,
|
NTSTATUS secrets_finish_password_change(const char *change_server,
|
||||||
NTTIME change_time,
|
NTTIME change_time,
|
||||||
const struct secrets_domain_info1 *cookie)
|
const struct secrets_domain_info1 *cookie,
|
||||||
|
NTSTATUS (*sync_pw2keytabs_fn)(void))
|
||||||
{
|
{
|
||||||
const char *domain = cookie->domain_info.name.string;
|
const char *domain = cookie->domain_info.name.string;
|
||||||
TALLOC_CTX *frame = talloc_stackframe();
|
TALLOC_CTX *frame = talloc_stackframe();
|
||||||
@ -2067,6 +2079,20 @@ NTSTATUS secrets_finish_password_change(const char *change_server,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For the clustered samba, it is important to have following order:
|
||||||
|
* 1. dbwrap_transaction_commit()
|
||||||
|
* 2. sync_pw2keytabs()
|
||||||
|
* Only this order ensures a correct behavior of
|
||||||
|
* the 'sync machine password script' that does:
|
||||||
|
* 'onnode all net ads keytab create'
|
||||||
|
*
|
||||||
|
* If we would call sync_pw2keytabs() before committing the changes to
|
||||||
|
* the secrets.tdb, it will not be updated on other nodes, so triggering
|
||||||
|
* 'net ads keytab create' will not see the new password yet.
|
||||||
|
*
|
||||||
|
* This applies also to secrets_prepare_password_change().
|
||||||
|
*/
|
||||||
ret = dbwrap_transaction_commit(db);
|
ret = dbwrap_transaction_commit(db);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
|
DBG_ERR("dbwrap_transaction_commit() failed for %s\n",
|
||||||
@ -2075,6 +2101,15 @@ NTSTATUS secrets_finish_password_change(const char *change_server,
|
|||||||
return NT_STATUS_INTERNAL_DB_ERROR;
|
return NT_STATUS_INTERNAL_DB_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sync_pw2keytabs_fn != NULL) {
|
||||||
|
status = sync_pw2keytabs_fn();
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
DBG_ERR("Sync of machine password failed.\n");
|
||||||
|
TALLOC_FREE(frame);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TALLOC_FREE(frame);
|
TALLOC_FREE(frame);
|
||||||
return NT_STATUS_OK;
|
return NT_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
@ -224,7 +224,13 @@ static int net_changesecretpw(struct net_context *c, int argc,
|
|||||||
"localhost",
|
"localhost",
|
||||||
trust_pw,
|
trust_pw,
|
||||||
talloc_tos(),
|
talloc_tos(),
|
||||||
&info, &prev);
|
&info,
|
||||||
|
&prev,
|
||||||
|
#ifdef HAVE_ADS
|
||||||
|
sync_pw2keytabs);
|
||||||
|
#else
|
||||||
|
NULL);
|
||||||
|
#endif
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
d_fprintf(stderr,
|
d_fprintf(stderr,
|
||||||
_("Unable to write the machine account password in the secrets database"));
|
_("Unable to write the machine account password in the secrets database"));
|
||||||
@ -243,7 +249,14 @@ static int net_changesecretpw(struct net_context *c, int argc,
|
|||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
status = secrets_finish_password_change("localhost", now, info);
|
status = secrets_finish_password_change("localhost",
|
||||||
|
now,
|
||||||
|
info,
|
||||||
|
#ifdef HAVE_ADS
|
||||||
|
sync_pw2keytabs);
|
||||||
|
#else
|
||||||
|
NULL);
|
||||||
|
#endif
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
d_fprintf(stderr,
|
d_fprintf(stderr,
|
||||||
_("Unable to write the machine account password in the secrets database"));
|
_("Unable to write the machine account password in the secrets database"));
|
||||||
|
Loading…
Reference in New Issue
Block a user