]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s4:kdc: split out samba_kdc_get_pac() from samba_wdc_get_pac()
authorStefan Metzmacher <metze@samba.org>
Wed, 19 Feb 2025 14:15:39 +0000 (15:15 +0100)
committerRalph Boehme <slow@samba.org>
Sat, 22 Feb 2025 22:06:39 +0000 (22:06 +0000)
samba_kdc_get_pac() will be re-used by mit_samba_get_pac() in
the next step.

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
source4/kdc/pac-glue.c
source4/kdc/pac-glue.h
source4/kdc/wdc-samba4.c

index 5c179049b38980d0170c780e434dbbff53ee6347..7c9d8a918a682982b3b369a33e4afda7fea37503 100644 (file)
@@ -898,6 +898,26 @@ static bool samba_kdc_entry_pac_issued_by_trust(const struct samba_kdc_entry_pac
        return entry.pac != NULL && samba_kdc_entry_is_trust(entry.krbtgt);
 }
 
+/*
+ * Return true if a principal is represented.
+ *
+ * This only returns false if the following are
+ * all NULL pointers:
+ *
+ * struct samba_kdc_entry *entry;
+ * const struct samba_kdc_entry *krbtgt;
+ * krb5_const_pac pac;
+ *
+ * This should only for a 'device_pac_entry' if FAST was not used
+ * and there's no decive ticket. Or similar cases where it
+ * represents optional things.
+ */
+static bool samba_kdc_entry_pac_valid_principal(
+               const struct samba_kdc_entry_pac entry)
+{
+       return entry.pac != NULL || entry.entry != NULL || entry.krbtgt != NULL;
+}
+
 NTSTATUS samba_kdc_get_logon_info_blob(TALLOC_CTX *mem_ctx,
                                       const struct auth_user_info_dc *user_info_dc,
                                       const enum auth_group_inclusion group_inclusion,
@@ -2289,6 +2309,265 @@ done:
        return code;
 }
 
