summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2006-01-24 05:31:08 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:51:26 -0500
commit28d78c40ade22c4b5d445dbe23f18ca210e41f8c (patch)
treed3cd9bdaca50e4cd7af031f1b2550836b9190417
parentfc29c3250af5fbcd81725e38fb48ca1ec5ae23bf (diff)
downloadsamba-28d78c40ade22c4b5d445dbe23f18ca210e41f8c.tar.gz
samba-28d78c40ade22c4b5d445dbe23f18ca210e41f8c.tar.bz2
samba-28d78c40ade22c4b5d445dbe23f18ca210e41f8c.zip
r13107: Follow the lead of Heimdal's kpasswdd and use the HDB (hdb-ldb in our
case) as the keytab. This avoids issues in replicated setups, as we will replicate the kpasswd key correctly (including from windows, which is why I care at the moment). Andrew Bartlett (This used to be commit 849500d1aa658817052423051b1f5d0b7a1db8e0)
-rw-r--r--source4/auth/credentials/credentials_files.c29
-rw-r--r--source4/auth/credentials/credentials_krb5.c14
-rw-r--r--source4/auth/kerberos/kerberos_util.c4
-rw-r--r--source4/auth/kerberos/krb5_init_context.c2
-rw-r--r--source4/heimdal/lib/hdb/hdb-protos.h6
-rw-r--r--source4/heimdal/lib/hdb/hdb.c5
-rw-r--r--source4/heimdal/lib/hdb/keytab.c276
-rw-r--r--source4/heimdal/lib/krb5/krb5.h3
-rw-r--r--source4/heimdal_build/config.mk2
-rw-r--r--source4/kdc/config.mk15
-rw-r--r--source4/kdc/hdb-ldb.c21
-rw-r--r--source4/kdc/kdc.c9
-rw-r--r--source4/kdc/kdc.h4
-rw-r--r--source4/kdc/kpasswdd.c5
-rw-r--r--source4/setup/secrets.ldif8
15 files changed, 369 insertions, 34 deletions
diff --git a/source4/auth/credentials/credentials_files.c b/source4/auth/credentials/credentials_files.c
index 219869cf3a..53350b8ed0 100644
--- a/source4/auth/credentials/credentials_files.c
+++ b/source4/auth/credentials/credentials_files.c
@@ -267,17 +267,12 @@ NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred,
cli_credentials_set_nt_hash(cred, &hash, CRED_SPECIFIED);
} else {
-
- DEBUG(1, ("Could not find 'secret' in join record to domain: %s\n",
- cli_credentials_get_domain(cred)));
-
- /* set anonymous as the fallback, if the machine account won't work */
- cli_credentials_set_anonymous(cred);
-
- talloc_free(mem_ctx);
- return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ cli_credentials_set_password(cred, NULL, CRED_SPECIFIED);
}
+ } else {
+ cli_credentials_set_password(cred, password, CRED_SPECIFIED);
}
+
domain = ldb_msg_find_string(msgs[0], "flatname", NULL);
if (domain) {
@@ -290,9 +285,6 @@ NTSTATUS cli_credentials_set_secrets(struct cli_credentials *cred,
}
cli_credentials_set_username(cred, machine_account, CRED_SPECIFIED);
- if (password) {
- cli_credentials_set_password(cred, password, CRED_SPECIFIED);
- }
cli_credentials_set_kvno(cred, ldb_msg_find_int(msgs[0], "msDS-KeyVersionNumber", 0));
@@ -417,13 +409,14 @@ NTSTATUS cli_credentials_update_all_keytabs(TALLOC_CTX *parent_ctx)
return NT_STATUS_ACCESS_DENIED;
}
- /* search for the secret record */
+ /* search for the secret record, but only of things we can
+ * actually update */
ldb_ret = gendb_search(ldb,
mem_ctx, NULL,
&msgs, attrs,
- "objectClass=kerberosSecret");
+ "(&(objectClass=kerberosSecret)(|(secret=*)(ntPwdHash=*)))");
if (ldb_ret == -1) {
- DEBUG(1, ("Error looking for kerberos type secrets to push into a keytab"));
+ DEBUG(1, ("Error looking for kerberos type secrets to push into a keytab:: %s", ldb_errstring(ldb)));
talloc_free(mem_ctx);
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
@@ -442,15 +435,13 @@ NTSTATUS cli_credentials_update_all_keytabs(TALLOC_CTX *parent_ctx)
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;
+ continue;
}
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;
+ continue;
}
}
return NT_STATUS_OK;
diff --git a/source4/auth/credentials/credentials_krb5.c b/source4/auth/credentials/credentials_krb5.c
index 5f40ca1046..29b70d9a53 100644
--- a/source4/auth/credentials/credentials_krb5.c
+++ b/source4/auth/credentials/credentials_krb5.c
@@ -43,6 +43,20 @@ int cli_credentials_get_krb5_context(struct cli_credentials *cred,
return 0;
}
+/* This needs to be called directly after the cli_credentials_init(),
+ * otherwise we might have problems with the krb5 context already
+ * being here.
+ */
+NTSTATUS cli_credentials_set_krb5_context(struct cli_credentials *cred,
+ struct smb_krb5_context *smb_krb5_context)
+{
+ if (!talloc_reference(cred, smb_krb5_context)) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ cred->smb_krb5_context = smb_krb5_context;
+ return NT_STATUS_OK;
+}
+
int cli_credentials_set_from_ccache(struct cli_credentials *cred,
enum credentials_obtained obtained)
{
diff --git a/source4/auth/kerberos/kerberos_util.c b/source4/auth/kerberos/kerberos_util.c
index ad0e18b2e7..776b591ba4 100644
--- a/source4/auth/kerberos/kerberos_util.c
+++ b/source4/auth/kerberos/kerberos_util.c
@@ -397,9 +397,9 @@ static int create_keytab(TALLOC_CTX *parent_ctx,
const struct samr_Password *mach_pwd;
mach_pwd = cli_credentials_get_nt_hash(machine_account, mem_ctx);
if (!mach_pwd) {
- talloc_free(mem_ctx);
DEBUG(1, ("create_keytab: Domain trust informaton for account %s not available\n",
cli_credentials_get_principal(machine_account, mem_ctx)));
+ talloc_free(mem_ctx);
return EINVAL;
}
ret = krb5_keyblock_init(smb_krb5_context->krb5_context,
@@ -410,6 +410,7 @@ static int create_keytab(TALLOC_CTX *parent_ctx,
DEBUG(1, ("create_keytab: krb5_keyblock_init failed: %s\n",
smb_get_krb5_error_message(smb_krb5_context->krb5_context,
ret, mem_ctx)));
+ talloc_free(mem_ctx);
return ret;
}
@@ -516,6 +517,7 @@ static krb5_error_code remove_old_entries(TALLOC_CTX *parent_ctx,
switch (ret) {
case 0:
break;
+ case HEIM_ERR_OPNOTSUPP:
case ENOENT:
case KRB5_KT_END:
/* no point enumerating if there isn't anything here */
diff --git a/source4/auth/kerberos/krb5_init_context.c b/source4/auth/kerberos/krb5_init_context.c
index 8e52ac5e3f..830c803524 100644
--- a/source4/auth/kerberos/krb5_init_context.c
+++ b/source4/auth/kerberos/krb5_init_context.c
@@ -448,6 +448,8 @@ static void smb_krb5_send_and_recv_close_func(krb5_context context, void *data)
return ret;
}
+ (*smb_krb5_context)->krb5_context->mem_ctx = *smb_krb5_context;
+
talloc_steal(parent_ctx, *smb_krb5_context);
talloc_free(tmp_ctx);
diff --git a/source4/heimdal/lib/hdb/hdb-protos.h b/source4/heimdal/lib/hdb/hdb-protos.h
index c221175e41..67e19f7e4a 100644
--- a/source4/heimdal/lib/hdb/hdb-protos.h
+++ b/source4/heimdal/lib/hdb/hdb-protos.h
@@ -491,6 +491,12 @@ hdb_ldapi_create (
const char */*arg*/);
krb5_error_code
+hdb_ldb_create (
+ krb5_context /*context*/,
+ HDB ** /*db*/,
+ const char */*arg*/);
+
+krb5_error_code
hdb_list_builtin (
krb5_context /*context*/,
char **/*list*/);
diff --git a/source4/heimdal/lib/hdb/hdb.c b/source4/heimdal/lib/hdb/hdb.c
index 5631d05332..406a50ecbd 100644
--- a/source4/heimdal/lib/hdb/hdb.c
+++ b/source4/heimdal/lib/hdb/hdb.c
@@ -55,6 +55,9 @@ static struct hdb_method methods[] = {
{"ldap:", hdb_ldap_create},
{"ldapi:", hdb_ldapi_create},
#endif
+#ifdef _SAMBA_BUILD_
+ {"ldb:", hdb_ldb_create},
+#endif
{NULL, NULL}
};
@@ -395,6 +398,6 @@ hdb_create(krb5_context context, HDB **db, const char *filename)
h = find_dynamic_method (context, filename, &residual);
#endif
if (h == NULL)
- krb5_errx(context, 1, "No database support! (hdb_create)");
+ krb5_errx(context, 1, "No database support! (hdb_create(%s))", filename);
return (*h->create)(context, db, residual);
}
diff --git a/source4/heimdal/lib/hdb/keytab.c b/source4/heimdal/lib/hdb/keytab.c
new file mode 100644
index 0000000000..21ee2f4274
--- /dev/null
+++ b/source4/heimdal/lib/hdb/keytab.c
@@ -0,0 +1,276 @@
+/*
+ * Copyright (c) 1999 - 2002 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "hdb_locl.h"
+
+/* keytab backend for HDB databases */
+
+RCSID("$Id: keytab.c,v 1.8 2005/12/12 12:35:36 lha Exp $");
+
+struct hdb_data {
+ char *dbname;
+ char *mkey;
+};
+
+/*
+ * the format for HDB keytabs is:
+ * HDB:[database:file:mkey]
+ */
+
+static krb5_error_code
+hdb_resolve(krb5_context context, const char *name, krb5_keytab id)
+{
+ struct hdb_data *d;
+ const char *db, *mkey;
+
+ d = malloc(sizeof(*d));
+ if(d == NULL) {
+ krb5_set_error_string(context, "malloc: out of memory");
+ return ENOMEM;
+ }
+ db = name;
+ mkey = strrchr(name, ':');
+ if(mkey == NULL || mkey[1] == '\0') {
+ if(*name == '\0')
+ d->dbname = NULL;
+ else {
+ d->dbname = strdup(name);
+ if(d->dbname == NULL) {
+ free(d);
+ krb5_set_error_string(context, "malloc: out of memory");
+ return ENOMEM;
+ }
+ }
+ d->mkey = NULL;
+ } else {
+ if((mkey - db) == 0) {
+ d->dbname = NULL;
+ } else {
+ d->dbname = malloc(mkey - db);
+ if(d->dbname == NULL) {
+ free(d);
+ krb5_set_error_string(context, "malloc: out of memory");
+ return ENOMEM;
+ }
+ memmove(d->dbname, db, mkey - db);
+ d->dbname[mkey - db] = '\0';
+ }
+ d->mkey = strdup(mkey + 1);
+ if(d->mkey == NULL) {
+ free(d->dbname);
+ free(d);
+ krb5_set_error_string(context, "malloc: out of memory");
+ return ENOMEM;
+ }
+ }
+ id->data = d;
+ return 0;
+}
+
+static krb5_error_code
+hdb_close(krb5_context context, krb5_keytab id)
+{
+ struct hdb_data *d = id->data;
+
+ free(d->dbname);
+ free(d->mkey);
+ free(d);
+ return 0;
+}
+
+static krb5_error_code
+hdb_get_name(krb5_context context,
+ krb5_keytab id,
+ char *name,
+ size_t namesize)
+{
+ struct hdb_data *d = id->data;
+
+ snprintf(name, namesize, "%s%s%s",
+ d->dbname ? d->dbname : "",
+ (d->dbname || d->mkey) ? ":" : "",
+ d->mkey ? d->mkey : "");
+ return 0;
+}
+
+static void
+set_config (krb5_context context,
+ const krb5_config_binding *binding,
+ const char **dbname,
+ const char **mkey)
+{
+ *dbname = krb5_config_get_string(context, binding, "dbname", NULL);
+ *mkey = krb5_config_get_string(context, binding, "mkey_file", NULL);
+}
+
+/*
+ * try to figure out the database (`dbname') and master-key (`mkey')
+ * that should be used for `principal'.
+ */
+
+static void
+find_db (krb5_context context,
+ const char **dbname,
+ const char **mkey,
+ krb5_const_principal principal)
+{
+ const krb5_config_binding *top_bind = NULL;
+ const krb5_config_binding *default_binding = NULL;
+ const krb5_config_binding *db;
+ krb5_realm *prealm = krb5_princ_realm(context, rk_UNCONST(principal));
+
+ *dbname = *mkey = NULL;
+
+ while ((db =
+ krb5_config_get_next(context,
+ NULL,
+ &top_bind,
+ krb5_config_list,
+ "kdc",
+ "database",
+ NULL)) != NULL) {
+ const char *p;
+
+ p = krb5_config_get_string (context, db, "realm", NULL);
+ if (p == NULL) {
+ if(default_binding) {
+ krb5_warnx(context, "WARNING: more than one realm-less "
+ "database specification");
+ krb5_warnx(context, "WARNING: using the first encountered");
+ } else
+ default_binding = db;
+ } else if (strcmp (*prealm, p) == 0) {
+ set_config (context, db, dbname, mkey);
+ break;
+ }
+ }
+ if (*dbname == NULL && default_binding != NULL)
+ set_config (context, default_binding, dbname, mkey);
+ if (*dbname == NULL)
+ *dbname = HDB_DEFAULT_DB;
+}
+
+/*
+ * find the keytab entry in `id' for `principal, kvno, enctype' and return
+ * it in `entry'. return 0 or an error code
+ */
+
+static krb5_error_code
+hdb_get_entry(krb5_context context,
+ krb5_keytab id,
+ krb5_const_principal principal,
+ krb5_kvno kvno,
+ krb5_enctype enctype,
+ krb5_keytab_entry *entry)
+{
+ hdb_entry_ex ent;
+ krb5_error_code ret;
+ struct hdb_data *d = id->data;
+ int i;
+ HDB *db;
+ const char *dbname = d->dbname;
+ const char *mkey = d->mkey;
+
+ if (dbname == NULL)
+ find_db (context, &dbname, &mkey, principal);
+
+ ret = hdb_create (context, &db, dbname);
+ if (ret)
+ return ret;
+ ret = hdb_set_master_keyfile (context, db, mkey);
+ if (ret) {
+ (*db->hdb_destroy)(context, db);
+ return ret;
+ }
+
+ ret = (*db->hdb_open)(context, db, O_RDONLY, 0);
+ if (ret) {
+ (*db->hdb_destroy)(context, db);
+ return ret;
+ }
+
+ ret = (*db->hdb_fetch)(context, db, HDB_F_DECRYPT, principal, HDB_ENT_TYPE_SERVER, &ent);
+
+ /* Shutdown the hdb on error */
+ if(ret == HDB_ERR_NOENTRY) {
+ (*db->hdb_close)(context, db);
+ (*db->hdb_destroy)(context, db);
+ return KRB5_KT_NOTFOUND;
+ } else if (ret) {
+ (*db->hdb_close)(context, db);
+ (*db->hdb_destroy)(context, db);
+ return ret;
+ }
+ if(kvno && ent.entry.kvno != kvno) {
+ /* The order here matters, we must free these in this order
+ * due to hdb-ldb and Samba4's talloc */
+ hdb_free_entry(context, &ent);
+ (*db->hdb_close)(context, db);
+ (*db->hdb_destroy)(context, db);
+ return KRB5_KT_NOTFOUND;
+ }
+ if(enctype == 0)
+ if(ent.entry.keys.len > 0)
+ enctype = ent.entry.keys.val[0].key.keytype;
+ ret = KRB5_KT_NOTFOUND;
+ for(i = 0; i < ent.entry.keys.len; i++) {
+ if(ent.entry.keys.val[i].key.keytype == enctype) {
+ krb5_copy_principal(context, principal, &entry->principal);
+ entry->vno = ent.entry.kvno;
+ krb5_copy_keyblock_contents(context,
+ &ent.entry.keys.val[i].key,
+ &entry->keyblock);
+ ret = 0;
+ break;
+ }
+ }
+ /* The order here matters, we must free these in this order
+ * due to hdb-ldb and Samba4's talloc */
+ hdb_free_entry(context, &ent);
+ (*db->hdb_close)(context, db);
+ (*db->hdb_destroy)(context, db);
+ return ret;
+}
+
+krb5_kt_ops hdb_kt_ops = {
+ "HDB",
+ hdb_resolve,
+ hdb_get_name,
+ hdb_close,
+ hdb_get_entry,
+ NULL, /* start_seq_get */
+ NULL, /* next_entry */
+ NULL, /* end_seq_get */
+ NULL, /* add */
+ NULL /* remove */
+};
diff --git a/source4/heimdal/lib/krb5/krb5.h b/source4/heimdal/lib/krb5/krb5.h
index adee4708e6..9814817600 100644
--- a/source4/heimdal/lib/krb5/krb5.h
+++ b/source4/heimdal/lib/krb5/krb5.h
@@ -451,6 +451,9 @@ typedef struct krb5_context_data {
int large_msg_size;
krb5_boolean fdns; /* Lookup hostnames to find full name, or send as-is */
struct send_and_recv *send_and_recv; /* Alternate functions for KDC communication */
+ void *mem_ctx; /* Some parts of Samba4 need a valid
+ memory context (under the event
+ context) to use */
} krb5_context_data;
enum {
diff --git a/source4/heimdal_build/config.mk b/source4/heimdal_build/config.mk
index 0d901258b3..0e65266526 100644
--- a/source4/heimdal_build/config.mk
+++ b/source4/heimdal_build/config.mk
@@ -23,6 +23,7 @@ OBJ_FILES = \
../heimdal/lib/hdb/hdb.o \
../heimdal/lib/hdb/ext.o \
../heimdal/lib/hdb/keys.o \
+ ../heimdal/lib/hdb/keytab.o \
../heimdal/lib/hdb/mkey.o \
../heimdal/lib/hdb/ndbm.o \
../heimdal/lib/hdb/asn1_Event.o \
@@ -40,6 +41,7 @@ OBJ_FILES = \
../heimdal/lib/hdb/asn1_Salt.o \
../heimdal/lib/hdb/asn1_hdb_entry.o \
../heimdal/lib/hdb/hdb_err.o
+REQUIRED_SUBSYSTEMS = HDB_LDB
NOPROTO = YES
# End SUBSYSTEM HEIMDAL_HDB
#######################
diff --git a/source4/kdc/config.mk b/source4/kdc/config.mk
index f1aef75df5..32f10c93a5 100644
--- a/source4/kdc/config.mk
+++ b/source4/kdc/config.mk
@@ -6,10 +6,21 @@
NOPROTO = YES
OBJ_FILES = \
kdc.o \
- pac-glue.o \
- hdb-ldb.o \
kpasswdd.o
REQUIRED_SUBSYSTEMS = \
LIBLDB KERBEROS_LIB HEIMDAL_KDC HEIMDAL_HDB
# End SUBSYSTEM KDC
#######################
+
+#######################
+# Start SUBSYSTEM KDC
+[SUBSYSTEM::HDB_LDB]
+NOPROTO = YES
+OBJ_FILES = \
+ hdb-ldb.o \
+ pac-glue.o
+REQUIRED_SUBSYSTEMS = \
+ LIBLDB KERBEROS_LIB HEIMDAL_HDB
+# End SUBSYSTEM KDC
+#######################
+
diff --git a/source4/kdc/hdb-ldb.c b/source4/kdc/hdb-ldb.c
index 43009c1c1b..a155e24e7e 100644
--- a/source4/kdc/hdb-ldb.c
+++ b/source4/kdc/hdb-ldb.c
@@ -948,8 +948,13 @@ static krb5_error_code LDB_destroy(krb5_context context, HDB *db)
return 0;
}
-NTSTATUS hdb_ldb_create(TALLOC_CTX *mem_ctx,
- krb5_context context, struct HDB **db, const char *arg)
+/* This interface is to be called by the KDC, which is expecting Samba
+ * calling conventions. It is also called by a wrapper
+ * (hdb_ldb_create) from the kpasswdd -> krb5 -> keytab_hdb -> hdb
+ * code */
+
+NTSTATUS kdc_hdb_ldb_create(TALLOC_CTX *mem_ctx,
+ krb5_context context, struct HDB **db, const char *arg)
{
NTSTATUS nt_status;
struct auth_session_info *session_info;
@@ -1008,3 +1013,15 @@ NTSTATUS hdb_ldb_create(TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
+
+krb5_error_code hdb_ldb_create(krb5_context context, struct HDB **db, const char *arg)
+{
+ NTSTATUS nt_status;
+ /* Disgusting, ugly hack, but it means one less private hook */
+ nt_status = kdc_hdb_ldb_create(context->mem_ctx, context, db, arg);
+
+ if (NT_STATUS_IS_OK(nt_status)) {
+ return 0;
+ }
+ return EINVAL;
+}
diff --git a/source4/kdc/kdc.c b/source4/kdc/kdc.c
index 12672bee53..4b958fdce8 100644
--- a/source4/kdc/kdc.c
+++ b/source4/kdc/kdc.c
@@ -570,13 +570,18 @@ static void kdc_task_init(struct task_server *task)
}
kdc->config->num_db = 1;
- status = hdb_ldb_create(kdc, kdc->smb_krb5_context->krb5_context,
- &kdc->config->db[0], NULL);
+ status = kdc_hdb_ldb_create(kdc, kdc->smb_krb5_context->krb5_context,
+ &kdc->config->db[0], NULL);
if (!NT_STATUS_IS_OK(status)) {
task_server_terminate(task, "kdc: hdb_ldb_create (setup KDC database) failed");
return;
}
+ ret = krb5_kt_register(kdc->smb_krb5_context->krb5_context, &hdb_kt_ops);
+ if(ret) {
+ task_server_terminate(task, "kdc: failed to register hdb keytab");
+ return;
+ }
/* start listening on the configured network interfaces */
status = kdc_startup_interfaces(kdc);
if (!NT_STATUS_IS_OK(status)) {
diff --git a/source4/kdc/kdc.h b/source4/kdc/kdc.h
index 1038c7df95..df6c5889e6 100644
--- a/source4/kdc/kdc.h
+++ b/source4/kdc/kdc.h
@@ -29,8 +29,8 @@
struct kdc_server;
-NTSTATUS hdb_ldb_create(TALLOC_CTX *mem_ctx,
- krb5_context context, struct HDB **db, const char *arg);
+NTSTATUS kdc_hdb_ldb_create(TALLOC_CTX *mem_ctx,
+ krb5_context context, struct HDB **db, const char *arg);
BOOL kpasswdd_process(struct kdc_server *kdc,
TALLOC_CTX *mem_ctx,
DATA_BLOB *input,
diff --git a/source4/kdc/kpasswdd.c b/source4/kdc/kpasswdd.c
index 05aced904d..8e6448435b 100644
--- a/source4/kdc/kpasswdd.c
+++ b/source4/kdc/kpasswdd.c
@@ -457,7 +457,10 @@ BOOL kpasswdd_process(struct kdc_server *kdc,
DEBUG(1, ("Failed to init server credentials\n"));
return False;
}
-
+
+ /* We want the credentials subsystem to use the krb5 context
+ * we already have, rather than a new context */
+ cli_credentials_set_krb5_context(server_credentials, kdc->smb_krb5_context);
cli_credentials_set_conf(server_credentials);
nt_status = cli_credentials_set_stored_principal(server_credentials, "kadmin/changepw");
if (!NT_STATUS_IS_OK(nt_status)) {
diff --git a/source4/setup/secrets.ldif b/source4/setup/secrets.ldif
index 43c3f69c9d..8c3c6917ae 100644
--- a/source4/setup/secrets.ldif
+++ b/source4/setup/secrets.ldif
@@ -38,18 +38,18 @@ msDS-KeyVersionNumber: 1
objectSid: ${DOMAINSID}
privateKeytab: secrets.keytab
+# A hook from our credentials system into HDB, as we must be on a KDC,
+# we can look directly into the database.
dn: samAccountName=krbtgt,flatname=${DOMAIN},CN=Principals
objectClass: top
objectClass: secret
objectClass: kerberosSecret
flatname: ${DOMAIN}
realm: ${REALM}
-secret: ${KRBTGTPASS}
sAMAccountName: krbtgt
whenCreated: ${LDAPTIME}
whenChanged: ${LDAPTIME}
-msDS-KeyVersionNumber: 1
objectSid: ${DOMAINSID}
servicePrincipalName: kadmin/changepw
-saltPrincipal: krbtgt@${REALM}
-privateKeytab: secrets.keytab
+krb5Keytab: HDB:ldb:sam.ldb:/dev/null
+#The /dev/null here is a HACK, but it matches the Heimdal format.