xref: /illumos-gate/usr/src/uts/common/gssapi/mechs/krb5/mech/gssapi_krb5.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1 /*
2  * Copyright 2001-2003 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  * Solaris Kerberos:  This is identical to MIT Release 1.2.1 except for
10  * changes to the call kg_get_context to get the context in release and
11  * getcred.  In order to be MT safe, we keep a global variable kg_context
12  * and do not keep a defcred for default credentials.
13  */
14 
15 /*
16  * Copyright 1993 by OpenVision Technologies, Inc.
17  *
18  * Permission to use, copy, modify, distribute, and sell this software
19  * and its documentation for any purpose is hereby granted without fee,
20  * provided that the above copyright notice appears in all copies and
21  * that both that copyright notice and this permission notice appear in
22  * supporting documentation, and that the name of OpenVision not be used
23  * in advertising or publicity pertaining to distribution of the software
24  * without specific, written prior permission. OpenVision makes no
25  * representations about the suitability of this software for any
26  * purpose.  It is provided "as is" without express or implied warranty.
27  *
28  * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
29  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
30  * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
31  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
32  * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
33  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
34  * PERFORMANCE OF THIS SOFTWARE.
35  */
36 
37 /*
38  * Copyright (C) 1998 by the FundsXpress, INC.
39  *
40  * All rights reserved.
41  *
42  * Export of this software from the United States of America may require
43  * a specific license from the United States Government.  It is the
44  * responsibility of any person or organization contemplating export to
45  * obtain such a license before exporting.
46  *
47  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
48  * distribute this software and its documentation for any purpose and
49  * without fee is hereby granted, provided that the above copyright
50  * notice appear in all copies and that both that copyright notice and
51  * this permission notice appear in supporting documentation, and that
52  * the name of FundsXpress. not be used in advertising or publicity pertaining
53  * to distribution of the software without specific, written prior
54  * permission.  FundsXpress makes no representations about the suitability of
55  * this software for any purpose.  It is provided "as is" without express
56  * or implied warranty.
57  *
58  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
59  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
60  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
61  */
62 
63 /*
64  * $Id: gssapi_krb5.c,v 1.18 1999/03/26 03:51:42 tytso Exp $
65  */
66 
67 #include <gssapiP_krb5.h>
68 #include <k5-int.h>
69 
70 /*
71  * Kernel kgssd module debugging aid. The global variable "krb5_log" is a bit
72  * mask which allows various types of log messages to be printed out.
73  *
74  * The log levels are defined in:
75  * usr/src/uts/common/gssapi/mechs/krb5/include/k5-int.h
76  *
77  * Note, KRB5_LOG_LVL can be assigned via the make invocation.  See KRB5_DEFS in
78  * the various Makefiles.
79  */
80 
81 #ifdef KRB5_LOG_LVL
82 /* set the log level to that specified */
83 u_int krb5_log = KRB5_LOG_LVL;
84 #else
85 /* default log level */
86 u_int krb5_log = 0;
87 #endif /* KRB5_LOG_LVL */
88 
89 /** exported constants defined in gssapi_krb5{,_nx}.h **/
90 
91 /* these are bogus, but will compile */
92 
93 /*
94  * The OID of the draft krb5 mechanism, assigned by IETF, is:
95  * 	iso(1) org(3) dod(5) internet(1) security(5)
96  *	kerberosv5(2) = 1.3.5.1.5.2
97  * The OID of the krb5_user_name type is:
98  *      iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2)
99  *      generic(1) user_name(1) = 1.2.840.113554.1.2.1.1
100  * The OID of the krb5_name type is:
101  * 	iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2)
102  * 	krb5(2) krb5_name(1) = 1.2.840.113554.1.2.2.1
103  * The OID of the krb5_principal type is:
104  *      iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2)
105  *      krb5(2) krb5_principal(2) = 1.2.840.113554.1.2.2.2
106  * The OID of the proposed standard krb5 mechanism is:
107  * 	iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2)
108  * 	krb5(2) = 1.2.840.113554.1.2.2
109  * The OID of the proposed standard krb5 v2 mechanism is:
110  * 	iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2)
111  * 	krb5v2(3) = 1.2.840.113554.1.2.3
112  *
113  */
114 
115 /* gss_mech_krb5 = 1.2.840.113554.1.2.2
116  * gss_mech_krb5_old = 1.3.5.1.5.2
117  * gss_mech_krb5_v2 = 1.2.840.113554.1.2.3
118  * gss_nt_krb5_name = 1.2.840.113554.1.2.2.1
119  * gss_nt_krb5_principal = 1.2.840.113554.1.2.2.2
120  */
121 
122 /*
123  * Encoding rules: The first two values are encoded in one byte as 40
124  * * value1 + value2.  Subsequent values are encoded base 128, most
125  * significant digit first, with the high bit (\200) set on all octets
126  * except the last in each value's encoding.
127  */
128 
129 /*  Global lock for krb5 mechanism  */
130 #ifdef  _KERNEL
131 kmutex_t	krb5_mutex;
132 #else
133 mutex_t		krb5_mutex;
134 #endif
135 
136 /* krb5 mechanism oids */
137 
138 const gss_OID_desc krb5_gss_oid_array[] = {
139    /* this is the official, rfc-specified OID */
140    {9, "\052\206\110\206\367\022\001\002\002"},
141    /* this is the unofficial, wrong OID */
142    {5, "\053\005\001\005\002"},
143    /* this is the v2 assigned OID */
144    {9, "\052\206\110\206\367\022\001\002\003"},
145    /* these two are name type OID's */
146    {10, "\052\206\110\206\367\022\001\002\002\001"},
147    /* XXX this value isn't defined in an RFC */
148    {10, "\052\206\110\206\367\022\001\002\002\002"},
149    /*
150     * Solaris Kerberos: the following element is the GSS_KRB5_NT_USER_NAME OID
151     * (1.2.840.113554.1.2.1.1, see RFC 1964) which is used for backward
152     * compatibility with earlier Solaris kerberos releases.
153     */
154    {10, "\052\206\110\206\367\022\001\002\001\001"},
155    { 0, 0 }
156 };
157 
158 const gss_OID_desc * const gss_mech_krb5 = krb5_gss_oid_array+0;
159 const gss_OID_desc * const gss_mech_krb5_old = krb5_gss_oid_array+1;
160 const gss_OID_desc * const gss_mech_krb5_v2 = krb5_gss_oid_array+2;
161 
162 /*
163  * Solaris Kerberos: gss_nt_krb5_name points to the GSS_KRB5_NT_USER_NAME OID
164  * for backwards compat with earlier Solaris Kerberos releases.  In MIT this
165  * points to the GSS_KRB5_NT_PRINCIPAL_NAME OID (1.2.840.113554.1.2.2.1).
166  */
167 
168 const gss_OID_desc * const gss_nt_krb5_name = krb5_gss_oid_array+5;
169 
170 /*
171  * XXX gss_nt_krb5_principal points to an OID value that is specific to MIT
172  * which is not described in any RFC at this point.  Be cautious about using
173  * this.
174  */
175 
176 const gss_OID_desc * const gss_nt_krb5_principal = krb5_gss_oid_array+4;
177 
178 static const gss_OID_set_desc oidsets[] = {
179    {1, (gss_OID) krb5_gss_oid_array+0},
180    {1, (gss_OID) krb5_gss_oid_array+1},
181    {2, (gss_OID) krb5_gss_oid_array+0},
182    {1, (gss_OID) krb5_gss_oid_array+2},
183    {3, (gss_OID) krb5_gss_oid_array+0},
184 };
185 
186 const gss_OID_set_desc * const gss_mech_set_krb5 = oidsets+0;
187 const gss_OID_set_desc * const gss_mech_set_krb5_old = oidsets+1;
188 const gss_OID_set_desc * const gss_mech_set_krb5_both = oidsets+2;
189 const gss_OID_set_desc * const gss_mech_set_krb5_v2 = oidsets+3;
190 const gss_OID_set_desc * const gss_mech_set_krb5_v1v2 = oidsets+4;
191 
192 void *kg_vdb = NULL;
193 
194 /** default credential support */
195 
196 /* default credentials */
197 
198 /*
199  * Solaris Kerberos:
200  * We no longer store the defcred in a global variable since this will
201  * prevent us from assuming different user ids by gss daemon.
202  * This also makes gss_release_defcred a no-op.
203  */
204 #if 0
205 static gss_cred_id_t defcred = GSS_C_NO_CREDENTIAL;
206 #endif
207 
208 krb5_context kg_context = NULL;
209 
210 /* XXX what happens when the default credentials expire or are invalidated? */
211 
212 #ifndef  _KERNEL
213 
214 /* Note, the krb5_mutex lock must be held prior to calling this function */
215 OM_uint32
216 kg_get_defcred(minor_status, cred)
217      OM_uint32 *minor_status;
218      gss_cred_id_t *cred;
219 {
220 OM_uint32 major;
221 
222    KRB5_LOG0(KRB5_INFO, "kg_get_defcred() start\n");
223 
224    if (!kg_context && GSS_ERROR(kg_get_context(minor_status,&kg_context))){
225 	 KRB5_LOG(KRB5_ERR, "kg_get_defcred() end, error, kg_get_context() "
226 		 "minor_status=%d\n", *minor_status);
227       return GSS_S_FAILURE;
228    }
229 
230       major = krb5_gss_acquire_cred_no_lock(kg_context,minor_status,
231 	(gss_name_t) NULL, GSS_C_INDEFINITE, GSS_C_NULL_OID_SET, GSS_C_INITIATE,
232 	 cred, NULL, NULL);
233       if (major && GSS_ERROR(major)) {
234 	 *cred = GSS_C_NO_CREDENTIAL;
235 	 KRB5_LOG(KRB5_ERR, "kg_get_defcred() end, error major=%d\n", major);
236 	 return(major);
237       }
238 
239    *minor_status = 0;
240    KRB5_LOG0(KRB5_INFO, "kg_get_defcred() end\n");
241    return(GSS_S_COMPLETE);
242 }
243 
244 OM_uint32
245 kg_release_defcred(minor_status)
246      OM_uint32 *minor_status;
247 {
248       *minor_status = 0;
249       return(GSS_S_COMPLETE);
250 }
251 
252 OM_uint32
253 kg_get_context(minor_status, context)
254    OM_uint32 *minor_status;
255    krb5_context *context;
256 {
257    /*
258     * Solaris Kerberos:  the following is a global variable declared
259     * above and initialized here below
260     */
261    /* static krb5_context kg_context = NULL; */
262    krb5_error_code code;
263 
264    KRB5_LOG0(KRB5_INFO, "kg_get_context() start\n");
265 
266    if (!kg_context) {
267 	   if ((code = krb5_init_context(&kg_context)))
268 		   goto fail;
269 	   if ((code = krb5_ser_context_init(kg_context)))
270 		   goto fail;
271 	   if ((code = krb5_ser_auth_context_init(kg_context)))
272 		   goto fail;
273 	   if ((code = krb5_ser_ccache_init(kg_context)))
274 		   goto fail;
275 	   if ((code = krb5_ser_rcache_init(kg_context)))
276 		   goto fail;
277 	   if ((code = krb5_ser_keytab_init(kg_context)))
278 		   goto fail;
279 	   if ((code = krb5_ser_auth_context_init(kg_context)))
280 	       goto fail;
281    }
282    *context = kg_context;
283    *minor_status = 0;
284    KRB5_LOG0(KRB5_INFO, "kg_get_context() end\n");
285    return GSS_S_COMPLETE;
286 
287 fail:
288    *minor_status = (OM_uint32) code;
289    KRB5_LOG(KRB5_ERR, "kg_get_context() end, error code=%d\n", code);
290    return GSS_S_FAILURE;
291 }
292 #endif
293