From: Andrew Bartlett Date: Thu, 11 Jun 2015 23:57:07 +0000 (+1200) Subject: winbindd: Sync secrets.ldb into secrets.tdb on startup X-Git-Url: http://git.samba.org/?a=commitdiff_plain;h=5de7621cbfba1e1fb52cddf41a5a13d027d45b46;p=obnox%2Fsamba%2Fsamba-obnox.git winbindd: Sync secrets.ldb into secrets.tdb on startup This ensures that the domain SID and machine account password are written into secrets.tdb if the secrets.tdb file was either never written or was deleted. BUG: https://bugzilla.samba.org/show_bug.cgi?id=10991 Signed-off-by: Andrew Bartlett Reviewed-by: Jeremy Allison --- diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index dc6faf14833..d73327c311b 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -29,6 +29,7 @@ #include "passdb.h" #include "source4/lib/messaging/messaging.h" #include "librpc/gen_ndr/ndr_lsa.h" +#include "auth/credentials/credentials.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND @@ -701,6 +702,49 @@ static void wb_imsg_new_trusted_domain(struct imessaging_context *msg, TALLOC_FREE(frame); } +/* + * We did not get the secret when we queried secrets.tdb, so read it + * from secrets.tdb and re-sync the databases + */ +static bool migrate_secrets_tdb_to_ldb(struct winbindd_domain *domain) +{ + bool ok; + struct cli_credentials *creds; + NTSTATUS can_migrate = pdb_get_trust_credentials(domain->name, + NULL, domain, &creds); + if (!NT_STATUS_IS_OK(can_migrate)) { + DEBUG(0, ("Failed to fetch our own, local AD domain join " + "password for winbindd's internal use, both from " + "secrets.tdb and secrets.ldb: %s\n", + nt_errstr(can_migrate))); + return false; + } + + /* + * NOTE: It is very unlikely we end up here if there is an + * oldpass, because a new password is created at + * classicupgrade, so this is not a concern. + */ + ok = secrets_store_machine_pw_sync(cli_credentials_get_password(creds), + NULL /* oldpass */, + cli_credentials_get_domain(creds), + cli_credentials_get_realm(creds), + cli_credentials_get_salt_principal(creds), + 0, /* Supported enc types, unused */ + &domain->sid, + cli_credentials_get_password_last_changed_time(creds), + cli_credentials_get_secure_channel_type(creds), + false /* do_delete: Do not delete */); + TALLOC_FREE(creds); + if (ok == false) { + DEBUG(0, ("Failed to write our our own, " + "local AD domain join password for " + "winbindd's internal use into secrets.tdb\n")); + return false; + } + return true; +} + /* Look up global info for the winbind daemon */ bool init_domain_list(void) { @@ -750,8 +794,32 @@ bool init_domain_list(void) &account_name, &sec_chan_type); if (!ok) { - DEBUG(0, ("Failed to fetch our own, local AD domain join password for winbindd's internal use\n")); - return false; + /* + * If get_trust_pw_hash() fails, then try and + * fetch the password from the more recent of + * secrets.{ldb,tdb} using the + * pdb_get_trust_credentials() + */ + ok = migrate_secrets_tdb_to_ldb(domain); + + if (ok == false) { + DEBUG(0, ("Failed to migrate our own, " + "local AD domain join password for " + "winbindd's internal use into " + "secrets.tdb\n")); + return false; + } + ok = get_trust_pw_hash(domain->name, + current_nt_hash.hash, + &account_name, + &sec_chan_type); + if (ok == false) { + DEBUG(0, ("Failed to find our our own, just " + "written local AD domain join " + "password for winbindd's internal " + "use in secrets.tdb\n")); + return false; + } } if (sec_chan_type == SEC_CHAN_RODC) { domain->rodc = true;