1295367Sdes/* $Id: platform.c,v 1.22 2014/07/18 04:11:26 djm Exp $ */ 2162852Sdes 3162852Sdes/* 4162852Sdes * Copyright (c) 2006 Darren Tucker. All rights reserved. 5162852Sdes * 6162852Sdes * Permission to use, copy, modify, and distribute this software for any 7162852Sdes * purpose with or without fee is hereby granted, provided that the above 8162852Sdes * copyright notice and this permission notice appear in all copies. 9162852Sdes * 10162852Sdes * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11162852Sdes * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12162852Sdes * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13162852Sdes * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14162852Sdes * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15162852Sdes * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16162852Sdes * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17162852Sdes */ 18162852Sdes 19221420Sdes#include "includes.h" 20221420Sdes 21221420Sdes#include <stdarg.h> 22221420Sdes#include <unistd.h> 23221420Sdes 24221420Sdes#include "log.h" 25221420Sdes#include "buffer.h" 26295367Sdes#include "misc.h" 27221420Sdes#include "servconf.h" 28221420Sdes#include "key.h" 29221420Sdes#include "hostfile.h" 30221420Sdes#include "auth.h" 31221420Sdes#include "auth-pam.h" 32162852Sdes#include "platform.h" 33162852Sdes 34162852Sdes#include "openbsd-compat/openbsd-compat.h" 35162852Sdes 36221420Sdesextern int use_privsep; 37221420Sdesextern ServerOptions options; 38221420Sdes 39162852Sdesvoid 40204917Sdesplatform_pre_listen(void) 41204917Sdes{ 42204917Sdes#ifdef LINUX_OOM_ADJUST 43204917Sdes /* Adjust out-of-memory killer so listening process is not killed */ 44204917Sdes oom_adjust_setup(); 45204917Sdes#endif 46204917Sdes} 47204917Sdes 48204917Sdesvoid 49162852Sdesplatform_pre_fork(void) 50162852Sdes{ 51162852Sdes#ifdef USE_SOLARIS_PROCESS_CONTRACTS 52162852Sdes solaris_contract_pre_fork(); 53162852Sdes#endif 54162852Sdes} 55162852Sdes 56162852Sdesvoid 57262566Sdesplatform_pre_restart(void) 58262566Sdes{ 59262566Sdes#ifdef LINUX_OOM_ADJUST 60262566Sdes oom_adjust_restore(); 61262566Sdes#endif 62262566Sdes} 63262566Sdes 64262566Sdesvoid 65162852Sdesplatform_post_fork_parent(pid_t child_pid) 66162852Sdes{ 67162852Sdes#ifdef USE_SOLARIS_PROCESS_CONTRACTS 68162852Sdes solaris_contract_post_fork_parent(child_pid); 69162852Sdes#endif 70162852Sdes} 71162852Sdes 72162852Sdesvoid 73162852Sdesplatform_post_fork_child(void) 74162852Sdes{ 75162852Sdes#ifdef USE_SOLARIS_PROCESS_CONTRACTS 76162852Sdes solaris_contract_post_fork_child(); 77162852Sdes#endif 78204917Sdes#ifdef LINUX_OOM_ADJUST 79204917Sdes oom_adjust_restore(); 80204917Sdes#endif 81162852Sdes} 82204917Sdes 83221420Sdes/* return 1 if we are running with privilege to swap UIDs, 0 otherwise */ 84221420Sdesint 85221420Sdesplatform_privileged_uidswap(void) 86221420Sdes{ 87221420Sdes#ifdef HAVE_CYGWIN 88221420Sdes /* uid 0 is not special on Cygwin so always try */ 89221420Sdes return 1; 90221420Sdes#else 91221420Sdes return (getuid() == 0 || geteuid() == 0); 92221420Sdes#endif 93221420Sdes} 94221420Sdes 95221420Sdes/* 96221420Sdes * This gets called before switching UIDs, and is called even when sshd is 97221420Sdes * not running as root. 98221420Sdes */ 99221420Sdesvoid 100221420Sdesplatform_setusercontext(struct passwd *pw) 101221420Sdes{ 102221420Sdes#ifdef WITH_SELINUX 103221420Sdes /* Cache selinux status for later use */ 104221420Sdes (void)ssh_selinux_enabled(); 105221420Sdes#endif 106221420Sdes 107221420Sdes#ifdef USE_SOLARIS_PROJECTS 108323124Sdes /* 109323124Sdes * If solaris projects were detected, set the default now, unless 110323124Sdes * we are using PAM in which case it is the responsibility of the 111323124Sdes * PAM stack. 112323124Sdes */ 113323124Sdes if (!options.use_pam && (getuid() == 0 || geteuid() == 0)) 114221420Sdes solaris_set_default_project(pw); 115221420Sdes#endif 116221420Sdes 117221420Sdes#if defined(HAVE_LOGIN_CAP) && defined (__bsdi__) 118221420Sdes if (getuid() == 0 || geteuid() == 0) 119221420Sdes setpgid(0, 0); 120221420Sdes# endif 121221420Sdes 122221420Sdes#if defined(HAVE_LOGIN_CAP) && defined(USE_PAM) 123221420Sdes /* 124221420Sdes * If we have both LOGIN_CAP and PAM, we want to establish creds 125221420Sdes * before calling setusercontext (in session.c:do_setusercontext). 126221420Sdes */ 127221420Sdes if (getuid() == 0 || geteuid() == 0) { 128221420Sdes if (options.use_pam) { 129221420Sdes do_pam_setcred(use_privsep); 130221420Sdes } 131221420Sdes } 132221420Sdes# endif /* USE_PAM */ 133221420Sdes 134221420Sdes#if !defined(HAVE_LOGIN_CAP) && defined(HAVE_GETLUID) && defined(HAVE_SETLUID) 135221420Sdes if (getuid() == 0 || geteuid() == 0) { 136221420Sdes /* Sets login uid for accounting */ 137221420Sdes if (getluid() == -1 && setluid(pw->pw_uid) == -1) 138221420Sdes error("setluid: %s", strerror(errno)); 139221420Sdes } 140221420Sdes#endif 141221420Sdes} 142221420Sdes 143221420Sdes/* 144221420Sdes * This gets called after we've established the user's groups, and is only 145221420Sdes * called if sshd is running as root. 146221420Sdes */ 147221420Sdesvoid 148221420Sdesplatform_setusercontext_post_groups(struct passwd *pw) 149221420Sdes{ 150221420Sdes#if !defined(HAVE_LOGIN_CAP) && defined(USE_PAM) 151221420Sdes /* 152221420Sdes * PAM credentials may take the form of supplementary groups. 153221420Sdes * These will have been wiped by the above initgroups() call. 154221420Sdes * Reestablish them here. 155221420Sdes */ 156221420Sdes if (options.use_pam) { 157221420Sdes do_pam_setcred(use_privsep); 158221420Sdes } 159221420Sdes#endif /* USE_PAM */ 160221420Sdes 161221420Sdes#if !defined(HAVE_LOGIN_CAP) && (defined(WITH_IRIX_PROJECT) || \ 162221420Sdes defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY)) 163221420Sdes irix_setusercontext(pw); 164221420Sdes#endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */ 165221420Sdes 166221420Sdes#ifdef _AIX 167221420Sdes aix_usrinfo(pw); 168221420Sdes#endif /* _AIX */ 169221420Sdes 170221420Sdes#ifdef HAVE_SETPCRED 171221420Sdes /* 172221420Sdes * If we have a chroot directory, we set all creds except real 173221420Sdes * uid which we will need for chroot. If we don't have a 174221420Sdes * chroot directory, we don't override anything. 175221420Sdes */ 176221420Sdes { 177221420Sdes char **creds = NULL, *chroot_creds[] = 178221420Sdes { "REAL_USER=root", NULL }; 179221420Sdes 180221420Sdes if (options.chroot_directory != NULL && 181221420Sdes strcasecmp(options.chroot_directory, "none") != 0) 182221420Sdes creds = chroot_creds; 183221420Sdes 184221420Sdes if (setpcred(pw->pw_name, creds) == -1) 185221420Sdes fatal("Failed to set process credentials"); 186221420Sdes } 187221420Sdes#endif /* HAVE_SETPCRED */ 188221420Sdes#ifdef WITH_SELINUX 189221420Sdes ssh_selinux_setup_exec_context(pw->pw_name); 190221420Sdes#endif 191221420Sdes} 192221420Sdes 193204917Sdeschar * 194204917Sdesplatform_krb5_get_principal_name(const char *pw_name) 195204917Sdes{ 196204917Sdes#ifdef USE_AIX_KRB_NAME 197204917Sdes return aix_krb5_get_principal_name(pw_name); 198204917Sdes#else 199204917Sdes return NULL; 200204917Sdes#endif 201204917Sdes} 202248619Sdes 203248619Sdes/* 204248619Sdes * return 1 if the specified uid is a uid that may own a system directory 205248619Sdes * otherwise 0. 206248619Sdes */ 207248619Sdesint 208248619Sdesplatform_sys_dir_uid(uid_t uid) 209248619Sdes{ 210248619Sdes if (uid == 0) 211248619Sdes return 1; 212248619Sdes#ifdef PLATFORM_SYS_DIR_UID 213248619Sdes if (uid == PLATFORM_SYS_DIR_UID) 214248619Sdes return 1; 215248619Sdes#endif 216248619Sdes return 0; 217248619Sdes} 218