From c8cb17a18c8acd831d9197fd4457881bf58250b1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 29 Mar 2010 18:13:46 +1100 Subject: s4:heimdal Create a new PAC when impersonating a user with S4U2Self If we don't do this, the PAC is given for the machine accout, not the account being impersonated. Andrew Bartlett --- source4/heimdal/kdc/krb5tgs.c | 50 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 4 deletions(-) (limited to 'source4/heimdal') diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c index ca650645de..dd14ae6513 100644 --- a/source4/heimdal/kdc/krb5tgs.c +++ b/source4/heimdal/kdc/krb5tgs.c @@ -542,9 +542,7 @@ check_s4u2self(krb5_context context, hdb_entry_ex *client, krb5_const_principal server) { - const HDB_Ext_Constrained_delegation_acl *acl; krb5_error_code ret; - int i; /* if client does a s4u2self to itself, that ok */ if (krb5_principal_compare(context, client->entry.principal, server) == TRUE) @@ -1446,8 +1444,8 @@ tgs_build_reply(krb5_context context, krb5_principal cp = NULL, sp = NULL; krb5_principal client_principal = NULL; char *spn = NULL, *cpn = NULL; - hdb_entry_ex *server = NULL, *client = NULL; - HDB *clientdb; + hdb_entry_ex *server = NULL, *client = NULL, *s4u2self_impersonated_client = NULL; + HDB *clientdb, *s4u2self_impersonated_clientdb; krb5_realm ref_realm = NULL; EncTicketPart *tgt = &ticket->ticket; krb5_principals spp = NULL; @@ -1811,6 +1809,48 @@ server_lookup: if (ret) goto out; + /* If we were about to put a PAC into the ticket, we better fix it to be the right PAC */ + if(rspac.data) { + krb5_pac p = NULL; + krb5_data_free(&rspac); + ret = _kdc_db_fetch(context, config, client_principal, HDB_F_GET_CLIENT | HDB_F_CANON, + &s4u2self_impersonated_clientdb, &s4u2self_impersonated_client); + if (ret) { + const char *msg; + + /* + * If the client belongs to the same realm as our krbtgt, it + * should exist in the local database. + * + */ + + if (ret == HDB_ERR_NOENTRY) + ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN; + msg = krb5_get_error_message(context, ret); + kdc_log(context, config, 1, "S2U4Self principal to impersonate %s not found in database: %s", cpn, msg); + krb5_free_error_message(context, msg); + goto out; + } + ret = _kdc_pac_generate(context, s4u2self_impersonated_client, &p); + if (ret) { + kdc_log(context, config, 0, "PAC generation failed for -- %s", + selfcpn); + goto out; + } + if (p != NULL) { + ret = _krb5_pac_sign(context, p, ticket->ticket.authtime, + s4u2self_impersonated_client->entry.principal, + ekey, &tkey->key, + &rspac); + krb5_pac_free(context, p); + if (ret) { + kdc_log(context, config, 0, "PAC signing failed for -- %s", + selfcpn); + goto out; + } + } + } + /* * Check that service doing the impersonating is * requesting a ticket to it-self. @@ -2048,6 +2088,8 @@ out: _kdc_free_ent(context, server); if(client) _kdc_free_ent(context, client); + if(s4u2self_impersonated_client) + _kdc_free_ent(context, s4u2self_impersonated_client); if (client_principal && client_principal != cp) krb5_free_principal(context, client_principal); -- cgit