]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
third_party/heimdal: Import lorikeet-heimdal-202306200407 (commit fc2894beeaa71897753...
authorJoseph Sutton <josephsutton@catalyst.net.nz>
Tue, 20 Jun 2023 04:33:17 +0000 (16:33 +1200)
committerStefan Metzmacher <metze@samba.org>
Tue, 27 Jun 2023 05:45:36 +0000 (05:45 +0000)
Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
third_party/heimdal/kdc/mssfu.c
third_party/heimdal/lib/hdb/hdb.h

index c583c9b667dace32d8c98aa88748233756aef7a9..cd5aa9a1df76af60b3e6f8219e6b7d5efeaa2cce 100644 (file)
@@ -96,6 +96,38 @@ check_constrained_delegation(krb5_context context,
     return ret;
 }
 
+/*
+ * Determine if resource-based constrained delegation is allowed from this
+ * client to this server
+ */
+
+static krb5_error_code
+check_rbcd(krb5_context context,
+          krb5_kdc_configuration *config,
+          HDB *clientdb,
+          krb5_const_principal s4u_principal,
+          krb5_const_principal client_principal,
+          krb5_const_pac client_pac,
+          const hdb_entry *target)
+{
+    krb5_error_code ret = KRB5KDC_ERR_BADOPTION;
+
+    if (clientdb->hdb_check_rbcd) {
+       ret = clientdb->hdb_check_rbcd(context,
+                                      clientdb,
+                                      s4u_principal,
+                                      client_principal,
+                                      client_pac,
+                                      target);
+       if (ret == 0)
+           return 0;
+    }
+
+    kdc_log(context, config, 4,
+           "Bad request for resource-based constrained delegation");
+    return ret;
+}
+
 /*
  * Validate a protocol transition (S4U2Self) request. If successfully
  * validated then the client in the request structure will be replaced
@@ -350,6 +382,9 @@ _kdc_validate_constrained_delegation(astgs_request_t r)
     Key *clientkey;
     Ticket *t;
     krb5_const_realm local_realm;
+    const PA_DATA *pac_options_data = NULL;
+    int pac_options_data_idx = 0;
+    krb5_boolean rbcd_support = FALSE;
 
     memset(&evidence_tkt, 0, sizeof(evidence_tkt));
     local_realm =
@@ -457,13 +492,55 @@ _kdc_validate_constrained_delegation(astgs_request_t r)
        goto out;
     }
 
-    ret = check_constrained_delegation(r->context, r->config, r->clientdb,
-                                      r->client, r->server, r->server_princ);
-    if (ret) {
+    pac_options_data = _kdc_find_padata(&r->req,
+                                       &pac_options_data_idx,
+                                       KRB5_PADATA_PAC_OPTIONS);
+    if (pac_options_data != NULL) {
+       PA_PAC_OPTIONS pac_options;
+       size_t size = 0;
+
+       ret = decode_PA_PAC_OPTIONS(pac_options_data->padata_value.data,
+                                   pac_options_data->padata_value.length,
+                                   &pac_options,
+                                   &size);
+       if (ret) {
+           goto out;
+       }
+
+       if (size != pac_options_data->padata_value.length) {
+           free_PA_PAC_OPTIONS(&pac_options);
+           ret = KRB5KDC_ERR_BADOPTION;
+           goto out;
+       }
+
+       rbcd_support = pac_options.flags.resource_based_constrained_delegation != 0;
+
+       free_PA_PAC_OPTIONS(&pac_options);
+    }
+
+    if (rbcd_support) {
+       ret = check_rbcd(r->context, r->config, r->clientdb,
+                        s4u_client_name, r->client_princ, r->pac, r->server);
+    } else {
+       ret = KRB5KDC_ERR_BADOPTION;
+    }
+    if (ret == KRB5KDC_ERR_BADOPTION) {
+       /* RBCD was denied or not supported; try constrained delegation. */
+       ret = check_constrained_delegation(r->context, r->config, r->clientdb,
+                                          r->client, r->server, r->server_princ);
+       if (ret) {
+           kdc_audit_addreason((kdc_request_t)r,
+                               "Constrained delegation not allowed");
+           kdc_log(r->context, r->config, 4,
+                   "constrained delegation from %s (%s) as %s to %s not allowed",
+                   r->cname, s4usname, s4ucname, r->sname);
+           goto out;
+       }
+    } else if (ret) {
        kdc_audit_addreason((kdc_request_t)r,
-                           "Constrained delegation not allowed");
+                           "Resource-based constrained delegation not allowed");
        kdc_log(r->context, r->config, 4,
-               "constrained delegation from %s (%s) as %s to %s not allowed",
+               "resource-based constrained delegation from %s (%s) as %s to %s not allowed",
                r->cname, s4usname, s4ucname, r->sname);
        goto out;
     }
index 87377513d549cbe0be66b405ea4964cb44be14b2..6534766a18cf2d11474ea34d72c43acbc9b47c22 100644 (file)
@@ -286,6 +286,11 @@ typedef struct HDB {
      */
     krb5_error_code (*hdb_check_constrained_delegation)(krb5_context, struct HDB *, hdb_entry *, krb5_const_principal);
 
+    /**
+     * Check if resource-based constrained delegation (RBCD) is allowed.
+     */
+    krb5_error_code (*hdb_check_rbcd)(krb5_context, struct HDB *, krb5_const_principal, krb5_const_principal, krb5_const_pac, const hdb_entry *);
+
     /**
      * Check if this name is an alias for the supplied client for PKINIT userPrinicpalName logins
      */