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