kdc: allow GSS error tokens in PA reply
If GSS_Accept_sec_context() returns an error status and error token, ensure we include the error token in the PA-GSS padata in the KRB-ERROR reply, rather than bailing out early.
This commit is contained in:
@@ -41,6 +41,8 @@
|
||||
#include "gss_preauth_authorizer_plugin.h"
|
||||
|
||||
struct gss_client_params {
|
||||
OM_uint32 major_status;
|
||||
OM_uint32 minor_status;
|
||||
gss_ctx_id_t context_handle;
|
||||
gss_name_t initiator_name;
|
||||
gss_OID mech_type;
|
||||
@@ -215,6 +217,8 @@ _kdc_gss_rd_padata(astgs_request_t r,
|
||||
goto out;
|
||||
}
|
||||
|
||||
gcp->major_status = GSS_S_NO_CONTEXT;
|
||||
|
||||
ret = pa_gss_get_context_state(r, gcp);
|
||||
if (ret)
|
||||
goto out;
|
||||
@@ -242,6 +246,10 @@ _kdc_gss_rd_padata(astgs_request_t r,
|
||||
&gcp->flags,
|
||||
&gcp->lifetime,
|
||||
NULL); /* delegated_cred_handle */
|
||||
|
||||
gcp->major_status = major;
|
||||
gcp->minor_status = minor;
|
||||
|
||||
if (GSS_ERROR(major)) {
|
||||
pa_gss_display_status(r, major, minor, gcp,
|
||||
"Failed to accept GSS security context");
|
||||
@@ -256,7 +264,7 @@ _kdc_gss_rd_padata(astgs_request_t r,
|
||||
goto out;
|
||||
}
|
||||
|
||||
*open = (major == GSS_S_COMPLETE);
|
||||
*open = (gcp->major_status == GSS_S_COMPLETE);
|
||||
|
||||
out:
|
||||
gss_release_cred(&minor, &cred);
|
||||
@@ -567,26 +575,7 @@ _kdc_gss_mk_pa_reply(astgs_request_t r,
|
||||
krb5_error_code ret;
|
||||
const KDC_REQ *req = &r->req;
|
||||
|
||||
OM_uint32 major, minor;
|
||||
int open;
|
||||
|
||||
major = gss_inquire_context(&minor,
|
||||
gcp->context_handle,
|
||||
NULL, /* initiator_name */
|
||||
NULL, /* target_name */
|
||||
NULL, /* lifetime_req */
|
||||
NULL, /* mech_type */
|
||||
NULL, /* ctx_flags */
|
||||
NULL, /* locally_initiated */
|
||||
&open);
|
||||
if (GSS_ERROR(major)) {
|
||||
pa_gss_display_status(r, major, minor, gcp,
|
||||
"Failed to inquire GSS context");
|
||||
ret = _krb5_gss_map_error(major, minor);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (open) {
|
||||
if (gcp->major_status == GSS_S_COMPLETE) {
|
||||
krb5_enctype enctype;
|
||||
uint32_t kfe = 0;
|
||||
krb5_keyblock *reply_key = NULL;
|
||||
@@ -611,23 +600,28 @@ _kdc_gss_mk_pa_reply(astgs_request_t r,
|
||||
krb5_free_keyblock_contents(r->context, &r->reply_key);
|
||||
r->reply_key = *reply_key;
|
||||
free(reply_key);
|
||||
} else {
|
||||
} else if (gcp->major_status == GSS_S_CONTINUE_NEEDED) {
|
||||
ret = pa_gss_set_context_state(r, gcp);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* only return padata in error case if we have an error token */
|
||||
if (!GSS_ERROR(gcp->major_status) || gcp->output_token.length) {
|
||||
ret = krb5_padata_add(r->context, &r->outpadata, KRB5_PADATA_GSS,
|
||||
gcp->output_token.value, gcp->output_token.length);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* token is now owned by outpadata */
|
||||
gcp->output_token.length = 0;
|
||||
gcp->output_token.value = NULL;
|
||||
|
||||
if (!open)
|
||||
if (gcp->major_status == GSS_S_CONTINUE_NEEDED)
|
||||
ret = KRB5_KDC_ERR_MORE_PREAUTH_DATA_REQUIRED;
|
||||
else
|
||||
ret = _krb5_gss_map_error(gcp->major_status, gcp->minor_status);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
|
@@ -514,14 +514,11 @@ pa_gss_validate(astgs_request_t r, const PA_DATA *pa)
|
||||
gss_client_params *gcp = NULL;
|
||||
char *client_name = NULL;
|
||||
krb5_error_code ret;
|
||||
int open;
|
||||
int open = 0;
|
||||
|
||||
ret = _kdc_gss_rd_padata(r, pa, &gcp, &open);
|
||||
if (ret) {
|
||||
_kdc_r_log(r, 4, "Failed to decode GSS PA-DATA -- %s",
|
||||
r->cname);
|
||||
goto out;
|
||||
}
|
||||
if (ret && gcp == NULL)
|
||||
return ret;
|
||||
|
||||
if (open) {
|
||||
ret = _kdc_gss_check_client(r, gcp, &client_name);
|
||||
|
Reference in New Issue
Block a user