summaryrefslogtreecommitdiff
path: root/source4/kdc
diff options
context:
space:
mode:
Diffstat (limited to 'source4/kdc')
-rw-r--r--source4/kdc/db-glue.c65
-rw-r--r--source4/kdc/db-glue.h1
-rw-r--r--source4/kdc/hdb-samba4.c9
-rw-r--r--source4/kdc/kdc.c1
-rw-r--r--source4/kdc/mit_samba.c2
-rw-r--r--source4/kdc/wdc-samba4.c42
6 files changed, 83 insertions, 37 deletions
diff --git a/source4/kdc/db-glue.c b/source4/kdc/db-glue.c
index 2cda04bca8..ecb160caf3 100644
--- a/source4/kdc/db-glue.c
+++ b/source4/kdc/db-glue.c
@@ -1049,10 +1049,11 @@ static krb5_error_code samba_kdc_fetch_client(krb5_context context,
}
static krb5_error_code samba_kdc_fetch_krbtgt(krb5_context context,
- struct samba_kdc_db_context *kdc_db_ctx,
- TALLOC_CTX *mem_ctx,
- krb5_const_principal principal,
- hdb_entry_ex *entry_ex)
+ struct samba_kdc_db_context *kdc_db_ctx,
+ TALLOC_CTX *mem_ctx,
+ krb5_const_principal principal,
+ uint32_t krbtgt_number,
+ hdb_entry_ex *entry_ex)
{
struct loadparm_context *lp_ctx = kdc_db_ctx->lp_ctx;
krb5_error_code ret;
@@ -1070,7 +1071,7 @@ static krb5_error_code samba_kdc_fetch_krbtgt(krb5_context context,
if (lpcfg_is_my_domain_or_realm(lp_ctx, principal->realm)
&& lpcfg_is_my_domain_or_realm(lp_ctx, principal->name.name_string.val[1])) {
- /* us */
+ /* us, or someone quite like us */
/* Cludge, cludge cludge. If the realm part of krbtgt/realm,
* is in our db, then direct the caller at our primary
* krbtgt */
@@ -1078,18 +1079,35 @@ static krb5_error_code samba_kdc_fetch_krbtgt(krb5_context context,
int lret;
char *realm_fixed;
- lret = dsdb_search_one(kdc_db_ctx->samdb, mem_ctx,
- &msg, realm_dn, LDB_SCOPE_SUBTREE,
- krbtgt_attrs,
- DSDB_SEARCH_SHOW_EXTENDED_DN,
- "(&(objectClass=user)(samAccountName=krbtgt))");
+ if (krbtgt_number == kdc_db_ctx->my_krbtgt_number) {
+ lret = dsdb_search_one(kdc_db_ctx->samdb, mem_ctx,
+ &msg, kdc_db_ctx->krbtgt_dn, LDB_SCOPE_BASE,
+ krbtgt_attrs, 0,
+ "(objectClass=user)");
+ } else {
+ /* We need to look up an RODC krbtgt (perhaps
+ * ours, if we are an RODC, perhaps another
+ * RODC if we are a read-write DC */
+ lret = dsdb_search_one(kdc_db_ctx->samdb, mem_ctx,
+ &msg, realm_dn, LDB_SCOPE_SUBTREE,
+ krbtgt_attrs,
+ DSDB_SEARCH_SHOW_EXTENDED_DN,
+ "(&(objectClass=user)(msDS-SecondaryKrbTgtNumber=%u))", (unsigned)(krbtgt_number));
+ }
+
if (lret == LDB_ERR_NO_SUCH_OBJECT) {
- krb5_warnx(context, "samba_kdc_fetch: could not find own KRBTGT in DB!");
- krb5_set_error_message(context, HDB_ERR_NOENTRY, "samba_kdc_fetch: could not find own KRBTGT in DB!");
+ krb5_warnx(context, "samba_kdc_fetch: could not find KRBTGT number %u in DB!",
+ (unsigned)(krbtgt_number));
+ krb5_set_error_message(context, HDB_ERR_NOENTRY,
+ "samba_kdc_fetch: could not find KRBTGT number %u in DB!",
+ (unsigned)(krbtgt_number));
return HDB_ERR_NOENTRY;
} else if (lret != LDB_SUCCESS) {
- krb5_warnx(context, "samba_kdc_fetch: could not find own KRBTGT in DB: %s", ldb_errstring(kdc_db_ctx->samdb));
- krb5_set_error_message(context, HDB_ERR_NOENTRY, "samba_kdc_fetch: could not find own KRBTGT in DB: %s", ldb_errstring(kdc_db_ctx->samdb));
+ krb5_warnx(context, "samba_kdc_fetch: could not find KRBTGT number %u in DB!",
+ (unsigned)(krbtgt_number));
+ krb5_set_error_message(context, HDB_ERR_NOENTRY,
+ "samba_kdc_fetch: could not find KRBTGT number %u in DB!",
+ (unsigned)(krbtgt_number));
return HDB_ERR_NOENTRY;
}
@@ -1281,11 +1299,24 @@ krb5_error_code samba_kdc_fetch(krb5_context context,
struct samba_kdc_db_context *kdc_db_ctx,
krb5_const_principal principal,
unsigned flags,
+ unsigned kvno,
hdb_entry_ex *entry_ex)
{
krb5_error_code ret = HDB_ERR_NOENTRY;
- TALLOC_CTX *mem_ctx = talloc_named(kdc_db_ctx, 0, "samba_kdc_fetch context");
+ TALLOC_CTX *mem_ctx;
+ unsigned int krbtgt_number;
+ if (flags & HDB_F_KVNO_SPECIFIED) {
+ krbtgt_number = kvno >> 16;
+ if (kdc_db_ctx->rodc) {
+ if (krbtgt_number != kdc_db_ctx->my_krbtgt_number) {
+ return HDB_ERR_NOT_FOUND_HERE;
+ }
+ }
+ } else {
+ krbtgt_number = kdc_db_ctx->my_krbtgt_number;
+ }
+ 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!");
@@ -1298,7 +1329,7 @@ krb5_error_code samba_kdc_fetch(krb5_context context,
}
if (flags & HDB_F_GET_SERVER) {
/* krbtgt fits into this situation for trusted realms, and for resolving different versions of our own realm name */
- ret = samba_kdc_fetch_krbtgt(context, kdc_db_ctx, mem_ctx, principal, entry_ex);
+ ret = samba_kdc_fetch_krbtgt(context, kdc_db_ctx, mem_ctx, principal, krbtgt_number, entry_ex);
if (ret != HDB_ERR_NOENTRY) goto done;
/* We return 'no entry' if it does not start with krbtgt/, so move to the common case quickly */
@@ -1306,7 +1337,7 @@ krb5_error_code samba_kdc_fetch(krb5_context context,
if (ret != HDB_ERR_NOENTRY) goto done;
}
if (flags & HDB_F_GET_KRBTGT) {
- ret = samba_kdc_fetch_krbtgt(context, kdc_db_ctx, mem_ctx, principal, entry_ex);
+ ret = samba_kdc_fetch_krbtgt(context, kdc_db_ctx, mem_ctx, principal, krbtgt_number, entry_ex);
if (ret != HDB_ERR_NOENTRY) goto done;
}
diff --git a/source4/kdc/db-glue.h b/source4/kdc/db-glue.h
index 5f9c39dfb6..9738fbc769 100644
--- a/source4/kdc/db-glue.h
+++ b/source4/kdc/db-glue.h
@@ -25,6 +25,7 @@ krb5_error_code samba_kdc_fetch(krb5_context context,
struct samba_kdc_db_context *kdc_db_ctx,
krb5_const_principal principal,
unsigned flags,
+ unsigned kvno,
hdb_entry_ex *entry_ex);
krb5_error_code samba_kdc_firstkey(krb5_context context,
diff --git a/source4/kdc/hdb-samba4.c b/source4/kdc/hdb-samba4.c
index cbc00df0ae..53b1abee94 100644
--- a/source4/kdc/hdb-samba4.c
+++ b/source4/kdc/hdb-samba4.c
@@ -83,16 +83,17 @@ static krb5_error_code hdb_samba4_remove(krb5_context context, HDB *db, krb5_con
}
static krb5_error_code hdb_samba4_fetch(krb5_context context, HDB *db,
- krb5_const_principal principal,
- unsigned flags,
- hdb_entry_ex *entry_ex)
+ krb5_const_principal principal,
+ unsigned flags,
+ unsigned kvno,
+ hdb_entry_ex *entry_ex)
{
struct samba_kdc_db_context *kdc_db_ctx;
kdc_db_ctx = talloc_get_type_abort(db->hdb_db,
struct samba_kdc_db_context);
- return samba_kdc_fetch(context, kdc_db_ctx, principal, flags, entry_ex);
+ return samba_kdc_fetch(context, kdc_db_ctx, principal, flags, kvno, entry_ex);
}
static krb5_error_code hdb_samba4_firstkey(krb5_context context, HDB *db, unsigned flags,
diff --git a/source4/kdc/kdc.c b/source4/kdc/kdc.c
index 5adb0709cf..4dd2113dff 100644
--- a/source4/kdc/kdc.c
+++ b/source4/kdc/kdc.c
@@ -632,6 +632,7 @@ static NTSTATUS kdc_check_generic_kerberos(struct irpc_message *msg,
kdc->config->db[0],
principal,
HDB_F_GET_KRBTGT | HDB_F_DECRYPT,
+ 0,
&ent);
if (ret != 0) {
diff --git a/source4/kdc/mit_samba.c b/source4/kdc/mit_samba.c
index 217f0983ae..14ad7be414 100644
--- a/source4/kdc/mit_samba.c
+++ b/source4/kdc/mit_samba.c
@@ -130,7 +130,7 @@ static int mit_samba_get_principal(struct mit_samba_context *ctx,
}
ret = samba_kdc_fetch(ctx->context, ctx->db_ctx,
- principal, flags, hentry);
+ principal, flags, 0, hentry);
krb5_free_principal(ctx->context, principal);
diff --git a/source4/kdc/wdc-samba4.c b/source4/kdc/wdc-samba4.c
index 0ebc4e7c2b..8926594698 100644
--- a/source4/kdc/wdc-samba4.c
+++ b/source4/kdc/wdc-samba4.c
@@ -60,7 +60,9 @@ static krb5_error_code samba_wdc_get_pac(void *priv, krb5_context context,
static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context,
const krb5_principal client_principal,
struct hdb_entry_ex *client,
- struct hdb_entry_ex *server, krb5_pac *pac)
+ struct hdb_entry_ex *server,
+ struct hdb_entry_ex *krbtgt,
+ krb5_pac *pac)
{
struct samba_kdc_entry *p = talloc_get_type(server->ctx, struct samba_kdc_entry);
TALLOC_CTX *mem_ctx = talloc_named(p, 0, "samba_kdc_reget_pac context");
@@ -72,27 +74,37 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context,
return ENOMEM;
}
- pac_blob = talloc_zero(mem_ctx, DATA_BLOB);
- if (!pac_blob) {
- talloc_free(mem_ctx);
- return ENOMEM;
- }
-
/* The user account may be set not to want the PAC */
if (!samba_princ_needs_pac(server)) {
talloc_free(mem_ctx);
return EINVAL;
}
- nt_status = samba_kdc_update_pac_blob(mem_ctx, context,
- pac, pac_blob);
- if (!NT_STATUS_IS_OK(nt_status)) {
- DEBUG(0, ("Building PAC failed: %s\n",
- nt_errstr(nt_status)));
- talloc_free(mem_ctx);
- return EINVAL;
- }
+ /* If the krbtgt was generated by an RODC, and we are not that
+ * RODC, then we need to regenerate the PAC - we can't trust
+ * it */
+ if (samba_krbtgt_was_untrusted_rodc(krbtgt)) {
+ nt_status = samba_kdc_get_pac_blob(mem_ctx, client, &pac_blob);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ talloc_free(mem_ctx);
+ return EINVAL;
+ }
+ } else {
+ pac_blob = talloc_zero(mem_ctx, DATA_BLOB);
+ if (!pac_blob) {
+ talloc_free(mem_ctx);
+ return ENOMEM;
+ }
+ nt_status = samba_kdc_update_pac_blob(mem_ctx, context,
+ pac, pac_blob);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(0, ("Building PAC failed: %s\n",
+ nt_errstr(nt_status)));
+ talloc_free(mem_ctx);
+ return EINVAL;
+ }
+ }
/* We now completely regenerate this pac */
krb5_pac_free(context, *pac);