gss_authorize_localname.c revision 1.1.1.1
1/* $NetBSD: gss_authorize_localname.c,v 1.1.1.1 2014/04/24 12:45:29 pettai Exp $ */ 2 3/* 4 * Copyright (c) 2011, PADL Software Pty Ltd. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * 3. Neither the name of PADL Software nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35#include "mech_locl.h" 36 37gss_buffer_desc GSSAPI_LIB_VARIABLE __gss_c_attr_local_login_user = { 38 sizeof("local-login-user") - 1, 39 "local-login-user" 40}; 41 42static OM_uint32 43mech_authorize_localname(OM_uint32 *minor_status, 44 const struct _gss_name *name, 45 const struct _gss_name *user) 46{ 47 OM_uint32 major_status = GSS_S_NAME_NOT_MN; 48 struct _gss_mechanism_name *mn; 49 50 HEIM_SLIST_FOREACH(mn, &name->gn_mn, gmn_link) { 51 gssapi_mech_interface m = mn->gmn_mech; 52 53 if (m->gm_authorize_localname == NULL) { 54 major_status = GSS_S_UNAVAILABLE; 55 continue; 56 } 57 58 major_status = m->gm_authorize_localname(minor_status, 59 mn->gmn_name, 60 &user->gn_value, 61 &user->gn_type); 62 if (major_status != GSS_S_UNAUTHORIZED) 63 break; 64 } 65 66 return major_status; 67} 68 69/* 70 * Naming extensions based local login authorization. 71 */ 72static OM_uint32 73attr_authorize_localname(OM_uint32 *minor_status, 74 const struct _gss_name *name, 75 const struct _gss_name *user) 76{ 77 OM_uint32 major_status = GSS_S_UNAVAILABLE; 78 int more = -1; 79 80 if (!gss_oid_equal(&user->gn_type, GSS_C_NT_USER_NAME)) 81 return GSS_S_BAD_NAMETYPE; 82 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; 88 89 tmpMajor = gss_get_name_attribute(minor_status, 90 (gss_name_t)name, 91 GSS_C_ATTR_LOCAL_LOGIN_USER, 92 &authenticated, 93 &complete, 94 &value, 95 &display_value, 96 &more); 97 if (GSS_ERROR(tmpMajor)) { 98 major_status = tmpMajor; 99 break; 100 } 101 102 /* If attribute is present, return an authoritative error code. */ 103 if (authenticated && 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; 107 else 108 major_status = GSS_S_UNAUTHORIZED; 109 110 gss_release_buffer(&tmpMinor, &value); 111 gss_release_buffer(&tmpMinor, &display_value); 112 } 113 114 return major_status; 115} 116 117GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL 118gss_authorize_localname(OM_uint32 *minor_status, 119 const gss_name_t gss_name, 120 const gss_name_t gss_user) 121 122{ 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; 127 128 *minor_status = 0; 129 130 if (gss_name == GSS_C_NO_NAME || gss_user == GSS_C_NO_NAME) 131 return GSS_S_CALL_INACCESSIBLE_READ; 132 133 /* 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. 137 */ 138#if 0 139 if (HEIM_SLIST_FIRST(&user->gn_mn) != NULL) 140 return GSS_S_BAD_NAME; 141#endif 142 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) 148 mechAvailable = 1; 149 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) 153 return major_status; 154 155 /* If mechanism did not implement SPI, compare the local name */ 156 if (mechAvailable == 0) { 157 int match = 0; 158 159 major_status = gss_compare_name(minor_status, gss_name, 160 gss_user, &match); 161 if (major_status == GSS_S_COMPLETE && match == 0) 162 major_status = GSS_S_UNAUTHORIZED; 163 } 164 165 return major_status; 166} 167 168GSSAPI_LIB_FUNCTION int GSSAPI_LIB_CALL 169gss_userok(const gss_name_t name, 170 const char *user) 171{ 172 OM_uint32 major_status, minor_status; 173 gss_buffer_desc userBuf; 174 gss_name_t userName; 175 176 userBuf.value = (void *)user; 177 userBuf.length = strlen(user); 178 179 major_status = gss_import_name(&minor_status, &userBuf, 180 GSS_C_NT_USER_NAME, &userName); 181 if (GSS_ERROR(major_status)) 182 return 0; 183 184 major_status = gss_authorize_localname(&minor_status, name, userName); 185 186 gss_release_name(&minor_status, &userName); 187 188 return (major_status == GSS_S_COMPLETE); 189} 190