From b0f0ed74e8f8e5ed715a9009b53627e7adfaaf02 Mon Sep 17 00:00:00 2001 From: Luke Howard Date: Thu, 30 Dec 2021 21:49:53 +1100 Subject: [PATCH] kdc: use attribute dictionary in altsec authorizer plugin --- kdc/altsecid_gss_preauth_authorizer.c | 68 ++++++++++++++++++--------- kdc/gss_preauth.c | 40 +++------------- kdc/gss_preauth_authorizer_plugin.h | 6 +-- 3 files changed, 55 insertions(+), 59 deletions(-) diff --git a/kdc/altsecid_gss_preauth_authorizer.c b/kdc/altsecid_gss_preauth_authorizer.c index 961ced0db..51ffdc6f8 100644 --- a/kdc/altsecid_gss_preauth_authorizer.c +++ b/kdc/altsecid_gss_preauth_authorizer.c @@ -272,7 +272,7 @@ ad_lookup(krb5_context context, gss_const_name_t initiator_name, gss_const_OID mech_type, krb5_principal *canon_principal, - krb5_data *requestor_sid) + heim_data_t *requestor_sid) { krb5_error_code ret; OM_uint32 minor; @@ -286,7 +286,8 @@ ad_lookup(krb5_context context, struct berval **values = NULL; *canon_principal = NULL; - krb5_data_zero(requestor_sid); + if (requestor_sid) + *requestor_sid = NULL; mech_type_str = gss_oid_to_name(mech_type); if (mech_type_str == NULL) { @@ -335,18 +336,6 @@ ad_lookup(krb5_context context, if (m0 == NULL) goto out; - if (requestor_sid) { - values = ldap_get_values_len(server->ld, m0, "objectSid"); - if (values == NULL || - ldap_count_values_len(values) == 0) - goto out; - - if (krb5_data_copy(requestor_sid, values[0]->bv_val, values[0]->bv_len) != 0) - goto enomem; - - ldap_value_free_len(values); - } - values = ldap_get_values_len(server->ld, m0, "sAMAccountName"); if (values == NULL || ldap_count_values_len(values) == 0) @@ -354,6 +343,22 @@ ad_lookup(krb5_context context, ret = krb5_make_principal(context, canon_principal, realm, values[0]->bv_val, NULL); + if (ret) + goto out; + + if (requestor_sid) { + ldap_value_free_len(values); + + values = ldap_get_values_len(server->ld, m0, "objectSid"); + if (values == NULL || + ldap_count_values_len(values) == 0) + goto out; + + *requestor_sid = heim_data_create(values[0]->bv_val, values[0]->bv_len); + if (*requestor_sid == NULL) + goto enomem; + } + goto out; enomem: @@ -361,6 +366,16 @@ enomem: goto out; out: + if (ret) { + krb5_free_principal(context, *canon_principal); + *canon_principal = NULL; + + if (requestor_sid) { + heim_release(*requestor_sid); + *requestor_sid = NULL; + } + } + ldap_value_free_len(values); ldap_msgfree(m); ldap_memfree(basedn); @@ -377,8 +392,7 @@ authorize(void *ctx, gss_const_OID mech_type, OM_uint32 ret_flags, krb5_boolean *authorized, - krb5_principal *mapped_name, - krb5_data *requestor_sid) + krb5_principal *mapped_name) { struct altsecid_gss_preauth_authorizer_context *c = ctx; struct ad_server_tuple *server = NULL; @@ -386,10 +400,10 @@ authorize(void *ctx, krb5_const_realm realm = krb5_principal_get_realm(r->context, r->client->entry.principal); krb5_boolean reconnect_p = FALSE; krb5_boolean is_tgs; + heim_data_t requestor_sid = NULL; *authorized = FALSE; *mapped_name = NULL; - krb5_data_zero(requestor_sid); if (!krb5_principal_is_federated(r->context, r->client->entry.principal) || (ret_flags & GSS_C_ANON_FLAG)) @@ -425,7 +439,7 @@ authorize(void *ctx, ret = ad_lookup(r->context, realm, server, initiator_name, mech_type, - mapped_name, is_tgs ? requestor_sid : NULL); + mapped_name, is_tgs ? &requestor_sid : NULL); if (ret == KRB5KDC_ERR_SVC_UNAVAILABLE) { ldap_unbind_ext_s(server->ld, NULL, NULL); server->ld = NULL; @@ -437,17 +451,27 @@ authorize(void *ctx, *authorized = (ret == 0); } while (reconnect_p); + if (requestor_sid) { + krb5_kdc_request_set_attribute((kdc_request_t)r, + HSTR("org.h5l.pac-requestor-sid"), requestor_sid); + heim_release(requestor_sid); + } + return ret; } static KRB5_LIB_CALL krb5_error_code -finalize_pac(void *ctx, astgs_request_t r, krb5_data *requestor_sid) +finalize_pac(void *ctx, astgs_request_t r) { - if (requestor_sid->length == 0) + heim_data_t requestor_sid; + + requestor_sid = krb5_kdc_request_get_attribute((kdc_request_t)r, + HSTR("org.h5l.pac-requestor-sid")); + if (requestor_sid == NULL) return 0; - return krb5_pac_add_buffer(r->context, r->pac, - PAC_REQUESTOR_SID, requestor_sid); + return krb5_pac_add_buffer(r->context, r->pac, PAC_REQUESTOR_SID, + heim_data_get_data(requestor_sid)); } static KRB5_LIB_CALL krb5_error_code diff --git a/kdc/gss_preauth.c b/kdc/gss_preauth.c index c6719f3af..626227e26 100644 --- a/kdc/gss_preauth.c +++ b/kdc/gss_preauth.c @@ -51,7 +51,6 @@ struct gss_client_params { OM_uint32 flags; OM_uint32 lifetime; krb5_checksum req_body_checksum; - krb5_data pac_data; }; static void @@ -501,7 +500,6 @@ struct pa_gss_authorize_plugin_ctx { struct gss_client_params *gcp; krb5_boolean authorized; krb5_principal initiator_princ; - krb5_data pac_data; }; static krb5_error_code KRB5_LIB_CALL @@ -519,8 +517,7 @@ pa_gss_authorize_cb(krb5_context context, pa_gss_authorize_plugin_ctx->gcp->mech_type, pa_gss_authorize_plugin_ctx->gcp->flags, &pa_gss_authorize_plugin_ctx->authorized, - &pa_gss_authorize_plugin_ctx->initiator_princ, - &pa_gss_authorize_plugin_ctx->pac_data); + &pa_gss_authorize_plugin_ctx->initiator_princ); } static const char *plugin_deps[] = { @@ -545,8 +542,7 @@ pa_gss_authorize_plugin(astgs_request_t r, struct gss_client_params *gcp, gss_const_buffer_t display_name, krb5_boolean *authorized, - krb5_principal *initiator_princ, - krb5_data *pac_data) + krb5_principal *initiator_princ) { krb5_error_code ret; struct pa_gss_authorize_plugin_ctx ctx; @@ -555,7 +551,6 @@ pa_gss_authorize_plugin(astgs_request_t r, ctx.gcp = gcp; ctx.authorized = 0; ctx.initiator_princ = NULL; - krb5_data_zero(&ctx.pac_data); krb5_clear_error_message(r->context); ret = _krb5_plugin_run_f(r->context, &gss_preauth_authorizer_data, @@ -576,7 +571,6 @@ pa_gss_authorize_plugin(astgs_request_t r, *authorized = ctx.authorized; *initiator_princ = ctx.initiator_princ; - *pac_data = ctx.pac_data; return ret; } @@ -586,8 +580,7 @@ pa_gss_authorize_default(astgs_request_t r, struct gss_client_params *gcp, gss_const_buffer_t display_name, krb5_boolean *authorized, - krb5_principal *initiator_princ, - krb5_data *pac_data) + krb5_principal *initiator_princ) { krb5_error_code ret; krb5_principal principal; @@ -689,14 +682,12 @@ _kdc_gss_check_client(astgs_request_t r, krb5_principal initiator_princ = NULL; hdb_entry_ex *initiator = NULL; krb5_boolean authorized = FALSE; - krb5_data pac_data; OM_uint32 minor; gss_buffer_desc display_name = GSS_C_EMPTY_BUFFER; gss_const_buffer_t display_name_p; *client_name = NULL; - krb5_data_zero(&pac_data); pa_gss_display_name(gcp->initiator_name, &display_name, &display_name_p); @@ -705,10 +696,10 @@ _kdc_gss_check_client(astgs_request_t r, * are authorized as the directly corresponding Kerberos principal. */ ret = pa_gss_authorize_plugin(r, gcp, display_name_p, - &authorized, &initiator_princ, &pac_data); + &authorized, &initiator_princ); if (ret == KRB5_PLUGIN_NO_HANDLE) ret = pa_gss_authorize_default(r, gcp, display_name_p, - &authorized, &initiator_princ, &pac_data); + &authorized, &initiator_princ); if (ret == 0 && !authorized) ret = KRB5_KDC_ERR_CLIENT_NAME_MISMATCH; if (ret) @@ -766,14 +757,10 @@ _kdc_gss_check_client(astgs_request_t r, goto out; } - gcp->pac_data = pac_data; - krb5_data_zero(&pac_data); - out: krb5_free_principal(r->context, initiator_princ); if (initiator) _kdc_free_ent(r->context, initiator); - krb5_data_free(&pac_data); gss_release_buffer(&minor, &display_name); return ret; @@ -880,7 +867,6 @@ pa_gss_dealloc_client_params(void *ptr) gss_release_name(&minor, &gcp->initiator_name); gss_release_buffer(&minor, &gcp->output_token); free_Checksum(&gcp->req_body_checksum); - krb5_data_free(&gcp->pac_data); memset(gcp, 0, sizeof(*gcp)); } @@ -1015,11 +1001,6 @@ pa_gss_display_name(gss_name_t name, *namebuf_p = namebuf; } -struct pa_gss_finalize_pac_plugin_ctx { - astgs_request_t r; - krb5_data *pac_data; -}; - static krb5_error_code KRB5_LIB_CALL pa_gss_finalize_pac_cb(krb5_context context, const void *plug, @@ -1027,11 +1008,8 @@ pa_gss_finalize_pac_cb(krb5_context context, void *userctx) { const krb5plugin_gss_preauth_authorizer_ftable *authorizer = plug; - struct pa_gss_finalize_pac_plugin_ctx *pa_gss_finalize_pac_ctx = userctx; - return authorizer->finalize_pac(plugctx, - pa_gss_finalize_pac_ctx->r, - pa_gss_finalize_pac_ctx->pac_data); + return authorizer->finalize_pac(plugctx, userctx); } @@ -1040,14 +1018,10 @@ _kdc_gss_finalize_pac(astgs_request_t r, gss_client_params *gcp) { krb5_error_code ret; - struct pa_gss_finalize_pac_plugin_ctx ctx; - - ctx.r = r; - ctx.pac_data = &gcp->pac_data; krb5_clear_error_message(r->context); ret = _krb5_plugin_run_f(r->context, &gss_preauth_authorizer_data, - 0, &ctx, pa_gss_finalize_pac_cb); + 0, r, pa_gss_finalize_pac_cb); if (ret == KRB5_PLUGIN_NO_HANDLE) ret = 0; diff --git a/kdc/gss_preauth_authorizer_plugin.h b/kdc/gss_preauth_authorizer_plugin.h index 69bd5fc1a..293e59da4 100644 --- a/kdc/gss_preauth_authorizer_plugin.h +++ b/kdc/gss_preauth_authorizer_plugin.h @@ -69,11 +69,9 @@ typedef struct krb5plugin_gss_preauth_authorizer_ftable_desc { gss_const_OID, /*mech_type*/ OM_uint32, /*ret_flags*/ krb5_boolean *, /*authorized*/ - krb5_principal *, /*mapped_name*/ - krb5_data *); /*pac_data*/ + krb5_principal *); /*mapped_name*/ krb5_error_code (KRB5_LIB_CALL *finalize_pac)(void *, /*plug_ctx*/ - astgs_request_t, /*r*/ - krb5_data *); /*pac_data*/ + astgs_request_t); /*r*/ } krb5plugin_gss_preauth_authorizer_ftable; #endif /* HEIMDAL_KDC_GSS_PREAUTH_AUTHORIZER_PLUGIN_H */