Print this page
first pass
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/gssapi/gssd_clnt_stubs.c
+++ new/usr/src/uts/common/gssapi/gssd_clnt_stubs.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 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 * Copyright 2012 Milan Jurik. All rights reserved.
25 25 */
26 26
27 27 /*
28 28 * GSSAPI library stub module for gssd.
29 29 */
30 30
31 31 #include <mechglueP.h>
32 32 #include "gssd_prot.h"
33 33 #include <rpc/rpc.h>
34 34
35 35 #include <sys/systm.h>
36 36 #include <sys/types.h>
37 37 #include <sys/cmn_err.h>
38 38 #include <sys/kmem.h>
39 39 #include <gssapi/kgssapi_defs.h>
40 40 #include <sys/debug.h>
41 41
42 42 #ifdef GSSDEBUG
43 43 /*
44 44 * Kernel kgssd module debugging aid. The global variable "gss_log"
45 45 * is a bit mask which allows various types of debugging messages
46 46 * to be printed out.
47 47 *
48 48 * gss_log & 1 will cause actual failures to be printed.
49 49 * gss_log & 2 will cause informational messages to be
50 50 * printed on the client side of kgssd.
51 51 * gss_log & 4 will cause informational messages to be
52 52 * printed on the server side of kgssd.
53 53 * gss_log & 8 will cause informational messages to be
54 54 * printed on both client and server side of kgssd.
55 55 */
56 56
57 57 uint_t gss_log = 1;
58 58
59 59 #endif /* GSSDEBUG */
60 60
61 61 #ifdef DEBUG
62 62 extern void prom_printf(const char *, ...);
↓ open down ↓ |
62 lines elided |
↑ open up ↑ |
63 63 #endif
64 64
65 65 char *server = "localhost";
66 66
67 67 static OM_uint32 kgss_sign_wrapped(void *, OM_uint32 *, gss_ctx_id_t, int,
68 68 gss_buffer_t, gss_buffer_t, OM_uint32);
69 69
70 70 static OM_uint32 kgss_verify_wrapped(void *, OM_uint32 *, gss_ctx_id_t,
71 71 gss_buffer_t, gss_buffer_t, int *qop_state, OM_uint32);
72 72
73 -/* EXPORT DELETE START */
74 73 static OM_uint32 kgss_seal_wrapped(void *, OM_uint32 *, gss_ctx_id_t,
75 74 int, int, gss_buffer_t, int *, gss_buffer_t, OM_uint32);
76 75
77 76 static OM_uint32 kgss_unseal_wrapped(void *, OM_uint32 *, gss_ctx_id_t,
78 77 gss_buffer_t, gss_buffer_t, int *conf_state, int *qop_state,
79 78 OM_uint32);
80 -/* EXPORT DELETE END */
81 79
82 80 static OM_uint32 kgss_delete_sec_context_wrapped(void *, OM_uint32 *,
83 81 gssd_ctx_id_t *, gss_buffer_t, OM_uint32);
84 82
85 83 static void __kgss_reset_mech(gss_mechanism *, gss_OID);
86 84
87 85 #define DEFAULT_MINOR_STAT ((OM_uint32) ~0)
88 86
89 87 OM_uint32
90 88 kgss_acquire_cred_wrapped(minor_status,
91 89 desired_name,
92 90 time_req,
93 91 desired_mechs,
94 92 cred_usage,
95 93 output_cred_handle,
96 94 actual_mechs,
97 95 time_rec,
98 96 uid,
99 97 gssd_cred_verifier)
100 98 OM_uint32 *minor_status;
101 99 const gss_name_t desired_name;
102 100 OM_uint32 time_req;
103 101 const gss_OID_set desired_mechs;
104 102 int cred_usage;
105 103 gssd_cred_id_t *output_cred_handle;
106 104 gss_OID_set *actual_mechs;
107 105 OM_uint32 *time_rec;
108 106 uid_t uid;
109 107 OM_uint32 *gssd_cred_verifier;
110 108 {
111 109 CLIENT *clnt;
112 110
113 111 OM_uint32 minor_status_temp;
114 112 gss_buffer_desc external_name;
115 113 gss_OID name_type;
116 114 enum clnt_stat client_stat;
117 115 int i;
118 116
119 117 gss_acquire_cred_arg arg;
120 118 gss_acquire_cred_res res;
121 119
122 120 /* get the client handle to GSSD */
123 121
124 122 if ((clnt = getgssd_handle()) == NULL) {
125 123 GSSLOG(1, "kgss_acquire_cred: can't connect to server on %s\n",
126 124 server);
127 125 return (GSS_S_FAILURE);
128 126 }
129 127
130 128 /* convert the desired name from internal to external format */
131 129
132 130 if (gss_display_name(&minor_status_temp, desired_name, &external_name,
133 131 &name_type) != GSS_S_COMPLETE) {
134 132
135 133 *minor_status = (OM_uint32) minor_status_temp;
136 134 killgssd_handle(clnt);
137 135 GSSLOG0(1, "kgss_acquire_cred: display name failed\n");
138 136 return ((OM_uint32) GSS_S_FAILURE);
139 137 }
140 138
141 139
142 140 /* copy the procedure arguments into the rpc arg parameter */
143 141
144 142 arg.uid = (OM_uint32) uid;
145 143
146 144 arg.desired_name.GSS_BUFFER_T_len = (uint_t)external_name.length;
147 145 arg.desired_name.GSS_BUFFER_T_val = (char *)external_name.value;
148 146
149 147 arg.name_type.GSS_OID_len =
150 148 name_type == GSS_C_NULL_OID ?
151 149 0 : (uint_t)name_type->length;
152 150
153 151 arg.name_type.GSS_OID_val =
154 152 name_type == GSS_C_NULL_OID ?
155 153 (char *)NULL : (char *)name_type->elements;
156 154
157 155 arg.time_req = time_req;
158 156
159 157 if (desired_mechs != GSS_C_NULL_OID_SET) {
160 158 arg.desired_mechs.GSS_OID_SET_len =
161 159 (uint_t)desired_mechs->count;
162 160 arg.desired_mechs.GSS_OID_SET_val = (GSS_OID *)
163 161 MALLOC(sizeof (GSS_OID) * desired_mechs->count);
164 162
165 163 for (i = 0; i < desired_mechs->count; i++) {
166 164 arg.desired_mechs.GSS_OID_SET_val[i].GSS_OID_len =
167 165 (uint_t)desired_mechs->elements[i].length;
168 166 arg.desired_mechs.GSS_OID_SET_val[i].GSS_OID_val =
169 167 (char *)MALLOC(desired_mechs->elements[i].length);
170 168 (void) memcpy(
171 169 arg.desired_mechs.GSS_OID_SET_val[i].GSS_OID_val,
172 170 desired_mechs->elements[i].elements,
173 171 desired_mechs->elements[i].length);
174 172 }
175 173 } else
176 174 arg.desired_mechs.GSS_OID_SET_len = 0;
177 175
178 176 arg.cred_usage = cred_usage;
179 177
180 178 /* call the remote procedure */
181 179
182 180 bzero((caddr_t)&res, sizeof (res));
183 181 client_stat = gss_acquire_cred_1(&arg, &res, clnt);
184 182
185 183 (void) gss_release_buffer(&minor_status_temp, &external_name);
186 184 if (desired_mechs != GSS_C_NULL_OID_SET) {
187 185 for (i = 0; i < desired_mechs->count; i++)
188 186 FREE(arg.desired_mechs.GSS_OID_SET_val[i].GSS_OID_val,
189 187 arg.desired_mechs.GSS_OID_SET_val[i].GSS_OID_len);
190 188 FREE(arg.desired_mechs.GSS_OID_SET_val,
191 189 arg.desired_mechs.GSS_OID_SET_len * sizeof (GSS_OID));
192 190 }
193 191
194 192 if (client_stat != RPC_SUCCESS) {
195 193
196 194 /*
197 195 * if the RPC call times out, null out all return arguments,
198 196 * set minor_status to its maximum value, and return
199 197 * GSS_S_FAILURE
200 198 */
201 199
202 200 if (minor_status != NULL)
203 201 *minor_status = DEFAULT_MINOR_STAT;
204 202 if (output_cred_handle != NULL)
205 203 *output_cred_handle = NULL;
206 204 if (actual_mechs != NULL)
207 205 *actual_mechs = NULL;
208 206 if (time_rec != NULL)
209 207 *time_rec = 0;
210 208
211 209 killgssd_handle(clnt);
212 210 GSSLOG0(1, "kgss_acquire_cred: RPC call times out\n");
213 211 return (GSS_S_FAILURE);
214 212 }
215 213
216 214 /* copy the rpc results into the return arguments */
217 215
218 216 if (minor_status != NULL)
219 217 *minor_status = res.minor_status;
220 218
221 219 if (output_cred_handle != NULL &&
222 220 (res.status == GSS_S_COMPLETE)) {
223 221 *output_cred_handle =
224 222 *((gssd_cred_id_t *)res.output_cred_handle.GSS_CRED_ID_T_val);
225 223 *gssd_cred_verifier = res.gssd_cred_verifier;
226 224 }
227 225
228 226 if (res.status == GSS_S_COMPLETE &&
229 227 res.actual_mechs.GSS_OID_SET_len != 0 &&
230 228 actual_mechs != NULL) {
231 229 *actual_mechs = (gss_OID_set) MALLOC(sizeof (gss_OID_set_desc));
232 230 (*actual_mechs)->count =
233 231 (int)res.actual_mechs.GSS_OID_SET_len;
234 232 (*actual_mechs)->elements = (gss_OID)
235 233 MALLOC(sizeof (gss_OID_desc) * (*actual_mechs)->count);
236 234
237 235 for (i = 0; i < (*actual_mechs)->count; i++) {
238 236 (*actual_mechs)->elements[i].length = (OM_uint32)
239 237 res.actual_mechs.GSS_OID_SET_val[i].GSS_OID_len;
240 238 (*actual_mechs)->elements[i].elements =
241 239 (void *) MALLOC((*actual_mechs)->elements[i].length);
242 240 (void) memcpy((*actual_mechs)->elements[i].elements,
243 241 res.actual_mechs.GSS_OID_SET_val[i].GSS_OID_val,
244 242 (*actual_mechs)->elements[i].length);
245 243 }
246 244 } else {
247 245 if (res.status == GSS_S_COMPLETE &&
248 246 actual_mechs != NULL)
249 247 (*actual_mechs) = NULL;
250 248 }
251 249
252 250 if (time_rec != NULL)
253 251 *time_rec = res.time_rec;
254 252
255 253 /*
256 254 * free the memory allocated for the results and return with the status
257 255 * received in the rpc call
258 256 */
259 257
260 258 clnt_freeres(clnt, xdr_gss_acquire_cred_res, (caddr_t)&res);
261 259 killgssd_handle(clnt);
262 260 return (res.status);
263 261
264 262 }
265 263
266 264 OM_uint32
267 265 kgss_acquire_cred(minor_status,
268 266 desired_name,
269 267 time_req,
270 268 desired_mechs,
271 269 cred_usage,
272 270 output_cred_handle,
273 271 actual_mechs,
274 272 time_rec,
275 273 uid)
276 274 OM_uint32 *minor_status;
277 275 const gss_name_t desired_name;
278 276 OM_uint32 time_req;
279 277 const gss_OID_set desired_mechs;
280 278 int cred_usage;
281 279 gss_cred_id_t *output_cred_handle;
282 280 gss_OID_set *actual_mechs;
283 281 OM_uint32 *time_rec;
284 282 uid_t uid;
285 283 {
286 284
287 285 OM_uint32 err;
288 286 struct kgss_cred *kcred;
289 287
290 288 kcred = KGSS_CRED_ALLOC();
291 289 *output_cred_handle = (gss_cred_id_t)kcred;
292 290 err = kgss_acquire_cred_wrapped(minor_status, desired_name, time_req,
293 291 desired_mechs, cred_usage, &kcred->gssd_cred, actual_mechs,
294 292 time_rec, uid, &kcred->gssd_cred_verifier);
295 293 if (GSS_ERROR(err)) {
296 294 KGSS_CRED_FREE(kcred);
297 295 *output_cred_handle = GSS_C_NO_CREDENTIAL;
298 296 }
299 297 return (err);
300 298 }
301 299
302 300 OM_uint32
303 301 kgss_add_cred_wrapped(minor_status,
304 302 input_cred_handle,
305 303 gssd_cred_verifier,
306 304 desired_name,
307 305 desired_mech_type,
308 306 cred_usage,
309 307 initiator_time_req,
310 308 acceptor_time_req,
311 309 actual_mechs,
312 310 initiator_time_rec,
313 311 acceptor_time_rec,
314 312 uid)
315 313 OM_uint32 *minor_status;
316 314 gssd_cred_id_t input_cred_handle;
317 315 OM_uint32 gssd_cred_verifier;
318 316 gss_name_t desired_name;
319 317 gss_OID desired_mech_type;
320 318 int cred_usage;
321 319 int initiator_time_req;
322 320 int acceptor_time_req;
323 321 gss_OID_set *actual_mechs;
324 322 OM_uint32 *initiator_time_rec;
325 323 OM_uint32 *acceptor_time_rec;
326 324 uid_t uid;
327 325 {
328 326 CLIENT *clnt;
329 327
330 328 OM_uint32 minor_status_temp;
331 329 gss_buffer_desc external_name;
332 330 gss_OID name_type;
333 331 int i;
334 332
335 333 gss_add_cred_arg arg;
336 334 gss_add_cred_res res;
337 335
338 336
339 337 /*
340 338 * NULL the params here once
341 339 * If there are errors then we won't
342 340 * have to do it for every error
343 341 * case
344 342 */
345 343
346 344 if (minor_status != NULL)
347 345 *minor_status = DEFAULT_MINOR_STAT;
348 346 if (actual_mechs != NULL)
349 347 *actual_mechs = NULL;
350 348 if (initiator_time_rec != NULL)
351 349 *initiator_time_rec = 0;
352 350 if (acceptor_time_rec != NULL)
353 351 *acceptor_time_rec = 0;
354 352 /* get the client handle to GSSD */
355 353
356 354 if ((clnt = getgssd_handle()) == NULL) {
357 355 GSSLOG(1, "kgss_add_cred: can't connect to server on %s\n",
358 356 server);
359 357 return (GSS_S_FAILURE);
360 358 }
361 359
362 360
363 361 /* convert the desired name from internal to external format */
364 362
365 363 if (gss_display_name(&minor_status_temp, desired_name, &external_name,
366 364 &name_type) != GSS_S_COMPLETE) {
367 365
368 366 *minor_status = (OM_uint32) minor_status_temp;
369 367 killgssd_handle(clnt);
370 368 GSSLOG0(1, "kgss_acquire_cred: display name failed\n");
371 369 return ((OM_uint32) GSS_S_FAILURE);
372 370 }
373 371
374 372
375 373 /* copy the procedure arguments into the rpc arg parameter */
376 374
377 375 arg.uid = (OM_uint32)uid;
378 376 arg.input_cred_handle.GSS_CRED_ID_T_len =
379 377 input_cred_handle == GSSD_NO_CREDENTIAL ?
380 378 0 : (uint_t)sizeof (gssd_cred_id_t);
381 379 arg.input_cred_handle.GSS_CRED_ID_T_val = (char *)&input_cred_handle;
382 380 arg.gssd_cred_verifier = gssd_cred_verifier;
383 381 arg.desired_name.GSS_BUFFER_T_len = (uint_t)external_name.length;
384 382 arg.desired_name.GSS_BUFFER_T_val = (char *)external_name.value;
385 383 arg.name_type.GSS_OID_len =
386 384 name_type == GSS_C_NULL_OID ?
387 385 0 : (uint_t)name_type->length;
388 386 arg.name_type.GSS_OID_val =
389 387 name_type == GSS_C_NULL_OID ?
390 388 (char *)NULL : (char *)name_type->elements;
391 389
392 390 arg.desired_mech_type.GSS_OID_len =
393 391 (uint_t)(desired_mech_type != GSS_C_NULL_OID ?
394 392 desired_mech_type->length : 0);
395 393 arg.desired_mech_type.GSS_OID_val =
396 394 (char *)(desired_mech_type != GSS_C_NULL_OID ?
397 395 desired_mech_type->elements : 0);
398 396 arg.cred_usage = cred_usage;
399 397 arg.initiator_time_req = initiator_time_req;
400 398 arg.acceptor_time_req = acceptor_time_req;
401 399
402 400 /* call the remote procedure */
403 401
404 402 bzero((caddr_t)&res, sizeof (res));
405 403 if (gss_add_cred_1(&arg, &res, clnt) != RPC_SUCCESS) {
406 404
407 405 /*
408 406 * if the RPC call times out, null out all return arguments,
409 407 * set minor_status to its maximum value, and return
410 408 * GSS_S_FAILURE
411 409 */
412 410
413 411 killgssd_handle(clnt);
414 412 (void) gss_release_buffer(&minor_status_temp, &external_name);
415 413 GSSLOG0(1, "kgss_add_cred: RPC call times out\n");
416 414 return (GSS_S_FAILURE);
417 415 }
418 416
419 417 /* free the allocated memory for the flattened name */
420 418
421 419 (void) gss_release_buffer(&minor_status_temp, &external_name);
422 420
423 421 /* copy the rpc results into the return arguments */
424 422
425 423 if (minor_status != NULL)
426 424 *minor_status = res.minor_status;
427 425
428 426 if (res.status == GSS_S_COMPLETE &&
429 427 res.actual_mechs.GSS_OID_SET_len != 0 &&
430 428 actual_mechs != NULL) {
431 429 *actual_mechs = (gss_OID_set) MALLOC(sizeof (gss_OID_set_desc));
432 430 (*actual_mechs)->count =
433 431 (int)res.actual_mechs.GSS_OID_SET_len;
434 432 (*actual_mechs)->elements = (gss_OID)
435 433 MALLOC(sizeof (gss_OID_desc) * (*actual_mechs)->count);
436 434
437 435 for (i = 0; i < (*actual_mechs)->count; i++) {
438 436 (*actual_mechs)->elements[i].length = (OM_uint32)
439 437 res.actual_mechs.GSS_OID_SET_val[i].GSS_OID_len;
440 438 (*actual_mechs)->elements[i].elements =
441 439 (void *) MALLOC((*actual_mechs)->elements[i].length);
442 440 (void) memcpy((*actual_mechs)->elements[i].elements,
443 441 res.actual_mechs.GSS_OID_SET_val[i].GSS_OID_val,
444 442 (*actual_mechs)->elements[i].length);
445 443 }
446 444 } else {
447 445 if (res.status == GSS_S_COMPLETE && actual_mechs != NULL)
448 446 (*actual_mechs) = NULL;
449 447 }
450 448 if (initiator_time_rec != NULL)
451 449 *initiator_time_rec = res.acceptor_time_rec;
452 450 if (acceptor_time_rec != NULL)
453 451 *acceptor_time_rec = res.acceptor_time_rec;
454 452
455 453 /*
456 454 * free the memory allocated for the results and return with the status
457 455 * received in the rpc call
458 456 */
459 457
460 458 clnt_freeres(clnt, xdr_gss_add_cred_res, (caddr_t)&res);
461 459 killgssd_handle(clnt);
462 460 return (res.status);
463 461
464 462 }
465 463
466 464 OM_uint32
467 465 kgss_add_cred(minor_status,
468 466 input_cred_handle,
469 467 desired_name,
470 468 desired_mech_type,
471 469 cred_usage,
472 470 initiator_time_req,
473 471 acceptor_time_req,
474 472 actual_mechs,
475 473 initiator_time_rec,
476 474 acceptor_time_rec,
477 475 uid)
478 476 OM_uint32 *minor_status;
479 477 gss_cred_id_t input_cred_handle;
480 478 gss_name_t desired_name;
481 479 gss_OID desired_mech_type;
482 480 int cred_usage;
483 481 int initiator_time_req;
484 482 int acceptor_time_req;
485 483 gss_OID_set *actual_mechs;
486 484 OM_uint32 *initiator_time_rec;
487 485 OM_uint32 *acceptor_time_rec;
488 486 uid_t uid;
489 487 {
490 488
491 489 OM_uint32 err;
492 490 OM_uint32 gssd_cred_verifier;
493 491 gssd_cred_id_t gssd_input_cred_handle;
494 492
495 493 if (input_cred_handle != GSS_C_NO_CREDENTIAL) {
496 494 gssd_cred_verifier = KCRED_TO_CREDV(input_cred_handle);
497 495 gssd_input_cred_handle = KCRED_TO_CRED(input_cred_handle);
498 496 } else {
499 497 gssd_input_cred_handle = GSSD_NO_CREDENTIAL;
500 498 }
501 499
502 500 err = kgss_add_cred_wrapped(minor_status, gssd_input_cred_handle,
503 501 gssd_cred_verifier, desired_name, desired_mech_type,
504 502 cred_usage, initiator_time_req, acceptor_time_req,
505 503 actual_mechs, initiator_time_rec,
506 504 acceptor_time_rec, uid);
507 505 return (err);
508 506 }
509 507
510 508
511 509 OM_uint32
512 510 kgss_release_cred_wrapped(minor_status,
513 511 cred_handle,
514 512 uid,
515 513 gssd_cred_verifier)
516 514 OM_uint32 *minor_status;
517 515 gssd_cred_id_t *cred_handle;
518 516 uid_t uid;
519 517 OM_uint32 gssd_cred_verifier;
520 518 {
521 519 CLIENT *clnt;
522 520
523 521 gss_release_cred_arg arg;
524 522 gss_release_cred_res res;
525 523
526 524
527 525 /* get the client handle to GSSD */
528 526
529 527 if ((clnt = getgssd_handle()) == NULL) {
530 528 GSSLOG(1, "kgss_release_cred: can't connect to server on %s\n",
531 529 server);
532 530 return (GSS_S_FAILURE);
533 531 }
534 532
535 533 /* copy the procedure arguments into the rpc arg parameter */
536 534
537 535 arg.uid = (OM_uint32)uid;
538 536 arg.gssd_cred_verifier = gssd_cred_verifier;
539 537
540 538 if (cred_handle != NULL) {
541 539 arg.cred_handle.GSS_CRED_ID_T_len =
542 540 (uint_t)sizeof (gssd_cred_id_t);
543 541 arg.cred_handle.GSS_CRED_ID_T_val = (char *)cred_handle;
544 542 } else
545 543 arg.cred_handle.GSS_CRED_ID_T_len = 0;
546 544
547 545 /* call the remote procedure */
548 546
549 547 bzero((caddr_t)&res, sizeof (res));
550 548 if (gss_release_cred_1(&arg, &res, clnt) != RPC_SUCCESS) {
551 549
552 550 /*
553 551 * if the RPC call times out, null out all return arguments, set
554 552 * minor_status to its maximum value, and return GSS_S_FAILURE
555 553 */
556 554
557 555 if (minor_status != NULL)
558 556 *minor_status = DEFAULT_MINOR_STAT;
559 557 if (cred_handle != NULL)
560 558 *cred_handle = NULL;
561 559
562 560 killgssd_handle(clnt);
563 561 GSSLOG0(1, "kgss_release_cred: RPC call times out\n");
564 562 return (GSS_S_FAILURE);
565 563 }
566 564
567 565 /* if the release succeeded, null out the cred_handle */
568 566
569 567 if (res.status == GSS_S_COMPLETE && cred_handle != NULL)
570 568 *cred_handle = NULL;
571 569
572 570 /* copy the rpc results into the return arguments */
573 571
574 572 if (minor_status != NULL)
575 573 *minor_status = res.minor_status;
576 574
577 575 /* return with status returned in rpc call */
578 576
579 577 killgssd_handle(clnt);
580 578
581 579 return (res.status);
582 580
583 581 }
584 582
585 583 OM_uint32
586 584 kgss_release_cred(minor_status,
587 585 cred_handle,
588 586 uid)
589 587 OM_uint32 *minor_status;
590 588 gss_cred_id_t *cred_handle;
591 589 uid_t uid;
592 590
593 591 {
594 592
595 593 OM_uint32 err;
596 594 struct kgss_cred *kcred;
597 595
598 596 if (*cred_handle == GSS_C_NO_CREDENTIAL)
599 597 return (GSS_S_COMPLETE);
600 598 else
601 599 kcred = KCRED_TO_KGSS_CRED(*cred_handle);
602 600
603 601 err = kgss_release_cred_wrapped(minor_status, &kcred->gssd_cred,
604 602 uid, kcred->gssd_cred_verifier);
605 603 KGSS_CRED_FREE(kcred);
606 604 *cred_handle = GSS_C_NO_CREDENTIAL;
607 605 return (err);
608 606 }
609 607
610 608 static OM_uint32
611 609 kgss_init_sec_context_wrapped(
612 610 OM_uint32 *minor_status,
613 611 const gssd_cred_id_t claimant_cred_handle,
614 612 OM_uint32 gssd_cred_verifier,
615 613 gssd_ctx_id_t *context_handle,
616 614 OM_uint32 *gssd_context_verifier,
617 615 const gss_name_t target_name,
618 616 const gss_OID mech_type,
619 617 int req_flags,
620 618 OM_uint32 time_req,
621 619 const gss_channel_bindings_t input_chan_bindings,
622 620 const gss_buffer_t input_token,
623 621 gss_OID *actual_mech_type,
624 622 gss_buffer_t output_token,
625 623 int *ret_flags,
626 624 OM_uint32 *time_rec,
627 625 uid_t uid)
628 626 {
629 627 CLIENT *clnt;
630 628
631 629 OM_uint32 minor_status_temp;
632 630 gss_buffer_desc external_name;
633 631 gss_OID name_type;
634 632
635 633 gss_init_sec_context_arg arg;
636 634 gss_init_sec_context_res res;
637 635
638 636 /* get the client handle to GSSD */
639 637
640 638 if ((clnt = getgssd_handle()) == NULL) {
641 639 GSSLOG(1,
642 640 "kgss_init_sec_context: can't connect to server on %s\n",
643 641 server);
644 642 return (GSS_S_FAILURE);
645 643 }
646 644
647 645 /* convert the target name from internal to external format */
648 646
649 647 if (gss_display_name(&minor_status_temp, target_name,
650 648 &external_name, &name_type) != GSS_S_COMPLETE) {
651 649
652 650 *minor_status = (OM_uint32) minor_status_temp;
653 651 killgssd_handle(clnt);
654 652 GSSLOG0(1, "kgss_init_sec_context: can't display name\n");
655 653 return ((OM_uint32) GSS_S_FAILURE);
656 654 }
657 655
658 656
659 657 /* copy the procedure arguments into the rpc arg parameter */
660 658
661 659 arg.uid = (OM_uint32)uid;
662 660
663 661 arg.context_handle.GSS_CTX_ID_T_len =
664 662 *context_handle == GSSD_NO_CONTEXT ?
665 663 0 : (uint_t)sizeof (gssd_ctx_id_t);
666 664 arg.context_handle.GSS_CTX_ID_T_val = (char *)context_handle;
667 665
668 666 arg.gssd_context_verifier = *gssd_context_verifier;
669 667
670 668 arg.claimant_cred_handle.GSS_CRED_ID_T_len =
671 669 claimant_cred_handle == GSSD_NO_CREDENTIAL ?
672 670 0 : (uint_t)sizeof (gssd_cred_id_t);
673 671 arg.claimant_cred_handle.GSS_CRED_ID_T_val =
674 672 (char *)&claimant_cred_handle;
675 673 arg.gssd_cred_verifier = gssd_cred_verifier;
676 674
677 675 arg.target_name.GSS_BUFFER_T_len = (uint_t)external_name.length;
678 676 arg.target_name.GSS_BUFFER_T_val = (char *)external_name.value;
679 677
680 678 arg.name_type.GSS_OID_len =
681 679 name_type == GSS_C_NULL_OID ? 0 : (uint_t)name_type->length;
682 680
683 681 arg.name_type.GSS_OID_val =
684 682 name_type == GSS_C_NULL_OID ?
685 683 (char *)NULL : (char *)name_type->elements;
686 684
687 685 arg.mech_type.GSS_OID_len = (uint_t)(mech_type != GSS_C_NULL_OID ?
688 686 mech_type->length : 0);
689 687 arg.mech_type.GSS_OID_val = (char *)(mech_type != GSS_C_NULL_OID ?
690 688 mech_type->elements : 0);
691 689
692 690 arg.req_flags = req_flags;
693 691
694 692 arg.time_req = time_req;
695 693
696 694 if (input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS) {
697 695 arg.input_chan_bindings.present = YES;
698 696 arg.input_chan_bindings.initiator_addrtype =
699 697 input_chan_bindings->initiator_addrtype;
700 698 arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_len =
701 699 (uint_t)input_chan_bindings->initiator_address.length;
702 700 arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_val =
703 701 (void *)input_chan_bindings->initiator_address.value;
704 702 arg.input_chan_bindings.acceptor_addrtype =
705 703 input_chan_bindings->acceptor_addrtype;
706 704 arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_len =
707 705 (uint_t)input_chan_bindings->acceptor_address.length;
708 706 arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_val =
709 707 (void *)input_chan_bindings->acceptor_address.value;
710 708 arg.input_chan_bindings.application_data.GSS_BUFFER_T_len =
711 709 (uint_t)input_chan_bindings->application_data.length;
712 710 arg.input_chan_bindings.application_data.GSS_BUFFER_T_val =
713 711 (void *)input_chan_bindings->application_data.value;
714 712 } else {
715 713 arg.input_chan_bindings.present = NO;
716 714 arg.input_chan_bindings.initiator_addrtype = 0;
717 715 arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_len = 0;
718 716 arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_val = 0;
719 717 arg.input_chan_bindings.acceptor_addrtype = 0;
720 718 arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_len = 0;
721 719 arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_val = 0;
722 720 arg.input_chan_bindings.application_data.GSS_BUFFER_T_len = 0;
723 721 arg.input_chan_bindings.application_data.GSS_BUFFER_T_val = 0;
724 722 }
725 723
726 724 arg.input_token.GSS_BUFFER_T_len =
727 725 (uint_t)(input_token != GSS_C_NO_BUFFER ? input_token->length : 0);
728 726 arg.input_token.GSS_BUFFER_T_val =
729 727 (char *)(input_token != GSS_C_NO_BUFFER ? input_token->value : 0);
730 728
731 729 /* call the remote procedure */
732 730
733 731 bzero((caddr_t)&res, sizeof (res));
734 732 if (gss_init_sec_context_1(&arg, &res, clnt) != RPC_SUCCESS) {
735 733
736 734 /*
737 735 * if the RPC call times out, null out all return arguments, set
738 736 * minor_status to its maximum value, and return GSS_S_FAILURE
739 737 */
740 738
741 739 if (minor_status != NULL)
742 740 *minor_status = DEFAULT_MINOR_STAT;
743 741 if (actual_mech_type != NULL)
744 742 *actual_mech_type = NULL;
745 743 if (output_token != NULL)
746 744 output_token->length = 0;
747 745 if (ret_flags != NULL)
748 746 *ret_flags = 0;
749 747 if (time_rec != NULL)
750 748 *time_rec = 0;
751 749
752 750 killgssd_handle(clnt);
753 751 (void) gss_release_buffer(&minor_status_temp, &external_name);
754 752 GSSLOG0(1, "kgss_init_sec_context: RPC call times out\n");
755 753 return (GSS_S_FAILURE);
756 754 }
757 755
758 756 /* free the allocated memory for the flattened name */
759 757
760 758 (void) gss_release_buffer(&minor_status_temp, &external_name);
761 759
762 760 if (minor_status != NULL)
763 761 *minor_status = res.minor_status;
764 762
765 763 if (output_token != NULL && res.output_token.GSS_BUFFER_T_val != NULL) {
766 764 output_token->length =
767 765 (size_t)res.output_token.GSS_BUFFER_T_len;
768 766 output_token->value =
769 767 (void *)MALLOC(output_token->length);
770 768 (void) memcpy(output_token->value,
771 769 res.output_token.GSS_BUFFER_T_val, output_token->length);
772 770 }
773 771
774 772 /* if the call was successful, copy out the results */
775 773 if (res.status == (OM_uint32) GSS_S_COMPLETE ||
776 774 res.status == (OM_uint32) GSS_S_CONTINUE_NEEDED) {
777 775 /*
778 776 * if the return code is GSS_S_CONTINUE_NEEDED
779 777 * ignore all return parameters except for
780 778 * status codes, output token and context handle.
781 779 */
782 780 *context_handle =
783 781 *((gssd_ctx_id_t *)res.context_handle.GSS_CTX_ID_T_val);
784 782 *gssd_context_verifier = res.gssd_context_verifier;
785 783
786 784 if (res.status == GSS_S_COMPLETE) {
787 785 if (actual_mech_type != NULL) {
788 786 *actual_mech_type =
789 787 (gss_OID) MALLOC(sizeof (gss_OID_desc));
790 788 (*actual_mech_type)->length =
791 789 (OM_UINT32)res.actual_mech_type.GSS_OID_len;
792 790 (*actual_mech_type)->elements =
793 791 (void *)MALLOC((*actual_mech_type)->length);
794 792 (void) memcpy((*actual_mech_type)->elements,
795 793 (void *)res.actual_mech_type.GSS_OID_val,
796 794 (*actual_mech_type)->length);
797 795 }
798 796
799 797
800 798 if (ret_flags != NULL)
801 799 *ret_flags = res.ret_flags;
802 800
803 801 if (time_rec != NULL)
804 802 *time_rec = res.time_rec;
805 803 }
806 804 }
807 805
808 806 /*
809 807 * free the memory allocated for the results and return with the status
810 808 * received in the rpc call
811 809 */
812 810
813 811 clnt_freeres(clnt, xdr_gss_init_sec_context_res, (caddr_t)&res);
↓ open down ↓ |
723 lines elided |
↑ open up ↑ |
814 812 killgssd_handle(clnt);
815 813 return (res.status);
816 814
817 815 }
818 816
819 817 static struct gss_config default_gc = {
820 818 { 0, NULL},
821 819 NULL,
822 820 NULL,
823 821 0,
824 -/* EXPORT DELETE START */ /* CRYPT DELETE START */
825 822 kgss_unseal_wrapped,
826 -/* EXPORT DELETE END */ /* CRYPT DELETE END */
827 823 NULL, /* kgss_delete_sec_context_wrapped */
828 -/* EXPORT DELETE START */ /* CRYPT DELETE START */
829 824 kgss_seal_wrapped,
830 -/* EXPORT DELETE END */ /* CRYPT DELETE END */
831 825 NULL, /* kgss_import_sec_context */
832 -/* EXPORT DELETE START */
833 -/* CRYPT DELETE START */
834 -#if 0
835 -/* CRYPT DELETE END */
836 - kgss_seal_wrapped,
837 - kgss_unseal_wrapped,
838 -/* CRYPT DELETE START */
839 -#endif
840 -/* CRYPT DELETE END */
841 -/* EXPORT DELETE END */
842 826 kgss_sign_wrapped,
843 827 kgss_verify_wrapped
844 828 };
845 829
846 830 void
847 831 kgss_free_oid(gss_OID oid)
848 832 {
849 833 FREE(oid->elements, oid->length);
850 834 FREE(oid, sizeof (gss_OID_desc));
851 835 }
852 836
853 837 OM_uint32
854 838 kgss_init_sec_context(
855 839 OM_uint32 *minor_status,
856 840 const gss_cred_id_t claimant_cred_handle,
857 841 gss_ctx_id_t *context_handle,
858 842 const gss_name_t target_name,
859 843 const gss_OID mech_type,
860 844 int req_flags,
861 845 OM_uint32 time_req,
862 846 const gss_channel_bindings_t input_chan_bindings,
863 847 const gss_buffer_t input_token,
864 848 gss_OID *actual_mech_type,
865 849 gss_buffer_t output_token,
866 850 int *ret_flags,
867 851 OM_uint32 *time_rec,
868 852 uid_t uid)
869 853 {
870 854 OM_uint32 err;
871 855 struct kgss_ctx *kctx;
872 856 gss_OID amt;
873 857 gssd_cred_id_t gssd_cl_cred_handle;
874 858 OM_uint32 gssd_cred_verifier;
875 859
876 860 /*
877 861 * If this is an initial call, we'll need to create the
878 862 * wrapper struct that contains kernel state information, and
879 863 * a reference to the handle from gssd.
880 864 */
881 865 if (*context_handle == GSS_C_NO_CONTEXT) {
882 866 kctx = KGSS_ALLOC();
883 867 /*
884 868 * The default gss-mechanism struct as pointers to
885 869 * the sign/seal/verify/unseal routines that make
886 870 * upcalls to gssd.
887 871 */
888 872 kctx->mech = &default_gc;
889 873 kctx->gssd_ctx = GSSD_NO_CONTEXT;
890 874 *context_handle = (gss_ctx_id_t)kctx;
891 875 } else
892 876 kctx = (struct kgss_ctx *)*context_handle;
893 877
894 878 if (claimant_cred_handle != GSS_C_NO_CREDENTIAL) {
895 879 gssd_cred_verifier = KCRED_TO_CREDV(claimant_cred_handle);
896 880 gssd_cl_cred_handle = KCRED_TO_CRED(claimant_cred_handle);
897 881 } else {
898 882 gssd_cl_cred_handle = GSSD_NO_CREDENTIAL;
899 883 }
900 884
901 885 /*
902 886 * We need to know the resulting mechanism oid, so allocate
903 887 * it if the caller won't.
904 888 */
905 889 if (actual_mech_type == NULL)
906 890 actual_mech_type = &amt;
907 891
908 892 err = kgss_init_sec_context_wrapped(minor_status, gssd_cl_cred_handle,
909 893 gssd_cred_verifier, &kctx->gssd_ctx, &kctx->gssd_ctx_verifier,
910 894 target_name, mech_type, req_flags, time_req,
911 895 input_chan_bindings, input_token, actual_mech_type,
912 896 output_token, ret_flags, time_rec, uid);
913 897
914 898 if (GSS_ERROR(err)) {
915 899 KGSS_FREE(kctx);
916 900 *context_handle = GSS_C_NO_CONTEXT;
917 901 } else if (err == GSS_S_COMPLETE) {
918 902 /*
919 903 * Now check if there is a kernel module for this
920 904 * mechanism OID. If so, set the gss_mechanism structure
921 905 * in the wrapper context to point to the kernel mech.
922 906 */
923 907 __kgss_reset_mech(&kctx->mech, *actual_mech_type);
924 908
925 909 /*
926 910 * If the mech oid was allocated for us, free it.
927 911 */
928 912 if (&amt == actual_mech_type) {
929 913 kgss_free_oid(amt);
930 914 }
931 915 }
932 916 return (err);
933 917 }
934 918
935 919 static OM_uint32
936 920 kgss_accept_sec_context_wrapped(
937 921 OM_uint32 *minor_status,
938 922 gssd_ctx_id_t *context_handle,
939 923 OM_uint32 *gssd_context_verifier,
940 924 const gssd_cred_id_t verifier_cred_handle,
941 925 OM_uint32 gssd_cred_verifier,
942 926 const gss_buffer_t input_token,
943 927 const gss_channel_bindings_t input_chan_bindings,
944 928 gss_buffer_t src_name,
945 929 gss_OID *mech_type,
946 930 gss_buffer_t output_token,
947 931 int *ret_flags,
948 932 OM_uint32 *time_rec,
949 933 gss_cred_id_t *delegated_cred_handle,
950 934 uid_t uid)
951 935 {
952 936 CLIENT *clnt;
953 937
954 938 gss_accept_sec_context_arg arg;
955 939 gss_accept_sec_context_res res;
956 940 struct kgss_cred *kcred;
957 941
958 942 /* get the client handle to GSSD */
959 943
960 944 if ((clnt = getgssd_handle()) == NULL) {
961 945 GSSLOG(1,
962 946 "kgss_accept_sec_context: can't connect to server on %s\n",
963 947 server);
964 948 return (GSS_S_FAILURE);
965 949 }
966 950
967 951 /* copy the procedure arguments into the rpc arg parameter */
968 952
969 953 arg.uid = (OM_uint32)uid;
970 954
971 955 arg.context_handle.GSS_CTX_ID_T_len =
972 956 *context_handle == GSSD_NO_CONTEXT ?
973 957 0 : (uint_t)sizeof (gssd_ctx_id_t);
974 958 arg.context_handle.GSS_CTX_ID_T_val = (char *)context_handle;
975 959 arg.gssd_context_verifier = *gssd_context_verifier;
976 960
977 961 arg.verifier_cred_handle.GSS_CRED_ID_T_len =
978 962 verifier_cred_handle == GSSD_NO_CREDENTIAL ?
979 963 0 : (uint_t)sizeof (gssd_cred_id_t);
980 964 arg.verifier_cred_handle.GSS_CRED_ID_T_val =
981 965 (char *)&verifier_cred_handle;
982 966 arg.gssd_cred_verifier = gssd_cred_verifier;
983 967
984 968 arg.input_token_buffer.GSS_BUFFER_T_len =
985 969 (uint_t)(input_token != GSS_C_NO_BUFFER ? input_token->length : 0);
986 970 arg.input_token_buffer.GSS_BUFFER_T_val =
987 971 (char *)(input_token != GSS_C_NO_BUFFER ? input_token->value : 0);
988 972
989 973 if (input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS) {
990 974 arg.input_chan_bindings.present = YES;
991 975 arg.input_chan_bindings.initiator_addrtype =
992 976 input_chan_bindings->initiator_addrtype;
993 977 arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_len =
994 978 (uint_t)input_chan_bindings->initiator_address.length;
995 979 arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_val =
996 980 (void *)input_chan_bindings->initiator_address.value;
997 981 arg.input_chan_bindings.acceptor_addrtype =
998 982 input_chan_bindings->acceptor_addrtype;
999 983 arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_len =
1000 984 (uint_t)input_chan_bindings->acceptor_address.length;
1001 985 arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_val =
1002 986 (void *)input_chan_bindings->acceptor_address.value;
1003 987 arg.input_chan_bindings.application_data.GSS_BUFFER_T_len =
1004 988 (uint_t)input_chan_bindings->application_data.length;
1005 989 arg.input_chan_bindings.application_data.GSS_BUFFER_T_val =
1006 990 (void *)input_chan_bindings->application_data.value;
1007 991 } else {
1008 992
1009 993 arg.input_chan_bindings.present = NO;
1010 994 arg.input_chan_bindings.initiator_addrtype = 0;
1011 995 arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_len = 0;
1012 996 arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_val = 0;
1013 997 arg.input_chan_bindings.acceptor_addrtype = 0;
1014 998 arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_len = 0;
1015 999 arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_val = 0;
1016 1000 arg.input_chan_bindings.application_data.GSS_BUFFER_T_len = 0;
1017 1001 arg.input_chan_bindings.application_data.GSS_BUFFER_T_val = 0;
1018 1002 }
1019 1003
1020 1004 /* set the return parameters in case of errors.... */
1021 1005 if (minor_status != NULL)
1022 1006 *minor_status = DEFAULT_MINOR_STAT;
1023 1007 if (src_name != NULL) {
1024 1008 src_name->length = 0;
1025 1009 src_name->value = NULL;
1026 1010 }
1027 1011 if (mech_type != NULL)
1028 1012 *mech_type = NULL;
1029 1013 if (output_token != NULL)
1030 1014 output_token->length = 0;
1031 1015 if (ret_flags != NULL)
1032 1016 *ret_flags = 0;
1033 1017 if (time_rec != NULL)
1034 1018 *time_rec = 0;
1035 1019 if (delegated_cred_handle != NULL)
1036 1020 *delegated_cred_handle = NULL;
1037 1021
1038 1022 /* call the remote procedure */
1039 1023
1040 1024 bzero((caddr_t)&res, sizeof (res));
1041 1025 if (gss_accept_sec_context_1(&arg, &res, clnt) != RPC_SUCCESS) {
1042 1026 killgssd_handle(clnt);
1043 1027 GSSLOG0(1, "kgss_accept_sec_context: RPC call times out\n");
1044 1028 return (GSS_S_FAILURE);
1045 1029 }
1046 1030
1047 1031 if (minor_status != NULL)
1048 1032 *minor_status = res.minor_status;
1049 1033
1050 1034 if (output_token != NULL && res.output_token.GSS_BUFFER_T_val != NULL) {
1051 1035 output_token->length = res.output_token.GSS_BUFFER_T_len;
1052 1036 output_token->value = (void *)MALLOC(output_token->length);
1053 1037 (void) memcpy(output_token->value,
1054 1038 res.output_token.GSS_BUFFER_T_val, output_token->length);
1055 1039 }
1056 1040
1057 1041 /* if the call was successful, copy out the results */
1058 1042
1059 1043 if (res.status == (OM_uint32)GSS_S_COMPLETE ||
1060 1044 res.status == (OM_uint32)GSS_S_CONTINUE_NEEDED) {
1061 1045
1062 1046 /*
1063 1047 * the only parameters that are ready when we
1064 1048 * get GSS_S_CONTINUE_NEEDED are: minor, ctxt_handle,
1065 1049 * and the output token to send to the peer.
1066 1050 */
1067 1051
1068 1052 *context_handle = *((gssd_ctx_id_t *)
1069 1053 res.context_handle.GSS_CTX_ID_T_val);
1070 1054 *gssd_context_verifier = res.gssd_context_verifier;
1071 1055
1072 1056 /* these other parameters are only ready upon GSS_S_COMPLETE */
1073 1057 if (res.status == (OM_uint32)GSS_S_COMPLETE) {
1074 1058
1075 1059 if (src_name != NULL) {
1076 1060 src_name->length =
1077 1061 res.src_name.GSS_BUFFER_T_len;
1078 1062 src_name->value = res.src_name.GSS_BUFFER_T_val;
1079 1063 res.src_name.GSS_BUFFER_T_val = NULL;
1080 1064 res.src_name.GSS_BUFFER_T_len = 0;
1081 1065 }
1082 1066
1083 1067 /*
1084 1068 * move mech type returned to mech_type
1085 1069 * for gss_import_name_for_mech()
1086 1070 */
1087 1071 if (mech_type != NULL) {
1088 1072 *mech_type =
1089 1073 (gss_OID)MALLOC(sizeof (gss_OID_desc));
1090 1074 (*mech_type)->length =
1091 1075 (OM_UINT32)res.mech_type.GSS_OID_len;
1092 1076 (*mech_type)->elements =
1093 1077 (void *)MALLOC((*mech_type)->length);
1094 1078 (void) memcpy((*mech_type)->elements,
1095 1079 res.mech_type.GSS_OID_val,
1096 1080 (*mech_type)->length);
1097 1081 }
1098 1082
1099 1083 if (ret_flags != NULL)
1100 1084 *ret_flags = res.ret_flags;
1101 1085
1102 1086 if (time_rec != NULL)
1103 1087 *time_rec = res.time_rec;
1104 1088
1105 1089 if ((delegated_cred_handle != NULL) &&
1106 1090 (res.delegated_cred_handle.GSS_CRED_ID_T_len
1107 1091 != 0)) {
1108 1092 kcred = KGSS_CRED_ALLOC();
1109 1093 kcred->gssd_cred =
1110 1094 *((gssd_cred_id_t *)
1111 1095 res.delegated_cred_handle.GSS_CRED_ID_T_val);
1112 1096 kcred->gssd_cred_verifier =
1113 1097 res.gssd_context_verifier;
1114 1098 *delegated_cred_handle = (gss_cred_id_t)kcred;
1115 1099 }
1116 1100
1117 1101 }
1118 1102 }
1119 1103
1120 1104
1121 1105 /*
1122 1106 * free the memory allocated for the results and return with the status
1123 1107 * received in the rpc call
1124 1108 */
1125 1109
1126 1110 clnt_freeres(clnt, xdr_gss_accept_sec_context_res, (caddr_t)&res);
1127 1111 killgssd_handle(clnt);
1128 1112 return (res.status);
1129 1113
1130 1114 }
1131 1115
1132 1116 OM_uint32
1133 1117 kgss_accept_sec_context(
1134 1118 OM_uint32 *minor_status,
1135 1119 gss_ctx_id_t *context_handle,
1136 1120 const gss_cred_id_t verifier_cred_handle,
1137 1121 const gss_buffer_t input_token,
1138 1122 const gss_channel_bindings_t input_chan_bindings,
1139 1123 gss_buffer_t src_name,
1140 1124 gss_OID *mech_type,
1141 1125 gss_buffer_t output_token,
1142 1126 int *ret_flags,
1143 1127 OM_uint32 *time_rec,
1144 1128 gss_cred_id_t *delegated_cred_handle,
1145 1129 uid_t uid)
1146 1130 {
1147 1131 OM_uint32 err;
1148 1132 struct kgss_ctx *kctx;
1149 1133 gss_OID mt;
1150 1134 OM_uint32 gssd_cred_verifier;
1151 1135 gssd_cred_id_t gssd_ver_cred_handle;
1152 1136
1153 1137
1154 1138 /*
1155 1139 * See kgss_init_sec_context() to get an idea of what is going
1156 1140 * on here.
1157 1141 */
1158 1142 if (mech_type == NULL)
1159 1143 mech_type = &mt;
1160 1144
1161 1145 if (*context_handle == GSS_C_NO_CONTEXT) {
1162 1146 kctx = KGSS_ALLOC();
1163 1147 kctx->mech = &default_gc;
1164 1148 kctx->gssd_ctx = GSSD_NO_CONTEXT;
1165 1149 *context_handle = (gss_ctx_id_t)kctx;
1166 1150 } else
1167 1151 kctx = (struct kgss_ctx *)*context_handle;
1168 1152
1169 1153 if (verifier_cred_handle != GSS_C_NO_CREDENTIAL) {
1170 1154 gssd_cred_verifier = KCRED_TO_CREDV(verifier_cred_handle);
1171 1155 gssd_ver_cred_handle = KCRED_TO_CRED(verifier_cred_handle);
1172 1156 } else {
1173 1157 gssd_ver_cred_handle = GSSD_NO_CREDENTIAL;
1174 1158 }
1175 1159
1176 1160 err = kgss_accept_sec_context_wrapped(minor_status,
1177 1161 &kctx->gssd_ctx, &kctx->gssd_ctx_verifier,
1178 1162 gssd_ver_cred_handle, gssd_cred_verifier,
1179 1163 input_token, input_chan_bindings, src_name,
1180 1164 mech_type, output_token, ret_flags,
1181 1165 time_rec, delegated_cred_handle, uid);
1182 1166
1183 1167 if (GSS_ERROR(err)) {
1184 1168 KGSS_FREE(kctx);
1185 1169 *context_handle = GSS_C_NO_CONTEXT;
1186 1170
1187 1171 } else if (err == GSS_S_COMPLETE) {
1188 1172 __kgss_reset_mech(&kctx->mech, *mech_type);
1189 1173
1190 1174 /*
1191 1175 * If the mech oid was allocated for us, free it.
1192 1176 */
1193 1177 if (&mt == mech_type) {
1194 1178 kgss_free_oid(mt);
1195 1179 }
1196 1180 }
1197 1181
1198 1182 return (err);
1199 1183 }
1200 1184
1201 1185 OM_uint32
1202 1186 kgss_process_context_token(minor_status,
1203 1187 context_handle,
1204 1188 token_buffer,
1205 1189 uid)
1206 1190 OM_uint32 *minor_status;
1207 1191 const gss_ctx_id_t context_handle;
1208 1192 gss_buffer_t token_buffer;
1209 1193 uid_t uid;
1210 1194 {
1211 1195 CLIENT *clnt;
1212 1196 OM_uint32 gssd_context_verifier;
1213 1197 gssd_ctx_id_t gssd_ctx_handle;
1214 1198 gss_process_context_token_arg arg;
1215 1199 gss_process_context_token_res res;
1216 1200
1217 1201 gssd_context_verifier = KGSS_CTX_TO_GSSD_CTXV(context_handle);
1218 1202 gssd_ctx_handle = (gssd_ctx_id_t)KGSS_CTX_TO_GSSD_CTX(context_handle);
1219 1203
1220 1204 /* get the client handle to GSSD */
1221 1205
1222 1206 if ((clnt = getgssd_handle()) == NULL) {
1223 1207 GSSLOG(1,
1224 1208 "kgss_process_context_token: can't connect to server on %s\n",
1225 1209 server);
1226 1210 return (GSS_S_FAILURE);
1227 1211 }
1228 1212
1229 1213 /* copy the procedure arguments into the rpc arg parameter */
1230 1214
1231 1215 arg.uid = (OM_uint32) uid;
1232 1216
1233 1217 arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gssd_ctx_id_t);
1234 1218 arg.context_handle.GSS_CTX_ID_T_val = (char *)&gssd_ctx_handle;
1235 1219 arg.gssd_context_verifier = gssd_context_verifier;
1236 1220 arg.token_buffer.GSS_BUFFER_T_len = (uint_t)token_buffer->length;
1237 1221 arg.token_buffer.GSS_BUFFER_T_val = (char *)token_buffer->value;
1238 1222
1239 1223 /* call the remote procedure */
1240 1224
1241 1225 bzero(&res, sizeof (res));
1242 1226
1243 1227 if (gss_process_context_token_1(&arg, &res, clnt) != RPC_SUCCESS) {
1244 1228
1245 1229 /*
1246 1230 * if the RPC call times out, null out all return arguments, set
1247 1231 * minor_status to its maximum value, and return GSS_S_FAILURE
1248 1232 */
1249 1233
1250 1234 if (minor_status != NULL)
1251 1235 *minor_status = DEFAULT_MINOR_STAT;
1252 1236 GSSLOG0(1, "kgss_process_context_token: RPC call times out\n");
1253 1237 killgssd_handle(clnt);
1254 1238 return (GSS_S_FAILURE);
1255 1239 }
1256 1240
1257 1241 /* copy the rpc results into the return arguments */
1258 1242
1259 1243 if (minor_status != NULL)
1260 1244 *minor_status = res.minor_status;
1261 1245
1262 1246 /* return with status returned in rpc call */
1263 1247
1264 1248 killgssd_handle(clnt);
1265 1249 return (res.status);
1266 1250
1267 1251 }
1268 1252
1269 1253 /*ARGSUSED*/
1270 1254 static OM_uint32
1271 1255 kgss_delete_sec_context_wrapped(void *private,
1272 1256 OM_uint32 *minor_status,
1273 1257 gssd_ctx_id_t *context_handle,
1274 1258 gss_buffer_t output_token,
1275 1259 OM_uint32 gssd_context_verifier)
1276 1260
1277 1261
1278 1262 {
1279 1263 CLIENT *clnt;
1280 1264
1281 1265 gss_delete_sec_context_arg arg;
1282 1266 gss_delete_sec_context_res res;
1283 1267
1284 1268
1285 1269 /* get the client handle to GSSD */
1286 1270
1287 1271 if ((clnt = getgssd_handle()) == NULL) {
1288 1272 GSSLOG(1,
1289 1273 "kgss_delete_sec_context: can't connect to server on %s\n",
1290 1274 server);
1291 1275 return (GSS_S_FAILURE);
1292 1276 }
1293 1277
1294 1278 /* copy the procedure arguments into the rpc arg parameter */
1295 1279
1296 1280 arg.context_handle.GSS_CTX_ID_T_len =
1297 1281 *context_handle == GSSD_NO_CONTEXT ?
1298 1282 0 : (uint_t)sizeof (gssd_ctx_id_t);
1299 1283 arg.context_handle.GSS_CTX_ID_T_val = (char *)context_handle;
1300 1284
1301 1285 arg.gssd_context_verifier = gssd_context_verifier;
1302 1286
1303 1287 /* call the remote procedure */
1304 1288
1305 1289 bzero((caddr_t)&res, sizeof (res));
1306 1290 if (gss_delete_sec_context_1(&arg, &res, clnt) != RPC_SUCCESS) {
1307 1291
1308 1292 /*
1309 1293 * if the RPC call times out, null out all return arguments, set
1310 1294 * minor_status to its maximum value, and return GSS_S_FAILURE
1311 1295 */
1312 1296
1313 1297 if (minor_status != NULL)
1314 1298 *minor_status = DEFAULT_MINOR_STAT;
1315 1299 if (context_handle != NULL)
1316 1300 *context_handle = NULL;
1317 1301 if (output_token != NULL)
1318 1302 output_token->length = 0;
1319 1303
1320 1304 killgssd_handle(clnt);
1321 1305 GSSLOG0(1, "kgssd_delete_sec_context: RPC call times out\n");
1322 1306 return (GSS_S_FAILURE);
1323 1307 }
1324 1308
1325 1309 /* copy the rpc results into the return arguments */
1326 1310
1327 1311 if (minor_status != NULL)
1328 1312 *minor_status = res.minor_status;
1329 1313
1330 1314 if (res.context_handle.GSS_CTX_ID_T_len == 0)
1331 1315 *context_handle = NULL;
1332 1316 else
1333 1317 *context_handle =
1334 1318 *((gssd_ctx_id_t *)res.context_handle.GSS_CTX_ID_T_val);
1335 1319
1336 1320 if (output_token != NULL) {
1337 1321 output_token->length = res.output_token.GSS_BUFFER_T_len;
1338 1322 output_token->value = res.output_token.GSS_BUFFER_T_val;
1339 1323 res.output_token.GSS_BUFFER_T_len = 0;
1340 1324 res.output_token.GSS_BUFFER_T_val = NULL;
1341 1325 }
1342 1326
1343 1327 /*
1344 1328 * free the memory allocated for the results and return with the status
1345 1329 * received in the rpc call
1346 1330 */
1347 1331
1348 1332 clnt_freeres(clnt, xdr_gss_delete_sec_context_res, (caddr_t)&res);
1349 1333 killgssd_handle(clnt);
1350 1334 return (res.status);
1351 1335
1352 1336 }
1353 1337
1354 1338 OM_uint32
1355 1339 kgss_delete_sec_context(
1356 1340 OM_uint32 *minor_status,
1357 1341 gss_ctx_id_t *context_handle,
1358 1342 gss_buffer_t output_token)
1359 1343 {
1360 1344 OM_uint32 err;
1361 1345 struct kgss_ctx *kctx;
1362 1346
1363 1347 if (*context_handle == GSS_C_NO_CONTEXT) {
1364 1348 GSSLOG0(8, "kgss_delete_sec_context: Null context handle \n");
1365 1349 return (GSS_S_COMPLETE);
1366 1350 } else
1367 1351 kctx = (struct kgss_ctx *)*context_handle;
1368 1352
1369 1353 if (kctx->ctx_imported == FALSE) {
1370 1354 if (kctx->gssd_ctx == GSSD_NO_CONTEXT) {
1371 1355 KGSS_FREE(kctx);
1372 1356 *context_handle = GSS_C_NO_CONTEXT;
1373 1357 return (GSS_S_COMPLETE);
1374 1358 }
1375 1359 err = kgss_delete_sec_context_wrapped(
1376 1360 KCTX_TO_PRIVATE(*context_handle),
1377 1361 minor_status,
1378 1362 &kctx->gssd_ctx,
1379 1363 output_token,
1380 1364 kctx->gssd_ctx_verifier);
1381 1365 } else {
1382 1366 if (kctx->gssd_i_ctx == (gss_ctx_id_t)GSS_C_NO_CONTEXT) {
1383 1367 KGSS_FREE(kctx);
1384 1368 *context_handle = GSS_C_NO_CONTEXT;
1385 1369 return (GSS_S_COMPLETE);
1386 1370 }
1387 1371 err = KGSS_DELETE_SEC_CONTEXT(minor_status, kctx,
1388 1372 &kctx->gssd_i_ctx, output_token);
1389 1373 }
1390 1374 KGSS_FREE(kctx);
1391 1375 *context_handle = GSS_C_NO_CONTEXT;
1392 1376 return (err);
1393 1377
1394 1378 }
1395 1379
1396 1380
1397 1381 OM_uint32
1398 1382 kgss_export_sec_context_wrapped(minor_status,
1399 1383 context_handle,
1400 1384 output_token,
1401 1385 gssd_context_verifier)
1402 1386 OM_uint32 *minor_status;
1403 1387 gssd_ctx_id_t *context_handle;
1404 1388 gss_buffer_t output_token;
1405 1389 OM_uint32 gssd_context_verifier;
1406 1390 {
1407 1391 CLIENT *clnt;
1408 1392 gss_export_sec_context_arg arg;
1409 1393 gss_export_sec_context_res res;
1410 1394
1411 1395
1412 1396 /* get the client handle to GSSD */
1413 1397
1414 1398 if ((clnt = getgssd_handle()) == NULL) {
1415 1399 GSSLOG(1, "kgss_export_sec_context_wrapped :"
1416 1400 " can't connect to server on %s\n", server);
1417 1401 return (GSS_S_FAILURE);
1418 1402 }
1419 1403
1420 1404 /* copy the procedure arguments into the rpc arg parameter */
1421 1405
1422 1406 arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gssd_ctx_id_t);
1423 1407 arg.context_handle.GSS_CTX_ID_T_val = (char *)context_handle;
1424 1408 arg.gssd_context_verifier = gssd_context_verifier;
1425 1409
1426 1410 /* call the remote procedure */
1427 1411
1428 1412 (void) memset(&res, 0, sizeof (res));
1429 1413 if (gss_export_sec_context_1(&arg, &res, clnt) != RPC_SUCCESS) {
1430 1414
1431 1415 /*
1432 1416 * if the RPC call times out, null out all return arguments,
1433 1417 * set minor_status to its maximum value, and return
1434 1418 * GSS_S_FAILURE
1435 1419 */
1436 1420
1437 1421 if (minor_status != NULL)
1438 1422 *minor_status = DEFAULT_MINOR_STAT;
1439 1423 if (context_handle != NULL)
1440 1424 *context_handle = NULL;
1441 1425 if (output_token != NULL)
1442 1426 output_token->length = 0;
1443 1427 killgssd_handle(clnt);
1444 1428 GSSLOG0(1,
1445 1429 "kgss_export_sec_context_wrapped: RPC call times out\n");
1446 1430 return (GSS_S_FAILURE);
1447 1431 }
1448 1432
1449 1433 /* copy the rpc results into the return arguments */
1450 1434
1451 1435 if (minor_status != NULL)
1452 1436 *minor_status = res.minor_status;
1453 1437
1454 1438 if (res.context_handle.GSS_CTX_ID_T_len == 0)
1455 1439 *context_handle = NULL;
1456 1440 else
1457 1441 *context_handle =
1458 1442 *((gssd_ctx_id_t *)res.context_handle.GSS_CTX_ID_T_val);
1459 1443
1460 1444 if (output_token != NULL) {
1461 1445 output_token->length = res.output_token.GSS_BUFFER_T_len;
1462 1446 output_token->value =
1463 1447 (void *) MALLOC(output_token->length);
1464 1448 (void) memcpy(output_token->value,
1465 1449 res.output_token.GSS_BUFFER_T_val,
1466 1450 output_token->length);
1467 1451 }
1468 1452
1469 1453 /*
1470 1454 * free the memory allocated for the results and return with the status
1471 1455 * received in the rpc call
1472 1456 */
1473 1457
1474 1458 clnt_freeres(clnt, xdr_gss_export_sec_context_res, (caddr_t)&res);
1475 1459 killgssd_handle(clnt);
1476 1460 return (res.status);
1477 1461
1478 1462 }
1479 1463
1480 1464 OM_uint32
1481 1465 kgss_export_sec_context(minor_status,
1482 1466 context_handle,
1483 1467 output_token)
1484 1468 OM_uint32 *minor_status;
1485 1469 gss_ctx_id_t context_handle;
1486 1470 gss_buffer_t output_token;
1487 1471 {
1488 1472 struct kgss_ctx *kctx;
1489 1473
1490 1474 if (context_handle == GSS_C_NO_CONTEXT)
1491 1475 return (GSS_S_FAILURE);
1492 1476 else
1493 1477 kctx = (struct kgss_ctx *)context_handle;
1494 1478
1495 1479
1496 1480
1497 1481 /*
1498 1482 * If there is a kernel module then import_sec context must be
1499 1483 * supported and we make an upcall to export_sec_context.
1500 1484 * If there is no kernel module then we return an error
1501 1485 */
1502 1486
1503 1487 *minor_status = 0;
1504 1488
1505 1489 if (kctx->mech->gss_import_sec_context) {
1506 1490 GSSLOG0(8, "kgss_export_sec_context: Kernel mod available \n");
1507 1491 return (kgss_export_sec_context_wrapped(minor_status,
1508 1492 &kctx->gssd_ctx,
1509 1493 output_token,
1510 1494 kctx->gssd_ctx_verifier));
1511 1495
1512 1496 } else {
1513 1497
1514 1498 /*
1515 1499 * This is not the right error value; instead of
1516 1500 * inventing new error we return GSS_S_NAME_NOT_MN
1517 1501 * This error is not returned by the export routine
1518 1502 */
1519 1503
1520 1504 GSSLOG0(8, "kgss_export_sec_context: Kernel mod "
1521 1505 "unavailable \n");
1522 1506 return (GSS_S_NAME_NOT_MN);
1523 1507 }
1524 1508
1525 1509 }
1526 1510
1527 1511 OM_uint32
1528 1512 kgss_import_sec_context(minor_status,
1529 1513 interprocess_token,
1530 1514 context_handle)
1531 1515
1532 1516 OM_uint32 * minor_status;
1533 1517 const gss_buffer_t interprocess_token;
1534 1518 gss_ctx_id_t context_handle;
1535 1519
1536 1520 {
1537 1521 OM_uint32 status;
1538 1522 struct kgss_ctx *kctx;
1539 1523
1540 1524 size_t length;
1541 1525 char *p;
1542 1526 gss_buffer_desc token;
1543 1527 gss_ctx_id_t internal_ctx_id;
1544 1528 kctx = (struct kgss_ctx *)context_handle;
1545 1529
1546 1530 if (kctx->gssd_ctx != GSSD_NO_CONTEXT) {
1547 1531 return (GSS_S_FAILURE);
1548 1532 }
1549 1533
1550 1534 if (!(KCTX_TO_MECH(context_handle)->gss_import_sec_context)) {
1551 1535
1552 1536 /*
1553 1537 * This should never happen
1554 1538 * If Kernel import sec context does not exist the export
1555 1539 * sec context should have caught this and returned an error
1556 1540 * and the caller should not have called this routine
1557 1541 */
1558 1542 GSSLOG0(1, "import_sec_context called improperly\n");
1559 1543 return (GSS_S_FAILURE);
1560 1544 }
1561 1545 *minor_status = 0;
1562 1546
1563 1547 if (interprocess_token->length == 0 || interprocess_token->value == 0)
1564 1548 return (GSS_S_DEFECTIVE_TOKEN);
1565 1549
1566 1550 status = GSS_S_FAILURE;
1567 1551
1568 1552 p = interprocess_token->value;
1569 1553 length = *p++;
1570 1554 length = (length << 8) + *p++;
1571 1555 length = (length << 8) + *p++;
1572 1556 length = (length << 8) + *p++;
1573 1557
1574 1558 p += length;
1575 1559
1576 1560 token.length = interprocess_token->length - 4 - length;
1577 1561 token.value = p;
1578 1562
1579 1563 /*
1580 1564 * select the approprate underlying mechanism routine and
1581 1565 * call it.
1582 1566 */
1583 1567
1584 1568 status = KGSS_IMPORT_SEC_CONTEXT(minor_status, &token, kctx,
1585 1569 &internal_ctx_id);
1586 1570
1587 1571 if (status == GSS_S_COMPLETE) {
1588 1572 KCTX_TO_I_CTX(kctx) = internal_ctx_id;
1589 1573 kctx->ctx_imported = TRUE;
1590 1574 return (GSS_S_COMPLETE);
1591 1575 } else
1592 1576 return (status);
1593 1577 }
1594 1578
1595 1579 /*ARGSUSED*/
1596 1580 OM_uint32
1597 1581 kgss_context_time(minor_status,
1598 1582 context_handle,
1599 1583 time_rec,
1600 1584 uid)
1601 1585 OM_uint32 *minor_status;
1602 1586 const gss_ctx_id_t context_handle;
1603 1587 OM_uint32 *time_rec;
1604 1588 uid_t uid;
1605 1589 {
1606 1590 return (GSS_S_FAILURE);
1607 1591 }
1608 1592
1609 1593 /*ARGSUSED*/
1610 1594 static OM_uint32
1611 1595 kgss_sign_wrapped(void *private,
1612 1596 OM_uint32 *minor_status,
1613 1597 const gss_ctx_id_t ctx_handle,
1614 1598 int qop_req,
1615 1599 const gss_buffer_t message_buffer,
1616 1600 gss_buffer_t msg_token,
1617 1601 OM_uint32 gssd_context_verifier)
1618 1602 {
1619 1603 CLIENT *clnt;
1620 1604 gssd_ctx_id_t context_handle;
1621 1605
1622 1606 gss_sign_arg arg;
1623 1607 gss_sign_res res;
1624 1608 context_handle = (gssd_ctx_id_t)KCTX_TO_GSSD_CTX(ctx_handle);
1625 1609 /* get the client handle to GSSD */
1626 1610
1627 1611 if ((clnt = getgssd_handle()) == NULL) {
1628 1612 GSSLOG(1, "kgss_sign: can't connect to server on %s\n", server);
1629 1613 return (GSS_S_FAILURE);
1630 1614 }
1631 1615
1632 1616 /* copy the procedure arguments into the rpc arg parameter */
1633 1617
1634 1618 arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gssd_ctx_id_t);
1635 1619 arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle;
1636 1620
1637 1621 arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gssd_ctx_id_t);
1638 1622 arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle;
1639 1623 arg.gssd_context_verifier = gssd_context_verifier;
1640 1624
1641 1625 arg.qop_req = qop_req;
1642 1626
1643 1627 arg.message_buffer.GSS_BUFFER_T_len = (uint_t)message_buffer->length;
1644 1628 arg.message_buffer.GSS_BUFFER_T_val = (char *)message_buffer->value;
1645 1629
1646 1630 /* call the remote procedure */
1647 1631
1648 1632 bzero((caddr_t)&res, sizeof (res));
1649 1633 if (gss_sign_1(&arg, &res, clnt) != RPC_SUCCESS) {
1650 1634
1651 1635 /*
1652 1636 * if the RPC call times out, null out all return arguments, set
1653 1637 * minor_status to its maximum value, and return GSS_S_FAILURE
1654 1638 */
1655 1639
1656 1640 if (minor_status != NULL)
1657 1641 *minor_status = DEFAULT_MINOR_STAT;
1658 1642 if (msg_token != NULL)
1659 1643 msg_token->length = 0;
1660 1644
1661 1645 killgssd_handle(clnt);
1662 1646 GSSLOG0(1, "kgss_sign: RPC call times out\n");
1663 1647 return (GSS_S_FAILURE);
1664 1648 }
1665 1649
1666 1650 /* copy the rpc results into the return arguments */
1667 1651
1668 1652 if (minor_status != NULL)
1669 1653 *minor_status = res.minor_status;
1670 1654
1671 1655 if (msg_token != NULL) {
1672 1656 msg_token->length = res.msg_token.GSS_BUFFER_T_len;
1673 1657 msg_token->value = (void *) MALLOC(msg_token->length);
1674 1658 (void) memcpy(msg_token->value, res.msg_token.GSS_BUFFER_T_val,
1675 1659 msg_token->length);
1676 1660 }
1677 1661
1678 1662 /*
1679 1663 * free the memory allocated for the results and return with the status
1680 1664 * received in the rpc call
1681 1665 */
1682 1666
1683 1667 clnt_freeres(clnt, xdr_gss_sign_res, (caddr_t)&res);
1684 1668 killgssd_handle(clnt);
1685 1669 return (res.status);
1686 1670
1687 1671 }
1688 1672
1689 1673 OM_uint32
1690 1674 kgss_sign(
1691 1675 OM_uint32 *minor_status,
1692 1676 const gss_ctx_id_t context_handle,
1693 1677 int qop_req,
1694 1678 const gss_buffer_t message_buffer,
1695 1679 gss_buffer_t msg_token)
1696 1680 {
1697 1681 if (context_handle == GSS_C_NO_CONTEXT)
1698 1682 return (GSS_S_FAILURE);
1699 1683 return (KGSS_SIGN(minor_status, context_handle, qop_req,
1700 1684 message_buffer, msg_token));
1701 1685 }
1702 1686
1703 1687 /*ARGSUSED*/
1704 1688 static OM_uint32
1705 1689 kgss_verify_wrapped(void *private,
1706 1690 OM_uint32 *minor_status,
1707 1691 const gss_ctx_id_t ctx_handle,
1708 1692 const gss_buffer_t message_buffer,
1709 1693 const gss_buffer_t token_buffer,
1710 1694 int *qop_state,
1711 1695 OM_uint32 gssd_context_verifier)
1712 1696 {
1713 1697 CLIENT *clnt;
1714 1698
1715 1699 gssd_ctx_id_t context_handle;
1716 1700 gss_verify_arg arg;
1717 1701 gss_verify_res res;
1718 1702
1719 1703 context_handle = (gssd_ctx_id_t)KCTX_TO_GSSD_CTX(ctx_handle);
1720 1704
1721 1705 /* get the client handle to GSSD */
1722 1706
1723 1707 if ((clnt = getgssd_handle()) == NULL) {
1724 1708 GSSLOG(1, "kgss_verify: can't connect to server on %s\n",
1725 1709 server);
1726 1710 return (GSS_S_FAILURE);
1727 1711 }
1728 1712
1729 1713 /* copy the procedure arguments into the rpc arg parameter */
1730 1714
1731 1715 arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gss_ctx_id_t);
1732 1716 arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle;
1733 1717
1734 1718 arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gssd_ctx_id_t);
1735 1719 arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle;
1736 1720 arg.gssd_context_verifier = gssd_context_verifier;
1737 1721
1738 1722 arg.message_buffer.GSS_BUFFER_T_len = (uint_t)message_buffer->length;
1739 1723 arg.message_buffer.GSS_BUFFER_T_val = (char *)message_buffer->value;
1740 1724
1741 1725 arg.token_buffer.GSS_BUFFER_T_len = (uint_t)token_buffer->length;
1742 1726 arg.token_buffer.GSS_BUFFER_T_val = (char *)token_buffer->value;
1743 1727
1744 1728 /* call the remote procedure */
1745 1729
1746 1730 bzero((caddr_t)&res, sizeof (res));
1747 1731 if (gss_verify_1(&arg, &res, clnt) != RPC_SUCCESS) {
1748 1732
1749 1733 /*
1750 1734 * if the RPC call times out, null out all return arguments, set
1751 1735 * minor_status to its maximum value, and return GSS_S_FAILURE
1752 1736 */
1753 1737
1754 1738 if (minor_status != NULL)
1755 1739 *minor_status = DEFAULT_MINOR_STAT;
1756 1740 if (qop_state != NULL)
1757 1741 *qop_state = 0;
1758 1742
1759 1743 killgssd_handle(clnt);
1760 1744 GSSLOG0(1, "kgss_verify: RPC call times out\n");
1761 1745 return (GSS_S_FAILURE);
1762 1746 }
1763 1747
1764 1748 /* copy the rpc results into the return arguments */
1765 1749
1766 1750 if (minor_status != NULL)
1767 1751 *minor_status = res.minor_status;
1768 1752
1769 1753 if (qop_state != NULL)
1770 1754 *qop_state = res.qop_state;
1771 1755
1772 1756 /* return with status returned in rpc call */
1773 1757
1774 1758 killgssd_handle(clnt);
1775 1759 return (res.status);
1776 1760
1777 1761 }
1778 1762
1779 1763 OM_uint32
1780 1764 kgss_verify(OM_uint32 *minor_status,
1781 1765 const gss_ctx_id_t context_handle,
↓ open down ↓ |
930 lines elided |
↑ open up ↑ |
1782 1766 const gss_buffer_t message_buffer,
1783 1767 const gss_buffer_t token_buffer,
1784 1768 int *qop_state)
1785 1769 {
1786 1770 if (context_handle == GSS_C_NO_CONTEXT)
1787 1771 return (GSS_S_FAILURE);
1788 1772 return (KGSS_VERIFY(minor_status, context_handle,
1789 1773 message_buffer, token_buffer, qop_state));
1790 1774 }
1791 1775
1792 -/* EXPORT DELETE START */
1793 -
1794 1776 /*ARGSUSED*/
1795 1777 static OM_uint32
1796 1778 kgss_seal_wrapped(void *private,
1797 1779 OM_uint32 *minor_status,
1798 1780 const gss_ctx_id_t ctx_handle,
1799 1781 int conf_req_flag,
1800 1782 int qop_req,
1801 1783 const gss_buffer_t input_message_buffer,
1802 1784 int *conf_state,
1803 1785 gss_buffer_t output_message_buffer,
1804 1786 OM_uint32 gssd_context_verifier)
1805 1787 {
1806 1788 CLIENT *clnt;
1807 1789 gssd_ctx_id_t context_handle;
1808 1790
1809 1791 gss_seal_arg arg;
1810 1792 gss_seal_res res;
1811 1793
1812 1794 context_handle = (gssd_ctx_id_t)KCTX_TO_GSSD_CTX(ctx_handle);
1813 1795
1814 1796 /* get the client handle to GSSD */
1815 1797
1816 1798 if ((clnt = getgssd_handle()) == NULL) {
1817 1799 GSSLOG(1, "kgss_seal: can't connect to server on %s\n", server);
1818 1800 return (GSS_S_FAILURE);
1819 1801 }
1820 1802
1821 1803 /* copy the procedure arguments into the rpc arg parameter */
1822 1804
1823 1805 arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gss_ctx_id_t);
1824 1806 arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle;
1825 1807
1826 1808 arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (OM_uint32);
1827 1809 arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle;
1828 1810 arg.gssd_context_verifier = gssd_context_verifier;
1829 1811
1830 1812 arg.conf_req_flag = conf_req_flag;
1831 1813
1832 1814 arg.qop_req = qop_req;
1833 1815
1834 1816 arg.input_message_buffer.GSS_BUFFER_T_len =
1835 1817 (uint_t)input_message_buffer->length;
1836 1818
1837 1819 arg.input_message_buffer.GSS_BUFFER_T_val =
1838 1820 (char *)input_message_buffer->value;
1839 1821
1840 1822 /* call the remote procedure */
1841 1823
1842 1824 bzero((caddr_t)&res, sizeof (res));
1843 1825 if (gss_seal_1(&arg, &res, clnt) != RPC_SUCCESS) {
1844 1826
1845 1827 /*
1846 1828 * if the RPC call times out, null out all return arguments, set
1847 1829 * minor_status to its maximum value, and return GSS_S_FAILURE
1848 1830 */
1849 1831
1850 1832 if (minor_status != NULL)
1851 1833 *minor_status = DEFAULT_MINOR_STAT;
1852 1834 if (conf_state != NULL)
1853 1835 *conf_state = 0;
1854 1836 if (output_message_buffer != NULL)
1855 1837 output_message_buffer->length = 0;
1856 1838
1857 1839 killgssd_handle(clnt);
1858 1840 GSSLOG0(1, "kgss_seal: RPC call times out\n");
1859 1841 return (GSS_S_FAILURE);
1860 1842 }
1861 1843
1862 1844 /* copy the rpc results into the return arguments */
1863 1845
1864 1846 if (minor_status != NULL)
1865 1847 *minor_status = res.minor_status;
1866 1848
1867 1849 if (conf_state != NULL)
1868 1850 *conf_state = res.conf_state;
1869 1851
1870 1852 if (output_message_buffer != NULL) {
1871 1853 output_message_buffer->length =
1872 1854 res.output_message_buffer.GSS_BUFFER_T_len;
1873 1855
1874 1856 output_message_buffer->value =
1875 1857 (void *) MALLOC(output_message_buffer->length);
1876 1858 (void) memcpy(output_message_buffer->value,
1877 1859 res.output_message_buffer.GSS_BUFFER_T_val,
1878 1860 output_message_buffer->length);
1879 1861 }
1880 1862
1881 1863 /*
1882 1864 * free the memory allocated for the results and return with the status
1883 1865 * received in the rpc call
1884 1866 */
1885 1867
1886 1868 clnt_freeres(clnt, xdr_gss_seal_res, (caddr_t)&res);
1887 1869 killgssd_handle(clnt);
1888 1870 return (res.status);
1889 1871 }
1890 1872
1891 1873 /*ARGSUSED*/
1892 1874 OM_uint32
1893 1875 kgss_seal(OM_uint32 *minor_status,
1894 1876 const gss_ctx_id_t context_handle,
1895 1877 int conf_req_flag,
1896 1878 int qop_req,
1897 1879 const gss_buffer_t input_message_buffer,
1898 1880 int *conf_state,
1899 1881 gss_buffer_t output_message_buffer)
1900 1882
1901 1883 {
1902 1884 if (context_handle == GSS_C_NO_CONTEXT)
1903 1885 return (GSS_S_FAILURE);
1904 1886 return (KGSS_SEAL(minor_status, context_handle,
1905 1887 conf_req_flag, qop_req,
1906 1888 input_message_buffer, conf_state,
1907 1889 output_message_buffer));
1908 1890 }
1909 1891
1910 1892 /*ARGSUSED*/
1911 1893 static OM_uint32
1912 1894 kgss_unseal_wrapped(void *private,
1913 1895 OM_uint32 *minor_status,
1914 1896 const gss_ctx_id_t ctx_handle,
1915 1897 const gss_buffer_t input_message_buffer,
1916 1898 gss_buffer_t output_message_buffer,
1917 1899 int *conf_state,
1918 1900 int *qop_state,
1919 1901 OM_uint32 gssd_context_verifier)
1920 1902 {
1921 1903 CLIENT *clnt;
1922 1904
1923 1905 gss_unseal_arg arg;
1924 1906 gss_unseal_res res;
1925 1907 gssd_ctx_id_t context_handle;
1926 1908
1927 1909 context_handle = (gssd_ctx_id_t)KCTX_TO_GSSD_CTX(ctx_handle);
1928 1910
1929 1911 /* get the client handle to GSSD */
1930 1912
1931 1913 if ((clnt = getgssd_handle()) == NULL) {
1932 1914 GSSLOG(1, "kgss_unseal: can't connect to server on %s\n",
1933 1915 server);
1934 1916 return (GSS_S_FAILURE);
1935 1917 }
1936 1918
1937 1919 /* copy the procedure arguments into the rpc arg parameter */
1938 1920
1939 1921 arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gss_ctx_id_t);
1940 1922 arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle;
1941 1923
1942 1924 arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gssd_ctx_id_t);
1943 1925 arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle;
1944 1926 arg.gssd_context_verifier = gssd_context_verifier;
1945 1927
1946 1928 arg.input_message_buffer.GSS_BUFFER_T_len =
1947 1929 (uint_t)input_message_buffer->length;
1948 1930
1949 1931 arg.input_message_buffer.GSS_BUFFER_T_val =
1950 1932 (char *)input_message_buffer->value;
1951 1933
1952 1934 /* call the remote procedure */
1953 1935
1954 1936 bzero((caddr_t)&res, sizeof (res));
1955 1937 if (gss_unseal_1(&arg, &res, clnt) != RPC_SUCCESS) {
1956 1938
1957 1939 /*
1958 1940 * if the RPC call times out, null out all return arguments, set
1959 1941 * minor_status to its maximum value, and return GSS_S_FAILURE
1960 1942 */
1961 1943
1962 1944 if (minor_status != NULL)
1963 1945 *minor_status = DEFAULT_MINOR_STAT;
1964 1946 if (output_message_buffer != NULL)
1965 1947 output_message_buffer->length = 0;
1966 1948 if (conf_state != NULL)
1967 1949 *conf_state = 0;
1968 1950 if (qop_state != NULL)
1969 1951 *qop_state = 0;
1970 1952
1971 1953 killgssd_handle(clnt);
1972 1954 GSSLOG0(1, "kgss_unseal: RPC call times out\n");
1973 1955 return (GSS_S_FAILURE);
1974 1956 }
1975 1957
1976 1958 /* copy the rpc results into the return arguments */
1977 1959
1978 1960 if (minor_status != NULL)
1979 1961 *minor_status = res.minor_status;
1980 1962
1981 1963 if (output_message_buffer != NULL) {
1982 1964 output_message_buffer->length =
1983 1965 res.output_message_buffer.GSS_BUFFER_T_len;
1984 1966
1985 1967 output_message_buffer->value =
1986 1968 (void *) MALLOC(output_message_buffer->length);
1987 1969 (void) memcpy(output_message_buffer->value,
1988 1970 res.output_message_buffer.GSS_BUFFER_T_val,
1989 1971 output_message_buffer->length);
1990 1972 }
1991 1973
1992 1974 if (conf_state != NULL)
1993 1975 *conf_state = res.conf_state;
1994 1976
1995 1977 if (qop_state != NULL)
1996 1978 *qop_state = res.qop_state;
1997 1979
1998 1980 /*
1999 1981 * free the memory allocated for the results and return with the
2000 1982 * status received in the rpc call
2001 1983 */
2002 1984
2003 1985 clnt_freeres(clnt, xdr_gss_unseal_res, (caddr_t)&res);
2004 1986 killgssd_handle(clnt);
2005 1987 return (res.status);
2006 1988 }
2007 1989
2008 1990 OM_uint32
2009 1991 kgss_unseal(OM_uint32 *minor_status,
2010 1992 const gss_ctx_id_t context_handle,
2011 1993 const gss_buffer_t input_message_buffer,
2012 1994 const gss_buffer_t output_message_buffer,
2013 1995 int *conf_state,
↓ open down ↓ |
210 lines elided |
↑ open up ↑ |
2014 1996 int *qop_state)
2015 1997 {
2016 1998
2017 1999 if (context_handle == GSS_C_NO_CONTEXT)
2018 2000 return (GSS_S_FAILURE);
2019 2001
2020 2002 return (KGSS_UNSEAL(minor_status, context_handle, input_message_buffer,
2021 2003 output_message_buffer, conf_state, qop_state));
2022 2004 }
2023 2005
2024 -/* EXPORT DELETE END */
2025 -
2026 2006 OM_uint32
2027 2007 kgss_display_status(minor_status,
2028 2008 status_value,
2029 2009 status_type,
2030 2010 mech_type,
2031 2011 message_context,
2032 2012 status_string,
2033 2013 uid)
2034 2014 OM_uint32 *minor_status;
2035 2015 OM_uint32 status_value;
2036 2016 int status_type;
2037 2017 const gss_OID mech_type;
2038 2018 int *message_context;
2039 2019 gss_buffer_t status_string;
2040 2020 uid_t uid;
2041 2021 {
2042 2022 CLIENT *clnt;
2043 2023
2044 2024 gss_display_status_arg arg;
2045 2025 gss_display_status_res res;
2046 2026
2047 2027 /* get the client handle to GSSD */
2048 2028
2049 2029 if ((clnt = getgssd_handle()) == NULL) {
2050 2030 GSSLOG(1, "kgss_display_status: can't connect to server on %s\n",
2051 2031 server);
2052 2032 return (GSS_S_FAILURE);
2053 2033 }
2054 2034
2055 2035 /* copy the procedure arguments into the rpc arg parameter */
2056 2036
2057 2037 arg.uid = (OM_uint32) uid;
2058 2038
2059 2039 arg.status_value = status_value;
2060 2040 arg.status_type = status_type;
2061 2041
2062 2042 arg.mech_type.GSS_OID_len = (uint_t)(mech_type != GSS_C_NULL_OID ?
2063 2043 mech_type->length : 0);
2064 2044 arg.mech_type.GSS_OID_val = (char *)(mech_type != GSS_C_NULL_OID ?
2065 2045 mech_type->elements : 0);
2066 2046
2067 2047 arg.message_context = *message_context;
2068 2048
2069 2049 /* call the remote procedure */
2070 2050
2071 2051 if (message_context != NULL)
2072 2052 *message_context = 0;
2073 2053 if (status_string != NULL) {
2074 2054 status_string->length = 0;
2075 2055 status_string->value = NULL;
2076 2056 }
2077 2057
2078 2058 bzero((caddr_t)&res, sizeof (res));
2079 2059 if (gss_display_status_1(&arg, &res, clnt) != RPC_SUCCESS) {
2080 2060
2081 2061 /*
2082 2062 * if the RPC call times out, null out all return arguments, set
2083 2063 * minor_status to its maximum value, and return GSS_S_FAILURE
2084 2064 */
2085 2065
2086 2066 if (minor_status != NULL)
2087 2067 *minor_status = DEFAULT_MINOR_STAT;
2088 2068
2089 2069 killgssd_handle(clnt);
2090 2070 GSSLOG0(1, "kgss_display_status: RPC call time out\n");
2091 2071 return (GSS_S_FAILURE);
2092 2072 }
2093 2073
2094 2074
2095 2075 /* now process the results and pass them back to the caller */
2096 2076
2097 2077 if (res.status == GSS_S_COMPLETE) {
2098 2078 if (minor_status != NULL)
2099 2079 *minor_status = res.minor_status;
2100 2080 if (message_context != NULL)
2101 2081 *message_context = res.message_context;
2102 2082 if (status_string != NULL) {
2103 2083 status_string->length =
2104 2084 (size_t)res.status_string.GSS_BUFFER_T_len;
2105 2085 status_string->value =
2106 2086 (void *) MALLOC(status_string->length);
2107 2087 (void) memcpy(status_string->value,
2108 2088 res.status_string.GSS_BUFFER_T_val,
2109 2089 status_string->length);
2110 2090 }
2111 2091 }
2112 2092
2113 2093 clnt_freeres(clnt, xdr_gss_display_status_res, (caddr_t)&res);
2114 2094 killgssd_handle(clnt);
2115 2095 return (res.status);
2116 2096 }
2117 2097
2118 2098 /*ARGSUSED*/
2119 2099 OM_uint32
2120 2100 kgss_indicate_mechs(minor_status,
2121 2101 mech_set,
2122 2102 uid)
2123 2103 OM_uint32 *minor_status;
2124 2104 gss_OID_set *mech_set;
2125 2105 uid_t uid;
2126 2106 {
2127 2107 CLIENT *clnt;
2128 2108 void *arg;
2129 2109 gss_indicate_mechs_res res;
2130 2110 int i;
2131 2111
2132 2112 /* get the client handle to GSSD */
2133 2113
2134 2114 if ((clnt = getgssd_handle()) == NULL) {
2135 2115 GSSLOG(1, "kgss_indicate_mechs: can't connect to server on %s\n",
2136 2116 server);
2137 2117 return (GSS_S_FAILURE);
2138 2118 }
2139 2119
2140 2120 bzero((caddr_t)&res, sizeof (res));
2141 2121 if (gss_indicate_mechs_1(&arg, &res, clnt) != RPC_SUCCESS) {
2142 2122
2143 2123 /*
2144 2124 * if the RPC call times out, null out all return arguments, set
2145 2125 * minor_status to its maximum value, and return GSS_S_FAILURE
2146 2126 */
2147 2127
2148 2128 if (minor_status != NULL)
2149 2129 *minor_status = DEFAULT_MINOR_STAT;
2150 2130 if (mech_set != NULL)
2151 2131 *mech_set = NULL;
2152 2132
2153 2133 killgssd_handle(clnt);
2154 2134 GSSLOG0(1, "kgss_indicate_mechs: RPC call times out\n");
2155 2135 return (GSS_S_FAILURE);
2156 2136 }
2157 2137
2158 2138 /* copy the rpc results into the return arguments */
2159 2139
2160 2140 if (minor_status != NULL)
2161 2141 *minor_status = res.minor_status;
2162 2142
2163 2143 if (mech_set != NULL) {
2164 2144 *mech_set = (gss_OID_set) MALLOC(sizeof (gss_OID_set_desc));
2165 2145 (*mech_set)->count = res.mech_set.GSS_OID_SET_len;
2166 2146 (*mech_set)->elements = (void *)
2167 2147 MALLOC ((*mech_set)->count * sizeof (gss_OID_desc));
2168 2148 for (i = 0; i < (*mech_set)->count; i++) {
2169 2149 (*mech_set)->elements[i].length =
2170 2150 res.mech_set.GSS_OID_SET_val[i].GSS_OID_len;
2171 2151 (*mech_set)->elements[i].elements = (void *)
2172 2152 MALLOC ((*mech_set)->elements[i].length);
2173 2153 (void) memcpy((*mech_set)->elements[i].elements,
2174 2154 res.mech_set.GSS_OID_SET_val[i].GSS_OID_val,
2175 2155 (*mech_set)->elements[i].length);
2176 2156 }
2177 2157 }
2178 2158
2179 2159 /*
2180 2160 * free the memory allocated for the results and return with the status
2181 2161 * received in the rpc call
2182 2162 */
2183 2163
2184 2164 clnt_freeres(clnt, xdr_gss_indicate_mechs_res, (caddr_t)&res);
2185 2165 killgssd_handle(clnt);
2186 2166 return (res.status);
2187 2167 }
2188 2168
2189 2169
2190 2170 OM_uint32
2191 2171 kgss_inquire_cred_wrapped(minor_status,
2192 2172 cred_handle,
2193 2173 gssd_cred_verifier,
2194 2174 name,
2195 2175 lifetime,
2196 2176 cred_usage,
2197 2177 mechanisms,
2198 2178 uid)
2199 2179 OM_uint32 *minor_status;
2200 2180 const gssd_cred_id_t cred_handle;
2201 2181 OM_uint32 gssd_cred_verifier;
2202 2182 gss_name_t *name;
2203 2183 OM_uint32 *lifetime;
2204 2184 int *cred_usage;
2205 2185 gss_OID_set *mechanisms;
2206 2186 uid_t uid;
2207 2187 {
2208 2188 CLIENT *clnt;
2209 2189
2210 2190 OM_uint32 minor_status_temp;
2211 2191 gss_buffer_desc external_name;
2212 2192 gss_OID_desc name_type;
2213 2193 int i;
2214 2194
2215 2195 gss_inquire_cred_arg arg;
2216 2196 gss_inquire_cred_res res;
2217 2197
2218 2198 /*
2219 2199 * NULL the params here once
2220 2200 * If there are errors then we won't
2221 2201 * have to do it for every error
2222 2202 * case
2223 2203 */
2224 2204 if (minor_status != NULL)
2225 2205 *minor_status = DEFAULT_MINOR_STAT;
2226 2206 if (name != NULL)
2227 2207 *name = NULL;
2228 2208 if (lifetime != NULL)
2229 2209 *lifetime = 0;
2230 2210 if (cred_usage != NULL)
2231 2211 *cred_usage = 0;
2232 2212 if (mechanisms != NULL)
2233 2213 *mechanisms = NULL;
2234 2214
2235 2215 /* get the client handle to GSSD */
2236 2216
2237 2217 if ((clnt = getgssd_handle()) == NULL) {
2238 2218 GSSLOG(1, "kgss_inquire_cred: can't connect to server on %s\n",
2239 2219 server);
2240 2220 return (GSS_S_FAILURE);
2241 2221 }
2242 2222
2243 2223
2244 2224 /* copy the procedure arguments into the rpc arg parameter */
2245 2225
2246 2226 arg.uid = (OM_uint32) uid;
2247 2227
2248 2228 arg.cred_handle.GSS_CRED_ID_T_len =
2249 2229 cred_handle == GSSD_NO_CREDENTIAL ?
2250 2230 0 : (uint_t)sizeof (gssd_cred_id_t);
2251 2231 arg.cred_handle.GSS_CRED_ID_T_val = (char *)&cred_handle;
2252 2232 arg.gssd_cred_verifier = gssd_cred_verifier;
2253 2233
2254 2234 /* call the remote procedure */
2255 2235
2256 2236 bzero((caddr_t)&res, sizeof (res));
2257 2237 if (gss_inquire_cred_1(&arg, &res, clnt) != RPC_SUCCESS) {
2258 2238
2259 2239 /*
2260 2240 * if the RPC call times out
2261 2241 * kill the handle and return GSS_S_FAILURE
2262 2242 * the parameters have been set to NULL already
2263 2243 */
2264 2244
2265 2245 killgssd_handle(clnt);
2266 2246 GSSLOG0(1, "kgss_inquire_cred: RPC call times out\n");
2267 2247 return (GSS_S_FAILURE);
2268 2248 }
2269 2249
2270 2250 /* copy the rpc results into the return arguments */
2271 2251
2272 2252 if (minor_status != NULL)
2273 2253 *minor_status = res.minor_status;
2274 2254
2275 2255 /* convert name from external to internal format */
2276 2256
2277 2257 if (name != NULL) {
2278 2258 external_name.length = res.name.GSS_BUFFER_T_len;
2279 2259 external_name.value = res.name.GSS_BUFFER_T_val;
2280 2260
2281 2261 /*
2282 2262 * we can pass a pointer to res structure
2283 2263 * since gss_import_name treats the name_type
2284 2264 * parameter as read only and performs a copy
2285 2265 */
2286 2266
2287 2267 name_type.length = res.name_type.GSS_OID_len;
2288 2268 name_type.elements = (void *)res.name_type.GSS_OID_val;
2289 2269
2290 2270 if (gss_import_name(&minor_status_temp, &external_name,
2291 2271 &name_type, name) != GSS_S_COMPLETE) {
2292 2272
2293 2273 *minor_status = (OM_uint32) minor_status_temp;
2294 2274 clnt_freeres(clnt, xdr_gss_inquire_cred_res,
2295 2275 (caddr_t)&res);
2296 2276 killgssd_handle(clnt);
2297 2277 GSSLOG0(1, "kgss_inquire_cred: import name fails\n");
2298 2278 return ((OM_uint32) GSS_S_FAILURE);
2299 2279 }
2300 2280 }
2301 2281
2302 2282 if (lifetime != NULL)
2303 2283 *lifetime = res.lifetime;
2304 2284
2305 2285 if (cred_usage != NULL)
2306 2286 *cred_usage = res.cred_usage;
2307 2287
2308 2288 if (res.status == GSS_S_COMPLETE &&
2309 2289 res.mechanisms.GSS_OID_SET_len != 0 &&
2310 2290 mechanisms != NULL) {
2311 2291 *mechanisms = (gss_OID_set) MALLOC(sizeof (gss_OID_set_desc));
2312 2292 (*mechanisms)->count =
2313 2293 (int)res.mechanisms.GSS_OID_SET_len;
2314 2294 (*mechanisms)->elements = (gss_OID)
2315 2295 MALLOC(sizeof (gss_OID_desc) * (*mechanisms)->count);
2316 2296
2317 2297 for (i = 0; i < (*mechanisms)->count; i++) {
2318 2298 (*mechanisms)->elements[i].length = (OM_uint32)
2319 2299 res.mechanisms.GSS_OID_SET_val[i].GSS_OID_len;
2320 2300 (*mechanisms)->elements[i].elements =
2321 2301 (void *) MALLOC((*mechanisms)->elements[i].length);
2322 2302 (void) memcpy((*mechanisms)->elements[i].elements,
2323 2303 res.mechanisms.GSS_OID_SET_val[i].GSS_OID_val,
2324 2304 (*mechanisms)->elements[i].length);
2325 2305 }
2326 2306 } else {
2327 2307 if (res.status == GSS_S_COMPLETE &&
2328 2308 mechanisms != NULL)
2329 2309 (*mechanisms) = NULL;
2330 2310 }
2331 2311 /*
2332 2312 * free the memory allocated for the results and return with the status
2333 2313 * received in the rpc call
2334 2314 */
2335 2315
2336 2316 clnt_freeres(clnt, xdr_gss_inquire_cred_res, (caddr_t)&res);
2337 2317 killgssd_handle(clnt);
2338 2318 return (res.status);
2339 2319
2340 2320 }
2341 2321
2342 2322 OM_uint32
2343 2323 kgss_inquire_cred(minor_status,
2344 2324 cred_handle,
2345 2325 name,
2346 2326 lifetime,
2347 2327 cred_usage,
2348 2328 mechanisms,
2349 2329 uid)
2350 2330 OM_uint32 *minor_status;
2351 2331 const gss_cred_id_t cred_handle;
2352 2332 gss_name_t *name;
2353 2333 OM_uint32 *lifetime;
2354 2334 int *cred_usage;
2355 2335 gss_OID_set * mechanisms;
2356 2336 uid_t uid;
2357 2337 {
2358 2338
2359 2339 OM_uint32 gssd_cred_verifier;
2360 2340 OM_uint32 gssd_cred_handle;
2361 2341
2362 2342 gssd_cred_verifier = KCRED_TO_CREDV(cred_handle);
2363 2343 gssd_cred_handle = KCRED_TO_CRED(cred_handle);
2364 2344
2365 2345 return (kgss_inquire_cred_wrapped(minor_status,
2366 2346 gssd_cred_handle, gssd_cred_verifier,
2367 2347 name, lifetime, cred_usage, mechanisms, uid));
2368 2348 }
2369 2349
2370 2350 OM_uint32
2371 2351 kgss_inquire_cred_by_mech_wrapped(minor_status,
2372 2352 cred_handle,
2373 2353 gssd_cred_verifier,
2374 2354 mech_type,
2375 2355 uid)
2376 2356 OM_uint32 *minor_status;
2377 2357 gssd_cred_id_t cred_handle;
2378 2358 OM_uint32 gssd_cred_verifier;
2379 2359 gss_OID mech_type;
2380 2360 uid_t uid;
2381 2361 {
2382 2362 CLIENT *clnt;
2383 2363
2384 2364 gss_inquire_cred_by_mech_arg arg;
2385 2365 gss_inquire_cred_by_mech_res res;
2386 2366
2387 2367 /* get the client handle to GSSD */
2388 2368
2389 2369 if ((clnt = getgssd_handle()) == NULL) {
2390 2370 GSSLOG(1, "kgss_inquire_cred: can't connect to server on %s\n",
2391 2371 server);
2392 2372 return (GSS_S_FAILURE);
2393 2373 }
2394 2374
2395 2375
2396 2376 /* copy the procedure arguments into the rpc arg parameter */
2397 2377
2398 2378 arg.uid = (OM_uint32) uid;
2399 2379
2400 2380 arg.cred_handle.GSS_CRED_ID_T_len =
2401 2381 cred_handle == GSSD_NO_CREDENTIAL ?
2402 2382 0 : (uint_t)sizeof (gssd_cred_id_t);
2403 2383 arg.cred_handle.GSS_CRED_ID_T_val = (char *)&cred_handle;
2404 2384 arg.gssd_cred_verifier = gssd_cred_verifier;
2405 2385
2406 2386 arg.mech_type.GSS_OID_len =
2407 2387 (uint_t)(mech_type != GSS_C_NULL_OID ?
2408 2388 mech_type->length : 0);
2409 2389 arg.mech_type.GSS_OID_val =
2410 2390 (char *)(mech_type != GSS_C_NULL_OID ?
2411 2391 mech_type->elements : 0);
2412 2392 /* call the remote procedure */
2413 2393
2414 2394 bzero((caddr_t)&res, sizeof (res));
2415 2395 if (gss_inquire_cred_by_mech_1(&arg, &res, clnt) != RPC_SUCCESS) {
2416 2396
2417 2397 /*
2418 2398 * if the RPC call times out, null out all return arguments, set
2419 2399 * minor_status to its maximum value, and return GSS_S_FAILURE
2420 2400 */
2421 2401
2422 2402 if (minor_status != NULL)
2423 2403 *minor_status = DEFAULT_MINOR_STAT;
2424 2404 killgssd_handle(clnt);
2425 2405 GSSLOG0(1, "kgss_inquire_cred: RPC call times out\n");
2426 2406 return (GSS_S_FAILURE);
2427 2407 }
2428 2408
2429 2409 /* copy the rpc results into the return arguments */
2430 2410
2431 2411 if (minor_status != NULL)
2432 2412 *minor_status = res.minor_status;
2433 2413
2434 2414 clnt_freeres(clnt, xdr_gss_inquire_cred_by_mech_res, (caddr_t)&res);
2435 2415 killgssd_handle(clnt);
2436 2416 return (res.status);
2437 2417
2438 2418 }
2439 2419
2440 2420 OM_uint32
2441 2421 kgss_inquire_cred_by_mech(minor_status,
2442 2422 cred_handle,
2443 2423 mech_type,
2444 2424 uid)
2445 2425 OM_uint32 *minor_status;
2446 2426 gss_cred_id_t cred_handle;
2447 2427 gss_OID mech_type;
2448 2428 uid_t uid;
2449 2429 {
2450 2430
2451 2431 OM_uint32 gssd_cred_verifier;
2452 2432 OM_uint32 gssd_cred_handle;
2453 2433
2454 2434 gssd_cred_verifier = KCRED_TO_CREDV(cred_handle);
2455 2435 gssd_cred_handle = KCRED_TO_CRED(cred_handle);
2456 2436
2457 2437 return (kgss_inquire_cred_by_mech_wrapped(minor_status,
2458 2438 gssd_cred_handle, gssd_cred_verifier,
2459 2439 mech_type, uid));
2460 2440 }
2461 2441
2462 2442 OM_uint32
2463 2443 kgsscred_expname_to_unix_cred(expName, uidOut, gidOut, gids, gidsLen, uid)
2464 2444 const gss_buffer_t expName;
2465 2445 uid_t *uidOut;
2466 2446 gid_t *gidOut;
2467 2447 gid_t *gids[];
2468 2448 int *gidsLen;
2469 2449 uid_t uid;
2470 2450 {
2471 2451 CLIENT *clnt;
2472 2452 gsscred_expname_to_unix_cred_arg args;
2473 2453 gsscred_expname_to_unix_cred_res res;
2474 2454
2475 2455 /* check input/output parameters */
2476 2456 if (expName == NULL || expName->value == NULL)
2477 2457 return (GSS_S_CALL_INACCESSIBLE_READ);
2478 2458
2479 2459 if (uidOut == NULL)
2480 2460 return (GSS_S_CALL_INACCESSIBLE_WRITE);
2481 2461
2482 2462 /* NULL out output parameters */
2483 2463 *uidOut = UID_NOBODY;
2484 2464 if (gidsLen)
2485 2465 *gidsLen = 0;
2486 2466
2487 2467 if (gids)
2488 2468 *gids = NULL;
2489 2469
2490 2470 /* get the client handle to gssd */
2491 2471 if ((clnt = getgssd_handle()) == NULL)
2492 2472 {
2493 2473 GSSLOG(1, "kgsscred_expname_to_unix_cred:"
2494 2474 " can't connect to server on %s\n", server);
2495 2475 return (GSS_S_FAILURE);
2496 2476 }
2497 2477
2498 2478 /* copy the procedure arguments */
2499 2479 args.uid = uid;
2500 2480 args.expname.GSS_BUFFER_T_val = expName->value;
2501 2481 args.expname.GSS_BUFFER_T_len = expName->length;
2502 2482
2503 2483 /* null out the return buffer and call the remote proc */
2504 2484 bzero(&res, sizeof (res));
2505 2485
2506 2486 if (gsscred_expname_to_unix_cred_1(&args, &res, clnt) != RPC_SUCCESS)
2507 2487 {
2508 2488 killgssd_handle(clnt);
2509 2489 GSSLOG0(1,
2510 2490 "kgsscred_expname_to_unix_cred: RPC call times out\n");
2511 2491 return (GSS_S_FAILURE);
2512 2492 }
2513 2493
2514 2494 /* copy the results into the result parameters */
2515 2495 if (res.major == GSS_S_COMPLETE)
2516 2496 {
2517 2497 *uidOut = res.uid;
2518 2498 if (gidOut)
2519 2499 *gidOut = res.gid;
2520 2500 if (gids && gidsLen)
2521 2501 {
2522 2502 *gids = res.gids.GSSCRED_GIDS_val;
2523 2503 *gidsLen = res.gids.GSSCRED_GIDS_len;
2524 2504 res.gids.GSSCRED_GIDS_val = NULL;
2525 2505 res.gids.GSSCRED_GIDS_len = 0;
2526 2506 }
2527 2507 }
2528 2508
2529 2509 /* free RPC results */
2530 2510 clnt_freeres(clnt, xdr_gsscred_expname_to_unix_cred_res, (caddr_t)&res);
2531 2511 killgssd_handle(clnt);
2532 2512
2533 2513 return (res.major);
2534 2514 } /* kgsscred_expname_to_unix_cred */
2535 2515
2536 2516 OM_uint32
2537 2517 kgsscred_name_to_unix_cred(intName, mechType, uidOut, gidOut, gids,
2538 2518 gidsLen, uid)
2539 2519 const gss_name_t intName;
2540 2520 const gss_OID mechType;
2541 2521 uid_t *uidOut;
2542 2522 gid_t *gidOut;
2543 2523 gid_t *gids[];
2544 2524 int *gidsLen;
2545 2525 uid_t uid;
2546 2526 {
2547 2527 CLIENT *clnt;
2548 2528 gsscred_name_to_unix_cred_arg args;
2549 2529 gsscred_name_to_unix_cred_res res;
2550 2530 OM_uint32 major, minor;
2551 2531 gss_OID nameOid;
2552 2532 gss_buffer_desc flatName = GSS_C_EMPTY_BUFFER;
2553 2533
2554 2534 /* check the input/output parameters */
2555 2535 if (intName == NULL || mechType == NULL)
2556 2536 return (GSS_S_CALL_INACCESSIBLE_READ);
2557 2537
2558 2538 if (uidOut == NULL)
2559 2539 return (GSS_S_CALL_INACCESSIBLE_WRITE);
2560 2540
2561 2541 /* NULL out the output parameters */
2562 2542 *uidOut = UID_NOBODY;
2563 2543 if (gids)
2564 2544 *gids = NULL;
2565 2545
2566 2546 if (gidsLen)
2567 2547 *gidsLen = 0;
2568 2548
2569 2549 /* get the client handle to gssd */
2570 2550 if ((clnt = getgssd_handle()) == NULL)
2571 2551 {
2572 2552 GSSLOG(1,
2573 2553 "kgsscred_name_to_unix_cred: can't connect to server %s\n",
2574 2554 server);
2575 2555 return (GSS_S_FAILURE);
2576 2556 }
2577 2557
2578 2558 /* convert the name to flat representation */
2579 2559 if ((major = gss_display_name(&minor, intName, &flatName, &nameOid))
2580 2560 != GSS_S_COMPLETE)
2581 2561 {
2582 2562 killgssd_handle(clnt);
2583 2563 GSSLOG0(1, "kgsscred_name_to_unix_cred: display name failed\n");
2584 2564 return (major);
2585 2565 }
2586 2566
2587 2567 /* set the rpc parameters */
2588 2568 args.uid = uid;
2589 2569 args.pname.GSS_BUFFER_T_len = flatName.length;
2590 2570 args.pname.GSS_BUFFER_T_val = flatName.value;
2591 2571 args.name_type.GSS_OID_len = nameOid->length;
2592 2572 args.name_type.GSS_OID_val = nameOid->elements;
2593 2573 args.mech_type.GSS_OID_len = mechType->length;
2594 2574 args.mech_type.GSS_OID_val = mechType->elements;
2595 2575
2596 2576 /* call the remote procedure */
2597 2577 bzero(&res, sizeof (res));
2598 2578 if (gsscred_name_to_unix_cred_1(&args, &res, clnt) != RPC_SUCCESS) {
2599 2579 killgssd_handle(clnt);
2600 2580 (void) gss_release_buffer(&minor, &flatName);
2601 2581 GSSLOG0(1, "kgsscred_name_to_unix_cred: RPC call times out\n");
2602 2582 return (GSS_S_FAILURE);
2603 2583 }
2604 2584
2605 2585 /* delete the flat name buffer */
2606 2586 (void) gss_release_buffer(&minor, &flatName);
2607 2587
2608 2588 /* copy the output parameters on output */
2609 2589 if (res.major == GSS_S_COMPLETE) {
2610 2590 *uidOut = res.uid;
2611 2591
2612 2592 if (gidOut)
2613 2593 *gidOut = res.gid;
2614 2594 if (gids && gidsLen) {
2615 2595 *gids = res.gids.GSSCRED_GIDS_val;
2616 2596 *gidsLen = res.gids.GSSCRED_GIDS_len;
2617 2597 res.gids.GSSCRED_GIDS_val = NULL;
2618 2598 res.gids.GSSCRED_GIDS_len = 0;
2619 2599 }
2620 2600 }
2621 2601
2622 2602 /* delete RPC allocated memory */
2623 2603 clnt_freeres(clnt, xdr_gsscred_name_to_unix_cred_res, (caddr_t)&res);
2624 2604 killgssd_handle(clnt);
2625 2605
2626 2606 return (res.major);
2627 2607 } /* kgsscred_name_to_unix_cred */
2628 2608
2629 2609 OM_uint32
2630 2610 kgss_get_group_info(puid, gidOut, gids, gidsLen, uid)
2631 2611 const uid_t puid;
2632 2612 gid_t *gidOut;
2633 2613 gid_t *gids[];
2634 2614 int *gidsLen;
2635 2615 uid_t uid;
2636 2616 {
2637 2617 CLIENT *clnt;
2638 2618 gss_get_group_info_arg args;
2639 2619 gss_get_group_info_res res;
2640 2620
2641 2621
2642 2622 /* check the output parameters */
2643 2623 if (gidOut == NULL || gids == NULL || gidsLen == NULL)
2644 2624 return (GSS_S_CALL_INACCESSIBLE_WRITE);
2645 2625
2646 2626 /* get the client GSSD handle */
2647 2627 if ((clnt = getgssd_handle()) == NULL) {
2648 2628 GSSLOG(1,
2649 2629 "kgss_get_group_info: can't connect to server on %s\n",
2650 2630 server);
2651 2631 return (GSS_S_FAILURE);
2652 2632 }
2653 2633
2654 2634 /* set the input parameters */
2655 2635 args.uid = uid;
2656 2636 args.puid = puid;
2657 2637
2658 2638 /* call the remote procedure */
2659 2639 bzero(&res, sizeof (res));
2660 2640 if (gss_get_group_info_1(&args, &res, clnt) != RPC_SUCCESS) {
2661 2641 killgssd_handle(clnt);
2662 2642 GSSLOG0(1, "kgss_get_group_info: RPC call times out\n");
2663 2643 return (GSS_S_FAILURE);
2664 2644 }
2665 2645
2666 2646 /* copy the results */
2667 2647 if (res.major == GSS_S_COMPLETE) {
2668 2648 *gidOut = res.gid;
2669 2649 *gids = res.gids.GSSCRED_GIDS_val;
2670 2650 *gidsLen = res.gids.GSSCRED_GIDS_len;
2671 2651 res.gids.GSSCRED_GIDS_val = NULL;
2672 2652 res.gids.GSSCRED_GIDS_len = 0;
2673 2653 }
2674 2654
2675 2655 /* no results to free */
2676 2656 killgssd_handle(clnt);
2677 2657
2678 2658 return (res.major);
2679 2659 } /* kgss_get_group_info */
2680 2660
2681 2661 static char *
2682 2662 kgss_get_kmod(gss_OID mech_oid)
2683 2663 {
2684 2664 CLIENT *clnt;
2685 2665 gss_get_kmod_arg args;
2686 2666 gss_get_kmod_res res;
2687 2667
2688 2668
2689 2669 /* get the client GSSD handle */
2690 2670 if ((clnt = getgssd_handle()) == NULL) {
2691 2671 GSSLOG(1, "kgss_get_kmod: can't connect to server on %s\n",
2692 2672 server);
2693 2673 return (NULL);
2694 2674 }
2695 2675
2696 2676 /* set the input parameters */
2697 2677 args.mech_oid.GSS_OID_len = mech_oid->length;
2698 2678 args.mech_oid.GSS_OID_val = mech_oid->elements;
2699 2679
2700 2680 /* call the remote procedure */
2701 2681 bzero(&res, sizeof (res));
2702 2682 if (gss_get_kmod_1(&args, &res, clnt) != RPC_SUCCESS) {
2703 2683 killgssd_handle(clnt);
2704 2684 GSSLOG0(1, "gss_get_kmod_1: RPC call times out\n");
2705 2685 return (NULL);
2706 2686 }
2707 2687 /* no results to free */
2708 2688 killgssd_handle(clnt);
2709 2689
2710 2690 if (res.module_follow == TRUE) {
2711 2691 return (res.gss_get_kmod_res_u.modname);
2712 2692 } else
2713 2693 return (NULL);
2714 2694 } /* kgss_get_kmod */
2715 2695
2716 2696 static gss_mechanism kgss_mech_head;
2717 2697 static gss_mechanism kgss_mech_tail;
2718 2698 kmutex_t __kgss_mech_lock;
2719 2699
2720 2700 /*
2721 2701 * See if there is kernel mechanism module, and if so, attempt to
2722 2702 * load it and reset the pointer (gss_mechanism) to the sign/seal/etc.
2723 2703 * entry points to that of the kernel module.
2724 2704 */
2725 2705 static void
2726 2706 __kgss_reset_mech(gss_mechanism *mechp, gss_OID mech_oid)
2727 2707 {
2728 2708 gss_mechanism mech;
2729 2709 char *kmod;
2730 2710
2731 2711 /*
2732 2712 * We can search the list without a mutex, becuase the list never
2733 2713 * shrinks and we always add to the end.
2734 2714 */
2735 2715 mech = __kgss_get_mechanism(mech_oid);
2736 2716 if (mech) {
2737 2717 *mechp = mech;
2738 2718 return;
2739 2719 }
2740 2720
2741 2721 /*
2742 2722 * Get the module name from the kernel.
2743 2723 */
2744 2724 kmod = kgss_get_kmod(mech_oid);
2745 2725
2746 2726 if (kmod) {
2747 2727 extern int modload(const char *, const char *);
2748 2728 if (modload("misc/kgss", kmod) < 0) {
2749 2729 /*
2750 2730 * Modload of 'kmod' failed, so log an
2751 2731 * appropriate comment
2752 2732 */
2753 2733 cmn_err(CE_NOTE, "kgss_reset_mech: Algorithm modload "
2754 2734 "(%s) failed. Userland gssd will now handle "
2755 2735 "all GSSAPI calls, which may result in "
2756 2736 "reduced performance.\n", kmod);
2757 2737 };
2758 2738
2759 2739 /*
2760 2740 * Allocated in the XDR routine called by gss_get_kmod_1().
2761 2741 */
2762 2742 FREE(kmod, strlen(kmod)+1);
2763 2743
2764 2744 mech = __kgss_get_mechanism(mech_oid);
2765 2745 if (mech) {
2766 2746 *mechp = mech;
2767 2747 }
2768 2748
2769 2749 /*
2770 2750 * If for some reason the module load didn't take,
2771 2751 * we return anyway and hope that the next context
2772 2752 * creation succeeds.
2773 2753 */
2774 2754 return;
2775 2755 }
2776 2756
2777 2757
2778 2758 /*
2779 2759 * No kernel module, so enter this mech oid into the list
2780 2760 * using the default sign/seal/etc. operations that upcall to
2781 2761 * gssd.
2782 2762 */
2783 2763 mutex_enter(&__kgss_mech_lock);
2784 2764 mech = __kgss_get_mechanism(mech_oid);
2785 2765 if (mech) {
2786 2766 mutex_exit(&__kgss_mech_lock);
2787 2767 *mechp = mech;
2788 2768 return;
2789 2769 }
2790 2770
2791 2771 /*
2792 2772 * Allocate space for the mechanism entry.
2793 2773 */
2794 2774 mech = kmem_zalloc(sizeof (struct gss_config), KM_SLEEP);
2795 2775
2796 2776 /*
2797 2777 * Copy basic information from default mechanism struct.
2798 2778 */
2799 2779 *mech = default_gc;
2800 2780
2801 2781 /*
2802 2782 * Record the real mech OID.
2803 2783 */
2804 2784 mech->mech_type.length = mech_oid->length;
2805 2785 mech->mech_type.elements = MALLOC(mech_oid->length);
2806 2786 bcopy(mech_oid->elements, mech->mech_type.elements, mech_oid->length);
2807 2787
2808 2788 /*
2809 2789 * Add it to the table.
2810 2790 */
2811 2791 __kgss_add_mechanism(mech);
2812 2792 mutex_exit(&__kgss_mech_lock);
2813 2793 *mechp = mech;
2814 2794 }
2815 2795
2816 2796 /*
2817 2797 * Called with __kgss_mech_lock held.
2818 2798 */
2819 2799 void
2820 2800 __kgss_add_mechanism(gss_mechanism mech)
2821 2801 {
2822 2802 gss_mechanism tmp;
2823 2803
2824 2804 tmp = kgss_mech_tail;
2825 2805 kgss_mech_tail = mech;
2826 2806
2827 2807 if (tmp != NULL)
2828 2808 tmp->next = mech;
2829 2809
2830 2810 if (kgss_mech_head == NULL)
2831 2811 kgss_mech_head = mech;
2832 2812 }
2833 2813
2834 2814 /*
2835 2815 * given the mechs_array and a mechanism OID, return the
2836 2816 * pointer to the mechanism, or NULL if that mechanism is
2837 2817 * not supported.
2838 2818 */
2839 2819 gss_mechanism
2840 2820 __kgss_get_mechanism(gss_OID type)
2841 2821 {
2842 2822 gss_mechanism mech;
2843 2823
2844 2824 mech = kgss_mech_head;
2845 2825
2846 2826 /*
2847 2827 * Note that a reader can scan this list without the mutex held.
2848 2828 * This is safe because we always append, and never shrink the list.
2849 2829 * Moreover, the entry is fully initialized before it is ever
2850 2830 * added to the list.
2851 2831 */
2852 2832 while (mech != NULL) {
2853 2833 if ((mech->mech_type.length == type->length) &&
2854 2834 (bcmp(mech->mech_type.elements, type->elements,
2855 2835 type->length) == 0))
2856 2836 return (mech);
2857 2837
2858 2838 mech = mech->next;
2859 2839 }
2860 2840 return (NULL);
2861 2841 }
↓ open down ↓ |
826 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX