1 /*
2 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
3 */
4 /*
5 * Copyright 1993 by OpenVision Technologies, Inc.
6 *
7 * Permission to use, copy, modify, distribute, and sell this software
8 * and its documentation for any purpose is hereby granted without fee,
9 * provided that the above copyright notice appears in all copies and
10 * that both that copyright notice and this permission notice appear in
11 * supporting documentation, and that the name of OpenVision not be used
12 * in advertising or publicity pertaining to distribution of the software
13 * without specific, written prior permission. OpenVision makes no
14 * representations about the suitability of this software for any
15 * purpose. It is provided "as is" without express or implied warranty.
16 *
17 * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
18 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
19 * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
20 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
21 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
22 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
23 * PERFORMANCE OF THIS SOFTWARE.
24 */
25
26 #include "gssapiP_krb5.h"
27 #include "mglueP.h" /* SUNW15resync - for KGSS_ macros */
28
29 /*
30 * $Id: delete_sec_context.c 18396 2006-07-25 20:29:43Z lxs $
31 */
32
33
34 #ifdef _KERNEL
35 /* SUNW15resync - todo - unify these kernel rel oid funcs with user spc ones */
36
37 OM_uint32
krb5_gss_internal_release_oid(minor_status,oid)38 krb5_gss_internal_release_oid(minor_status, oid)
39 OM_uint32 *minor_status;
40 gss_OID *oid;
41 {
42 /*
43 * This function only knows how to release internal OIDs. It will
44 * return GSS_S_CONTINUE_NEEDED for any OIDs it does not recognize.
45 */
46
47 if ((*oid != gss_mech_krb5) &&
48 (*oid != gss_mech_krb5_old) &&
49 (*oid != gss_mech_krb5_wrong) &&
50 (*oid != gss_nt_krb5_name) &&
51 (*oid != gss_nt_krb5_principal)) {
52 /* We don't know about this OID */
53 return(GSS_S_CONTINUE_NEEDED);
54 }
55 else {
56 *oid = GSS_C_NO_OID;
57 *minor_status = 0;
58 return(GSS_S_COMPLETE);
59 }
60 }
61
62 OM_uint32
generic_gss_release_oid(minor_status,oid)63 generic_gss_release_oid(minor_status, oid)
64 OM_uint32 *minor_status;
65 gss_OID *oid;
66 {
67 if (minor_status)
68 *minor_status = 0;
69
70 if (*oid == GSS_C_NO_OID)
71 return(GSS_S_COMPLETE);
72
73
74 if ((*oid != GSS_C_NT_USER_NAME) &&
75 (*oid != GSS_C_NT_MACHINE_UID_NAME) &&
76 (*oid != GSS_C_NT_STRING_UID_NAME) &&
77 (*oid != GSS_C_NT_HOSTBASED_SERVICE) &&
78 (*oid != GSS_C_NT_ANONYMOUS) &&
79 (*oid != GSS_C_NT_EXPORT_NAME) &&
80 (*oid != gss_nt_service_name)) {
81 FREE((*oid)->elements, (*oid)->length);
82 FREE(*oid, sizeof(gss_OID_desc));
83 }
84 *oid = GSS_C_NO_OID;
85 return(GSS_S_COMPLETE);
86 }
87
88 OM_uint32
krb5_gss_release_oid(minor_status,oid)89 krb5_gss_release_oid(minor_status, oid)
90 OM_uint32 *minor_status;
91 gss_OID *oid;
92 {
93
94 if (krb5_gss_internal_release_oid(minor_status, oid) != GSS_S_COMPLETE) {
95 /* Pawn it off on the generic routine */
96 return(generic_gss_release_oid(minor_status, oid));
97 }
98 else {
99 *oid = GSS_C_NO_OID;
100 *minor_status = 0;
101 return(GSS_S_COMPLETE);
102 }
103 }
104 #endif
105
106 /*ARGSUSED*/
107 OM_uint32
krb5_gss_delete_sec_context(minor_status,context_handle,output_token,gssd_ctx_verifier)108 krb5_gss_delete_sec_context(minor_status,
109 context_handle,
110 output_token
111 #ifdef _KERNEL
112 , gssd_ctx_verifier
113 #endif
114 )
115 OM_uint32 *minor_status;
116 gss_ctx_id_t *context_handle;
117 gss_buffer_t output_token;
118 #ifdef _KERNEL
119 OM_uint32 gssd_ctx_verifier;
120 #endif
121 {
122 krb5_context context;
123 krb5_gss_ctx_id_rec *ctx;
124
125 if (output_token) {
126 output_token->length = 0;
127 output_token->value = NULL;
128 }
129
130 /*SUPPRESS 29*/
131 if (*context_handle == GSS_C_NO_CONTEXT) {
132 *minor_status = 0;
133 return(GSS_S_COMPLETE);
134 }
135
136 /*SUPPRESS 29*/
137 /* validate the context handle */
138 if (! kg_validate_ctx_id(*context_handle)) {
139 *minor_status = (OM_uint32) G_VALIDATE_FAILED;
140 return(GSS_S_NO_CONTEXT);
141 }
142
143 ctx = (krb5_gss_ctx_id_t) *context_handle;
144 context = ctx->k5_context;
145
146 /* construct a delete context token if necessary */
147
148 if (output_token) {
149 OM_uint32 major;
150 gss_buffer_desc empty;
151 empty.length = 0; empty.value = NULL;
152
153 if ((major = kg_seal(minor_status, *context_handle, 0,
154 GSS_C_QOP_DEFAULT,
155 &empty, NULL, output_token, KG_TOK_DEL_CTX))) {
156 save_error_info(*minor_status, context);
157 return(major);
158 }
159 }
160
161 /* invalidate the context handle */
162
163 (void)kg_delete_ctx_id(*context_handle);
164
165 /* free all the context state */
166
167 if (ctx->seqstate)
168 g_order_free(&(ctx->seqstate));
169
170 if (ctx->enc)
171 krb5_free_keyblock(context, ctx->enc);
172
173 if (ctx->seq)
174 krb5_free_keyblock(context, ctx->seq);
175
176 if (ctx->here)
177 krb5_free_principal(context, ctx->here);
178 if (ctx->there)
179 krb5_free_principal(context, ctx->there);
180 if (ctx->subkey)
181 krb5_free_keyblock(context, ctx->subkey);
182 if (ctx->acceptor_subkey)
183 krb5_free_keyblock(context, ctx->acceptor_subkey);
184
185 /* We never import the auth_context into the kernel */
186 #ifndef _KERNEL
187 if (ctx->auth_context) {
188 if (ctx->cred_rcache)
189 (void)krb5_auth_con_setrcache(context, ctx->auth_context, NULL);
190
191 krb5_auth_con_free(context, ctx->auth_context);
192 }
193 #endif
194
195 if (ctx->mech_used)
196 (void) KGSS_RELEASE_OID(minor_status, &ctx->mech_used);
197
198 if (ctx->authdata)
199 krb5_free_authdata(context, ctx->authdata);
200
201 if (ctx->k5_context)
202 krb5_free_context(ctx->k5_context);
203
204 /* Zero out context */
205 (void) memset(ctx, 0, sizeof(*ctx));
206 xfree_wrap(ctx, sizeof (krb5_gss_ctx_id_rec));
207
208 /* zero the handle itself */
209
210 *context_handle = GSS_C_NO_CONTEXT;
211
212 *minor_status = 0;
213 return(GSS_S_COMPLETE);
214 }
215