From 75ab6bb518945865d649356c271923dbf6f7a637 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Aug 2017 15:33:17 +0200 Subject: [PATCH 1/6] lib/krb5: add krb5_rd_req_in_set_verify_ap_req_flags() In the next commits we want to be able to pass down things like KRB5_VERIFY_AP_REQ_NO_TRANSITED_CHECK. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12907 Signed-off-by: Stefan Metzmacher --- lib/krb5/rd_req.c | 18 ++++++++++++++++-- lib/krb5/version-script.map | 1 + 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/krb5/rd_req.c b/lib/krb5/rd_req.c index fbced144e72..98dd2dbf256 100644 --- a/lib/krb5/rd_req.c +++ b/lib/krb5/rd_req.c @@ -481,6 +481,7 @@ struct krb5_rd_req_in_ctx_data { krb5_keytab keytab; krb5_keyblock *keyblock; krb5_boolean check_pac; + krb5_flags verify_ap_req_flags; }; struct krb5_rd_req_out_ctx_data { @@ -536,6 +537,15 @@ krb5_rd_req_in_set_keytab(krb5_context context, return 0; } +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_rd_req_in_set_verify_ap_req_flags(krb5_context context, + krb5_rd_req_in_ctx in, + krb5_flags flags) +{ + in->verify_ap_req_flags = flags; + return 0; +} + /** * Set if krb5_rq_red() is going to check the Windows PAC or not * @@ -821,6 +831,7 @@ krb5_rd_req_ctx(krb5_context context, krb5_rd_req_out_ctx o = NULL; krb5_keytab id = NULL, keytab = NULL; krb5_principal service = NULL; + krb5_flags verify_ap_req_flags = 0; *outctx = NULL; @@ -858,6 +869,9 @@ krb5_rd_req_ctx(krb5_context context, if (inctx && inctx->keytab) id = inctx->keytab; + if (inctx) + verify_ap_req_flags = inctx->verify_ap_req_flags; + if((*auth_context)->keyblock){ ret = krb5_copy_keyblock(context, (*auth_context)->keyblock, @@ -915,7 +929,7 @@ krb5_rd_req_ctx(krb5_context context, &ap_req, server, o->keyblock, - 0, + verify_ap_req_flags, &o->ap_req_options, &o->ticket, KRB5_KU_AP_REQ_AUTH); @@ -963,7 +977,7 @@ krb5_rd_req_ctx(krb5_context context, &ap_req, server, &entry.keyblock, - 0, + verify_ap_req_flags, &o->ap_req_options, &o->ticket, KRB5_KU_AP_REQ_AUTH); diff --git a/lib/krb5/version-script.map b/lib/krb5/version-script.map index 023f9bd6820..9b202c36edd 100644 --- a/lib/krb5/version-script.map +++ b/lib/krb5/version-script.map @@ -529,6 +529,7 @@ HEIMDAL_KRB5_2.0 { krb5_rd_req_in_set_keyblock; krb5_rd_req_in_set_keytab; krb5_rd_req_in_set_pac_check; + krb5_rd_req_in_set_verify_ap_req_flags; krb5_rd_req_out_ctx_free; krb5_rd_req_out_get_ap_req_options; krb5_rd_req_out_get_keyblock; -- 2.17.1 From ddbeb8a53fc9a8989ba9694c2f8f1b2ccce632a5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Aug 2017 15:33:17 +0200 Subject: [PATCH 2/6] lib/krb5: add KRB5_VERIFY_AP_REQ_NO_TRANSITED_CHECK In active directory a domain member replies on (trusts) the [K]DCs of the domain. It's the job of the [K]DCs to only generate useful tickets as they know about the trust topology. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12907 Signed-off-by: Stefan Metzmacher --- lib/krb5/krb5.h | 1 + lib/krb5/rd_req.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/krb5/krb5.h b/lib/krb5/krb5.h index ea32052f0a7..43fdf947322 100644 --- a/lib/krb5/krb5.h +++ b/lib/krb5/krb5.h @@ -442,6 +442,7 @@ typedef union { /* flags for krb5_verify_ap_req */ #define KRB5_VERIFY_AP_REQ_IGNORE_INVALID (1 << 0) +#define KRB5_VERIFY_AP_REQ_NO_TRANSITED_CHECK (1 << 1) #define KRB5_GC_CACHED (1U << 0) #define KRB5_GC_USER_USER (1U << 1) diff --git a/lib/krb5/rd_req.c b/lib/krb5/rd_req.c index 98dd2dbf256..a3993826145 100644 --- a/lib/krb5/rd_req.c +++ b/lib/krb5/rd_req.c @@ -220,7 +220,8 @@ krb5_decrypt_ticket(krb5_context context, return KRB5KRB_AP_ERR_TKT_EXPIRED; } - if(!t.flags.transited_policy_checked) { + if(!t.flags.transited_policy_checked + && !(flags & KRB5_VERIFY_AP_REQ_NO_TRANSITED_CHECK)) { ret = check_transited(context, ticket, &t); if(ret) { free_EncTicketPart(&t); -- 2.17.1 From 8abc8be36622c172ab82abeddcd51705f1d1f4d4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Aug 2017 15:33:17 +0200 Subject: [PATCH 3/6] lib/gssapi/krb5: add GSS_KRB5_CRED_NO_TRANSIT_CHECK_X This allows KRB5_GC_NO_TRANSIT_CHECK (on the initiator) and KRB5_VERIFY_AP_REQ_NO_TRANSITED_CHECK (on the acceptor) to be controlled via the gssapi layer. BUG: https://bugzilla.samba.org/show_bug.cgi?id=12907 Signed-off-by: Stefan Metzmacher --- lib/gssapi/gssapi/gssapi_oid.h | 3 +++ lib/gssapi/krb5/accept_sec_context.c | 11 ++++++++++- lib/gssapi/krb5/gsskrb5_locl.h | 1 + lib/gssapi/krb5/init_sec_context.c | 12 +++++++++--- lib/gssapi/krb5/set_cred_option.c | 24 ++++++++++++++++++++++++ lib/gssapi/mech/gss_oid.c | 3 +++ lib/gssapi/version-script.map | 1 + 7 files changed, 51 insertions(+), 4 deletions(-) diff --git a/lib/gssapi/gssapi/gssapi_oid.h b/lib/gssapi/gssapi/gssapi_oid.h index 30ffbe4adb3..1a619cfd167 100644 --- a/lib/gssapi/gssapi/gssapi_oid.h +++ b/lib/gssapi/gssapi/gssapi_oid.h @@ -96,6 +96,9 @@ extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_c_ntlm_force_v1_oid_desc; extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_cred_no_ci_flags_x_oid_desc; #define GSS_KRB5_CRED_NO_CI_FLAGS_X (&__gss_krb5_cred_no_ci_flags_x_oid_desc) +extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_cred_no_transit_check_x_oid_desc; +#define GSS_KRB5_CRED_NO_TRANSIT_CHECK_X (&__gss_krb5_cred_no_transit_check_x_oid_desc) + extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_import_cred_x_oid_desc; #define GSS_KRB5_IMPORT_CRED_X (&__gss_krb5_import_cred_x_oid_desc) diff --git a/lib/gssapi/krb5/accept_sec_context.c b/lib/gssapi/krb5/accept_sec_context.c index d4680e9e8fb..42482c51f1f 100644 --- a/lib/gssapi/krb5/accept_sec_context.c +++ b/lib/gssapi/krb5/accept_sec_context.c @@ -412,13 +412,22 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status, krb5_rd_req_in_ctx in = NULL; krb5_rd_req_out_ctx out = NULL; krb5_principal server = NULL; + krb5_flags verify_ap_req_flags = 0; - if (acceptor_cred) + if (acceptor_cred) { server = acceptor_cred->principal; + if (acceptor_cred->cred_flags & GSS_CF_NO_TRANSIT_CHECK) { + verify_ap_req_flags |= KRB5_VERIFY_AP_REQ_NO_TRANSITED_CHECK; + } + } + kret = krb5_rd_req_in_ctx_alloc(context, &in); if (kret == 0) kret = krb5_rd_req_in_set_keytab(context, in, keytab); + if (kret == 0) + kret = krb5_rd_req_in_set_verify_ap_req_flags(context, in, + verify_ap_req_flags); if (kret) { if (in) krb5_rd_req_in_ctx_free(context, in); diff --git a/lib/gssapi/krb5/gsskrb5_locl.h b/lib/gssapi/krb5/gsskrb5_locl.h index 555d095de88..072260bcf13 100644 --- a/lib/gssapi/krb5/gsskrb5_locl.h +++ b/lib/gssapi/krb5/gsskrb5_locl.h @@ -94,6 +94,7 @@ typedef struct { int cred_flags; #define GSS_CF_DESTROY_CRED_ON_RELEASE 1 #define GSS_CF_NO_CI_FLAGS 2 +#define GSS_CF_NO_TRANSIT_CHECK 4 struct krb5_keytab_data *keytab; time_t endtime; gss_cred_usage_t usage; diff --git a/lib/gssapi/krb5/init_sec_context.c b/lib/gssapi/krb5/init_sec_context.c index 4ef5c9c7123..0053b76381a 100644 --- a/lib/gssapi/krb5/init_sec_context.c +++ b/lib/gssapi/krb5/init_sec_context.c @@ -205,6 +205,7 @@ gsskrb5_get_creds( OM_uint32 * minor_status, krb5_context context, krb5_ccache ccache, + krb5_flags options, gsskrb5_ctx ctx, gss_const_name_t target_name, OM_uint32 time_req, @@ -245,7 +246,7 @@ gsskrb5_get_creds( this_cred.session.keytype = KEYTYPE_NULL; kret = krb5_get_credentials(context, - 0, + options, ccache, &this_cred, &ctx->kcred); @@ -393,6 +394,7 @@ init_auth krb5_error_code kret; krb5_data fwd_data; OM_uint32 lifetime_rec; + krb5_flags options = 0; krb5_data_zero(&fwd_data); @@ -409,8 +411,12 @@ init_auth goto failure; } ctx->more_flags |= CLOSE_CCACHE; - } else + } else { ctx->ccache = cred->ccache; + if (cred->cred_flags & GSS_CF_NO_TRANSIT_CHECK) { + options |= KRB5_GC_NO_TRANSIT_CHECK; + } + } kret = krb5_cc_get_principal (context, ctx->ccache, &ctx->source); if (kret) { @@ -428,7 +434,7 @@ init_auth krb5_set_default_in_tkt_etypes(context, cred->enctypes); ret = gsskrb5_get_creds(minor_status, context, ctx->ccache, - ctx, name, time_req, time_rec); + options, ctx, name, time_req, time_rec); if (ret) goto failure; diff --git a/lib/gssapi/krb5/set_cred_option.c b/lib/gssapi/krb5/set_cred_option.c index 1411f866563..e59568c9bd0 100644 --- a/lib/gssapi/krb5/set_cred_option.c +++ b/lib/gssapi/krb5/set_cred_option.c @@ -217,6 +217,26 @@ no_ci_flags(OM_uint32 *minor_status, } +static OM_uint32 +no_transit_check(OM_uint32 *minor_status, + krb5_context context, + gss_cred_id_t *cred_handle, + const gss_buffer_t value) +{ + gsskrb5_cred cred; + + if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL) { + *minor_status = 0; + return GSS_S_FAILURE; + } + + cred = (gsskrb5_cred)*cred_handle; + cred->cred_flags |= GSS_CF_NO_TRANSIT_CHECK; + + *minor_status = 0; + return GSS_S_COMPLETE; +} + OM_uint32 GSSAPI_CALLCONV _gsskrb5_set_cred_option (OM_uint32 *minor_status, @@ -244,6 +264,10 @@ _gsskrb5_set_cred_option } + if (gss_oid_equal(desired_object, GSS_KRB5_CRED_NO_TRANSIT_CHECK_X)) { + return no_transit_check(minor_status, context, cred_handle, value); + } + *minor_status = EINVAL; return GSS_S_FAILURE; } diff --git a/lib/gssapi/mech/gss_oid.c b/lib/gssapi/mech/gss_oid.c index 5b9bd362360..e8973d6fdd3 100644 --- a/lib/gssapi/mech/gss_oid.c +++ b/lib/gssapi/mech/gss_oid.c @@ -94,6 +94,9 @@ gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_cred_no_ci_flags_x_oid_desc = { 6, r /* GSS_KRB5_IMPORT_CRED_X - 1.2.752.43.13.30 */ gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_import_cred_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x1e") }; +/* GSS_KRB5_CRED_NO_TRANSIT_CHECK_X - 1.2.752.43.13.31 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_cred_no_transit_check_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x1f") }; + /* GSS_C_MA_SASL_MECH_NAME - 1.2.752.43.13.100 */ gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_sasl_mech_name_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x64") }; diff --git a/lib/gssapi/version-script.map b/lib/gssapi/version-script.map index 3265970344f..ce85b402dc8 100644 --- a/lib/gssapi/version-script.map +++ b/lib/gssapi/version-script.map @@ -161,6 +161,7 @@ HEIMDAL_GSS_2.0 { __gss_c_ntlm_session_key_oid_desc; __gss_c_ntlm_force_v1_oid_desc; __gss_krb5_cred_no_ci_flags_x_oid_desc; + __gss_krb5_cred_no_transit_check_x_oid_desc; __gss_krb5_import_cred_x_oid_desc; __gss_c_ma_sasl_mech_name_oid_desc; __gss_c_ma_mech_name_oid_desc; -- 2.17.1 From 83fd10a8e980a7ffa9299ac880ba992589f45041 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 20 Jul 2019 10:15:04 +0000 Subject: [PATCH 4/6] lib/krb5: let krb5_rd_req_ctx() fallback only on KRB5KRB_AP_ERR_BAD_INTEGRITY This avoids hidding a real error like KRB5KRB_AP_ERR_ILL_CR_TKT. We only want to retry with the next key if the decryption failed. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14125 Signed-off-by: Stefan Metzmacher --- lib/krb5/rd_req.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/krb5/rd_req.c b/lib/krb5/rd_req.c index a3993826145..dd0352791cb 100644 --- a/lib/krb5/rd_req.c +++ b/lib/krb5/rd_req.c @@ -982,10 +982,15 @@ krb5_rd_req_ctx(krb5_context context, &o->ap_req_options, &o->ticket, KRB5_KU_AP_REQ_AUTH); - if (ret) { + if (ret == KRB5KRB_AP_ERR_BAD_INTEGRITY) { + /* failed to decrypt, try the next key */ krb5_kt_free_entry (context, &entry); continue; } + if (ret) { + krb5_kt_free_entry (context, &entry); + break; + } /* * Found a match, save the keyblock for PAC processing, -- 2.17.1 From 4a7ad28148b53791eb3660879166d4a302481b0f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 20 Jul 2019 10:15:04 +0000 Subject: [PATCH 5/6] lib/krb5: add krb5_rd_req_in_set_iterate_keytab() A caller might not know the kvno maintained by the KDC. And most often there's need to know it. So this function makes it possible to force the keytab iteration in order to get a consistent behavior. Otherwise it's possible to get a different behavior if the guessed kvno in the keytab accidentally matches the kvno of the ticket and we'll give up if the key is not able to decrypt the ticket. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14125 Signed-off-by: Stefan Metzmacher --- lib/krb5/rd_req.c | 27 +++++++++++++++++++++++++++ lib/krb5/version-script.map | 1 + 2 files changed, 28 insertions(+) diff --git a/lib/krb5/rd_req.c b/lib/krb5/rd_req.c index dd0352791cb..5426dd70040 100644 --- a/lib/krb5/rd_req.c +++ b/lib/krb5/rd_req.c @@ -480,6 +480,7 @@ krb5_verify_ap_req2(krb5_context context, struct krb5_rd_req_in_ctx_data { krb5_keytab keytab; + krb5_boolean iterate_keytab; krb5_keyblock *keyblock; krb5_boolean check_pac; krb5_flags verify_ap_req_flags; @@ -547,6 +548,27 @@ krb5_rd_req_in_set_verify_ap_req_flags(krb5_context context, return 0; } +/** + * Set if krb5_rq_red() is going to iterate the keytab to find a key + * + * @param context Keberos 5 context. + * @param in krb5_rd_req_in_ctx to check the option on. + * @param flag flag to select if the keytab should be iterated (TRUE) or not (FALSE). + * + * @return Kerberos 5 error code, see krb5_get_error_message(). + * + * @ingroup krb5_auth + */ + +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_rd_req_in_set_iterate_keytab(krb5_context context, + krb5_rd_req_in_ctx in, + krb5_boolean flag) +{ + in->iterate_keytab = flag; + return 0; +} + /** * Set if krb5_rq_red() is going to check the Windows PAC or not * @@ -885,6 +907,11 @@ krb5_rd_req_ctx(krb5_context context, &o->keyblock); if (ret) goto out; + } else if (id && inctx && inctx->iterate_keytab) { + /* + * Force iterating over the keytab. + */ + o->keyblock = NULL; } else { if(id == NULL) { diff --git a/lib/krb5/version-script.map b/lib/krb5/version-script.map index 9b202c36edd..5d2db0c3589 100644 --- a/lib/krb5/version-script.map +++ b/lib/krb5/version-script.map @@ -526,6 +526,7 @@ HEIMDAL_KRB5_2.0 { krb5_rd_req_ctx; krb5_rd_req_in_ctx_alloc; krb5_rd_req_in_ctx_free; + krb5_rd_req_in_set_iterate_keytab; krb5_rd_req_in_set_keyblock; krb5_rd_req_in_set_keytab; krb5_rd_req_in_set_pac_check; -- 2.17.1 From ea5ab863ab5121fa4628b71c8422c8b8600eb798 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Aug 2019 10:30:01 +0200 Subject: [PATCH 6/6] lib/gssapi/krb5: add GSS_KRB5_CRED_ITERATE_ACCEPTOR_KEYTAB_X This allows krb5_rd_req_in_set_iterate_keytab() to be used via the gssapi layer. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14125 Signed-off-by: Stefan Metzmacher --- lib/gssapi/gssapi/gssapi_oid.h | 3 +++ lib/gssapi/krb5/accept_sec_context.c | 7 +++++++ lib/gssapi/krb5/gsskrb5_locl.h | 1 + lib/gssapi/krb5/set_cred_option.c | 22 ++++++++++++++++++++++ lib/gssapi/mech/gss_oid.c | 3 +++ lib/gssapi/version-script.map | 1 + 6 files changed, 37 insertions(+) diff --git a/lib/gssapi/gssapi/gssapi_oid.h b/lib/gssapi/gssapi/gssapi_oid.h index 1a619cfd167..ecfcd8e5520 100644 --- a/lib/gssapi/gssapi/gssapi_oid.h +++ b/lib/gssapi/gssapi/gssapi_oid.h @@ -99,6 +99,9 @@ extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_cred_no_ci_flags_x_oid_desc; extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_cred_no_transit_check_x_oid_desc; #define GSS_KRB5_CRED_NO_TRANSIT_CHECK_X (&__gss_krb5_cred_no_transit_check_x_oid_desc) +extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_cred_iterate_acceptor_keytab_x_oid_desc; +#define GSS_KRB5_CRED_ITERATE_ACCEPTOR_KEYTAB_X (&__gss_krb5_cred_iterate_acceptor_keytab_x_oid_desc) + extern GSSAPI_LIB_VARIABLE gss_OID_desc __gss_krb5_import_cred_x_oid_desc; #define GSS_KRB5_IMPORT_CRED_X (&__gss_krb5_import_cred_x_oid_desc) diff --git a/lib/gssapi/krb5/accept_sec_context.c b/lib/gssapi/krb5/accept_sec_context.c index 42482c51f1f..37786934850 100644 --- a/lib/gssapi/krb5/accept_sec_context.c +++ b/lib/gssapi/krb5/accept_sec_context.c @@ -412,11 +412,16 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status, krb5_rd_req_in_ctx in = NULL; krb5_rd_req_out_ctx out = NULL; krb5_principal server = NULL; + krb5_boolean iterate_keytab = FALSE; krb5_flags verify_ap_req_flags = 0; if (acceptor_cred) { server = acceptor_cred->principal; + if (acceptor_cred->cred_flags & GSS_CF_ITERATE_ACCEPTOR_KEYTAB) { + iterate_keytab = TRUE; + } + if (acceptor_cred->cred_flags & GSS_CF_NO_TRANSIT_CHECK) { verify_ap_req_flags |= KRB5_VERIFY_AP_REQ_NO_TRANSITED_CHECK; } @@ -425,6 +430,8 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status, kret = krb5_rd_req_in_ctx_alloc(context, &in); if (kret == 0) kret = krb5_rd_req_in_set_keytab(context, in, keytab); + if (kret == 0 && iterate_keytab) + kret = krb5_rd_req_in_set_iterate_keytab(context, in, TRUE); if (kret == 0) kret = krb5_rd_req_in_set_verify_ap_req_flags(context, in, verify_ap_req_flags); diff --git a/lib/gssapi/krb5/gsskrb5_locl.h b/lib/gssapi/krb5/gsskrb5_locl.h index 072260bcf13..92501fc4900 100644 --- a/lib/gssapi/krb5/gsskrb5_locl.h +++ b/lib/gssapi/krb5/gsskrb5_locl.h @@ -95,6 +95,7 @@ typedef struct { #define GSS_CF_DESTROY_CRED_ON_RELEASE 1 #define GSS_CF_NO_CI_FLAGS 2 #define GSS_CF_NO_TRANSIT_CHECK 4 +#define GSS_CF_ITERATE_ACCEPTOR_KEYTAB 8 struct krb5_keytab_data *keytab; time_t endtime; gss_cred_usage_t usage; diff --git a/lib/gssapi/krb5/set_cred_option.c b/lib/gssapi/krb5/set_cred_option.c index e59568c9bd0..9aec0203671 100644 --- a/lib/gssapi/krb5/set_cred_option.c +++ b/lib/gssapi/krb5/set_cred_option.c @@ -216,6 +216,25 @@ no_ci_flags(OM_uint32 *minor_status, } +static OM_uint32 +iterate_acceptor_keytab(OM_uint32 *minor_status, + krb5_context context, + gss_cred_id_t *cred_handle, + const gss_buffer_t value) +{ + gsskrb5_cred cred; + + if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL) { + *minor_status = 0; + return GSS_S_FAILURE; + } + + cred = (gsskrb5_cred)*cred_handle; + cred->cred_flags |= GSS_CF_ITERATE_ACCEPTOR_KEYTAB; + + *minor_status = 0; + return GSS_S_COMPLETE; +} static OM_uint32 no_transit_check(OM_uint32 *minor_status, @@ -263,6 +282,9 @@ _gsskrb5_set_cred_option return no_ci_flags(minor_status, context, cred_handle, value); } + if (gss_oid_equal(desired_object, GSS_KRB5_CRED_ITERATE_ACCEPTOR_KEYTAB_X)) { + return iterate_acceptor_keytab(minor_status, context, cred_handle, value); + } if (gss_oid_equal(desired_object, GSS_KRB5_CRED_NO_TRANSIT_CHECK_X)) { return no_transit_check(minor_status, context, cred_handle, value); diff --git a/lib/gssapi/mech/gss_oid.c b/lib/gssapi/mech/gss_oid.c index e8973d6fdd3..4bd59b6d974 100644 --- a/lib/gssapi/mech/gss_oid.c +++ b/lib/gssapi/mech/gss_oid.c @@ -97,6 +97,9 @@ gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_import_cred_x_oid_desc = { 6, rk_UNC /* GSS_KRB5_CRED_NO_TRANSIT_CHECK_X - 1.2.752.43.13.31 */ gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_cred_no_transit_check_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x1f") }; +/* GSS_KRB5_CRED_ITERATE_ACCEPTOR_KEYTAB_X - 1.2.752.43.13.32 */ +gss_OID_desc GSSAPI_LIB_VARIABLE __gss_krb5_cred_iterate_acceptor_keytab_x_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x20") }; + /* GSS_C_MA_SASL_MECH_NAME - 1.2.752.43.13.100 */ gss_OID_desc GSSAPI_LIB_VARIABLE __gss_c_ma_sasl_mech_name_oid_desc = { 6, rk_UNCONST("\x2a\x85\x70\x2b\x0d\x64") }; diff --git a/lib/gssapi/version-script.map b/lib/gssapi/version-script.map index ce85b402dc8..c7cda5adcb1 100644 --- a/lib/gssapi/version-script.map +++ b/lib/gssapi/version-script.map @@ -160,6 +160,7 @@ HEIMDAL_GSS_2.0 { __gss_c_ntlm_v2_oid_desc; __gss_c_ntlm_session_key_oid_desc; __gss_c_ntlm_force_v1_oid_desc; + __gss_krb5_cred_iterate_acceptor_keytab_x_oid_desc; __gss_krb5_cred_no_ci_flags_x_oid_desc; __gss_krb5_cred_no_transit_check_x_oid_desc; __gss_krb5_import_cred_x_oid_desc; -- 2.17.1