CVE-2020-25719 s4:kdc: Add KDC support for PAC_REQUESTER_SID PAC buffer
authorJoseph Sutton <josephsutton@catalyst.net.nz>
Tue, 26 Oct 2021 07:42:41 +0000 (20:42 +1300)
committerJule Anger <janger@samba.org>
Mon, 8 Nov 2021 09:52:12 +0000 (10:52 +0100)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14561

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

index 80044551c9cad00bb8d0324cc73fefb700d609f3..9cad1ca4d052da03d320420ca2a1f47038f81968 100644 (file)
 ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_user_pac_request_false
 ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_user_pac_request_none
 ^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_user2user_user_pac_request_true
-#
-# PAC requester SID tests
-#
-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_as_requester_sid
-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_sid_mismatch_existing
-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_logon_info_sid_mismatch_nonexisting
-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_requester_sid_mismatch_existing
-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_requester_sid_mismatch_nonexisting
-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_req_from_rodc_no_requester_sid
-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid
-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_renew
-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_missing_rodc_renew
-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_renew
-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_requester_sid_rodc_renew
-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_sid_mismatch_existing
-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_logon_info_sid_mismatch_nonexisting
-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_requester_sid_mismatch_existing
-^samba.tests.krb5.kdc_tgs_tests.samba.tests.krb5.kdc_tgs_tests.KdcTgsTests.test_tgs_rodc_requester_sid_mismatch_nonexisting
-#
-# PAC tests
-#
-^samba4.blackbox.pkinit_pac.STEP1 remote.pac verification.ad_dc:local
-^samba4.blackbox.pkinit_pac.STEP1 remote.pac verification.ad_dc_ntvfs:local
-^samba4.blackbox.pkinit_pac.netr-bdc-aes.verify-sig-aes.ad_dc:local
-^samba4.blackbox.pkinit_pac.netr-bdc-aes.verify-sig-aes.ad_dc_ntvfs:local
-^samba4.blackbox.pkinit_pac.netr-mem-aes.s4u2proxy-aes.ad_dc:local
-^samba4.blackbox.pkinit_pac.netr-mem-aes.s4u2proxy-aes.ad_dc_ntvfs:local
-^samba4.blackbox.pkinit_pac.netr-mem-aes.verify-sig-aes.ad_dc:local
-^samba4.blackbox.pkinit_pac.netr-mem-aes.verify-sig-aes.ad_dc_ntvfs:local
-^samba4.blackbox.pkinit_pac.netr-mem-arcfour.s4u2proxy-arcfour.ad_dc:local
-^samba4.blackbox.pkinit_pac.netr-mem-arcfour.s4u2proxy-arcfour.ad_dc_ntvfs:local
-^samba4.blackbox.pkinit_pac.netr-mem-arcfour.verify-sig-arcfour.ad_dc:local
-^samba4.blackbox.pkinit_pac.netr-mem-arcfour.verify-sig-arcfour.ad_dc_ntvfs:local
-^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2000dc
-^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2003dc
-^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2008dc
-^samba4.rpc.pac on ncacn_np.netr-bdc-aes.verify-sig-aes.fl2008r2dc
-^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2000dc
-^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2003dc
-^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2008dc
-^samba4.rpc.pac on ncacn_np.netr-bdc-arcfour.verify-sig-arcfour.fl2008r2dc
-^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2000dc
-^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2003dc
-^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2008dc
-^samba4.rpc.pac on ncacn_np.netr-mem-aes.s4u2proxy-aes.fl2008r2dc
-^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2000dc
-^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2003dc
-^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2008dc
-^samba4.rpc.pac on ncacn_np.netr-mem-aes.verify-sig-aes.fl2008r2dc
-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2000dc
-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2003dc
-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2008dc
-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.s4u2proxy-arcfour.fl2008r2dc
-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2000dc
-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2003dc
-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2008dc
-^samba4.rpc.pac on ncacn_np.netr-mem-arcfour.verify-sig-arcfour.fl2008r2dc
index 99a5214a89629487dd236e69e2f7928a808b3c0a..e015c5a52dbe97efc7593ac5b941ea93bfa0e1be 100644 (file)
@@ -435,7 +435,7 @@ int mit_samba_get_pac(struct mit_samba_context *smb_ctx,
                                            &logon_info_blob,
                                            cred_ndr_ptr,
                                            &upn_dns_info_blob,
-                                           NULL, NULL,
+                                           NULL, NULL, NULL,
                                            NULL);
        if (!NT_STATUS_IS_OK(nt_status)) {
                talloc_free(tmp_ctx);
@@ -465,6 +465,7 @@ int mit_samba_get_pac(struct mit_samba_context *smb_ctx,
                                   upn_dns_info_blob,
                                   NULL,
                                   NULL,
+                                  NULL,
                                   pac);
 
        talloc_free(tmp_ctx);
@@ -569,6 +570,7 @@ krb5_error_code mit_samba_reget_pac(struct mit_samba_context *ctx,
                                                    NULL,
                                                    &upn_blob,
                                                    NULL, NULL,
+                                                   NULL,
                                                    NULL);
                if (!NT_STATUS_IS_OK(nt_status)) {
                        code = EINVAL;
index 95f71c04b2321079dfef3fa99a7c048b94efa1e8..e0e483662c0f54b8b1d8226b0748a08d2bdc06fa 100644 (file)
@@ -40,7 +40,8 @@
 static
 NTSTATUS samba_get_logon_info_pac_blob(TALLOC_CTX *mem_ctx,
                                       const struct auth_user_info_dc *info,
-                                      DATA_BLOB *pac_data)
+                                      DATA_BLOB *pac_data,
+                                      DATA_BLOB *requester_sid_blob)
 {
        struct netr_SamInfo3 *info3;
        union PAC_INFO pac_info;
@@ -50,6 +51,9 @@ NTSTATUS samba_get_logon_info_pac_blob(TALLOC_CTX *mem_ctx,
        ZERO_STRUCT(pac_info);
 
        *pac_data = data_blob_null;
+       if (requester_sid_blob != NULL) {
+               *requester_sid_blob = data_blob_null;
+       }
 
        nt_status = auth_convert_user_info_dc_saminfo3(mem_ctx, info, &info3);
        if (!NT_STATUS_IS_OK(nt_status)) {
@@ -75,6 +79,25 @@ NTSTATUS samba_get_logon_info_pac_blob(TALLOC_CTX *mem_ctx,
                return nt_status;
        }
 
+       if (requester_sid_blob != NULL && info->num_sids > 0) {
+               union PAC_INFO pac_requester_sid;
+
+               ZERO_STRUCT(pac_requester_sid);
+
+               pac_requester_sid.requester_sid.sid = info->sids[0];
+
+               ndr_err = ndr_push_union_blob(requester_sid_blob, mem_ctx,
+                                             &pac_requester_sid,
+                                             PAC_TYPE_REQUESTER_SID,
+                                             (ndr_push_flags_fn_t)ndr_push_PAC_INFO);
+               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       nt_status = ndr_map_error2ntstatus(ndr_err);
+                       DEBUG(1, ("PAC_REQUESTER_SID (presig) push failed: %s\n",
+                                 nt_errstr(nt_status)));
+                       return nt_status;
+               }
+       }
+
        return NT_STATUS_OK;
 }
 
@@ -460,6 +483,7 @@ krb5_error_code samba_make_krb5_pac(krb5_context context,
                                    const DATA_BLOB *cred_blob,
                                    const DATA_BLOB *upn_blob,
                                    const DATA_BLOB *pac_attrs_blob,
+                                   const DATA_BLOB *requester_sid_blob,
                                    const DATA_BLOB *deleg_blob,
                                    krb5_pac *pac)
 {
@@ -467,6 +491,7 @@ krb5_error_code samba_make_krb5_pac(krb5_context context,
        krb5_data cred_data;
        krb5_data upn_data;
        krb5_data pac_attrs_data;
+       krb5_data requester_sid_data;
        krb5_data deleg_data;
        krb5_error_code ret;
 #ifdef SAMBA4_USES_HEIMDAL
@@ -524,6 +549,20 @@ krb5_error_code samba_make_krb5_pac(krb5_context context,
                }
        }
 
+       ZERO_STRUCT(requester_sid_data);
+       if (requester_sid_blob != NULL) {
+               ret = smb_krb5_copy_data_contents(&requester_sid_data,
+                                                 requester_sid_blob->data,
+                                                 requester_sid_blob->length);
+               if (ret != 0) {
+                       smb_krb5_free_data_contents(context, &logon_data);
+                       smb_krb5_free_data_contents(context, &cred_data);
+                       smb_krb5_free_data_contents(context, &upn_data);
+                       smb_krb5_free_data_contents(context, &pac_attrs_data);
+                       return ret;
+               }
+       }
+
        ZERO_STRUCT(deleg_data);
        if (deleg_blob != NULL) {
                ret = smb_krb5_copy_data_contents(&deleg_data,
@@ -534,6 +573,7 @@ krb5_error_code samba_make_krb5_pac(krb5_context context,
                        smb_krb5_free_data_contents(context, &cred_data);
                        smb_krb5_free_data_contents(context, &upn_data);
                        smb_krb5_free_data_contents(context, &pac_attrs_data);
+                       smb_krb5_free_data_contents(context, &requester_sid_data);
                        return ret;
                }
        }
@@ -544,6 +584,7 @@ krb5_error_code samba_make_krb5_pac(krb5_context context,
                smb_krb5_free_data_contents(context, &cred_data);
                smb_krb5_free_data_contents(context, &upn_data);
                smb_krb5_free_data_contents(context, &pac_attrs_data);
+               smb_krb5_free_data_contents(context, &requester_sid_data);
                smb_krb5_free_data_contents(context, &deleg_data);
                return ret;
        }
@@ -554,6 +595,7 @@ krb5_error_code samba_make_krb5_pac(krb5_context context,
                smb_krb5_free_data_contents(context, &cred_data);
                smb_krb5_free_data_contents(context, &upn_data);
                smb_krb5_free_data_contents(context, &pac_attrs_data);
+               smb_krb5_free_data_contents(context, &requester_sid_data);
                smb_krb5_free_data_contents(context, &deleg_data);
                return ret;
        }
@@ -566,6 +608,7 @@ krb5_error_code samba_make_krb5_pac(krb5_context context,
                if (ret != 0) {
                        smb_krb5_free_data_contents(context, &upn_data);
                        smb_krb5_free_data_contents(context, &pac_attrs_data);
+                       smb_krb5_free_data_contents(context, &requester_sid_data);
                        smb_krb5_free_data_contents(context, &deleg_data);
                        return ret;
                }
@@ -585,6 +628,7 @@ krb5_error_code samba_make_krb5_pac(krb5_context context,
        if (ret != 0) {
                smb_krb5_free_data_contents(context, &upn_data);
                smb_krb5_free_data_contents(context, &pac_attrs_data);
+               smb_krb5_free_data_contents(context, &requester_sid_data);
                smb_krb5_free_data_contents(context, &deleg_data);
                return ret;
        }
@@ -597,6 +641,7 @@ krb5_error_code samba_make_krb5_pac(krb5_context context,
                smb_krb5_free_data_contents(context, &upn_data);
                if (ret != 0) {
                        smb_krb5_free_data_contents(context, &pac_attrs_data);
+                       smb_krb5_free_data_contents(context, &requester_sid_data);
                        smb_krb5_free_data_contents(context, &deleg_data);
                        return ret;
                }
@@ -607,6 +652,18 @@ krb5_error_code samba_make_krb5_pac(krb5_context context,
                                          PAC_TYPE_ATTRIBUTES_INFO,
                                          &pac_attrs_data);
                smb_krb5_free_data_contents(context, &pac_attrs_data);
+               if (ret != 0) {
+                       smb_krb5_free_data_contents(context, &requester_sid_data);
+                       smb_krb5_free_data_contents(context, &deleg_data);
+                       return ret;
+               }
+       }
+
+       if (requester_sid_blob != NULL) {
+               ret = krb5_pac_add_buffer(context, *pac,
+                                         PAC_TYPE_REQUESTER_SID,
+                                         &requester_sid_data);
+               smb_krb5_free_data_contents(context, &requester_sid_data);
                if (ret != 0) {
                        smb_krb5_free_data_contents(context, &deleg_data);
                        return ret;
@@ -765,6 +822,7 @@ NTSTATUS samba_kdc_get_pac_blobs(TALLOC_CTX *mem_ctx,
                                 DATA_BLOB **_upn_info_blob,
                                 DATA_BLOB **_pac_attrs_blob,
                                 const krb5_boolean *pac_request,
+                                DATA_BLOB **_requester_sid_blob,
                                 struct auth_user_info_dc **_user_info_dc)
 {
        struct auth_user_info_dc *user_info_dc;
@@ -772,6 +830,7 @@ NTSTATUS samba_kdc_get_pac_blobs(TALLOC_CTX *mem_ctx,
        DATA_BLOB *cred_blob = NULL;
        DATA_BLOB *upn_blob = NULL;
        DATA_BLOB *pac_attrs_blob = NULL;
+       DATA_BLOB *requester_sid_blob = NULL;
        NTSTATUS nt_status;
 
        *_logon_info_blob = NULL;
@@ -782,6 +841,9 @@ NTSTATUS samba_kdc_get_pac_blobs(TALLOC_CTX *mem_ctx,
        if (_pac_attrs_blob != NULL) {
                *_pac_attrs_blob = NULL;
        }
+       if (_requester_sid_blob != NULL) {
+               *_requester_sid_blob = NULL;
+       }
 
        logon_blob = talloc_zero(mem_ctx, DATA_BLOB);
        if (logon_blob == NULL) {
@@ -807,6 +869,13 @@ NTSTATUS samba_kdc_get_pac_blobs(TALLOC_CTX *mem_ctx,
                }
        }
 
+       if (_requester_sid_blob != NULL) {
+               requester_sid_blob = talloc_zero(mem_ctx, DATA_BLOB);
+               if (requester_sid_blob == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+       }
+
        nt_status = authsam_make_user_info_dc(mem_ctx, p->kdc_db_ctx->samdb,
                                             lpcfg_netbios_name(p->kdc_db_ctx->lp_ctx),
                                             lpcfg_sam_name(p->kdc_db_ctx->lp_ctx),
@@ -824,7 +893,8 @@ NTSTATUS samba_kdc_get_pac_blobs(TALLOC_CTX *mem_ctx,
 
        nt_status = samba_get_logon_info_pac_blob(logon_blob,
                                                  user_info_dc,
-                                                 logon_blob);
+                                                 logon_blob,
+                                                 requester_sid_blob);
        if (!NT_STATUS_IS_OK(nt_status)) {
                DEBUG(0, ("Building PAC LOGON INFO failed: %s\n",
                          nt_errstr(nt_status)));
@@ -880,6 +950,9 @@ NTSTATUS samba_kdc_get_pac_blobs(TALLOC_CTX *mem_ctx,
        if (_pac_attrs_blob != NULL) {
                *_pac_attrs_blob = pac_attrs_blob;
        }
+       if (_requester_sid_blob != NULL) {
+               *_requester_sid_blob = requester_sid_blob;
+       }
        return NT_STATUS_OK;
 }
 
@@ -912,7 +985,7 @@ NTSTATUS samba_kdc_update_pac_blob(TALLOC_CTX *mem_ctx,
        }
 
        nt_status = samba_get_logon_info_pac_blob(mem_ctx,
-                                                 user_info_dc, pac_blob);
+                                                 user_info_dc, pac_blob, NULL);
 
        return nt_status;
 }
@@ -1062,6 +1135,52 @@ NTSTATUS samba_kdc_check_client_access(struct samba_kdc_entry *kdc_entry,
        return nt_status;
 }
 
+static krb5_error_code samba_get_requester_sid(TALLOC_CTX *mem_ctx,
+                                              krb5_pac pac,
+                                              krb5_context context,
+                                              struct dom_sid *sid)
+{
+       NTSTATUS nt_status;
+       enum ndr_err_code ndr_err;
+       krb5_error_code ret;
+
+       DATA_BLOB pac_requester_sid_in;
+       krb5_data k5pac_requester_sid_in;
+
+       union PAC_INFO info;
+
+       TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+       if (tmp_ctx == NULL) {
+               return ENOMEM;
+       }
+
+       ret = krb5_pac_get_buffer(context, pac, PAC_TYPE_REQUESTER_SID,
+                                 &k5pac_requester_sid_in);
+       if (ret != 0) {
+               talloc_free(tmp_ctx);
+               return ret;
+       }
+
+       pac_requester_sid_in = data_blob_const(k5pac_requester_sid_in.data,
+                                              k5pac_requester_sid_in.length);
+
+       ndr_err = ndr_pull_union_blob(&pac_requester_sid_in, tmp_ctx, &info,
+                                     PAC_TYPE_REQUESTER_SID,
+                                     (ndr_pull_flags_fn_t)ndr_pull_PAC_INFO);
+       smb_krb5_free_data_contents(context, &k5pac_requester_sid_in);
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               nt_status = ndr_map_error2ntstatus(ndr_err);
+               DEBUG(0,("can't parse the PAC REQUESTER_SID: %s\n", nt_errstr(nt_status)));
+               talloc_free(tmp_ctx);
+               return EINVAL;
+       }
+
+       *sid = info.requester_sid.sid;
+
+       talloc_free(tmp_ctx);
+       return 0;
+}
+
 /* Does a parse and SID check, but no crypto. */
 krb5_error_code samba_kdc_validate_pac_blob(
                krb5_context context,
@@ -1075,22 +1194,36 @@ krb5_error_code samba_kdc_validate_pac_blob(
        krb5_error_code code;
        bool ok;
 
-       code = kerberos_pac_to_user_info_dc(frame,
-                                           pac,
-                                           context,
-                                           &pac_user_info,
-                                           NULL,
-                                           NULL);
-       if (code != 0) {
-               goto out;
-       }
+       /*
+        * First, try to get the SID from the requester SID buffer in the PAC.
+        */
+       code = samba_get_requester_sid(frame, pac, context, &pac_sid);
+
+       if (code == ENOENT) {
+               /*
+                * If the requester SID buffer isn't present, fall back to the
+                * SID in the LOGON_INFO PAC buffer.
+                */
+               code = kerberos_pac_to_user_info_dc(frame,
+                                                   pac,
+                                                   context,
+                                                   &pac_user_info,
+                                                   NULL,
+                                                   NULL);
+               if (code != 0) {
+                       goto out;
+               }
+
+               if (pac_user_info->num_sids == 0) {
+                       code = EINVAL;
+                       goto out;
+               }
 
-       if (pac_user_info->num_sids == 0) {
-               code = EINVAL;
+               pac_sid = pac_user_info->sids[0];
+       } else if (code != 0) {
                goto out;
        }
 
-       pac_sid = pac_user_info->sids[0];
        client_sid = samdb_result_dom_sid(frame,
                                          client_skdc_entry->msg,
                                          "objectSid");
index 89aa8da63c39f5defd59b21fb618dba0d30fce23..266e000f9cdda39ff5701b60898915e15c69b00a 100644 (file)
@@ -32,6 +32,7 @@ krb5_error_code samba_make_krb5_pac(krb5_context context,
                                    const DATA_BLOB *cred_blob,
                                    const DATA_BLOB *upn_blob,
                                    const DATA_BLOB *pac_attrs_blob,
+                                   const DATA_BLOB *requester_sid_blob,
                                    const DATA_BLOB *deleg_blob,
                                    krb5_pac *pac);
 
@@ -53,6 +54,7 @@ NTSTATUS samba_kdc_get_pac_blobs(TALLOC_CTX *mem_ctx,
                                 DATA_BLOB **_upn_info_blob,
                                 DATA_BLOB **_pac_attrs_blob,
                                 const krb5_boolean *pac_request,
+                                DATA_BLOB **_requester_sid_blob,
                                 struct auth_user_info_dc **_user_info_dc);
 NTSTATUS samba_kdc_update_pac_blob(TALLOC_CTX *mem_ctx,
                                   krb5_context context,
index c9bf5dd9cf57afe1cb4b69077cba40d803f1ade7..ecd182702c3452f668038ce42abb81e902c181fc 100644 (file)
@@ -49,6 +49,7 @@ static krb5_error_code samba_wdc_get_pac(void *priv, krb5_context context,
        DATA_BLOB *cred_blob = NULL;
        DATA_BLOB *upn_blob = NULL;
        DATA_BLOB *pac_attrs_blob = NULL;
+       DATA_BLOB *requester_sid_blob = NULL;
        krb5_error_code ret;
        NTSTATUS nt_status;
        struct samba_kdc_entry *skdc_entry =
@@ -70,6 +71,7 @@ static krb5_error_code samba_wdc_get_pac(void *priv, krb5_context context,
                                            &upn_blob,
                                            &pac_attrs_blob,
                                            pac_request,
+                                           &requester_sid_blob,
                                            NULL);
        if (!NT_STATUS_IS_OK(nt_status)) {
                talloc_free(mem_ctx);
@@ -91,7 +93,7 @@ static krb5_error_code samba_wdc_get_pac(void *priv, krb5_context context,
 
        ret = samba_make_krb5_pac(context, logon_blob, cred_blob,
                                  upn_blob, pac_attrs_blob,
-                                 NULL, pac);
+                                 requester_sid_blob, NULL, pac);
 
        talloc_free(mem_ctx);
        return ret;
@@ -125,6 +127,7 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context,
        krb5_pac new_pac = NULL;
        DATA_BLOB *pac_blob = NULL;
        DATA_BLOB *upn_blob = NULL;
+       DATA_BLOB *requester_sid_blob = NULL;
        DATA_BLOB *deleg_blob = NULL;
        krb5_error_code ret;
        NTSTATUS nt_status;
@@ -141,6 +144,7 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context,
        ssize_t kdc_checksum_idx = -1;
        ssize_t tkt_checksum_idx = -1;
        ssize_t attrs_info_idx = -1;
+       ssize_t requester_sid_idx = -1;
 
        if (!mem_ctx) {
                return ENOMEM;
@@ -257,7 +261,7 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context,
 
                nt_status = samba_kdc_get_pac_blobs(mem_ctx, client_skdc_entry,
                                                    &pac_blob, NULL, &upn_blob,
-                                                   NULL, NULL,
+                                                   NULL, NULL, &requester_sid_blob,
                                                    &user_info_dc);
                if (!NT_STATUS_IS_OK(nt_status)) {
                        talloc_free(mem_ctx);
@@ -408,6 +412,18 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context,
                        }
                        attrs_info_idx = i;
                        break;
+               case PAC_TYPE_REQUESTER_SID:
+                       if (requester_sid_idx != -1) {
+                               DEBUG(1, ("requester sid type[%"PRIu32"] twice [%zd] and [%zu]: \n",
+                                         types[i],
+                                         requester_sid_idx,
+                                         i));
+                               SAFE_FREE(types);
+                               talloc_free(mem_ctx);
+                               return EINVAL;
+                       }
+                       requester_sid_idx = i;
+                       break;
                default:
                        continue;
                }
@@ -546,6 +562,11 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context,
                         * we just add a place holder here.
                         */
                        type_blob = data_blob_const(&zero_byte, 1);
+
+                       if (requester_sid_idx == -1 && requester_sid_blob != NULL) {
+                               /* inject REQUESTER_SID behind */
+                               forced_next_type = PAC_TYPE_REQUESTER_SID;
+                       }
                        break;
                case PAC_TYPE_KDC_CHECKSUM:
                        /*
@@ -557,6 +578,15 @@ static krb5_error_code samba_wdc_reget_pac2(krb5_context context,
                case PAC_TYPE_ATTRIBUTES_INFO:
                        /* just copy... */
                        break;
+               case PAC_TYPE_REQUESTER_SID:
+                       /*
+                        * Replace in the RODC case, otherwise
+                        * requester_sid_blob is NULL and we just copy.
+                        */
+                       if (requester_sid_blob != NULL) {
+                               type_blob = *requester_sid_blob;
+                       }
+                       break;
                default:
                        /* just copy... */
                        break;