4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 * GSSAPI library stub module for gssd.
32 #include <mechglueP.h>
37 #define MALLOC(n) kmem_alloc((n), KM_SLEEP)
38 #define FREE(x, n) kmem_free((x), (n))
39 #define memcpy(dst, src, n) bcopy((src), (dst), (n))
40 #define clnt_pcreateerror(srv) printf("Cannot connect to server on %s\n", srv)
43 #ifndef _SYS_CMN_ERR_H
44 #define _SYS_CMN_ERR_H
47 #include <sys/types.h>
48 #include <sys/devops.h>
53 #include <sys/sunddi.h>
58 #define MALLOC(n) malloc(n)
59 #define FREE(x, n) free(x)
61 #define DEFAULT_MINOR_STAT ((OM_uint32) ~0)
63 CLIENT
*clnt
, *getgssd_handle();
64 char *server
= "localhost";
67 kgss_acquire_cred_wrapped(minor_status
,
77 OM_uint32
*minor_status
;
78 gss_name_t desired_name
;
80 gss_OID_set desired_mechs
;
82 gssd_cred_id_t
*output_cred_handle
;
83 gss_OID_set
*actual_mechs
;
86 OM_uint32
*gssd_cred_verifier
;
88 OM_uint32 minor_status_temp
;
89 gss_buffer_desc external_name
;
93 gss_acquire_cred_arg arg
;
94 gss_acquire_cred_res res
;
96 /* get the client handle to GSSD */
98 if ((clnt
= getgssd_handle()) == NULL
) {
99 clnt_pcreateerror(server
);
100 return (GSS_S_FAILURE
);
103 /* convert the desired name from internal to external format */
105 if (gss_display_name(&minor_status_temp
, desired_name
, &external_name
,
106 &name_type
) != GSS_S_COMPLETE
) {
108 *minor_status
= (OM_uint32
) minor_status_temp
;
109 gss_release_buffer(&minor_status_temp
, &external_name
);
110 return ((OM_uint32
) GSS_S_FAILURE
);
114 /* copy the procedure arguments into the rpc arg parameter */
116 arg
.uid
= (OM_uint32
)uid
;
118 arg
.desired_name
.GSS_BUFFER_T_len
= (uint_t
)external_name
.length
;
119 arg
.desired_name
.GSS_BUFFER_T_val
= (char *)external_name
.value
;
121 arg
.name_type
.GSS_OID_len
=
122 name_type
== GSS_C_NULL_OID
?
123 0 : (uint_t
)name_type
->length
;
125 arg
.name_type
.GSS_OID_val
=
126 name_type
== GSS_C_NULL_OID
?
127 (char *)NULL
: (char *)name_type
->elements
;
129 arg
.time_req
= time_req
;
131 if (desired_mechs
!= GSS_C_NULL_OID_SET
) {
132 arg
.desired_mechs
.GSS_OID_SET_len
=
133 (uint_t
)desired_mechs
->count
;
134 arg
.desired_mechs
.GSS_OID_SET_val
= (GSS_OID
*)
135 MALLOC(sizeof (GSS_OID
) * desired_mechs
->count
);
137 for (i
= 0; i
< desired_mechs
->count
; i
++) {
138 arg
.desired_mechs
.GSS_OID_SET_val
[i
].GSS_OID_len
=
139 (uint_t
)desired_mechs
->elements
[i
].length
;
140 arg
.desired_mechs
.GSS_OID_SET_val
[i
].GSS_OID_val
=
142 MALLOC(desired_mechs
->elements
[i
].length
);
143 memcpy(arg
.desired_mechs
.GSS_OID_SET_val
[i
].GSS_OID_val
,
144 desired_mechs
->elements
[i
].elements
,
145 desired_mechs
->elements
[i
].length
);
148 arg
.desired_mechs
.GSS_OID_SET_len
= 0;
150 arg
.cred_usage
= cred_usage
;
152 /* call the remote procedure */
154 memset(&res
, 0, sizeof (res
));
155 if (gss_acquire_cred_1(&arg
, &res
, clnt
) != RPC_SUCCESS
) {
158 * if the RPC call times out, null out all return arguments,
159 * set minor_status to its maximum value, and return GSS_S_FAILURE
162 if (minor_status
!= NULL
)
163 *minor_status
= DEFAULT_MINOR_STAT
;
164 if (output_cred_handle
!= NULL
)
165 *output_cred_handle
= 0;
166 if (actual_mechs
!= NULL
)
167 *actual_mechs
= NULL
;
168 if (time_rec
!= NULL
)
171 return (GSS_S_FAILURE
);
174 /* free the allocated memory for the flattened name and desire_mechs */
176 gss_release_buffer(&minor_status_temp
, &external_name
);
177 for (i
= 0; i
< desired_mechs
->count
; i
++)
178 FREE(arg
.desired_mechs
.GSS_OID_SET_val
[i
].GSS_OID_val
,
179 arg
.desired_mechs
.GSS_OID_SET_val
[i
].GSS_OID_len
);
180 FREE(arg
.desired_mechs
.GSS_OID_SET_val
,
181 arg
.desired_mechs
.GSS_OID_SET_len
* sizeof (GSS_OID
));
183 /* copy the rpc results into the return arguments */
185 if (minor_status
!= NULL
)
186 *minor_status
= res
.minor_status
;
188 if (output_cred_handle
!= NULL
) {
189 *output_cred_handle
=
191 *((gssd_cred_id_t
*)res
.output_cred_handle
.GSS_CRED_ID_T_val
);
192 *gssd_cred_verifier
= res
.gssd_cred_verifier
;
195 if (res
.status
== GSS_S_COMPLETE
&&
196 res
.actual_mechs
.GSS_OID_SET_len
!= 0 &&
197 actual_mechs
!= NULL
) {
198 *actual_mechs
= (gss_OID_set
) MALLOC(sizeof (gss_OID_set_desc
));
199 (*actual_mechs
)->count
=
200 (int)res
.actual_mechs
.GSS_OID_SET_len
;
201 (*actual_mechs
)->elements
= (gss_OID
)
202 MALLOC(sizeof (gss_OID_desc
) * (*actual_mechs
)->count
);
204 for (i
= 0; i
< (*actual_mechs
)->count
; i
++) {
205 (*actual_mechs
)->elements
[i
].length
= (OM_uint32
)
206 res
.actual_mechs
.GSS_OID_SET_val
[i
].GSS_OID_len
;
207 (*actual_mechs
)->elements
[i
].elements
=
208 (void *) MALLOC((*actual_mechs
)->elements
[i
].length
);
209 memcpy((*actual_mechs
)->elements
[i
].elements
,
210 res
.actual_mechs
.GSS_OID_SET_val
[i
].GSS_OID_val
,
211 (*actual_mechs
)->elements
[i
].length
);
214 if (res
.status
== GSS_S_COMPLETE
&& actual_mechs
!= NULL
)
215 (*actual_mechs
)->count
= 0;
218 if (time_rec
!= NULL
)
219 *time_rec
= res
.time_rec
;
222 * free the memory allocated for the results and return with the status
223 * received in the rpc call
226 clnt_freeres(clnt
, xdr_gss_acquire_cred_res
, (caddr_t
)&res
);
231 kgss_acquire_cred(minor_status
,
240 OM_uint32
*minor_status
;
241 gss_name_t desired_name
;
243 gss_OID_set desired_mechs
;
245 gss_cred_id_t
*output_cred_handle
;
246 gss_OID_set
*actual_mechs
;
252 struct kgss_cred
*kcred
;
254 kcred
= KGSS_CRED_ALLOC();
255 *output_cred_handle
= (gss_cred_id_t
)kcred
;
256 err
= kgss_acquire_cred_wrapped(minor_status
,
257 desired_name
, time_req
,
258 desired_mechs
, cred_usage
,
259 &kcred
->gssd_cred
, actual_mechs
,
261 &kcred
->gssd_cred_verifier
);
262 if (GSS_ERROR(err
)) {
263 KGSS_CRED_FREE(kcred
);
264 *output_cred_handle
= GSS_C_NO_CREDENTIAL
;
270 kgss_add_cred_wrapped(minor_status
,
282 OM_uint32
*minor_status
;
283 gssd_cred_id_t input_cred_handle
;
284 OM_uint32 gssd_cred_verifier
;
285 gss_name_t desired_name
;
286 gss_OID desired_mech_type
;
288 int initiator_time_req
;
289 int acceptor_time_req
;
290 gss_OID_set
*actual_mechs
;
291 OM_uint32
*initiator_time_rec
;
292 OM_uint32
*acceptor_time_rec
;
297 OM_uint32 minor_status_temp
;
298 gss_buffer_desc external_name
;
302 gss_add_cred_arg arg
;
303 gss_add_cred_res res
;
305 /* get the client handle to GSSD */
307 if ((clnt
= getgssd_handle()) == NULL
) {
308 clnt_pcreateerror(server
);
309 return (GSS_S_FAILURE
);
313 /* convert the desired name from internal to external format */
315 if (gss_display_name(&minor_status_temp
, desired_name
, &external_name
,
316 &name_type
) != GSS_S_COMPLETE
) {
318 *minor_status
= (OM_uint32
) minor_status_temp
;
319 (void) gss_release_buffer(&minor_status_temp
, &external_name
);
320 clnt_pcreateerror(server
);
321 return ((OM_uint32
) GSS_S_FAILURE
);
325 /* copy the procedure arguments into the rpc arg parameter */
327 arg
.uid
= (OM_uint32
) uid
;
328 arg
.input_cred_handle
.GSS_CRED_ID_T_len
=
329 input_cred_handle
== GSSD_NO_CREDENTIAL
?
330 0 : (uint_t
)sizeof (gssd_cred_id_t
);
331 arg
.input_cred_handle
.GSS_CRED_ID_T_val
=
332 (char *)&input_cred_handle
;
333 arg
.gssd_cred_verifier
= gssd_cred_verifier
;
334 arg
.desired_name
.GSS_BUFFER_T_len
= (uint_t
)external_name
.length
;
335 arg
.desired_name
.GSS_BUFFER_T_val
= (char *)external_name
.value
;
336 arg
.name_type
.GSS_OID_len
=
337 name_type
== GSS_C_NULL_OID
?
338 0 : (uint_t
)name_type
->length
;
339 arg
.name_type
.GSS_OID_val
=
340 name_type
== GSS_C_NULL_OID
?
341 (char *)NULL
: (char *)name_type
->elements
;
343 arg
.desired_mech_type
.GSS_OID_len
=
344 (uint_t
)(desired_mech_type
!= GSS_C_NULL_OID
?
345 desired_mech_type
->length
: 0);
346 arg
.desired_mech_type
.GSS_OID_val
=
347 (char *)(desired_mech_type
!= GSS_C_NULL_OID
?
348 desired_mech_type
->elements
: 0);
349 arg
.cred_usage
= cred_usage
;
350 arg
.initiator_time_req
= initiator_time_req
;
351 arg
.acceptor_time_req
= acceptor_time_req
;
353 /* call the remote procedure */
355 bzero((caddr_t
)&res
, sizeof (res
));
356 if (gss_add_cred_1(&arg
, &res
, clnt
) != RPC_SUCCESS
) {
359 * if the RPC call times out, null out all return arguments,
360 * set minor_status to its maximum value, and return
364 if (minor_status
!= NULL
)
365 *minor_status
= DEFAULT_MINOR_STAT
;
366 if (actual_mechs
!= NULL
)
367 *actual_mechs
= NULL
;
368 if (initiator_time_rec
!= NULL
)
369 *initiator_time_rec
= 0;
370 if (acceptor_time_rec
!= NULL
)
371 *acceptor_time_rec
= 0;
372 return (GSS_S_FAILURE
);
375 /* free the allocated memory for the flattened name */
377 (void) gss_release_buffer(&minor_status_temp
, &external_name
);
379 /* copy the rpc results into the return arguments */
381 if (minor_status
!= NULL
)
382 *minor_status
= res
.minor_status
;
384 if (res
.status
== GSS_S_COMPLETE
&&
385 res
.actual_mechs
.GSS_OID_SET_len
!= 0 &&
386 actual_mechs
!= NULL
) {
387 *actual_mechs
= (gss_OID_set
) MALLOC(sizeof (gss_OID_set_desc
));
388 (*actual_mechs
)->count
=
389 (int)res
.actual_mechs
.GSS_OID_SET_len
;
390 (*actual_mechs
)->elements
= (gss_OID
)
391 MALLOC(sizeof (gss_OID_desc
) * (*actual_mechs
)->count
);
393 for (i
= 0; i
< (*actual_mechs
)->count
; i
++) {
394 (*actual_mechs
)->elements
[i
].length
= (OM_uint32
)
395 res
.actual_mechs
.GSS_OID_SET_val
[i
].GSS_OID_len
;
396 (*actual_mechs
)->elements
[i
].elements
=
397 (void *) MALLOC((*actual_mechs
)->elements
[i
].length
);
398 memcpy((*actual_mechs
)->elements
[i
].elements
,
399 res
.actual_mechs
.GSS_OID_SET_val
[i
].GSS_OID_val
,
400 (*actual_mechs
)->elements
[i
].length
);
403 if (res
.status
== GSS_S_COMPLETE
&&
404 actual_mechs
!= NULL
)
405 (*actual_mechs
)->count
= 0;
407 if (initiator_time_rec
!= NULL
)
408 *initiator_time_rec
= res
.initiator_time_rec
;
409 if (acceptor_time_rec
!= NULL
)
410 *acceptor_time_rec
= res
.acceptor_time_rec
;
413 * free the memory allocated for the results and return with the status
414 * received in the rpc call
417 clnt_freeres(clnt
, xdr_gss_add_cred_res
, (caddr_t
)&res
);
423 kgss_add_cred(minor_status
,
434 OM_uint32
*minor_status
;
435 gss_cred_id_t input_cred_handle
;
436 gss_name_t desired_name
;
437 gss_OID desired_mech_type
;
439 int initiator_time_req
;
440 int acceptor_time_req
;
441 gss_OID_set
*actual_mechs
;
442 OM_uint32
*initiator_time_rec
;
443 OM_uint32
*acceptor_time_rec
;
448 OM_uint32 gssd_cred_verifier
;
449 gssd_cred_id_t gssd_input_cred_handle
;
452 if (input_cred_handle
!= GSS_C_NO_CREDENTIAL
) {
453 gssd_cred_verifier
= KCRED_TO_CREDV(input_cred_handle
);
454 gssd_input_cred_handle
= KCRED_TO_CRED(input_cred_handle
);
456 gssd_input_cred_handle
= GSSD_NO_CREDENTIAL
;
458 err
= kgss_add_cred_wrapped(minor_status
, gssd_input_cred_handle
,
459 gssd_cred_verifier
, desired_name
, desired_mech_type
,
460 cred_usage
, initiator_time_req
, acceptor_time_req
,
461 actual_mechs
, initiator_time_rec
,
462 acceptor_time_rec
, uid
);
467 kgss_release_cred_wrapped(minor_status
,
471 OM_uint32
*minor_status
;
472 gssd_cred_id_t
*cred_handle
;
474 OM_uint32 gssd_cred_verifier
;
477 gss_release_cred_arg arg
;
478 gss_release_cred_res res
;
481 /* get the client handle to GSSD */
482 if ((clnt
= getgssd_handle()) == NULL
) {
483 clnt_pcreateerror(server
);
484 return (GSS_S_FAILURE
);
487 /* copy the procedure arguments into the rpc arg parameter */
489 arg
.uid
= (OM_uint32
) uid
;
490 arg
.gssd_cred_verifier
= gssd_cred_verifier
;
492 if (cred_handle
!= NULL
) {
493 arg
.cred_handle
.GSS_CRED_ID_T_len
=
494 (uint_t
)sizeof (gssd_cred_id_t
);
495 arg
.cred_handle
.GSS_CRED_ID_T_val
= (char *)cred_handle
;
497 arg
.cred_handle
.GSS_CRED_ID_T_len
= 0;
499 /* call the remote procedure */
501 memset(&res
, 0, sizeof (res
));
502 if (gss_release_cred_1(&arg
, &res
, clnt
) != RPC_SUCCESS
) {
505 * if the RPC call times out, null out all return arguments,
506 * set minor_status to its max value, and return GSS_S_FAILURE
509 if (minor_status
!= NULL
)
510 *minor_status
= DEFAULT_MINOR_STAT
;
511 if (cred_handle
!= NULL
)
514 return (GSS_S_FAILURE
);
517 /* if the release succeeded, null out the cred_handle */
518 if (res
.status
== GSS_S_COMPLETE
&& cred_handle
!= NULL
)
521 /* copy the rpc results into the return arguments */
522 if (minor_status
!= NULL
)
523 *minor_status
= res
.minor_status
;
525 /* return with status returned in rpc call */
530 kgss_release_cred(minor_status
,
533 OM_uint32
*minor_status
;
534 gss_cred_id_t
*cred_handle
;
540 struct kgss_cred
*kcred
;
542 if (*cred_handle
== GSS_C_NO_CREDENTIAL
)
543 return (GSS_S_COMPLETE
);
545 kcred
= KCRED_TO_KGSS_CRED(*cred_handle
);
547 err
= kgss_release_cred_wrapped(minor_status
, &kcred
->gssd_cred
,
548 uid
, kcred
->gssd_cred_verifier
);
549 KGSS_CRED_FREE(kcred
);
550 *cred_handle
= GSS_C_NO_CREDENTIAL
;
555 kgss_init_sec_context_wrapped(minor_status
,
556 claimant_cred_handle
,
559 gssd_context_verifier
,
571 OM_uint32
*minor_status
;
572 gssd_cred_id_t claimant_cred_handle
;
573 OM_uint32 gssd_cred_verifier
;
574 OM_uint32
*context_handle
;
575 OM_uint32
*gssd_context_verifier
;
576 gss_name_t target_name
;
580 gss_channel_bindings_t input_chan_bindings
;
581 gss_buffer_t input_token
;
582 gss_OID
*actual_mech_type
;
583 gss_buffer_t output_token
;
588 OM_uint32 minor_status_temp
;
589 gss_buffer_desc external_name
;
591 gss_init_sec_context_arg arg
;
592 gss_init_sec_context_res res
;
594 /* get the client handle to GSSD */
596 if ((clnt
= getgssd_handle()) == NULL
) {
597 clnt_pcreateerror(server
);
598 return (GSS_S_FAILURE
);
601 /* convert the target name from internal to external format */
603 if (gss_display_name(&minor_status_temp
, target_name
,
604 &external_name
, &name_type
) != GSS_S_COMPLETE
) {
606 *minor_status
= (OM_uint32
) minor_status_temp
;
607 return ((OM_uint32
) GSS_S_FAILURE
);
611 /* copy the procedure arguments into the rpc arg parameter */
613 arg
.uid
= (OM_uint32
) uid
;
615 arg
.context_handle
.GSS_CTX_ID_T_len
=
616 *context_handle
== (OM_uint32
) GSS_C_NO_CONTEXT
? 0 :
617 (uint_t
)sizeof (OM_uint32
);
618 arg
.context_handle
.GSS_CTX_ID_T_val
= (char *)context_handle
;
619 arg
.gssd_context_verifier
= *gssd_context_verifier
;
621 arg
.claimant_cred_handle
.GSS_CRED_ID_T_len
=
622 claimant_cred_handle
== GSSD_NO_CREDENTIAL
?
623 0 : (uint_t
)sizeof (gssd_cred_id_t
);
624 arg
.claimant_cred_handle
.GSS_CRED_ID_T_val
=
625 (char *)&claimant_cred_handle
;
626 arg
.gssd_cred_verifier
= gssd_cred_verifier
;
628 arg
.target_name
.GSS_BUFFER_T_len
= (uint_t
)external_name
.length
;
629 arg
.target_name
.GSS_BUFFER_T_val
= (char *)external_name
.value
;
631 arg
.name_type
.GSS_OID_len
=
632 name_type
== GSS_C_NULL_OID
?
633 0 : (uint_t
)name_type
->length
;
635 arg
.name_type
.GSS_OID_val
=
636 name_type
== GSS_C_NULL_OID
?
637 (char *)NULL
: (char *)name_type
->elements
;
639 arg
.mech_type
.GSS_OID_len
= (uint_t
)(mech_type
!= GSS_C_NULL_OID
?
640 mech_type
->length
: 0);
641 arg
.mech_type
.GSS_OID_val
= (char *)(mech_type
!= GSS_C_NULL_OID
?
642 mech_type
->elements
: 0);
644 arg
.req_flags
= req_flags
;
646 arg
.time_req
= time_req
;
648 if (input_chan_bindings
!= GSS_C_NO_CHANNEL_BINDINGS
) {
649 arg
.input_chan_bindings
.present
= YES
;
650 arg
.input_chan_bindings
.initiator_addrtype
=
651 input_chan_bindings
->initiator_addrtype
;
652 arg
.input_chan_bindings
.initiator_address
.GSS_BUFFER_T_len
=
653 (uint_t
)input_chan_bindings
->initiator_address
.length
;
654 arg
.input_chan_bindings
.initiator_address
.GSS_BUFFER_T_val
=
655 (void *) input_chan_bindings
->initiator_address
.value
;
656 arg
.input_chan_bindings
.acceptor_addrtype
=
657 input_chan_bindings
->acceptor_addrtype
;
658 arg
.input_chan_bindings
.acceptor_address
.GSS_BUFFER_T_len
=
659 (uint_t
)input_chan_bindings
->acceptor_address
.length
;
660 arg
.input_chan_bindings
.acceptor_address
.GSS_BUFFER_T_val
=
661 (void *) input_chan_bindings
->acceptor_address
.value
;
662 arg
.input_chan_bindings
.application_data
.GSS_BUFFER_T_len
=
663 (uint_t
)input_chan_bindings
->application_data
.length
;
664 arg
.input_chan_bindings
.application_data
.GSS_BUFFER_T_val
=
665 (void *) input_chan_bindings
->application_data
.value
;
667 arg
.input_chan_bindings
.present
= NO
;
668 arg
.input_chan_bindings
.initiator_addrtype
= 0;
669 arg
.input_chan_bindings
.initiator_address
.GSS_BUFFER_T_len
= 0;
670 arg
.input_chan_bindings
.initiator_address
.GSS_BUFFER_T_val
= 0;
671 arg
.input_chan_bindings
.acceptor_addrtype
= 0;
672 arg
.input_chan_bindings
.acceptor_address
.GSS_BUFFER_T_len
= 0;
673 arg
.input_chan_bindings
.acceptor_address
.GSS_BUFFER_T_val
= 0;
674 arg
.input_chan_bindings
.application_data
.GSS_BUFFER_T_len
= 0;
675 arg
.input_chan_bindings
.application_data
.GSS_BUFFER_T_val
= 0;
678 arg
.input_token
.GSS_BUFFER_T_len
= (uint_t
)
679 (input_token
!= GSS_C_NO_BUFFER
? input_token
->length
: 0);
680 arg
.input_token
.GSS_BUFFER_T_val
= (char *)
681 (input_token
!= GSS_C_NO_BUFFER
? input_token
->value
: 0);
683 /* initialize the output parameters to empty values */
684 if (minor_status
!= NULL
)
685 *minor_status
= DEFAULT_MINOR_STAT
;
686 if (actual_mech_type
!= NULL
)
687 *actual_mech_type
= NULL
;
688 if (output_token
!= NULL
)
689 output_token
->length
= 0;
690 if (ret_flags
!= NULL
)
692 if (time_rec
!= NULL
)
695 /* call the remote procedure */
696 memset(&res
, 0, sizeof (res
));
697 if (gss_init_sec_context_1(&arg
, &res
, clnt
) != RPC_SUCCESS
) {
699 /* free the allocated memory for the flattened name */
700 gss_release_buffer(&minor_status_temp
, &external_name
);
702 return (GSS_S_FAILURE
);
706 * We could return from a GSS error here and need to return both the
707 * minor_status and output_token, back to the caller if applicable.
709 if (minor_status
!= NULL
)
710 *minor_status
= res
.minor_status
;
712 if (output_token
!= NULL
&& res
.output_token
.GSS_BUFFER_T_val
!= NULL
) {
713 output_token
->length
=
714 (size_t)res
.output_token
.GSS_BUFFER_T_len
;
715 output_token
->value
=
716 (void *)res
.output_token
.GSS_BUFFER_T_val
;
717 res
.output_token
.GSS_BUFFER_T_val
= NULL
;
718 res
.output_token
.GSS_BUFFER_T_len
= 0;
721 /* free the allocated memory for the flattened name */
722 gss_release_buffer(&minor_status_temp
, &external_name
);
724 /* if the call was successful, copy out the results */
725 if (res
.status
== (OM_uint32
) GSS_S_COMPLETE
||
726 res
.status
== (OM_uint32
) GSS_S_CONTINUE_NEEDED
) {
728 * copy the rpc results into the return argument
729 * on CONTINUE_NEEDED only ctx handle is ready.
732 *context_handle
= *((OM_uint32
*)
733 res
.context_handle
.GSS_CTX_ID_T_val
);
735 *gssd_context_verifier
= res
.gssd_context_verifier
;
737 /* the rest of the parameters is only ready on COMPLETE */
738 if (res
.status
== GSS_S_COMPLETE
) {
739 if (actual_mech_type
!= NULL
) {
740 *actual_mech_type
= (gss_OID
)
741 MALLOC(sizeof (gss_OID_desc
));
742 (*actual_mech_type
)->length
= (OM_UINT32
)
743 res
.actual_mech_type
.GSS_OID_len
;
744 (*actual_mech_type
)->elements
= (void *)
745 MALLOC((*actual_mech_type
)->length
);
746 memcpy((*actual_mech_type
)->elements
, (void *)
747 res
.actual_mech_type
.GSS_OID_val
,
748 (*actual_mech_type
)->length
);
752 if (ret_flags
!= NULL
)
753 *ret_flags
= res
.ret_flags
;
755 if (time_rec
!= NULL
)
756 *time_rec
= res
.time_rec
;
762 * free the memory allocated for the results and return with the
763 * status received in the rpc call.
766 clnt_freeres(clnt
, xdr_gss_init_sec_context_res
, (caddr_t
)&res
);
770 kgss_init_sec_context(
771 OM_uint32
*minor_status
,
772 gss_cred_id_t claimant_cred_handle
,
773 gss_ctx_id_t
*context_handle
,
774 gss_name_t target_name
,
778 gss_channel_bindings_t input_chan_bindings
,
779 gss_buffer_t input_token
,
780 gss_OID
*actual_mech_type
,
781 gss_buffer_t output_token
,
787 struct kgss_ctx
*kctx
;
788 OM_uint32 gssd_cred_verifier
;
789 gssd_cred_id_t gssd_cl_cred_handle
;
792 * If this is an initial call, we'll need to create the
793 * wrapper struct that contains kernel state information, and
794 * a reference to the handle from gssd.
796 if (*context_handle
== GSS_C_NO_CONTEXT
) {
798 *context_handle
= (gss_ctx_id_t
)kctx
;
799 kctx
->gssd_ctx
= (OM_uint32
) GSS_C_NO_CONTEXT
;
801 kctx
= (struct kgss_ctx
*)*context_handle
;
803 if (claimant_cred_handle
!= GSS_C_NO_CREDENTIAL
) {
805 KCRED_TO_CREDV(claimant_cred_handle
);
806 gssd_cl_cred_handle
=
807 KCRED_TO_CRED(claimant_cred_handle
);
809 gssd_cl_cred_handle
= GSSD_NO_CREDENTIAL
;
812 err
= kgss_init_sec_context_wrapped(minor_status
,
814 gssd_cred_verifier
, &kctx
->gssd_ctx
,
815 &kctx
->gssd_ctx_verifier
,
816 target_name
, mech_type
, req_flags
, time_req
,
817 input_chan_bindings
, input_token
, actual_mech_type
,
818 output_token
, ret_flags
, time_rec
, uid
);
820 if (GSS_ERROR(err
)) {
822 *context_handle
= GSS_C_NO_CONTEXT
;
827 kgss_accept_sec_context_wrapped(minor_status
,
829 gssd_context_verifier
,
830 verifier_cred_handle
,
839 delegated_cred_handle
,
841 OM_uint32
*minor_status
;
842 gssd_ctx_id_t
*context_handle
;
843 OM_uint32
*gssd_context_verifier
;
844 gssd_cred_id_t verifier_cred_handle
;
845 OM_uint32 gssd_cred_verifier
;
846 gss_buffer_t input_token
;
847 gss_channel_bindings_t input_chan_bindings
;
848 gss_buffer_t src_name
;
850 gss_buffer_t output_token
;
853 gss_cred_id_t
*delegated_cred_handle
;
856 gss_accept_sec_context_arg arg
;
857 gss_accept_sec_context_res res
;
858 struct kgss_cred
*kcred
;
860 /* get the client handle to GSSD */
861 if ((clnt
= getgssd_handle()) == NULL
) {
862 clnt_pcreateerror(server
);
863 return (GSS_S_FAILURE
);
866 /* copy the procedure arguments into the rpc arg parameter */
867 arg
.uid
= (OM_uint32
) uid
;
869 arg
.context_handle
.GSS_CTX_ID_T_len
=
870 *context_handle
== GSSD_NO_CONTEXT
?
871 0 : (uint_t
)sizeof (gssd_ctx_id_t
);
872 arg
.context_handle
.GSS_CTX_ID_T_val
= (char *)context_handle
;
873 arg
.gssd_context_verifier
=
874 *context_handle
== (OM_uint32
) GSS_C_NO_CONTEXT
?
875 0 : *gssd_context_verifier
;
877 arg
.verifier_cred_handle
.GSS_CRED_ID_T_len
=
878 verifier_cred_handle
== GSSD_NO_CREDENTIAL
?
879 0 : (uint_t
)sizeof (gssd_cred_id_t
);
880 arg
.verifier_cred_handle
.GSS_CRED_ID_T_val
=
881 (char *)&verifier_cred_handle
;
882 arg
.gssd_cred_verifier
= gssd_cred_verifier
;
884 arg
.input_token_buffer
.GSS_BUFFER_T_len
=
885 (uint_t
)(input_token
!= GSS_C_NO_BUFFER
?
886 input_token
->length
: 0);
887 arg
.input_token_buffer
.GSS_BUFFER_T_val
=
888 (char *)(input_token
!= GSS_C_NO_BUFFER
?
889 input_token
->value
: 0);
891 if (input_chan_bindings
!= GSS_C_NO_CHANNEL_BINDINGS
) {
892 arg
.input_chan_bindings
.present
= YES
;
893 arg
.input_chan_bindings
.initiator_addrtype
=
894 input_chan_bindings
->initiator_addrtype
;
895 arg
.input_chan_bindings
.initiator_address
.GSS_BUFFER_T_len
=
896 (uint_t
)input_chan_bindings
->initiator_address
.length
;
897 arg
.input_chan_bindings
.initiator_address
.GSS_BUFFER_T_val
=
898 (void *) input_chan_bindings
->initiator_address
.value
;
899 arg
.input_chan_bindings
.acceptor_addrtype
=
900 input_chan_bindings
->acceptor_addrtype
;
901 arg
.input_chan_bindings
.acceptor_address
.GSS_BUFFER_T_len
=
902 (uint_t
)input_chan_bindings
->acceptor_address
.length
;
903 arg
.input_chan_bindings
.acceptor_address
.GSS_BUFFER_T_val
=
904 (void *) input_chan_bindings
->acceptor_address
.value
;
905 arg
.input_chan_bindings
.application_data
.GSS_BUFFER_T_len
=
906 (uint_t
)input_chan_bindings
->application_data
.length
;
907 arg
.input_chan_bindings
.application_data
.GSS_BUFFER_T_val
=
908 (void *) input_chan_bindings
->application_data
.value
;
910 arg
.input_chan_bindings
.present
= NO
;
911 arg
.input_chan_bindings
.initiator_addrtype
= 0;
912 arg
.input_chan_bindings
.initiator_address
.GSS_BUFFER_T_len
= 0;
913 arg
.input_chan_bindings
.initiator_address
.GSS_BUFFER_T_val
= 0;
914 arg
.input_chan_bindings
.acceptor_addrtype
= 0;
915 arg
.input_chan_bindings
.acceptor_address
.GSS_BUFFER_T_len
= 0;
916 arg
.input_chan_bindings
.acceptor_address
.GSS_BUFFER_T_val
= 0;
917 arg
.input_chan_bindings
.application_data
.GSS_BUFFER_T_len
= 0;
918 arg
.input_chan_bindings
.application_data
.GSS_BUFFER_T_val
= 0;
921 /* set the output parameters to empty values.... */
922 if (minor_status
!= NULL
)
923 *minor_status
= DEFAULT_MINOR_STAT
;
924 if (src_name
!= NULL
) {
925 src_name
->length
= 0;
926 src_name
->value
= NULL
;
928 if (mech_type
!= NULL
)
930 if (output_token
!= NULL
)
931 output_token
->length
= 0;
932 if (ret_flags
!= NULL
)
934 if (time_rec
!= NULL
)
936 if (delegated_cred_handle
!= NULL
)
937 *delegated_cred_handle
= NULL
;
939 /* call the remote procedure */
940 memset(&res
, 0, sizeof (res
));
941 if (gss_accept_sec_context_1(&arg
, &res
, clnt
) != RPC_SUCCESS
) {
942 return (GSS_S_FAILURE
);
946 * We could return from a GSS error here and need to return both the
947 * minor_status and output_token, back to the caller if applicable.
949 if (minor_status
!= NULL
)
950 *minor_status
= res
.minor_status
;
952 if (output_token
!= NULL
&& res
.output_token
.GSS_BUFFER_T_val
!= NULL
) {
953 output_token
->length
=
954 res
.output_token
.GSS_BUFFER_T_len
;
955 output_token
->value
=
956 (void *) res
.output_token
.GSS_BUFFER_T_val
;
957 res
.output_token
.GSS_BUFFER_T_val
= 0;
958 res
.output_token
.GSS_BUFFER_T_len
= 0;
961 if (res
.status
== (OM_uint32
) GSS_S_COMPLETE
||
962 res
.status
== (OM_uint32
) GSS_S_CONTINUE_NEEDED
) {
964 * when gss returns CONTINUE_NEEDED we can only
965 * use the context parameter.
968 *context_handle
= *((gssd_ctx_id_t
*)
969 res
.context_handle
.GSS_CTX_ID_T_val
);
970 *gssd_context_verifier
= res
.gssd_context_verifier
;
972 /* the other parameters are ready on for COMPLETE */
973 if (res
.status
== GSS_S_COMPLETE
)
977 * The src_name is in external format.
979 if (src_name
!= NULL
) {
980 src_name
->length
= res
.src_name
.GSS_BUFFER_T_len
;
981 src_name
->value
= res
.src_name
.GSS_BUFFER_T_val
;
982 res
.src_name
.GSS_BUFFER_T_val
= NULL
;
983 res
.src_name
.GSS_BUFFER_T_len
= 0;
986 * move mech type returned to mech_type
987 * for gss_import_name_for_mech()
989 if (mech_type
!= NULL
) {
991 (gss_OID
) MALLOC(sizeof (gss_OID_desc
));
992 (*mech_type
)->length
=
993 (OM_UINT32
) res
.mech_type
.GSS_OID_len
;
994 (*mech_type
)->elements
=
995 (void *) MALLOC((*mech_type
)->length
);
996 memcpy((*mech_type
)->elements
,
997 res
.mech_type
.GSS_OID_val
,
998 (*mech_type
)->length
);
1001 if (ret_flags
!= NULL
)
1002 *ret_flags
= res
.ret_flags
;
1004 if (time_rec
!= NULL
)
1005 *time_rec
= res
.time_rec
;
1007 if ((delegated_cred_handle
!= NULL
) &&
1008 (res
.delegated_cred_handle
.GSS_CRED_ID_T_len
1010 kcred
= KGSS_CRED_ALLOC();
1012 kcred
->gssd_cred
= *((gssd_cred_id_t
*)
1013 res
.delegated_cred_handle
.GSS_CRED_ID_T_val
);
1014 kcred
->gssd_cred_verifier
=
1015 res
.gssd_context_verifier
;
1016 *delegated_cred_handle
= (gss_cred_id_t
)kcred
;
1018 } /* res.status == GSS_S_COMPLETE */
1019 } /* res.status == GSS_S_COMPLETE or GSS_CONTINUE_NEEDED */
1023 * free the memory allocated for the results and return with the status
1024 * received in the rpc call
1027 clnt_freeres(clnt
, xdr_gss_accept_sec_context_res
, (caddr_t
)&res
);
1028 return (res
.status
);
1032 kgss_accept_sec_context(
1033 OM_uint32
*minor_status
,
1034 gss_ctx_id_t
*context_handle
,
1035 gss_cred_id_t verifier_cred_handle
,
1036 gss_buffer_t input_token
,
1037 gss_channel_bindings_t input_chan_bindings
,
1038 gss_buffer_t src_name
,
1040 gss_buffer_t output_token
,
1042 OM_uint32
*time_rec
,
1043 gss_cred_id_t
*delegated_cred_handle
,
1047 struct kgss_ctx
*kctx
;
1048 OM_uint32 gssd_cred_verifier
;
1049 gssd_cred_id_t gssd_ver_cred_handle
;
1052 if (*context_handle
== GSS_C_NO_CONTEXT
) {
1053 kctx
= KGSS_ALLOC();
1054 *context_handle
= (gss_ctx_id_t
)kctx
;
1055 kctx
->gssd_ctx
= GSSD_NO_CONTEXT
;
1057 kctx
= (struct kgss_ctx
*)*context_handle
;
1059 if (verifier_cred_handle
!= GSS_C_NO_CREDENTIAL
) {
1060 gssd_cred_verifier
=
1061 KCRED_TO_CREDV(verifier_cred_handle
);
1062 gssd_ver_cred_handle
=
1063 KCRED_TO_CRED(verifier_cred_handle
);
1065 gssd_ver_cred_handle
= GSSD_NO_CREDENTIAL
;
1067 err
= kgss_accept_sec_context_wrapped(minor_status
, &kctx
->gssd_ctx
,
1068 &kctx
->gssd_ctx_verifier
, gssd_ver_cred_handle
,
1069 gssd_cred_verifier
, input_token
, input_chan_bindings
,
1070 src_name
, mech_type
, output_token
, ret_flags
,
1071 time_rec
, delegated_cred_handle
, uid
);
1073 if (GSS_ERROR(err
)) {
1075 *context_handle
= GSS_C_NO_CONTEXT
;
1083 kgss_process_context_token(minor_status
,
1087 OM_uint32
*minor_status
;
1088 gss_ctx_id_t context_handle
;
1089 gss_buffer_t token_buffer
;
1092 OM_uint32 gssd_context_verifier
;
1094 gss_process_context_token_arg arg
;
1095 gss_process_context_token_res res
;
1097 gssd_context_verifier
= KGSS_CTX_TO_GSSD_CTXV(context_handle
);
1099 /* get the client handle to GSSD */
1101 if ((clnt
= getgssd_handle()) == NULL
) {
1102 clnt_pcreateerror(server
);
1103 return (GSS_S_FAILURE
);
1106 /* copy the procedure arguments into the rpc arg parameter */
1107 arg
.uid
= (OM_uint32
) uid
;
1109 arg
.context_handle
.GSS_CTX_ID_T_len
= (uint_t
)sizeof (gss_ctx_id_t
);
1110 arg
.context_handle
.GSS_CTX_ID_T_val
= (char *)&context_handle
;
1111 arg
.gssd_context_verifier
= gssd_context_verifier
;
1112 arg
.token_buffer
.GSS_BUFFER_T_len
= (uint_t
)token_buffer
;
1113 arg
.token_buffer
.GSS_BUFFER_T_val
= (char *)token_buffer
->value
;
1115 /* call the remote procedure */
1117 memset(&res
, 0, sizeof (res
));
1118 if (gss_process_context_token_1(&arg
, &res
, clnt
) != RPC_SUCCESS
) {
1121 * if the RPC call times out, null out all return arguments,
1122 * set minor_status to its maximum value, and return GSS_S_FAILURE
1125 if (minor_status
!= NULL
)
1126 *minor_status
= DEFAULT_MINOR_STAT
;
1128 return (GSS_S_FAILURE
);
1131 /* copy the rpc results into the return arguments */
1133 if (minor_status
!= NULL
)
1134 *minor_status
= res
.minor_status
;
1136 /* return with status returned in rpc call */
1138 return (res
.status
);
1142 kgss_delete_sec_context_wrapped(minor_status
,
1144 gssd_context_verifier
,
1146 OM_uint32
*minor_status
;
1147 gssd_ctx_id_t
*context_handle
;
1148 OM_uint32 gssd_context_verifier
;
1149 gss_buffer_t output_token
;
1151 gss_delete_sec_context_arg arg
;
1152 gss_delete_sec_context_res res
;
1155 /* get the client handle to GSSD */
1156 if ((clnt
= getgssd_handle()) == NULL
) {
1157 clnt_pcreateerror(server
);
1158 return (GSS_S_FAILURE
);
1161 /* copy the procedure arguments into the rpc arg parameter */
1163 arg
.context_handle
.GSS_CTX_ID_T_len
=
1164 *context_handle
== (OM_uint32
) GSS_C_NO_CONTEXT
? 0 :
1165 (uint_t
)sizeof (OM_uint32
);
1166 arg
.context_handle
.GSS_CTX_ID_T_val
= (char *)context_handle
;
1168 arg
.gssd_context_verifier
= gssd_context_verifier
;
1170 /* call the remote procedure */
1172 memset(&res
, 0, sizeof (res
));
1173 if (gss_delete_sec_context_1(&arg
, &res
, clnt
) != RPC_SUCCESS
) {
1176 * if the RPC call times out, null out all return arguments,
1177 * set minor_status to its max value, and return GSS_S_FAILURE
1180 if (minor_status
!= NULL
)
1181 *minor_status
= DEFAULT_MINOR_STAT
;
1182 if (context_handle
!= NULL
)
1183 *context_handle
= 0;
1184 if (output_token
!= NULL
)
1185 output_token
->length
= 0;
1187 return (GSS_S_FAILURE
);
1190 /* copy the rpc results into the return arguments */
1192 if (minor_status
!= NULL
)
1193 *minor_status
= res
.minor_status
;
1195 if (res
.context_handle
.GSS_CTX_ID_T_len
== 0)
1196 *context_handle
= 0;
1199 *context_handle
= *((gssd_ctx_id_t
*)
1200 res
.context_handle
.GSS_CTX_ID_T_val
);
1202 if (output_token
!= NULL
&& res
.output_token
.GSS_BUFFER_T_val
!= NULL
) {
1203 output_token
->length
= res
.output_token
.GSS_BUFFER_T_len
;
1204 output_token
->value
= res
.output_token
.GSS_BUFFER_T_val
;
1205 res
.output_token
.GSS_BUFFER_T_len
= 0;
1206 res
.output_token
.GSS_BUFFER_T_val
= NULL
;
1210 * free the memory allocated for the results and return with the status
1211 * received in the rpc call
1214 clnt_freeres(clnt
, xdr_gss_delete_sec_context_res
, (caddr_t
)&res
);
1215 return (res
.status
);
1220 kgss_delete_sec_context(
1221 OM_uint32
*minor_status
,
1222 gss_ctx_id_t
*context_handle
,
1223 gss_buffer_t output_token
)
1226 struct kgss_ctx
*kctx
;
1228 if (*context_handle
== GSS_C_NO_CONTEXT
) {
1229 return (GSS_S_NO_CONTEXT
);
1231 kctx
= KCTX_TO_KGSS_CTX(*context_handle
);
1233 err
= kgss_delete_sec_context_wrapped(minor_status
,
1234 &kctx
->gssd_ctx
, kctx
->gssd_ctx_verifier
,
1237 if (kctx
->gssd_ctx
!= GSSD_NO_CONTEXT
)
1238 err
= GSS_S_FAILURE
;
1240 err
= GSS_S_COMPLETE
;
1243 *context_handle
= GSS_C_NO_CONTEXT
;
1249 kgss_context_time(minor_status
,
1253 OM_uint32
*minor_status
;
1254 gss_ctx_id_t context_handle
;
1255 OM_uint32
*time_rec
;
1258 return (GSS_S_FAILURE
);
1262 kgss_sign_wrapped(minor_status
,
1267 gssd_context_verifier
)
1268 OM_uint32
*minor_status
;
1269 gssd_ctx_id_t context_handle
;
1270 OM_uint32 gssd_context_verifier
;
1272 gss_buffer_t message_buffer
;
1273 gss_buffer_t msg_token
;
1279 /* get the client handle to GSSD */
1281 if ((clnt
= getgssd_handle()) == NULL
) {
1282 clnt_pcreateerror(server
);
1283 return (GSS_S_FAILURE
);
1286 /* copy the procedure arguments into the rpc arg parameter */
1289 arg
.context_handle
.GSS_CTX_ID_T_len
= (uint_t
)sizeof (gssd_ctx_id_t
);
1290 arg
.context_handle
.GSS_CTX_ID_T_val
= (char *)&context_handle
;
1291 arg
.gssd_context_verifier
= gssd_context_verifier
;
1293 arg
.qop_req
= qop_req
;
1294 arg
.message_buffer
.GSS_BUFFER_T_len
= (uint_t
)message_buffer
->length
;
1295 arg
.message_buffer
.GSS_BUFFER_T_val
= (char *)message_buffer
->value
;
1297 /* call the remote procedure */
1299 memset(&res
, 0, sizeof (res
));
1300 if (gss_sign_1(&arg
, &res
, clnt
) != RPC_SUCCESS
) {
1303 * if the RPC call times out, null out all return arguments,
1304 * set minor_status to its maximum value, and return GSS_S_FAILURE
1307 if (minor_status
!= NULL
)
1308 *minor_status
= DEFAULT_MINOR_STAT
;
1309 if (msg_token
!= NULL
)
1310 msg_token
->length
= 0;
1312 return (GSS_S_FAILURE
);
1315 /* copy the rpc results into the return arguments */
1317 if (minor_status
!= NULL
)
1318 *minor_status
= res
.minor_status
;
1320 if (msg_token
!= NULL
) {
1321 msg_token
->length
= res
.msg_token
.GSS_BUFFER_T_len
;
1322 msg_token
->value
= (void *) MALLOC(msg_token
->length
);
1323 memcpy(msg_token
->value
, res
.msg_token
.GSS_BUFFER_T_val
,
1328 * free the memory allocated for the results and return with the status
1329 * received in the rpc call
1332 clnt_freeres(clnt
, xdr_gss_sign_res
, (caddr_t
)&res
);
1333 return (res
.status
);
1338 OM_uint32
*minor_status
,
1339 gss_ctx_id_t context_handle
,
1341 gss_buffer_t message_buffer
,
1342 gss_buffer_t msg_token
)
1344 if (context_handle
== GSS_C_NO_CONTEXT
)
1345 return (GSS_S_FAILURE
);
1347 return (KGSS_SIGN(minor_status
,
1348 context_handle
, qop_req
, message_buffer
,
1353 kgss_verify_wrapped(
1359 gssd_context_verifier
)
1360 OM_uint32
*minor_status
;
1361 gssd_ctx_id_t context_handle
;
1362 OM_uint32 gssd_context_verifier
;
1363 gss_buffer_t message_buffer
;
1364 gss_buffer_t token_buffer
;
1370 /* get the client handle to GSSD */
1372 if ((clnt
= getgssd_handle()) == NULL
) {
1373 clnt_pcreateerror(server
);
1374 return (GSS_S_FAILURE
);
1377 /* copy the procedure arguments into the rpc arg parameter */
1379 arg
.context_handle
.GSS_CTX_ID_T_len
= (uint_t
)sizeof (gssd_ctx_id_t
);
1380 arg
.context_handle
.GSS_CTX_ID_T_val
= (char *)&context_handle
;
1382 arg
.gssd_context_verifier
= gssd_context_verifier
;
1384 arg
.message_buffer
.GSS_BUFFER_T_len
= (uint_t
)message_buffer
->length
;
1385 arg
.message_buffer
.GSS_BUFFER_T_val
= (char *)message_buffer
->value
;
1387 arg
.token_buffer
.GSS_BUFFER_T_len
= (uint_t
)token_buffer
->length
;
1388 arg
.token_buffer
.GSS_BUFFER_T_val
= (char *)token_buffer
->value
;
1390 /* call the remote procedure */
1392 memset(&res
, 0, sizeof (res
));
1393 if (gss_verify_1(&arg
, &res
, clnt
) != RPC_SUCCESS
) {
1396 * if the RPC call times out, null out all return arguments,
1397 * set minor_status to its maximum value, and return GSS_S_FAILURE
1400 if (minor_status
!= NULL
)
1401 *minor_status
= DEFAULT_MINOR_STAT
;
1402 if (qop_state
!= NULL
)
1405 return (GSS_S_FAILURE
);
1408 /* copy the rpc results into the return arguments */
1410 if (minor_status
!= NULL
)
1411 *minor_status
= res
.minor_status
;
1413 if (qop_state
!= NULL
)
1414 *qop_state
= res
.qop_state
;
1416 /* return with status returned in rpc call */
1418 return (res
.status
);
1422 kgss_verify(OM_uint32
*minor_status
,
1423 gss_ctx_id_t context_handle
,
1424 gss_buffer_t message_buffer
,
1425 gss_buffer_t token_buffer
,
1428 if (context_handle
== GSS_C_NO_CONTEXT
)
1429 return (GSS_S_FAILURE
);
1431 return (KGSS_VERIFY(minor_status
, context_handle
,
1432 message_buffer
, token_buffer
, qop_state
));
1442 input_message_buffer
,
1444 output_message_buffer
,
1445 gssd_context_verifier
)
1447 OM_uint32
*minor_status
;
1448 gssd_ctx_id_t context_handle
;
1449 OM_uint32 gssd_context_verifier
;
1452 gss_buffer_t input_message_buffer
;
1454 gss_buffer_t output_message_buffer
;
1459 /* get the client handle to GSSD */
1461 if ((clnt
= getgssd_handle()) == NULL
) {
1462 clnt_pcreateerror(server
);
1463 return (GSS_S_FAILURE
);
1466 /* copy the procedure arguments into the rpc arg parameter */
1469 arg
.context_handle
.GSS_CTX_ID_T_len
= (uint_t
)sizeof (gssd_ctx_id_t
);
1470 arg
.context_handle
.GSS_CTX_ID_T_val
= (char *)&context_handle
;
1471 arg
.gssd_context_verifier
= gssd_context_verifier
;
1473 arg
.conf_req_flag
= conf_req_flag
;
1475 arg
.qop_req
= qop_req
;
1477 arg
.input_message_buffer
.GSS_BUFFER_T_len
=
1478 (uint_t
)input_message_buffer
->length
;
1480 arg
.input_message_buffer
.GSS_BUFFER_T_val
=
1481 (char *)input_message_buffer
->value
;
1483 /* call the remote procedure */
1485 memset(&res
, 0, sizeof (res
));
1486 if (gss_seal_1(&arg
, &res
, clnt
) != RPC_SUCCESS
) {
1489 * if the RPC call times out, null out all return arguments,
1490 * set minor_status to its maximum value, and return GSS_S_FAILURE
1493 if (minor_status
!= NULL
)
1494 *minor_status
= DEFAULT_MINOR_STAT
;
1495 if (conf_state
!= NULL
)
1497 if (output_message_buffer
!= NULL
)
1498 output_message_buffer
->length
= 0;
1500 return (GSS_S_FAILURE
);
1503 /* copy the rpc results into the return arguments */
1505 if (minor_status
!= NULL
)
1506 *minor_status
= res
.minor_status
;
1508 if (conf_state
!= NULL
)
1509 *conf_state
= res
.conf_state
;
1511 if (output_message_buffer
!= NULL
) {
1512 output_message_buffer
->length
=
1513 res
.output_message_buffer
.GSS_BUFFER_T_len
;
1515 output_message_buffer
->value
=
1516 (void *) MALLOC(output_message_buffer
->length
);
1517 memcpy(output_message_buffer
->value
,
1518 res
.output_message_buffer
.GSS_BUFFER_T_val
,
1519 output_message_buffer
->length
);
1523 * free the memory allocated for the results and return with the status
1524 * received in the rpc call
1527 clnt_freeres(clnt
, xdr_gss_seal_res
, (caddr_t
)&res
);
1528 return (res
.status
);
1532 kgss_seal(OM_uint32
*minor_status
,
1533 gss_ctx_id_t context_handle
,
1536 gss_buffer_t input_message_buffer
,
1538 gss_buffer_t output_message_buffer
)
1541 if (context_handle
== GSS_C_NO_CONTEXT
)
1542 return (GSS_S_FAILURE
);
1544 return (KGSS_SEAL(minor_status
, context_handle
,
1545 conf_req_flag
, qop_req
,
1546 input_message_buffer
,
1547 conf_state
, output_message_buffer
));
1551 kgss_unseal_wrapped(minor_status
,
1553 input_message_buffer
,
1554 output_message_buffer
,
1557 gssd_context_verifier
)
1558 OM_uint32
*minor_status
;
1559 gssd_ctx_id_t context_handle
;
1560 OM_uint32 gssd_context_verifier
;
1561 gss_buffer_t input_message_buffer
;
1562 gss_buffer_t output_message_buffer
;
1569 /* get the client handle to GSSD */
1571 if ((clnt
= getgssd_handle()) == NULL
) {
1572 clnt_pcreateerror(server
);
1573 return (GSS_S_FAILURE
);
1576 /* copy the procedure arguments into the rpc arg parameter */
1579 arg
.context_handle
.GSS_CTX_ID_T_len
= (uint_t
)sizeof (gssd_ctx_id_t
);
1580 arg
.context_handle
.GSS_CTX_ID_T_val
= (char *)&context_handle
;
1581 arg
.gssd_context_verifier
= gssd_context_verifier
;
1583 arg
.input_message_buffer
.GSS_BUFFER_T_len
=
1584 (uint_t
)input_message_buffer
->length
;
1586 arg
.input_message_buffer
.GSS_BUFFER_T_val
=
1587 (char *)input_message_buffer
->value
;
1589 /* call the remote procedure */
1591 memset(&res
, 0, sizeof (res
));
1592 if (gss_unseal_1(&arg
, &res
, clnt
) != RPC_SUCCESS
) {
1595 * if the RPC call times out, null out all return arguments,
1596 * set minor_status to its maximum value, and return GSS_S_FAILURE
1599 if (minor_status
!= NULL
)
1600 *minor_status
= DEFAULT_MINOR_STAT
;
1601 if (output_message_buffer
!= NULL
)
1602 output_message_buffer
->length
= 0;
1603 if (conf_state
!= NULL
)
1605 if (qop_state
!= NULL
)
1608 return (GSS_S_FAILURE
);
1611 /* copy the rpc results into the return arguments */
1613 if (minor_status
!= NULL
)
1614 *minor_status
= res
.minor_status
;
1616 if (output_message_buffer
!= NULL
) {
1617 output_message_buffer
->length
=
1618 res
.output_message_buffer
.GSS_BUFFER_T_len
;
1620 output_message_buffer
->value
=
1621 (void *) MALLOC(output_message_buffer
->length
);
1622 memcpy(output_message_buffer
->value
,
1623 res
.output_message_buffer
.GSS_BUFFER_T_val
,
1624 output_message_buffer
->length
);
1627 if (conf_state
!= NULL
)
1628 *conf_state
= res
.conf_state
;
1630 if (qop_state
!= NULL
)
1631 *qop_state
= res
.qop_state
;
1634 * free the memory allocated for the results and return with the status
1635 * received in the rpc call
1638 clnt_freeres(clnt
, xdr_gss_unseal_res
, (caddr_t
)&res
);
1639 return (res
.status
);
1643 kgss_unseal(OM_uint32
*minor_status
,
1644 gss_ctx_id_t context_handle
,
1645 gss_buffer_t input_message_buffer
,
1646 gss_buffer_t output_message_buffer
,
1650 if (context_handle
== GSS_C_NO_CONTEXT
)
1651 return (GSS_S_FAILURE
);
1653 return (KGSS_UNSEAL(minor_status
, context_handle
,
1654 input_message_buffer
, output_message_buffer
,
1655 conf_state
, qop_state
));
1659 kgss_display_status(minor_status
,
1666 OM_uint32
*minor_status
;
1667 OM_uint32 status_value
;
1670 int *message_context
;
1671 gss_buffer_t status_string
;
1674 gss_display_status_arg arg
;
1675 gss_display_status_res res
;
1677 /* get the client handle to GSSD */
1679 if ((clnt
= getgssd_handle()) == NULL
) {
1680 clnt_pcreateerror(server
);
1681 return (GSS_S_FAILURE
);
1684 /* copy the procedure arguments into the rpc arg parameter */
1686 arg
.uid
= (OM_uint32
) uid
;
1688 arg
.status_value
= status_value
;
1689 arg
.status_type
= status_type
;
1691 arg
.mech_type
.GSS_OID_len
= (uint_t
)(mech_type
!= GSS_C_NULL_OID
?
1692 mech_type
->length
: 0);
1693 arg
.mech_type
.GSS_OID_val
= (char *)(mech_type
!= GSS_C_NULL_OID
?
1694 mech_type
->elements
: 0);
1696 arg
.message_context
= *message_context
;
1698 /* call the remote procedure */
1700 if (message_context
!= NULL
)
1701 *message_context
= 0;
1702 if (status_string
!= NULL
) {
1703 status_string
->length
= 0;
1704 status_string
->value
= NULL
;
1707 memset(&res
, 0, sizeof (res
));
1708 if (gss_display_status_1(&arg
, &res
, clnt
) != RPC_SUCCESS
) {
1711 * if the RPC call times out, null out all return arguments,
1712 * set minor_status to its maximum value, and return GSS_S_FAILURE
1715 if (minor_status
!= NULL
)
1716 *minor_status
= DEFAULT_MINOR_STAT
;
1718 return (GSS_S_FAILURE
);
1721 if (minor_status
!= NULL
)
1722 *minor_status
= res
.minor_status
;
1724 /* now process the results and pass them back to the caller */
1726 if (res
.status
== GSS_S_COMPLETE
) {
1727 if (message_context
!= NULL
)
1728 *message_context
= res
.message_context
;
1729 if (status_string
!= NULL
) {
1730 status_string
->length
=
1731 (size_t)res
.status_string
.GSS_BUFFER_T_len
;
1732 status_string
->value
=
1733 (void *)MALLOC(status_string
->length
);
1734 memcpy(status_string
->value
,
1735 res
.status_string
.GSS_BUFFER_T_val
,
1736 status_string
->length
);
1740 clnt_freeres(clnt
, xdr_gss_display_status_res
, (caddr_t
)&res
);
1741 return (res
.status
);
1746 kgss_indicate_mechs(minor_status
,
1749 OM_uint32
*minor_status
;
1750 gss_OID_set
*mech_set
;
1754 gss_indicate_mechs_res res
;
1757 /* get the client handle to GSSD */
1759 if ((clnt
= getgssd_handle()) == NULL
) {
1760 clnt_pcreateerror(server
);
1761 return (GSS_S_FAILURE
);
1764 memset(&res
, 0, sizeof (res
));
1765 if (gss_indicate_mechs_1(&arg
, &res
, clnt
) != RPC_SUCCESS
) {
1768 * if the RPC call times out, null out all return arguments,
1769 * set minor_status to its maximum value, and return GSS_S_FAILURE
1772 if (minor_status
!= NULL
)
1773 *minor_status
= DEFAULT_MINOR_STAT
;
1774 if (mech_set
!= NULL
)
1777 return (GSS_S_FAILURE
);
1780 /* copy the rpc results into the return arguments */
1782 if (minor_status
!= NULL
)
1783 *minor_status
= res
.minor_status
;
1785 if (mech_set
!= NULL
) {
1786 *mech_set
= (gss_OID_set
) MALLOC(sizeof (gss_OID_set_desc
));
1787 (*mech_set
)->count
= res
.mech_set
.GSS_OID_SET_len
;
1788 (*mech_set
)->elements
= (void *)
1789 MALLOC ((*mech_set
)->count
* sizeof (gss_OID_desc
));
1790 for (i
= 0; i
< (*mech_set
)->count
; i
++) {
1791 (*mech_set
)->elements
[i
].length
=
1792 res
.mech_set
.GSS_OID_SET_val
[i
].GSS_OID_len
;
1793 (*mech_set
)->elements
[i
].elements
= (void *)
1794 MALLOC ((*mech_set
)->elements
[i
].length
);
1795 memcpy ((*mech_set
)->elements
[i
].elements
,
1796 res
.mech_set
.GSS_OID_SET_val
[i
].GSS_OID_val
,
1797 (*mech_set
)->elements
[i
].length
);
1802 * free the memory allocated for the results and return with the status
1803 * received in the rpc call
1806 clnt_freeres(clnt
, xdr_gss_indicate_mechs_res
, (caddr_t
)&res
);
1807 return (res
.status
);
1812 kgss_inquire_cred_wrapped(minor_status
,
1820 OM_uint32
*minor_status
;
1821 gssd_cred_id_t cred_handle
;
1822 OM_uint32 gssd_cred_verifier
;
1824 OM_uint32
*lifetime
;
1826 gss_OID_set
*mechanisms
;
1829 OM_uint32 minor_status_temp
;
1830 gss_buffer_desc external_name
;
1834 gss_inquire_cred_arg arg
;
1835 gss_inquire_cred_res res
;
1837 /* get the client handle to GSSD */
1839 if ((clnt
= getgssd_handle()) == NULL
) {
1840 clnt_pcreateerror(server
);
1841 return (GSS_S_FAILURE
);
1845 /* copy the procedure arguments into the rpc arg parameter */
1847 arg
.uid
= (OM_uint32
) uid
;
1849 arg
.cred_handle
.GSS_CRED_ID_T_len
=
1850 cred_handle
== GSSD_NO_CREDENTIAL
?
1851 0 : (uint_t
)sizeof (gssd_cred_id_t
);
1852 arg
.cred_handle
.GSS_CRED_ID_T_val
= (char *)&cred_handle
;
1853 arg
.gssd_cred_verifier
= gssd_cred_verifier
;
1855 /* call the remote procedure */
1857 memset(&res
, 0, sizeof (res
));
1858 if (gss_inquire_cred_1(&arg
, &res
, clnt
) != RPC_SUCCESS
) {
1861 * if the RPC call times out, null out all return arguments,
1862 * set minor_status to its maximum value, and return GSS_S_FAILURE
1865 if (minor_status
!= NULL
)
1866 *minor_status
= DEFAULT_MINOR_STAT
;
1869 if (lifetime
!= NULL
)
1871 if (cred_usage
!= NULL
)
1873 if (mechanisms
!= NULL
)
1876 return (GSS_S_FAILURE
);
1879 /* copy the rpc results into the return arguments */
1881 if (minor_status
!= NULL
)
1882 *minor_status
= res
.minor_status
;
1884 /* convert name from external to internal format */
1887 external_name
.length
= res
.name
.GSS_BUFFER_T_len
;
1888 external_name
.value
= res
.name
.GSS_BUFFER_T_val
;
1891 * we have to allocate a name_type descriptor and
1892 * elements storage, since gss_import_name() only
1893 * stores a pointer to the name_type info in the
1897 name_type
= (gss_OID
) MALLOC(sizeof (gss_OID_desc
));
1899 name_type
->length
= res
.name_type
.GSS_OID_len
;
1900 name_type
->elements
= (void *) MALLOC(name_type
->length
);
1901 memcpy(name_type
->elements
, res
.name_type
.GSS_OID_val
,
1904 if (gss_import_name(&minor_status_temp
, &external_name
,
1905 name_type
, name
) != GSS_S_COMPLETE
) {
1907 *minor_status
= (OM_uint32
) minor_status_temp
;
1908 gss_release_buffer(&minor_status_temp
, &external_name
);
1910 clnt_freeres(clnt
, xdr_gss_inquire_cred_res
,
1912 return ((OM_uint32
) GSS_S_FAILURE
);
1916 if (lifetime
!= NULL
)
1917 *lifetime
= res
.lifetime
;
1919 if (cred_usage
!= NULL
)
1920 *cred_usage
= res
.cred_usage
;
1922 if (mechanisms
!= NULL
) {
1924 (gss_OID_set
) MALLOC(sizeof (gss_OID_set_desc
));
1925 if (res
.mechanisms
.GSS_OID_SET_len
!= 0) {
1926 (*mechanisms
)->count
=
1927 (int)res
.mechanisms
.GSS_OID_SET_len
;
1928 (*mechanisms
)->elements
= (gss_OID
)
1929 MALLOC(sizeof (gss_OID
) * (*mechanisms
)->count
);
1931 for (i
= 0; i
< (*mechanisms
)->count
; i
++) {
1932 (*mechanisms
)->elements
[i
].length
= (OM_uint32
)
1933 res
.mechanisms
.GSS_OID_SET_val
[i
].GSS_OID_len
;
1934 (*mechanisms
)->elements
[i
].elements
= (void *)
1935 MALLOC((*mechanisms
)->elements
[i
].length
);
1936 memcpy((*mechanisms
)->elements
[i
].elements
,
1937 res
.mechanisms
.GSS_OID_SET_val
[i
].GSS_OID_val
,
1938 (*mechanisms
)->elements
[i
].length
);
1941 (*mechanisms
)->count
= 0;
1945 * free the memory allocated for the results and return with the status
1946 * received in the rpc call
1949 clnt_freeres(clnt
, xdr_gss_inquire_cred_res
, (caddr_t
)&res
);
1950 return (res
.status
);
1955 kgss_inquire_cred(minor_status
,
1962 OM_uint32
*minor_status
;
1963 gss_cred_id_t cred_handle
;
1965 OM_uint32
*lifetime
;
1967 gss_OID_set
* mechanisms
;
1971 OM_uint32 gssd_cred_verifier
;
1972 gssd_cred_id_t gssd_cred_handle
;
1974 gssd_cred_verifier
= KCRED_TO_CREDV(cred_handle
);
1975 gssd_cred_handle
= KCRED_TO_CRED(cred_handle
);
1977 return (kgss_inquire_cred_wrapped(minor_status
,
1978 gssd_cred_handle
, gssd_cred_verifier
,
1979 name
, lifetime
, cred_usage
, mechanisms
, uid
));
1984 kgss_inquire_cred_by_mech_wrapped(minor_status
,
1989 OM_uint32
*minor_status
;
1990 gssd_cred_id_t cred_handle
;
1991 OM_uint32 gssd_cred_verifier
;
1995 OM_uint32 minor_status_temp
;
1997 gss_inquire_cred_by_mech_arg arg
;
1998 gss_inquire_cred_by_mech_res res
;
2000 /* get the client handle to GSSD */
2002 if ((clnt
= getgssd_handle()) == NULL
) {
2003 clnt_pcreateerror(server
);
2004 return (GSS_S_FAILURE
);
2008 /* copy the procedure arguments into the rpc arg parameter */
2010 arg
.uid
= (OM_uint32
) uid
;
2012 arg
.cred_handle
.GSS_CRED_ID_T_len
=
2013 cred_handle
== GSSD_NO_CREDENTIAL
?
2014 0 : (uint_t
)sizeof (gssd_cred_id_t
);
2015 arg
.cred_handle
.GSS_CRED_ID_T_val
= (char *)&cred_handle
;
2016 arg
.gssd_cred_verifier
= gssd_cred_verifier
;
2018 arg
.mech_type
.GSS_OID_len
=
2019 (uint_t
)(mech_type
!= GSS_C_NULL_OID
?
2020 mech_type
->length
: 0);
2021 arg
.mech_type
.GSS_OID_val
=
2022 (char *)(mech_type
!= GSS_C_NULL_OID
?
2023 mech_type
->elements
: 0);
2024 /* call the remote procedure */
2026 memset(&res
, 0, sizeof (res
));
2027 if (gss_inquire_cred_by_mech_1(&arg
, &res
, clnt
) != RPC_SUCCESS
) {
2030 * if the RPC call times out, null out all return arguments,
2031 * set minor_status to its maximum value, and return GSS_S_FAILURE
2034 if (minor_status
!= NULL
)
2035 *minor_status
= DEFAULT_MINOR_STAT
;
2036 return (GSS_S_FAILURE
);
2039 /* copy the rpc results into the return arguments */
2041 if (minor_status
!= NULL
)
2042 *minor_status
= res
.minor_status
;
2044 /* convert name from external to internal format */
2047 * free the memory allocated for the results and return with the status
2048 * received in the rpc call
2051 clnt_freeres(clnt
, xdr_gss_inquire_cred_by_mech_res
, (caddr_t
)&res
);
2052 return (res
.status
);
2057 kgss_inquire_cred_by_mech(minor_status
,
2061 OM_uint32
*minor_status
;
2062 gss_cred_id_t cred_handle
;
2067 OM_uint32 gssd_cred_verifier
;
2068 gssd_cred_id_t gssd_cred_handle
;
2070 gssd_cred_verifier
= KCRED_TO_CREDV(cred_handle
);
2071 gssd_cred_handle
= KCRED_TO_CRED(cred_handle
);
2073 return (kgss_inquire_cred_by_mech_wrapped(minor_status
,
2074 gssd_cred_handle
, gssd_cred_verifier
,
2079 kgsscred_expname_to_unix_cred(expName
, uidOut
, gidOut
, gids
, gidsLen
, uid
)
2080 const gss_buffer_t expName
;
2087 gsscred_expname_to_unix_cred_arg args
;
2088 gsscred_expname_to_unix_cred_res res
;
2090 /* check input/output parameters */
2091 if (expName
== NULL
|| expName
->value
== NULL
)
2092 return (GSS_S_CALL_INACCESSIBLE_READ
);
2095 return (GSS_S_CALL_INACCESSIBLE_WRITE
);
2097 /* NULL out output parameters */
2105 /* get the client handle to gssd */
2106 if ((clnt
= getgssd_handle()) == NULL
)
2108 clnt_pcreateerror(server
);
2109 return (GSS_S_FAILURE
);
2112 /* copy the procedure arguments */
2114 args
.expname
.GSS_BUFFER_T_val
= expName
->value
;
2115 args
.expname
.GSS_BUFFER_T_len
= expName
->length
;
2117 /* null out the return buffer and call the remote proc */
2118 memset(&res
, 0, sizeof (res
));
2120 if (gsscred_expname_to_unix_cred_1(&args
, &res
, clnt
) != RPC_SUCCESS
)
2122 return (GSS_S_FAILURE
);
2125 /* copy the results into the result parameters */
2126 if (res
.major
== GSS_S_COMPLETE
)
2131 if (gids
&& gidsLen
)
2133 *gids
= res
.gids
.GSSCRED_GIDS_val
;
2134 *gidsLen
= res
.gids
.GSSCRED_GIDS_len
;
2135 res
.gids
.GSSCRED_GIDS_val
= NULL
;
2136 res
.gids
.GSSCRED_GIDS_len
= 0;
2140 /* free RPC results */
2141 clnt_freeres(clnt
, xdr_gsscred_expname_to_unix_cred_res
, (caddr_t
)&res
);
2144 } /* kgsscred_expname_to_unix_cred */
2147 kgsscred_name_to_unix_cred(intName
, mechType
, uidOut
, gidOut
, gids
,
2149 const gss_name_t intName
;
2150 const gss_OID mechType
;
2157 gsscred_name_to_unix_cred_arg args
;
2158 gsscred_name_to_unix_cred_res res
;
2159 OM_uint32 major
, minor
;
2161 gss_buffer_desc flatName
= GSS_C_EMPTY_BUFFER
;
2164 /* check the input/output parameters */
2165 if (intName
== NULL
|| mechType
== NULL
)
2166 return (GSS_S_CALL_INACCESSIBLE_READ
);
2169 return (GSS_S_CALL_INACCESSIBLE_WRITE
);
2171 /* NULL out the output parameters */
2179 /* get the client handle to gssd */
2180 if ((clnt
= getgssd_handle()) == NULL
)
2182 clnt_pcreateerror(server
);
2183 return (GSS_S_FAILURE
);
2186 /* convert the name to flat representation */
2187 if ((major
= gss_display_name(&minor
, intName
, &flatName
, &nameOid
))
2193 /* set the rpc parameters */
2195 args
.pname
.GSS_BUFFER_T_len
= flatName
.length
;
2196 args
.pname
.GSS_BUFFER_T_val
= flatName
.value
;
2197 args
.name_type
.GSS_OID_len
= nameOid
->length
;
2198 args
.name_type
.GSS_OID_val
= nameOid
->elements
;
2199 args
.mech_type
.GSS_OID_len
= mechType
->length
;
2200 args
.mech_type
.GSS_OID_val
= mechType
->elements
;
2202 /* call the remote procedure */
2203 memset(&res
, 0, sizeof (res
));
2204 if (gsscred_name_to_unix_cred_1(&args
, &res
, clnt
) != RPC_SUCCESS
)
2206 gss_release_buffer(&minor
, &flatName
);
2207 return (GSS_S_FAILURE
);
2210 gss_release_buffer(&minor
, &flatName
);
2211 /* copy the output parameters on output */
2212 if (res
.major
== GSS_S_COMPLETE
)
2217 if (gids
&& gidsLen
)
2219 *gids
= res
.gids
.GSSCRED_GIDS_val
;
2220 *gidsLen
= res
.gids
.GSSCRED_GIDS_len
;
2221 res
.gids
.GSSCRED_GIDS_val
= NULL
;
2222 res
.gids
.GSSCRED_GIDS_len
= 0;
2226 /* delete RPC allocated memory */
2227 clnt_freeres(clnt
, xdr_gsscred_name_to_unix_cred_res
, (caddr_t
)&res
);
2230 } /* kgsscred_name_to_unix_cred */
2233 kgss_get_group_info(puid
, gidOut
, gids
, gidsLen
, uid
)
2240 gss_get_group_info_arg args
;
2241 gss_get_group_info_res res
;
2244 /* check the output parameters */
2245 if (gidOut
== NULL
|| gids
== NULL
|| gidsLen
== NULL
)
2246 return (GSS_S_CALL_INACCESSIBLE_WRITE
);
2248 /* get the client GSSD handle */
2249 if ((clnt
= getgssd_handle()) == NULL
)
2251 clnt_pcreateerror(server
);
2252 return (GSS_S_FAILURE
);
2255 /* set the input parameters */
2260 /* call the remote procedure */
2261 memset(&res
, 0, sizeof (res
));
2262 if (gss_get_group_info_1(&args
, &res
, clnt
) != RPC_SUCCESS
)
2264 return (GSS_S_FAILURE
);
2267 /* copy the results */
2268 if (res
.major
== GSS_S_COMPLETE
)
2271 *gids
= res
.gids
.GSSCRED_GIDS_val
;
2272 *gidsLen
= res
.gids
.GSSCRED_GIDS_len
;
2273 res
.gids
.GSSCRED_GIDS_val
= NULL
;
2274 res
.gids
.GSSCRED_GIDS_len
= 0;
2277 /* nothing to free */
2280 } /* kgss_get_group_info */
2283 kgss_export_sec_context_wrapped(minor_status
,
2286 gssd_context_verifier
)
2287 OM_uint32
*minor_status
;
2288 gssd_ctx_id_t
*context_handle
;
2289 gss_buffer_t output_token
;
2290 OM_uint32 gssd_context_verifier
;
2293 gss_export_sec_context_arg arg
;
2294 gss_export_sec_context_res res
;
2297 /* get the client handle to GSSD */
2299 if ((clnt
= getgssd_handle()) == NULL
) {
2300 clnt_pcreateerror(server
);
2301 return (GSS_S_FAILURE
);
2304 /* copy the procedure arguments into the rpc arg parameter */
2306 arg
.context_handle
.GSS_CTX_ID_T_len
= (uint_t
)sizeof (gssd_ctx_id_t
);
2307 arg
.context_handle
.GSS_CTX_ID_T_val
= (char *)context_handle
;
2308 arg
.gssd_context_verifier
= gssd_context_verifier
;
2310 /* call the remote procedure */
2312 memset(&res
, 0, sizeof (res
));
2313 if (gss_export_sec_context_1(&arg
, &res
, clnt
) != RPC_SUCCESS
) {
2316 * if the RPC call times out, null out all return arguments, set minor_status
2317 * to its maximum value, and return GSS_S_FAILURE
2320 if (minor_status
!= NULL
)
2321 *minor_status
= DEFAULT_MINOR_STAT
;
2322 if (context_handle
!= NULL
)
2323 *context_handle
= 0;
2324 if (output_token
!= NULL
)
2325 output_token
->length
= 0;
2327 return (GSS_S_FAILURE
);
2330 /* copy the rpc results into the return arguments */
2332 if (minor_status
!= NULL
)
2333 *minor_status
= res
.minor_status
;
2335 if (res
.context_handle
.GSS_CTX_ID_T_len
== 0)
2336 *context_handle
= 0;
2339 *((gssd_ctx_id_t
*)res
.context_handle
.GSS_CTX_ID_T_val
);
2341 if (output_token
!= NULL
&& res
.output_token
.GSS_BUFFER_T_val
!= NULL
) {
2342 output_token
->length
= res
.output_token
.GSS_BUFFER_T_len
;
2343 output_token
->value
=
2344 (void *) MALLOC(output_token
->length
);
2345 memcpy(output_token
->value
,
2346 res
.output_token
.GSS_BUFFER_T_val
,
2347 output_token
->length
);
2351 * free the memory allocated for the results and return with the status
2352 * received in the rpc call
2355 clnt_freeres(clnt
, xdr_gss_export_sec_context_res
, (caddr_t
)&res
);
2356 return (res
.status
);
2361 kgss_export_sec_context(minor_status
,
2364 OM_uint32
*minor_status
;
2365 gss_ctx_id_t
*context_handle
;
2366 gss_buffer_t output_token
;
2369 struct kgss_ctx
*kctx
;
2371 if (*context_handle
== GSS_C_NO_CONTEXT
) {
2372 return (GSS_S_NO_CONTEXT
);
2374 kctx
= KCTX_TO_KGSS_CTX(*context_handle
);
2376 err
= kgss_export_sec_context_wrapped(minor_status
,
2377 &kctx
->gssd_ctx
, output_token
,
2378 kctx
->gssd_ctx_verifier
);
2384 *context_handle
= GSS_C_NO_CONTEXT
;
2391 kgss_import_sec_context_wrapped(minor_status
,
2394 gssd_context_verifier
)
2395 OM_uint32
*minor_status
;
2396 gss_buffer_t input_token
;
2397 gss_ctx_id_t
*context_handle
;
2398 OM_uint32 gssd_context_verifier
;
2401 gss_import_sec_context_arg arg
;
2402 gss_import_sec_context_res res
;
2405 /* get the client handle to GSSD */
2407 if ((clnt
= getgssd_handle()) == NULL
) {
2408 clnt_pcreateerror(server
);
2409 return (GSS_S_FAILURE
);
2412 /* copy the procedure arguments into the rpc arg parameter */
2413 arg
.input_token
.GSS_BUFFER_T_len
= (uint_t
)
2414 (input_token
!= GSS_C_NO_BUFFER
? input_token
->length
: 0);
2415 arg
.input_token
.GSS_BUFFER_T_val
= (char *)
2416 (input_token
!= GSS_C_NO_BUFFER
? input_token
->value
: 0);
2417 arg
.gssd_context_verifier
= gssd_context_verifier
;
2420 /* call the remote procedure */
2422 memset(&res
, 0, sizeof (res
));
2423 if (gss_import_sec_context_1(&arg
, &res
, clnt
) != RPC_SUCCESS
) {
2426 * if the RPC call times out, null out all return arguments, set minor_status
2427 * to its maximum value, and return GSS_S_FAILURE
2430 if (minor_status
!= NULL
)
2431 *minor_status
= DEFAULT_MINOR_STAT
;
2432 if (context_handle
!= NULL
)
2433 *context_handle
= NULL
;
2435 return (GSS_S_FAILURE
);
2438 /* copy the rpc results into the return arguments */
2440 if (minor_status
!= NULL
)
2441 *minor_status
= res
.minor_status
;
2443 if (res
.context_handle
.GSS_CTX_ID_T_len
== 0)
2444 *context_handle
= NULL
;
2447 *((gss_ctx_id_t
*)res
.context_handle
.GSS_CTX_ID_T_val
);
2451 * free the memory allocated for the results and return with the status
2452 * received in the rpc call
2455 clnt_freeres(clnt
, xdr_gss_import_sec_context_res
, (caddr_t
)&res
);
2456 return (res
.status
);
2460 kgss_import_sec_context(minor_status
,
2463 OM_uint32
*minor_status
;
2464 gss_buffer_t input_token
;
2465 gss_ctx_id_t
*context_handle
;
2467 struct kgss_ctx
*kctx
;
2469 if (*context_handle
== GSS_C_NO_CONTEXT
) {
2470 kctx
= KGSS_ALLOC();
2471 *context_handle
= (gss_ctx_id_t
)kctx
;
2472 kctx
->gssd_ctx
= (OM_uint32
) GSS_C_NO_CONTEXT
;
2474 kctx
= (struct kgss_ctx
*)*context_handle
;
2475 return (kgss_import_sec_context_wrapped(minor_status
,
2476 input_token
, &kctx
->gssd_ctx
,
2477 KCTX_TO_CTXV(context_handle
)));
2481 #include <sys/modctl.h>
2483 static void *gss_clnt
= NULL
;
2487 char *name
; /* just put something here */
2491 static void *gssd_state
;
2493 static int gssd_attach(dev_info_t
*dip
, ddi_attach_cmd_t cmd
)
2495 /* cmn_err(CE_NOTE, "In gssd_attach"); */
2498 if (ddi_create_minor_node(dip
, "gssd", S_IFCHR
, 0, "gssd", 0)
2500 ddi_remove_minor_node(dip
, NULL
);
2501 return (DDI_FAILURE
);
2503 return (DDI_SUCCESS
);
2506 return (DDI_FAILURE
);
2510 static int gssd_getinfo(dev_info_t
*dip
, ddi_info_cmd_t infocmd
,
2511 void *arg
, void **result
)
2516 /* cmn_err(CE_NOTE, "In gssd_getinfo"); */
2519 case DDI_INFO_DEVT2INSTANCE
:
2521 *result
= (void *) getminor(dev
);
2522 error
= DDI_SUCCESS
;
2525 case DDI_INFO_DEVT2DEVINFO
:
2526 /* cmn_err(CE_NOTE, "getinfo wants devinfo"); */
2528 error
= DDI_FAILURE
;
2534 static int gssd_identify(dev_info_t
*dip
)
2536 /* cmn_err(CE_NOTE, "in gssd_identify"); */
2537 if (strcmp(ddi_get_name(dip
), "gssd") == 0)
2538 return (DDI_IDENTIFIED
);
2540 return (DDI_NOT_IDENTIFIED
);
2543 static int gssd_probe(dev_info_t
*dip
)
2545 /* cmn_err(CE_NOTE, "In gssd_probe"); */
2547 return (DDI_PROBE_SUCCESS
);
2550 static int gssd_open(dev_t
*devp
, int flag
, int otyp
, cred_t
*credp
)
2552 /* cmn_err (CE_NOTE, "In gssd_open"); */
2553 if (otyp
!= OTYP_CHR
)
2556 gss_clnt
= getgssd_handle();
2560 static int gssd_close(dev_t dev
, int flag
, int otyp
, cred_t
*credp
)
2562 /* cmn_err(CE_NOTE, "In gssd_close"); */
2563 killgssd_handle(gss_clnt
);
2567 static int gssd_write(dev_t dev
, struct uio
*uiop
, cred_t
*credp
)
2572 /* cmn_err(CE_NOTE, "In gssd_write"); */
2573 bzero(buffer
, 1024);
2575 uiomove(buffer
, 1024, UIO_WRITE
, uiop
);
2576 len
= strlen(buffer
);
2578 if (buffer
[len
-1] == '\n')
2579 buffer
[--len
] = '\0';
2581 cmn_err(CE_NOTE
, "Got command: (%d) \"%s\"", len
, buffer
);
2582 do_gssdtest(buffer
);
2586 static struct cb_ops gssd_cb_ops
= {
2587 gssd_open
, /* cb_open */
2588 gssd_close
, /* cb_close */
2589 nodev
, /* cb_strategy */
2590 nodev
, /* cb_print */
2591 nodev
, /* cb_dump */
2592 nulldev
, /* cb_read */
2593 gssd_write
, /* cb_write */
2594 nodev
, /* cb_ioctl */
2595 nodev
, /* cb_devmap */
2596 nodev
, /* cb_mmap */
2597 nodev
, /* cb_segmap */
2598 nochpoll
, /* cb_chpoll */
2599 ddi_prop_op
, /* cb_prop_op */
2600 NULL
, /* cb_stream */
2601 (int)(D_NEW
|D_MP
) /* cb_flag */
2604 static struct dev_ops gssd_ops
= {
2605 DEVO_REV
, /* devo_rev */
2606 0, /* devo_refcnt */
2607 gssd_getinfo
, /* devo_getinfo */
2608 gssd_identify
, /* devo_identify */
2609 nulldev
, /* devo_probe */
2610 gssd_attach
, /* devo_attach */
2611 nulldev
, /* devo_detach */
2612 nodev
, /* devo_reset */
2613 &gssd_cb_ops
, /* devo_cb_ops */
2614 NULL
/* devo_bus_ops */
2617 extern struct mod_ops mod_driverops
;
2619 static struct modldrv modlmisc
= {
2621 "GSSD DRV Client Module",
2626 static struct modlmisc modlmisc
= {
2628 "GSSD Client Module"
2632 static struct modlinkage modlinkage
= {
2638 char _depends_on
[] = "strmod/rpcmod misc/tlimod";
2644 if ((status
= ddi_soft_state_init(&gssd_state
,
2645 sizeof (gssd_devstate_t
), 1)) != 0)
2648 if ((status
= mod_install((struct modlinkage
*)&modlinkage
)) != 0)
2649 ddi_soft_state_fini(&gssd_state
);
2651 cmn_err(CE_NOTE
, "gssd: I'm in the kernel: %d.", status
);
2659 killgssd_handle(gss_clnt
);
2660 cmn_err(CE_NOTE
, "gssd: Handle destroyed.. leaving module.");
2662 if ((status
= mod_remove(&modlinkage
)) != 0)
2665 ddi_soft_state_fini(&gssd_state
);
2670 struct modinfo
*modinfop
;
2672 return (mod_info(&modlinkage
, modinfop
));