]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s4:kdc: Split verifying a PAC out of updating it
authorJoseph Sutton <josephsutton@catalyst.net.nz>
Mon, 20 Mar 2023 01:51:53 +0000 (14:51 +1300)
committerAndrew Bartlett <abartlet@samba.org>
Fri, 31 Mar 2023 01:48:30 +0000 (01:48 +0000)
This is to adapt to the changed Heimdal KDC plugin API.

When we add support for device claims, we want to be able to verify the
PAC of the armor ticket without modifying or updating it. Previously, we
couldn't do this as the two operations were tightly intertwined. Now the
parts that only perform verification are split out into a new function,
samba_kdc_verify_pac().

NOTE: This commit finally works again!

Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
source4/kdc/mit_samba.c
source4/kdc/pac-glue.c
source4/kdc/pac-glue.h
source4/kdc/wdc-samba4.c

index 48e4b74efaf78e93fd92308137eaa00630321b5e..29e2c57ea13fa15bab757a579ae680bde34ae6ad 100644 (file)
@@ -675,6 +675,19 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx,
                delegated_proxy_principal = discard_const(client_principal);
        }
 
+       code = samba_kdc_verify_pac(tmp_ctx,
+                                   context,
+                                   flags,
+                                   client_skdc_entry,
+                                   server->princ,
+                                   krbtgt_skdc_entry,
+                                   NULL, /* device */
+                                   NULL, /* device_pac */
+                                   *pac);
+       if (code != 0) {
+               goto done;
+       }
+
        /* Build an updated PAC */
        code = krb5_pac_init(context, &new_pac);
        if (code != 0) {
@@ -688,7 +701,6 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx,
                                    client_skdc_entry,
                                    server->princ,
                                    server_skdc_entry,
-                                   krbtgt_skdc_entry,
                                    delegated_proxy_principal,
                                    NULL, /* device */
                                    NULL, /* device_pac */
@@ -784,6 +796,19 @@ krb5_error_code mit_samba_update_pac(struct mit_samba_context *ctx,
                flags |= SAMBA_KDC_FLAG_CONSTRAINED_DELEGATION;
        }
 
+       code = samba_kdc_verify_pac(tmp_ctx,
+                                   context,
+                                   flags,
+                                   client_skdc_entry,
+                                   server->princ,
+                                   krbtgt_skdc_entry,
+                                   NULL, /* device */
+                                   NULL, /* device_pac */
+                                   old_pac);
+       if (code != 0) {
+               goto done;
+       }
+
        code = samba_kdc_update_pac(tmp_ctx,
                                    context,
                                    krbtgt_skdc_entry->kdc_db_ctx->samdb,
@@ -791,7 +816,6 @@ krb5_error_code mit_samba_update_pac(struct mit_samba_context *ctx,
                                    client_skdc_entry,
                                    server->princ,
                                    server_skdc_entry,
-                                   krbtgt_skdc_entry,
                                    NULL, /* delegated_proxy_principal */
                                    NULL, /* device */
                                    NULL, /* device_pac */
index 1fcc79a2e6215a5b8a3777c3a74b40c4a2d6d808..04d998a1e308e5230b6aa2e63fb298f1619bd786 100644 (file)
@@ -1377,7 +1377,7 @@ NTSTATUS samba_kdc_update_pac_blob(TALLOC_CTX *mem_ctx,
                                   krb5_context context,
                                   struct ldb_context *samdb,
                                   const enum auth_group_inclusion group_inclusion,
-                                  const krb5_pac pac, DATA_BLOB *pac_blob,
+                                  const krb5_const_pac pac, DATA_BLOB *pac_blob,
                                   struct PAC_SIGNATURE_DATA *pac_srv_sig,
                                   struct PAC_SIGNATURE_DATA *pac_kdc_sig)
 {
@@ -1784,6 +1784,202 @@ WERROR samba_rodc_confirm_user_is_allowed(uint32_t num_object_sids,
        return werr;
 }
 
+/**
+ * @brief Verify a PAC
+ *
+ * @param mem_ctx   A talloc memory context
+ *
+ * @param context   A krb5 context
+ *
+ * @param flags     Bitwise OR'ed flags
+ *
+ * @param client    The client samba kdc entry.
+
+ * @param server_principal  The server principal
+
+ * @param krbtgt    The krbtgt samba kdc entry.
+ *
+ * @param device    The computer's samba kdc entry; used for compound
+ *                  authentication.
+
+ * @param device_pac        The PAC from the computer's TGT; used
+ *                          for compound authentication.
+
+ * @param pac                       The PAC
+
+ * @return A Kerberos error code.
+ */
+krb5_error_code samba_kdc_verify_pac(TALLOC_CTX *mem_ctx,
+                                    krb5_context context,
+                                    uint32_t flags,
+                                    struct samba_kdc_entry *client,
+                                    const krb5_principal server_principal,
+                                    const struct samba_kdc_entry *krbtgt,
+                                    const struct samba_kdc_entry *device,
+                                    const krb5_const_pac *device_pac,
+                                    const krb5_const_pac pac)
+{
+       krb5_error_code code = EINVAL;
+       NTSTATUS nt_status;
+       bool is_trusted = flags & SAMBA_KDC_FLAG_KRBTGT_IS_TRUSTED;
+
+       struct pac_blobs pac_blobs;
+       pac_blobs_init(&pac_blobs);
+
+       if (client != NULL) {
+               /*
+                * Check the objectSID of the client and pac data are the same.
+                * Does a parse and SID check, but no crypto.
+                */
+               code = samba_kdc_validate_pac_blob(context,
+                                                  client,
+                                                  pac);
+               if (code != 0) {
+                       goto done;
+               }
+       }
+
+       if (device != NULL) {
+               SMB_ASSERT(*device_pac != NULL);
+
+               /*
+                * Check the objectSID of the device and pac data are the same.
+                * Does a parse and SID check, but no crypto.
+                */
+               code = samba_kdc_validate_pac_blob(context,
+                                                  device,
+                                                  *device_pac);
+               if (code != 0) {
+                       goto done;
+               }
+
+               /*
+                * TODO: When we support compound authentication, we will use
+                * the device PAC to generate PAC buffers for Device Info
+                * (containing the computer account's groups) and Device Claims
+                * (containing claims for the computer account), and insert them
+                * into the emitted PAC.
+                *
+                * See [MS-KILE 1.3.4], [MS-KILE 3.3.5.7.4].
+                */
+       }
+
+       if (!is_trusted) {
+               const struct auth_user_info_dc *user_info_dc = NULL;
+               WERROR werr;
+
+               struct dom_sid *object_sids = NULL;
+               uint32_t j;
+
+               if (client == NULL) {
+                       code = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
+                       goto done;
+               }
+
+               nt_status = samba_kdc_get_user_info_from_db(mem_ctx, client, client->msg, &user_info_dc);
+               if (!NT_STATUS_IS_OK(nt_status)) {
+                       DBG_ERR("Getting user info for PAC failed: %s\n",
+                               nt_errstr(nt_status));
+                       code = KRB5KDC_ERR_TGT_REVOKED;
+                       goto done;
+               }
+
+               /*
+                * Check if the SID list in the user_info_dc intersects
+                * correctly with the RODC allow/deny lists.
+                */
+               object_sids = talloc_array(mem_ctx, struct dom_sid, user_info_dc->num_sids);
+               if (object_sids == NULL) {
+                       code = ENOMEM;
+                       goto done;
+               }
+
+               for (j = 0; j < user_info_dc->num_sids; ++j) {
+                       object_sids[j] = user_info_dc->sids[j].sid;
+               }
+
+               werr = samba_rodc_confirm_user_is_allowed(user_info_dc->num_sids,
+                                                         object_sids,
+                                                         krbtgt,
+                                                         client);
+               TALLOC_FREE(object_sids);
+               if (!W_ERROR_IS_OK(werr)) {
+                       code = KRB5KDC_ERR_TGT_REVOKED;
+                       if (W_ERROR_EQUAL(werr,
+                                         WERR_DOMAIN_CONTROLLER_NOT_FOUND)) {
+                               code = KRB5KDC_ERR_POLICY;
+                       }
+                       goto done;
+               }
+
+               /*
+                * The RODC PAC data isn't trusted for authorization as it may
+                * be stale. The only thing meaningful we can do with an RODC
+                * account on a full DC is exchange the RODC TGT for a 'real'
+                * TGT.
+                *
+                * So we match Windows (at least server 2022) and
+                * don't allow S4U2Self.
+                *
+                * https://lists.samba.org/archive/cifs-protocol/2022-April/003673.html
+                */
+               if (flags & SAMBA_KDC_FLAG_PROTOCOL_TRANSITION) {
+                       code = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
+                       goto done;
+               }
+       }
+
+       /* Check the types of the given PAC */
+
+       code = pac_blobs_from_krb5_pac(&pac_blobs,
+                                      mem_ctx,
+                                      context,
+                                      pac);
+       if (code != 0) {
+               goto done;
+       }
+
+       code = pac_blobs_ensure_exists(&pac_blobs,
+                                      PAC_TYPE_LOGON_INFO);
+       if (code != 0) {
+               goto done;
+       }
+
+       code = pac_blobs_ensure_exists(&pac_blobs,
+                                      PAC_TYPE_LOGON_NAME);
+       if (code != 0) {
+               goto done;
+       }
+
+       code = pac_blobs_ensure_exists(&pac_blobs,
+                                      PAC_TYPE_SRV_CHECKSUM);
+       if (code != 0) {
+               goto done;
+       }
+
+       code = pac_blobs_ensure_exists(&pac_blobs,
+                                      PAC_TYPE_KDC_CHECKSUM);
+       if (code != 0) {
+               goto done;
+       }
+
+       if (!(flags & SAMBA_KDC_FLAG_CONSTRAINED_DELEGATION)) {
+               code = pac_blobs_ensure_exists(&pac_blobs,
+                                              PAC_TYPE_REQUESTER_SID);
+               if (code != 0) {
+                       code = KRB5KDC_ERR_TGT_REVOKED;
+                       goto done;
+               }
+       }
+
+       code = 0;
+
+done:
+       pac_blobs_destroy(&pac_blobs);
+
+       return code;
+}
+
 /**
  * @brief Update a PAC
  *
@@ -1801,8 +1997,6 @@ WERROR samba_rodc_confirm_user_is_allowed(uint32_t num_object_sids,
 
  * @param server    The server samba kdc entry.
 
- * @param krbtgt    The krbtgt samba kdc entry.
- *
  * @param delegated_proxy_principal The delegated proxy principal used for
  *                                  updating the constrained delegation PAC
  *                                  buffer.
@@ -1827,12 +2021,11 @@ krb5_error_code samba_kdc_update_pac(TALLOC_CTX *mem_ctx,
                                     struct samba_kdc_entry *client,
                                     const krb5_principal server_principal,
                                     const struct samba_kdc_entry *server,
-                                    const struct samba_kdc_entry *krbtgt,
                                     const krb5_principal delegated_proxy_principal,
-                                    const struct samba_kdc_entry *device,
-                                    const krb5_const_pac *device_pac,
-                                    const krb5_pac old_pac,
-                                    const krb5_pac new_pac)
+                                    struct samba_kdc_entry *device,
+                                    const krb5_const_pac device_pac,
+                                    const krb5_const_pac old_pac,
+                                    krb5_pac new_pac)
 {
        krb5_error_code code = EINVAL;
        NTSTATUS nt_status;
@@ -1864,19 +2057,6 @@ krb5_error_code samba_kdc_update_pac(TALLOC_CTX *mem_ctx,
                group_inclusion = AUTH_INCLUDE_RESOURCE_GROUPS_COMPRESSED;
        }
 
-       if (client != NULL) {
-               /*
-                * Check the objectSID of the client and pac data are the same.
-                * Does a parse and SID check, but no crypto.
-                */
-               code = samba_kdc_validate_pac_blob(context,
-                                                  client,
-                                                  old_pac);
-               if (code != 0) {
-                       goto done;
-               }
-       }
-
        if (delegated_proxy_principal != NULL) {
                deleg_blob = talloc_zero(mem_ctx, DATA_BLOB);
                if (deleg_blob == NULL) {
@@ -1899,37 +2079,8 @@ krb5_error_code samba_kdc_update_pac(TALLOC_CTX *mem_ctx,
                }
        }
 
-       if (device != NULL) {
-               SMB_ASSERT(*device_pac != NULL);
-
-               /*
-                * Check the objectSID of the device and pac data are the same.
-                * Does a parse and SID check, but no crypto.
-                */
-               code = samba_kdc_validate_pac_blob(context,
-                                                  device,
-                                                  *device_pac);
-               if (code != 0) {
-                       goto done;
-               }
-
-               /*
-                * TODO: When we support compound authentication, we will use
-                * the device PAC to generate PAC buffers for Device Info
-                * (containing the computer account's groups) and Device Claims
-                * (containing claims for the computer account), and insert them
-                * into the emitted PAC.
-                *
-                * See [MS-KILE 1.3.4], [MS-KILE 3.3.5.7.4].
-                */
-       }
-
        if (!is_trusted) {
                struct auth_user_info_dc user_info_dc = {};
-               WERROR werr;
-
-               struct dom_sid *object_sids = NULL;
-               uint32_t j;
 
                /*
                 * In this case the RWDC discards the PAC an RODC generated.
@@ -2001,50 +2152,6 @@ krb5_error_code samba_kdc_update_pac(TALLOC_CTX *mem_ctx,
                        code = EINVAL;
                        goto done;
                }
-
-               /*
-                * Check if the SID list in the user_info_dc intersects
-                * correctly with the RODC allow/deny lists.
-                */
-               object_sids = talloc_array(mem_ctx, struct dom_sid, user_info_dc.num_sids);
-               if (object_sids == NULL) {
-                       code = ENOMEM;
-                       goto done;
-               }
-
-               for (j = 0; j < user_info_dc.num_sids; ++j) {
-                       object_sids[j] = user_info_dc.sids[j].sid;
-               }
-
-               werr = samba_rodc_confirm_user_is_allowed(user_info_dc.num_sids,
-                                                         object_sids,
-                                                         krbtgt,
-                                                         client);
-               TALLOC_FREE(object_sids);
-               if (!W_ERROR_IS_OK(werr)) {
-                       code = KRB5KDC_ERR_TGT_REVOKED;
-                       if (W_ERROR_EQUAL(werr,
-                                         WERR_DOMAIN_CONTROLLER_NOT_FOUND)) {
-                               code = KRB5KDC_ERR_POLICY;
-                       }
-                       goto done;
-               }
-
-               /*
-                * The RODC PAC data isn't trusted for authorization as it may
-                * be stale. The only thing meaningful we can do with an RODC
-                * account on a full DC is exchange the RODC TGT for a 'real'
-                * TGT.
-                *
-                * So we match Windows (at least server 2022) and
-                * don't allow S4U2Self.
-                *
-                * https://lists.samba.org/archive/cifs-protocol/2022-April/003673.html
-                */
-               if (flags & SAMBA_KDC_FLAG_PROTOCOL_TRANSITION) {
-                       code = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
-                       goto done;
-               }
        } else {
                pac_blob = talloc_zero(mem_ctx, DATA_BLOB);
                if (pac_blob == NULL) {
@@ -2108,15 +2215,6 @@ krb5_error_code samba_kdc_update_pac(TALLOC_CTX *mem_ctx,
        }
 #endif
 
-       if (!(flags & SAMBA_KDC_FLAG_CONSTRAINED_DELEGATION)) {
-               code = pac_blobs_ensure_exists(&pac_blobs,
-                                              PAC_TYPE_REQUESTER_SID);
-               if (code != 0) {
-                       code = KRB5KDC_ERR_TGT_REVOKED;
-                       goto done;
-               }
-       }
-
        code = pac_blobs_add_blob(&pac_blobs,
                                  mem_ctx,
                                  PAC_TYPE_CONSTRAINED_DELEGATION,
index 9113e88ed306309442b08cabe8837261f6ca7bf6..0ba27a8e8e15f6dc8204f50818c9a64d09ded195 100644 (file)
@@ -75,7 +75,7 @@ NTSTATUS samba_kdc_update_pac_blob(TALLOC_CTX *mem_ctx,
                                   krb5_context context,
                                   struct ldb_context *samdb,
                                   enum auth_group_inclusion group_inclusion,
-                                  const krb5_pac pac, DATA_BLOB *pac_blob,
+                                  const krb5_const_pac pac, DATA_BLOB *pac_blob,
                                   struct PAC_SIGNATURE_DATA *pac_srv_sig,
                                   struct PAC_SIGNATURE_DATA *pac_kdc_sig);
 
@@ -112,6 +112,16 @@ WERROR samba_rodc_confirm_user_is_allowed(uint32_t num_sids,
                                          const struct samba_kdc_entry *rodc,
                                          const struct samba_kdc_entry *object);
 
+krb5_error_code samba_kdc_verify_pac(TALLOC_CTX *mem_ctx,
+                                    krb5_context context,
+                                    uint32_t flags,
+                                    struct samba_kdc_entry *client,
+                                    krb5_principal server_principal,
+                                    const struct samba_kdc_entry *krbtgt,
+                                    const struct samba_kdc_entry *device,
+                                    const krb5_const_pac *device_pac,
+                                    krb5_const_pac pac);
+
 krb5_error_code samba_kdc_update_pac(TALLOC_CTX *mem_ctx,
                                     krb5_context context,
                                     struct ldb_context *samdb,
@@ -119,11 +129,10 @@ krb5_error_code samba_kdc_update_pac(TALLOC_CTX *mem_ctx,
                                     struct samba_kdc_entry *client,
                                     krb5_principal server_principal,
                                     const struct samba_kdc_entry *server,
-                                    const struct samba_kdc_entry *krbtgt,
                                     krb5_principal delegated_proxy_principal,
-                                    const struct samba_kdc_entry *device,
-                                    const krb5_const_pac *device_pac,
-                                    krb5_pac old_pac,
+                                    struct samba_kdc_entry *device,
+                                    krb5_const_pac device_pac,
+                                    krb5_const_pac old_pac,
                                     krb5_pac new_pac);
 
 NTSTATUS samba_kdc_get_logon_info_blob(TALLOC_CTX *mem_ctx,
index e3983f16ad6776ac48e98c0b505c0f837f246c62..167393bbaec80d1839c93400006d952199384e5a 100644 (file)
@@ -234,32 +234,30 @@ static krb5_error_code samba_wdc_get_pac(void *priv,
        return ret;
 }
 
-static krb5_error_code samba_wdc_reget_pac2(astgs_request_t r,
-                                           const krb5_principal delegated_proxy_principal,
-                                           const hdb_entry *client,
-                                           const hdb_entry *server,
-                                           hdb_entry *krbtgt,
-                                           krb5_pac *pac,
-                                           krb5_cksumtype ctype,
-                                           const hdb_entry *device,
-                                           krb5_const_pac *device_pac)
+static krb5_error_code samba_wdc_verify_pac2(astgs_request_t r,
+                                            const krb5_principal delegated_proxy_principal,
+                                            const hdb_entry *client,
+                                            const hdb_entry *server,
+                                            const hdb_entry *krbtgt,
+                                            const krb5_pac pac,
+                                            krb5_cksumtype ctype,
+                                            const hdb_entry *device,
+                                            krb5_const_pac *device_pac,
+                                            krb5_boolean *is_trusted_out)
 {
        krb5_context context = kdc_request_get_context((kdc_request_t)r);
        struct samba_kdc_entry *client_skdc_entry = NULL;
-       struct samba_kdc_entry *server_skdc_entry =
-               talloc_get_type_abort(server->context, struct samba_kdc_entry);
        struct samba_kdc_entry *device_skdc_entry = NULL;
        struct samba_kdc_entry *krbtgt_skdc_entry =
                talloc_get_type_abort(krbtgt->context, struct samba_kdc_entry);
        TALLOC_CTX *mem_ctx = NULL;
-       krb5_pac new_pac = NULL;
        krb5_error_code ret;
        bool is_s4u2self = samba_wdc_is_s4u2self_req(r);
        bool is_in_db = false;
        bool is_trusted = false;
        uint32_t flags = 0;
 
-       mem_ctx = talloc_named(NULL, 0, "samba_wdc_reget_pac2 context");
+       mem_ctx = talloc_named(NULL, 0, "samba_wdc_verify_pac2 context");
        if (mem_ctx == NULL) {
                return ENOMEM;
        }
@@ -326,7 +324,7 @@ static krb5_error_code samba_wdc_reget_pac2(astgs_request_t r,
 
                /* Check the KDC, whole-PAC and ticket signatures. */
                ret = krb5_pac_verify(context,
-                                     *pac,
+                                     pac,
                                      0,
                                      NULL,
                                      NULL,
@@ -347,12 +345,79 @@ static krb5_error_code samba_wdc_reget_pac2(astgs_request_t r,
                flags |= SAMBA_KDC_FLAG_KRBTGT_IN_DB;
        }
 
+       ret = samba_kdc_verify_pac(mem_ctx,
+                                  context,
+                                  flags,
+                                  client_skdc_entry,
+                                  server->principal,
+                                  krbtgt_skdc_entry,
+                                  device_skdc_entry,
+                                  device_pac,
+                                  pac);
+       if (ret != 0) {
+               goto out;
+       }
+
+       if (is_trusted_out != NULL) {
+               *is_trusted_out = is_trusted;
+       }
+
+out:
+       talloc_free(mem_ctx);
+       return ret;
+}
+
+/* Resign (and reform, including possibly new groups) a PAC */
+
+static krb5_error_code samba_wdc_reget_pac(void *priv, astgs_request_t r,
+                                          const krb5_principal _client_principal,
+                                          const krb5_principal delegated_proxy_principal,
+                                          hdb_entry *client,
+                                          hdb_entry *server,
+                                          hdb_entry *krbtgt,
+                                          krb5_pac *pac)
+{
+       krb5_context context = kdc_request_get_context((kdc_request_t)r);
+       const hdb_entry *device = kdc_request_get_explicit_armor_client(r);
+       const krb5_const_pac device_pac = kdc_request_get_explicit_armor_pac(r);
+       struct samba_kdc_entry *client_skdc_entry = NULL;
+       struct samba_kdc_entry *device_skdc_entry = NULL;
+       const struct samba_kdc_entry *server_skdc_entry =
+               talloc_get_type_abort(server->context, struct samba_kdc_entry);
+       const struct samba_kdc_entry *krbtgt_skdc_entry =
+               talloc_get_type_abort(krbtgt->context, struct samba_kdc_entry);
+       TALLOC_CTX *mem_ctx = NULL;
+       krb5_pac new_pac = NULL;
+       krb5_error_code ret;
+       bool is_trusted = false;
+       uint32_t flags = 0;
+
+       mem_ctx = talloc_named(NULL, 0, "samba_wdc_reget_pac context");
+       if (mem_ctx == NULL) {
+               return ENOMEM;
+       }
+
+       if (client != NULL) {
+               client_skdc_entry = talloc_get_type_abort(client->context,
+                                                         struct samba_kdc_entry);
+       }
+
+       if (device != NULL) {
+               device_skdc_entry = talloc_get_type_abort(device->context,
+                                                         struct samba_kdc_entry);
+       }
+
        ret = krb5_pac_init(context, &new_pac);
        if (ret != 0) {
                new_pac = NULL;
                goto out;
        }
 
+       is_trusted = krb5_pac_is_trusted(*pac);
+       if (is_trusted) {
+               flags |= SAMBA_KDC_FLAG_KRBTGT_IS_TRUSTED;
+       }
+
        ret = samba_kdc_update_pac(mem_ctx,
                                   context,
                                   krbtgt_skdc_entry->kdc_db_ctx->samdb,
@@ -360,7 +425,6 @@ static krb5_error_code samba_wdc_reget_pac2(astgs_request_t r,
                                   client_skdc_entry,
                                   server->principal,
                                   server_skdc_entry,
-                                  krbtgt_skdc_entry,
                                   delegated_proxy_principal,
                                   device_skdc_entry,
                                   device_pac,
@@ -385,15 +449,16 @@ out:
        return ret;
 }
 
-/* Resign (and reform, including possibly new groups) a PAC */
+/* Verify a PAC's SID and signatures */
 
-static krb5_error_code samba_wdc_reget_pac(void *priv, astgs_request_t r,
-                                          const krb5_principal client_principal,
-                                          const krb5_principal delegated_proxy_principal,
-                                          hdb_entry *client,
-                                          hdb_entry *server,
-                                          hdb_entry *krbtgt,
-                                          krb5_pac *pac)
+static krb5_error_code samba_wdc_verify_pac(void *priv, astgs_request_t r,
+                                           const krb5_principal client_principal,
+                                           const krb5_principal delegated_proxy_principal,
+                                           hdb_entry *client,
+                                           hdb_entry *server,
+                                           hdb_entry *krbtgt,
+                                           krb5_pac pac,
+                                           krb5_boolean *is_trusted)
 {
        krb5_context context = kdc_request_get_context((kdc_request_t)r);
        krb5_kdc_configuration *config = kdc_request_get_config((kdc_request_t)r);
@@ -427,7 +492,7 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, astgs_request_t r,
                 * the PAC, and this will need to be updated.
                 */
                ret = krb5_pac_get_kdc_checksum_info(context,
-                                                    *pac,
+                                                    pac,
                                                     &ctype,
                                                     &rodc_id);
                if (ret != 0) {
@@ -527,15 +592,16 @@ static krb5_error_code samba_wdc_reget_pac(void *priv, astgs_request_t r,
                }
        }
 
-       ret = samba_wdc_reget_pac2(r,
-                                  delegated_proxy_principal,
-                                  client,
-                                  server,
-                                  krbtgt,
-                                  pac,
-                                  ctype,
-                                  explicit_armor_client,
-                                  &explicit_armor_pac);
+       ret = samba_wdc_verify_pac2(r,
+                                   delegated_proxy_principal,
+                                   client,
+                                   server,
+                                   krbtgt,
+                                   pac,
+                                   ctype,
+                                   explicit_armor_client,
+                                   &explicit_armor_pac,
+                                   is_trusted);
 
        if (krbtgt == &signing_krbtgt_hdb) {
                hdb_free_entry(context, config->db[0], &signing_krbtgt_hdb);
@@ -715,10 +781,11 @@ static krb5_error_code samba_wdc_referral_policy(void *priv,
 }
 
 struct krb5plugin_kdc_ftable kdc_plugin_table = {
-       .minor_version = KRB5_PLUGIN_KDC_VERSION_10,
+       .minor_version = KRB5_PLUGIN_KDC_VERSION_11,
        .init = samba_wdc_plugin_init,
        .fini = samba_wdc_plugin_fini,
-       .pac_verify = samba_wdc_reget_pac,
+       .pac_verify = samba_wdc_verify_pac,
+       .pac_update = samba_wdc_reget_pac,
        .client_access = samba_wdc_check_client_access,
        .finalize_reply = samba_wdc_finalize_reply,
        .pac_generate = samba_wdc_get_pac,