dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / gss_mechs / mech_dh / backend / mech / cred.c
blobe05ec6db4a27fa3b105faba6528a70fac5619e7a
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
23 * cred.c
25 * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
26 * Use is subject to license terms.
30 #pragma ident "%Z%%M% %I% %E% SMI"
32 #include <unistd.h>
33 #include <sys/note.h>
34 #include "dh_gssapi.h"
37 * This module supports the GSS credential family of routines for
38 * Diffie-Hellman mechanism.
42 * __dh_gss_acquire_cred: Get the credential associated with principal
43 * with the requested expire time and usage. Return the credential with
44 * the optional set of supported mechs and actual time left on the credential.
46 * Note in Diffie-Hellman the supplied principal name must be that of
47 * the caller. There is no way to delegate credentials.
49 * Libgss alwas sets desired_mechs to GSS_C_NO_OID_SET and set the return
50 * set of mechs to NULL.
53 OM_uint32
54 __dh_gss_acquire_cred(void *ctx, /* Per mechanism context */
55 OM_uint32 *minor, /* Mechanism status */
56 gss_name_t principal, /* Requested principal */
57 OM_uint32 expire_req, /* Requested Expire time */
58 gss_OID_set desired_mechs, /* Set of desired mechs */
59 gss_cred_usage_t usage, /* Usage: init, accept, both */
60 gss_cred_id_t *cred, /* The return credential */
61 gss_OID_set *mechs, /* The return set of mechs */
62 OM_uint32 *expire_rec /* The expire time received*/)
64 /* Diffie-Hellman mechanism context is ctx */
65 dh_context_t cntx = (dh_context_t)ctx;
66 dh_principal netname;
67 dh_cred_id_t dh_cred;
69 /* Need to write to these */
70 if (minor == 0 || cred == 0)
71 return (GSS_S_CALL_INACCESSIBLE_WRITE);
73 /* Set sane outputs */
74 *minor = 0;
75 if (mechs)
76 *mechs = GSS_C_NO_OID_SET;
77 if (expire_rec)
78 *expire_rec = 0;
79 *cred = GSS_C_NO_CREDENTIAL;
82 * If not GSS_C_NO_OID_SET then the set must contain the
83 * Diffie-Hellman mechanism
85 if (desired_mechs != GSS_C_NO_OID_SET &&
86 !__OID_is_member(desired_mechs, cntx->mech))
87 return (GSS_S_BAD_MECH);
89 /* See if the callers secretkey is available */
90 if (!cntx->keyopts->key_secretkey_is_set())
91 return (GSS_S_NO_CRED);
93 /* Get the principal name of the caller */
94 if ((netname = cntx->keyopts->get_principal()) == NULL)
95 return (GSS_S_NO_CRED);
98 * Diffie-Hellman requires the principal to be the principal
99 * of the caller
102 if (principal &&
103 strncmp(netname, (char *)principal, MAXNETNAMELEN) != 0) {
104 Free(netname);
105 return (GSS_S_NO_CRED);
108 /* Allocate the credential */
109 dh_cred = New(dh_cred_id_desc, 1);
110 if (dh_cred == NULL) {
111 Free(netname);
112 *minor = DH_NOMEM_FAILURE;
113 return (GSS_S_FAILURE);
116 /* Set credential state */
117 dh_cred->uid = geteuid();
118 dh_cred->usage = usage;
119 dh_cred->principal = netname;
120 dh_cred->expire = expire_req ? time(0) + expire_req : GSS_C_INDEFINITE;
123 * If mechs set it to the set that contains the appropriate
124 * Diffie-Hellman mechanism
126 if (mechs && (*minor = __OID_to_OID_set(mechs, cntx->mech))) {
127 Free(dh_cred);
128 Free(netname);
129 return (GSS_S_FAILURE);
132 /* Register the credential */
133 if ((*minor = __dh_install_cred(dh_cred)) != DH_SUCCESS) {
134 Free(dh_cred);
135 Free(netname);
136 return (GSS_S_FAILURE);
139 if (expire_rec)
140 *expire_rec = expire_req ? expire_req : GSS_C_INDEFINITE;
142 /* Return the Diffie-Hellman credential through cred */
143 *cred = (gss_cred_id_t)dh_cred;
145 return (GSS_S_COMPLETE);
150 * __dh_gss_add_cred is currently a no-op. All the work is done at the
151 * libgss layer. That layer will invoke the mechanism specific gss_acquire_cred
152 * routine. This entry point should never be called. The entry point for
153 * this routine is set to NULL in dhmech.c.
157 * OM_uint32
158 * __dh_gss_add_cred(void * ctx, OM_uint32 *minor, gss_cred_id_t cred_in,
159 * gss_name_t name, gss_OID mech, gss_cred_usage_t usage,
160 * OM_uint32 init_time_req, OM_uint32 accep_time_req,
161 * gss_cred_id_t *cred_out, gss_OID_set *mechs,
162 * OM_uint32 *init_time_rec, OM_uint32 *accep_time_rec)
164 * return (GSS_S_UNAVAILABLE);
169 * __dh_gss_inquire_cred: Return tracked state of the supplied credential.
171 OM_uint32
172 __dh_gss_inquire_cred(void *ctx, /* Per mechanism context */
173 OM_uint32 *minor, /* Mechanism status */
174 gss_cred_id_t cred, /* cred of interest */
175 gss_name_t *name, /* name of principal */
176 OM_uint32 *lifetime, /* return the time remainning */
177 gss_cred_usage_t *usage, /* usage: init, accept, both */
178 gss_OID_set *mechs /* Set containing mech_dh */)
180 /* cred is a Diffie-Hellman credential */
181 dh_cred_id_t crid = (dh_cred_id_t)cred;
182 /* ctx is a Diffie-Hellman context */
183 dh_context_t cntx = (dh_context_t)ctx;
184 OM_uint32 t = GSS_C_INDEFINITE;
186 if (minor == 0)
187 return (GSS_S_CALL_INACCESSIBLE_WRITE);
188 if (cntx == 0)
189 return (GSS_S_CALL_INACCESSIBLE_READ);
191 *minor = DH_SUCCESS;
193 /* Default case */
194 if (cred == GSS_C_NO_CREDENTIAL) {
195 if (!(*cntx->keyopts->key_secretkey_is_set)())
196 return (GSS_S_NO_CRED);
197 if (name)
198 *name = (gss_name_t)(*cntx->keyopts->get_principal)();
199 if (lifetime)
200 *lifetime = GSS_C_INDEFINITE;
201 if (usage)
202 *usage = GSS_C_BOTH;
203 } else {
204 /* Validate creditial */
205 if ((*minor = __dh_validate_cred(crid)) != DH_SUCCESS)
206 return (GSS_S_DEFECTIVE_CREDENTIAL);
207 if (name)
208 *name = (gss_name_t)strdup(crid->principal);
209 if (lifetime) {
210 if (crid->expire == GSS_C_INDEFINITE)
211 *lifetime = GSS_C_INDEFINITE;
212 else {
213 time_t now = time(0);
214 t = crid->expire > now ? crid->expire-now : 0;
215 *lifetime = t;
218 if (usage)
219 *usage = crid->usage;
222 if (name && *name == 0)
223 return (GSS_S_FAILURE);
226 if (mechs &&
227 (*minor = __OID_to_OID_set(mechs, cntx->mech)) != DH_SUCCESS) {
228 free(name);
229 return (GSS_S_FAILURE);
232 /* Check if the credential is still valid */
233 return (t ? GSS_S_COMPLETE : GSS_S_CREDENTIALS_EXPIRED);
238 * __dh_gss_inquire_cred_by_mech: Return the information associated with
239 * cred and mech. Since we're a backend, mech must be our mech.
241 * We verify that passed in mech is correct and use the above routine
242 * to do the work.
244 OM_uint32
245 __dh_gss_inquire_cred_by_mech(void *ctx, /* Per mechananism context */
246 OM_uint32 *minor, /* Mechanism status */
247 gss_cred_id_t cred, /* Cred to iquire about */
248 gss_OID mech, /* Along with the mechanism */
249 gss_name_t *name, /* where to return principal */
250 OM_uint32 *init_time, /* Init time left */
251 OM_uint32 *accept_time, /* Accept time left */
252 gss_cred_usage_t *usage /* cred usage */)
254 /* ctx is them Diffie-Hellman mechanism context */
255 dh_context_t context = (dh_context_t)ctx;
256 OM_uint32 lifetime;
257 OM_uint32 major;
258 gss_cred_usage_t use;
260 /* This should never happen. It would indicate a libgss failure */
261 if (!__OID_equal(mech, context->mech)) {
262 *minor = DH_BAD_CONTEXT;
263 return (GSS_S_FAILURE);
266 /* Fetch cred info */
267 major = __dh_gss_inquire_cred(ctx, minor, cred, name,
268 &lifetime, &use, NULL);
270 /* Return option values */
271 if (major == GSS_S_COMPLETE) {
272 /* set init_time if we can */
273 if (init_time)
274 *init_time = (use == GSS_C_BOTH ||
275 use == GSS_C_INITIATE) ? lifetime : 0;
276 /* Ditto for accept time */
277 if (accept_time)
278 *accept_time = (use == GSS_C_BOTH ||
279 use == GSS_C_ACCEPT) ? lifetime : 0;
280 if (usage)
281 *usage = use;
284 return (major);
288 * __dh_gss_release_cred: Release the resources associated with cred.
290 OM_uint32
291 __dh_gss_release_cred(void *ctx, /* Per mechananism context (not used) */
292 OM_uint32 *minor, /* Mechanism status */
293 gss_cred_id_t *cred /* The cred to free */)
295 _NOTE(ARGUNUSED(ctx))
296 dh_cred_id_t dh_cred = (dh_cred_id_t)*cred;
298 /* Check that we can read and write required parameters */
299 if (minor == 0 || cred == 0)
300 return (GSS_S_CALL_INACCESSIBLE_WRITE);
302 /* Nothing to do */
303 if (*cred == GSS_C_NO_CREDENTIAL)
304 return (GSS_S_COMPLETE);
306 /* Check if the credential is valid */
307 if ((*minor = __dh_validate_cred(dh_cred)) != DH_SUCCESS)
308 return (GSS_S_NO_CRED);
310 /* Unregister the credential */
311 *minor = __dh_remove_cred(dh_cred);
313 /* Free the principal and the cred itself */
314 Free(dh_cred->principal);
315 Free(dh_cred);
317 /* Set cred to no credential */
318 *cred = GSS_C_NO_CREDENTIAL;
320 return (GSS_S_COMPLETE);