summaryrefslogtreecommitdiff
path: root/source4/auth/credentials/credentials_files.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/auth/credentials/credentials_files.c')
-rw-r--r--source4/auth/credentials/credentials_files.c92
1 files changed, 88 insertions, 4 deletions
diff --git a/source4/auth/credentials/credentials_files.c b/source4/auth/credentials/credentials_files.c
index 35bbc43b34..6b3c77c4e3 100644
--- a/source4/auth/credentials/credentials_files.c
+++ b/source4/auth/credentials/credentials_files.c
@@ -164,9 +164,9 @@ BOOL cli_credentials_parse_file(struct cli_credentials *cred, const char *file,
* @param cred Credentials structure to fill in
* @retval NTSTATUS error detailing any failure
*/
-static NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred,
- const char *base,
- const char *filter)
+NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred,
+ const char *base,
+ const char *filter)
{
TALLOC_CTX *mem_ctx;
@@ -183,6 +183,8 @@ static NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred,
"ntPwdHash",
"msDS-KeyVersionNumber",
"saltPrincipal",
+ "privateKeytab",
+ "krb5Keytab",
NULL
};
@@ -193,6 +195,7 @@ static NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred,
const char *realm;
enum netr_SchannelType sct;
const char *salt_principal;
+ const char *keytab;
/* ok, we are going to get it now, don't recurse back here */
cred->machine_account_pending = False;
@@ -201,6 +204,7 @@ static NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred,
cred->machine_account = True;
mem_ctx = talloc_named(cred, 0, "cli_credentials fetch machine password");
+
/* Local secrets are stored in secrets.ldb */
ldb = secrets_db_connect(mem_ctx);
if (!ldb) {
@@ -279,7 +283,22 @@ static NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred,
}
cli_credentials_set_kvno(cred, ldb_msg_find_int(msgs[0], "msDS-KeyVersionNumber", 0));
-
+
+ /* If there was an external keytab specified by reference in
+ * the LDB, then use this. Otherwise we will make one up
+ * (chewing CPU time) from the password */
+ keytab = ldb_msg_find_string(msgs[0], "krb5Keytab", NULL);
+ if (keytab) {
+ cli_credentials_set_keytab(cred, keytab, CRED_SPECIFIED);
+ } else {
+ keytab = ldb_msg_find_string(msgs[0], "privateKeytab", NULL);
+ if (keytab) {
+ keytab = talloc_asprintf(mem_ctx, "FILE:%s", private_path(mem_ctx, keytab));
+ if (keytab) {
+ cli_credentials_set_keytab(cred, keytab, CRED_SPECIFIED);
+ }
+ }
+ }
talloc_free(mem_ctx);
return NT_STATUS_OK;
@@ -345,3 +364,68 @@ void cli_credentials_set_machine_account_pending(struct cli_credentials *cred)
cred->machine_account_pending = True;
}
+
+NTSTATUS cli_credentials_update_all_keytabs(TALLOC_CTX *parent_ctx)
+{
+ TALLOC_CTX *mem_ctx;
+ int ldb_ret;
+ struct ldb_context *ldb;
+ struct ldb_message **msgs;
+ const char *attrs[] = { NULL };
+ struct cli_credentials *creds;
+ const char *filter;
+ NTSTATUS status;
+ int i, ret;
+
+ mem_ctx = talloc_new(parent_ctx);
+ if (!mem_ctx) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* Local secrets are stored in secrets.ldb */
+ ldb = secrets_db_connect(mem_ctx);
+ if (!ldb) {
+ DEBUG(1, ("Could not open secrets.ldb\n"));
+ talloc_free(mem_ctx);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ /* search for the secret record */
+ ldb_ret = gendb_search(ldb,
+ mem_ctx, NULL,
+ &msgs, attrs,
+ "objectClass=kerberosSecret");
+ if (ldb_ret == -1) {
+ DEBUG(1, ("Error looking for kerberos type secrets to push into a keytab"));
+ talloc_free(mem_ctx);
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ for (i=0; i < ldb_ret; i++) {
+ /* Make a credentials structure from it */
+ creds = cli_credentials_init(mem_ctx);
+ if (!creds) {
+ DEBUG(1, ("cli_credentials_init failed!"));
+ talloc_free(mem_ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+ cli_credentials_set_conf(creds);
+ filter = talloc_asprintf(mem_ctx, "dn=%s", ldb_dn_linearize(mem_ctx, msgs[i]->dn));
+ status = cli_credentials_set_secrets(creds, NULL, filter);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1, ("Failed to read secrets for keytab update for %s\n",
+ filter));
+ talloc_free(mem_ctx);
+ return status;
+ }
+ ret = cli_credentials_update_keytab(creds);
+ if (ret != 0) {
+ DEBUG(1, ("Failed to update keytab for %s\n",
+ filter));
+ talloc_free(mem_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ }
+ return NT_STATUS_OK;
+}
+