1c19800e8SDoug Rabson /*
2c19800e8SDoug Rabson  * Copyright (c) 1997, 2003 Kungliga Tekniska Högskolan
3c19800e8SDoug Rabson  * (Royal Institute of Technology, Stockholm, Sweden).
4c19800e8SDoug Rabson  * All rights reserved.
5c19800e8SDoug Rabson  *
6c19800e8SDoug Rabson  * Redistribution and use in source and binary forms, with or without
7c19800e8SDoug Rabson  * modification, are permitted provided that the following conditions
8c19800e8SDoug Rabson  * are met:
9c19800e8SDoug Rabson  *
10c19800e8SDoug Rabson  * 1. Redistributions of source code must retain the above copyright
11c19800e8SDoug Rabson  *    notice, this list of conditions and the following disclaimer.
12c19800e8SDoug Rabson  *
13c19800e8SDoug Rabson  * 2. Redistributions in binary form must reproduce the above copyright
14c19800e8SDoug Rabson  *    notice, this list of conditions and the following disclaimer in the
15c19800e8SDoug Rabson  *    documentation and/or other materials provided with the distribution.
16c19800e8SDoug Rabson  *
17c19800e8SDoug Rabson  * 3. Neither the name of the Institute nor the names of its contributors
18c19800e8SDoug Rabson  *    may be used to endorse or promote products derived from this software
19c19800e8SDoug Rabson  *    without specific prior written permission.
20c19800e8SDoug Rabson  *
21c19800e8SDoug Rabson  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22c19800e8SDoug Rabson  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23c19800e8SDoug Rabson  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24c19800e8SDoug Rabson  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25c19800e8SDoug Rabson  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26c19800e8SDoug Rabson  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27c19800e8SDoug Rabson  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28c19800e8SDoug Rabson  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29c19800e8SDoug Rabson  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30c19800e8SDoug Rabson  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31c19800e8SDoug Rabson  * SUCH DAMAGE.
32c19800e8SDoug Rabson  */
33c19800e8SDoug Rabson 
34c19800e8SDoug Rabson #include "gsskrb5_locl.h"
35c19800e8SDoug Rabson 
_gsskrb5_inquire_cred(OM_uint32 * minor_status,const gss_cred_id_t cred_handle,gss_name_t * output_name,OM_uint32 * lifetime,gss_cred_usage_t * cred_usage,gss_OID_set * mechanisms)36c19800e8SDoug Rabson OM_uint32 GSSAPI_CALLCONV _gsskrb5_inquire_cred
37c19800e8SDoug Rabson (OM_uint32 * minor_status,
38c19800e8SDoug Rabson  const gss_cred_id_t cred_handle,
39c19800e8SDoug Rabson  gss_name_t * output_name,
40c19800e8SDoug Rabson  OM_uint32 * lifetime,
41c19800e8SDoug Rabson  gss_cred_usage_t * cred_usage,
42c19800e8SDoug Rabson  gss_OID_set * mechanisms
43c19800e8SDoug Rabson     )
44c19800e8SDoug Rabson {
45c19800e8SDoug Rabson     krb5_context context;
46c19800e8SDoug Rabson     gss_cred_id_t aqcred_init = GSS_C_NO_CREDENTIAL;
47c19800e8SDoug Rabson     gss_cred_id_t aqcred_accept = GSS_C_NO_CREDENTIAL;
48c19800e8SDoug Rabson     gsskrb5_cred acred = NULL, icred = NULL;
49c19800e8SDoug Rabson     OM_uint32 ret;
50c19800e8SDoug Rabson 
51c19800e8SDoug Rabson     *minor_status = 0;
52c19800e8SDoug Rabson 
53c19800e8SDoug Rabson     if (output_name)
54c19800e8SDoug Rabson 	*output_name = NULL;
55c19800e8SDoug Rabson     if (mechanisms)
56c19800e8SDoug Rabson 	*mechanisms = GSS_C_NO_OID_SET;
57c19800e8SDoug Rabson 
58c19800e8SDoug Rabson     GSSAPI_KRB5_INIT (&context);
59c19800e8SDoug Rabson 
60c19800e8SDoug Rabson     if (cred_handle == GSS_C_NO_CREDENTIAL) {
61c19800e8SDoug Rabson 	ret = _gsskrb5_acquire_cred(minor_status,
62c19800e8SDoug Rabson 				    GSS_C_NO_NAME,
63c19800e8SDoug Rabson 				    GSS_C_INDEFINITE,
64c19800e8SDoug Rabson 				    GSS_C_NO_OID_SET,
65c19800e8SDoug Rabson 				    GSS_C_ACCEPT,
66c19800e8SDoug Rabson 				    &aqcred_accept,
67c19800e8SDoug Rabson 				    NULL,
68c19800e8SDoug Rabson 				    NULL);
69c19800e8SDoug Rabson 	if (ret == GSS_S_COMPLETE)
70c19800e8SDoug Rabson 	    acred = (gsskrb5_cred)aqcred_accept;
71c19800e8SDoug Rabson 
72c19800e8SDoug Rabson 	ret = _gsskrb5_acquire_cred(minor_status,
73c19800e8SDoug Rabson 				    GSS_C_NO_NAME,
74c19800e8SDoug Rabson 				    GSS_C_INDEFINITE,
75c19800e8SDoug Rabson 				    GSS_C_NO_OID_SET,
76c19800e8SDoug Rabson 				    GSS_C_INITIATE,
77c19800e8SDoug Rabson 				    &aqcred_init,
78c19800e8SDoug Rabson 				    NULL,
79c19800e8SDoug Rabson 				    NULL);
80c19800e8SDoug Rabson 	if (ret == GSS_S_COMPLETE)
81c19800e8SDoug Rabson 	    icred = (gsskrb5_cred)aqcred_init;
82c19800e8SDoug Rabson 
83c19800e8SDoug Rabson 	if (icred == NULL && acred == NULL) {
84c19800e8SDoug Rabson 	    *minor_status = 0;
85c19800e8SDoug Rabson 	    return GSS_S_NO_CRED;
86c19800e8SDoug Rabson 	}
87c19800e8SDoug Rabson     } else
88c19800e8SDoug Rabson 	acred = (gsskrb5_cred)cred_handle;
89c19800e8SDoug Rabson 
90c19800e8SDoug Rabson     if (acred)
91c19800e8SDoug Rabson 	HEIMDAL_MUTEX_lock(&acred->cred_id_mutex);
92c19800e8SDoug Rabson     if (icred)
93c19800e8SDoug Rabson 	HEIMDAL_MUTEX_lock(&icred->cred_id_mutex);
94c19800e8SDoug Rabson 
95c19800e8SDoug Rabson     if (output_name != NULL) {
96c19800e8SDoug Rabson 	if (icred && icred->principal != NULL) {
97c19800e8SDoug Rabson 	    gss_name_t name;
98c19800e8SDoug Rabson 
99c19800e8SDoug Rabson 	    if (acred && acred->principal)
100c19800e8SDoug Rabson 		name = (gss_name_t)acred->principal;
101c19800e8SDoug Rabson 	    else
102c19800e8SDoug Rabson 		name = (gss_name_t)icred->principal;
103c19800e8SDoug Rabson 
104c19800e8SDoug Rabson             ret = _gsskrb5_duplicate_name(minor_status, name, output_name);
105c19800e8SDoug Rabson             if (ret)
106c19800e8SDoug Rabson 		goto out;
107c19800e8SDoug Rabson 	} else if (acred && acred->usage == GSS_C_ACCEPT) {
108c19800e8SDoug Rabson 	    krb5_principal princ;
109c19800e8SDoug Rabson 	    *minor_status = krb5_sname_to_principal(context, NULL,
110c19800e8SDoug Rabson 						    NULL, KRB5_NT_SRV_HST,
111c19800e8SDoug Rabson 						    &princ);
112c19800e8SDoug Rabson 	    if (*minor_status) {
113c19800e8SDoug Rabson 		ret = GSS_S_FAILURE;
114c19800e8SDoug Rabson 		goto out;
115c19800e8SDoug Rabson 	    }
116c19800e8SDoug Rabson 	    *output_name = (gss_name_t)princ;
117c19800e8SDoug Rabson 	} else {
118c19800e8SDoug Rabson 	    krb5_principal princ;
119c19800e8SDoug Rabson 	    *minor_status = krb5_get_default_principal(context,
120c19800e8SDoug Rabson 						       &princ);
121c19800e8SDoug Rabson 	    if (*minor_status) {
122c19800e8SDoug Rabson 		ret = GSS_S_FAILURE;
123c19800e8SDoug Rabson 		goto out;
124c19800e8SDoug Rabson 	    }
125c19800e8SDoug Rabson 	    *output_name = (gss_name_t)princ;
126c19800e8SDoug Rabson 	}
127c19800e8SDoug Rabson     }
128c19800e8SDoug Rabson     if (lifetime != NULL) {
129c19800e8SDoug Rabson 	OM_uint32 alife = GSS_C_INDEFINITE, ilife = GSS_C_INDEFINITE;
130c19800e8SDoug Rabson 
131c19800e8SDoug Rabson 	if (acred) alife = acred->lifetime;
132c19800e8SDoug Rabson 	if (icred) ilife = icred->lifetime;
133c19800e8SDoug Rabson 
134c19800e8SDoug Rabson 	ret = _gsskrb5_lifetime_left(minor_status,
135c19800e8SDoug Rabson 				     context,
136c19800e8SDoug Rabson 				     min(alife,ilife),
137c19800e8SDoug Rabson 				     lifetime);
138c19800e8SDoug Rabson 	if (ret)
139c19800e8SDoug Rabson 	    goto out;
140c19800e8SDoug Rabson     }
141c19800e8SDoug Rabson     if (cred_usage != NULL) {
142c19800e8SDoug Rabson 	if (acred && icred)
143c19800e8SDoug Rabson 	    *cred_usage = GSS_C_BOTH;
144c19800e8SDoug Rabson 	else if (acred)
145c19800e8SDoug Rabson 	    *cred_usage = GSS_C_ACCEPT;
146c19800e8SDoug Rabson 	else if (icred)
147c19800e8SDoug Rabson 	    *cred_usage = GSS_C_INITIATE;
148c19800e8SDoug Rabson 	else
149c19800e8SDoug Rabson 	    abort();
150c19800e8SDoug Rabson     }
151c19800e8SDoug Rabson 
152c19800e8SDoug Rabson     if (mechanisms != NULL) {
153c19800e8SDoug Rabson         ret = gss_create_empty_oid_set(minor_status, mechanisms);
154c19800e8SDoug Rabson         if (ret)
155c19800e8SDoug Rabson 	    goto out;
156c19800e8SDoug Rabson 	if (acred)
157c19800e8SDoug Rabson 	    ret = gss_add_oid_set_member(minor_status,
158c19800e8SDoug Rabson 					 &acred->mechanisms->elements[0],
159c19800e8SDoug Rabson 					 mechanisms);
160c19800e8SDoug Rabson 	if (ret == GSS_S_COMPLETE && icred)
161c19800e8SDoug Rabson 	    ret = gss_add_oid_set_member(minor_status,
162c19800e8SDoug Rabson 					 &icred->mechanisms->elements[0],
163c19800e8SDoug Rabson 					 mechanisms);
164c19800e8SDoug Rabson         if (ret)
165c19800e8SDoug Rabson 	    goto out;
166c19800e8SDoug Rabson     }
167c19800e8SDoug Rabson     ret = GSS_S_COMPLETE;
168c19800e8SDoug Rabson out:
169c19800e8SDoug Rabson     if (acred)
170c19800e8SDoug Rabson 	HEIMDAL_MUTEX_unlock(&acred->cred_id_mutex);
171c19800e8SDoug Rabson     if (icred)
172c19800e8SDoug Rabson 	HEIMDAL_MUTEX_unlock(&icred->cred_id_mutex);
173c19800e8SDoug Rabson 
174c19800e8SDoug Rabson     if (aqcred_init != GSS_C_NO_CREDENTIAL)
175c19800e8SDoug Rabson 	ret = _gsskrb5_release_cred(minor_status, &aqcred_init);
176c19800e8SDoug Rabson     if (aqcred_accept != GSS_C_NO_CREDENTIAL)
177c19800e8SDoug Rabson 	ret = _gsskrb5_release_cred(minor_status, &aqcred_accept);
178c19800e8SDoug Rabson 
179c19800e8SDoug Rabson     return ret;
180c19800e8SDoug Rabson }
181c19800e8SDoug Rabson