summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2010-03-29 18:13:46 +1100
committerAndrew Bartlett <abartlet@samba.org>2010-04-10 21:40:59 +1000
commitc8cb17a18c8acd831d9197fd4457881bf58250b1 (patch)
tree113514a4aea941d346ca81e7740bd3f07c5d48cd /source4
parentf2b63d58da895d11ed490dddd5df30c777369fad (diff)
downloadsamba-c8cb17a18c8acd831d9197fd4457881bf58250b1.tar.gz
samba-c8cb17a18c8acd831d9197fd4457881bf58250b1.tar.bz2
samba-c8cb17a18c8acd831d9197fd4457881bf58250b1.zip
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
Diffstat (limited to 'source4')
-rw-r--r--source4/heimdal/kdc/krb5tgs.c50
1 files changed, 46 insertions, 4 deletions
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);