Path: blob/main/crypto/heimdal/lib/gssapi/mech/gss_authorize_localname.c
34914 views
/*1* Copyright (c) 2011, PADL Software Pty Ltd.2* All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7*8* 1. Redistributions of source code must retain the above copyright9* notice, this list of conditions and the following disclaimer.10*11* 2. Redistributions in binary form must reproduce the above copyright12* notice, this list of conditions and the following disclaimer in the13* documentation and/or other materials provided with the distribution.14*15* 3. Neither the name of PADL Software nor the names of its contributors16* may be used to endorse or promote products derived from this software17* without specific prior written permission.18*19* THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND20* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE21* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE22* ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE23* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL24* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS25* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)26* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT27* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY28* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF29* SUCH DAMAGE.30*/3132#include "mech_locl.h"3334gss_buffer_desc GSSAPI_LIB_VARIABLE __gss_c_attr_local_login_user = {35sizeof("local-login-user") - 1,36"local-login-user"37};3839static OM_uint3240mech_authorize_localname(OM_uint32 *minor_status,41const struct _gss_name *name,42const struct _gss_name *user)43{44OM_uint32 major_status = GSS_S_NAME_NOT_MN;45struct _gss_mechanism_name *mn;4647HEIM_SLIST_FOREACH(mn, &name->gn_mn, gmn_link) {48gssapi_mech_interface m = mn->gmn_mech;4950if (m->gm_authorize_localname == NULL) {51major_status = GSS_S_UNAVAILABLE;52continue;53}5455major_status = m->gm_authorize_localname(minor_status,56mn->gmn_name,57&user->gn_value,58&user->gn_type);59if (major_status != GSS_S_UNAUTHORIZED)60break;61}6263return major_status;64}6566/*67* Naming extensions based local login authorization.68*/69static OM_uint3270attr_authorize_localname(OM_uint32 *minor_status,71const struct _gss_name *name,72const struct _gss_name *user)73{74OM_uint32 major_status = GSS_S_UNAVAILABLE;75int more = -1;7677if (!gss_oid_equal(&user->gn_type, GSS_C_NT_USER_NAME))78return GSS_S_BAD_NAMETYPE;7980while (more != 0 && major_status != GSS_S_COMPLETE) {81OM_uint32 tmpMajor, tmpMinor;82gss_buffer_desc value;83gss_buffer_desc display_value;84int authenticated = 0, complete = 0;8586tmpMajor = gss_get_name_attribute(minor_status,87(gss_name_t)name,88GSS_C_ATTR_LOCAL_LOGIN_USER,89&authenticated,90&complete,91&value,92&display_value,93&more);94if (GSS_ERROR(tmpMajor)) {95major_status = tmpMajor;96break;97}9899/* If attribute is present, return an authoritative error code. */100if (authenticated &&101value.length == user->gn_value.length &&102memcmp(value.value, user->gn_value.value, user->gn_value.length) == 0)103major_status = GSS_S_COMPLETE;104else105major_status = GSS_S_UNAUTHORIZED;106107gss_release_buffer(&tmpMinor, &value);108gss_release_buffer(&tmpMinor, &display_value);109}110111return major_status;112}113114GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL115gss_authorize_localname(OM_uint32 *minor_status,116const gss_name_t gss_name,117const gss_name_t gss_user)118119{120OM_uint32 major_status;121const struct _gss_name *name = (const struct _gss_name *) gss_name;122const struct _gss_name *user = (const struct _gss_name *) gss_user;123int mechAvailable = 0;124125*minor_status = 0;126127if (gss_name == GSS_C_NO_NAME || gss_user == GSS_C_NO_NAME)128return GSS_S_CALL_INACCESSIBLE_READ;129130/*131* We should check that the user name is not a mechanism name, but132* as Heimdal always calls the mechanism's gss_import_name(), it's133* not possible to make this check.134*/135#if 0136if (HEIM_SLIST_FIRST(&user->gn_mn) != NULL)137return GSS_S_BAD_NAME;138#endif139140/* If mech returns yes, we return yes */141major_status = mech_authorize_localname(minor_status, name, user);142if (major_status == GSS_S_COMPLETE)143return GSS_S_COMPLETE;144else if (major_status != GSS_S_UNAVAILABLE)145mechAvailable = 1;146147/* If attribute exists, it is authoritative */148major_status = attr_authorize_localname(minor_status, name, user);149if (major_status == GSS_S_COMPLETE || major_status == GSS_S_UNAUTHORIZED)150return major_status;151152/* If mechanism did not implement SPI, compare the local name */153if (mechAvailable == 0) {154int match = 0;155156major_status = gss_compare_name(minor_status, gss_name,157gss_user, &match);158if (major_status == GSS_S_COMPLETE && match == 0)159major_status = GSS_S_UNAUTHORIZED;160}161162return major_status;163}164165GSSAPI_LIB_FUNCTION int GSSAPI_LIB_CALL166gss_userok(const gss_name_t name,167const char *user)168{169OM_uint32 major_status, minor_status;170gss_buffer_desc userBuf;171gss_name_t userName;172173userBuf.value = (void *)user;174userBuf.length = strlen(user);175176major_status = gss_import_name(&minor_status, &userBuf,177GSS_C_NT_USER_NAME, &userName);178if (GSS_ERROR(major_status))179return 0;180181major_status = gss_authorize_localname(&minor_status, name, userName);182183gss_release_name(&minor_status, &userName);184185return (major_status == GSS_S_COMPLETE);186}187188189