diff --git a/kdc/bx509d.c b/kdc/bx509d.c index b03664911..6914fd854 100644 --- a/kdc/bx509d.c +++ b/kdc/bx509d.c @@ -882,6 +882,7 @@ set_req_desc(struct MHD_Connection *connection, r->req_life = 0; r->ret = 0; r->kv = heim_dict_create(10); + r->attributes = heim_dict_create(1); ci = MHD_get_connection_info(connection, MHD_CONNECTION_INFO_CLIENT_ADDRESS); if (ci) { diff --git a/kdc/gss_preauth.c b/kdc/gss_preauth.c index ce62a29af..c6719f3af 100644 --- a/kdc/gss_preauth.c +++ b/kdc/gss_preauth.c @@ -66,6 +66,9 @@ pa_gss_display_name(gss_name_t name, gss_buffer_t namebuf, gss_const_buffer_t *namebuf_p); +static void +pa_gss_dealloc_client_params(void *ptr); + /* * Create a checksum over KDC-REQ-BODY (without the nonce), used to * assert the request is invariant within the preauth conversation. @@ -421,7 +424,7 @@ _kdc_gss_rd_padata(astgs_request_t r, goto out; } - gcp = calloc(1, sizeof(*gcp)); + gcp = heim_alloc(sizeof(*gcp), "pa-gss-client-params", pa_gss_dealloc_client_params); if (gcp == NULL) { ret = krb5_enomem(r->context); goto out; @@ -471,7 +474,7 @@ out: if (gcp && gcp->major != GSS_S_NO_CONTEXT) *pgcp = gcp; else - _kdc_gss_free_client_param(r, gcp); + heim_release(gcp); return ret; } @@ -864,10 +867,10 @@ _kdc_gss_mk_composite_name_ad(astgs_request_t r, return ret; } -void -_kdc_gss_free_client_param(astgs_request_t r, - gss_client_params *gcp) +static void +pa_gss_dealloc_client_params(void *ptr) { + gss_client_params *gcp = ptr; OM_uint32 minor; if (gcp == NULL) @@ -879,7 +882,6 @@ _kdc_gss_free_client_param(astgs_request_t r, free_Checksum(&gcp->req_body_checksum); krb5_data_free(&gcp->pac_data); memset(gcp, 0, sizeof(*gcp)); - free(gcp); } krb5_error_code diff --git a/kdc/httpkadmind.c b/kdc/httpkadmind.c index b578075aa..d562764db 100644 --- a/kdc/httpkadmind.c +++ b/kdc/httpkadmind.c @@ -1529,6 +1529,7 @@ set_req_desc(struct MHD_Connection *connection, r->cname = NULL; r->addr = NULL; r->kv = heim_dict_create(10); + r->attributes = heim_dict_create(1); /* Our fields */ r->connection = connection; r->kadm_handle = NULL; diff --git a/kdc/kdc_locl.h b/kdc/kdc_locl.h index e7b86151d..2dc72cada 100644 --- a/kdc/kdc_locl.h +++ b/kdc/kdc_locl.h @@ -64,7 +64,6 @@ struct kdc_request_desc { HEIM_SVC_REQUEST_DESC_COMMON_ELEMENTS; }; -struct as_request_pa_state; struct kdc_patypes; struct astgs_request_desc { @@ -72,7 +71,6 @@ struct astgs_request_desc { /* Only AS */ const struct kdc_patypes *pa_used; - struct as_request_pa_state *pa_state; /* PA methods can affect both the reply key and the session key (pkinit) */ krb5_enctype sessionetype; diff --git a/kdc/kerberos5.c b/kdc/kerberos5.c index 864456ba8..88c34f32d 100644 --- a/kdc/kerberos5.c +++ b/kdc/kerberos5.c @@ -583,13 +583,13 @@ pa_gss_validate(astgs_request_t r, const PA_DATA *pa) goto out; } - heim_assert(r->pa_state == NULL, "already have PA state, should be NULL"); - r->pa_state = (struct as_request_pa_state *)gcp; - gcp = NULL; + ret = krb5_kdc_request_set_attribute((kdc_request_t)r, + HSTR("org.h5l.pa-gss-client-params"), gcp); + if (ret) + goto out; out: - if (gcp) - _kdc_gss_free_client_param(r, gcp); + heim_release(gcp); free(client_name); return ret; @@ -598,24 +598,15 @@ out: static krb5_error_code pa_gss_finalize_pac(astgs_request_t r) { - gss_client_params *gcp = (gss_client_params *)r->pa_state; + gss_client_params *gcp; + + gcp = krb5_kdc_request_get_attribute((kdc_request_t)r, HSTR("org.h5l.pa-gss-client-params")); heim_assert(gcp != NULL, "invalid GSS-API client params"); return _kdc_gss_finalize_pac(r, gcp); } -static void -pa_gss_cleanup(astgs_request_t r) -{ - gss_client_params *gcp = (gss_client_params *)r->pa_state; - - if (gcp) { - _kdc_gss_free_client_param(r, gcp); - r->pa_state = NULL; - } -} - static krb5_error_code pa_enc_chal_validate(astgs_request_t r, const PA_DATA *pa) { @@ -1009,7 +1000,7 @@ static const struct kdc_patypes pat[] = { { KRB5_PADATA_GSS , "GSS", PA_ANNOUNCE | PA_SYNTHETIC_OK | PA_REPLACE_REPLY_KEY, - pa_gss_validate, pa_gss_finalize_pac, pa_gss_cleanup + pa_gss_validate, pa_gss_finalize_pac, NULL }, }; diff --git a/kdc/libkdc-exports.def b/kdc/libkdc-exports.def index a8775c8a7..d7813e42a 100644 --- a/kdc/libkdc-exports.def +++ b/kdc/libkdc-exports.def @@ -16,6 +16,10 @@ EXPORTS krb5_kdc_save_request krb5_kdc_update_time krb5_kdc_pk_initialize + krb5_kdc_request_set_attribute + krb5_kdc_request_get_attribute + krb5_kdc_request_copy_attribute + krb5_kdc_request_delete_attribute _kdc_audit_addkv _kdc_audit_addkv_timediff _kdc_audit_getkv diff --git a/kdc/process.c b/kdc/process.c index 4f44877a5..34bd16dcd 100644 --- a/kdc/process.c +++ b/kdc/process.c @@ -359,7 +359,10 @@ process_request(krb5_context context, r->datagram_reply = datagram_reply; r->reply = reply; r->kv = heim_dict_create(10); - if (!r->kv) { + r->attributes = heim_dict_create(1); + if (r->kv == NULL || r->attributes == NULL) { + heim_release(r->kv); + heim_release(r->attributes); free(r); return krb5_enomem(context); } @@ -385,6 +388,7 @@ process_request(krb5_context context, heim_release(r->reason); heim_release(r->kv); + heim_release(r->attributes); free(r); return ret; } @@ -392,6 +396,7 @@ process_request(krb5_context context, heim_release(r->reason); heim_release(r->kv); + heim_release(r->attributes); free(r); return -1; } @@ -505,3 +510,27 @@ out: return 0; } + +krb5_error_code +krb5_kdc_request_set_attribute(kdc_request_t r, heim_object_t key, heim_object_t value) +{ + return heim_dict_set_value(r->attributes, key, value); +} + +heim_object_t +krb5_kdc_request_get_attribute(kdc_request_t r, heim_object_t key) +{ + return heim_dict_get_value(r->attributes, key); +} + +heim_object_t +krb5_kdc_request_copy_attribute(kdc_request_t r, heim_object_t key) +{ + return heim_dict_copy_value(r->attributes, key); +} + +void +krb5_kdc_request_delete_attribute(kdc_request_t r, heim_object_t key) +{ + heim_dict_delete_key(r->attributes, key); +} diff --git a/kdc/version-script.map b/kdc/version-script.map index f8918ae19..8325adb53 100644 --- a/kdc/version-script.map +++ b/kdc/version-script.map @@ -20,6 +20,10 @@ HEIMDAL_KDC_1.0 { krb5_kdc_save_request; krb5_kdc_update_time; krb5_kdc_pk_initialize; + krb5_kdc_request_set_attribute; + krb5_kdc_request_get_attribute; + krb5_kdc_request_copy_attribute; + krb5_kdc_request_delete_attribute; _kdc_audit_addkv; _kdc_audit_setkv_bool; _kdc_audit_setkv_number; diff --git a/lib/base/heimbase-svc.h b/lib/base/heimbase-svc.h index 0bec3635d..405a2975a 100644 --- a/lib/base/heimbase-svc.h +++ b/lib/base/heimbase-svc.h @@ -72,6 +72,7 @@ heim_string_t reason; \ /* auditing key/value store */ \ heim_dict_t kv; \ + heim_dict_t attributes; \ int32_t ret #endif /* HEIMBASE_SVC_H */ diff --git a/tests/plugin/kdc_test_plugin.c b/tests/plugin/kdc_test_plugin.c index 786030427..8b4c2cf88 100644 --- a/tests/plugin/kdc_test_plugin.c +++ b/tests/plugin/kdc_test_plugin.c @@ -106,20 +106,48 @@ static krb5_error_code KRB5_CALLCONV client_access(void *ctx, astgs_request_t r) { logit("client_access", r); + return 0; } static krb5_error_code KRB5_CALLCONV finalize_reply(void *ctx, astgs_request_t r) { + heim_number_t n; + krb5_error_code ret; + logit("finalize_reply", r); - return 0; + + n = heim_number_create(1234); + if (n == NULL) + return ENOMEM; + + ret = krb5_kdc_request_set_attribute((kdc_request_t)r, + HSTR("org.h5l.tests.kdc-plugin"), n); + heim_release(n); + + return ret; } static krb5_error_code KRB5_CALLCONV audit(void *ctx, astgs_request_t r) { + heim_number_t n; + logit("audit", r); + + if (r->ret) + return 0; /* finalize_reply only called in success */ + + n = krb5_kdc_request_get_attribute((kdc_request_t)r, + HSTR("org.h5l.tests.kdc-plugin")); + + heim_assert(n && heim_number_get_int(n) == 1234, + "attribute not passed from finalize_reply"); + + if (n == NULL || heim_number_get_int(n) != 1234) + return EINVAL; /* return value is ignored, but for completeness */ + return 0; }