summaryrefslogtreecommitdiff
path: root/source4/kdc
diff options
context:
space:
mode:
Diffstat (limited to 'source4/kdc')
-rw-r--r--source4/kdc/config.mk10
-rw-r--r--source4/kdc/hdb-samba4.c (renamed from source4/kdc/hdb-ldb.c)88
-rw-r--r--source4/kdc/kdc.c23
3 files changed, 72 insertions, 49 deletions
diff --git a/source4/kdc/config.mk b/source4/kdc/config.mk
index 2c96e22cb3..dfd2879bd6 100644
--- a/source4/kdc/config.mk
+++ b/source4/kdc/config.mk
@@ -4,9 +4,9 @@
# Start SUBSYSTEM KDC
[MODULE::KDC]
INIT_FUNCTION = server_service_kdc_init
-SUBSYSTEM = smbd
+SUBSYSTEM = samba
PRIVATE_DEPENDENCIES = \
- HEIMDAL_KDC HDB_LDB
+ HEIMDAL_KDC HDB_SAMBA4
# End SUBSYSTEM KDC
#######################
@@ -14,7 +14,7 @@ KDC_OBJ_FILES = $(addprefix $(kdcsrcdir)/, kdc.o kpasswdd.o)
#######################
# Start SUBSYSTEM KDC
-[SUBSYSTEM::HDB_LDB]
+[SUBSYSTEM::HDB_SAMBA4]
CFLAGS = -Iheimdal/kdc -Iheimdal/lib/hdb
PRIVATE_DEPENDENCIES = \
LIBLDB auth_sam auth_sam_reply CREDENTIALS \
@@ -22,5 +22,5 @@ PRIVATE_DEPENDENCIES = \
# End SUBSYSTEM KDC
#######################
-HDB_LDB_OBJ_FILES = $(addprefix $(kdcsrcdir)/, hdb-ldb.o pac-glue.o)
-$(eval $(call proto_header_template,$(kdcsrcdir)/pac_glue.h,$(HDB_LDB_OBJ_FILES:.o=.c)))
+HDB_SAMBA4_OBJ_FILES = $(addprefix $(kdcsrcdir)/, hdb-samba4.o pac-glue.o)
+$(eval $(call proto_header_template,$(kdcsrcdir)/pac_glue.h,$(HDB_SAMBA4_OBJ_FILES:.o=.c)))
diff --git a/source4/kdc/hdb-ldb.c b/source4/kdc/hdb-samba4.c
index ef3a0bcb8a..51f464cd09 100644
--- a/source4/kdc/hdb-ldb.c
+++ b/source4/kdc/hdb-samba4.c
@@ -50,11 +50,11 @@
#include "param/param.h"
#include "events/events.h"
#include "kdc/kdc.h"
-#include "lib/crypto/md4.h"
+#include "../lib/crypto/md4.h"
enum hdb_ldb_ent_type
-{ HDB_LDB_ENT_TYPE_CLIENT, HDB_LDB_ENT_TYPE_SERVER,
- HDB_LDB_ENT_TYPE_KRBTGT, HDB_LDB_ENT_TYPE_TRUST, HDB_LDB_ENT_TYPE_ANY };
+{ HDB_SAMBA4_ENT_TYPE_CLIENT, HDB_SAMBA4_ENT_TYPE_SERVER,
+ HDB_SAMBA4_ENT_TYPE_KRBTGT, HDB_SAMBA4_ENT_TYPE_TRUST, HDB_SAMBA4_ENT_TYPE_ANY };
enum trust_direction {
UNKNOWN = 0,
@@ -115,26 +115,26 @@ static HDBFlags uf2HDBFlags(krb5_context context, int userAccountControl, enum h
/* Account types - clear the invalid bit if it turns out to be valid */
if (userAccountControl & UF_NORMAL_ACCOUNT) {
- if (ent_type == HDB_LDB_ENT_TYPE_CLIENT || ent_type == HDB_LDB_ENT_TYPE_ANY) {
+ if (ent_type == HDB_SAMBA4_ENT_TYPE_CLIENT || ent_type == HDB_SAMBA4_ENT_TYPE_ANY) {
flags.client = 1;
}
flags.invalid = 0;
}
if (userAccountControl & UF_INTERDOMAIN_TRUST_ACCOUNT) {
- if (ent_type == HDB_LDB_ENT_TYPE_CLIENT || ent_type == HDB_LDB_ENT_TYPE_ANY) {
+ if (ent_type == HDB_SAMBA4_ENT_TYPE_CLIENT || ent_type == HDB_SAMBA4_ENT_TYPE_ANY) {
flags.client = 1;
}
flags.invalid = 0;
}
if (userAccountControl & UF_WORKSTATION_TRUST_ACCOUNT) {
- if (ent_type == HDB_LDB_ENT_TYPE_CLIENT || ent_type == HDB_LDB_ENT_TYPE_ANY) {
+ if (ent_type == HDB_SAMBA4_ENT_TYPE_CLIENT || ent_type == HDB_SAMBA4_ENT_TYPE_ANY) {
flags.client = 1;
}
flags.invalid = 0;
}
if (userAccountControl & UF_SERVER_TRUST_ACCOUNT) {
- if (ent_type == HDB_LDB_ENT_TYPE_CLIENT || ent_type == HDB_LDB_ENT_TYPE_ANY) {
+ if (ent_type == HDB_SAMBA4_ENT_TYPE_CLIENT || ent_type == HDB_SAMBA4_ENT_TYPE_ANY) {
flags.client = 1;
}
flags.invalid = 0;
@@ -186,7 +186,7 @@ static HDBFlags uf2HDBFlags(krb5_context context, int userAccountControl, enum h
return flags;
}
-static int hdb_ldb_destrutor(struct hdb_ldb_private *private)
+static int hdb_ldb_destructor(struct hdb_ldb_private *private)
{
hdb_entry_ex *entry_ex = private->entry_ex;
free_hdb_entry(&entry_ex->entry);
@@ -542,7 +542,7 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
private->iconv_convenience = lp_iconv_convenience(lp_ctx);
private->netbios_name = lp_netbios_name(lp_ctx);
- talloc_set_destructor(private, hdb_ldb_destrutor);
+ talloc_set_destructor(private, hdb_ldb_destructor);
entry_ex->ctx = private;
entry_ex->free_entry = hdb_ldb_free_entry;
@@ -551,7 +551,7 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
entry_ex->entry.principal = malloc(sizeof(*(entry_ex->entry.principal)));
- if (ent_type == HDB_LDB_ENT_TYPE_ANY && principal == NULL) {
+ if (ent_type == HDB_SAMBA4_ENT_TYPE_ANY && principal == NULL) {
const char *samAccountName = ldb_msg_find_attr_as_string(msg, "samAccountName", NULL);
if (!samAccountName) {
krb5_set_error_string(context, "LDB_message2entry: no samAccountName present");
@@ -587,7 +587,7 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
entry_ex->entry.flags = uf2HDBFlags(context, userAccountControl, ent_type);
- if (ent_type == HDB_LDB_ENT_TYPE_KRBTGT) {
+ if (ent_type == HDB_SAMBA4_ENT_TYPE_KRBTGT) {
entry_ex->entry.flags.invalid = 0;
entry_ex->entry.flags.server = 1;
entry_ex->entry.flags.forwardable = 1;
@@ -631,7 +631,7 @@ static krb5_error_code LDB_message2entry(krb5_context context, HDB *db,
*entry_ex->entry.valid_end = nt_time_to_unix(acct_expiry);
}
- if (ent_type != HDB_LDB_ENT_TYPE_KRBTGT) {
+ if (ent_type != HDB_SAMBA4_ENT_TYPE_KRBTGT) {
NTTIME must_change_time
= samdb_result_force_password_change((struct ldb_context *)db->hdb_db, mem_ctx,
domain_dn, msg);
@@ -728,7 +728,7 @@ static krb5_error_code LDB_trust_message2entry(krb5_context context, HDB *db,
private->iconv_convenience = lp_iconv_convenience(lp_ctx);
private->netbios_name = lp_netbios_name(lp_ctx);
- talloc_set_destructor(private, hdb_ldb_destrutor);
+ talloc_set_destructor(private, hdb_ldb_destructor);
entry_ex->ctx = private;
entry_ex->free_entry = hdb_ldb_free_entry;
@@ -757,13 +757,20 @@ static krb5_error_code LDB_trust_message2entry(krb5_context context, HDB *db,
goto out;
}
- ndr_err = ndr_pull_struct_blob_all(password_val, mem_ctx, private->iconv_convenience, &password_blob,
+ ndr_err = ndr_pull_struct_blob(password_val, mem_ctx, private->iconv_convenience, &password_blob,
(ndr_pull_flags_fn_t)ndr_pull_trustAuthInOutBlob);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
ret = EINVAL;
goto out;
}
+ entry_ex->entry.kvno = -1;
+ for (i=0; i < password_blob.count; i++) {
+ if (password_blob.current->array[i].AuthType == TRUST_AUTH_TYPE_VERSION) {
+ entry_ex->entry.kvno = password_blob.current->array[i].AuthInfo.version.version;
+ }
+ }
+
for (i=0; i < password_blob.count; i++) {
if (password_blob.current->array[i].AuthType == TRUST_AUTH_TYPE_CLEAR) {
password_utf16 = data_blob_const(password_blob.current->array[i].AuthInfo.clear.password,
@@ -806,6 +813,8 @@ static krb5_error_code LDB_trust_message2entry(krb5_context context, HDB *db,
entry_ex->entry.keys.len++;
}
+ entry_ex->entry.principal = malloc(sizeof(*(entry_ex->entry.principal)));
+
ret = copy_Principal(principal, entry_ex->entry.principal);
if (ret) {
krb5_clear_error_string(context);
@@ -909,16 +918,16 @@ static krb5_error_code LDB_lookup_principal(krb5_context context, struct ldb_con
}
switch (ent_type) {
- case HDB_LDB_ENT_TYPE_CLIENT:
- case HDB_LDB_ENT_TYPE_TRUST:
- case HDB_LDB_ENT_TYPE_ANY:
+ case HDB_SAMBA4_ENT_TYPE_CLIENT:
+ case HDB_SAMBA4_ENT_TYPE_TRUST:
+ case HDB_SAMBA4_ENT_TYPE_ANY:
/* Can't happen */
return EINVAL;
- case HDB_LDB_ENT_TYPE_KRBTGT:
+ case HDB_SAMBA4_ENT_TYPE_KRBTGT:
filter = talloc_asprintf(mem_ctx, "(&(objectClass=user)(samAccountName=%s))",
KRB5_TGS_NAME);
break;
- case HDB_LDB_ENT_TYPE_SERVER:
+ case HDB_SAMBA4_ENT_TYPE_SERVER:
filter = talloc_asprintf(mem_ctx, "(&(objectClass=user)(samAccountName=%s))",
short_princ_talloc);
break;
@@ -929,8 +938,8 @@ static krb5_error_code LDB_lookup_principal(krb5_context context, struct ldb_con
return ENOMEM;
}
- lret = ldb_search(ldb_ctx, realm_dn, LDB_SCOPE_SUBTREE, filter, princ_attrs, &res);
-
+ lret = ldb_search(ldb_ctx, mem_ctx, &res, realm_dn,
+ LDB_SCOPE_SUBTREE, princ_attrs, "%s", filter);
if (lret != LDB_SUCCESS) {
DEBUG(3, ("Failed to search for %s: %s\n", filter, ldb_errstring(ldb_ctx)));
return HDB_ERR_NOENTRY;
@@ -963,8 +972,9 @@ static krb5_error_code LDB_lookup_trust(krb5_context context, struct ldb_context
return ENOMEM;
}
- lret = ldb_search(ldb_ctx, ldb_get_default_basedn(ldb_ctx), LDB_SCOPE_SUBTREE, filter, attrs, &res);
-
+ lret = ldb_search(ldb_ctx, mem_ctx, &res,
+ ldb_get_default_basedn(ldb_ctx),
+ LDB_SCOPE_SUBTREE, attrs, "%s", filter);
if (lret != LDB_SUCCESS) {
DEBUG(3, ("Failed to search for %s: %s\n", filter, ldb_errstring(ldb_ctx)));
return HDB_ERR_NOENTRY;
@@ -988,7 +998,7 @@ static krb5_error_code LDB_lookup_realm(krb5_context context, struct ldb_context
struct ldb_result *cross_ref_res;
struct ldb_dn *partitions_basedn = samdb_partitions_dn(ldb_ctx, mem_ctx);
- ret = ldb_search_exp_fmt(ldb_ctx, mem_ctx, &cross_ref_res,
+ ret = ldb_search(ldb_ctx, mem_ctx, &cross_ref_res,
partitions_basedn, LDB_SCOPE_SUBTREE, realm_ref_attrs,
"(&(&(|(&(dnsRoot=%s)(nETBIOSName=*))(nETBIOSName=%s))(objectclass=crossRef))(ncName=*))",
realm, realm);
@@ -1074,7 +1084,7 @@ static krb5_error_code LDB_fetch_client(krb5_context context, HDB *db,
}
ret = LDB_message2entry(context, db, mem_ctx,
- principal, HDB_LDB_ENT_TYPE_CLIENT,
+ principal, HDB_SAMBA4_ENT_TYPE_CLIENT,
msg[0], realm_ref_msg[0], entry_ex);
return ret;
}
@@ -1135,7 +1145,7 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db,
ret = LDB_lookup_principal(context, (struct ldb_context *)db->hdb_db,
mem_ctx,
- principal, HDB_LDB_ENT_TYPE_KRBTGT, realm_dn, &msg);
+ principal, HDB_SAMBA4_ENT_TYPE_KRBTGT, realm_dn, &msg);
if (ret != 0) {
krb5_warnx(context, "LDB_fetch: could not find principal in DB");
@@ -1144,10 +1154,10 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db,
}
ret = LDB_message2entry(context, db, mem_ctx,
- principal, HDB_LDB_ENT_TYPE_KRBTGT,
+ principal, HDB_SAMBA4_ENT_TYPE_KRBTGT,
msg[0], realm_ref_msg_1[0], entry_ex);
if (ret != 0) {
- krb5_warnx(context, "LDB_fetch: message2entry failed");
+ krb5_warnx(context, "LDB_fetch: self krbtgt message2entry failed");
}
return ret;
@@ -1185,7 +1195,7 @@ static krb5_error_code LDB_fetch_krbtgt(krb5_context context, HDB *db,
principal, direction,
msg[0], entry_ex);
if (ret != 0) {
- krb5_warnx(context, "LDB_fetch: message2entry failed");
+ krb5_warnx(context, "LDB_fetch: trust_message2entry failed");
}
return ret;
@@ -1264,7 +1274,7 @@ static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db,
ret = LDB_lookup_principal(context, (struct ldb_context *)db->hdb_db,
mem_ctx,
- principal, HDB_LDB_ENT_TYPE_SERVER, realm_dn, &msg);
+ principal, HDB_SAMBA4_ENT_TYPE_SERVER, realm_dn, &msg);
if (ret != 0) {
return ret;
@@ -1272,7 +1282,7 @@ static krb5_error_code LDB_fetch_server(krb5_context context, HDB *db,
}
ret = LDB_message2entry(context, db, mem_ctx,
- principal, HDB_LDB_ENT_TYPE_SERVER,
+ principal, HDB_SAMBA4_ENT_TYPE_SERVER,
msg[0], realm_ref_msg[0], entry_ex);
if (ret != 0) {
krb5_warnx(context, "LDB_fetch: message2entry failed");
@@ -1357,7 +1367,7 @@ static krb5_error_code LDB_seq(krb5_context context, HDB *db, unsigned flags, hd
if (priv->index < priv->count) {
ret = LDB_message2entry(context, db, mem_ctx,
- NULL, HDB_LDB_ENT_TYPE_ANY,
+ NULL, HDB_SAMBA4_ENT_TYPE_ANY,
priv->msgs[priv->index++],
priv->realm_ref_msgs[0], entry);
} else {
@@ -1432,9 +1442,9 @@ static krb5_error_code LDB_firstkey(krb5_context context, HDB *db, unsigned flag
priv->realm_ref_msgs = talloc_steal(priv, realm_ref_msgs);
- lret = ldb_search(ldb_ctx, realm_dn,
- LDB_SCOPE_SUBTREE, "(objectClass=user)",
- user_attrs, &res);
+ lret = ldb_search(ldb_ctx, priv, &res,
+ realm_dn, LDB_SCOPE_SUBTREE, user_attrs,
+ "(objectClass=user)");
if (lret != LDB_SUCCESS) {
talloc_free(priv);
@@ -1475,7 +1485,7 @@ static krb5_error_code LDB_destroy(krb5_context context, HDB *db)
* (hdb_ldb_create) from the kpasswdd -> krb5 -> keytab_hdb -> hdb
* code */
-NTSTATUS kdc_hdb_ldb_create(TALLOC_CTX *mem_ctx,
+NTSTATUS kdc_hdb_samba4_create(TALLOC_CTX *mem_ctx,
struct event_context *ev_ctx,
struct loadparm_context *lp_ctx,
krb5_context context, struct HDB **db, const char *arg)
@@ -1535,12 +1545,12 @@ NTSTATUS kdc_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)
+krb5_error_code hdb_samba4_create(krb5_context context, struct HDB **db, const char *arg)
{
NTSTATUS nt_status;
/* The global kdc_mem_ctx and kdc_lp_ctx, Disgusting, ugly hack, but it means one less private hook */
- nt_status = kdc_hdb_ldb_create(kdc_mem_ctx, event_context_find(kdc_mem_ctx), kdc_lp_ctx,
- context, db, arg);
+ nt_status = kdc_hdb_samba4_create(kdc_mem_ctx, event_context_find(kdc_mem_ctx), kdc_lp_ctx,
+ context, db, arg);
if (NT_STATUS_IS_OK(nt_status)) {
return 0;
diff --git a/source4/kdc/kdc.c b/source4/kdc/kdc.c
index b7009b030f..83c6f1c2ee 100644
--- a/source4/kdc/kdc.c
+++ b/source4/kdc/kdc.c
@@ -484,7 +484,7 @@ static NTSTATUS kdc_add_socket(struct kdc_server *kdc, const char *address,
/* within the kdc task we want to be a single process, so
ask for the single process model ops and pass these to the
stream_setup_socket() call. */
- model_ops = process_model_byname("single");
+ model_ops = process_model_startup(kdc->task->event_ctx, "single");
if (!model_ops) {
DEBUG(0,("Can't find 'single' process model_ops\n"));
talloc_free(kdc_socket);
@@ -584,13 +584,11 @@ static NTSTATUS kdc_check_generic_kerberos(struct irpc_message *msg,
return NT_STATUS_INVALID_PARAMETER;
}
-#if 0
- /* Windows does not check this */
if (pac_validate.MessageType != 3) {
/* We don't implement any other message types - such as certificate validation - yet */
return NT_STATUS_INVALID_PARAMETER;
}
-#endif
+
if (pac_validate.ChecksumAndSignature.length != (pac_validate.ChecksumLength + pac_validate.SignatureLength)
|| pac_validate.ChecksumAndSignature.length < pac_validate.ChecksumLength
|| pac_validate.ChecksumAndSignature.length < pac_validate.SignatureLength ) {
@@ -669,6 +667,11 @@ static void kdc_task_init(struct task_server *task)
NTSTATUS status;
krb5_error_code ret;
struct interface *ifaces;
+ struct hdb_method hdb_samba4 = {
+ .interface_version = HDB_INTERFACE_VERSION,
+ .prefix = "samba4:",
+ .create = hdb_samba4_create
+ };
switch (lp_server_role(task->lp_ctx)) {
case ROLE_STANDALONE:
@@ -726,7 +729,7 @@ static void kdc_task_init(struct task_server *task)
}
kdc->config->num_db = 1;
- status = kdc_hdb_ldb_create(kdc, task->event_ctx, task->lp_ctx,
+ status = kdc_hdb_samba4_create(kdc, task->event_ctx, task->lp_ctx,
kdc->smb_krb5_context->krb5_context,
&kdc->config->db[0], NULL);
if (!NT_STATUS_IS_OK(status)) {
@@ -734,6 +737,16 @@ static void kdc_task_init(struct task_server *task)
return;
}
+
+ /* Register hdb-samba4 hooks */
+ ret = krb5_plugin_register(kdc->smb_krb5_context->krb5_context,
+ PLUGIN_TYPE_DATA, "hdb",
+ &hdb_samba4);
+ if(ret) {
+ task_server_terminate(task, "kdc: failed to register hdb keytab");
+ 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");