summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2018-09-19 19:24:11 -0700
committerJoseph Sutton <jsutton@samba.org>2022-01-19 20:50:35 +0000
commit8d7e9366f90a549cd191c271fddfd03b4d00e4bb (patch)
tree17912cd26b99239ea5f83110ba324c13656c210a /source4
parent8329e8d46917d67f0cb51c3a004e323a87fa1499 (diff)
downloadsamba-8d7e9366f90a549cd191c271fddfd03b4d00e4bb.tar.gz
s4:kdc/hdb: Store and retrieve a FX-COOKIE value
Note Windows uses the string "MICROSOFT" as cookie, so it's wrong to have a per DC cookie, but we need to adjust the Heimdal logic to support that. NOTE: THIS COMMIT WON'T COMPILE/WORK ON ITS OWN! Signed-off-by: Andrew Bartlett <abartlet@samba.org> Reviewed-by: Stefan Metzmacher <metze@samba.org>
Diffstat (limited to 'source4')
-rw-r--r--source4/kdc/db-glue.c186
-rw-r--r--source4/kdc/db-glue.h6
-rw-r--r--source4/kdc/hdb-samba4.c129
-rw-r--r--source4/kdc/samba_kdc.h2
4 files changed, 253 insertions, 70 deletions
diff --git a/source4/kdc/db-glue.c b/source4/kdc/db-glue.c
index b059d8c7e61..bef8bd4f454 100644
--- a/source4/kdc/db-glue.c
+++ b/source4/kdc/db-glue.c
@@ -29,6 +29,7 @@
#include "dsdb/common/util.h"
#include "librpc/gen_ndr/ndr_drsblobs.h"
#include "param/param.h"
+#include "param/secrets.h"
#include "../lib/crypto/md4.h"
#include "system/kerberos.h"
#include "auth/kerberos/kerberos.h"
@@ -317,6 +318,104 @@ static int samba_kdc_sort_encryption_keys(struct sdb_entry_ex *entry_ex)
return 0;
}
+int samba_kdc_set_fixed_keys(krb5_context context,
+ struct samba_kdc_db_context *kdc_db_ctx,
+ const struct ldb_val *secretbuffer,
+ struct sdb_entry_ex *entry_ex)
+{
+ const uint32_t supported_enctypes = ENC_ALL_TYPES;
+ uint16_t allocated_keys = 0;
+ int ret;
+
+ allocated_keys = 3;
+ entry_ex->entry.keys.len = 0;
+ entry_ex->entry.keys.val = calloc(allocated_keys, sizeof(struct sdb_key));
+ if (entry_ex->entry.keys.val == NULL) {
+ memset(secretbuffer->data, 0, secretbuffer->length);
+ ret = ENOMEM;
+ goto out;
+ }
+
+ if (supported_enctypes & ENC_HMAC_SHA1_96_AES256) {
+ struct sdb_key key = {};
+
+ ret = smb_krb5_keyblock_init_contents(context,
+ ENCTYPE_AES256_CTS_HMAC_SHA1_96,
+ secretbuffer->data,
+ MIN(secretbuffer->length, 32),
+ &key.key);
+ if (ret) {
+ memset(secretbuffer->data, 0, secretbuffer->length);
+ goto out;
+ }
+
+ entry_ex->entry.keys.val[entry_ex->entry.keys.len] = key;
+ entry_ex->entry.keys.len++;
+ }
+
+ if (supported_enctypes & ENC_HMAC_SHA1_96_AES128) {
+ struct sdb_key key = {};
+
+ ret = smb_krb5_keyblock_init_contents(context,
+ ENCTYPE_AES128_CTS_HMAC_SHA1_96,
+ secretbuffer->data,
+ MIN(secretbuffer->length, 16),
+ &key.key);
+ if (ret) {
+ memset(secretbuffer->data, 0, secretbuffer->length);
+ goto out;
+ }
+
+ entry_ex->entry.keys.val[entry_ex->entry.keys.len] = key;
+ entry_ex->entry.keys.len++;
+ }
+
+ if (supported_enctypes & ENC_RC4_HMAC_MD5) {
+ struct sdb_key key = {};
+
+ ret = smb_krb5_keyblock_init_contents(context,
+ ENCTYPE_ARCFOUR_HMAC,
+ secretbuffer->data,
+ MIN(secretbuffer->length, 16),
+ &key.key);
+ if (ret) {
+ memset(secretbuffer->data, 0, secretbuffer->length);
+ goto out;
+ }
+
+ entry_ex->entry.keys.val[entry_ex->entry.keys.len] = key;
+ entry_ex->entry.keys.len++;
+ }
+ ret = 0;
+out:
+ return ret;
+}
+
+
+static int samba_kdc_set_random_keys(krb5_context context,
+ struct samba_kdc_db_context *kdc_db_ctx,
+ struct sdb_entry_ex *entry_ex)
+{
+ struct ldb_val secret_val;
+ uint8_t secretbuffer[32];
+
+ /*
+ * Fake keys until we have a better way to reject
+ * non-pkinit requests.
+ *
+ * We just need to indicate which encryption types are
+ * supported.
+ */
+ generate_secret_buffer(secretbuffer, sizeof(secretbuffer));
+
+ secret_val = data_blob_const(secretbuffer,
+ sizeof(secretbuffer));
+ return samba_kdc_set_fixed_keys(context, kdc_db_ctx,
+ &secret_val,
+ entry_ex);
+}
+
+
static krb5_error_code samba_kdc_message2entry_keys(krb5_context context,
struct samba_kdc_db_context *kdc_db_ctx,
TALLOC_CTX *mem_ctx,
@@ -386,75 +485,9 @@ static krb5_error_code samba_kdc_message2entry_keys(krb5_context context,
if ((ent_type == SAMBA_KDC_ENT_TYPE_CLIENT)
&& (userAccountControl & UF_SMARTCARD_REQUIRED)) {
- uint8_t secretbuffer[32];
-
- /*
- * Fake keys until we have a better way to reject
- * non-pkinit requests.
- *
- * We just need to indicate which encryption types are
- * supported.
- */
- generate_secret_buffer(secretbuffer, sizeof(secretbuffer));
-
- allocated_keys = 3;
- entry_ex->entry.keys.len = 0;
- entry_ex->entry.keys.val = calloc(allocated_keys, sizeof(struct sdb_key));
- if (entry_ex->entry.keys.val == NULL) {
- ZERO_STRUCT(secretbuffer);
- ret = ENOMEM;
- goto out;
- }
-
- if (supported_enctypes & ENC_HMAC_SHA1_96_AES256) {
- struct sdb_key key = {};
-
- ret = smb_krb5_keyblock_init_contents(context,
- ENCTYPE_AES256_CTS_HMAC_SHA1_96,
- secretbuffer, 32,
- &key.key);
- if (ret) {
- ZERO_STRUCT(secretbuffer);
- goto out;
- }
-
- entry_ex->entry.keys.val[entry_ex->entry.keys.len] = key;
- entry_ex->entry.keys.len++;
- }
-
- if (supported_enctypes & ENC_HMAC_SHA1_96_AES128) {
- struct sdb_key key = {};
-
- ret = smb_krb5_keyblock_init_contents(context,
- ENCTYPE_AES128_CTS_HMAC_SHA1_96,
- secretbuffer, 16,
- &key.key);
- if (ret) {
- ZERO_STRUCT(secretbuffer);
- goto out;
- }
-
- entry_ex->entry.keys.val[entry_ex->entry.keys.len] = key;
- entry_ex->entry.keys.len++;
- }
-
- if (supported_enctypes & ENC_RC4_HMAC_MD5) {
- struct sdb_key key = {};
-
- ret = smb_krb5_keyblock_init_contents(context,
- ENCTYPE_ARCFOUR_HMAC,
- secretbuffer, 16,
- &key.key);
- if (ret) {
- ZERO_STRUCT(secretbuffer);
- goto out;
- }
-
- entry_ex->entry.keys.val[entry_ex->entry.keys.len] = key;
- entry_ex->entry.keys.len++;
- }
-
- ret = 0;
+ ret = samba_kdc_set_random_keys(context,
+ kdc_db_ctx,
+ entry_ex);
goto out;
}
@@ -2788,6 +2821,21 @@ NTSTATUS samba_kdc_setup_db_ctx(TALLOC_CTX *mem_ctx, struct samba_kdc_base_conte
return NT_STATUS_INTERNAL_ERROR;
}
+ /* Setup the link to secrets.ldb */
+
+ kdc_db_ctx->secrets_db = secrets_db_connect(kdc_db_ctx,
+ base_ctx->lp_ctx);
+ if (kdc_db_ctx->secrets_db == NULL) {
+ DEBUG(1, ("samba_kdc_setup_db_ctx: "
+ "Cannot open secrets.ldb for KDC backend!"));
+ talloc_free(kdc_db_ctx);
+ return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ }
+
+ kdc_db_ctx->fx_cookie_dn = ldb_dn_new(kdc_db_ctx,
+ kdc_db_ctx->secrets_db,
+ "CN=FX Cookie");
+
/* Setup the link to LDB */
kdc_db_ctx->samdb = samdb_connect(kdc_db_ctx,
base_ctx->ev_ctx,
diff --git a/source4/kdc/db-glue.h b/source4/kdc/db-glue.h
index 4defca2320c..218bd3cfae2 100644
--- a/source4/kdc/db-glue.h
+++ b/source4/kdc/db-glue.h
@@ -23,6 +23,12 @@
struct sdb_entry_ex;
+
+int samba_kdc_set_fixed_keys(krb5_context context,
+ struct samba_kdc_db_context *kdc_db_ctx,
+ const struct ldb_val *secretbuffer,
+ struct sdb_entry_ex *entry_ex);
+
krb5_error_code samba_kdc_fetch(krb5_context context,
struct samba_kdc_db_context *kdc_db_ctx,
krb5_const_principal principal,
diff --git a/source4/kdc/hdb-samba4.c b/source4/kdc/hdb-samba4.c
index 9132bb46212..c0ec4bd3cd8 100644
--- a/source4/kdc/hdb-samba4.c
+++ b/source4/kdc/hdb-samba4.c
@@ -92,6 +92,128 @@ static krb5_error_code hdb_samba4_set_sync(krb5_context context, struct HDB *db,
return 0;
}
+static int hdb_samba4_fill_fast_cookie(krb5_context context,
+ struct samba_kdc_db_context *kdc_db_ctx)
+{
+ struct ldb_message *msg = ldb_msg_new(kdc_db_ctx);
+ int ldb_ret;
+
+ uint8_t secretbuffer[32];
+ struct ldb_val val = data_blob_const(secretbuffer,
+ sizeof(secretbuffer));
+
+ if (msg == NULL) {
+ DBG_ERR("Failed to allocate msg for new fast cookie\n");
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ /* Fill in all the keys with the same secret */
+ generate_secret_buffer(secretbuffer,
+ sizeof(secretbuffer));
+
+ msg->dn = kdc_db_ctx->fx_cookie_dn;
+
+ ldb_ret = ldb_msg_add_value(msg, "secret", &val, NULL);
+
+ if (ldb_ret != LDB_SUCCESS) {
+ return ldb_ret;
+ }
+
+ ldb_ret = ldb_add(kdc_db_ctx->secrets_db,
+ msg);
+ if (ldb_ret != LDB_SUCCESS) {
+ DBG_ERR("Failed to add fast cookie to ldb: %s\n",
+ ldb_errstring(kdc_db_ctx->secrets_db));
+ }
+ return ldb_ret;
+}
+
+static krb5_error_code hdb_samba4_fetch_fast_cookie(krb5_context context,
+ struct samba_kdc_db_context *kdc_db_ctx,
+ hdb_entry_ex *entry_ex)
+{
+ krb5_error_code ret = SDB_ERR_NOENTRY;
+ TALLOC_CTX *mem_ctx;
+ struct ldb_result *res;
+ int ldb_ret;
+ struct sdb_entry_ex sdb_entry_ex = {};
+ const char *attrs[] = {
+ "secret",
+ NULL
+ };
+ const struct ldb_val *val;
+
+ mem_ctx = talloc_named(kdc_db_ctx, 0, "samba_kdc_fetch context");
+ if (!mem_ctx) {
+ ret = ENOMEM;
+ krb5_set_error_message(context, ret, "samba_kdc_fetch: talloc_named() failed!");
+ return ret;
+ }
+
+ /* search for CN=FX-COOKIE */
+ ldb_ret = ldb_search(kdc_db_ctx->secrets_db,
+ mem_ctx,
+ &res,
+ kdc_db_ctx->fx_cookie_dn,
+ LDB_SCOPE_BASE,
+ attrs, NULL);
+
+ if (ldb_ret == LDB_ERR_NO_SUCH_OBJECT || res->count == 0) {
+
+ ldb_ret = hdb_samba4_fill_fast_cookie(context,
+ kdc_db_ctx);
+
+ if (ldb_ret != LDB_SUCCESS) {
+ TALLOC_FREE(mem_ctx);
+ return HDB_ERR_NO_WRITE_SUPPORT;
+ }
+
+ /* search for CN=FX-COOKIE */
+ ldb_ret = ldb_search(kdc_db_ctx->secrets_db,
+ mem_ctx,
+ &res,
+ kdc_db_ctx->fx_cookie_dn,
+ LDB_SCOPE_BASE,
+ attrs, NULL);
+
+ if (ldb_ret != LDB_SUCCESS || res->count != 1) {
+ TALLOC_FREE(mem_ctx);
+ return HDB_ERR_NOENTRY;
+ }
+ }
+
+ val = ldb_msg_find_ldb_val(res->msgs[0],
+ "secret");
+ if (val == NULL || val->length != 32) {
+ TALLOC_FREE(mem_ctx);
+ return HDB_ERR_NOENTRY;
+ }
+
+
+ ret = krb5_make_principal(context,
+ &sdb_entry_ex.entry.principal,
+ KRB5_WELLKNOWN_ORG_H5L_REALM,
+ KRB5_WELLKNOWN_NAME, "org.h5l.fast-cookie",
+ NULL);
+ if (ret) {
+ TALLOC_FREE(mem_ctx);
+ return ret;
+ }
+
+ ret = samba_kdc_set_fixed_keys(context, kdc_db_ctx,
+ val, &sdb_entry_ex);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = sdb_entry_ex_to_hdb_entry_ex(context,
+ &sdb_entry_ex,
+ entry_ex);
+ TALLOC_FREE(mem_ctx);
+
+ return ret;
+}
+
static krb5_error_code hdb_samba4_fetch_kvno(krb5_context context, HDB *db,
krb5_const_principal principal,
unsigned flags,
@@ -101,10 +223,15 @@ static krb5_error_code hdb_samba4_fetch_kvno(krb5_context context, HDB *db,
struct samba_kdc_db_context *kdc_db_ctx;
struct sdb_entry_ex sdb_entry_ex = {};
krb5_error_code code, ret;
-
kdc_db_ctx = talloc_get_type_abort(db->hdb_db,
struct samba_kdc_db_context);
+ if (flags & HDB_F_GET_FAST_COOKIE) {
+ return hdb_samba4_fetch_fast_cookie(context,
+ kdc_db_ctx,
+ entry_ex);
+ }
+
ret = samba_kdc_fetch(context,
kdc_db_ctx,
principal,
diff --git a/source4/kdc/samba_kdc.h b/source4/kdc/samba_kdc.h
index e228a82ce6a..150729a01f3 100644
--- a/source4/kdc/samba_kdc.h
+++ b/source4/kdc/samba_kdc.h
@@ -48,6 +48,8 @@ struct samba_kdc_db_context {
unsigned int my_krbtgt_number;
struct ldb_dn *krbtgt_dn;
struct samba_kdc_policy policy;
+ struct ldb_dn *fx_cookie_dn;
+ struct ldb_context *secrets_db;
};
struct samba_kdc_entry {