1ba7b222eSGlenn Barry /*
2*12b65585SGordon Ross  * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
3ba7b222eSGlenn Barry  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
4ba7b222eSGlenn Barry  * Use is subject to license terms.
5ba7b222eSGlenn Barry  */
6ba7b222eSGlenn Barry /* -*- mode: c; indent-tabs-mode: nil -*- */
77c478bd9Sstevel@tonic-gate /*
87c478bd9Sstevel@tonic-gate  * Copyright 1993 by OpenVision Technologies, Inc.
9ba7b222eSGlenn Barry  *
107c478bd9Sstevel@tonic-gate  * Permission to use, copy, modify, distribute, and sell this software
117c478bd9Sstevel@tonic-gate  * and its documentation for any purpose is hereby granted without fee,
127c478bd9Sstevel@tonic-gate  * provided that the above copyright notice appears in all copies and
137c478bd9Sstevel@tonic-gate  * that both that copyright notice and this permission notice appear in
147c478bd9Sstevel@tonic-gate  * supporting documentation, and that the name of OpenVision not be used
157c478bd9Sstevel@tonic-gate  * in advertising or publicity pertaining to distribution of the software
167c478bd9Sstevel@tonic-gate  * without specific, written prior permission. OpenVision makes no
177c478bd9Sstevel@tonic-gate  * representations about the suitability of this software for any
187c478bd9Sstevel@tonic-gate  * purpose.  It is provided "as is" without express or implied warranty.
19ba7b222eSGlenn Barry  *
207c478bd9Sstevel@tonic-gate  * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
217c478bd9Sstevel@tonic-gate  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
227c478bd9Sstevel@tonic-gate  * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
237c478bd9Sstevel@tonic-gate  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
247c478bd9Sstevel@tonic-gate  * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
257c478bd9Sstevel@tonic-gate  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
267c478bd9Sstevel@tonic-gate  * PERFORMANCE OF THIS SOFTWARE.
277c478bd9Sstevel@tonic-gate  */
28ba7b222eSGlenn Barry /*
29ba7b222eSGlenn Barry  * Copyright (c) 2006-2008, Novell, Inc.
30ba7b222eSGlenn Barry  * All rights reserved.
31ba7b222eSGlenn Barry  *
32ba7b222eSGlenn Barry  * Redistribution and use in source and binary forms, with or without
33ba7b222eSGlenn Barry  * modification, are permitted provided that the following conditions are met:
34ba7b222eSGlenn Barry  *
35ba7b222eSGlenn Barry  *   * Redistributions of source code must retain the above copyright notice,
36ba7b222eSGlenn Barry  *       this list of conditions and the following disclaimer.
37ba7b222eSGlenn Barry  *   * Redistributions in binary form must reproduce the above copyright
38ba7b222eSGlenn Barry  *       notice, this list of conditions and the following disclaimer in the
39ba7b222eSGlenn Barry  *       documentation and/or other materials provided with the distribution.
40ba7b222eSGlenn Barry  *   * The copyright holder's name is not used to endorse or promote products
41ba7b222eSGlenn Barry  *       derived from this software without specific prior written permission.
42ba7b222eSGlenn Barry  *
43ba7b222eSGlenn Barry  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
44ba7b222eSGlenn Barry  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
45ba7b222eSGlenn Barry  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46ba7b222eSGlenn Barry  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
47ba7b222eSGlenn Barry  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
48ba7b222eSGlenn Barry  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
49ba7b222eSGlenn Barry  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
50ba7b222eSGlenn Barry  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
51ba7b222eSGlenn Barry  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
52ba7b222eSGlenn Barry  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
53ba7b222eSGlenn Barry  * POSSIBILITY OF SUCH DAMAGE.
54ba7b222eSGlenn Barry  */
55ba7b222eSGlenn Barry /*
56ba7b222eSGlenn Barry  * Copyright (c) 2006-2008, Novell, Inc.
57ba7b222eSGlenn Barry  * All rights reserved.
58ba7b222eSGlenn Barry  *
59ba7b222eSGlenn Barry  * Redistribution and use in source and binary forms, with or without
60ba7b222eSGlenn Barry  * modification, are permitted provided that the following conditions are met:
61ba7b222eSGlenn Barry  *
62ba7b222eSGlenn Barry  *   * Redistributions of source code must retain the above copyright notice,
63ba7b222eSGlenn Barry  *       this list of conditions and the following disclaimer.
64ba7b222eSGlenn Barry  *   * Redistributions in binary form must reproduce the above copyright
65ba7b222eSGlenn Barry  *       notice, this list of conditions and the following disclaimer in the
66ba7b222eSGlenn Barry  *       documentation and/or other materials provided with the distribution.
67ba7b222eSGlenn Barry  *   * The copyright holder's name is not used to endorse or promote products
68ba7b222eSGlenn Barry  *       derived from this software without specific prior written permission.
69ba7b222eSGlenn Barry  *
70ba7b222eSGlenn Barry  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
71ba7b222eSGlenn Barry  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
72ba7b222eSGlenn Barry  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
73ba7b222eSGlenn Barry  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
74ba7b222eSGlenn Barry  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
75ba7b222eSGlenn Barry  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
76ba7b222eSGlenn Barry  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
77ba7b222eSGlenn Barry  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
78ba7b222eSGlenn Barry  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
79ba7b222eSGlenn Barry  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
80ba7b222eSGlenn Barry  * POSSIBILITY OF SUCH DAMAGE.
81ba7b222eSGlenn Barry  */
827c478bd9Sstevel@tonic-gate 
83ab9b2e15Sgtb #include "gssapiP_krb5.h"
84ba7b222eSGlenn Barry #include "mechglueP.h" /* SUNW17PACresync */
857c478bd9Sstevel@tonic-gate 
867c478bd9Sstevel@tonic-gate OM_uint32
krb5_gss_inquire_context(minor_status,context_handle,initiator_name,acceptor_name,lifetime_rec,mech_type,ret_flags,locally_initiated,opened)87ba7b222eSGlenn Barry krb5_gss_inquire_context(minor_status, context_handle, initiator_name,
88ba7b222eSGlenn Barry                          acceptor_name, lifetime_rec, mech_type, ret_flags,
89ba7b222eSGlenn Barry                          locally_initiated, opened)
90ba7b222eSGlenn Barry     OM_uint32 *minor_status;
91ba7b222eSGlenn Barry     gss_ctx_id_t context_handle;
92ba7b222eSGlenn Barry     gss_name_t *initiator_name;
93ba7b222eSGlenn Barry     gss_name_t *acceptor_name;
94ba7b222eSGlenn Barry     OM_uint32 *lifetime_rec;
95ba7b222eSGlenn Barry     gss_OID *mech_type;
96ba7b222eSGlenn Barry     OM_uint32 *ret_flags;
97ba7b222eSGlenn Barry     int *locally_initiated;
98ba7b222eSGlenn Barry     int *opened;
997c478bd9Sstevel@tonic-gate {
100ba7b222eSGlenn Barry     krb5_context context;
101ba7b222eSGlenn Barry     krb5_error_code code;
102ba7b222eSGlenn Barry     krb5_gss_ctx_id_rec *ctx;
103ba7b222eSGlenn Barry     krb5_principal initiator, acceptor;
104ba7b222eSGlenn Barry     krb5_timestamp now;
105ba7b222eSGlenn Barry     krb5_deltat lifetime;
106ba7b222eSGlenn Barry 
107ba7b222eSGlenn Barry     if (initiator_name)
108ba7b222eSGlenn Barry         *initiator_name = (gss_name_t) NULL;
109ba7b222eSGlenn Barry     if (acceptor_name)
110ba7b222eSGlenn Barry         *acceptor_name = (gss_name_t) NULL;
111ba7b222eSGlenn Barry 
112ba7b222eSGlenn Barry     /* validate the context handle */
113ba7b222eSGlenn Barry     if (! kg_validate_ctx_id(context_handle)) {
114ba7b222eSGlenn Barry         *minor_status = (OM_uint32) G_VALIDATE_FAILED;
115ba7b222eSGlenn Barry         return(GSS_S_NO_CONTEXT);
116ba7b222eSGlenn Barry     }
117ba7b222eSGlenn Barry 
118ba7b222eSGlenn Barry     ctx = (krb5_gss_ctx_id_rec *) context_handle;
119ba7b222eSGlenn Barry 
120ba7b222eSGlenn Barry     if (! ctx->established) {
121ba7b222eSGlenn Barry         *minor_status = KG_CTX_INCOMPLETE;
122ba7b222eSGlenn Barry         return(GSS_S_NO_CONTEXT);
123ba7b222eSGlenn Barry     }
124ba7b222eSGlenn Barry 
125ba7b222eSGlenn Barry     initiator = NULL;
126ba7b222eSGlenn Barry     acceptor = NULL;
127ba7b222eSGlenn Barry     context = ctx->k5_context;
128ba7b222eSGlenn Barry 
129ba7b222eSGlenn Barry     if ((code = krb5_timeofday(context, &now))) {
130ba7b222eSGlenn Barry         *minor_status = code;
131ba7b222eSGlenn Barry         save_error_info(*minor_status, context);
132ba7b222eSGlenn Barry         return(GSS_S_FAILURE);
133ba7b222eSGlenn Barry     }
134ba7b222eSGlenn Barry 
135ba7b222eSGlenn Barry 
136ba7b222eSGlenn Barry     /* SUNW17PACresync - should be krb_times.endtime (revisit) */
137ba7b222eSGlenn Barry     if ((lifetime = ctx->endtime - now) < 0)
138ba7b222eSGlenn Barry         lifetime = 0;
139ba7b222eSGlenn Barry 
140ba7b222eSGlenn Barry     if (initiator_name) {
141ba7b222eSGlenn Barry         if ((code = krb5_copy_principal(context,
142ba7b222eSGlenn Barry                                         ctx->initiate?ctx->here:ctx->there,
143ba7b222eSGlenn Barry                                         &initiator))) {
144ba7b222eSGlenn Barry             *minor_status = code;
145ba7b222eSGlenn Barry             save_error_info(*minor_status, context);
146ba7b222eSGlenn Barry             return(GSS_S_FAILURE);
147ba7b222eSGlenn Barry         }
148ba7b222eSGlenn Barry         if (! kg_save_name((gss_name_t) initiator)) {
149ba7b222eSGlenn Barry             krb5_free_principal(context, initiator);
150ba7b222eSGlenn Barry             *minor_status = (OM_uint32) G_VALIDATE_FAILED;
151ba7b222eSGlenn Barry             return(GSS_S_FAILURE);
152ba7b222eSGlenn Barry         }
153ba7b222eSGlenn Barry     }
154ba7b222eSGlenn Barry 
155ba7b222eSGlenn Barry     if (acceptor_name) {
156ba7b222eSGlenn Barry         if ((code = krb5_copy_principal(context,
157ba7b222eSGlenn Barry                                         ctx->initiate?ctx->there:ctx->here,
158ba7b222eSGlenn Barry                                         &acceptor))) {
159ba7b222eSGlenn Barry             if (initiator) krb5_free_principal(context, initiator);
160ba7b222eSGlenn Barry             *minor_status = code;
161ba7b222eSGlenn Barry             save_error_info(*minor_status, context);
162ba7b222eSGlenn Barry             return(GSS_S_FAILURE);
163ba7b222eSGlenn Barry         }
164ba7b222eSGlenn Barry         if (! kg_save_name((gss_name_t) acceptor)) {
165ba7b222eSGlenn Barry             krb5_free_principal(context, acceptor);
166ba7b222eSGlenn Barry             if (initiator) {
167ba7b222eSGlenn Barry                 kg_delete_name((gss_name_t) initiator);
168ba7b222eSGlenn Barry                 krb5_free_principal(context, initiator);
169ba7b222eSGlenn Barry             }
170ba7b222eSGlenn Barry             *minor_status = (OM_uint32) G_VALIDATE_FAILED;
171ba7b222eSGlenn Barry             return(GSS_S_FAILURE);
172ba7b222eSGlenn Barry         }
173ba7b222eSGlenn Barry     }
174ba7b222eSGlenn Barry 
175ba7b222eSGlenn Barry     if (initiator_name)
176ba7b222eSGlenn Barry         *initiator_name = (gss_name_t) initiator;
177ba7b222eSGlenn Barry 
178ba7b222eSGlenn Barry     if (acceptor_name)
179ba7b222eSGlenn Barry         *acceptor_name = (gss_name_t) acceptor;
180ba7b222eSGlenn Barry 
181ba7b222eSGlenn Barry     if (lifetime_rec)
182ba7b222eSGlenn Barry         *lifetime_rec = lifetime;
183ba7b222eSGlenn Barry 
184ba7b222eSGlenn Barry     if (mech_type)
185ba7b222eSGlenn Barry         *mech_type = (gss_OID) ctx->mech_used;
186ba7b222eSGlenn Barry 
187ba7b222eSGlenn Barry     if (ret_flags)
188ba7b222eSGlenn Barry         *ret_flags = ctx->gss_flags;
189ba7b222eSGlenn Barry 
190ba7b222eSGlenn Barry     if (locally_initiated)
191ba7b222eSGlenn Barry         *locally_initiated = ctx->initiate;
192ba7b222eSGlenn Barry 
193ba7b222eSGlenn Barry     if (opened)
194ba7b222eSGlenn Barry         *opened = ctx->established;
195ba7b222eSGlenn Barry 
196ba7b222eSGlenn Barry     *minor_status = 0;
197ba7b222eSGlenn Barry 
198ba7b222eSGlenn Barry     return((lifetime == 0)?GSS_S_CONTEXT_EXPIRED:GSS_S_COMPLETE);
1997c478bd9Sstevel@tonic-gate }
200ba7b222eSGlenn Barry 
201ba7b222eSGlenn Barry OM_uint32
gss_krb5int_inq_session_key(OM_uint32 * minor_status,const gss_ctx_id_t context_handle,const gss_OID desired_object,gss_buffer_set_t * data_set)202ba7b222eSGlenn Barry gss_krb5int_inq_session_key(
203ba7b222eSGlenn Barry     OM_uint32 *minor_status,
204ba7b222eSGlenn Barry     const gss_ctx_id_t context_handle,
205ba7b222eSGlenn Barry     const gss_OID desired_object,
206ba7b222eSGlenn Barry     gss_buffer_set_t *data_set)
207ba7b222eSGlenn Barry {
208ba7b222eSGlenn Barry     krb5_gss_ctx_id_rec *ctx;
209ba7b222eSGlenn Barry     krb5_keyblock *key;
210ba7b222eSGlenn Barry     gss_buffer_desc keyvalue, keyinfo;
211ba7b222eSGlenn Barry     OM_uint32 major_status, minor;
212ba7b222eSGlenn Barry     unsigned char oid_buf[GSS_KRB5_SESSION_KEY_ENCTYPE_OID_LENGTH + 6];
213ba7b222eSGlenn Barry     gss_OID_desc oid;
214ba7b222eSGlenn Barry 
215ba7b222eSGlenn Barry     ctx = (krb5_gss_ctx_id_rec *) context_handle;
216ba7b222eSGlenn Barry     key = ctx->have_acceptor_subkey ? ctx->acceptor_subkey : ctx->subkey;
217ba7b222eSGlenn Barry 
218ba7b222eSGlenn Barry     keyvalue.value = key->contents;
219ba7b222eSGlenn Barry     keyvalue.length = key->length;
220ba7b222eSGlenn Barry 
221ba7b222eSGlenn Barry     major_status = generic_gss_add_buffer_set_member(minor_status, &keyvalue, data_set);
222ba7b222eSGlenn Barry     if (GSS_ERROR(major_status))
223ba7b222eSGlenn Barry         goto cleanup;
224ba7b222eSGlenn Barry 
225ba7b222eSGlenn Barry     oid.elements = oid_buf;
226ba7b222eSGlenn Barry     oid.length = sizeof(oid_buf);
227ba7b222eSGlenn Barry 
228ba7b222eSGlenn Barry     major_status = generic_gss_oid_compose(minor_status,
229ba7b222eSGlenn Barry                                            GSS_KRB5_SESSION_KEY_ENCTYPE_OID,
230ba7b222eSGlenn Barry                                            GSS_KRB5_SESSION_KEY_ENCTYPE_OID_LENGTH,
231ba7b222eSGlenn Barry                                            key->enctype,
232ba7b222eSGlenn Barry                                            &oid);
233ba7b222eSGlenn Barry     if (GSS_ERROR(major_status))
234ba7b222eSGlenn Barry         goto cleanup;
235ba7b222eSGlenn Barry 
236ba7b222eSGlenn Barry     keyinfo.value = oid.elements;
237ba7b222eSGlenn Barry     keyinfo.length = oid.length;
238ba7b222eSGlenn Barry 
239ba7b222eSGlenn Barry     major_status = generic_gss_add_buffer_set_member(minor_status, &keyinfo, data_set);
240ba7b222eSGlenn Barry     if (GSS_ERROR(major_status))
241ba7b222eSGlenn Barry         goto cleanup;
242ba7b222eSGlenn Barry 
243ba7b222eSGlenn Barry     return GSS_S_COMPLETE;
244ba7b222eSGlenn Barry 
245ba7b222eSGlenn Barry cleanup:
246ba7b222eSGlenn Barry     if (*data_set != GSS_C_NO_BUFFER_SET) {
247ba7b222eSGlenn Barry         if ((*data_set)->count != 0)
248ba7b222eSGlenn Barry             memset((*data_set)->elements[0].value, 0, (*data_set)->elements[0].length);
249ba7b222eSGlenn Barry         gss_release_buffer_set(&minor, data_set);
250ba7b222eSGlenn Barry     }
251ba7b222eSGlenn Barry 
252ba7b222eSGlenn Barry     return major_status;
253ba7b222eSGlenn Barry }
254ba7b222eSGlenn Barry 
255ba7b222eSGlenn Barry OM_uint32
gss_krb5int_extract_authz_data_from_sec_context(OM_uint32 * minor_status,const gss_ctx_id_t context_handle,const gss_OID desired_object,gss_buffer_set_t * data_set)256ba7b222eSGlenn Barry gss_krb5int_extract_authz_data_from_sec_context(
257ba7b222eSGlenn Barry    OM_uint32 *minor_status,
258ba7b222eSGlenn Barry    const gss_ctx_id_t context_handle,
259ba7b222eSGlenn Barry    const gss_OID desired_object,
260ba7b222eSGlenn Barry    gss_buffer_set_t *data_set)
261ba7b222eSGlenn Barry {
262*12b65585SGordon Ross     gss_buffer_desc ad_data;
263ba7b222eSGlenn Barry     OM_uint32 major_status;
264*12b65585SGordon Ross     krb5_error_code code;
265ba7b222eSGlenn Barry     krb5_gss_ctx_id_rec *ctx;
266ba7b222eSGlenn Barry     int ad_type = 0;
267*12b65585SGordon Ross     int i, j;
268ba7b222eSGlenn Barry 
269ba7b222eSGlenn Barry     *data_set = GSS_C_NO_BUFFER_SET;
270ba7b222eSGlenn Barry 
271ba7b222eSGlenn Barry     ctx = (krb5_gss_ctx_id_rec *) context_handle;
272ba7b222eSGlenn Barry 
273ba7b222eSGlenn Barry     major_status = generic_gss_oid_decompose(minor_status,
274ba7b222eSGlenn Barry                                              GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_OID,
275ba7b222eSGlenn Barry                                              GSS_KRB5_EXTRACT_AUTHZ_DATA_FROM_SEC_CONTEXT_OID_LENGTH,
276ba7b222eSGlenn Barry                                              desired_object,
277ba7b222eSGlenn Barry                                              &ad_type);
278ba7b222eSGlenn Barry     if (major_status != GSS_S_COMPLETE || ad_type == 0) {
279ba7b222eSGlenn Barry         *minor_status = ENOENT;
280ba7b222eSGlenn Barry         return major_status; /* SUNW17PACresync */
281ba7b222eSGlenn Barry     }
282ba7b222eSGlenn Barry 
283ba7b222eSGlenn Barry     if (ctx->authdata != NULL) {
284ba7b222eSGlenn Barry         for (i = 0; ctx->authdata[i] != NULL; i++) {
285ba7b222eSGlenn Barry             if (ctx->authdata[i]->ad_type == ad_type) {
286ba7b222eSGlenn Barry 
287ba7b222eSGlenn Barry                 ad_data.length = ctx->authdata[i]->length;
288ba7b222eSGlenn Barry                 ad_data.value = ctx->authdata[i]->contents;
289ba7b222eSGlenn Barry 
290ba7b222eSGlenn Barry                 major_status = generic_gss_add_buffer_set_member(minor_status,
291ba7b222eSGlenn Barry                                                                  &ad_data, data_set);
292ba7b222eSGlenn Barry                 if (GSS_ERROR(major_status))
293ba7b222eSGlenn Barry                     break;
294*12b65585SGordon Ross             } else if (ctx->authdata[i]->ad_type == KRB5_AUTHDATA_IF_RELEVANT) {
295*12b65585SGordon Ross                 /*
296*12b65585SGordon Ross                  * Solaris Kerberos (illumos)
297*12b65585SGordon Ross                  * Unwrap the AD-IF-RELEVANT object and look inside.
298*12b65585SGordon Ross                  */
299*12b65585SGordon Ross                 krb5_authdata **ad_if_relevant = NULL;
300*12b65585SGordon Ross                 code = krb5_decode_authdata_container(ctx->k5_context,
301*12b65585SGordon Ross                                                       KRB5_AUTHDATA_IF_RELEVANT,
302*12b65585SGordon Ross                                                       ctx->authdata[i],
303*12b65585SGordon Ross                                                       &ad_if_relevant);
304*12b65585SGordon Ross                 if (code != 0)
305*12b65585SGordon Ross                     continue;
306*12b65585SGordon Ross 
307*12b65585SGordon Ross                 for (j = 0; ad_if_relevant[j] != NULL; j++) {
308*12b65585SGordon Ross                     if (ad_if_relevant[j]->ad_type == ad_type) {
309*12b65585SGordon Ross                         ad_data.length = ad_if_relevant[j]->length;
310*12b65585SGordon Ross                         ad_data.value = ad_if_relevant[j]->contents;
311*12b65585SGordon Ross 
312*12b65585SGordon Ross                         major_status = generic_gss_add_buffer_set_member(minor_status,
313*12b65585SGordon Ross                                                                          &ad_data, data_set);
314*12b65585SGordon Ross                         if (GSS_ERROR(major_status)) {
315*12b65585SGordon Ross                             krb5_free_authdata(ctx->k5_context, ad_if_relevant);
316*12b65585SGordon Ross                             goto break2;
317*12b65585SGordon Ross                         }
318*12b65585SGordon Ross                     }
319*12b65585SGordon Ross                 }
320*12b65585SGordon Ross                 krb5_free_authdata(ctx->k5_context, ad_if_relevant);
321*12b65585SGordon Ross                 /* Solaris Kerberos (illumos) */
322ba7b222eSGlenn Barry             }
323ba7b222eSGlenn Barry         }
324ba7b222eSGlenn Barry     }
325ba7b222eSGlenn Barry 
326*12b65585SGordon Ross break2:
327ba7b222eSGlenn Barry     if (GSS_ERROR(major_status)) {
328ba7b222eSGlenn Barry         OM_uint32 tmp;
329ba7b222eSGlenn Barry 
330ba7b222eSGlenn Barry         generic_gss_release_buffer_set(&tmp, data_set);
331ba7b222eSGlenn Barry     }
332ba7b222eSGlenn Barry 
333ba7b222eSGlenn Barry     return major_status;
334ba7b222eSGlenn Barry }
335ba7b222eSGlenn Barry 
336ba7b222eSGlenn Barry OM_uint32
gss_krb5int_extract_authtime_from_sec_context(OM_uint32 * minor_status,const gss_ctx_id_t context_handle,const gss_OID desired_oid,gss_buffer_set_t * data_set)337ba7b222eSGlenn Barry gss_krb5int_extract_authtime_from_sec_context(OM_uint32 *minor_status,
338ba7b222eSGlenn Barry                                               const gss_ctx_id_t context_handle,
339ba7b222eSGlenn Barry                                               const gss_OID desired_oid,
340ba7b222eSGlenn Barry                                               gss_buffer_set_t *data_set)
341ba7b222eSGlenn Barry {
342ba7b222eSGlenn Barry     krb5_gss_ctx_id_rec *ctx;
343ba7b222eSGlenn Barry     gss_buffer_desc rep;
344ba7b222eSGlenn Barry 
345ba7b222eSGlenn Barry     ctx = (krb5_gss_ctx_id_rec *) context_handle;
346ba7b222eSGlenn Barry 
347ba7b222eSGlenn Barry     rep.value = &ctx->krb_times.authtime;
348ba7b222eSGlenn Barry     rep.length = sizeof(ctx->krb_times.authtime);
349ba7b222eSGlenn Barry 
350ba7b222eSGlenn Barry     return generic_gss_add_buffer_set_member(minor_status, &rep, data_set);
351ba7b222eSGlenn Barry }
352ba7b222eSGlenn Barry 
353