set_cred_option.c revision 233294
1178825Sdfr/* 2178825Sdfr * Copyright (c) 2004, PADL Software Pty Ltd. 3178825Sdfr * All rights reserved. 4178825Sdfr * 5178825Sdfr * Redistribution and use in source and binary forms, with or without 6178825Sdfr * modification, are permitted provided that the following conditions 7178825Sdfr * are met: 8178825Sdfr * 9178825Sdfr * 1. Redistributions of source code must retain the above copyright 10178825Sdfr * notice, this list of conditions and the following disclaimer. 11178825Sdfr * 12178825Sdfr * 2. Redistributions in binary form must reproduce the above copyright 13178825Sdfr * notice, this list of conditions and the following disclaimer in the 14178825Sdfr * documentation and/or other materials provided with the distribution. 15178825Sdfr * 16178825Sdfr * 3. Neither the name of PADL Software nor the names of its contributors 17178825Sdfr * may be used to endorse or promote products derived from this software 18178825Sdfr * without specific prior written permission. 19178825Sdfr * 20178825Sdfr * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND 21178825Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22178825Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23178825Sdfr * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE 24178825Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25178825Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26178825Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27178825Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28178825Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29178825Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30178825Sdfr * SUCH DAMAGE. 31178825Sdfr */ 32178825Sdfr 33233294Sstas#include "gsskrb5_locl.h" 34178825Sdfr 35178825Sdfrstatic OM_uint32 36178825Sdfrimport_cred(OM_uint32 *minor_status, 37178825Sdfr krb5_context context, 38178825Sdfr gss_cred_id_t *cred_handle, 39178825Sdfr const gss_buffer_t value) 40178825Sdfr{ 41178825Sdfr OM_uint32 major_stat; 42178825Sdfr krb5_error_code ret; 43178825Sdfr krb5_principal keytab_principal = NULL; 44178825Sdfr krb5_keytab keytab = NULL; 45178825Sdfr krb5_storage *sp = NULL; 46178825Sdfr krb5_ccache id = NULL; 47178825Sdfr char *str; 48178825Sdfr 49178825Sdfr if (cred_handle == NULL || *cred_handle != GSS_C_NO_CREDENTIAL) { 50178825Sdfr *minor_status = 0; 51178825Sdfr return GSS_S_FAILURE; 52178825Sdfr } 53178825Sdfr 54178825Sdfr sp = krb5_storage_from_mem(value->value, value->length); 55178825Sdfr if (sp == NULL) { 56178825Sdfr *minor_status = 0; 57178825Sdfr return GSS_S_FAILURE; 58178825Sdfr } 59178825Sdfr 60178825Sdfr /* credential cache name */ 61178825Sdfr ret = krb5_ret_string(sp, &str); 62178825Sdfr if (ret) { 63178825Sdfr *minor_status = ret; 64178825Sdfr major_stat = GSS_S_FAILURE; 65178825Sdfr goto out; 66178825Sdfr } 67178825Sdfr if (str[0]) { 68178825Sdfr ret = krb5_cc_resolve(context, str, &id); 69178825Sdfr if (ret) { 70178825Sdfr *minor_status = ret; 71178825Sdfr major_stat = GSS_S_FAILURE; 72178825Sdfr goto out; 73178825Sdfr } 74178825Sdfr } 75178825Sdfr free(str); 76178825Sdfr str = NULL; 77178825Sdfr 78178825Sdfr /* keytab principal name */ 79178825Sdfr ret = krb5_ret_string(sp, &str); 80178825Sdfr if (ret == 0 && str[0]) 81178825Sdfr ret = krb5_parse_name(context, str, &keytab_principal); 82178825Sdfr if (ret) { 83178825Sdfr *minor_status = ret; 84178825Sdfr major_stat = GSS_S_FAILURE; 85178825Sdfr goto out; 86178825Sdfr } 87178825Sdfr free(str); 88178825Sdfr str = NULL; 89178825Sdfr 90178825Sdfr /* keytab principal */ 91178825Sdfr ret = krb5_ret_string(sp, &str); 92178825Sdfr if (ret) { 93178825Sdfr *minor_status = ret; 94178825Sdfr major_stat = GSS_S_FAILURE; 95178825Sdfr goto out; 96178825Sdfr } 97178825Sdfr if (str[0]) { 98178825Sdfr ret = krb5_kt_resolve(context, str, &keytab); 99178825Sdfr if (ret) { 100178825Sdfr *minor_status = ret; 101178825Sdfr major_stat = GSS_S_FAILURE; 102178825Sdfr goto out; 103178825Sdfr } 104178825Sdfr } 105178825Sdfr free(str); 106178825Sdfr str = NULL; 107178825Sdfr 108233294Sstas major_stat = _gsskrb5_krb5_import_cred(minor_status, id, keytab_principal, 109233294Sstas keytab, cred_handle); 110178825Sdfrout: 111178825Sdfr if (id) 112178825Sdfr krb5_cc_close(context, id); 113178825Sdfr if (keytab_principal) 114178825Sdfr krb5_free_principal(context, keytab_principal); 115178825Sdfr if (keytab) 116178825Sdfr krb5_kt_close(context, keytab); 117178825Sdfr if (str) 118178825Sdfr free(str); 119178825Sdfr if (sp) 120178825Sdfr krb5_storage_free(sp); 121178825Sdfr 122178825Sdfr return major_stat; 123178825Sdfr} 124178825Sdfr 125178825Sdfr 126178825Sdfrstatic OM_uint32 127178825Sdfrallowed_enctypes(OM_uint32 *minor_status, 128178825Sdfr krb5_context context, 129178825Sdfr gss_cred_id_t *cred_handle, 130178825Sdfr const gss_buffer_t value) 131178825Sdfr{ 132178825Sdfr OM_uint32 major_stat; 133178825Sdfr krb5_error_code ret; 134178825Sdfr size_t len, i; 135178825Sdfr krb5_enctype *enctypes = NULL; 136178825Sdfr krb5_storage *sp = NULL; 137178825Sdfr gsskrb5_cred cred; 138178825Sdfr 139178825Sdfr if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL) { 140178825Sdfr *minor_status = 0; 141178825Sdfr return GSS_S_FAILURE; 142178825Sdfr } 143178825Sdfr 144178825Sdfr cred = (gsskrb5_cred)*cred_handle; 145178825Sdfr 146178825Sdfr if ((value->length % 4) != 0) { 147178825Sdfr *minor_status = 0; 148178825Sdfr major_stat = GSS_S_FAILURE; 149178825Sdfr goto out; 150178825Sdfr } 151178825Sdfr 152178825Sdfr len = value->length / 4; 153178825Sdfr enctypes = malloc((len + 1) * 4); 154178825Sdfr if (enctypes == NULL) { 155178825Sdfr *minor_status = ENOMEM; 156178825Sdfr major_stat = GSS_S_FAILURE; 157178825Sdfr goto out; 158178825Sdfr } 159178825Sdfr 160178825Sdfr sp = krb5_storage_from_mem(value->value, value->length); 161178825Sdfr if (sp == NULL) { 162178825Sdfr *minor_status = ENOMEM; 163178825Sdfr major_stat = GSS_S_FAILURE; 164178825Sdfr goto out; 165178825Sdfr } 166178825Sdfr 167178825Sdfr for (i = 0; i < len; i++) { 168178825Sdfr uint32_t e; 169178825Sdfr 170178825Sdfr ret = krb5_ret_uint32(sp, &e); 171178825Sdfr if (ret) { 172178825Sdfr *minor_status = ret; 173178825Sdfr major_stat = GSS_S_FAILURE; 174178825Sdfr goto out; 175178825Sdfr } 176178825Sdfr enctypes[i] = e; 177178825Sdfr } 178178825Sdfr enctypes[i] = 0; 179178825Sdfr 180178825Sdfr if (cred->enctypes) 181178825Sdfr free(cred->enctypes); 182178825Sdfr cred->enctypes = enctypes; 183178825Sdfr 184178825Sdfr krb5_storage_free(sp); 185178825Sdfr 186178825Sdfr return GSS_S_COMPLETE; 187178825Sdfr 188178825Sdfrout: 189178825Sdfr if (sp) 190178825Sdfr krb5_storage_free(sp); 191178825Sdfr if (enctypes) 192178825Sdfr free(enctypes); 193178825Sdfr 194178825Sdfr return major_stat; 195178825Sdfr} 196178825Sdfr 197233294Sstasstatic OM_uint32 198233294Sstasno_ci_flags(OM_uint32 *minor_status, 199233294Sstas krb5_context context, 200233294Sstas gss_cred_id_t *cred_handle, 201233294Sstas const gss_buffer_t value) 202233294Sstas{ 203233294Sstas gsskrb5_cred cred; 204178825Sdfr 205233294Sstas if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL) { 206233294Sstas *minor_status = 0; 207233294Sstas return GSS_S_FAILURE; 208233294Sstas } 209233294Sstas 210233294Sstas cred = (gsskrb5_cred)*cred_handle; 211233294Sstas cred->cred_flags |= GSS_CF_NO_CI_FLAGS; 212233294Sstas 213233294Sstas *minor_status = 0; 214233294Sstas return GSS_S_COMPLETE; 215233294Sstas 216233294Sstas} 217233294Sstas 218233294Sstas 219233294SstasOM_uint32 GSSAPI_CALLCONV 220178825Sdfr_gsskrb5_set_cred_option 221178825Sdfr (OM_uint32 *minor_status, 222178825Sdfr gss_cred_id_t *cred_handle, 223178825Sdfr const gss_OID desired_object, 224178825Sdfr const gss_buffer_t value) 225178825Sdfr{ 226178825Sdfr krb5_context context; 227178825Sdfr 228178825Sdfr GSSAPI_KRB5_INIT (&context); 229178825Sdfr 230178825Sdfr if (value == GSS_C_NO_BUFFER) { 231178825Sdfr *minor_status = EINVAL; 232178825Sdfr return GSS_S_FAILURE; 233178825Sdfr } 234178825Sdfr 235178825Sdfr if (gss_oid_equal(desired_object, GSS_KRB5_IMPORT_CRED_X)) 236178825Sdfr return import_cred(minor_status, context, cred_handle, value); 237178825Sdfr 238178825Sdfr if (gss_oid_equal(desired_object, GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X)) 239178825Sdfr return allowed_enctypes(minor_status, context, cred_handle, value); 240178825Sdfr 241233294Sstas if (gss_oid_equal(desired_object, GSS_KRB5_CRED_NO_CI_FLAGS_X)) { 242233294Sstas return no_ci_flags(minor_status, context, cred_handle, value); 243233294Sstas } 244233294Sstas 245233294Sstas 246178825Sdfr *minor_status = EINVAL; 247178825Sdfr return GSS_S_FAILURE; 248178825Sdfr} 249