summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/kdc/do_tgs_req.c19
-rw-r--r--src/kdc/kdc_util.h4
2 files changed, 21 insertions, 2 deletions
diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c
index 240203638..a71c01ced 100644
--- a/src/kdc/do_tgs_req.c
+++ b/src/kdc/do_tgs_req.c
@@ -270,8 +270,16 @@ process_tgs_req(struct server_handle *handle, krb5_data *pkt,
&status);
if (errcode)
goto cleanup;
- if (s4u_x509_user != NULL)
+ if (s4u_x509_user != NULL) {
setflag(c_flags, KRB5_KDB_FLAG_PROTOCOL_TRANSITION);
+ if (is_referral) {
+ /* The requesting server appears to no longer exist, and we found
+ * a referral instead. Treat this as a server lookup failure. */
+ errcode = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
+ status = "LOOKING_UP_SERVER";
+ goto cleanup;
+ }
+ }
errcode = decrypt_2ndtkt(kdc_active_realm, request, c_flags,
&stkt_server, &status);
@@ -1191,9 +1199,16 @@ search_sprinc(kdc_realm_t *kdc_active_realm, krb5_kdc_req *req,
krb5_error_code ret;
krb5_principal princ = req->server;
krb5_principal reftgs = NULL;
+ krb5_boolean allow_referral;
+
+ /* Do not allow referrals for u2u or ticket modification requests, because
+ * the server is supposed to match an already-issued ticket. */
+ allow_referral = !(req->kdc_options & NO_REFERRAL_OPTION);
+ if (!allow_referral)
+ flags &= ~KRB5_KDB_FLAG_CANONICALIZE;
ret = db_get_svc_princ(kdc_context, princ, flags, server, status);
- if (ret == 0 || ret != KRB5_KDB_NOENTRY)
+ if (ret == 0 || ret != KRB5_KDB_NOENTRY || !allow_referral)
goto cleanup;
if (!is_cross_tgs_principal(req->server)) {
diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h
index c50ee848a..6c5433361 100644
--- a/src/kdc/kdc_util.h
+++ b/src/kdc/kdc_util.h
@@ -410,6 +410,10 @@ struct krb5_kdcpreauth_rock_st {
#define NON_TGT_OPTION (KDC_OPT_FORWARDED | KDC_OPT_PROXY | KDC_OPT_RENEW | \
KDC_OPT_VALIDATE)
+
+/* TGS-REQ options which are not compatible with referrals */
+#define NO_REFERRAL_OPTION (NON_TGT_OPTION | KDC_OPT_ENC_TKT_IN_SKEY)
+
int check_anon(kdc_realm_t *kdc_active_realm,
krb5_principal client, krb5_principal server);
int errcode_to_protocol(krb5_error_code code);