kdc: pass the correct principal name for the resulting service ticket

Depending on S4U2Proxy the principal name for the resulting
ticket is not the principal of the client ticket.

metze

Signed-off-by: Love Hörnquist Åstrand <lha@h5l.org>
This commit is contained in:
Stefan Metzmacher
2011-03-25 12:36:14 +01:00
committed by Love Hörnquist Åstrand
parent 2c031ca78c
commit 9ab4070800

View File

@@ -1466,10 +1466,9 @@ tgs_build_reply(krb5_context context,
const struct sockaddr *from_addr) const struct sockaddr *from_addr)
{ {
krb5_error_code ret; krb5_error_code ret;
krb5_principal cp = NULL, sp = NULL; krb5_principal cp = NULL, sp = NULL, tp = NULL;
krb5_principal client_principal = NULL;
krb5_principal krbtgt_principal = NULL; krb5_principal krbtgt_principal = NULL;
char *spn = NULL, *cpn = NULL; char *spn = NULL, *cpn = NULL, *tpn = NULL;
hdb_entry_ex *server = NULL, *client = NULL, *s4u2self_impersonated_client = NULL; hdb_entry_ex *server = NULL, *client = NULL, *s4u2self_impersonated_client = NULL;
HDB *clientdb, *s4u2self_impersonated_clientdb; HDB *clientdb, *s4u2self_impersonated_clientdb;
krb5_realm ref_realm = NULL; krb5_realm ref_realm = NULL;
@@ -1723,16 +1722,16 @@ server_lookup:
krb5_free_principal(context, krbtgt_principal); krb5_free_principal(context, krbtgt_principal);
if (ret) { if (ret) {
krb5_error_code ret2; krb5_error_code ret2;
char *tpn, *tpn2; char *ktpn, *ktpn2;
ret = krb5_unparse_name(context, krbtgt->entry.principal, &tpn); ret = krb5_unparse_name(context, krbtgt->entry.principal, &ktpn);
ret2 = krb5_unparse_name(context, krbtgt->entry.principal, &tpn2); ret2 = krb5_unparse_name(context, krbtgt_principal, &ktpn2);
kdc_log(context, config, 0, kdc_log(context, config, 0,
"Request with wrong krbtgt: %s, %s not found in our database", "Request with wrong krbtgt: %s, %s not found in our database",
(ret == 0) ? tpn : "<unknown>", (ret2 == 0) ? tpn2 : "<unknown>"); (ret == 0) ? ktpn : "<unknown>", (ret2 == 0) ? ktpn2 : "<unknown>");
if(ret == 0) if(ret == 0)
free(tpn); free(ktpn);
if(ret2 == 0) if(ret2 == 0)
free(tpn2); free(ktpn2);
ret = KRB5KRB_AP_ERR_NOT_US; ret = KRB5KRB_AP_ERR_NOT_US;
goto out; goto out;
} }
@@ -1744,13 +1743,13 @@ server_lookup:
* this) before the strcmp() */ * this) before the strcmp() */
if (strcmp(krb5_principal_get_realm(context, server->entry.principal), if (strcmp(krb5_principal_get_realm(context, server->entry.principal),
krb5_principal_get_realm(context, krbtgt_out->entry.principal)) != 0) { krb5_principal_get_realm(context, krbtgt_out->entry.principal)) != 0) {
char *tpn; char *ktpn;
ret = krb5_unparse_name(context, krbtgt_out->entry.principal, &tpn); ret = krb5_unparse_name(context, krbtgt_out->entry.principal, &ktpn);
kdc_log(context, config, 0, kdc_log(context, config, 0,
"Request with wrong krbtgt: %s", "Request with wrong krbtgt: %s",
(ret == 0) ? tpn : "<unknown>"); (ret == 0) ? ktpn : "<unknown>");
if(ret == 0) if(ret == 0)
free(tpn); free(ktpn);
ret = KRB5KRB_AP_ERR_NOT_US; ret = KRB5KRB_AP_ERR_NOT_US;
} }
@@ -1827,7 +1826,9 @@ server_lookup:
* Process request * Process request
*/ */
client_principal = cp; /* by default the tgt principal matches the client principal */
tp = cp;
tpn = cpn;
if (client) { if (client) {
const PA_DATA *sdata; const PA_DATA *sdata;
@@ -1838,7 +1839,6 @@ server_lookup:
krb5_crypto crypto; krb5_crypto crypto;
krb5_data datack; krb5_data datack;
PA_S4U2Self self; PA_S4U2Self self;
char *selfcpn = NULL;
const char *str; const char *str;
ret = decode_PA_S4U2Self(sdata->padata_value.data, ret = decode_PA_S4U2Self(sdata->padata_value.data,
@@ -1881,14 +1881,14 @@ server_lookup:
} }
ret = _krb5_principalname2krb5_principal(context, ret = _krb5_principalname2krb5_principal(context,
&client_principal, &tp,
self.name, self.name,
self.realm); self.realm);
free_PA_S4U2Self(&self); free_PA_S4U2Self(&self);
if (ret) if (ret)
goto out; goto out;
ret = krb5_unparse_name(context, client_principal, &selfcpn); ret = krb5_unparse_name(context, tp, &tpn);
if (ret) if (ret)
goto out; goto out;
@@ -1896,7 +1896,7 @@ server_lookup:
if(rspac.data) { if(rspac.data) {
krb5_pac p = NULL; krb5_pac p = NULL;
krb5_data_free(&rspac); krb5_data_free(&rspac);
ret = _kdc_db_fetch(context, config, client_principal, HDB_F_GET_CLIENT | HDB_F_CANON, ret = _kdc_db_fetch(context, config, tp, HDB_F_GET_CLIENT | HDB_F_CANON,
NULL, &s4u2self_impersonated_clientdb, &s4u2self_impersonated_client); NULL, &s4u2self_impersonated_clientdb, &s4u2self_impersonated_client);
if (ret) { if (ret) {
const char *msg; const char *msg;
@@ -1910,14 +1910,16 @@ server_lookup:
if (ret == HDB_ERR_NOENTRY) if (ret == HDB_ERR_NOENTRY)
ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
msg = krb5_get_error_message(context, ret); msg = krb5_get_error_message(context, ret);
kdc_log(context, config, 1, "S2U4Self principal to impersonate %s not found in database: %s", cpn, msg); kdc_log(context, config, 1,
"S2U4Self principal to impersonate %s not found in database: %s",
tpn, msg);
krb5_free_error_message(context, msg); krb5_free_error_message(context, msg);
goto out; goto out;
} }
ret = _kdc_pac_generate(context, s4u2self_impersonated_client, &p); ret = _kdc_pac_generate(context, s4u2self_impersonated_client, &p);
if (ret) { if (ret) {
kdc_log(context, config, 0, "PAC generation failed for -- %s", kdc_log(context, config, 0, "PAC generation failed for -- %s",
selfcpn); tpn);
goto out; goto out;
} }
if (p != NULL) { if (p != NULL) {
@@ -1928,7 +1930,7 @@ server_lookup:
krb5_pac_free(context, p); krb5_pac_free(context, p);
if (ret) { if (ret) {
kdc_log(context, config, 0, "PAC signing failed for -- %s", kdc_log(context, config, 0, "PAC signing failed for -- %s",
selfcpn); tpn);
goto out; goto out;
} }
} }
@@ -1943,8 +1945,7 @@ server_lookup:
kdc_log(context, config, 0, "S4U2Self: %s is not allowed " kdc_log(context, config, 0, "S4U2Self: %s is not allowed "
"to impersonate to service " "to impersonate to service "
"(tried for user %s to service %s)", "(tried for user %s to service %s)",
cpn, selfcpn, spn); cpn, tpn, spn);
free(selfcpn);
goto out; goto out;
} }
@@ -1960,8 +1961,7 @@ server_lookup:
str = ""; str = "";
} }
kdc_log(context, config, 0, "s4u2self %s impersonating %s to " kdc_log(context, config, 0, "s4u2self %s impersonating %s to "
"service %s %s", cpn, selfcpn, spn, str); "service %s %s", cpn, tpn, spn, str);
free(selfcpn);
} }
} }
@@ -1977,7 +1977,6 @@ server_lookup:
int ad_signedpath = 0; int ad_signedpath = 0;
Key *clientkey; Key *clientkey;
Ticket *t; Ticket *t;
char *str;
/* /*
* Require that the KDC have issued the service's krbtgt (not * Require that the KDC have issued the service's krbtgt (not
@@ -2027,19 +2026,18 @@ server_lookup:
} }
ret = _krb5_principalname2krb5_principal(context, ret = _krb5_principalname2krb5_principal(context,
&client_principal, &tp,
adtkt.cname, adtkt.cname,
adtkt.crealm); adtkt.crealm);
if (ret) if (ret)
goto out; goto out;
ret = krb5_unparse_name(context, client_principal, &str); ret = krb5_unparse_name(context, tp, &tpn);
if (ret) if (ret)
goto out; goto out;
ret = verify_flags(context, config, &adtkt, str); ret = verify_flags(context, config, &adtkt, tpn);
if (ret) { if (ret) {
free(str);
goto out; goto out;
} }
@@ -2049,7 +2047,7 @@ server_lookup:
ret = check_KRB5SignedPath(context, ret = check_KRB5SignedPath(context,
config, config,
krbtgt, krbtgt,
cp, tp,
&adtkt, &adtkt,
NULL, NULL,
&ad_signedpath); &ad_signedpath);
@@ -2061,15 +2059,13 @@ server_lookup:
"KRB5SignedPath check from service %s failed " "KRB5SignedPath check from service %s failed "
"for delegation to %s for client %s " "for delegation to %s for client %s "
"from %s failed with %s", "from %s failed with %s",
spn, str, cpn, from, msg); spn, tpn, cpn, from, msg);
krb5_free_error_message(context, msg); krb5_free_error_message(context, msg);
free(str);
goto out; goto out;
} }
kdc_log(context, config, 0, "constrained delegation for %s " kdc_log(context, config, 0, "constrained delegation for %s "
"from %s to %s", str, cpn, spn); "from %s to %s", tpn, cpn, spn);
free(str);
} }
/* /*
@@ -2140,7 +2136,7 @@ server_lookup:
ret = tgs_make_reply(context, ret = tgs_make_reply(context,
config, config,
b, b,
client_principal, tp,
tgt, tgt,
replykey, replykey,
rk_is_subkey, rk_is_subkey,
@@ -2162,6 +2158,8 @@ server_lookup:
reply); reply);
out: out:
if (tpn != cpn)
free(tpn);
free(spn); free(spn);
free(cpn); free(cpn);
@@ -2176,8 +2174,8 @@ out:
if(s4u2self_impersonated_client) if(s4u2self_impersonated_client)
_kdc_free_ent(context, s4u2self_impersonated_client); _kdc_free_ent(context, s4u2self_impersonated_client);
if (client_principal && client_principal != cp) if (tp && tp != cp)
krb5_free_principal(context, client_principal); krb5_free_principal(context, tp);
if (cp) if (cp)
krb5_free_principal(context, cp); krb5_free_principal(context, cp);
if (sp) if (sp)