s4:kdc: Use samba_kdc_obtain_user_info_dc() for !client_pac_is_trusted case
authorJoseph Sutton <josephsutton@catalyst.net.nz>
Fri, 16 Jun 2023 02:04:43 +0000 (14:04 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Sun, 25 Jun 2023 23:29:33 +0000 (23:29 +0000)
This will help to reduce code duplication and the number of branching
code paths.

View with ‘git show -b’.

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

index ffa131daad14b648b127a6740e6568b56ebc1d62..41053d1d2b3a153900c2268c74db2d5b2869e92c 100644 (file)
@@ -1219,60 +1219,99 @@ static krb5_error_code samba_kdc_obtain_user_info_dc(TALLOC_CTX *mem_ctx,
                                                     krb5_context context,
                                                     struct ldb_context *samdb,
                                                     const enum auth_group_inclusion group_inclusion,
+                                                    struct samba_kdc_entry *skdc_entry,
                                                     const krb5_const_pac pac,
+                                                    const bool pac_is_trusted,
                                                     struct auth_user_info_dc **user_info_dc_out,
                                                     struct PAC_DOMAIN_GROUP_MEMBERSHIP **resource_groups_out)
 {
        struct auth_user_info_dc *user_info_dc = NULL;
        krb5_error_code ret = 0;
        NTSTATUS nt_status;
-       struct PAC_DOMAIN_GROUP_MEMBERSHIP **resource_groups = NULL;
 
        *user_info_dc_out = NULL;
        if (resource_groups_out != NULL) {
                *resource_groups_out = NULL;
        }
 
-       if (group_inclusion == AUTH_EXCLUDE_RESOURCE_GROUPS) {
+       if (pac != NULL && pac_is_trusted) {
+               struct PAC_DOMAIN_GROUP_MEMBERSHIP **resource_groups = NULL;
+
+               if (group_inclusion == AUTH_EXCLUDE_RESOURCE_GROUPS) {
+                       /*
+                        * Since we are creating a TGT, resource groups from our domain
+                        * are not to be put into the PAC. Instead, we take the resource
+                        * groups directly from the original PAC and copy them
+                        * unmodified into the new one.
+                        */
+                       resource_groups = resource_groups_out;
+               }
+
+               ret = kerberos_pac_to_user_info_dc(mem_ctx,
+                                                  pac,
+                                                  context,
+                                                  &user_info_dc,
+                                                  AUTH_EXCLUDE_RESOURCE_GROUPS,
+                                                  NULL,
+                                                  NULL,
+                                                  resource_groups);
+               if (ret) {
+                       const char *krb5err = krb5_get_error_message(context, ret);
+                       DBG_ERR("kerberos_pac_to_user_info_dc failed: %s\n",
+                               krb5err != NULL ? krb5err : "?");
+                       krb5_free_error_message(context, krb5err);
+
+                       goto out;
+               }
+
                /*
-                * Since we are creating a TGT, resource groups from our domain
-                * are not to be put into the PAC. Instead, we take the resource
-                * groups directly from the original PAC and copy them
-                * unmodified into the new one.
+                * We need to expand group memberships within our local domain,
+                * as the token might be generated by a trusted domain.
                 */
-               resource_groups = resource_groups_out;
-       }
-
-       ret = kerberos_pac_to_user_info_dc(mem_ctx,
-                                          pac,
-                                          context,
-                                          &user_info_dc,
-                                          AUTH_EXCLUDE_RESOURCE_GROUPS,
-                                          NULL,
-                                          NULL,
-                                          resource_groups);
-       if (ret) {
-               const char *krb5err = krb5_get_error_message(context, ret);
-               DBG_ERR("kerberos_pac_to_user_info_dc failed: %s\n",
-                       krb5err != NULL ? krb5err : "?");
-               krb5_free_error_message(context, krb5err);
+               nt_status = authsam_update_user_info_dc(mem_ctx,
+                                                       samdb,
+                                                       user_info_dc);
+               if (!NT_STATUS_IS_OK(nt_status)) {
+                       DBG_ERR("authsam_update_user_info_dc failed: %s\n",
+                               nt_errstr(nt_status));
 
-               goto out;
-       }
+                       ret = EINVAL;
+                       goto out;
+               }
+       } else {
+               /*
+                * In this case the RWDC discards the PAC an RODC generated.
+                * Windows adds the asserted_identity in this case too.
+                *
+                * Note that SAMBA_KDC_FLAG_CONSTRAINED_DELEGATION
+                * generates KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN.
+                * So we can always use
+                * SAMBA_ASSERTED_IDENTITY_AUTHENTICATION_AUTHORITY
+                * here.
+                */
+               enum samba_asserted_identity asserted_identity =
+                       SAMBA_ASSERTED_IDENTITY_AUTHENTICATION_AUTHORITY;
+               const enum samba_claims_valid claims_valid = SAMBA_CLAIMS_VALID_EXCLUDE;
+               const enum samba_compounded_auth compounded_auth =
+                       SAMBA_COMPOUNDED_AUTH_EXCLUDE;
 
-       /*
-        * We need to expand group memberships within our local domain,
-        * as the token might be generated by a trusted domain.
-        */
-       nt_status = authsam_update_user_info_dc(mem_ctx,
-                                               samdb,
-                                               user_info_dc);
-       if (!NT_STATUS_IS_OK(nt_status)) {
-               DBG_ERR("authsam_update_user_info_dc failed: %s\n",
-                       nt_errstr(nt_status));
+               if (skdc_entry == NULL) {
+                       ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
+                       goto out;
+               }
 
-               ret = EINVAL;
-               goto out;
+               nt_status = samba_kdc_get_user_info_dc(mem_ctx,
+                                                      skdc_entry,
+                                                      asserted_identity,
+                                                      claims_valid,
+                                                      compounded_auth,
+                                                      &user_info_dc);
+               if (!NT_STATUS_IS_OK(nt_status)) {
+                       DBG_ERR("samba_kdc_get_user_info_dc failed: %s\n",
+                               nt_errstr(nt_status));
+                       ret = KRB5KDC_ERR_TGT_REVOKED;
+                       goto out;
+               }
        }
 
        *user_info_dc_out = user_info_dc;
@@ -2420,19 +2459,6 @@ krb5_error_code samba_kdc_update_pac(TALLOC_CTX *mem_ctx,
        }
 
        if (!client_pac_is_trusted) {
-               /*
-                * In this case the RWDC discards the PAC an RODC generated.
-                * Windows adds the asserted_identity in this case too.
-                *
-                * Note that SAMBA_KDC_FLAG_CONSTRAINED_DELEGATION
-                * generates KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN.
-                * So we can always use
-                * SAMBA_ASSERTED_IDENTITY_AUTHENTICATION_AUTHORITY
-                * here.
-                */
-               enum samba_asserted_identity asserted_identity =
-                       SAMBA_ASSERTED_IDENTITY_AUTHENTICATION_AUTHORITY;
-               const enum samba_claims_valid claims_valid = SAMBA_CLAIMS_VALID_EXCLUDE;
                const enum samba_compounded_auth compounded_auth =
                        (device != NULL && !is_tgs) ?
                        SAMBA_COMPOUNDED_AUTH_INCLUDE :
@@ -2443,15 +2469,30 @@ krb5_error_code samba_kdc_update_pac(TALLOC_CTX *mem_ctx,
                        goto done;
                }
 
-               nt_status = samba_kdc_get_user_info_dc(mem_ctx,
-                                                      client,
-                                                      asserted_identity,
-                                                      claims_valid,
-                                                      compounded_auth,
-                                                      &user_info_dc);
+               code = samba_kdc_obtain_user_info_dc(mem_ctx,
+                                                    context,
+                                                    samdb,
+                                                    group_inclusion,
+                                                    client,
+                                                    old_pac,
+                                                    client_pac_is_trusted,
+                                                    &user_info_dc,
+                                                    &_resource_groups);
+               if (code != 0) {
+                       const char *err_str = krb5_get_error_message(context, code);
+                       DBG_ERR("samba_kdc_obtain_user_info_dc failed: %s\n",
+                               err_str != NULL ? err_str : "<unknown>");
+                       krb5_free_error_message(context, err_str);
+
+                       goto done;
+               }
+
+               nt_status = samba_add_compounded_auth(compounded_auth,
+                                                     user_info_dc);
                if (!NT_STATUS_IS_OK(nt_status)) {
-                       DBG_ERR("samba_kdc_get_user_info_dc failed: %s\n",
+                       DBG_ERR("Failed to add Compounded Authentication: %s\n",
                                nt_errstr(nt_status));
+
                        code = KRB5KDC_ERR_TGT_REVOKED;
                        goto done;
                }
@@ -2512,7 +2553,9 @@ krb5_error_code samba_kdc_update_pac(TALLOC_CTX *mem_ctx,
                                                     context,
                                                     samdb,
                                                     group_inclusion,
+                                                    client,
                                                     old_pac,
+                                                    client_pac_is_trusted,
                                                     &user_info_dc,
                                                     &_resource_groups);
                if (code != 0) {