set_cred_option.c revision 178825
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 33178825Sdfr#include "krb5/gsskrb5_locl.h" 34178825Sdfr 35178825SdfrRCSID("$Id: set_cred_option.c 20325 2007-04-12 16:49:17Z lha $"); 36178825Sdfr 37178825Sdfrstatic gss_OID_desc gss_krb5_import_cred_x_oid_desc = 38178825Sdfr{9, (void *)"\x2b\x06\x01\x04\x01\xa9\x4a\x13\x04"}; /* XXX */ 39178825Sdfr 40178825Sdfrgss_OID GSS_KRB5_IMPORT_CRED_X = &gss_krb5_import_cred_x_oid_desc; 41178825Sdfr 42178825Sdfrstatic OM_uint32 43178825Sdfrimport_cred(OM_uint32 *minor_status, 44178825Sdfr krb5_context context, 45178825Sdfr gss_cred_id_t *cred_handle, 46178825Sdfr const gss_buffer_t value) 47178825Sdfr{ 48178825Sdfr OM_uint32 major_stat; 49178825Sdfr krb5_error_code ret; 50178825Sdfr krb5_principal keytab_principal = NULL; 51178825Sdfr krb5_keytab keytab = NULL; 52178825Sdfr krb5_storage *sp = NULL; 53178825Sdfr krb5_ccache id = NULL; 54178825Sdfr char *str; 55178825Sdfr 56178825Sdfr if (cred_handle == NULL || *cred_handle != GSS_C_NO_CREDENTIAL) { 57178825Sdfr *minor_status = 0; 58178825Sdfr return GSS_S_FAILURE; 59178825Sdfr } 60178825Sdfr 61178825Sdfr sp = krb5_storage_from_mem(value->value, value->length); 62178825Sdfr if (sp == NULL) { 63178825Sdfr *minor_status = 0; 64178825Sdfr return GSS_S_FAILURE; 65178825Sdfr } 66178825Sdfr 67178825Sdfr /* credential cache name */ 68178825Sdfr ret = krb5_ret_string(sp, &str); 69178825Sdfr if (ret) { 70178825Sdfr *minor_status = ret; 71178825Sdfr major_stat = GSS_S_FAILURE; 72178825Sdfr goto out; 73178825Sdfr } 74178825Sdfr if (str[0]) { 75178825Sdfr ret = krb5_cc_resolve(context, str, &id); 76178825Sdfr if (ret) { 77178825Sdfr *minor_status = ret; 78178825Sdfr major_stat = GSS_S_FAILURE; 79178825Sdfr goto out; 80178825Sdfr } 81178825Sdfr } 82178825Sdfr free(str); 83178825Sdfr str = NULL; 84178825Sdfr 85178825Sdfr /* keytab principal name */ 86178825Sdfr ret = krb5_ret_string(sp, &str); 87178825Sdfr if (ret == 0 && str[0]) 88178825Sdfr ret = krb5_parse_name(context, str, &keytab_principal); 89178825Sdfr if (ret) { 90178825Sdfr *minor_status = ret; 91178825Sdfr major_stat = GSS_S_FAILURE; 92178825Sdfr goto out; 93178825Sdfr } 94178825Sdfr free(str); 95178825Sdfr str = NULL; 96178825Sdfr 97178825Sdfr /* keytab principal */ 98178825Sdfr ret = krb5_ret_string(sp, &str); 99178825Sdfr if (ret) { 100178825Sdfr *minor_status = ret; 101178825Sdfr major_stat = GSS_S_FAILURE; 102178825Sdfr goto out; 103178825Sdfr } 104178825Sdfr if (str[0]) { 105178825Sdfr ret = krb5_kt_resolve(context, str, &keytab); 106178825Sdfr if (ret) { 107178825Sdfr *minor_status = ret; 108178825Sdfr major_stat = GSS_S_FAILURE; 109178825Sdfr goto out; 110178825Sdfr } 111178825Sdfr } 112178825Sdfr free(str); 113178825Sdfr str = NULL; 114178825Sdfr 115178825Sdfr major_stat = _gsskrb5_import_cred(minor_status, id, keytab_principal, 116178825Sdfr keytab, cred_handle); 117178825Sdfrout: 118178825Sdfr if (id) 119178825Sdfr krb5_cc_close(context, id); 120178825Sdfr if (keytab_principal) 121178825Sdfr krb5_free_principal(context, keytab_principal); 122178825Sdfr if (keytab) 123178825Sdfr krb5_kt_close(context, keytab); 124178825Sdfr if (str) 125178825Sdfr free(str); 126178825Sdfr if (sp) 127178825Sdfr krb5_storage_free(sp); 128178825Sdfr 129178825Sdfr return major_stat; 130178825Sdfr} 131178825Sdfr 132178825Sdfr 133178825Sdfrstatic OM_uint32 134178825Sdfrallowed_enctypes(OM_uint32 *minor_status, 135178825Sdfr krb5_context context, 136178825Sdfr gss_cred_id_t *cred_handle, 137178825Sdfr const gss_buffer_t value) 138178825Sdfr{ 139178825Sdfr OM_uint32 major_stat; 140178825Sdfr krb5_error_code ret; 141178825Sdfr size_t len, i; 142178825Sdfr krb5_enctype *enctypes = NULL; 143178825Sdfr krb5_storage *sp = NULL; 144178825Sdfr gsskrb5_cred cred; 145178825Sdfr 146178825Sdfr if (cred_handle == NULL || *cred_handle == GSS_C_NO_CREDENTIAL) { 147178825Sdfr *minor_status = 0; 148178825Sdfr return GSS_S_FAILURE; 149178825Sdfr } 150178825Sdfr 151178825Sdfr cred = (gsskrb5_cred)*cred_handle; 152178825Sdfr 153178825Sdfr if ((value->length % 4) != 0) { 154178825Sdfr *minor_status = 0; 155178825Sdfr major_stat = GSS_S_FAILURE; 156178825Sdfr goto out; 157178825Sdfr } 158178825Sdfr 159178825Sdfr len = value->length / 4; 160178825Sdfr enctypes = malloc((len + 1) * 4); 161178825Sdfr if (enctypes == NULL) { 162178825Sdfr *minor_status = ENOMEM; 163178825Sdfr major_stat = GSS_S_FAILURE; 164178825Sdfr goto out; 165178825Sdfr } 166178825Sdfr 167178825Sdfr sp = krb5_storage_from_mem(value->value, value->length); 168178825Sdfr if (sp == NULL) { 169178825Sdfr *minor_status = ENOMEM; 170178825Sdfr major_stat = GSS_S_FAILURE; 171178825Sdfr goto out; 172178825Sdfr } 173178825Sdfr 174178825Sdfr for (i = 0; i < len; i++) { 175178825Sdfr uint32_t e; 176178825Sdfr 177178825Sdfr ret = krb5_ret_uint32(sp, &e); 178178825Sdfr if (ret) { 179178825Sdfr *minor_status = ret; 180178825Sdfr major_stat = GSS_S_FAILURE; 181178825Sdfr goto out; 182178825Sdfr } 183178825Sdfr enctypes[i] = e; 184178825Sdfr } 185178825Sdfr enctypes[i] = 0; 186178825Sdfr 187178825Sdfr if (cred->enctypes) 188178825Sdfr free(cred->enctypes); 189178825Sdfr cred->enctypes = enctypes; 190178825Sdfr 191178825Sdfr krb5_storage_free(sp); 192178825Sdfr 193178825Sdfr return GSS_S_COMPLETE; 194178825Sdfr 195178825Sdfrout: 196178825Sdfr if (sp) 197178825Sdfr krb5_storage_free(sp); 198178825Sdfr if (enctypes) 199178825Sdfr free(enctypes); 200178825Sdfr 201178825Sdfr return major_stat; 202178825Sdfr} 203178825Sdfr 204178825Sdfr 205178825SdfrOM_uint32 206178825Sdfr_gsskrb5_set_cred_option 207178825Sdfr (OM_uint32 *minor_status, 208178825Sdfr gss_cred_id_t *cred_handle, 209178825Sdfr const gss_OID desired_object, 210178825Sdfr const gss_buffer_t value) 211178825Sdfr{ 212178825Sdfr krb5_context context; 213178825Sdfr 214178825Sdfr GSSAPI_KRB5_INIT (&context); 215178825Sdfr 216178825Sdfr if (value == GSS_C_NO_BUFFER) { 217178825Sdfr *minor_status = EINVAL; 218178825Sdfr return GSS_S_FAILURE; 219178825Sdfr } 220178825Sdfr 221178825Sdfr if (gss_oid_equal(desired_object, GSS_KRB5_IMPORT_CRED_X)) 222178825Sdfr return import_cred(minor_status, context, cred_handle, value); 223178825Sdfr 224178825Sdfr if (gss_oid_equal(desired_object, GSS_KRB5_SET_ALLOWABLE_ENCTYPES_X)) 225178825Sdfr return allowed_enctypes(minor_status, context, cred_handle, value); 226178825Sdfr 227178825Sdfr *minor_status = EINVAL; 228178825Sdfr return GSS_S_FAILURE; 229178825Sdfr} 230