1 /* 2 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 7 /* 8 * Copyright 1993 by OpenVision Technologies, Inc. 9 * 10 * Permission to use, copy, modify, distribute, and sell this software 11 * and its documentation for any purpose is hereby granted without fee, 12 * provided that the above copyright notice appears in all copies and 13 * that both that copyright notice and this permission notice appear in 14 * supporting documentation, and that the name of OpenVision not be used 15 * in advertising or publicity pertaining to distribution of the software 16 * without specific, written prior permission. OpenVision makes no 17 * representations about the suitability of this software for any 18 * purpose. It is provided "as is" without express or implied warranty. 19 * 20 * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 21 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 22 * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR 23 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 24 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 25 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 26 * PERFORMANCE OF THIS SOFTWARE. 27 */ 28 29 /* 30 * Copyright (C) 1998 by the FundsXpress, INC. 31 * 32 * All rights reserved. 33 * 34 * Export of this software from the United States of America may require 35 * a specific license from the United States Government. It is the 36 * responsibility of any person or organization contemplating export to 37 * obtain such a license before exporting. 38 * 39 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 40 * distribute this software and its documentation for any purpose and 41 * without fee is hereby granted, provided that the above copyright 42 * notice appear in all copies and that both that copyright notice and 43 * this permission notice appear in supporting documentation, and that 44 * the name of FundsXpress. not be used in advertising or publicity pertaining 45 * to distribution of the software without specific, written prior 46 * permission. FundsXpress makes no representations about the suitability of 47 * this software for any purpose. It is provided "as is" without express 48 * or implied warranty. 49 * 50 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 51 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 52 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 53 */ 54 55 /* 56 * $Id: gssapi_krb5.c 18343 2006-07-19 18:14:01Z lxs $ 57 */ 58 59 60 /* For declaration of krb5_ser_context_init */ 61 #include "k5-int.h" 62 #include "gssapiP_krb5.h" 63 64 /* 65 * Solaris Kerberos 66 * Kernel kgssd module debugging aid. The global variable "krb5_log" is a bit 67 * mask which allows various types of log messages to be printed out. 68 * 69 * The log levels are defined in: 70 * usr/src/uts/common/gssapi/mechs/krb5/include/k5-int.h 71 * 72 * Note, KRB5_LOG_LVL can be assigned via the make invocation. 73 * See KRB5_DEFS in the various Makefiles. 74 */ 75 76 #ifdef KRB5_LOG_LVL 77 /* set the log level to that specified */ 78 u_int krb5_log = KRB5_LOG_LVL; 79 #else 80 /* default log level */ 81 u_int krb5_log = 0; 82 #endif /* KRB5_LOG_LVL */ 83 84 /** exported constants defined in gssapi_krb5{,_nx}.h **/ 85 86 /* these are bogus, but will compile */ 87 88 /* 89 * The OID of the draft krb5 mechanism, assigned by IETF, is: 90 * iso(1) org(3) dod(5) internet(1) security(5) 91 * kerberosv5(2) = 1.3.5.1.5.2 92 * The OID of the krb5_name type is: 93 * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2) 94 * krb5(2) krb5_name(1) = 1.2.840.113554.1.2.2.1 95 * The OID of the krb5_principal type is: 96 * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2) 97 * krb5(2) krb5_principal(2) = 1.2.840.113554.1.2.2.2 98 * The OID of the proposed standard krb5 mechanism is: 99 * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2) 100 * krb5(2) = 1.2.840.113554.1.2.2 101 * The OID of the proposed standard krb5 v2 mechanism is: 102 * iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2) 103 * krb5v2(3) = 1.2.840.113554.1.2.3 104 * 105 */ 106 107 /* 108 * Encoding rules: The first two values are encoded in one byte as 40 109 * * value1 + value2. Subsequent values are encoded base 128, most 110 * significant digit first, with the high bit (\200) set on all octets 111 * except the last in each value's encoding. 112 */ 113 114 const gss_OID_desc krb5_gss_oid_array[] = { 115 /* this is the official, rfc-specified OID */ 116 {GSS_MECH_KRB5_OID_LENGTH, GSS_MECH_KRB5_OID}, 117 /* this pre-RFC mech OID */ 118 {GSS_MECH_KRB5_OLD_OID_LENGTH, GSS_MECH_KRB5_OLD_OID}, 119 /* this is the unofficial, incorrect mech OID emitted by MS */ 120 {GSS_MECH_KRB5_WRONG_OID_LENGTH, GSS_MECH_KRB5_WRONG_OID}, 121 /* this is the v2 assigned OID */ 122 {9, "\052\206\110\206\367\022\001\002\003"}, 123 /* these two are name type OID's */ 124 125 /* 2.1.1. Kerberos Principal Name Form: (rfc 1964) 126 * This name form shall be represented by the Object Identifier {iso(1) 127 * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2) 128 * krb5(2) krb5_name(1)}. The recommended symbolic name for this type 129 * is "GSS_KRB5_NT_PRINCIPAL_NAME". */ 130 {10, "\052\206\110\206\367\022\001\002\002\001"}, 131 132 /* gss_nt_krb5_principal. Object identifier for a krb5_principal. Do not use. */ 133 {10, "\052\206\110\206\367\022\001\002\002\002"}, 134 { 0, 0 } 135 }; 136 137 const gss_OID_desc * const gss_mech_krb5 = krb5_gss_oid_array+0; 138 const gss_OID_desc * const gss_mech_krb5_old = krb5_gss_oid_array+1; 139 const gss_OID_desc * const gss_mech_krb5_wrong = krb5_gss_oid_array+2; 140 const gss_OID_desc * const gss_nt_krb5_name = krb5_gss_oid_array+4; 141 const gss_OID_desc * const gss_nt_krb5_principal = krb5_gss_oid_array+5; 142 const gss_OID_desc * const GSS_KRB5_NT_PRINCIPAL_NAME = krb5_gss_oid_array+4; 143 144 static const gss_OID_set_desc oidsets[] = { 145 {1, (gss_OID) krb5_gss_oid_array+0}, 146 {1, (gss_OID) krb5_gss_oid_array+1}, 147 {3, (gss_OID) krb5_gss_oid_array+0}, 148 {1, (gss_OID) krb5_gss_oid_array+2}, 149 {3, (gss_OID) krb5_gss_oid_array+0}, 150 }; 151 152 const gss_OID_set_desc * const gss_mech_set_krb5 = oidsets+0; 153 const gss_OID_set_desc * const gss_mech_set_krb5_old = oidsets+1; 154 const gss_OID_set_desc * const gss_mech_set_krb5_both = oidsets+2; 155 156 g_set kg_vdb = G_SET_INIT; 157 158 /** default credential support */ 159 160 #ifndef _KERNEL 161 162 /* 163 * init_sec_context() will explicitly re-acquire default credentials, 164 * so handling the expiration/invalidation condition here isn't needed. 165 */ 166 OM_uint32 167 kg_get_defcred(minor_status, cred) 168 OM_uint32 *minor_status; 169 gss_cred_id_t *cred; 170 { 171 OM_uint32 major; 172 173 if ((major = krb5_gss_acquire_cred(minor_status, 174 (gss_name_t) NULL, GSS_C_INDEFINITE, 175 GSS_C_NULL_OID_SET, GSS_C_INITIATE, 176 cred, NULL, NULL)) && GSS_ERROR(major)) { 177 return(major); 178 } 179 *minor_status = 0; 180 return(GSS_S_COMPLETE); 181 } 182 183 OM_uint32 184 kg_sync_ccache_name (krb5_context context, OM_uint32 *minor_status) 185 { 186 OM_uint32 err = 0; 187 188 /* 189 * Sync up the context ccache name with the GSSAPI ccache name. 190 * If kg_ccache_name is NULL -- normal unless someone has called 191 * gss_krb5_ccache_name() -- then the system default ccache will 192 * be picked up and used by resetting the context default ccache. 193 * This is needed for platforms which support multiple ccaches. 194 */ 195 196 if (!err) { 197 /* if NULL, resets the context default ccache */ 198 err = krb5_cc_set_default_name(context, 199 (char *) k5_getspecific(K5_KEY_GSS_KRB5_CCACHE_NAME)); 200 } 201 202 *minor_status = err; 203 return (*minor_status == 0) ? GSS_S_COMPLETE : GSS_S_FAILURE; 204 } 205 206 /* This function returns whether or not the caller set a cccache name. Used by 207 * gss_acquire_cred to figure out if the caller wants to only look at this 208 * ccache or search the cache collection for the desired name */ 209 OM_uint32 210 kg_caller_provided_ccache_name (OM_uint32 *minor_status, 211 int *out_caller_provided_name) 212 { 213 if (out_caller_provided_name) { 214 *out_caller_provided_name = 215 (k5_getspecific(K5_KEY_GSS_KRB5_CCACHE_NAME) != NULL); 216 } 217 218 *minor_status = 0; 219 return GSS_S_COMPLETE; 220 } 221 222 OM_uint32 223 kg_get_ccache_name (OM_uint32 *minor_status, const char **out_name) 224 { 225 const char *name = NULL; 226 OM_uint32 err = 0; 227 char *kg_ccache_name; 228 229 kg_ccache_name = k5_getspecific(K5_KEY_GSS_KRB5_CCACHE_NAME); 230 231 if (kg_ccache_name != NULL) { 232 name = strdup(kg_ccache_name); 233 if (name == NULL) 234 err = errno; 235 } else { 236 krb5_context context = NULL; 237 238 /* Reset the context default ccache (see text above), and then 239 retrieve it. */ 240 err = krb5_gss_init_context(&context); 241 if (!err) 242 err = krb5_cc_set_default_name (context, NULL); 243 if (!err) { 244 name = krb5_cc_default_name(context); 245 if (name) { 246 name = strdup(name); 247 if (name == NULL) 248 err = errno; 249 } 250 } 251 if (context) 252 krb5_free_context(context); 253 } 254 255 if (!err) { 256 if (out_name) { 257 *out_name = name; 258 } 259 } 260 261 *minor_status = err; 262 return (*minor_status == 0) ? GSS_S_COMPLETE : GSS_S_FAILURE; 263 } 264 265 OM_uint32 266 kg_set_ccache_name (OM_uint32 *minor_status, const char *name) 267 { 268 char *new_name = NULL; 269 char *swap = NULL; 270 char *kg_ccache_name; 271 krb5_error_code kerr; 272 273 if (name) { 274 new_name = malloc(strlen(name) + 1); 275 if (new_name == NULL) { 276 *minor_status = ENOMEM; 277 return GSS_S_FAILURE; 278 } 279 strcpy(new_name, name); 280 } 281 282 kg_ccache_name = k5_getspecific(K5_KEY_GSS_KRB5_CCACHE_NAME); 283 swap = kg_ccache_name; 284 kg_ccache_name = new_name; 285 new_name = swap; 286 kerr = k5_setspecific(K5_KEY_GSS_KRB5_CCACHE_NAME, kg_ccache_name); 287 if (kerr != 0) { 288 /* Can't store, so free up the storage. */ 289 free(kg_ccache_name); 290 /* ??? free(new_name); */ 291 *minor_status = kerr; 292 return GSS_S_FAILURE; 293 } 294 295 free (new_name); 296 *minor_status = 0; 297 return GSS_S_COMPLETE; 298 } 299 #endif 300