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