diff --git a/kdc/misc.c b/kdc/misc.c index 6a8a8933a..1c780df9f 100644 --- a/kdc/misc.c +++ b/kdc/misc.c @@ -331,14 +331,22 @@ _kdc_verify_checksum(krb5_context context, * tickets, policy is governed by whether the client explicitly requested * a PAC be omitted when requesting a TGT, or if the no-auth-data-reqd * flag is set on the service principal entry. + * + * However, when issuing a cross-realm TGT to an AD realm our PAC might not + * interoperate correctly. Therefore we honor the no-auth-data-reqd HDB entry + * flag on cross-realm TGTs. */ krb5_boolean _kdc_include_pac_p(astgs_request_t r) { - if (krb5_principal_is_krbtgt(r->context, r->server->principal)) - return TRUE; - else if (r->server->flags.no_auth_data_reqd) + /* Always include a PAC in root TGTs */ + if (krb5_principal_is_krbtgt(r->context, r->server->principal)) { + if (krb5_principal_is_root_krbtgt(r->context, r->server->principal) || + !r->server->flags.no_auth_data_reqd) + return TRUE; + } + if (r->server->flags.no_auth_data_reqd) return FALSE; return !!(r->pac_attributes & (KRB5_PAC_WAS_REQUESTED | KRB5_PAC_WAS_GIVEN_IMPLICITLY)); diff --git a/tests/kdc/check-kdc.in b/tests/kdc/check-kdc.in index 7d2f4edc7..307312e1f 100644 --- a/tests/kdc/check-kdc.in +++ b/tests/kdc/check-kdc.in @@ -261,6 +261,7 @@ ${kadmin} ext -k ${keytab} ${alias1}@${R} || exit 1 ${kadmin} modify --alias=${alias2}@${R} ${alias1}@${R} ${kadmin} add -p cross1 --use-defaults krbtgt/${R2}@${R} || exit 1 +${kadmin} modify --attributes=+no-auth-data-reqd krbtgt/${R2}@${R} || exit 1 ${kadmin} add -p cross2 --use-defaults krbtgt/${R}@${R2} || exit 1 ${kadmin} add -p cross1 --use-defaults krbtgt/${R3}@${R2} || exit 1 @@ -551,6 +552,20 @@ for a in $enctypes; do done ${kdestroy} +echo "Getting client initial tickets with PAC"; > messages.log +${kinit} --request-pac --password-file=${objdir}/foopassword foo@$R || \ + { ec=1 ; eval "${testfailed}"; } +for a in $enctypes; do + echo "Getting tickets for PAC-less service principal ($a)"; > messages.log + ${kgetcred} -e $a ${server4}@${R2} || { ec=1 ; eval "${testfailed}"; } + ${test_ap_req} --verify-pac ${server4}@${R2} ${keytab} ${cache} && \ + { ec=1 ; eval "${testfailed}"; } + ${test_ap_req} --no-verify-pac ${server4}@${R2} ${keytab} ${cache} || \ + { ec=1 ; eval "${testfailed}"; } + ${kdestroy} --credential=${server4}@${R2} +done +${kdestroy} + echo "Getting client authenticated anonymous initial tickets"; > messages.log ${kinit} -n --password-file=${objdir}/foopassword foo@$R || \ { ec=1 ; eval "${testfailed}"; } @@ -559,6 +574,8 @@ for a in $enctypes; do ${kgetcred} -e $a ${server}@${R} || { ec=1 ; eval "${testfailed}"; } ${test_ap_req} --no-verify-pac ${server}@${R} ${keytab} ${cache} || \ { ec=1 ; eval "${testfailed}"; } + ${test_ap_req} --verify-pac ${server}@${R} ${keytab} ${cache} && \ + { ec=1 ; eval "${testfailed}"; } ${kdestroy} --credential=${server}@${R} done ${kdestroy} @@ -575,7 +592,7 @@ for a in $enctypes; do done ${kdestroy} -echo "Getting client initial tickets for cross realm case"; > messages.log +echo "Getting client initial tickets for cross realm case (no-auth-data-reqd for ${R2})"; > messages.log ${kinit} --password-file=${objdir}/foopassword foo@$R || { ec=1 ; eval "${testfailed}"; } for a in $enctypes; do echo "Getting cross realm tickets ($a)"; > messages.log @@ -583,7 +600,24 @@ for a in $enctypes; do echo " checking we we got back right ticket" ${klist} | grep ${server2}@ > /dev/null || { ec=1 ; eval "${testfailed}"; } echo " checking if ticket is useful" - ${test_ap_req} ${server2}@${R2} ${keytab} ${cache} || \ + ${test_ap_req} --no-verify-pac ${server2}@${R2} ${keytab} ${cache} || \ + { ec=1 ; eval "${testfailed}"; } + ${test_ap_req} --verify-pac ${server2}@${R2} ${keytab} ${cache} && \ + { ec=1 ; eval "${testfailed}"; } + ${kdestroy} --credential=${server2}@${R2} +done +${kdestroy} + +echo "Getting client initial tickets for cross realm case (w/ PAC)"; > messages.log +${kadmin} modify --attributes=-no-auth-data-reqd krbtgt/${R2}@${R} || exit 1 +${kinit} --password-file=${objdir}/foopassword foo@$R || { ec=1 ; eval "${testfailed}"; } +for a in $enctypes; do + echo "Getting cross realm tickets ($a)"; > messages.log + ${kgetcred} -e $a ${server2}@${R2} || { ec=1 ; eval "${testfailed}"; } + echo " checking we we got back right ticket" + ${klist} | grep ${server2}@ > /dev/null || { ec=1 ; eval "${testfailed}"; } + echo " checking if ticket is useful" + ${test_ap_req} --verify-pac ${server2}@${R2} ${keytab} ${cache} || \ { ec=1 ; eval "${testfailed}"; } ${kdestroy} --credential=${server2}@${R2} done