Line data Source code
1 : /*-
2 : * Copyright (c) 2005 Doug Rabson
3 : * All rights reserved.
4 : *
5 : * Redistribution and use in source and binary forms, with or without
6 : * modification, are permitted provided that the following conditions
7 : * are met:
8 : * 1. Redistributions of source code must retain the above copyright
9 : * notice, this list of conditions and the following disclaimer.
10 : * 2. Redistributions in binary form must reproduce the above copyright
11 : * notice, this list of conditions and the following disclaimer in the
12 : * documentation and/or other materials provided with the distribution.
13 : *
14 : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 : * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 : * SUCH DAMAGE.
25 : *
26 : * $FreeBSD: src/lib/libgssapi/gss_inquire_cred.c,v 1.1 2005/12/29 14:40:20 dfr Exp $
27 : */
28 :
29 : #include "mech_locl.h"
30 :
31 : #define AUSAGE 1
32 : #define IUSAGE 2
33 :
34 : static void
35 10607 : updateusage(gss_cred_usage_t usage, int *usagemask)
36 : {
37 10607 : if (usage == GSS_C_BOTH)
38 0 : *usagemask |= AUSAGE | IUSAGE;
39 10607 : else if (usage == GSS_C_ACCEPT)
40 0 : *usagemask |= AUSAGE;
41 10607 : else if (usage == GSS_C_INITIATE)
42 10607 : *usagemask |= IUSAGE;
43 10157 : }
44 :
45 : GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
46 10607 : gss_inquire_cred(OM_uint32 *minor_status,
47 : gss_const_cred_id_t cred_handle,
48 : gss_name_t *name_ret,
49 : OM_uint32 *lifetime,
50 : gss_cred_usage_t *cred_usage,
51 : gss_OID_set *mechanisms)
52 : {
53 450 : OM_uint32 major_status;
54 450 : struct _gss_mech_switch *m;
55 10607 : struct _gss_cred *cred = (struct _gss_cred *) cred_handle;
56 450 : struct _gss_name *name;
57 450 : struct _gss_mechanism_name *mn;
58 450 : OM_uint32 min_lifetime;
59 10607 : int found = FALSE;
60 10607 : int usagemask = 0;
61 450 : gss_cred_usage_t usage;
62 :
63 10607 : _gss_load_mech();
64 :
65 10607 : *minor_status = 0;
66 10607 : if (name_ret)
67 0 : *name_ret = GSS_C_NO_NAME;
68 10607 : if (lifetime)
69 10607 : *lifetime = 0;
70 10607 : if (cred_usage)
71 10607 : *cred_usage = 0;
72 10607 : if (mechanisms)
73 0 : *mechanisms = GSS_C_NO_OID_SET;
74 :
75 10607 : if (name_ret) {
76 0 : name = _gss_create_name(NULL, NULL);
77 0 : if (name == NULL) {
78 0 : *minor_status = ENOMEM;
79 0 : return (GSS_S_FAILURE);
80 : }
81 : } else {
82 10157 : name = NULL;
83 : }
84 :
85 10607 : if (mechanisms) {
86 0 : major_status = gss_create_empty_oid_set(minor_status,
87 : mechanisms);
88 0 : if (major_status) {
89 0 : if (name) free(name);
90 0 : return (major_status);
91 : }
92 : }
93 :
94 10607 : min_lifetime = GSS_C_INDEFINITE;
95 10607 : if (cred) {
96 450 : struct _gss_mechanism_cred *mc;
97 :
98 21214 : HEIM_TAILQ_FOREACH(mc, &cred->gc_mc, gmc_link) {
99 10607 : gss_name_t mc_name = GSS_C_NO_NAME;
100 10607 : OM_uint32 mc_lifetime = GSS_C_INDEFINITE;
101 :
102 10607 : heim_assert((mc->gmc_mech->gm_flags & GM_USE_MG_CRED) == 0,
103 : "should not have mech creds for GM_USE_MG_CRED mechs");
104 :
105 10607 : if (mc->gmc_mech->gm_inquire_cred == NULL)
106 0 : continue;
107 :
108 11057 : major_status = mc->gmc_mech->gm_inquire_cred(minor_status,
109 10607 : mc->gmc_cred, &mc_name, &mc_lifetime, &usage, NULL);
110 10607 : if (major_status)
111 0 : continue;
112 :
113 10607 : updateusage(usage, &usagemask);
114 10607 : if (name) {
115 0 : mn = malloc(sizeof(struct _gss_mechanism_name));
116 0 : if (!mn) {
117 0 : mc->gmc_mech->gm_release_name(minor_status,
118 : &mc_name);
119 0 : continue;
120 : }
121 0 : mn->gmn_mech = mc->gmc_mech;
122 0 : mn->gmn_mech_oid = mc->gmc_mech_oid;
123 0 : mn->gmn_name = mc_name;
124 0 : HEIM_TAILQ_INSERT_TAIL(&name->gn_mn, mn, gmn_link);
125 : } else {
126 10607 : mc->gmc_mech->gm_release_name(minor_status,
127 : &mc_name);
128 : }
129 :
130 10607 : if (mc_lifetime < min_lifetime)
131 10157 : min_lifetime = mc_lifetime;
132 :
133 10607 : if (mechanisms)
134 0 : gss_add_oid_set_member(minor_status,
135 : mc->gmc_mech_oid, mechanisms);
136 10607 : found = TRUE;
137 : }
138 : } else {
139 0 : HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) {
140 0 : gss_name_t mc_name;
141 0 : OM_uint32 mc_lifetime;
142 :
143 0 : if (m->gm_mech.gm_inquire_cred == NULL ||
144 0 : (m->gm_mech.gm_flags & GM_USE_MG_CRED))
145 0 : continue;
146 :
147 0 : major_status = m->gm_mech.gm_inquire_cred(minor_status,
148 : GSS_C_NO_CREDENTIAL, &mc_name, &mc_lifetime,
149 : &usage, NULL);
150 0 : if (major_status)
151 0 : continue;
152 :
153 0 : updateusage(usage, &usagemask);
154 0 : if (name && mc_name) {
155 0 : mn = malloc(
156 : sizeof(struct _gss_mechanism_name));
157 0 : if (!mn) {
158 0 : m->gm_mech.gm_release_name(
159 : minor_status, &mc_name);
160 0 : continue;
161 : }
162 0 : mn->gmn_mech = &m->gm_mech;
163 0 : mn->gmn_mech_oid = m->gm_mech_oid;
164 0 : mn->gmn_name = mc_name;
165 0 : HEIM_TAILQ_INSERT_TAIL(&name->gn_mn, mn, gmn_link);
166 0 : } else if (mc_name) {
167 0 : m->gm_mech.gm_release_name(minor_status,
168 : &mc_name);
169 : }
170 :
171 0 : if (mc_lifetime < min_lifetime)
172 0 : min_lifetime = mc_lifetime;
173 :
174 0 : if (mechanisms)
175 0 : gss_add_oid_set_member(minor_status,
176 : m->gm_mech_oid, mechanisms);
177 0 : found = TRUE;
178 : }
179 : }
180 :
181 10607 : if (found && mechanisms) {
182 : /* GM_USE_MG_CRED mechs (SPNEGO) always can be used */
183 0 : HEIM_TAILQ_FOREACH(m, &_gss_mechs, gm_link) {
184 0 : if ((m->gm_mech.gm_flags & GM_USE_MG_CRED) == 0)
185 0 : continue;
186 :
187 0 : gss_add_oid_set_member(minor_status,
188 : m->gm_mech_oid, mechanisms);
189 : }
190 : }
191 :
192 10607 : if (found == FALSE || min_lifetime == 0) {
193 0 : gss_name_t n = (gss_name_t)name;
194 0 : if (n)
195 0 : gss_release_name(minor_status, &n);
196 0 : gss_release_oid_set(minor_status, mechanisms);
197 0 : *minor_status = 0;
198 0 : if (min_lifetime == 0)
199 0 : return (GSS_S_CREDENTIALS_EXPIRED);
200 :
201 0 : return (GSS_S_NO_CRED);
202 : }
203 :
204 10607 : *minor_status = 0;
205 10607 : if (name_ret)
206 0 : *name_ret = (gss_name_t) name;
207 10607 : if (lifetime)
208 10607 : *lifetime = min_lifetime;
209 10607 : if (cred_usage) {
210 10607 : if ((usagemask & (AUSAGE|IUSAGE)) == (AUSAGE|IUSAGE))
211 0 : *cred_usage = GSS_C_BOTH;
212 10607 : else if (usagemask & IUSAGE)
213 10607 : *cred_usage = GSS_C_INITIATE;
214 0 : else if (usagemask & AUSAGE)
215 0 : *cred_usage = GSS_C_ACCEPT;
216 : }
217 10157 : return (GSS_S_COMPLETE);
218 : }
|