1 /* 2 * Copyright (c) 2004, PADL Software Pty Ltd. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * 3. Neither the name of PADL Software nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 /* 34 * glue routine for _gsskrb5_inquire_sec_context_by_oid 35 */ 36 37 #include "krb5/gsskrb5_locl.h" 38 39 RCSID("$Id: set_sec_context_option.c 20384 2007-04-18 08:51:06Z lha $"); 40 41 static OM_uint32 42 get_bool(OM_uint32 *minor_status, 43 const gss_buffer_t value, 44 int *flag) 45 { 46 if (value->value == NULL || value->length != 1) { 47 *minor_status = EINVAL; 48 return GSS_S_FAILURE; 49 } 50 *flag = *((const char *)value->value) != 0; 51 return GSS_S_COMPLETE; 52 } 53 54 static OM_uint32 55 get_string(OM_uint32 *minor_status, 56 const gss_buffer_t value, 57 char **str) 58 { 59 if (value == NULL || value->length == 0) { 60 *str = NULL; 61 } else { 62 *str = malloc(value->length + 1); 63 if (*str == NULL) { 64 *minor_status = 0; 65 return GSS_S_UNAVAILABLE; 66 } 67 memcpy(*str, value->value, value->length); 68 (*str)[value->length] = '\0'; 69 } 70 return GSS_S_COMPLETE; 71 } 72 73 OM_uint32 74 _gsskrb5_set_sec_context_option 75 (OM_uint32 *minor_status, 76 gss_ctx_id_t *context_handle, 77 const gss_OID desired_object, 78 const gss_buffer_t value) 79 { 80 krb5_context context; 81 OM_uint32 maj_stat; 82 83 GSSAPI_KRB5_INIT (&context); 84 85 if (value == GSS_C_NO_BUFFER) { 86 *minor_status = EINVAL; 87 return GSS_S_FAILURE; 88 } 89 90 if (gss_oid_equal(desired_object, GSS_KRB5_COMPAT_DES3_MIC_X)) { 91 gsskrb5_ctx ctx; 92 int flag; 93 94 if (*context_handle == GSS_C_NO_CONTEXT) { 95 *minor_status = EINVAL; 96 return GSS_S_NO_CONTEXT; 97 } 98 99 maj_stat = get_bool(minor_status, value, &flag); 100 if (maj_stat != GSS_S_COMPLETE) 101 return maj_stat; 102 103 ctx = (gsskrb5_ctx)*context_handle; 104 HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); 105 if (flag) 106 ctx->more_flags |= COMPAT_OLD_DES3; 107 else 108 ctx->more_flags &= ~COMPAT_OLD_DES3; 109 ctx->more_flags |= COMPAT_OLD_DES3_SELECTED; 110 HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); 111 return GSS_S_COMPLETE; 112 } else if (gss_oid_equal(desired_object, GSS_KRB5_SET_DNS_CANONICALIZE_X)) { 113 int flag; 114 115 maj_stat = get_bool(minor_status, value, &flag); 116 if (maj_stat != GSS_S_COMPLETE) 117 return maj_stat; 118 119 krb5_set_dns_canonicalize_hostname(context, flag); 120 return GSS_S_COMPLETE; 121 122 } else if (gss_oid_equal(desired_object, GSS_KRB5_REGISTER_ACCEPTOR_IDENTITY_X)) { 123 char *str; 124 125 maj_stat = get_string(minor_status, value, &str); 126 if (maj_stat != GSS_S_COMPLETE) 127 return maj_stat; 128 129 _gsskrb5_register_acceptor_identity(str); 130 free(str); 131 132 *minor_status = 0; 133 return GSS_S_COMPLETE; 134 135 } else if (gss_oid_equal(desired_object, GSS_KRB5_SET_DEFAULT_REALM_X)) { 136 char *str; 137 138 maj_stat = get_string(minor_status, value, &str); 139 if (maj_stat != GSS_S_COMPLETE) 140 return maj_stat; 141 if (str == NULL) { 142 *minor_status = 0; 143 return GSS_S_CALL_INACCESSIBLE_READ; 144 } 145 146 krb5_set_default_realm(context, str); 147 free(str); 148 149 *minor_status = 0; 150 return GSS_S_COMPLETE; 151 152 } else if (gss_oid_equal(desired_object, GSS_KRB5_SEND_TO_KDC_X)) { 153 154 if (value == NULL || value->length == 0) { 155 krb5_set_send_to_kdc_func(context, NULL, NULL); 156 } else { 157 struct gsskrb5_send_to_kdc c; 158 159 if (value->length != sizeof(c)) { 160 *minor_status = EINVAL; 161 return GSS_S_FAILURE; 162 } 163 memcpy(&c, value->value, sizeof(c)); 164 krb5_set_send_to_kdc_func(context, 165 (krb5_send_to_kdc_func)c.func, 166 c.ptr); 167 } 168 169 *minor_status = 0; 170 return GSS_S_COMPLETE; 171 } else if (gss_oid_equal(desired_object, GSS_KRB5_CCACHE_NAME_X)) { 172 char *str; 173 174 maj_stat = get_string(minor_status, value, &str); 175 if (maj_stat != GSS_S_COMPLETE) 176 return maj_stat; 177 if (str == NULL) { 178 *minor_status = 0; 179 return GSS_S_CALL_INACCESSIBLE_READ; 180 } 181 182 *minor_status = krb5_cc_set_default_name(context, str); 183 free(str); 184 if (*minor_status) 185 return GSS_S_FAILURE; 186 187 return GSS_S_COMPLETE; 188 } 189 190 *minor_status = EINVAL; 191 return GSS_S_FAILURE; 192 } 193