Print this page
6817447 libgss and various mechs are hiding both the real minor_status and the error token
6405422 Solaris acceptors fail in AD-KDC environments when using non-"host" services (e.g. "cifs")
6824434 Unable to accept context establishment initiated by Windows 2000 clients
6787343 kclient's site lookups fail in certain network environments
6692646 kclient should output errors to stderr
6525327 kinit failed when arcfour-hmac-md5-exp was used for the principal's key
6745582 SUNWkdcu missing package dependencies after kclientv2 integration
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/lib/libgss/g_accept_sec_context.c
+++ new/usr/src/lib/libgss/g_accept_sec_context.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 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.
5 + * Common Development and Distribution License (the "License").
6 + * You may not use this file except in compliance with the License.
8 7 *
9 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 9 * or http://www.opensolaris.org/os/licensing.
11 10 * See the License for the specific language governing permissions
12 11 * and limitations under the License.
13 12 *
14 13 * When distributing Covered Code, include this CDDL HEADER in each
15 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 15 * If applicable, add the following below this CDDL HEADER, with the
17 16 * fields enclosed by brackets "[]" replaced with your own identifying
18 17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 18 *
20 19 * CDDL HEADER END
21 20 */
21 +
22 22 /*
23 - * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
23 + * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26
27 -#pragma ident "%Z%%M% %I% %E% SMI"
28 -
29 27 /*
30 28 * glue routine for gss_accept_sec_context
31 29 */
32 30
33 31 #include <mechglueP.h>
34 32 #ifdef HAVE_STDLIB_H
35 33 #include <stdlib.h>
36 34 #endif
37 35 #include <string.h>
38 36 #include <errno.h>
39 37
40 38 OM_uint32
41 39 gss_accept_sec_context(minor_status,
42 40 context_handle,
43 41 verifier_cred_handle,
44 42 input_token_buffer,
45 43 input_chan_bindings,
46 44 src_name,
47 45 mech_type,
48 46 output_token,
49 47 ret_flags,
50 48 time_rec,
51 49 d_cred)
52 50
53 51 OM_uint32 *minor_status;
54 52 gss_ctx_id_t *context_handle;
55 53 const gss_cred_id_t verifier_cred_handle;
56 54 const gss_buffer_t input_token_buffer;
57 55 const gss_channel_bindings_t input_chan_bindings;
58 56 gss_name_t *src_name;
59 57 gss_OID *mech_type;
60 58 gss_buffer_t output_token;
61 59 OM_uint32 *ret_flags;
62 60 OM_uint32 *time_rec;
63 61 gss_cred_id_t *d_cred; /* delegated cred handle */
64 62
65 63 {
66 64 OM_uint32 status, temp_status, t_minstat;
67 65 gss_union_ctx_id_t union_ctx_id;
68 66 gss_union_cred_t union_cred;
69 67 gss_cred_id_t input_cred_handle = GSS_C_NO_CREDENTIAL;
70 68 gss_cred_id_t tmp_d_cred = GSS_C_NO_CREDENTIAL;
71 69 gss_name_t internal_name = GSS_C_NO_NAME;
72 70 gss_name_t tmp_src_name = GSS_C_NO_NAME;
73 71 gss_OID_desc token_mech_type_desc;
74 72 gss_OID token_mech_type = &token_mech_type_desc;
75 73 gss_OID actual_mech = GSS_C_NO_OID;
76 74 OM_uint32 flags;
77 75 gss_mechanism mech;
78 76
79 77 /* check parameters first */
80 78 if (minor_status == NULL)
81 79 return (GSS_S_CALL_INACCESSIBLE_WRITE);
82 80 *minor_status = 0;
83 81
84 82 if (context_handle == NULL || output_token == NULL)
85 83 return (GSS_S_CALL_INACCESSIBLE_WRITE);
86 84
87 85 /* clear optional fields */
88 86 output_token->value = NULL;
89 87 output_token->length = 0;
90 88 if (src_name)
91 89 *src_name = NULL;
92 90
93 91 if (mech_type)
94 92 *mech_type = NULL;
95 93
96 94 if (d_cred)
97 95 *d_cred = NULL;
98 96 /*
99 97 * if context_handle is GSS_C_NO_CONTEXT, allocate a union context
100 98 * descriptor to hold the mech type information as well as the
101 99 * underlying mechanism context handle. Otherwise, cast the
102 100 * value of *context_handle to the union context variable.
103 101 */
104 102
105 103 if (*context_handle == GSS_C_NO_CONTEXT) {
106 104
107 105 if (GSS_EMPTY_BUFFER(input_token_buffer))
108 106 return (GSS_S_CALL_INACCESSIBLE_READ);
109 107
110 108 /* Get the token mech type */
111 109 status = __gss_get_mech_type(token_mech_type,
112 110 input_token_buffer);
113 111
114 112 if (status)
115 113 return (status);
116 114
117 115 status = GSS_S_FAILURE;
118 116 union_ctx_id = (gss_union_ctx_id_t)
119 117 malloc(sizeof (gss_union_ctx_id_desc));
120 118 if (!union_ctx_id)
121 119 return (GSS_S_FAILURE);
122 120
123 121 union_ctx_id->internal_ctx_id = GSS_C_NO_CONTEXT;
124 122 status = generic_gss_copy_oid(&t_minstat,
125 123 token_mech_type,
126 124 &union_ctx_id->mech_type);
127 125 if (status != GSS_S_COMPLETE) {
128 126 free(union_ctx_id);
129 127 return (status);
130 128 }
131 129
132 130 /* set the new context handle to caller's data */
133 131 *context_handle = (gss_ctx_id_t)union_ctx_id;
134 132 } else {
135 133 union_ctx_id = (gss_union_ctx_id_t)*context_handle;
136 134 token_mech_type = union_ctx_id->mech_type;
137 135 }
138 136
139 137 /*
140 138 * get the appropriate cred handle from the union cred struct.
141 139 * defaults to GSS_C_NO_CREDENTIAL if there is no cred, which will
142 140 * use the default credential.
143 141 */
144 142 union_cred = (gss_union_cred_t)verifier_cred_handle;
145 143 input_cred_handle = __gss_get_mechanism_cred(union_cred,
146 144 token_mech_type);
147 145
148 146 /*
149 147 * now select the approprate underlying mechanism routine and
150 148 * call it.
151 149 */
152 150
153 151 mech = __gss_get_mechanism(token_mech_type);
154 152 if (mech && mech->gss_accept_sec_context) {
155 153 status = mech->gss_accept_sec_context(
156 154 mech->context,
157 155 minor_status,
158 156 &union_ctx_id->internal_ctx_id,
159 157 input_cred_handle,
160 158 input_token_buffer,
161 159 input_chan_bindings,
162 160 &internal_name,
163 161 &actual_mech,
164 162 output_token,
165 163 &flags,
166 164 time_rec,
167 165 d_cred ? &tmp_d_cred : NULL);
168 166
169 167 /* If there's more work to do, keep going... */
170 168 if (status == GSS_S_CONTINUE_NEEDED)
171 169 return (GSS_S_CONTINUE_NEEDED);
172 170
173 171 /* if the call failed, return with failure */
174 172 if (status != GSS_S_COMPLETE)
175 173 goto error_out;
176 174
177 175 if (mech_type != NULL)
178 176 *mech_type = actual_mech;
179 177
180 178 /*
181 179 * if src_name is non-NULL,
182 180 * convert internal_name into a union name equivalent
183 181 * First call the mechanism specific display_name()
184 182 * then call gss_import_name() to create
185 183 * the union name struct cast to src_name
186 184 */
187 185 if (internal_name != NULL) {
188 186 temp_status = __gss_convert_name_to_union_name(
189 187 &t_minstat, mech,
190 188 internal_name, &tmp_src_name);
191 189 if (temp_status != GSS_S_COMPLETE) {
192 190 *minor_status = t_minstat;
193 191 if (output_token->length)
194 192 (void) gss_release_buffer(
195 193 &t_minstat,
196 194 output_token);
197 195 if (internal_name != GSS_C_NO_NAME)
198 196 mech->gss_release_name(
199 197 mech->context,
200 198 &t_minstat,
201 199 &internal_name);
202 200 return (temp_status);
203 201 }
204 202 if (src_name != NULL) {
205 203 *src_name = tmp_src_name;
206 204 }
207 205 } else if (src_name != NULL) {
208 206 *src_name = GSS_C_NO_NAME;
209 207 }
210 208
211 209 /* Ensure we're returning correct creds format */
212 210 if ((flags & GSS_C_DELEG_FLAG) &&
213 211 tmp_d_cred != GSS_C_NO_CREDENTIAL) {
214 212 /*
215 213 * If we got back an OID different from the original
216 214 * token OID, assume the delegated_cred is already
217 215 * a proper union_cred and just return it. Don't
218 216 * try to re-wrap it. This is for SPNEGO or other
219 217 * pseudo-mechanisms.
220 218 */
221 219 if (actual_mech != GSS_C_NO_OID &&
222 220 token_mech_type != GSS_C_NO_OID &&
223 221 !g_OID_equal(actual_mech, token_mech_type)) {
224 222 *d_cred = tmp_d_cred;
225 223 } else {
226 224 gss_union_cred_t d_u_cred = NULL;
227 225
228 226 d_u_cred = malloc(sizeof (gss_union_cred_desc));
229 227 if (d_u_cred == NULL) {
230 228 status = GSS_S_FAILURE;
231 229 goto error_out;
232 230 }
233 231 (void) memset(d_u_cred, 0,
234 232 sizeof (gss_union_cred_desc));
235 233
236 234 d_u_cred->count = 1;
237 235
238 236 status = generic_gss_copy_oid(
239 237 &t_minstat,
240 238 actual_mech,
241 239 &d_u_cred->mechs_array);
242 240
243 241 if (status != GSS_S_COMPLETE) {
244 242 free(d_u_cred);
245 243 goto error_out;
246 244 }
247 245
248 246 d_u_cred->cred_array = malloc(
249 247 sizeof (gss_cred_id_t));
250 248 if (d_u_cred->cred_array != NULL) {
251 249 d_u_cred->cred_array[0] = tmp_d_cred;
252 250 } else {
253 251 free(d_u_cred);
254 252 status = GSS_S_FAILURE;
255 253 goto error_out;
256 254 }
257 255
258 256 if (status != GSS_S_COMPLETE) {
259 257 free(d_u_cred->cred_array);
260 258 free(d_u_cred);
261 259 goto error_out;
262 260 }
263 261
264 262 internal_name = GSS_C_NO_NAME;
265 263
266 264 d_u_cred->auxinfo.creation_time = time(0);
267 265 d_u_cred->auxinfo.time_rec = 0;
268 266
269 267 if (mech->gss_inquire_cred) {
270 268 status = mech->gss_inquire_cred(
271 269 mech->context,
272 270 minor_status,
273 271 tmp_d_cred,
274 272 &internal_name,
275 273 &d_u_cred->auxinfo.time_rec,
276 274 &d_u_cred->auxinfo.cred_usage,
277 275 NULL);
278 276 }
279 277
280 278 if (internal_name != NULL) {
281 279 temp_status =
282 280 __gss_convert_name_to_union_name(
283 281 &t_minstat, mech,
284 282 internal_name, &tmp_src_name);
285 283 if (temp_status != GSS_S_COMPLETE) {
286 284 *minor_status = t_minstat;
287 285 if (output_token->length)
288 286 (void) gss_release_buffer(
289 287 &t_minstat,
290 288 output_token);
291 289 free(d_u_cred->cred_array);
292 290 free(d_u_cred);
293 291 return (temp_status);
294 292 }
295 293 }
296 294
297 295 if (tmp_src_name != NULL) {
298 296 status = gss_display_name(
299 297 &t_minstat,
300 298 tmp_src_name,
301 299 &d_u_cred->auxinfo.name,
302 300 &d_u_cred->auxinfo.name_type);
303 301 }
304 302
305 303 *d_cred = (gss_cred_id_t)d_u_cred;
306 304 }
307 305 }
308 306 if (ret_flags != NULL) {
309 307 *ret_flags = flags;
310 308 }
311 309
312 310 if (src_name == NULL && tmp_src_name != NULL)
313 311 (void) gss_release_name(&t_minstat,
314 312 &tmp_src_name);
315 313 return (status);
316 314 } else {
317 315
318 316 status = GSS_S_BAD_MECH;
319 317 }
320 318
321 319 error_out:
|
↓ open down ↓ |
283 lines elided |
↑ open up ↑ |
322 320 if (union_ctx_id) {
323 321 if (union_ctx_id->mech_type) {
324 322 if (union_ctx_id->mech_type->elements)
325 323 free(union_ctx_id->mech_type->elements);
326 324 free(union_ctx_id->mech_type);
327 325 }
328 326 free(union_ctx_id);
329 327 *context_handle = GSS_C_NO_CONTEXT;
330 328 }
331 329
332 - if (output_token->length)
333 - (void) gss_release_buffer(&t_minstat, output_token);
334 -
335 330 if (src_name)
336 331 *src_name = GSS_C_NO_NAME;
337 332
338 333 if (tmp_src_name != GSS_C_NO_NAME)
339 334 (void) gss_release_buffer(&t_minstat,
340 335 (gss_buffer_t)tmp_src_name);
341 336
342 337 return (status);
343 338 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX