s4:heimdal Add hooks to check with the DB before we allow s4u2self
authorAndrew Bartlett <abartlet@samba.org>
Sat, 27 Mar 2010 12:09:31 +0000 (23:09 +1100)
committerAndrew Bartlett <abartlet@samba.org>
Sat, 10 Apr 2010 11:40:58 +0000 (21:40 +1000)
This allows us to resolve multiple forms of a name, allowing for
example machine$@REALM to get an S4U2Self ticket for
host/machine@REALM.

Andrew Bartlett

source4/heimdal/kdc/krb5tgs.c
source4/heimdal/lib/hdb/hdb.h

index 53c0a589ba98a0e9fd75ce0dbfef4bab0ba20b43..ca650645ded4e4f48e910ee98ce6f734e7b848fa 100644 (file)
@@ -486,7 +486,7 @@ check_tgs_flags(krb5_context context,
 }
 
 /*
- *
+ * Determine if constrained delegation is allowed from this client to this server
  */
 
 static krb5_error_code
@@ -528,6 +528,38 @@ check_constrained_delegation(krb5_context context,
     return ret;
 }
 
+/*
+ * Determine if s4u2self is allowed from this client to this server
+ *
+ * For example, regardless of the principal being impersonated, if the
+ * 'client' and 'server' are the same, then it's safe.
+ */
+
+static krb5_error_code
+check_s4u2self(krb5_context context,
+              krb5_kdc_configuration *config,
+              HDB *clientdb,
+              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)
+       return 0;
+
+    if (clientdb->hdb_check_s4u2self) {
+       ret = clientdb->hdb_check_s4u2self(context, clientdb, client, server);
+       if (ret == 0)
+           return 0;
+    } else {
+       ret = KRB5KDC_ERR_BADOPTION;
+    }
+    return ret;
+}
+
 /*
  *
  */
@@ -1783,13 +1815,13 @@ server_lookup:
             * Check that service doing the impersonating is
             * requesting a ticket to it-self.
             */
-           if (krb5_principal_compare(context, cp, sp) != TRUE) {
+           ret = check_s4u2self(context, config, clientdb, client, sp);
+           if (ret) {
                kdc_log(context, config, 0, "S4U2Self: %s is not allowed "
-                       "to impersonate some other user "
+                       "to impersonate to service "
                        "(tried for user %s to service %s)",
                        cpn, selfcpn, spn);
                free(selfcpn);
-               ret = KRB5KDC_ERR_BADOPTION; /* ? */
                goto out;
            }
 
index d118555121541677ed05a79e39e3f57f51dc1752..ad32a145c0014de153b2d7aa8317c1497095e00e 100644 (file)
@@ -235,9 +235,14 @@ typedef struct HDB{
      * Check if this name is an alias for the supplied client for PKINIT userPrinicpalName logins
      */
     krb5_error_code (*hdb_check_pkinit_ms_upn_match)(krb5_context, struct HDB *, hdb_entry_ex *, krb5_const_principal);
+
+    /**
+     * Check if s4u2self is allowed from this client to this server
+     */
+    krb5_error_code (*hdb_check_s4u2self)(krb5_context, struct HDB *, hdb_entry_ex *, krb5_const_principal);
 }HDB;
 
-#define HDB_INTERFACE_VERSION  6
+#define HDB_INTERFACE_VERSION  7
 
 struct hdb_so_method {
     int version;