2 * Copyright (c) 2011, PADL Software Pty Ltd.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of PADL Software nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 #include "mech_locl.h"
35 static gss_buffer_desc localLoginUserAttr
= {
36 sizeof("local-login-user") - 1,
40 gss_buffer_t GSSAPI_LIB_VARIABLE GSS_C_ATTR_LOCAL_LOGIN_USER
= &localLoginUserAttr
;
43 mech_authorize_localname(OM_uint32
*minor_status
,
44 const struct _gss_name
*name
,
45 const struct _gss_name
*user
)
47 OM_uint32 major_status
= GSS_S_NAME_NOT_MN
;
48 struct _gss_mechanism_name
*mn
;
50 HEIM_SLIST_FOREACH(mn
, &name
->gn_mn
, gmn_link
) {
51 gssapi_mech_interface m
= mn
->gmn_mech
;
53 if (m
->gm_authorize_localname
== NULL
) {
54 major_status
= GSS_S_UNAVAILABLE
;
58 major_status
= m
->gm_authorize_localname(minor_status
,
62 if (major_status
!= GSS_S_UNAUTHORIZED
)
70 * Naming extensions based local login authorization.
73 attr_authorize_localname(OM_uint32
*minor_status
,
74 const struct _gss_name
*name
,
75 const struct _gss_name
*user
)
77 OM_uint32 major_status
= GSS_S_UNAVAILABLE
;
80 if (!gss_oid_equal(&user
->gn_type
, GSS_C_NT_USER_NAME
))
81 return GSS_S_BAD_NAMETYPE
;
83 while (more
!= 0 && major_status
!= GSS_S_COMPLETE
) {
84 OM_uint32 tmpMajor
, tmpMinor
;
85 gss_buffer_desc value
;
86 gss_buffer_desc display_value
;
87 int authenticated
= 0, complete
= 0;
89 tmpMajor
= gss_get_name_attribute(minor_status
,
91 GSS_C_ATTR_LOCAL_LOGIN_USER
,
97 if (GSS_ERROR(major_status
)) {
98 major_status
= tmpMajor
;
102 /* If attribute is present, return an authoritative error code. */
104 value
.length
== user
->gn_value
.length
&&
105 memcmp(value
.value
, user
->gn_value
.value
, user
->gn_value
.length
) == 0)
106 major_status
= GSS_S_COMPLETE
;
108 major_status
= GSS_S_UNAUTHORIZED
;
110 gss_release_buffer(&tmpMinor
, &value
);
111 gss_release_buffer(&tmpMinor
, &display_value
);
118 gss_authorize_localname(OM_uint32
*minor_status
,
119 const gss_name_t gss_name
,
120 const gss_name_t gss_user
)
123 OM_uint32 major_status
;
124 const struct _gss_name
*name
= (const struct _gss_name
*) gss_name
;
125 const struct _gss_name
*user
= (const struct _gss_name
*) gss_user
;
126 int mechAvailable
= 0;
130 if (gss_name
== GSS_C_NO_NAME
|| gss_user
== GSS_C_NO_NAME
)
131 return GSS_S_CALL_INACCESSIBLE_READ
;
134 * We should check that the user name is not a mechanism name, but
135 * as Heimdal always calls the mechanism's gss_import_name(), it's
136 * not possible to make this check.
139 if (HEIM_SLIST_FIRST(&user
->gn_mn
) != NULL
)
140 return GSS_S_BAD_NAME
;
143 /* If mech returns yes, we return yes */
144 major_status
= mech_authorize_localname(minor_status
, name
, user
);
145 if (major_status
== GSS_S_COMPLETE
)
146 return GSS_S_COMPLETE
;
147 else if (major_status
!= GSS_S_UNAVAILABLE
)
150 /* If attribute exists, it is authoritative */
151 major_status
= attr_authorize_localname(minor_status
, name
, user
);
152 if (major_status
== GSS_S_COMPLETE
|| major_status
== GSS_S_UNAUTHORIZED
)
155 /* If mechanism did not implement SPI, compare the local name */
156 if (mechAvailable
== 0) {
159 major_status
= gss_compare_name(minor_status
, gss_name
,
161 if (major_status
== GSS_S_COMPLETE
&& match
== 0)
162 major_status
= GSS_S_UNAUTHORIZED
;
169 gss_userok(const gss_name_t name
,
172 OM_uint32 major_status
, minor_status
;
173 gss_buffer_desc userBuf
;
176 userBuf
.value
= (void *)user
;
177 userBuf
.length
= strlen(user
);
179 major_status
= gss_import_name(&minor_status
, &userBuf
,
180 GSS_C_NT_USER_NAME
, &userName
);
181 if (GSS_ERROR(major_status
))
184 major_status
= gss_authorize_localname(&minor_status
, name
, userName
);
186 gss_release_name(&minor_status
, &userName
);
188 return (major_status
== GSS_S_COMPLETE
);