summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2012-08-27 21:37:19 +1000
committerAndrew Bartlett <abartlet@samba.org>2012-08-28 07:57:29 +1000
commitf873d422b153c55754c0d1e83670cda7c3a7f7e3 (patch)
tree8bb53dadfbe1e19c4686aa0c285176829971e205
parent1a8fd711d7e4f97a6749b5d6c4806b11c38f20f4 (diff)
downloadsamba-f873d422b153c55754c0d1e83670cda7c3a7f7e3.tar.gz
samba-f873d422b153c55754c0d1e83670cda7c3a7f7e3.tar.bz2
samba-f873d422b153c55754c0d1e83670cda7c3a7f7e3.zip
auth/credentials: Rework credentials handling to try and find the most recent machine pw
As winbindd will update secrets.tdb but not secrets.ldb, we need to detect this and use secrets.tdb Andrew Bartlett
-rw-r--r--auth/credentials/credentials_secrets.c104
1 files changed, 71 insertions, 33 deletions
diff --git a/auth/credentials/credentials_secrets.c b/auth/credentials/credentials_secrets.c
index dc31f9d8ca..3304200607 100644
--- a/auth/credentials/credentials_secrets.c
+++ b/auth/credentials/credentials_secrets.c
@@ -204,6 +204,15 @@ _PUBLIC_ NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *cr
char *error_string;
const char *domain;
const char *realm;
+ bool secrets_tdb_password_more_recent;
+ time_t secrets_tdb_lct = 0;
+ char *secrets_tdb_password = NULL;
+ char *keystr;
+ char *keystr_upper = NULL;
+ char *secrets_tdb = lpcfg_private_path(cred, lp_ctx, "secrets.tdb");
+ struct db_context *db_ctx = dbwrap_local_open(cred, lp_ctx, secrets_tdb, 0,
+ TDB_DEFAULT, O_RDWR, 0600,
+ DBWRAP_LOCK_ORDER_1);
/* Bleh, nasty recursion issues: We are setting a machine
* account here, so we don't want the 'pending' flag around
* any more */
@@ -213,49 +222,78 @@ _PUBLIC_ NTSTATUS cli_credentials_set_machine_account(struct cli_credentials *cr
* cli_credentials_set_secrets is to run as anonymous, so the domain is wiped */
domain = cli_credentials_get_domain(cred);
realm = cli_credentials_get_realm(cred);
+
+ if (db_ctx) {
+ TDB_DATA dbuf;
+ keystr = talloc_asprintf(cred, "%s/%s",
+ SECRETS_MACHINE_LAST_CHANGE_TIME,
+ domain);
+ keystr_upper = strupper_talloc(cred, keystr);
+ TALLOC_FREE(keystr);
+ status = dbwrap_fetch(db_ctx, cred, string_tdb_data(keystr_upper),
+ &dbuf);
+ TALLOC_FREE(keystr_upper);
+ if (NT_STATUS_IS_OK(status) && dbuf.dsize == 4) {
+ secrets_tdb_lct = IVAL(dbuf.dptr,0);
+ }
+ TALLOC_FREE(dbuf.dptr);
+
+ keystr = talloc_asprintf(cred, "%s/%s",
+ SECRETS_MACHINE_PASSWORD,
+ domain);
+ keystr_upper = strupper_talloc(cred, keystr);
+ TALLOC_FREE(keystr);
+ status = dbwrap_fetch(db_ctx, cred, string_tdb_data(keystr_upper),
+ &dbuf);
+ if (NT_STATUS_IS_OK(status)) {
+ secrets_tdb_password = (char *)dbuf.dptr;
+ }
+ }
+
filter = talloc_asprintf(cred, SECRETS_PRIMARY_DOMAIN_FILTER,
domain);
status = cli_credentials_set_secrets(cred, lp_ctx, NULL,
SECRETS_PRIMARY_DOMAIN_DN,
filter, &error_string);
- if (NT_STATUS_EQUAL(NT_STATUS_CANT_ACCESS_DOMAIN_INFO, status)
+ if (secrets_tdb_password == NULL) {
+ secrets_tdb_password_more_recent = false;
+ } else if (NT_STATUS_EQUAL(NT_STATUS_CANT_ACCESS_DOMAIN_INFO, status)
|| NT_STATUS_EQUAL(NT_STATUS_NOT_FOUND, status)) {
- TDB_DATA dbuf;
- char *secrets_tdb = lpcfg_private_path(cred, lp_ctx, "secrets.tdb");
- struct db_context *db_ctx = dbwrap_local_open(cred, lp_ctx, secrets_tdb, 0,
- TDB_DEFAULT, O_RDWR, 0600,
- DBWRAP_LOCK_ORDER_1);
+ secrets_tdb_password_more_recent = true;
+ } else if (secrets_tdb_lct > cli_credentials_get_password_last_changed_time(cred)) {
+ secrets_tdb_password_more_recent = true;
+ } else if (secrets_tdb_lct == cli_credentials_get_password_last_changed_time(cred)) {
+ secrets_tdb_password_more_recent = strcmp(secrets_tdb_password, cli_credentials_get_password(cred)) != 0;
+ } else {
+ secrets_tdb_password_more_recent = false;
+ }
+
+ if (secrets_tdb_password_more_recent) {
+ char *machine_account = talloc_asprintf(cred, "%s$", lpcfg_netbios_name(lp_ctx));
+ cli_credentials_set_password(cred, secrets_tdb_password, CRED_SPECIFIED);
+ cli_credentials_set_domain(cred, domain, CRED_SPECIFIED);
+ cli_credentials_set_realm(cred, realm, CRED_SPECIFIED);
+ cli_credentials_set_workstation(cred, lpcfg_netbios_name(lp_ctx), CRED_SPECIFIED);
+ cli_credentials_set_username(cred, machine_account, CRED_SPECIFIED);
+ TALLOC_FREE(machine_account);
+ } else if (NT_STATUS_EQUAL(NT_STATUS_CANT_ACCESS_DOMAIN_INFO, status)
+ || NT_STATUS_EQUAL(NT_STATUS_NOT_FOUND, status)) {
if (db_ctx) {
- char *keystr;
- char *keystr_upper;
- keystr = talloc_asprintf(cred, "%s/%s",
- SECRETS_MACHINE_PASSWORD,
- domain);
- keystr_upper = strupper_talloc(cred, keystr);
- TALLOC_FREE(keystr);
- status = dbwrap_fetch(db_ctx, cred, string_tdb_data(keystr_upper),
- &dbuf);
-
- if (NT_STATUS_IS_OK(status)) {
- char *machine_account = talloc_asprintf(cred, "%s$", lpcfg_netbios_name(lp_ctx));
- cli_credentials_set_password(cred, (const char *)dbuf.dptr, CRED_SPECIFIED);
- cli_credentials_set_domain(cred, domain, CRED_SPECIFIED);
- cli_credentials_set_realm(cred, domain, CRED_SPECIFIED);
- cli_credentials_set_workstation(cred, lpcfg_netbios_name(lp_ctx), CRED_SPECIFIED);
- cli_credentials_set_username(cred, machine_account, CRED_SPECIFIED);
- TALLOC_FREE(machine_account);
- TALLOC_FREE(dbuf.dptr);
- } else {
- error_string = talloc_asprintf(cred,
- "Failed to fetch machine account password from "
- "secrets.ldb: %s and failed to fetch %s from %s",
- error_string, keystr_upper, secrets_tdb);
- }
- TALLOC_FREE(keystr_upper);
- TALLOC_FREE(secrets_tdb);
+ error_string = talloc_asprintf(cred,
+ "Failed to fetch machine account password from "
+ "secrets.ldb: %s and failed to fetch %s from %s",
+ error_string, keystr_upper, secrets_tdb);
+ } else {
+ error_string = talloc_asprintf(cred,
+ "Failed to fetch machine account password from "
+ "secrets.ldb: %s and failed to open %s",
+ error_string, secrets_tdb);
}
}
+ TALLOC_FREE(secrets_tdb_password);
+ TALLOC_FREE(secrets_tdb);
+ TALLOC_FREE(db_ctx);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("Could not find machine account in secrets database: %s: %s\n",
error_string, nt_errstr(status)));