xref: /illumos-gate/usr/src/uts/common/gssapi/mechs/krb5/mech/gssapi_krb5.c (revision 55fea89dcaa64928bed4327112404dcb3e07b79f)
17c478bd9Sstevel@tonic-gate /*
2*5e01956fSGlenn Barry  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
37c478bd9Sstevel@tonic-gate  */
47c478bd9Sstevel@tonic-gate 
57c478bd9Sstevel@tonic-gate 
67c478bd9Sstevel@tonic-gate /*
77c478bd9Sstevel@tonic-gate  * Copyright 1993 by OpenVision Technologies, Inc.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * Permission to use, copy, modify, distribute, and sell this software
107c478bd9Sstevel@tonic-gate  * and its documentation for any purpose is hereby granted without fee,
117c478bd9Sstevel@tonic-gate  * provided that the above copyright notice appears in all copies and
127c478bd9Sstevel@tonic-gate  * that both that copyright notice and this permission notice appear in
137c478bd9Sstevel@tonic-gate  * supporting documentation, and that the name of OpenVision not be used
147c478bd9Sstevel@tonic-gate  * in advertising or publicity pertaining to distribution of the software
157c478bd9Sstevel@tonic-gate  * without specific, written prior permission. OpenVision makes no
167c478bd9Sstevel@tonic-gate  * representations about the suitability of this software for any
177c478bd9Sstevel@tonic-gate  * purpose.  It is provided "as is" without express or implied warranty.
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
207c478bd9Sstevel@tonic-gate  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
217c478bd9Sstevel@tonic-gate  * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
227c478bd9Sstevel@tonic-gate  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
237c478bd9Sstevel@tonic-gate  * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
247c478bd9Sstevel@tonic-gate  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
257c478bd9Sstevel@tonic-gate  * PERFORMANCE OF THIS SOFTWARE.
267c478bd9Sstevel@tonic-gate  */
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate /*
297c478bd9Sstevel@tonic-gate  * Copyright (C) 1998 by the FundsXpress, INC.
307c478bd9Sstevel@tonic-gate  *
317c478bd9Sstevel@tonic-gate  * All rights reserved.
327c478bd9Sstevel@tonic-gate  *
337c478bd9Sstevel@tonic-gate  * Export of this software from the United States of America may require
347c478bd9Sstevel@tonic-gate  * a specific license from the United States Government.  It is the
357c478bd9Sstevel@tonic-gate  * responsibility of any person or organization contemplating export to
367c478bd9Sstevel@tonic-gate  * obtain such a license before exporting.
377c478bd9Sstevel@tonic-gate  *
387c478bd9Sstevel@tonic-gate  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
397c478bd9Sstevel@tonic-gate  * distribute this software and its documentation for any purpose and
407c478bd9Sstevel@tonic-gate  * without fee is hereby granted, provided that the above copyright
417c478bd9Sstevel@tonic-gate  * notice appear in all copies and that both that copyright notice and
427c478bd9Sstevel@tonic-gate  * this permission notice appear in supporting documentation, and that
437c478bd9Sstevel@tonic-gate  * the name of FundsXpress. not be used in advertising or publicity pertaining
447c478bd9Sstevel@tonic-gate  * to distribution of the software without specific, written prior
457c478bd9Sstevel@tonic-gate  * permission.  FundsXpress makes no representations about the suitability of
467c478bd9Sstevel@tonic-gate  * this software for any purpose.  It is provided "as is" without express
477c478bd9Sstevel@tonic-gate  * or implied warranty.
487c478bd9Sstevel@tonic-gate  *
497c478bd9Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
507c478bd9Sstevel@tonic-gate  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
517c478bd9Sstevel@tonic-gate  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
527c478bd9Sstevel@tonic-gate  */
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate /*
55159d09a2SMark Phalan  * $Id: gssapi_krb5.c 18343 2006-07-19 18:14:01Z lxs $
567c478bd9Sstevel@tonic-gate  */
577c478bd9Sstevel@tonic-gate 
58ab9b2e15Sgtb 
59ab9b2e15Sgtb /* For declaration of krb5_ser_context_init */
60ab9b2e15Sgtb #include "k5-int.h"
61ab9b2e15Sgtb #include "gssapiP_krb5.h"
62*5e01956fSGlenn Barry #ifndef	_KERNEL
63*5e01956fSGlenn Barry #include "gss_libinit.h"
64*5e01956fSGlenn Barry #endif
657c478bd9Sstevel@tonic-gate 
667c478bd9Sstevel@tonic-gate /*
67ab9b2e15Sgtb  * Solaris Kerberos
687c478bd9Sstevel@tonic-gate  * Kernel kgssd module debugging aid. The global variable "krb5_log" is a bit
697c478bd9Sstevel@tonic-gate  * mask which allows various types of log messages to be printed out.
707c478bd9Sstevel@tonic-gate  *
717c478bd9Sstevel@tonic-gate  * The log levels are defined in:
727c478bd9Sstevel@tonic-gate  * usr/src/uts/common/gssapi/mechs/krb5/include/k5-int.h
737c478bd9Sstevel@tonic-gate  *
74ab9b2e15Sgtb  * Note, KRB5_LOG_LVL can be assigned via the make invocation.
75ab9b2e15Sgtb  * See KRB5_DEFS in the various Makefiles.
767c478bd9Sstevel@tonic-gate  */
777c478bd9Sstevel@tonic-gate 
787c478bd9Sstevel@tonic-gate #ifdef KRB5_LOG_LVL
797c478bd9Sstevel@tonic-gate /* set the log level to that specified */
807c478bd9Sstevel@tonic-gate u_int krb5_log = KRB5_LOG_LVL;
817c478bd9Sstevel@tonic-gate #else
827c478bd9Sstevel@tonic-gate /* default log level */
837c478bd9Sstevel@tonic-gate u_int krb5_log = 0;
847c478bd9Sstevel@tonic-gate #endif /* KRB5_LOG_LVL */
857c478bd9Sstevel@tonic-gate 
867c478bd9Sstevel@tonic-gate /** exported constants defined in gssapi_krb5{,_nx}.h **/
877c478bd9Sstevel@tonic-gate 
887c478bd9Sstevel@tonic-gate /* these are bogus, but will compile */
897c478bd9Sstevel@tonic-gate 
907c478bd9Sstevel@tonic-gate /*
917c478bd9Sstevel@tonic-gate  * The OID of the draft krb5 mechanism, assigned by IETF, is:
927c478bd9Sstevel@tonic-gate  * 	iso(1) org(3) dod(5) internet(1) security(5)
937c478bd9Sstevel@tonic-gate  *	kerberosv5(2) = 1.3.5.1.5.2
947c478bd9Sstevel@tonic-gate  * The OID of the krb5_name type is:
957c478bd9Sstevel@tonic-gate  * 	iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2)
967c478bd9Sstevel@tonic-gate  * 	krb5(2) krb5_name(1) = 1.2.840.113554.1.2.2.1
977c478bd9Sstevel@tonic-gate  * The OID of the krb5_principal type is:
987c478bd9Sstevel@tonic-gate  * 	iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2)
997c478bd9Sstevel@tonic-gate  * 	krb5(2) krb5_principal(2) = 1.2.840.113554.1.2.2.2
1007c478bd9Sstevel@tonic-gate  * The OID of the proposed standard krb5 mechanism is:
1017c478bd9Sstevel@tonic-gate  * 	iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2)
1027c478bd9Sstevel@tonic-gate  * 	krb5(2) = 1.2.840.113554.1.2.2
1037c478bd9Sstevel@tonic-gate  * The OID of the proposed standard krb5 v2 mechanism is:
1047c478bd9Sstevel@tonic-gate  * 	iso(1) member-body(2) US(840) mit(113554) infosys(1) gssapi(2)
1057c478bd9Sstevel@tonic-gate  * 	krb5v2(3) = 1.2.840.113554.1.2.3
1067c478bd9Sstevel@tonic-gate  *
1077c478bd9Sstevel@tonic-gate  */
1087c478bd9Sstevel@tonic-gate 
1097c478bd9Sstevel@tonic-gate /*
1107c478bd9Sstevel@tonic-gate  * Encoding rules: The first two values are encoded in one byte as 40
1117c478bd9Sstevel@tonic-gate  * * value1 + value2.  Subsequent values are encoded base 128, most
1127c478bd9Sstevel@tonic-gate  * significant digit first, with the high bit (\200) set on all octets
1137c478bd9Sstevel@tonic-gate  * except the last in each value's encoding.
1147c478bd9Sstevel@tonic-gate  */
1157c478bd9Sstevel@tonic-gate 
1167c478bd9Sstevel@tonic-gate const gss_OID_desc krb5_gss_oid_array[] = {
1177c478bd9Sstevel@tonic-gate    /* this is the official, rfc-specified OID */
118ab9b2e15Sgtb    {GSS_MECH_KRB5_OID_LENGTH, GSS_MECH_KRB5_OID},
119ab9b2e15Sgtb    /* this pre-RFC mech OID */
120ab9b2e15Sgtb    {GSS_MECH_KRB5_OLD_OID_LENGTH, GSS_MECH_KRB5_OLD_OID},
121ab9b2e15Sgtb    /* this is the unofficial, incorrect mech OID emitted by MS */
122ab9b2e15Sgtb    {GSS_MECH_KRB5_WRONG_OID_LENGTH, GSS_MECH_KRB5_WRONG_OID},
1237c478bd9Sstevel@tonic-gate    /* this is the v2 assigned OID */
1247c478bd9Sstevel@tonic-gate    {9, "\052\206\110\206\367\022\001\002\003"},
1257c478bd9Sstevel@tonic-gate    /* these two are name type OID's */
126ab9b2e15Sgtb 
127ab9b2e15Sgtb     /* 2.1.1. Kerberos Principal Name Form:  (rfc 1964)
128ab9b2e15Sgtb      * This name form shall be represented by the Object Identifier {iso(1)
129ab9b2e15Sgtb      * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
130ab9b2e15Sgtb      * krb5(2) krb5_name(1)}.  The recommended symbolic name for this type
131ab9b2e15Sgtb      * is "GSS_KRB5_NT_PRINCIPAL_NAME". */
1327c478bd9Sstevel@tonic-gate    {10, "\052\206\110\206\367\022\001\002\002\001"},
133ab9b2e15Sgtb 
134ab9b2e15Sgtb    /* gss_nt_krb5_principal.  Object identifier for a krb5_principal. Do not use. */
1357c478bd9Sstevel@tonic-gate    {10, "\052\206\110\206\367\022\001\002\002\002"},
1367c478bd9Sstevel@tonic-gate    { 0, 0 }
1377c478bd9Sstevel@tonic-gate };
1387c478bd9Sstevel@tonic-gate 
1397c478bd9Sstevel@tonic-gate const gss_OID_desc * const gss_mech_krb5              = krb5_gss_oid_array+0;
1407c478bd9Sstevel@tonic-gate const gss_OID_desc * const gss_mech_krb5_old          = krb5_gss_oid_array+1;
141ab9b2e15Sgtb const gss_OID_desc * const gss_mech_krb5_wrong        = krb5_gss_oid_array+2;
142ab9b2e15Sgtb const gss_OID_desc * const gss_nt_krb5_name           = krb5_gss_oid_array+4;
143ab9b2e15Sgtb const gss_OID_desc * const gss_nt_krb5_principal      = krb5_gss_oid_array+5;
144ab9b2e15Sgtb const gss_OID_desc * const GSS_KRB5_NT_PRINCIPAL_NAME = krb5_gss_oid_array+4;
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate static const gss_OID_set_desc oidsets[] = {
1477c478bd9Sstevel@tonic-gate    {1, (gss_OID) krb5_gss_oid_array+0},
1487c478bd9Sstevel@tonic-gate    {1, (gss_OID) krb5_gss_oid_array+1},
149ab9b2e15Sgtb    {3, (gss_OID) krb5_gss_oid_array+0},
1507c478bd9Sstevel@tonic-gate    {1, (gss_OID) krb5_gss_oid_array+2},
1517c478bd9Sstevel@tonic-gate    {3, (gss_OID) krb5_gss_oid_array+0},
1527c478bd9Sstevel@tonic-gate };
1537c478bd9Sstevel@tonic-gate 
1547c478bd9Sstevel@tonic-gate const gss_OID_set_desc * const gss_mech_set_krb5 = oidsets+0;
1557c478bd9Sstevel@tonic-gate const gss_OID_set_desc * const gss_mech_set_krb5_old = oidsets+1;
1567c478bd9Sstevel@tonic-gate const gss_OID_set_desc * const gss_mech_set_krb5_both = oidsets+2;
1577c478bd9Sstevel@tonic-gate 
158ab9b2e15Sgtb g_set kg_vdb = G_SET_INIT;
1597c478bd9Sstevel@tonic-gate 
1607c478bd9Sstevel@tonic-gate /** default credential support */
1617c478bd9Sstevel@tonic-gate 
1627c478bd9Sstevel@tonic-gate #ifndef  _KERNEL
1637c478bd9Sstevel@tonic-gate 
164ab9b2e15Sgtb /*
165ab9b2e15Sgtb  * init_sec_context() will explicitly re-acquire default credentials,
166ab9b2e15Sgtb  * so handling the expiration/invalidation condition here isn't needed.
167ab9b2e15Sgtb  */
1687c478bd9Sstevel@tonic-gate OM_uint32
kg_get_defcred(minor_status,cred)1697c478bd9Sstevel@tonic-gate kg_get_defcred(minor_status, cred)
1707c478bd9Sstevel@tonic-gate      OM_uint32 *minor_status;
1717c478bd9Sstevel@tonic-gate      gss_cred_id_t *cred;
1727c478bd9Sstevel@tonic-gate {
1737c478bd9Sstevel@tonic-gate     OM_uint32 major;
1747c478bd9Sstevel@tonic-gate 
175ab9b2e15Sgtb     if ((major = krb5_gss_acquire_cred(minor_status,
176ab9b2e15Sgtb 				      (gss_name_t) NULL, GSS_C_INDEFINITE,
177ab9b2e15Sgtb 				      GSS_C_NULL_OID_SET, GSS_C_INITIATE,
178ab9b2e15Sgtb 				      cred, NULL, NULL)) && GSS_ERROR(major)) {
1797c478bd9Sstevel@tonic-gate       return(major);
1807c478bd9Sstevel@tonic-gate    }
1817c478bd9Sstevel@tonic-gate    *minor_status = 0;
1827c478bd9Sstevel@tonic-gate    return(GSS_S_COMPLETE);
1837c478bd9Sstevel@tonic-gate }
1847c478bd9Sstevel@tonic-gate 
1857c478bd9Sstevel@tonic-gate OM_uint32
kg_sync_ccache_name(krb5_context context,OM_uint32 * minor_status)186ab9b2e15Sgtb kg_sync_ccache_name (krb5_context context, OM_uint32 *minor_status)
1877c478bd9Sstevel@tonic-gate {
188ab9b2e15Sgtb     OM_uint32 err = 0;
189ab9b2e15Sgtb 
1907c478bd9Sstevel@tonic-gate     /*
191ab9b2e15Sgtb      * Sync up the context ccache name with the GSSAPI ccache name.
192ab9b2e15Sgtb      * If kg_ccache_name is NULL -- normal unless someone has called
193ab9b2e15Sgtb      * gss_krb5_ccache_name() -- then the system default ccache will
194ab9b2e15Sgtb      * be picked up and used by resetting the context default ccache.
195ab9b2e15Sgtb      * This is needed for platforms which support multiple ccaches.
1967c478bd9Sstevel@tonic-gate      */
1977c478bd9Sstevel@tonic-gate 
198ab9b2e15Sgtb     if (!err) {
199ab9b2e15Sgtb         /* if NULL, resets the context default ccache */
200ab9b2e15Sgtb         err = krb5_cc_set_default_name(context,
201ab9b2e15Sgtb 				       (char *) k5_getspecific(K5_KEY_GSS_KRB5_CCACHE_NAME));
2027c478bd9Sstevel@tonic-gate     }
2037c478bd9Sstevel@tonic-gate 
204ab9b2e15Sgtb     *minor_status = err;
205ab9b2e15Sgtb     return (*minor_status == 0) ? GSS_S_COMPLETE : GSS_S_FAILURE;
206ab9b2e15Sgtb }
207ab9b2e15Sgtb 
208159d09a2SMark Phalan /* This function returns whether or not the caller set a cccache name.  Used by
209159d09a2SMark Phalan  * gss_acquire_cred to figure out if the caller wants to only look at this
210159d09a2SMark Phalan  * ccache or search the cache collection for the desired name */
211159d09a2SMark Phalan OM_uint32
kg_caller_provided_ccache_name(OM_uint32 * minor_status,int * out_caller_provided_name)212159d09a2SMark Phalan kg_caller_provided_ccache_name (OM_uint32 *minor_status,
213159d09a2SMark Phalan int *out_caller_provided_name)
214159d09a2SMark Phalan {
215159d09a2SMark Phalan     if (out_caller_provided_name) {
216159d09a2SMark Phalan         *out_caller_provided_name =
217159d09a2SMark Phalan 	  (k5_getspecific(K5_KEY_GSS_KRB5_CCACHE_NAME) != NULL);
218159d09a2SMark Phalan     }
219159d09a2SMark Phalan 
220159d09a2SMark Phalan     *minor_status = 0;
221159d09a2SMark Phalan     return GSS_S_COMPLETE;
222159d09a2SMark Phalan }
223159d09a2SMark Phalan 
224ab9b2e15Sgtb OM_uint32
kg_get_ccache_name(OM_uint32 * minor_status,const char ** out_name)225ab9b2e15Sgtb kg_get_ccache_name (OM_uint32 *minor_status, const char **out_name)
226ab9b2e15Sgtb {
227ab9b2e15Sgtb     const char *name = NULL;
228ab9b2e15Sgtb     OM_uint32 err = 0;
229ab9b2e15Sgtb     char *kg_ccache_name;
230ab9b2e15Sgtb 
231ab9b2e15Sgtb     kg_ccache_name = k5_getspecific(K5_KEY_GSS_KRB5_CCACHE_NAME);
232ab9b2e15Sgtb 
233ab9b2e15Sgtb     if (kg_ccache_name != NULL) {
234ab9b2e15Sgtb 	name = strdup(kg_ccache_name);
235ab9b2e15Sgtb 	if (name == NULL)
236ab9b2e15Sgtb 	    err = errno;
237ab9b2e15Sgtb     } else {
238ab9b2e15Sgtb 	krb5_context context = NULL;
239ab9b2e15Sgtb 
240ab9b2e15Sgtb 	/* Reset the context default ccache (see text above), and then
241ab9b2e15Sgtb 	   retrieve it.  */
242ab9b2e15Sgtb 	err = krb5_gss_init_context(&context);
243ab9b2e15Sgtb 	if (!err)
244ab9b2e15Sgtb 	    err = krb5_cc_set_default_name (context, NULL);
245ab9b2e15Sgtb 	if (!err) {
246ab9b2e15Sgtb 	    name = krb5_cc_default_name(context);
247ab9b2e15Sgtb 	    if (name) {
248ab9b2e15Sgtb 		name = strdup(name);
249ab9b2e15Sgtb 		if (name == NULL)
250*5e01956fSGlenn Barry 		    err = ENOMEM;
251ab9b2e15Sgtb 	    }
252ab9b2e15Sgtb 	}
253*5e01956fSGlenn Barry 	if (err && context)
254*5e01956fSGlenn Barry 	    save_error_info(err, context);
255ab9b2e15Sgtb    	if (context)
256ab9b2e15Sgtb 	    krb5_free_context(context);
257ab9b2e15Sgtb     }
258ab9b2e15Sgtb 
259ab9b2e15Sgtb     if (!err) {
260ab9b2e15Sgtb         if (out_name) {
261ab9b2e15Sgtb             *out_name = name;
262ab9b2e15Sgtb         }
263ab9b2e15Sgtb     }
264ab9b2e15Sgtb 
265ab9b2e15Sgtb     *minor_status = err;
266ab9b2e15Sgtb     return (*minor_status == 0) ? GSS_S_COMPLETE : GSS_S_FAILURE;
267ab9b2e15Sgtb }
268ab9b2e15Sgtb 
269ab9b2e15Sgtb OM_uint32
kg_set_ccache_name(OM_uint32 * minor_status,const char * name)270ab9b2e15Sgtb kg_set_ccache_name (OM_uint32 *minor_status, const char *name)
271ab9b2e15Sgtb {
272ab9b2e15Sgtb     char *new_name = NULL;
273ab9b2e15Sgtb     char *swap = NULL;
274ab9b2e15Sgtb     char *kg_ccache_name;
275ab9b2e15Sgtb     krb5_error_code kerr;
276ab9b2e15Sgtb 
277ab9b2e15Sgtb     if (name) {
278ab9b2e15Sgtb 	new_name = malloc(strlen(name) + 1);
279ab9b2e15Sgtb 	if (new_name == NULL) {
280ab9b2e15Sgtb 	    *minor_status = ENOMEM;
2817c478bd9Sstevel@tonic-gate 	    return GSS_S_FAILURE;
2827c478bd9Sstevel@tonic-gate 	}
283ab9b2e15Sgtb 	strcpy(new_name, name);
284ab9b2e15Sgtb     }
285ab9b2e15Sgtb 
286ab9b2e15Sgtb     kg_ccache_name = k5_getspecific(K5_KEY_GSS_KRB5_CCACHE_NAME);
287ab9b2e15Sgtb     swap = kg_ccache_name;
288ab9b2e15Sgtb     kg_ccache_name = new_name;
289ab9b2e15Sgtb     new_name = swap;
290ab9b2e15Sgtb     kerr = k5_setspecific(K5_KEY_GSS_KRB5_CCACHE_NAME, kg_ccache_name);
291ab9b2e15Sgtb     if (kerr != 0) {
292ab9b2e15Sgtb 	/* Can't store, so free up the storage.  */
293ab9b2e15Sgtb 	free(kg_ccache_name);
294ab9b2e15Sgtb 	/* ??? free(new_name); */
295ab9b2e15Sgtb 	*minor_status = kerr;
296ab9b2e15Sgtb 	return GSS_S_FAILURE;
297ab9b2e15Sgtb     }
298ab9b2e15Sgtb 
299ab9b2e15Sgtb     free (new_name);
300ab9b2e15Sgtb     *minor_status = 0;
301ab9b2e15Sgtb     return GSS_S_COMPLETE;
302ab9b2e15Sgtb }
303ba7b222eSGlenn Barry 
304ba7b222eSGlenn Barry #define g_OID_prefix_equal(o1, o2) \
305ba7b222eSGlenn Barry         (((o1)->length >= (o2)->length) && \
306ba7b222eSGlenn Barry         (memcmp((o1)->elements, (o2)->elements, (o2)->length) == 0))
307ba7b222eSGlenn Barry 
308ba7b222eSGlenn Barry /*
309ba7b222eSGlenn Barry  * gss_inquire_sec_context_by_oid() methods
310ba7b222eSGlenn Barry  */
311ba7b222eSGlenn Barry static struct {
312ba7b222eSGlenn Barry     gss_OID_desc oid;
313ba7b222eSGlenn Barry     OM_uint32 (*func)(OM_uint32 *, const gss_ctx_id_t, const gss_OID, gss_buffer_set_t *);
314ba7b222eSGlenn Barry } krb5_gss_inquire_sec_context_by_oid_ops[] = {
315ba7b222eSGlenn Barry     {
316ba7b222eSGlenn Barry         {GSS_KRB5_GET_TKT_FLAGS_OID_LENGTH, GSS_KRB5_GET_TKT_FLAGS_OID},
317ba7b222eSGlenn Barry         gss_krb5int_get_tkt_flags
318ba7b222eSGlenn Barry     },
319ba7b222eSGlenn Barry     {
320ba7b222eSGlenn Barry         {GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_OID_LENGTH, GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_OID},
321ba7b222eSGlenn Barry         gss_krb5int_extract_authz_data_from_sec_context
322ba7b222eSGlenn Barry     },
323ba7b222eSGlenn Barry     {
324ba7b222eSGlenn Barry         {GSS_KRB5_INQ_SSPI_SESSION_KEY_OID_LENGTH, GSS_KRB5_INQ_SSPI_SESSION_KEY_OID},
325ba7b222eSGlenn Barry         gss_krb5int_inq_session_key
326ba7b222eSGlenn Barry     },
327ba7b222eSGlenn Barry     {
328ba7b222eSGlenn Barry         {GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT_OID_LENGTH, GSS_KRB5_EXPORT_LUCID_SEC_CONTEXT_OID},
329ba7b222eSGlenn Barry         gss_krb5int_export_lucid_sec_context
330ba7b222eSGlenn Barry     },
331ba7b222eSGlenn Barry     {
332ba7b222eSGlenn Barry         {GSS_KRB5_EXTRACT_AUTHTIME_FROM_SEC_CONTEXT_OID_LENGTH, GSS_KRB5_EXTRACT_AUTHTIME_FROM_SEC_CONTEXT_OID},
333ba7b222eSGlenn Barry         gss_krb5int_extract_authtime_from_sec_context
334ba7b222eSGlenn Barry     }
335ba7b222eSGlenn Barry };
336ba7b222eSGlenn Barry 
337ba7b222eSGlenn Barry OM_uint32
krb5_gss_inquire_sec_context_by_oid(OM_uint32 * minor_status,const gss_ctx_id_t context_handle,const gss_OID desired_object,gss_buffer_set_t * data_set)338ba7b222eSGlenn Barry krb5_gss_inquire_sec_context_by_oid (OM_uint32 *minor_status,
339ba7b222eSGlenn Barry                                      const gss_ctx_id_t context_handle,
340ba7b222eSGlenn Barry                                      const gss_OID desired_object,
341ba7b222eSGlenn Barry                                      gss_buffer_set_t *data_set)
342ba7b222eSGlenn Barry {
343ba7b222eSGlenn Barry     krb5_gss_ctx_id_rec *ctx;
344ba7b222eSGlenn Barry     size_t i;
345ba7b222eSGlenn Barry 
346ba7b222eSGlenn Barry     if (minor_status == NULL)
347ba7b222eSGlenn Barry         return GSS_S_CALL_INACCESSIBLE_WRITE;
348ba7b222eSGlenn Barry 
349ba7b222eSGlenn Barry     *minor_status = 0;
350ba7b222eSGlenn Barry 
351ba7b222eSGlenn Barry     if (desired_object == GSS_C_NO_OID)
352ba7b222eSGlenn Barry         return GSS_S_CALL_INACCESSIBLE_READ;
353ba7b222eSGlenn Barry 
354ba7b222eSGlenn Barry     if (data_set == NULL)
355ba7b222eSGlenn Barry         return GSS_S_CALL_INACCESSIBLE_WRITE;
356ba7b222eSGlenn Barry 
357ba7b222eSGlenn Barry     *data_set = GSS_C_NO_BUFFER_SET;
358ba7b222eSGlenn Barry 
359ba7b222eSGlenn Barry     if (!kg_validate_ctx_id(context_handle))
360ba7b222eSGlenn Barry         return GSS_S_NO_CONTEXT;
361ba7b222eSGlenn Barry 
362ba7b222eSGlenn Barry     ctx = (krb5_gss_ctx_id_rec *) context_handle;
363ba7b222eSGlenn Barry 
364ba7b222eSGlenn Barry     if (!ctx->established)
365ba7b222eSGlenn Barry         return GSS_S_NO_CONTEXT;
366ba7b222eSGlenn Barry 
367ba7b222eSGlenn Barry     for (i = 0; i < sizeof(krb5_gss_inquire_sec_context_by_oid_ops)/
368ba7b222eSGlenn Barry                     sizeof(krb5_gss_inquire_sec_context_by_oid_ops[0]); i++) {
369ba7b222eSGlenn Barry         if (g_OID_prefix_equal(desired_object, &krb5_gss_inquire_sec_context_by_oid_ops[i].oid)) {
370ba7b222eSGlenn Barry             return (*krb5_gss_inquire_sec_context_by_oid_ops[i].func)(minor_status,
371ba7b222eSGlenn Barry                                                                       context_handle,
372ba7b222eSGlenn Barry                                                                       desired_object,
373ba7b222eSGlenn Barry                                                                       data_set);
374ba7b222eSGlenn Barry         }
375ba7b222eSGlenn Barry     }
376ba7b222eSGlenn Barry 
377ba7b222eSGlenn Barry     *minor_status = EINVAL;
378ba7b222eSGlenn Barry 
379ba7b222eSGlenn Barry     return GSS_S_UNAVAILABLE;
380ba7b222eSGlenn Barry }
381ba7b222eSGlenn Barry 
382*5e01956fSGlenn Barry 
383*5e01956fSGlenn Barry #if 0 /* Solaris Kerberos - revisit for full 1.7/next resync */
384*5e01956fSGlenn Barry MAKE_INIT_FUNCTION(gss_krb5int_lib_init);
385*5e01956fSGlenn Barry MAKE_FINI_FUNCTION(gss_krb5int_lib_fini);
3867c478bd9Sstevel@tonic-gate #endif
387*5e01956fSGlenn Barry 
gss_krb5int_initialize_library(void)388*5e01956fSGlenn Barry OM_uint32 gss_krb5int_initialize_library (void)
389*5e01956fSGlenn Barry {
390*5e01956fSGlenn Barry #if 0 /* Solaris Kerberos - revisit for full 1.7/next resync */
391*5e01956fSGlenn Barry #ifdef _GSS_STATIC_LINK
392*5e01956fSGlenn Barry 	return gssint_mechglue_initialize_library();
393*5e01956fSGlenn Barry #else
394*5e01956fSGlenn Barry 	return CALL_INIT_FUNCTION(gss_krb5int_lib_init);
395*5e01956fSGlenn Barry #endif
396*5e01956fSGlenn Barry #endif
397*5e01956fSGlenn Barry 	return gssint_initialize_library();
398*5e01956fSGlenn Barry }
399*5e01956fSGlenn Barry #endif /* !KERNEL */
400