155682Smarkm/* 2233294Sstas * Copyright (c) 1997 - 2001 Kungliga Tekniska H��gskolan 3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden). 4233294Sstas * All rights reserved. 555682Smarkm * 6233294Sstas * Redistribution and use in source and binary forms, with or without 7233294Sstas * modification, are permitted provided that the following conditions 8233294Sstas * are met: 955682Smarkm * 10233294Sstas * 1. Redistributions of source code must retain the above copyright 11233294Sstas * notice, this list of conditions and the following disclaimer. 1255682Smarkm * 13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright 14233294Sstas * notice, this list of conditions and the following disclaimer in the 15233294Sstas * documentation and/or other materials provided with the distribution. 1655682Smarkm * 17233294Sstas * 3. Neither the name of the Institute nor the names of its contributors 18233294Sstas * may be used to endorse or promote products derived from this software 19233294Sstas * without specific prior written permission. 2055682Smarkm * 21233294Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24233294Sstas * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31233294Sstas * SUCH DAMAGE. 3255682Smarkm */ 3355682Smarkm 3455682Smarkm#include "krb5_locl.h" 3555682Smarkm 3655682Smarkm/* 3755682Smarkm * Try to find out what's a reasonable default principal. 3855682Smarkm */ 3955682Smarkm 4078527Sassarstatic const char* 4178527Sassarget_env_user(void) 4278527Sassar{ 4378527Sassar const char *user = getenv("USER"); 4478527Sassar if(user == NULL) 4578527Sassar user = getenv("LOGNAME"); 4678527Sassar if(user == NULL) 4778527Sassar user = getenv("USERNAME"); 4878527Sassar return user; 4978527Sassar} 5078527Sassar 51233294Sstas#ifndef _WIN32 52233294Sstas 53178825Sdfr/* 54178825Sdfr * Will only use operating-system dependant operation to get the 55178825Sdfr * default principal, for use of functions that in ccache layer to 56178825Sdfr * avoid recursive calls. 57178825Sdfr */ 58178825Sdfr 5955682Smarkmkrb5_error_code 60233294Sstas_krb5_get_default_principal_local (krb5_context context, 61178825Sdfr krb5_principal *princ) 6255682Smarkm{ 6355682Smarkm krb5_error_code ret; 6455682Smarkm const char *user; 6578527Sassar uid_t uid; 6655682Smarkm 67178825Sdfr *princ = NULL; 6855682Smarkm 69233294Sstas uid = getuid(); 7078527Sassar if(uid == 0) { 7178527Sassar user = getlogin(); 7278527Sassar if(user == NULL) 7378527Sassar user = get_env_user(); 7478527Sassar if(user != NULL && strcmp(user, "root") != 0) 7578527Sassar ret = krb5_make_principal(context, princ, NULL, user, "root", NULL); 7678527Sassar else 7778527Sassar ret = krb5_make_principal(context, princ, NULL, "root", NULL); 7855682Smarkm } else { 79233294Sstas struct passwd *pw = getpwuid(uid); 8078527Sassar if(pw != NULL) 8178527Sassar user = pw->pw_name; 8278527Sassar else { 8378527Sassar user = get_env_user(); 8478527Sassar if(user == NULL) 8578527Sassar user = getlogin(); 8678527Sassar } 8778527Sassar if(user == NULL) { 88233294Sstas krb5_set_error_message(context, ENOTTY, 89233294Sstas N_("unable to figure out current " 90233294Sstas "principal", "")); 9178527Sassar return ENOTTY; /* XXX */ 9278527Sassar } 9355682Smarkm ret = krb5_make_principal(context, princ, NULL, user, NULL); 9455682Smarkm } 9555682Smarkm return ret; 9655682Smarkm} 97178825Sdfr 98233294Sstas#else /* _WIN32 */ 99233294Sstas 100233294Sstas#define SECURITY_WIN32 101233294Sstas#include <security.h> 102233294Sstas 103233294Sstaskrb5_error_code 104233294Sstas_krb5_get_default_principal_local(krb5_context context, 105233294Sstas krb5_principal *princ) 106233294Sstas{ 107233294Sstas /* See if we can get the principal first. We only expect this to 108233294Sstas work if logged into a domain. */ 109233294Sstas { 110233294Sstas char username[1024]; 111233294Sstas ULONG sz = sizeof(username); 112233294Sstas 113233294Sstas if (GetUserNameEx(NameUserPrincipal, username, &sz)) { 114233294Sstas return krb5_parse_name_flags(context, username, 115233294Sstas KRB5_PRINCIPAL_PARSE_ENTERPRISE, 116233294Sstas princ); 117233294Sstas } 118233294Sstas } 119233294Sstas 120233294Sstas /* Just get the Windows username. This should pretty much always 121233294Sstas work. */ 122233294Sstas { 123233294Sstas char username[1024]; 124233294Sstas DWORD dsz = sizeof(username); 125233294Sstas 126233294Sstas if (GetUserName(username, &dsz)) { 127233294Sstas return krb5_make_principal(context, princ, NULL, username, NULL); 128233294Sstas } 129233294Sstas } 130233294Sstas 131233294Sstas /* Failing that, we look at the environment */ 132233294Sstas { 133233294Sstas const char * username = get_env_user(); 134233294Sstas 135233294Sstas if (username == NULL) { 136233294Sstas krb5_set_error_string(context, 137233294Sstas "unable to figure out current principal"); 138233294Sstas return ENOTTY; /* Really? */ 139233294Sstas } 140233294Sstas 141233294Sstas return krb5_make_principal(context, princ, NULL, username, NULL); 142233294Sstas } 143233294Sstas} 144233294Sstas 145233294Sstas#endif 146233294Sstas 147233294SstasKRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 148178825Sdfrkrb5_get_default_principal (krb5_context context, 149178825Sdfr krb5_principal *princ) 150178825Sdfr{ 151178825Sdfr krb5_error_code ret; 152178825Sdfr krb5_ccache id; 153178825Sdfr 154178825Sdfr *princ = NULL; 155178825Sdfr 156178825Sdfr ret = krb5_cc_default (context, &id); 157178825Sdfr if (ret == 0) { 158178825Sdfr ret = krb5_cc_get_principal (context, id, princ); 159178825Sdfr krb5_cc_close (context, id); 160178825Sdfr if (ret == 0) 161178825Sdfr return 0; 162178825Sdfr } 163178825Sdfr 164178825Sdfr return _krb5_get_default_principal_local(context, princ); 165178825Sdfr} 166