set_cred_option.c revision 233294
1193323Sed/* 2193323Sed * Copyright (c) 2004, PADL Software Pty Ltd. 3193323Sed * All rights reserved. 4193323Sed * 5193323Sed * Redistribution and use in source and binary forms, with or without 6193323Sed * modification, are permitted provided that the following conditions 7193323Sed * are met: 8193323Sed * 9193323Sed * 1. Redistributions of source code must retain the above copyright 10193323Sed * notice, this list of conditions and the following disclaimer. 11193323Sed * 12193323Sed * 2. Redistributions in binary form must reproduce the above copyright 13193323Sed * notice, this list of conditions and the following disclaimer in the 14193323Sed * documentation and/or other materials provided with the distribution. 15193323Sed * 16193323Sed * 3. Neither the name of PADL Software nor the names of its contributors 17193323Sed * may be used to endorse or promote products derived from this software 18193323Sed * without specific prior written permission. 19193323Sed * 20193323Sed * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND 21193323Sed * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22193323Sed * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23249423Sdim * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE 24249423Sdim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25249423Sdim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26249423Sdim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27249423Sdim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28249423Sdim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29249423Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30193323Sed * SUCH DAMAGE. 31193323Sed */ 32198090Srdivacky 33193323Sed#include "gsskrb5_locl.h" 34198090Srdivacky 35249423Sdimstatic OM_uint32 36249423Sdimimport_cred(OM_uint32 *minor_status, 37249423Sdim krb5_context context, 38263508Sdim gss_cred_id_t *cred_handle, 39263508Sdim const gss_buffer_t value) 40193323Sed{ 41193323Sed OM_uint32 major_stat; 42193323Sed krb5_error_code ret; 43193323Sed krb5_principal keytab_principal = NULL; 44193323Sed krb5_keytab keytab = NULL; 45193323Sed krb5_storage *sp = NULL; 46193323Sed krb5_ccache id = NULL; 47218893Sdim char *str; 48263508Sdim 49193323Sed if (cred_handle == NULL || *cred_handle != GSS_C_NO_CREDENTIAL) { 50193323Sed *minor_status = 0; 51193323Sed return GSS_S_FAILURE; 52193323Sed } 53193323Sed 54193323Sed sp = krb5_storage_from_mem(value->value, value->length); 55193323Sed if (sp == NULL) { 56193323Sed *minor_status = 0; 57193323Sed return GSS_S_FAILURE; 58193323Sed } 59263508Sdim 60263508Sdim /* credential cache name */ 61263508Sdim ret = krb5_ret_string(sp, &str); 62263508Sdim if (ret) { 63263508Sdim *minor_status = ret; 64263508Sdim major_stat = GSS_S_FAILURE; 65263508Sdim goto out; 66263508Sdim } 67193323Sed if (str[0]) { 68193323Sed ret = krb5_cc_resolve(context, str, &id); 69198892Srdivacky if (ret) { 70193323Sed *minor_status = ret; 71193323Sed major_stat = GSS_S_FAILURE; 72193323Sed goto out; 73193323Sed } 74193323Sed } 75193323Sed free(str); 76263508Sdim str = NULL; 77193323Sed 78193323Sed /* keytab principal name */ 79234353Sdim ret = krb5_ret_string(sp, &str); 80234353Sdim if (ret == 0 && str[0]) 81234353Sdim ret = krb5_parse_name(context, str, &keytab_principal); 82234353Sdim if (ret) { 83234353Sdim *minor_status = ret; 84234353Sdim major_stat = GSS_S_FAILURE; 85234353Sdim goto out; 86234353Sdim } 87234353Sdim free(str); 88234353Sdim str = NULL; 89234353Sdim 90234353Sdim /* keytab principal */ 91234353Sdim ret = krb5_ret_string(sp, &str); 92234353Sdim if (ret) { 93234353Sdim *minor_status = ret; 94234353Sdim major_stat = GSS_S_FAILURE; 95234353Sdim goto out; 96234353Sdim } 97193323Sed if (str[0]) { 98193323Sed ret = krb5_kt_resolve(context, str, &keytab); 99193323Sed if (ret) { 100193323Sed *minor_status = ret; 101193323Sed major_stat = GSS_S_FAILURE; 102193323Sed goto out; 103193323Sed } 104193323Sed } 105193323Sed free(str); 106193323Sed str = NULL; 107193323Sed 108193323Sed major_stat = _gsskrb5_krb5_import_cred(minor_status, id, keytab_principal, 109193323Sed keytab, cred_handle); 110193323Sedout: 111193323Sed if (id) 112193323Sed krb5_cc_close(context, id); 113193323Sed if (keytab_principal) 114193323Sed krb5_free_principal(context, keytab_principal); 115193323Sed if (keytab) 116234353Sdim krb5_kt_close(context, keytab); 117234353Sdim if (str) 118193323Sed free(str); 119234353Sdim if (sp) 120234353Sdim krb5_storage_free(sp); 121193323Sed 122193323Sed return major_stat; 123193323Sed} 124193323Sed 125193323Sed 126234353Sdimstatic OM_uint32 127193323Sedallowed_enctypes(OM_uint32 *minor_status, 128193323Sed krb5_context context, 129193323Sed gss_cred_id_t *cred_handle, 130193323Sed const gss_buffer_t value) 131193323Sed{ 132193323Sed OM_uint32 major_stat; 133193323Sed krb5_error_code ret; 134193323Sed size_t len, i; 135193323Sed krb5_enctype *enctypes = NULL; 136193323Sed krb5_storage *sp = NULL; 137193323Sed gsskrb5_cred cred; 138193323Sed 139193323Sed if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL) { 140193323Sed *minor_status = 0; 141193323Sed return GSS_S_FAILURE; 142193323Sed } 143193323Sed 144193323Sed cred = (gsskrb5_cred)*cred_handle; 145193323Sed 146193323Sed if ((value->length % 4) != 0) { 147193323Sed *minor_status = 0; 148193323Sed major_stat = GSS_S_FAILURE; 149193323Sed goto out; 150200581Srdivacky } 151200581Srdivacky 152193323Sed len = value->length / 4; 153193323Sed enctypes = malloc((len + 1) * 4); 154193323Sed if (enctypes == NULL) { 155193323Sed *minor_status = ENOMEM; 156193323Sed major_stat = GSS_S_FAILURE; 157193323Sed goto out; 158193323Sed } 159263508Sdim 160193323Sed sp = krb5_storage_from_mem(value->value, value->length); 161207618Srdivacky if (sp == NULL) { 162207618Srdivacky *minor_status = ENOMEM; 163207618Srdivacky major_stat = GSS_S_FAILURE; 164207618Srdivacky goto out; 165207618Srdivacky } 166207618Srdivacky 167207618Srdivacky for (i = 0; i < len; i++) { 168207618Srdivacky uint32_t e; 169193323Sed 170263508Sdim ret = krb5_ret_uint32(sp, &e); 171263508Sdim if (ret) { 172224145Sdim *minor_status = ret; 173224145Sdim major_stat = GSS_S_FAILURE; 174193323Sed goto out; 175193323Sed } 176193323Sed enctypes[i] = e; 177193323Sed } 178193323Sed enctypes[i] = 0; 179193323Sed 180193323Sed if (cred->enctypes) 181193323Sed free(cred->enctypes); 182193323Sed cred->enctypes = enctypes; 183193323Sed 184193323Sed krb5_storage_free(sp); 185193323Sed 186193323Sed return GSS_S_COMPLETE; 187193323Sed 188193323Sedout: 189193323Sed if (sp) 190193323Sed krb5_storage_free(sp); 191234353Sdim if (enctypes) 192193323Sed free(enctypes); 193234353Sdim 194193323Sed return major_stat; 195193323Sed} 196193323Sed 197193323Sedstatic OM_uint32 198193323Sedno_ci_flags(OM_uint32 *minor_status, 199193323Sed krb5_context context, 200193323Sed gss_cred_id_t *cred_handle, 201193323Sed const gss_buffer_t value) 202193323Sed{ 203223017Sdim gsskrb5_cred cred; 204223017Sdim 205193323Sed if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL) { 206193323Sed *minor_status = 0; 207193323Sed return GSS_S_FAILURE; 208193323Sed } 209193323Sed 210193323Sed cred = (gsskrb5_cred)*cred_handle; 211243830Sdim cred->cred_flags |= GSS_CF_NO_CI_FLAGS; 212193323Sed 213193323Sed *minor_status = 0; 214193323Sed return GSS_S_COMPLETE; 215193323Sed 216234353Sdim} 217193323Sed 218234353Sdim 219193323SedOM_uint32 GSSAPI_CALLCONV 220193323Sed_gsskrb5_set_cred_option 221251662Sdim (OM_uint32 *minor_status, 222193323Sed gss_cred_id_t *cred_handle, 223193323Sed const gss_OID desired_object, 224193323Sed const gss_buffer_t value) 225193323Sed{ 226193323Sed krb5_context context; 227193323Sed 228193323Sed GSSAPI_KRB5_INIT (&context); 229218893Sdim 230193323Sed if (value == GSS_C_NO_BUFFER) { 231193323Sed *minor_status = EINVAL; 232193323Sed return GSS_S_FAILURE; 233193323Sed } 234239462Sdim 235193323Sed if (gss_oid_equal(desired_object, GSS_KRB5_IMPORT_CRED_X)) 236193323Sed return import_cred(minor_status, context, cred_handle, value); 237193323Sed 238193323Sed if (gss_oid_equal(desired_object, GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X)) 239193323Sed return allowed_enctypes(minor_status, context, cred_handle, value); 240193323Sed 241193323Sed if (gss_oid_equal(desired_object, GSS_KRB5_CRED_NO_CI_FLAGS_X)) { 242193323Sed return no_ci_flags(minor_status, context, cred_handle, value); 243193323Sed } 244193323Sed 245193323Sed 246193323Sed *minor_status = EINVAL; 247239462Sdim return GSS_S_FAILURE; 248239462Sdim} 249239462Sdim