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 gss_buffer_desc GSSAPI_LIB_VARIABLE __gss_c_attr_local_login_user
= {
36 sizeof("local-login-user") - 1,
41 mech_authorize_localname(OM_uint32
*minor_status
,
42 const struct _gss_name
*name
,
43 const struct _gss_name
*user
)
45 OM_uint32 major_status
= GSS_S_NAME_NOT_MN
;
46 struct _gss_mechanism_name
*mn
;
48 HEIM_SLIST_FOREACH(mn
, &name
->gn_mn
, gmn_link
) {
49 gssapi_mech_interface m
= mn
->gmn_mech
;
51 if (m
->gm_authorize_localname
== NULL
) {
52 major_status
= GSS_S_UNAVAILABLE
;
56 major_status
= m
->gm_authorize_localname(minor_status
,
60 if (major_status
!= GSS_S_UNAUTHORIZED
)
68 * Naming extensions based local login authorization.
71 attr_authorize_localname(OM_uint32
*minor_status
,
72 const struct _gss_name
*name
,
73 const struct _gss_name
*user
)
75 OM_uint32 major_status
= GSS_S_UNAVAILABLE
;
78 if (!gss_oid_equal(&user
->gn_type
, GSS_C_NT_USER_NAME
))
79 return GSS_S_BAD_NAMETYPE
;
81 while (more
!= 0 && major_status
!= GSS_S_COMPLETE
) {
82 OM_uint32 tmpMajor
, tmpMinor
;
83 gss_buffer_desc value
;
84 gss_buffer_desc display_value
;
85 int authenticated
= 0, complete
= 0;
87 tmpMajor
= gss_get_name_attribute(minor_status
,
89 GSS_C_ATTR_LOCAL_LOGIN_USER
,
95 if (GSS_ERROR(tmpMajor
)) {
96 major_status
= tmpMajor
;
100 /* If attribute is present, return an authoritative error code. */
102 value
.length
== user
->gn_value
.length
&&
103 memcmp(value
.value
, user
->gn_value
.value
, user
->gn_value
.length
) == 0)
104 major_status
= GSS_S_COMPLETE
;
106 major_status
= GSS_S_UNAUTHORIZED
;
108 gss_release_buffer(&tmpMinor
, &value
);
109 gss_release_buffer(&tmpMinor
, &display_value
);
115 GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
116 gss_authorize_localname(OM_uint32
*minor_status
,
117 gss_const_name_t gss_name
,
118 gss_const_name_t gss_user
)
121 OM_uint32 major_status
;
122 const struct _gss_name
*name
= (const struct _gss_name
*) gss_name
;
123 const struct _gss_name
*user
= (const struct _gss_name
*) gss_user
;
124 int mechAvailable
= 0;
128 if (gss_name
== GSS_C_NO_NAME
|| gss_user
== GSS_C_NO_NAME
)
129 return GSS_S_CALL_INACCESSIBLE_READ
;
132 * We should check that the user name is not a mechanism name, but
133 * as Heimdal always calls the mechanism's gss_import_name(), it's
134 * not possible to make this check.
137 if (HEIM_SLIST_FIRST(&user
->gn_mn
) != NULL
)
138 return GSS_S_BAD_NAME
;
141 /* If mech returns yes, we return yes */
142 major_status
= mech_authorize_localname(minor_status
, name
, user
);
143 if (major_status
== GSS_S_COMPLETE
)
144 return GSS_S_COMPLETE
;
145 else if (major_status
!= GSS_S_UNAVAILABLE
)
148 /* If attribute exists, it is authoritative */
149 major_status
= attr_authorize_localname(minor_status
, name
, user
);
150 if (major_status
== GSS_S_COMPLETE
|| major_status
== GSS_S_UNAUTHORIZED
)
153 /* If mechanism did not implement SPI, compare the local name */
154 if (mechAvailable
== 0) {
157 major_status
= gss_compare_name(minor_status
, gss_name
,
159 if (major_status
== GSS_S_COMPLETE
&& match
== 0)
160 major_status
= GSS_S_UNAUTHORIZED
;
166 GSSAPI_LIB_FUNCTION
int GSSAPI_LIB_CALL
167 gss_userok(gss_const_name_t name
,
170 OM_uint32 major_status
, minor_status
;
171 gss_buffer_desc userBuf
;
174 userBuf
.value
= (void *)user
;
175 userBuf
.length
= strlen(user
);
177 major_status
= gss_import_name(&minor_status
, &userBuf
,
178 GSS_C_NT_USER_NAME
, &userName
);
179 if (GSS_ERROR(major_status
))
182 major_status
= gss_authorize_localname(&minor_status
, name
, userName
);
184 gss_release_name(&minor_status
, &userName
);
186 return (major_status
== GSS_S_COMPLETE
);