1226031Sstas/* 2226031Sstas * Copyright (c) 2011, PADL Software Pty Ltd. 3226031Sstas * All rights reserved. 4226031Sstas * 5226031Sstas * Redistribution and use in source and binary forms, with or without 6226031Sstas * modification, are permitted provided that the following conditions 7226031Sstas * are met: 8226031Sstas * 9226031Sstas * 1. Redistributions of source code must retain the above copyright 10226031Sstas * notice, this list of conditions and the following disclaimer. 11226031Sstas * 12226031Sstas * 2. Redistributions in binary form must reproduce the above copyright 13226031Sstas * notice, this list of conditions and the following disclaimer in the 14226031Sstas * documentation and/or other materials provided with the distribution. 15226031Sstas * 16226031Sstas * 3. Neither the name of PADL Software nor the names of its contributors 17226031Sstas * may be used to endorse or promote products derived from this software 18226031Sstas * without specific prior written permission. 19226031Sstas * 20226031Sstas * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND 21226031Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22226031Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23226031Sstas * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE 24226031Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25226031Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26226031Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27226031Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28226031Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29226031Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30226031Sstas * SUCH DAMAGE. 31226031Sstas */ 32226031Sstas 33226031Sstas#include "mech_locl.h" 34226031Sstas 35226031Sstasstatic OM_uint32 36226031Sstasmech_pname_to_uid(OM_uint32 *minor_status, 37226031Sstas struct _gss_mechanism_name *mn, 38226031Sstas uid_t *uidp) 39226031Sstas{ 40226031Sstas OM_uint32 major_status = GSS_S_UNAVAILABLE; 41226031Sstas 42226031Sstas *minor_status = 0; 43226031Sstas 44226031Sstas if (mn->gmn_mech->gm_pname_to_uid == NULL) 45226031Sstas return GSS_S_UNAVAILABLE; 46226031Sstas 47226031Sstas major_status = mn->gmn_mech->gm_pname_to_uid(minor_status, 48226031Sstas mn->gmn_name, 49226031Sstas mn->gmn_mech_oid, 50226031Sstas uidp); 51226031Sstas if (GSS_ERROR(major_status)) 52226031Sstas _gss_mg_error(mn->gmn_mech, major_status, *minor_status); 53226031Sstas 54226031Sstas return major_status; 55226031Sstas} 56226031Sstas 57226031Sstasstatic OM_uint32 58226031Sstasattr_pname_to_uid(OM_uint32 *minor_status, 59226031Sstas struct _gss_mechanism_name *mn, 60226031Sstas uid_t *uidp) 61226031Sstas{ 62226031Sstas#ifdef NO_LOCALNAME 63226031Sstas return GSS_S_UNAVAILABLE; 64226031Sstas#else 65226031Sstas OM_uint32 major_status = GSS_S_UNAVAILABLE; 66226031Sstas OM_uint32 tmpMinor; 67226031Sstas int more = -1; 68226031Sstas 69226031Sstas *minor_status = 0; 70226031Sstas 71226031Sstas if (mn->gmn_mech->gm_get_name_attribute == NULL) 72226031Sstas return GSS_S_UNAVAILABLE; 73226031Sstas 74226031Sstas while (more != 0) { 75226031Sstas gss_buffer_desc value; 76226031Sstas gss_buffer_desc display_value; 77226031Sstas int authenticated = 0, complete = 0; 78226031Sstas#ifdef POSIX_GETPWNAM_R 79226031Sstas char pwbuf[2048]; 80226031Sstas struct passwd pw, *pwd; 81226031Sstas#else 82226031Sstas struct passwd *pwd; 83226031Sstas#endif 84226031Sstas char *localname; 85226031Sstas 86226031Sstas major_status = mn->gmn_mech->gm_get_name_attribute(minor_status, 87226031Sstas mn->gmn_name, 88226031Sstas GSS_C_ATTR_LOCAL_LOGIN_USER, 89226031Sstas &authenticated, 90226031Sstas &complete, 91226031Sstas &value, 92226031Sstas &display_value, 93226031Sstas &more); 94226031Sstas if (GSS_ERROR(major_status)) { 95226031Sstas _gss_mg_error(mn->gmn_mech, major_status, *minor_status); 96226031Sstas break; 97226031Sstas } 98226031Sstas 99226031Sstas localname = malloc(value.length + 1); 100226031Sstas if (localname == NULL) { 101226031Sstas major_status = GSS_S_FAILURE; 102226031Sstas *minor_status = ENOMEM; 103226031Sstas break; 104226031Sstas } 105226031Sstas 106226031Sstas memcpy(localname, value.value, value.length); 107226031Sstas localname[value.length] = '\0'; 108226031Sstas 109226031Sstas#ifdef POSIX_GETPWNAM_R 110226031Sstas if (getpwnam_r(localname, &pw, pwbuf, sizeof(pwbuf), &pwd) != 0) 111226031Sstas pwd = NULL; 112226031Sstas#else 113226031Sstas pwd = getpwnam(localname); 114226031Sstas#endif 115226031Sstas 116226031Sstas free(localname); 117226031Sstas gss_release_buffer(&tmpMinor, &value); 118226031Sstas gss_release_buffer(&tmpMinor, &display_value); 119226031Sstas 120226031Sstas if (pwd != NULL) { 121226031Sstas *uidp = pwd->pw_uid; 122226031Sstas major_status = GSS_S_COMPLETE; 123226031Sstas *minor_status = 0; 124226031Sstas break; 125226031Sstas } else 126226031Sstas major_status = GSS_S_UNAVAILABLE; 127226031Sstas } 128226031Sstas 129226031Sstas return major_status; 130226031Sstas#endif /* NO_LOCALNAME */ 131226031Sstas} 132226031Sstas 133226031SstasGSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL 134226031Sstasgss_pname_to_uid(OM_uint32 *minor_status, 135226031Sstas const gss_name_t pname, 136226031Sstas const gss_OID mech_type, 137226031Sstas uid_t *uidp) 138226031Sstas{ 139226031Sstas OM_uint32 major_status = GSS_S_UNAVAILABLE; 140226031Sstas struct _gss_name *name = (struct _gss_name *) pname; 141226031Sstas struct _gss_mechanism_name *mn = NULL; 142226031Sstas 143226031Sstas *minor_status = 0; 144226031Sstas 145226031Sstas if (mech_type != GSS_C_NO_OID) { 146226031Sstas major_status = _gss_find_mn(minor_status, name, mech_type, &mn); 147226031Sstas if (GSS_ERROR(major_status)) 148226031Sstas return major_status; 149226031Sstas 150226031Sstas major_status = mech_pname_to_uid(minor_status, mn, uidp); 151226031Sstas if (major_status != GSS_S_COMPLETE) 152226031Sstas major_status = attr_pname_to_uid(minor_status, mn, uidp); 153226031Sstas } else { 154226031Sstas HEIM_SLIST_FOREACH(mn, &name->gn_mn, gmn_link) { 155226031Sstas major_status = mech_pname_to_uid(minor_status, mn, uidp); 156226031Sstas if (major_status != GSS_S_COMPLETE) 157226031Sstas major_status = attr_pname_to_uid(minor_status, mn, uidp); 158226031Sstas if (major_status != GSS_S_UNAVAILABLE) 159226031Sstas break; 160226031Sstas } 161226031Sstas } 162226031Sstas 163226031Sstas if (major_status != GSS_S_COMPLETE && mn != NULL) 164226031Sstas _gss_mg_error(mn->gmn_mech, major_status, *minor_status); 165226031Sstas 166226031Sstas return major_status; 167226031Sstas} 168