Path: blob/main/sys/kgssapi/gss_accept_sec_context.c
39476 views
/*-1* SPDX-License-Identifier: BSD-2-Clause2*3* Copyright (c) 2008 Isilon Inc http://www.isilon.com/4* Authors: Doug Rabson <[email protected]>5* Developed with Red Inc: Alfred Perlstein <[email protected]>6*7* Redistribution and use in source and binary forms, with or without8* modification, are permitted provided that the following conditions9* are met:10* 1. Redistributions of source code must retain the above copyright11* notice, this list of conditions and the following disclaimer.12* 2. Redistributions in binary form must reproduce the above copyright13* notice, this list of conditions and the following disclaimer in the14* documentation and/or other materials provided with the distribution.15*16* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND17* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE18* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE19* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE20* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL21* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS22* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)23* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT24* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY25* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF26* SUCH DAMAGE.27*/2829#include <sys/param.h>30#include <sys/kernel.h>31#include <sys/kobj.h>32#include <sys/lock.h>33#include <sys/malloc.h>34#include <sys/mutex.h>3536#include <kgssapi/gssapi.h>37#include <kgssapi/gssapi_impl.h>38#include <rpc/rpc.h>3940#include "gssd.h"41#include "kgss_if.h"4243/*44* This function should only be called when the gssd45* daemon running on the system is an old one that46* does not use gss_krb5_export_lucid_sec_context().47*/48OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status,49gss_ctx_id_t *context_handle,50const gss_cred_id_t acceptor_cred_handle,51const gss_buffer_t input_token,52const gss_channel_bindings_t input_chan_bindings,53gss_name_t *src_name,54gss_OID *mech_type,55gss_buffer_t output_token,56OM_uint32 *ret_flags,57OM_uint32 *time_rec,58gss_cred_id_t *delegated_cred_handle)59{60struct accept_sec_context_res res;61struct accept_sec_context_args args;62enum clnt_stat stat;63gss_ctx_id_t ctx = *context_handle;64gss_name_t name;65gss_cred_id_t cred;66CLIENT *cl;6768cl = kgss_gssd_client();69if (cl == NULL) {70*minor_status = 0;71return (GSS_S_FAILURE);72}7374if (ctx)75args.ctx = ctx->handle;76else77args.ctx = 0;78if (acceptor_cred_handle)79args.cred = acceptor_cred_handle->handle;80else81args.cred = 0;82args.input_token = *input_token;83args.input_chan_bindings = input_chan_bindings;8485bzero(&res, sizeof(res));86stat = gssd_accept_sec_context_1(&args, &res, cl);87CLNT_RELEASE(cl);88if (stat != RPC_SUCCESS) {89*minor_status = stat;90return (GSS_S_FAILURE);91}9293if (res.major_status != GSS_S_COMPLETE94&& res.major_status != GSS_S_CONTINUE_NEEDED) {95*minor_status = res.minor_status;96xdr_free((xdrproc_t) xdr_accept_sec_context_res, &res);97return (res.major_status);98}99100*minor_status = res.minor_status;101102if (!ctx) {103ctx = kgss_create_context(res.mech_type);104if (!ctx) {105xdr_free((xdrproc_t) xdr_accept_sec_context_res, &res);106*minor_status = 0;107return (GSS_S_BAD_MECH);108}109}110*context_handle = ctx;111112ctx->handle = res.ctx;113name = malloc(sizeof(struct _gss_name_t), M_GSSAPI, M_WAITOK);114name->handle = res.src_name;115if (src_name) {116*src_name = name;117} else {118OM_uint32 junk;119gss_release_name(&junk, &name);120}121if (mech_type)122*mech_type = KGSS_MECH_TYPE(ctx);123kgss_copy_buffer(&res.output_token, output_token);124if (ret_flags)125*ret_flags = res.ret_flags;126if (time_rec)127*time_rec = res.time_rec;128cred = malloc(sizeof(struct _gss_cred_id_t), M_GSSAPI, M_WAITOK);129cred->handle = res.delegated_cred_handle;130if (delegated_cred_handle) {131*delegated_cred_handle = cred;132} else {133OM_uint32 junk;134gss_release_cred(&junk, &cred);135}136137xdr_free((xdrproc_t) xdr_accept_sec_context_res, &res);138139/*140* If the context establishment is complete, export it from141* userland and hand the result (which includes key material142* etc.) to the kernel implementation.143*/144if (res.major_status == GSS_S_COMPLETE)145res.major_status = kgss_transfer_context(ctx, NULL);146147return (res.major_status);148}149150/*151* This function should be called when the gssd daemon is152* one that uses gss_krb5_export_lucid_sec_context().153* There is a lot of code common with154* gss_accept_sec_context(). However, the structures used155* are not the same and future changes may be needed for156* this one. As such, I have not factored out the common157* code.158* gss_supports_lucid() may be used to check to see if the159* gssd daemon uses gss_krb5_export_lucid_sec_context().160*/161OM_uint32 gss_accept_sec_context_lucid_v1(OM_uint32 *minor_status,162gss_ctx_id_t *context_handle,163const gss_cred_id_t acceptor_cred_handle,164const gss_buffer_t input_token,165const gss_channel_bindings_t input_chan_bindings,166gss_name_t *src_name,167gss_OID *mech_type,168gss_buffer_t output_token,169OM_uint32 *ret_flags,170OM_uint32 *time_rec,171gss_cred_id_t *delegated_cred_handle,172gss_buffer_t exported_name,173uid_t *uidp,174gid_t *gidp,175int *numgroups,176gid_t *groups)177{178struct accept_sec_context_lucid_v1_res res;179struct accept_sec_context_lucid_v1_args args;180enum clnt_stat stat;181gss_ctx_id_t ctx = *context_handle;182gss_name_t name;183gss_cred_id_t cred;184CLIENT *cl;185186cl = kgss_gssd_client();187if (cl == NULL) {188*minor_status = 0;189return (GSS_S_FAILURE);190}191192if (ctx)193args.ctx = ctx->handle;194else195args.ctx = 0;196if (acceptor_cred_handle)197args.cred = acceptor_cred_handle->handle;198else199args.cred = 0;200args.input_token = *input_token;201args.input_chan_bindings = input_chan_bindings;202203bzero(&res, sizeof(res));204stat = gssd_accept_sec_context_lucid_v1_1(&args, &res, cl);205CLNT_RELEASE(cl);206if (stat != RPC_SUCCESS) {207*minor_status = stat;208return (GSS_S_FAILURE);209}210211if (res.major_status != GSS_S_COMPLETE212&& res.major_status != GSS_S_CONTINUE_NEEDED) {213*minor_status = res.minor_status;214xdr_free((xdrproc_t) xdr_accept_sec_context_res, &res);215return (res.major_status);216}217218*minor_status = res.minor_status;219220if (!ctx) {221ctx = kgss_create_context(res.mech_type);222if (!ctx) {223xdr_free((xdrproc_t) xdr_accept_sec_context_res, &res);224*minor_status = 0;225return (GSS_S_BAD_MECH);226}227}228*context_handle = ctx;229230ctx->handle = res.ctx;231name = malloc(sizeof(struct _gss_name_t), M_GSSAPI, M_WAITOK);232name->handle = res.src_name;233if (src_name) {234*src_name = name;235} else {236OM_uint32 junk;237gss_release_name(&junk, &name);238}239if (mech_type)240*mech_type = KGSS_MECH_TYPE(ctx);241kgss_copy_buffer(&res.output_token, output_token);242if (ret_flags)243*ret_flags = res.ret_flags;244if (time_rec)245*time_rec = res.time_rec;246cred = malloc(sizeof(struct _gss_cred_id_t), M_GSSAPI, M_WAITOK);247cred->handle = res.delegated_cred_handle;248if (delegated_cred_handle) {249*delegated_cred_handle = cred;250} else {251OM_uint32 junk;252gss_release_cred(&junk, &cred);253}254255/*256* If the context establishment is complete, export it from257* userland and hand the result (which includes key material258* etc.) to the kernel implementation.259*/260if (res.major_status == GSS_S_COMPLETE) {261int i, n;262263/* First, get the unix credentials. */264*uidp = res.uid;265*gidp = res.gid;266n = res.gidlist.gidlist_len;267if (n > *numgroups)268n = *numgroups;269for (i = 0; i < n; i++)270groups[i] = res.gidlist.gidlist_val[i];271*numgroups = n;272273/* Next, get the exported_name. */274kgss_copy_buffer(&res.exported_name, exported_name);275276/* Now, handle the lucid credential setup. */277res.major_status = kgss_transfer_context(ctx, &res.lucid);278if (res.major_status != GSS_S_COMPLETE)279printf("gss_accept_sec_context_lucid_v1: "280"transfer failed\n");281}282283xdr_free((xdrproc_t) xdr_accept_sec_context_res, &res);284285return (res.major_status);286}287288289