xref: /illumos-gate/usr/src/uts/common/gssapi/mechs/krb5/krb5mech.c (revision 505d05c73a6e56769f263d4803b22eddd168ee24)
1 /*
2  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  *
5  * A module for Kerberos V5  security mechanism.
6  *
7  */
8 
9 #pragma ident	"%Z%%M%	%I%	%E% SMI"
10 
11 char _depends_on[] = "misc/kgssapi crypto/md5";
12 
13 #include <sys/types.h>
14 #include <sys/modctl.h>
15 #include <sys/errno.h>
16 #include <mechglueP.h>
17 #include <gssapiP_krb5.h>
18 #include <gssapi_err_generic.h>
19 #include <gssapi/kgssapi_defs.h>
20 #include <sys/debug.h>
21 #include <k5-int.h>
22 
23 OM_uint32 krb5_gss_get_context(void ** context);
24 
25 extern krb5_error_code krb5_ser_context_init
26 	(krb5_context);
27 
28 extern	krb5_error_code	krb5_ser_auth_context_init
29 	(krb5_context);
30 
31 static	struct	gss_config krb5_mechanism =
32 	{{9, "\052\206\110\206\367\022\001\002\002"},
33 	NULL,	/* context */
34 	NULL,	/* next */
35 	TRUE,	/* uses_kmod */
36 /* EXPORT DELETE START */ /* CRYPT DELETE START */
37 	krb5_gss_unseal,
38 /* EXPORT DELETE END */ /* CRYPT DELETE END */
39 	krb5_gss_delete_sec_context,
40 /* EXPORT DELETE START */ /* CRYPT DELETE START */
41 	krb5_gss_seal,
42 /* EXPORT DELETE END */ /* CRYPT DELETE END */
43 	krb5_gss_import_sec_context,
44 /* EXPORT DELETE START */
45 /* CRYPT DELETE START */
46 #if 0
47 /* CRYPT DELETE END */
48 	krb5_gss_seal,
49 	krb5_gss_unseal,
50 /* CRYPT DELETE START */
51 #endif
52 /* CRYPT DELETE END */
53 /* EXPORT DELETE END */
54 	krb5_gss_sign,
55 	krb5_gss_verify,
56 };
57 
58 static gss_mechanism
59 	gss_mech_initialize()
60 {
61 	(void) krb5_gss_get_context(&(krb5_mechanism.context));
62 	return (&krb5_mechanism);
63 }
64 
65 
66 /*
67  * Module linkage information for the kernel.
68  */
69 extern struct mod_ops mod_miscops;
70 
71 #if defined(sun4u)
72 
73 static struct modlmisc modlmisc = {
74 	&mod_miscops, "Krb5 GSS mech, sun4u optimized"
75 };
76 
77 #else
78 
79 static struct modlmisc modlmisc = {
80 	&mod_miscops, "Krb5 GSS mechanism"
81 };
82 
83 #endif
84 
85 static struct modlinkage modlinkage = {
86 	MODREV_1,
87 	(void *)&modlmisc,
88 	NULL
89 };
90 
91 
92 static int krb5_fini_code = EBUSY;
93 
94 int
95 _init()
96 {
97 	int retval;
98 	gss_mechanism mech, tmp;
99 
100 	if ((retval = mod_install(&modlinkage)) != 0)
101 		return (retval);
102 
103 	mech = gss_mech_initialize();
104 
105 	mutex_enter(&__kgss_mech_lock);
106 	tmp = __kgss_get_mechanism(&mech->mech_type);
107 	if (tmp != NULL) {
108 
109 		KRB5_LOG0(KRB5_INFO,
110 			"KRB5 GSS mechanism: mechanism already in table.\n");
111 
112 		if (tmp->uses_kmod == TRUE) {
113 			KRB5_LOG0(KRB5_INFO, "KRB5 GSS mechanism: mechanism "
114 				"table supports kernel operations!\n");
115 		}
116 		/*
117 		 * keep us loaded, but let us be unloadable. This
118 		 * will give the developer time to trouble shoot
119 		 */
120 		krb5_fini_code = 0;
121 	} else {
122 		__kgss_add_mechanism(mech);
123 		ASSERT(__kgss_get_mechanism(&mech->mech_type) == mech);
124 	}
125 	mutex_exit(&__kgss_mech_lock);
126 
127 	return (0);
128 }
129 
130 int
131 _fini()
132 {
133 	int ret = krb5_fini_code;
134 
135 	if (ret == 0) {
136 		ret = (mod_remove(&modlinkage));
137 	}
138 	return (ret);
139 }
140 
141 int
142 _info(struct modinfo *modinfop)
143 {
144 	return (mod_info(&modlinkage, modinfop));
145 }
146 
147 OM_uint32
148 krb5_gss_get_context(context)
149 void **	context;
150 {
151 	OM_uint32 major_status = 0;
152 
153 	mutex_lock(&krb5_mutex);
154 	if (context == NULL)
155 	{
156 		major_status = GSS_S_FAILURE;
157 		goto unlock;
158 	}
159 	if (kg_context) {
160 		*context = kg_context;
161 		major_status = GSS_S_COMPLETE;
162 		goto unlock;
163 	}
164 
165 	if (krb5_init_context(&kg_context))
166 	{
167 		major_status = GSS_S_FAILURE;
168 		goto unlock;
169 	}
170 	if (krb5_ser_auth_context_init(kg_context))
171 	{
172 		kg_context = 0;
173 		major_status = GSS_S_FAILURE;
174 		goto unlock;
175 	}
176 
177 	*context = kg_context;
178 unlock:
179 	mutex_unlock(&krb5_mutex);
180 	return (major_status);
181 }
182