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:

committed by
Love Hörnquist Åstrand

parent
2c031ca78c
commit
9ab4070800
@@ -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)
|
||||||
|
Reference in New Issue
Block a user