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