1 /* #pragma ident "@(#)gssd_pname_to_uid.c 1.18 04/02/23 SMI" */
2 /*
3 * Copyright (c) 2011, PADL Software Pty Ltd.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of PADL Software nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33 /*
34 * Copyright 1996 by Sun Microsystems, Inc.
35 *
36 * Permission to use, copy, modify, distribute, and sell this software
37 * and its documentation for any purpose is hereby granted without fee,
38 * provided that the above copyright notice appears in all copies and
39 * that both that copyright notice and this permission notice appear in
40 * supporting documentation, and that the name of Sun Microsystems not be used
41 * in advertising or publicity pertaining to distribution of the software
42 * without specific, written prior permission. Sun Microsystems makes no
43 * representations about the suitability of this software for any
44 * purpose. It is provided "as is" without express or implied warranty.
45 *
46 * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
47 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
48 * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
49 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
50 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
51 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
52 * PERFORMANCE OF THIS SOFTWARE.
53 */
54
55 /*
56 * glue routines that test the mech id either passed in to
57 * gss_init_sec_contex() or gss_accept_sec_context() or within the glue
58 * routine supported version of the security context and then call
59 * the appropriate underlying mechanism library procedure.
60 *
61 */
62
63 #include "mglueP.h"
64
65 #ifndef NO_PASSWORD
66 #include <pwd.h>
67 #endif
68
69 static OM_uint32
attr_localname(OM_uint32 * minor,const gss_mechanism mech,const gss_name_t mech_name,gss_buffer_t localname)70 attr_localname(OM_uint32 *minor,
71 const gss_mechanism mech,
72 const gss_name_t mech_name,
73 gss_buffer_t localname)
74 {
75 OM_uint32 major = GSS_S_UNAVAILABLE;
76 OM_uint32 tmpMinor;
77 int more = -1;
78 gss_buffer_desc value;
79 gss_buffer_desc display_value;
80 int authenticated = 0, complete = 0;
81
82 value.value = NULL;
83 display_value.value = NULL;
84 if (mech->gss_get_name_attribute == NULL)
85 return GSS_S_UNAVAILABLE;
86
87 major = mech->gss_get_name_attribute(minor,
88 mech_name,
89 GSS_C_ATTR_LOCAL_LOGIN_USER,
90 &authenticated,
91 &complete,
92 &value,
93 &display_value,
94 &more);
95 if (GSS_ERROR(major)) {
96 map_error(minor, mech);
97 goto cleanup;
98 }
99
100 if (!authenticated)
101 major = GSS_S_UNAVAILABLE;
102 else {
103 localname->value = value.value;
104 localname->length = value.length;
105 value.value = NULL;
106 }
107
108 cleanup:
109 if (display_value.value)
110 gss_release_buffer(&tmpMinor, &display_value);
111 if (value.value)
112 gss_release_buffer(&tmpMinor, &value);
113 return major;
114 }
115
116 OM_uint32 KRB5_CALLCONV
gss_localname(OM_uint32 * minor,const gss_name_t pname,gss_const_OID mech_type,gss_buffer_t localname)117 gss_localname(OM_uint32 *minor,
118 const gss_name_t pname,
119 gss_const_OID mech_type,
120 gss_buffer_t localname)
121 {
122 OM_uint32 major, tmpMinor;
123 gss_mechanism mech;
124 gss_union_name_t unionName;
125 gss_name_t mechName = GSS_C_NO_NAME, mechNameP;
126 gss_OID selected_mech = GSS_C_NO_OID, public_mech;
127
128 if (localname != GSS_C_NO_BUFFER) {
129 localname->length = 0;
130 localname->value = NULL;
131 }
132
133 if (minor == NULL)
134 return GSS_S_CALL_INACCESSIBLE_WRITE;
135
136 *minor = 0;
137
138 if (pname == GSS_C_NO_NAME)
139 return GSS_S_CALL_INACCESSIBLE_READ;
140
141 if (localname == NULL)
142 return GSS_S_CALL_INACCESSIBLE_WRITE;
143
144 unionName = (gss_union_name_t)pname;
145
146 if (mech_type != GSS_C_NO_OID) {
147 major = gssint_select_mech_type(minor, mech_type, &selected_mech);
148 if (major != GSS_S_COMPLETE)
149 return major;
150 mech = gssint_get_mechanism(selected_mech);
151 } else
152 mech = gssint_get_mechanism(unionName->mech_type);
153
154 if (mech == NULL)
155 return GSS_S_BAD_MECH;
156
157 /* may need to create a mechanism specific name */
158 if (unionName->mech_type == GSS_C_NO_OID ||
159 (unionName->mech_type != GSS_C_NO_OID &&
160 !g_OID_equal(unionName->mech_type, &mech->mech_type))) {
161 major = gssint_import_internal_name(minor, &mech->mech_type,
162 unionName, &mechName);
163 if (GSS_ERROR(major))
164 return major;
165
166 mechNameP = mechName;
167 } else
168 mechNameP = unionName->mech_name;
169
170 major = GSS_S_UNAVAILABLE;
171
172 if (mech->gss_localname != NULL) {
173 public_mech = gssint_get_public_oid(selected_mech);
174 major = mech->gss_localname(minor, mechNameP, public_mech, localname);
175 if (GSS_ERROR(major))
176 map_error(minor, mech);
177 }
178
179 if (GSS_ERROR(major))
180 major = attr_localname(minor, mech, mechNameP, localname);
181
182 if (mechName != GSS_C_NO_NAME)
183 gssint_release_internal_name(&tmpMinor, &mech->mech_type, &mechName);
184
185 return major;
186 }
187
188 #ifndef _WIN32
189 OM_uint32 KRB5_CALLCONV
gss_pname_to_uid(OM_uint32 * minor,const gss_name_t name,const gss_OID mech_type,uid_t * uidOut)190 gss_pname_to_uid(OM_uint32 *minor,
191 const gss_name_t name,
192 const gss_OID mech_type,
193 uid_t *uidOut)
194 {
195 OM_uint32 major = GSS_S_UNAVAILABLE, tmpminor;
196 #ifndef NO_PASSWORD
197 gss_buffer_desc localname;
198 char pwbuf[BUFSIZ];
199 char *localuser = NULL;
200 struct passwd *pwd = NULL;
201 struct passwd pw;
202 int code = 0;
203
204 localname.value = NULL;
205 major = gss_localname(minor, name, mech_type, &localname);
206 if (!GSS_ERROR(major) && localname.value) {
207 localuser = malloc(localname.length + 1);
208 if (localuser == NULL)
209 code = ENOMEM;
210 if (code == 0) {
211 memcpy(localuser, localname.value, localname.length);
212 localuser[localname.length] = '\0';
213 code = k5_getpwnam_r(localuser, &pw, pwbuf, sizeof(pwbuf), &pwd);
214 }
215 if ((code == 0) && pwd)
216 *uidOut = pwd->pw_uid;
217 else
218 major = GSS_S_FAILURE;
219 }
220 free(localuser);
221 if (localname.value)
222 gss_release_buffer(&tmpminor, &localname);
223 #endif /*NO_PASSWORD*/
224 return major;
225 }
226 #endif /*_WIN32*/
227