+krb5_error_code samba_kdc_get_pac(TALLOC_CTX *mem_ctx,
+                                 krb5_context context,
+                                 struct samba_kdc_db_context *kdc_db_ctx,
+                                 uint32_t flags,
+                                 struct samba_kdc_entry *client,
+                                 const krb5_const_principal server_principal,
+                                 const struct samba_kdc_entry *server,
+                                 const struct samba_kdc_entry_pac device,
+                                 const krb5_keyblock *pk_reply_key,
+                                 uint64_t pac_attributes,
+                                 krb5_pac new_pac,
+                                 struct authn_audit_info **server_audit_info_out,
+                                 NTSTATUS *status_out)
+{
+       TALLOC_CTX *frame = talloc_stackframe();
+       DATA_BLOB *logon_blob = NULL;
+       DATA_BLOB *cred_ndr = NULL;
+       DATA_BLOB **cred_ndr_ptr = NULL;
+       DATA_BLOB _cred_blob = data_blob_null;
+       DATA_BLOB *cred_blob = NULL;
+       DATA_BLOB *upn_blob = NULL;
+       DATA_BLOB *pac_attrs_blob = NULL;
+       DATA_BLOB *requester_sid_blob = NULL;
+       DATA_BLOB client_claims_blob = {};
+       krb5_error_code ret;
+       NTSTATUS nt_status;
+       bool is_krbtgt = false;
+       enum auth_group_inclusion group_inclusion;
+       bool is_s4u2self = flags & SAMBA_KDC_FLAG_PROTOCOL_TRANSITION;
+       enum samba_asserted_identity asserted_identity =
+               (is_s4u2self) ?
+                       SAMBA_ASSERTED_IDENTITY_SERVICE :
+                       SAMBA_ASSERTED_IDENTITY_AUTHENTICATION_AUTHORITY;
+       bool pkinit_freshness = flags & SAMBA_KDC_FLAG_PKINIT_FRESHNESS_USED;
+       const struct auth_user_info_dc *user_info_dc_const = NULL;
+       struct auth_user_info_dc *user_info_dc = NULL;
+       struct auth_claims auth_claims = {};
+
+       if (server_audit_info_out != NULL) {
+               *server_audit_info_out = NULL;
+       }
+
+       if (status_out != NULL) {
+               *status_out = NT_STATUS_OK;
+       }
+
+       {
+               int result = smb_krb5_principal_is_tgs(context, server_principal);
+               if (result == -1) {
+                       TALLOC_FREE(frame);
+                       return ENOMEM;
+               }
+
+               is_krbtgt = result;
+       }
+
+       /* Only include resource groups in a service ticket. */
+       if (is_krbtgt) {
+               group_inclusion = AUTH_EXCLUDE_RESOURCE_GROUPS;
+       } else if (server->supported_enctypes & KERB_ENCTYPE_RESOURCE_SID_COMPRESSION_DISABLED) {
+               group_inclusion = AUTH_INCLUDE_RESOURCE_GROUPS;
+       } else {
+               group_inclusion = AUTH_INCLUDE_RESOURCE_GROUPS_COMPRESSED;
+       }
+
+       if (pk_reply_key != NULL) {
+               cred_ndr_ptr = &cred_ndr;
+       }
+
+       ret = samba_kdc_get_user_info_from_db(frame,
+                                             kdc_db_ctx,
+                                             client,
+                                             client->msg,
+                                             &user_info_dc_const);
+       if (ret) {
+               TALLOC_FREE(frame);
+               return ret;
+       }
+
+       /* Make a shallow copy of the user_info_dc structure. */
+       nt_status = authsam_shallow_copy_user_info_dc(frame,
+                                                     user_info_dc_const,
+                                                     &user_info_dc);
+       user_info_dc_const = NULL;
+
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               DBG_ERR("Failed to allocate user_info_dc SIDs: %s\n",
+                       nt_errstr(nt_status));
+               TALLOC_FREE(frame);
+               return map_errno_from_nt_status(nt_status);
+       }
+
+       nt_status = samba_kdc_add_asserted_identity(asserted_identity,
+                                                   user_info_dc);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               DBG_ERR("Failed to add asserted identity: %s\n",
+                       nt_errstr(nt_status));
+               TALLOC_FREE(frame);
+               return map_errno_from_nt_status(nt_status);
+       }
+
+       nt_status = samba_kdc_add_claims_valid(user_info_dc);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               DBG_ERR("Failed to add Claims Valid: %s\n",
+                       nt_errstr(nt_status));
+               TALLOC_FREE(frame);
+               return map_errno_from_nt_status(nt_status);
+       }
+
+       if (pkinit_freshness) {
+               nt_status = samba_kdc_add_fresh_public_key_identity(user_info_dc);
+               if (!NT_STATUS_IS_OK(nt_status)) {
+                       DBG_ERR("Failed to add Fresh Public Key Identity: %s\n",
+                               nt_errstr(nt_status));
+                       TALLOC_FREE(frame);
+                       return map_errno_from_nt_status(nt_status);
+               }
+       }
+
+       ret = samba_kdc_get_claims_data_from_db(kdc_db_ctx->samdb,
+                                               client,
+                                               &auth_claims.user_claims);
+       if (ret) {
+               TALLOC_FREE(frame);
+               return ret;
+       }
+
+       nt_status = claims_data_encoded_claims_set(frame,
+                                                  auth_claims.user_claims,
+                                                  &client_claims_blob);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               talloc_free(mem_ctx);
+               return map_errno_from_nt_status(nt_status);
+       }
+
+       /*
+        * For an S4U2Self request, the authentication policy is not enforced.
+        */
+       if (!is_s4u2self &&
+           authn_policy_restrictions_present(server->server_policy))
+       {
+               const struct auth_user_info_dc *device_info_dc = NULL;
+
+               if (samba_kdc_entry_pac_valid_principal(device)) {
+                       ret = samba_kdc_get_user_info_dc(frame,
+                                                        context,
+                                                        kdc_db_ctx,
+                                                        device,
+                                                        &device_info_dc,
+                                                        NULL /* resource_groups_out */);
+                       if (ret) {
+                               TALLOC_FREE(frame);
+                               return ret;
+                       }
+
+                       ret = samba_kdc_get_claims_data(frame,
+                                                       context,
+                                                       kdc_db_ctx,
+                                                       device,
+                                                       &auth_claims.device_claims);
+                       if (ret) {
+                               TALLOC_FREE(frame);
+                               return ret;
+                       }
+               }
+
+               /*
+                * Allocate the audit info and output status on to the parent
+                * mem_ctx, not the temporary context.
+                */
+               ret = samba_kdc_allowed_to_authenticate_to(mem_ctx,
+                                                          kdc_db_ctx,
+                                                          client,
+                                                          user_info_dc,
+                                                          device_info_dc,
+                                                          auth_claims,
+                                                          server,
+                                                          server_audit_info_out,
+                                                          status_out);
+               if (ret) {
+                       TALLOC_FREE(frame);
+                       return ret;
+               }
+       }
+
+       nt_status = samba_kdc_get_logon_info_blob(frame,
+                                                 user_info_dc,
+                                                 group_inclusion,
+                                                 &logon_blob);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               TALLOC_FREE(frame);
+               return map_errno_from_nt_status(nt_status);
+       }
+
+       if (cred_ndr_ptr != NULL) {
+               nt_status = samba_kdc_get_cred_ndr_blob(frame,
+                                                       client,
+                                                       cred_ndr_ptr);
+               if (!NT_STATUS_IS_OK(nt_status)) {
+                       TALLOC_FREE(frame);
+                       return map_errno_from_nt_status(nt_status);
+               }
+       }
+
+       nt_status = samba_kdc_get_upn_info_blob(frame,
+                                               user_info_dc,
+                                               &upn_blob);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               TALLOC_FREE(frame);
+               return map_errno_from_nt_status(nt_status);
+       }
+
+       if (is_krbtgt) {
+               nt_status = samba_kdc_get_pac_attrs_blob(frame,
+                                                        pac_attributes,
+                                                        &pac_attrs_blob);
+               if (!NT_STATUS_IS_OK(nt_status)) {
+                       TALLOC_FREE(frame);
+                       return map_errno_from_nt_status(nt_status);
+               }
+
+               nt_status = samba_kdc_get_requester_sid_blob(frame,
+                                                            user_info_dc,
+                                                            &requester_sid_blob);
+               if (!NT_STATUS_IS_OK(nt_status)) {
+                       TALLOC_FREE(frame);
+                       return map_errno_from_nt_status(nt_status);
+               }
+       }
+
+       if (pk_reply_key != NULL && cred_ndr != NULL) {
+               ret = samba_kdc_encrypt_pac_credentials(context,
+                                                       pk_reply_key,
+                                                       cred_ndr,
+                                                       frame,
+                                                       &_cred_blob);
+               if (ret != 0) {
+                       TALLOC_FREE(frame);
+                       return ret;
+               }
+               cred_blob = &_cred_blob;
+       }
+
+       ret = samba_make_krb5_pac(context,
+                                 logon_blob,
+                                 cred_blob,
+                                 upn_blob,
+                                 pac_attrs_blob,
+                                 requester_sid_blob,
+                                 NULL, /* deleg_blob */
+                                 &client_claims_blob,
+                                 NULL, /* device_info_blob */
+                                 NULL, /* device_claims_blob */
+                                 new_pac);
+
+       TALLOC_FREE(frame);
+       return ret;
+}
+
 /**
  * @brief Update a PAC
  *
index 974801df0e3445b0d8772cb54ab266a798d04752..fe7c34402746933e022dc2cfbbb23b38ff812487 100644 (file)
@@ -43,6 +43,7 @@ enum samba_asserted_identity {
 enum {
        SAMBA_KDC_FLAG_PROTOCOL_TRANSITION    = 0x00000001,
        SAMBA_KDC_FLAG_CONSTRAINED_DELEGATION = 0x00000002,
+       SAMBA_KDC_FLAG_PKINIT_FRESHNESS_USED  = 0x00000004,
 };
 
 bool samba_kdc_entry_is_trust(const struct samba_kdc_entry *entry);
@@ -126,6 +127,19 @@ krb5_error_code samba_kdc_verify_pac(TALLOC_CTX *mem_ctx,
                                     const struct samba_kdc_entry *krbtgt);
 
 struct authn_audit_info;
+krb5_error_code samba_kdc_get_pac(TALLOC_CTX *mem_ctx,
+                                 krb5_context context,
+                                 struct samba_kdc_db_context *kdc_db_ctx,
+                                 uint32_t flags,
+                                 struct samba_kdc_entry *client,
+                                 const krb5_const_principal server_principal,
+                                 const struct samba_kdc_entry *server,
+                                 const struct samba_kdc_entry_pac device,
+                                 const krb5_keyblock *pk_reply_key,
+                                 uint64_t pac_attributes,
+                                 krb5_pac new_pac,
+                                 struct authn_audit_info **server_audit_info_out,
+                                 NTSTATUS *status_out);
 krb5_error_code samba_kdc_update_pac(TALLOC_CTX *mem_ctx,
                                     krb5_context context,
                                     struct samba_kdc_db_context *kdc_db_ctx,
index b49b2d641f5509f3433c73cfa38c3f68dbf136b3..685d25b88b9d6bb1e115e85701135ba2a6f2a72f 100644 (file)
@@ -76,271 +76,99 @@ static krb5_error_code samba_wdc_get_pac(void *priv,
 {
        krb5_context context = kdc_request_get_context((kdc_request_t)r);
        TALLOC_CTX *mem_ctx;
-       DATA_BLOB *logon_blob = NULL;
-       DATA_BLOB *cred_ndr = NULL;
-       DATA_BLOB **cred_ndr_ptr = NULL;
-       DATA_BLOB _cred_blob = data_blob_null;
-       DATA_BLOB *cred_blob = NULL;
-       DATA_BLOB *upn_blob = NULL;
-       DATA_BLOB *pac_attrs_blob = NULL;
-       DATA_BLOB *requester_sid_blob = NULL;
-       DATA_BLOB client_claims_blob = {};
        krb5_error_code ret;
-       NTSTATUS nt_status;
-       struct samba_kdc_entry *skdc_entry =
+       struct samba_kdc_entry *client_entry =
                talloc_get_type_abort(client->context,
                struct samba_kdc_entry);
        const struct samba_kdc_entry *server_entry =
                talloc_get_type_abort(server->context,
                struct samba_kdc_entry);
-       bool is_krbtgt = krb5_principal_is_krbtgt(context, server->principal);
-       enum auth_group_inclusion group_inclusion;
+       const hdb_entry *device = kdc_request_get_armor_client(r);
+       struct samba_kdc_entry_pac device_pac_entry = {};
        bool is_s4u2self = samba_wdc_is_s4u2self_req(r);
-       enum samba_asserted_identity asserted_identity =
-               (is_s4u2self) ?
-                       SAMBA_ASSERTED_IDENTITY_SERVICE :
-                       SAMBA_ASSERTED_IDENTITY_AUTHENTICATION_AUTHORITY;
+       uint32_t flags = 0;
        struct authn_audit_info *server_audit_info = NULL;
        NTSTATUS reply_status = NT_STATUS_OK;
 
-       const struct auth_user_info_dc *user_info_dc_const = NULL;
-       struct auth_user_info_dc *user_info_dc_shallow_copy = NULL;
-       struct auth_claims auth_claims = {};
-
-       /* Only include resource groups in a service ticket. */
-       if (is_krbtgt) {
-               group_inclusion = AUTH_EXCLUDE_RESOURCE_GROUPS;
-       } else if (server_entry->supported_enctypes & KERB_ENCTYPE_RESOURCE_SID_COMPRESSION_DISABLED) {
-               group_inclusion = AUTH_INCLUDE_RESOURCE_GROUPS;
-       } else {
-               group_inclusion = AUTH_INCLUDE_RESOURCE_GROUPS_COMPRESSED;
-       }
-
-       mem_ctx = talloc_named(client->context, 0, "samba_wdc_get_pac context");
-       if (!mem_ctx) {
-               return ENOMEM;
-       }
-
-       if (pk_reply_key != NULL) {
-               cred_ndr_ptr = &cred_ndr;
-       }
-
-       ret = samba_kdc_get_user_info_from_db(mem_ctx,
-                                             server_entry->kdc_db_ctx,
-                                             skdc_entry,
-                                             skdc_entry->msg,
-                                             &user_info_dc_const);
-       if (ret) {
-               talloc_free(mem_ctx);
-               return ret;
-       }
-
-       /* Make a shallow copy of the user_info_dc structure. */
-       nt_status = authsam_shallow_copy_user_info_dc(mem_ctx,
-                                                     user_info_dc_const,
-                                                     &user_info_dc_shallow_copy);
-       user_info_dc_const = NULL;
-
-       if (!NT_STATUS_IS_OK(nt_status)) {
-               DBG_ERR("Failed to allocate user_info_dc SIDs: %s\n",
-                       nt_errstr(nt_status));
-               talloc_free(mem_ctx);
-               return map_errno_from_nt_status(nt_status);
-       }
-
-       nt_status = samba_kdc_add_asserted_identity(asserted_identity,
-                                                   user_info_dc_shallow_copy);
-       if (!NT_STATUS_IS_OK(nt_status)) {
-               DBG_ERR("Failed to add asserted identity: %s\n",
-                       nt_errstr(nt_status));
-               talloc_free(mem_ctx);
-               return map_errno_from_nt_status(nt_status);
+       if (pac == NULL) {
+               return EINVAL;
        }
 
-       nt_status = samba_kdc_add_claims_valid(user_info_dc_shallow_copy);
-       if (!NT_STATUS_IS_OK(nt_status)) {
-               DBG_ERR("Failed to add Claims Valid: %s\n",
-                       nt_errstr(nt_status));
-               talloc_free(mem_ctx);
-               return map_errno_from_nt_status(nt_status);
+       if (is_s4u2self) {
+               flags |= SAMBA_KDC_FLAG_PROTOCOL_TRANSITION;
        }
 
        if (kdc_request_get_pkinit_freshness_used(r)) {
-               nt_status = samba_kdc_add_fresh_public_key_identity(user_info_dc_shallow_copy);
-               if (!NT_STATUS_IS_OK(nt_status)) {
-                       DBG_ERR("Failed to add Fresh Public Key Identity: %s\n",
-                               nt_errstr(nt_status));
-                       talloc_free(mem_ctx);
-                       return map_errno_from_nt_status(nt_status);
-               }
+               flags |= SAMBA_KDC_FLAG_PKINIT_FRESHNESS_USED;
        }
 
-       ret = samba_kdc_get_claims_data_from_db(server_entry->kdc_db_ctx->samdb,
-                                               skdc_entry,
-                                               &auth_claims.user_claims);
-       if (ret) {
-               talloc_free(mem_ctx);
-               return ret;
+       mem_ctx = talloc_named(client->context, 0, "samba_wdc_get_pac context");
+       if (!mem_ctx) {
+               return ENOMEM;
        }
 
-       nt_status = claims_data_encoded_claims_set(mem_ctx,
-                                                  auth_claims.user_claims,
-                                                  &client_claims_blob);
-       if (!NT_STATUS_IS_OK(nt_status)) {
-               talloc_free(mem_ctx);
-               return map_errno_from_nt_status(nt_status);
-       }
+       if (device != NULL) {
+               const hdb_entry *device_krbtgt = NULL;
+               struct samba_kdc_entry *device_skdc_entry = NULL;
+               const struct samba_kdc_entry *device_krbtgt_skdc_entry = NULL;
+               const krb5_const_pac device_pac = kdc_request_get_armor_pac(r);
 
-       /*
-        * For an S4U2Self request, the authentication policy is not enforced.
-        */
-       if (!is_s4u2self && authn_policy_restrictions_present(server_entry->server_policy)) {
-               const hdb_entry *device = kdc_request_get_armor_client(r);
-               const struct auth_user_info_dc *device_info = NULL;
-
-               if (device != NULL) {
-                       const hdb_entry *device_krbtgt = NULL;
-                       struct samba_kdc_entry *device_skdc_entry = NULL;
-                       const struct samba_kdc_entry *device_krbtgt_skdc_entry = NULL;
-                       const krb5_const_pac device_pac = kdc_request_get_armor_pac(r);
-                       struct samba_kdc_entry_pac device_pac_entry = {};
-
-                       device_skdc_entry = talloc_get_type_abort(device->context,
-                                                                 struct samba_kdc_entry);
-
-                       device_krbtgt = kdc_request_get_armor_server(r);
-                       if (device_krbtgt != NULL) {
-                               device_krbtgt_skdc_entry = talloc_get_type_abort(device_krbtgt->context,
-                                                                                struct samba_kdc_entry);
-                       }
-
-                       device_pac_entry = samba_kdc_entry_pac(device_pac,
-                                                              device_skdc_entry,
-                                                              device_krbtgt_skdc_entry);
-
-                       ret = samba_kdc_get_user_info_dc(mem_ctx,
-                                                        context,
-                                                        server_entry->kdc_db_ctx,
-                                                        device_pac_entry,
-                                                        &device_info,
-                                                        NULL /* resource_groups_out */);
-                       if (ret) {
-                               talloc_free(mem_ctx);
-                               return ret;
-                       }
-
-                       ret = samba_kdc_get_claims_data(mem_ctx,
-                                                       context,
-                                                       server_entry->kdc_db_ctx,
-                                                       device_pac_entry,
-                                                       &auth_claims.device_claims);
-                       if (ret) {
-                               talloc_free(mem_ctx);
-                               return ret;
-                       }
-               }
+               device_skdc_entry = talloc_get_type_abort(device->context,
+                                                         struct samba_kdc_entry);
 
-               ret = samba_kdc_allowed_to_authenticate_to(mem_ctx,
-                                                          server_entry->kdc_db_ctx,
-                                                          skdc_entry,
-                                                          user_info_dc_shallow_copy,
-                                                          device_info,
-                                                          auth_claims,
-                                                          server_entry,
-                                                          &server_audit_info,
-                                                          &reply_status);
-               if (server_audit_info != NULL) {
-                       krb5_error_code ret2;
-
-                       ret2 = hdb_samba4_set_steal_server_audit_info(r, server_audit_info);
-                       if (ret == 0) {
-                               ret = ret2;
-                       }
+               device_krbtgt = kdc_request_get_armor_server(r);
+               if (device_krbtgt != NULL) {
+                       device_krbtgt_skdc_entry = talloc_get_type_abort(device_krbtgt->context,
+                                                                        struct samba_kdc_entry);
                }
-               if (!NT_STATUS_IS_OK(reply_status)) {
-                       krb5_error_code ret2;
 
-                       ret2 = hdb_samba4_set_ntstatus(r, reply_status, ret);
-                       if (ret == 0) {
-                               ret = ret2;
-                       }
-               }
-               if (ret) {
-                       talloc_free(mem_ctx);
-                       return ret;
-               }
-       }
-
-       nt_status = samba_kdc_get_logon_info_blob(mem_ctx,
-                                                 user_info_dc_shallow_copy,
-                                                 group_inclusion,
-                                                 &logon_blob);
-       if (!NT_STATUS_IS_OK(nt_status)) {
-               talloc_free(mem_ctx);
-               return map_errno_from_nt_status(nt_status);
+               device_pac_entry = samba_kdc_entry_pac(device_pac,
+                                                      device_skdc_entry,
+                                                      device_krbtgt_skdc_entry);
        }
 
-       if (cred_ndr_ptr != NULL) {
-               nt_status = samba_kdc_get_cred_ndr_blob(mem_ctx,
-                                                       skdc_entry,
-                                                       cred_ndr_ptr);
-               if (!NT_STATUS_IS_OK(nt_status)) {
-                       talloc_free(mem_ctx);
-                       return map_errno_from_nt_status(nt_status);
-               }
-       }
-
-       nt_status = samba_kdc_get_upn_info_blob(mem_ctx,
-                                               user_info_dc_shallow_copy,
-                                               &upn_blob);
-       if (!NT_STATUS_IS_OK(nt_status)) {
+       ret = krb5_pac_init(context, pac);
+       if (ret != 0) {
                talloc_free(mem_ctx);
-               return map_errno_from_nt_status(nt_status);
+               return ret;
        }
 
-       if (is_krbtgt) {
-               nt_status = samba_kdc_get_pac_attrs_blob(mem_ctx,
-                                                        pac_attributes,
-                                                        &pac_attrs_blob);
-               if (!NT_STATUS_IS_OK(nt_status)) {
-                       talloc_free(mem_ctx);
-                       return map_errno_from_nt_status(nt_status);
-               }
+       ret = samba_kdc_get_pac(mem_ctx,
+                               context,
+                               server_entry->kdc_db_ctx,
+                               flags,
+                               client_entry,
+                               server->principal,
+                               server_entry,
+                               device_pac_entry,
+                               pk_reply_key,
+                               pac_attributes,
+                               *pac,
+                               &server_audit_info,
+                               &reply_status);
+       if (server_audit_info != NULL) {
+               krb5_error_code ret2;
 
-               nt_status = samba_kdc_get_requester_sid_blob(mem_ctx,
-                                                            user_info_dc_shallow_copy,
-                                                            &requester_sid_blob);
-               if (!NT_STATUS_IS_OK(nt_status)) {
-                       talloc_free(mem_ctx);
-                       return map_errno_from_nt_status(nt_status);
+               ret2 = hdb_samba4_set_steal_server_audit_info(r, server_audit_info);
+               if (ret == 0) {
+                       ret = ret2;
                }
        }
+       if (!NT_STATUS_IS_OK(reply_status)) {
+               krb5_error_code ret2;
 
-       if (pk_reply_key != NULL && cred_ndr != NULL) {
-               ret = samba_kdc_encrypt_pac_credentials(context,
-                                                       pk_reply_key,
-                                                       cred_ndr,
-                                                       mem_ctx,
-                                                       &_cred_blob);
-               if (ret != 0) {
-                       talloc_free(mem_ctx);
-                       return ret;
+               ret2 = hdb_samba4_set_ntstatus(r, reply_status, ret);
+               if (ret == 0) {
+                       ret = ret2;
                }
-               cred_blob = &_cred_blob;
        }
-
-       ret = krb5_pac_init(context, pac);
-       if (ret != 0) {
+       if (ret) {
+               krb5_pac_free(context, *pac);
+               *pac = NULL;
                talloc_free(mem_ctx);
                return ret;
        }
 
-       ret = samba_make_krb5_pac(context, logon_blob, cred_blob,
-                                 upn_blob, pac_attrs_blob,
-                                 requester_sid_blob, NULL,
-                                 &client_claims_blob, NULL, NULL,
-                                 *pac);
-
        talloc_free(mem_ctx);
        return ret;
 }