summaryrefslogtreecommitdiff
path: root/source4/kdc
diff options
context:
space:
mode:
Diffstat (limited to 'source4/kdc')
-rw-r--r--source4/kdc/hdb-ldb.c104
1 files changed, 93 insertions, 11 deletions
diff --git a/source4/kdc/hdb-ldb.c b/source4/kdc/hdb-ldb.c
index 80e8cdc74e..87e8273898 100644
--- a/source4/kdc/hdb-ldb.c
+++ b/source4/kdc/hdb-ldb.c
@@ -38,6 +38,7 @@
#include "hdb.h"
#include "lib/ldb/include/ldb.h"
#include "system/iconv.h"
+#include "librpc/gen_ndr/netlogon.h"
enum hdb_ldb_ent_type
{ HDB_LDB_ENT_TYPE_CLIENT, HDB_LDB_ENT_TYPE_SERVER,
@@ -72,6 +73,12 @@ static const char *realm_ref_attrs[] = {
NULL
};
+struct hdb_ldb_private {
+ struct ldb_context *samdb;
+ struct ldb_message **msg;
+ struct ldb_message **realm_ref_msg;
+};
+
static KerberosTime ldb_msg_find_krb5time_ldap_time(struct ldb_message *msg, const char *attr, KerberosTime default_val)
{
const char *tmp;
@@ -611,10 +618,48 @@ static krb5_error_code LDB_rename(krb5_context context, HDB *db, const char *new
return HDB_ERR_DB_INUSE;
}
-static krb5_error_code LDB_fetch(krb5_context context, HDB *db, unsigned flags,
- krb5_const_principal principal,
- enum hdb_ent_type ent_type,
- hdb_entry *entry)
+static krb5_error_code hdb_ldb_free_private(krb5_context context, hdb_entry_ex *entry_ex)
+{
+ talloc_free(entry_ex->private);
+ return 0;
+}
+
+static krb5_error_code hdb_ldb_check_client_access(krb5_context context, hdb_entry_ex *entry_ex,
+ HostAddresses *addresses)
+{
+ krb5_error_code ret;
+ NTSTATUS nt_status;
+ TALLOC_CTX *tmp_ctx = talloc_new(entry_ex->private);
+ struct hdb_ldb_private *private = entry_ex->private;
+ char *name, *workstation = NULL;
+ if (!tmp_ctx) {
+ return ENOMEM;
+ }
+
+ ret = krb5_unparse_name(context, entry_ex->entry.principal, &name);
+ if (ret != 0) {
+ talloc_free(tmp_ctx);
+ }
+ nt_status = authsam_account_ok(tmp_ctx,
+ private->samdb,
+ MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT | MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT,
+ private->msg,
+ private->realm_ref_msg,
+ workstation,
+ name);
+ free(name);
+
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ return KRB5KDC_ERR_POLICY;
+ }
+ return 0;
+}
+
+
+static krb5_error_code LDB_fetch_ex(krb5_context context, HDB *db, unsigned flags,
+ krb5_const_principal principal,
+ enum hdb_ent_type ent_type,
+ hdb_entry_ex *entry_ex)
{
struct ldb_message **msg = NULL;
struct ldb_message **realm_ref_msg = NULL;
@@ -631,10 +676,6 @@ static krb5_error_code LDB_fetch(krb5_context context, HDB *db, unsigned flags,
return ENOMEM;
}
- /* Cludge, cludge cludge. If the realm part of krbtgt/realm,
- * is in our db, then direct the caller at our primary
- * krgtgt */
-
switch (ent_type) {
case HDB_ENT_TYPE_CLIENT:
{
@@ -662,7 +703,23 @@ static krb5_error_code LDB_fetch(krb5_context context, HDB *db, unsigned flags,
ret = LDB_message2entry(context, db, mem_ctx,
principal, ldb_ent_type,
- msg[0], realm_ref_msg[0], entry);
+ msg[0], realm_ref_msg[0], &entry_ex->entry);
+
+ if (ret == 0) {
+ struct hdb_ldb_private *private = talloc(db, struct hdb_ldb_private);
+ if (!private) {
+ hdb_free_entry(context, &entry_ex->entry);
+ ret = ENOMEM;
+ }
+ private->msg = talloc_steal(private, msg);
+ private->realm_ref_msg = talloc_steal(private, realm_ref_msg);
+ private->samdb = (struct ldb_context *)db->hdb_db;
+
+ entry_ex->private = private;
+ entry_ex->free_private = hdb_ldb_free_private;
+ entry_ex->check_client_access = hdb_ldb_check_client_access;
+ }
+
talloc_free(mem_ctx);
return ret;
}
@@ -673,6 +730,10 @@ static krb5_error_code LDB_fetch(krb5_context context, HDB *db, unsigned flags,
if ((LDB_lookup_realm(context, (struct ldb_context *)db->hdb_db,
mem_ctx, principal->name.name_string.val[1], &realm_fixed_msg) == 0)) {
/* us */
+ /* Cludge, cludge cludge. If the realm part of krbtgt/realm,
+ * is in our db, then direct the caller at our primary
+ * krgtgt */
+
const char *dnsdomain = ldb_msg_find_string(realm_fixed_msg[0], "dnsRoot", NULL);
char *realm_fixed = strupper_talloc(mem_ctx, dnsdomain);
if (!realm_fixed) {
@@ -741,7 +802,7 @@ static krb5_error_code LDB_fetch(krb5_context context, HDB *db, unsigned flags,
ret = LDB_message2entry(context, db, mem_ctx,
principal, ldb_ent_type,
- msg[0], realm_ref_msg[0], entry);
+ msg[0], realm_ref_msg[0], &entry_ex->entry);
talloc_free(mem_ctx);
return ret;
@@ -784,7 +845,7 @@ static krb5_error_code LDB_fetch(krb5_context context, HDB *db, unsigned flags,
} else {
ret = LDB_message2entry(context, db, mem_ctx,
principal, ldb_ent_type,
- msg[0], realm_ref_msg[0], entry);
+ msg[0], realm_ref_msg[0], &entry_ex->entry);
if (ret != 0) {
krb5_warnx(context, "LDB_fetch: message2entry failed\n");
}
@@ -794,6 +855,26 @@ static krb5_error_code LDB_fetch(krb5_context context, HDB *db, unsigned flags,
return ret;
}
+static krb5_error_code LDB_fetch(krb5_context context, HDB *db, unsigned flags,
+ krb5_const_principal principal,
+ enum hdb_ent_type ent_type,
+ hdb_entry *entry)
+{
+ struct hdb_entry_ex entry_ex;
+ krb5_error_code ret;
+
+ memset(&entry_ex, '\0', sizeof(entry_ex));
+ ret = LDB_fetch_ex(context, db, flags, principal, ent_type, &entry_ex);
+
+ if (ret == 0) {
+ if (entry_ex.free_private) {
+ entry_ex.free_private(context, &entry_ex);
+ }
+ *entry = entry_ex.entry;
+ }
+ return ret;
+}
+
static krb5_error_code LDB_store(krb5_context context, HDB *db, unsigned flags, hdb_entry *entry)
{
return HDB_ERR_DB_INUSE;
@@ -967,6 +1048,7 @@ krb5_error_code hdb_ldb_create(TALLOC_CTX *mem_ctx,
(*db)->hdb_open = LDB_open;
(*db)->hdb_close = LDB_close;
(*db)->hdb_fetch = LDB_fetch;
+ (*db)->hdb_fetch_ex = LDB_fetch_ex;
(*db)->hdb_store = LDB_store;
(*db)->hdb_remove = LDB_remove;
(*db)->hdb_firstkey = LDB_firstkey;