1 /*
2  * Copyright 2004 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  * Copyright 1993 by OpenVision Technologies, Inc.
10  *
11  * Permission to use, copy, modify, distribute, and sell this software
12  * and its documentation for any purpose is hereby granted without fee,
13  * provided that the above copyright notice appears in all copies and
14  * that both that copyright notice and this permission notice appear in
15  * supporting documentation, and that the name of OpenVision not be used
16  * in advertising or publicity pertaining to distribution of the software
17  * without specific, written prior permission. OpenVision makes no
18  * representations about the suitability of this software for any
19  * purpose.  It is provided "as is" without express or implied warranty.
20  *
21  * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
22  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
23  * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
24  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
25  * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
26  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
27  * PERFORMANCE OF THIS SOFTWARE.
28  */
29 
30 #include <gssapiP_krb5.h>
31 
32 /*
33  * $Id: delete_sec_context.c,v 1.15 1998/10/30 02:54:17 marc Exp $
34  */
35 
36 OM_uint32
37 krb5_gss_delete_sec_context(ct,
38 			minor_status,
39 			context_handle,
40 			output_token
41 #ifdef	 _KERNEL
42 		, gssd_ctx_verifier
43 #endif
44 			)
45     void *ct;
46     OM_uint32 *minor_status;
47     gss_ctx_id_t *context_handle;
48     gss_buffer_t output_token;
49 #ifdef	 _KERNEL
50     OM_uint32 gssd_ctx_verifier;
51 #endif
52 {
53    OM_uint32 major_status = GSS_S_FAILURE;
54 
55    mutex_lock(&krb5_mutex);
56 
57    major_status = krb5_gss_delete_sec_context_no_lock(ct, minor_status,
58 	   context_handle, output_token
59 #ifdef   _KERNEL
60            , gssd_ctx_verifier
61 #endif
62 	   );
63    mutex_unlock(&krb5_mutex);
64    return(major_status);
65 
66 }
67 
68 /*ARGSUSED*/
69 OM_uint32
70 krb5_gss_delete_sec_context_no_lock(ct,
71 			minor_status,
72 			context_handle,
73 			output_token
74 #ifdef	 _KERNEL
75 		, gssd_ctx_verifier
76 #endif
77 			)
78      void *ct;
79      OM_uint32 *minor_status;
80      gss_ctx_id_t *context_handle;
81      gss_buffer_t output_token;
82 #ifdef	 _KERNEL
83 	OM_uint32 gssd_ctx_verifier;
84 #endif
85 {
86    krb5_context context = ct;
87    krb5_gss_ctx_id_rec *ctx;
88    OM_uint32 major_status = GSS_S_FAILURE;
89 
90    /* Solaris Kerberos:  we use the global kg_context for MT safe */
91 #if 0
92    if (GSS_ERROR(kg_get_context(minor_status, &context)))
93       return(GSS_S_FAILURE);
94 #endif
95 
96    if (output_token) {
97       output_token->length = 0;
98       output_token->value = NULL;
99    }
100 
101    /*SUPPRESS 29*/
102    if (*context_handle == GSS_C_NO_CONTEXT) {
103       *minor_status = 0;
104       major_status = GSS_S_COMPLETE;
105       goto out;
106    }
107 
108    /*SUPPRESS 29*/
109    /* validate the context handle */
110    if (! kg_validate_ctx_id(*context_handle)) {
111       *minor_status = (OM_uint32) G_VALIDATE_FAILED;
112       major_status = GSS_S_NO_CONTEXT;
113       goto out;
114    }
115 
116    /* construct a delete context token if necessary */
117 
118    if (output_token) {
119       gss_buffer_desc empty;
120       empty.length = 0; empty.value = NULL;
121 
122       if ((major_status = kg_seal(context, minor_status, *context_handle, 0,
123 			   GSS_C_QOP_DEFAULT,
124 			   &empty, NULL, output_token, KG_TOK_DEL_CTX)))
125 	 goto out;
126    }
127 
128    /* invalidate the context handle */
129 
130    (void)kg_delete_ctx_id(*context_handle);
131 
132    /* free all the context state */
133 
134    ctx = (krb5_gss_ctx_id_rec *) *context_handle;
135 
136    if (ctx->seqstate)
137       g_order_free(&(ctx->seqstate));
138 
139    if (ctx->enc)
140       krb5_free_keyblock(context, ctx->enc);
141 
142    if (ctx->seq)
143       krb5_free_keyblock(context, ctx->seq);
144 
145    if (ctx->here)
146       krb5_free_principal(context, ctx->here);
147    if (ctx->there)
148       krb5_free_principal(context, ctx->there);
149    if (ctx->subkey)
150       krb5_free_keyblock(context, ctx->subkey);
151    if (ctx->acceptor_subkey)
152       krb5_free_keyblock(context, ctx->acceptor_subkey);
153 
154 /* We never import the auth_context into the kernel */
155 #ifndef _KERNEL
156    if (ctx->auth_context) {
157        (void)krb5_auth_con_setrcache(context, ctx->auth_context, NULL);
158        krb5_auth_con_free(context, ctx->auth_context);
159    }
160 #endif
161 
162   /* Solaris Kerberos:  the mech_used element of this structure
163    * is the actual gss_OID_desc type in gssapiP_krb5.h, and not
164    * a gss_OID_desc * type, in particular, the gss_release_oid
165    * is not needed, as the oid is memset to zero below, then freed.
166    */
167   if (ctx->mech_used.length) {
168 	xfree_wrap(ctx->mech_used.elements, ctx->mech_used.length);
169         /* gss_release_oid(minor_status, &(ctx->mech_used)); */
170   }
171 
172    /* Zero out context */
173    (void) memset(ctx, 0, sizeof(*ctx));
174    xfree_wrap(ctx, sizeof (krb5_gss_ctx_id_rec));
175 
176    /* zero the handle itself */
177 
178    *context_handle = GSS_C_NO_CONTEXT;
179 
180    *minor_status = 0;
181    major_status = GSS_S_COMPLETE;
182 out:
183    return(major_status);
184 }
185