xref: /freebsd/lib/libgssapi/gss_inquire_cred.c (revision 2b743a9e9ddc6736208dc8ca1ce06ce64ad20a19)
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$
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 
37 OM_uint32
38 gss_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