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 (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
26 * glue routine for gss_init_sec_context
28 #include <mechglueP.h>
29 #include "gssapiP_generic.h"
35 val_init_sec_ctx_args(
36 OM_uint32
*minor_status
,
37 gss_ctx_id_t
*context_handle
,
38 gss_name_t target_name
,
39 gss_OID
*actual_mech_type
,
40 gss_buffer_t output_token
)
43 /* Initialize outputs. */
45 if (minor_status
!= NULL
)
48 if (actual_mech_type
!= NULL
)
49 *actual_mech_type
= GSS_C_NO_OID
;
51 if (output_token
!= GSS_C_NO_BUFFER
) {
52 output_token
->length
= 0;
53 output_token
->value
= NULL
;
56 /* Validate arguments. */
58 if (minor_status
== NULL
)
59 return (GSS_S_CALL_INACCESSIBLE_WRITE
);
61 if (context_handle
== NULL
)
62 return (GSS_S_CALL_INACCESSIBLE_WRITE
| GSS_S_NO_CONTEXT
);
64 if (target_name
== NULL
)
65 return (GSS_S_CALL_INACCESSIBLE_READ
| GSS_S_BAD_NAME
);
67 if (output_token
== NULL
)
68 return (GSS_S_CALL_INACCESSIBLE_WRITE
);
70 return (GSS_S_COMPLETE
);
74 gss_init_sec_context(minor_status
,
88 OM_uint32
* minor_status
;
89 const gss_cred_id_t claimant_cred_handle
;
90 gss_ctx_id_t
*context_handle
;
91 const gss_name_t target_name
;
92 const gss_OID req_mech_type
;
95 const gss_channel_bindings_t input_chan_bindings
;
96 const gss_buffer_t input_token
;
97 gss_OID
* actual_mech_type
;
98 gss_buffer_t output_token
;
99 OM_uint32
* ret_flags
;
100 OM_uint32
* time_rec
;
103 OM_uint32 status
, temp_minor_status
;
104 gss_union_name_t union_name
;
105 gss_union_cred_t union_cred
;
106 gss_name_t internal_name
;
107 gss_union_ctx_id_t union_ctx_id
;
108 gss_OID mech_type
= GSS_C_NULL_OID
;
110 gss_cred_id_t input_cred_handle
;
112 status
= val_init_sec_ctx_args(minor_status
,
117 if (status
!= GSS_S_COMPLETE
)
121 mech_type
= (gss_OID
)req_mech_type
;
123 union_name
= (gss_union_name_t
)target_name
;
126 * obtain the gss mechanism information for the requested
127 * mechanism. If mech_type is NULL, set it to the resultant
130 mech
= __gss_get_mechanism(mech_type
);
132 return (GSS_S_BAD_MECH
);
134 if (mech
->gss_init_sec_context
== NULL
)
135 return (GSS_S_UNAVAILABLE
);
137 if (mech_type
== GSS_C_NULL_OID
)
138 mech_type
= &mech
->mech_type
;
141 * If target_name is mechanism_specific, then it must match the
142 * mech_type that we're about to use. Otherwise, do an import on
143 * the external_name form of the target name.
145 if (union_name
->mech_type
&&
146 g_OID_equal(union_name
->mech_type
, mech_type
)) {
147 internal_name
= union_name
->mech_name
;
149 if ((status
= __gss_import_internal_name(minor_status
,
150 mech_type
, union_name
,
151 &internal_name
)) != GSS_S_COMPLETE
)
156 * if context_handle is GSS_C_NO_CONTEXT, allocate a union context
157 * descriptor to hold the mech type information as well as the
158 * underlying mechanism context handle. Otherwise, cast the
159 * value of *context_handle to the union context variable.
161 if (*context_handle
== GSS_C_NO_CONTEXT
) {
162 status
= GSS_S_FAILURE
;
163 union_ctx_id
= (gss_union_ctx_id_t
)
164 malloc(sizeof (gss_union_ctx_id_desc
));
165 if (union_ctx_id
== NULL
)
168 if (generic_gss_copy_oid(&temp_minor_status
, mech_type
,
169 &union_ctx_id
->mech_type
) != GSS_S_COMPLETE
) {
174 /* copy the supplied context handle */
175 union_ctx_id
->internal_ctx_id
= *context_handle
;
177 union_ctx_id
= (gss_union_ctx_id_t
)*context_handle
;
180 * get the appropriate cred handle from the union cred struct.
181 * defaults to GSS_C_NO_CREDENTIAL if there is no cred, which will
182 * use the default credential.
184 union_cred
= (gss_union_cred_t
)claimant_cred_handle
;
185 input_cred_handle
= __gss_get_mechanism_cred(union_cred
, mech_type
);
188 * now call the approprate underlying mechanism routine
191 status
= mech
->gss_init_sec_context(
195 &union_ctx_id
->internal_ctx_id
,
207 if (status
!= GSS_S_COMPLETE
&& status
!= GSS_S_CONTINUE_NEEDED
) {
209 * the spec says (the preferred) method is to delete all
210 * context info on the first call to init, and on all
211 * subsequent calls make the caller responsible for
212 * calling gss_delete_sec_context
214 map_error(minor_status
, mech
);
215 if (*context_handle
== GSS_C_NO_CONTEXT
) {
216 free(union_ctx_id
->mech_type
->elements
);
217 free(union_ctx_id
->mech_type
);
220 } else if (*context_handle
== GSS_C_NO_CONTEXT
)
221 *context_handle
= (gss_ctx_id_t
)union_ctx_id
;
224 if (union_name
->mech_name
== NULL
||
225 union_name
->mech_name
!= internal_name
) {
226 (void) __gss_release_internal_name(&temp_minor_status
,
227 mech_type
, &internal_name
);