summaryrefslogtreecommitdiffstats
path: root/auth
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 /auth
parent1a8fd711d7e4f97a6749b5d6c4806b11c38f20f4 (diff)
downloadsamba-f873d422b153c55754c0d1e83670cda7c3a7f7e3.tar.gz
samba-f873d422b153c55754c0d1e83670cda7c3a7f7e3.tar.xz
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
Diffstat (limited to 'auth')
-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)));