gss_inquire_cred.c revision 153838
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: head/lib/libgssapi/gss_inquire_cred.c 153838 2005-12-29 14:40:22Z dfr $
27 */
28
29#include <gssapi/gssapi.h>
30#include <stdlib.h>
31#include <errno.h>
32
33#include "mech_switch.h"
34#include "name.h"
35#include "cred.h"
36
37OM_uint32
38gss_inquire_cred(OM_uint32 *minor_status,
39    const gss_cred_id_t cred_handle,
40    gss_name_t *name_ret,
41    OM_uint32 *lifetime,
42    gss_cred_usage_t *cred_usage,
43    gss_OID_set *mechanisms)
44{
45	OM_uint32 major_status;
46	struct _gss_mech_switch *m;
47	struct _gss_cred *cred = (struct _gss_cred *) cred_handle;
48	struct _gss_mechanism_cred *mc;
49	struct _gss_name *name;
50	struct _gss_mechanism_name *mn;
51	OM_uint32 min_lifetime;
52
53	*minor_status = 0;
54	if (name_ret)
55		*name_ret = 0;
56	if (lifetime)
57		*lifetime = 0;
58	if (cred_usage)
59		*cred_usage = 0;
60
61	if (name_ret) {
62		name = malloc(sizeof(struct _gss_name));
63		if (!name) {
64			*minor_status = ENOMEM;
65			return (GSS_S_FAILURE);
66		}
67		memset(name, 0, sizeof(struct _gss_name));
68		SLIST_INIT(&name->gn_mn);
69	} else {
70		name = 0;
71	}
72
73	if (mechanisms) {
74		major_status = gss_create_empty_oid_set(minor_status,
75		    mechanisms);
76		if (major_status) {
77			if (name) free(name);
78			return (major_status);
79		}
80	}
81
82	min_lifetime = GSS_C_INDEFINITE;
83	if (cred) {
84		SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) {
85			gss_name_t mc_name;
86			OM_uint32 mc_lifetime;
87
88			major_status = mc->gmc_mech->gm_inquire_cred(minor_status,
89			    mc->gmc_cred, &mc_name, &mc_lifetime, NULL, NULL);
90			if (major_status)
91				continue;
92
93			if (name) {
94				mn = malloc(sizeof(struct _gss_mechanism_name));
95				if (!mn) {
96					mc->gmc_mech->gm_release_name(minor_status,
97					    &mc_name);
98					continue;
99				}
100				mn->gmn_mech = mc->gmc_mech;
101				mn->gmn_mech_oid = mc->gmc_mech_oid;
102				mn->gmn_name = mc_name;
103				SLIST_INSERT_HEAD(&name->gn_mn, mn, gmn_link);
104			} else {
105				mc->gmc_mech->gm_release_name(minor_status,
106				    &mc_name);
107			}
108
109			if (mc_lifetime < min_lifetime)
110				min_lifetime = mc_lifetime;
111
112			if (mechanisms)
113				gss_add_oid_set_member(minor_status,
114				    mc->gmc_mech_oid, mechanisms);
115		}
116	} else {
117		SLIST_FOREACH(m, &_gss_mechs, gm_link) {
118			gss_name_t mc_name;
119			OM_uint32 mc_lifetime;
120
121			major_status = m->gm_inquire_cred(minor_status,
122			    GSS_C_NO_CREDENTIAL, &mc_name, &mc_lifetime,
123			    cred_usage, NULL);
124			if (major_status)
125				continue;
126
127			if (name && mc_name) {
128				mn = malloc(
129					sizeof(struct _gss_mechanism_name));
130				if (!mn) {
131					mc->gmc_mech->gm_release_name(
132						minor_status, &mc_name);
133					continue;
134				}
135				mn->gmn_mech = mc->gmc_mech;
136				mn->gmn_mech_oid = mc->gmc_mech_oid;
137				mn->gmn_name = mc_name;
138				SLIST_INSERT_HEAD(&name->gn_mn, mn, gmn_link);
139			} else if (mc_name) {
140				mc->gmc_mech->gm_release_name(minor_status,
141				    &mc_name);
142			}
143
144			if (mc_lifetime < min_lifetime)
145				min_lifetime = mc_lifetime;
146
147			if (mechanisms)
148				gss_add_oid_set_member(minor_status,
149				    &m->gm_mech_oid, mechanisms);
150		}
151
152		if ((*mechanisms)->count == 0) {
153			gss_release_oid_set(minor_status, mechanisms);
154			*minor_status = 0;
155			return (GSS_S_NO_CRED);
156		}
157	}
158
159	*minor_status = 0;
160	if (name_ret)
161		*name_ret = (gss_name_t) name;
162	if (lifetime)
163		*lifetime = min_lifetime;
164	if (cred && cred_usage)
165		*cred_usage = cred->gc_usage;
166	return (GSS_S_COMPLETE);
167}
168