summaryrefslogtreecommitdiff
path: root/source4/auth/credentials/credentials_files.c
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2005-12-01 05:20:39 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:46:56 -0500
commit9c6b7f2d62e134a4bc15efc04e05be25e4a53dc7 (patch)
tree8ef389a528fdc2caca79f279c086b4f8bea7afeb /source4/auth/credentials/credentials_files.c
parent22f1de0998ee34be4c032b16e4a6d30c9f8e6b85 (diff)
downloadsamba-9c6b7f2d62e134a4bc15efc04e05be25e4a53dc7.tar.gz
samba-9c6b7f2d62e134a4bc15efc04e05be25e4a53dc7.tar.bz2
samba-9c6b7f2d62e134a4bc15efc04e05be25e4a53dc7.zip
r11995: A big kerberos-related update.
This merges Samba4 up to current lorikeet-heimdal, which includes a replacement for some Samba-specific hacks. In particular, the credentials system now supplies GSS client and server credentials. These are imported into GSS with gss_krb5_import_creds(). Unfortunetly this can't take an MEMORY keytab, so we now create a FILE based keytab as provision and join time. Because the keytab is now created in advance, we don't spend .4s at negprot doing sha1 s2k calls. Also, because the keytab is read in real time, any change in the server key will be correctly picked up by the the krb5 code. To mark entries in the secrets which should be exported to a keytab, there is a new kerberosSecret objectClass. The new routine cli_credentials_update_all_keytabs() searches for these, and updates the keytabs. This is called in the provision.js via the ejs wrapper credentials_update_all_keytabs(). We can now (in theory) use a system-provided /etc/krb5.keytab, if krb5Keytab: FILE:/etc/krb5.keytab is added to the secrets.ldb record. By default the attribute privateKeytab: secrets.keytab is set, pointing to allow the whole private directory to be moved without breaking the internal links. (This used to be commit 6b75573df49c6210e1b9d71e108a9490976bd41d)
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;
+}
+