|
Packit Service |
9f2c4a |
/* Copyright (C) 2011 the GSS-PROXY contributors, see COPYING for license */
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
#include "gp_rpc_process.h"
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
int gp_accept_sec_context(struct gp_call_ctx *gpcall,
|
|
Packit Service |
9f2c4a |
union gp_rpc_arg *arg,
|
|
Packit Service |
9f2c4a |
union gp_rpc_res *res)
|
|
Packit Service |
9f2c4a |
{
|
|
Packit Service |
9f2c4a |
struct gssx_arg_accept_sec_context *asca;
|
|
Packit Service |
9f2c4a |
struct gssx_res_accept_sec_context *ascr;
|
|
Packit Service |
9f2c4a |
uint32_t ret_maj;
|
|
Packit Service |
9f2c4a |
uint32_t ret_min;
|
|
Packit Service |
9f2c4a |
gss_ctx_id_t ctx = GSS_C_NO_CONTEXT;
|
|
Packit Service |
9f2c4a |
gss_cred_id_t ach = GSS_C_NO_CREDENTIAL;
|
|
Packit Service |
9f2c4a |
gss_buffer_desc ibuf;
|
|
Packit Service |
9f2c4a |
struct gss_channel_bindings_struct cbs;
|
|
Packit Service |
9f2c4a |
gss_channel_bindings_t pcbs;
|
|
Packit Service |
9f2c4a |
gss_name_t src_name = GSS_C_NO_NAME;
|
|
Packit Service |
9f2c4a |
gss_OID oid = GSS_C_NO_OID;
|
|
Packit Service |
9f2c4a |
gss_buffer_desc obuf = GSS_C_EMPTY_BUFFER;
|
|
Packit Service |
9f2c4a |
uint32_t ret_flags;
|
|
Packit Service |
9f2c4a |
gss_cred_id_t dch = GSS_C_NO_CREDENTIAL;
|
|
Packit Service |
9f2c4a |
gss_cred_id_t *pdch = NULL;
|
|
Packit Service |
9f2c4a |
int exp_ctx_type;
|
|
Packit Service |
9f2c4a |
int exp_creds_type;
|
|
Packit Service |
9f2c4a |
uint32_t acpt_maj;
|
|
Packit Service |
9f2c4a |
uint32_t acpt_min;
|
|
Packit Service |
9f2c4a |
struct gp_cred_check_handle gcch = {
|
|
Packit Service |
9f2c4a |
.ctx = gpcall,
|
|
Packit Service |
9f2c4a |
.options.options_len = arg->accept_sec_context.options.options_len,
|
|
Packit Service |
9f2c4a |
.options.options_val = arg->accept_sec_context.options.options_val,
|
|
Packit Service |
9f2c4a |
};
|
|
Packit Service |
9f2c4a |
uint32_t gccn_before = 0;
|
|
Packit Service |
9f2c4a |
uint32_t gccn_after = 0;
|
|
Packit Service |
9f2c4a |
int ret;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
asca = &arg->accept_sec_context;
|
|
Packit Service |
9f2c4a |
ascr = &res->accept_sec_context;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
GPRPCDEBUG(gssx_arg_accept_sec_context, asca);
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
exp_ctx_type = gp_get_exported_context_type(&asca->call_ctx);
|
|
Packit Service |
9f2c4a |
if (exp_ctx_type == -1) {
|
|
Packit Service |
9f2c4a |
ret_maj = GSS_S_FAILURE;
|
|
Packit Service |
9f2c4a |
ret_min = EINVAL;
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
exp_creds_type = gp_get_export_creds_type(&asca->call_ctx);
|
|
Packit Service |
9f2c4a |
if (exp_creds_type == -1) {
|
|
Packit Service |
9f2c4a |
ret_maj = GSS_S_FAILURE;
|
|
Packit Service |
9f2c4a |
ret_min = EINVAL;
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
if (asca->cred_handle) {
|
|
Packit Service |
9f2c4a |
ret_maj = gp_import_gssx_cred(&ret_min, gpcall,
|
|
Packit Service |
9f2c4a |
asca->cred_handle, &ach;;
|
|
Packit Service |
9f2c4a |
if (ret_maj) {
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
gccn_before = gp_check_sync_creds(&gcch, ach);
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
if (ach == GSS_C_NO_CREDENTIAL) {
|
|
Packit Service |
9f2c4a |
ret_maj = gp_add_krb5_creds(&ret_min, gpcall,
|
|
Packit Service |
9f2c4a |
ACQ_NORMAL, NULL, NULL,
|
|
Packit Service |
9f2c4a |
GSS_C_ACCEPT,
|
|
Packit Service |
9f2c4a |
0, 0,
|
|
Packit Service |
9f2c4a |
&ach,
|
|
Packit Service |
9f2c4a |
NULL, NULL, NULL);
|
|
Packit Service |
9f2c4a |
if (ret_maj) {
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
gp_conv_gssx_to_buffer(&asca->input_token, &ibuf);
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
if (asca->input_cb) {
|
|
Packit Service |
9f2c4a |
pcbs = &cb;;
|
|
Packit Service |
9f2c4a |
gp_conv_gssx_to_cb(asca->input_cb, pcbs);
|
|
Packit Service |
9f2c4a |
} else {
|
|
Packit Service |
9f2c4a |
pcbs = GSS_C_NO_CHANNEL_BINDINGS;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
if (asca->ret_deleg_cred) {
|
|
Packit Service |
9f2c4a |
pdch = &dch;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ret_maj = gss_accept_sec_context(&ret_min,
|
|
Packit Service |
9f2c4a |
&ctx,
|
|
Packit Service |
9f2c4a |
ach,
|
|
Packit Service |
9f2c4a |
&ibuf,
|
|
Packit Service |
9f2c4a |
pcbs,
|
|
Packit Service |
9f2c4a |
&src_name,
|
|
Packit Service |
9f2c4a |
&oid,
|
|
Packit Service |
9f2c4a |
&obuf,
|
|
Packit Service |
9f2c4a |
&ret_flags,
|
|
Packit Service |
9f2c4a |
NULL,
|
|
Packit Service |
9f2c4a |
pdch);
|
|
Packit Service |
9f2c4a |
if (ret_maj != GSS_S_COMPLETE &&
|
|
Packit Service |
9f2c4a |
ret_maj != GSS_S_CONTINUE_NEEDED) {
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
} else {
|
|
Packit Service |
9f2c4a |
acpt_maj = ret_maj;
|
|
Packit Service |
9f2c4a |
acpt_min = ret_min;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
if (acpt_maj == GSS_S_CONTINUE_NEEDED) {
|
|
Packit Service |
9f2c4a |
exp_ctx_type = gp_get_continue_needed_type();
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ascr->context_handle = calloc(1, sizeof(gssx_ctx));
|
|
Packit Service |
9f2c4a |
if (!ascr->context_handle) {
|
|
Packit Service |
9f2c4a |
ret_maj = GSS_S_FAILURE;
|
|
Packit Service |
9f2c4a |
ret_min = ENOMEM;
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
ret_maj = gp_export_ctx_id_to_gssx(&ret_min, exp_ctx_type, oid,
|
|
Packit Service |
9f2c4a |
&ctx, ascr->context_handle);
|
|
Packit Service |
9f2c4a |
if (ret_maj) {
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ascr->output_token = calloc(1, sizeof(gssx_buffer));
|
|
Packit Service |
9f2c4a |
if (!ascr->output_token) {
|
|
Packit Service |
9f2c4a |
ret_maj = GSS_S_FAILURE;
|
|
Packit Service |
9f2c4a |
ret_min = ENOMEM;
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
ret = gp_conv_buffer_to_gssx(&obuf, ascr->output_token);
|
|
Packit Service |
9f2c4a |
if (ret) {
|
|
Packit Service |
9f2c4a |
ret_maj = GSS_S_FAILURE;
|
|
Packit Service |
9f2c4a |
ret_min = ret;
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
if ((ret_flags & GSS_C_DELEG_FLAG) && asca->ret_deleg_cred && dch) {
|
|
Packit Service |
9f2c4a |
ascr->delegated_cred_handle = calloc(1, sizeof(gssx_cred));
|
|
Packit Service |
9f2c4a |
if (!ascr->delegated_cred_handle) {
|
|
Packit Service |
9f2c4a |
ret_maj = GSS_S_FAILURE;
|
|
Packit Service |
9f2c4a |
ret_min = ENOMEM;
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
ret_maj = gp_export_gssx_cred(&ret_min, gpcall,
|
|
Packit Service |
9f2c4a |
&dch, ascr->delegated_cred_handle);
|
|
Packit Service |
9f2c4a |
if (ret_maj) {
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ret_maj = gp_export_creds_to_gssx_options(&ret_min,
|
|
Packit Service |
9f2c4a |
exp_creds_type,
|
|
Packit Service |
9f2c4a |
src_name, oid,
|
|
Packit Service |
9f2c4a |
&ascr->options.options_len,
|
|
Packit Service |
9f2c4a |
&ascr->options.options_val);
|
|
Packit Service |
9f2c4a |
if (ret_maj) {
|
|
Packit Service |
9f2c4a |
goto done;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
gccn_after = gp_check_sync_creds(&gcch, ach);
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
if (gccn_before != gccn_after) {
|
|
Packit Service |
9f2c4a |
/* export creds back to client for sync up */
|
|
Packit Service |
9f2c4a |
ret_maj = gp_export_sync_creds(&ret_min, gpcall, &ach,
|
|
Packit Service |
9f2c4a |
&ascr->options.options_val,
|
|
Packit Service |
9f2c4a |
&ascr->options.options_len);
|
|
Packit Service |
9f2c4a |
if (ret_maj) {
|
|
Packit Service |
9f2c4a |
/* not fatal, log and continue */
|
|
Packit Service |
9f2c4a |
GPDEBUG("Failed to export sync creds (%d: %d)",
|
|
Packit Service |
9f2c4a |
(int)ret_maj, (int)ret_min);
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
ret_maj = GSS_S_COMPLETE;
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
done:
|
|
Packit Service |
9f2c4a |
if (ret_maj == GSS_S_COMPLETE) {
|
|
Packit Service |
9f2c4a |
ret_maj = acpt_maj;
|
|
Packit Service |
9f2c4a |
ret_min = acpt_min;
|
|
Packit Service |
9f2c4a |
}
|
|
Packit Service |
9f2c4a |
ret = gp_conv_status_to_gssx(ret_maj, ret_min, oid,
|
|
Packit Service |
9f2c4a |
&ascr->status);
|
|
Packit Service |
9f2c4a |
GPRPCDEBUG(gssx_res_accept_sec_context, ascr);
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
gss_release_name(&ret_min, &src_name);
|
|
Packit Service |
9f2c4a |
gss_release_buffer(&ret_min, &obuf);
|
|
Packit Service |
9f2c4a |
gss_release_cred(&ret_min, &dch;;
|
|
Packit Service |
9f2c4a |
gss_release_cred(&ret_min, &ach;;
|
|
Packit Service |
9f2c4a |
gss_delete_sec_context(&ret_min, &ctx, GSS_C_NO_BUFFER);
|
|
Packit Service |
9f2c4a |
|
|
Packit Service |
9f2c4a |
return ret;
|
|
Packit Service |
9f2c4a |
}
|