summaryrefslogtreecommitdiff
path: root/source4/kdc/db-glue.c
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2010-09-28 13:13:28 +1000
committerAndrew Bartlett <abartlet@samba.org>2010-09-29 04:23:07 +1000
commit89ee9e6518f5bd398bb44e0cd47454e2d69f469e (patch)
tree97c294dd0fd053b4ec9078fcd84e6bbf83efcaf6 /source4/kdc/db-glue.c
parent9d33929d76d0969917c1d42e1097d75af3401008 (diff)
downloadsamba-89ee9e6518f5bd398bb44e0cd47454e2d69f469e.tar.gz
samba-89ee9e6518f5bd398bb44e0cd47454e2d69f469e.tar.bz2
samba-89ee9e6518f5bd398bb44e0cd47454e2d69f469e.zip
s4-kdc Handle the case where we may be given a ticket from an RODC in db layer
This includes rewriting the PAC if the original krbtgt isn't to be trusted, and reading different entries from the DB for the krbtgt depending on the krbtgt number. Andrew Bartlett
Diffstat (limited to 'source4/kdc/db-glue.c')
-rw-r--r--source4/kdc/db-glue.c65
1 files changed, 48 insertions, 17 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;
}