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