1139804Simp/* $Id: platform.c,v 1.22 2014/07/18 04:11:26 djm Exp $ */ 21541Srgrimes 31541Srgrimes/* 41541Srgrimes * Copyright (c) 2006 Darren Tucker. All rights reserved. 51541Srgrimes * 61541Srgrimes * Permission to use, copy, modify, and distribute this software for any 71541Srgrimes * purpose with or without fee is hereby granted, provided that the above 81541Srgrimes * copyright notice and this permission notice appear in all copies. 91541Srgrimes * 101541Srgrimes * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 111541Srgrimes * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 121541Srgrimes * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 131541Srgrimes * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 141541Srgrimes * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 151541Srgrimes * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 161541Srgrimes * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 171541Srgrimes */ 181541Srgrimes 191541Srgrimes#include "includes.h" 201541Srgrimes 211541Srgrimes#include <sys/types.h> 221541Srgrimes 231541Srgrimes#include <stdarg.h> 241541Srgrimes#include <unistd.h> 251541Srgrimes 261541Srgrimes#include "log.h" 271541Srgrimes#include "buffer.h" 281541Srgrimes#include "misc.h" 291541Srgrimes#include "servconf.h" 301541Srgrimes#include "key.h" 311541Srgrimes#include "hostfile.h" 32116182Sobrien#include "auth.h" 33116182Sobrien#include "auth-pam.h" 34116182Sobrien#include "platform.h" 3531778Seivind 3631778Seivind#include "openbsd-compat/openbsd-compat.h" 371541Srgrimes 381541Srgrimesextern int use_privsep; 3912221Sbdeextern ServerOptions options; 401541Srgrimes 41164033Srwatsonvoid 421541Srgrimesplatform_pre_listen(void) 4382717Sdillon{ 4482717Sdillon#ifdef LINUX_OOM_ADJUST 45186570Sed /* Adjust out-of-memory killer so listening process is not killed */ 461541Srgrimes oom_adjust_setup(); 471549Srgrimes#endif 481541Srgrimes} 49186570Sed 508876Srgrimesvoid 51130344Sphkplatform_pre_fork(void) 521541Srgrimes{ 5312221Sbde#ifdef USE_SOLARIS_PROCESS_CONTRACTS 541541Srgrimes solaris_contract_pre_fork(); 551541Srgrimes#endif 561541Srgrimes} 571541Srgrimes 5812221Sbdevoid 591541Srgrimesplatform_pre_restart(void) 601549Srgrimes{ 6183366Sjulian#ifdef LINUX_OOM_ADJUST 6283366Sjulian oom_adjust_restore(); 631541Srgrimes#endif 641541Srgrimes} 6512171Sphk 6638517Sdfrvoid 671541Srgrimesplatform_post_fork_parent(pid_t child_pid) 6812171Sphk{ 6912171Sphk#ifdef USE_SOLARIS_PROCESS_CONTRACTS 70186564Sed solaris_contract_post_fork_parent(child_pid); 71186564Sed#endif 721541Srgrimes} 731541Srgrimes 7412221Sbdevoid 751541Srgrimesplatform_post_fork_child(void) 761541Srgrimes{ 771541Srgrimes#ifdef USE_SOLARIS_PROCESS_CONTRACTS 781541Srgrimes solaris_contract_post_fork_child(); 7912221Sbde#endif 801541Srgrimes#ifdef LINUX_OOM_ADJUST 811549Srgrimes oom_adjust_restore(); 8283366Sjulian#endif 8383366Sjulian} 841541Srgrimes 851541Srgrimes/* return 1 if we are running with privilege to swap UIDs, 0 otherwise */ 8612171Sphkint 871541Srgrimesplatform_privileged_uidswap(void) 8812171Sphk{ 8912171Sphk#ifdef HAVE_CYGWIN 90186564Sed /* uid 0 is not special on Cygwin so always try */ 91186564Sed return 1; 921541Srgrimes#else 931541Srgrimes return (getuid() == 0 || geteuid() == 0); 9412221Sbde#endif 9512200Sbde} 961541Srgrimes 971541Srgrimes/* 9812221Sbde * This gets called before switching UIDs, and is called even when sshd is 991541Srgrimes * not running as root. 1001549Srgrimes */ 10183366Sjulianvoid 10283366Sjulianplatform_setusercontext(struct passwd *pw) 10312200Sbde{ 1041541Srgrimes#ifdef WITH_SELINUX 105193066Sjamie /* Cache selinux status for later use */ 106193066Sjamie (void)ssh_selinux_enabled(); 1071541Srgrimes#endif 108193066Sjamie 109193066Sjamie#ifdef USE_SOLARIS_PROJECTS 110193066Sjamie /* if solaris projects were detected, set the default now */ 111193066Sjamie if (getuid() == 0 || geteuid() == 0) 1121541Srgrimes solaris_set_default_project(pw); 113130344Sphk#endif 1141541Srgrimes 1151541Srgrimes#if defined(HAVE_LOGIN_CAP) && defined (__bsdi__) 11612221Sbde if (getuid() == 0 || geteuid() == 0) 11712200Sbde setpgid(0, 0); 1181541Srgrimes# endif 1191541Srgrimes 12012221Sbde#if defined(HAVE_LOGIN_CAP) && defined(USE_PAM) 1211541Srgrimes /* 1221549Srgrimes * If we have both LOGIN_CAP and PAM, we want to establish creds 12383366Sjulian * before calling setusercontext (in session.c:do_setusercontext). 12483366Sjulian */ 12512200Sbde if (getuid() == 0 || geteuid() == 0) { 1261541Srgrimes if (options.use_pam) { 127193066Sjamie do_pam_setcred(use_privsep); 1281541Srgrimes } 129193066Sjamie } 130193066Sjamie# endif /* USE_PAM */ 131193066Sjamie 132193066Sjamie#if !defined(HAVE_LOGIN_CAP) && defined(HAVE_GETLUID) && defined(HAVE_SETLUID) 1331541Srgrimes if (getuid() == 0 || geteuid() == 0) { 1341541Srgrimes /* Sets login uid for accounting */ 1351549Srgrimes if (getluid() == -1 && setluid(pw->pw_uid) == -1) 13683366Sjulian error("setluid: %s", strerror(errno)); 13783366Sjulian } 13812200Sbde#endif 1391541Srgrimes} 140167232Srwatson 1411541Srgrimes/* 1421541Srgrimes * This gets called after we've established the user's groups, and is only 143186570Sed * called if sshd is running as root. 144186570Sed */ 145186570Sedvoid 146186570Sedplatform_setusercontext_post_groups(struct passwd *pw) 147186570Sed{ 148186570Sed#if !defined(HAVE_LOGIN_CAP) && defined(USE_PAM) 149186570Sed /* 150186570Sed * PAM credentials may take the form of supplementary groups. 151186570Sed * These will have been wiped by the above initgroups() call. 152186570Sed * Reestablish them here. 153186570Sed */ 154186570Sed if (options.use_pam) { 155186570Sed do_pam_setcred(use_privsep); 156186570Sed } 157186570Sed#endif /* USE_PAM */ 158186570Sed 159186570Sed#if !defined(HAVE_LOGIN_CAP) && (defined(WITH_IRIX_PROJECT) || \ 160186570Sed defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY)) 161186570Sed irix_setusercontext(pw); 162186570Sed#endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */ 163186570Sed 164186570Sed#ifdef _AIX 165186570Sed aix_usrinfo(pw); 166186570Sed#endif /* _AIX */ 167186570Sed 168186570Sed#ifdef HAVE_SETPCRED 169186570Sed /* 170186570Sed * If we have a chroot directory, we set all creds except real 171186570Sed * uid which we will need for chroot. If we don't have a 172186570Sed * chroot directory, we don't override anything. 173186570Sed */ 174186570Sed { 175186570Sed char **creds = NULL, *chroot_creds[] = 176186570Sed { "REAL_USER=root", NULL }; 177186570Sed 178186570Sed if (options.chroot_directory != NULL && 179186570Sed strcasecmp(options.chroot_directory, "none") != 0) 180186570Sed creds = chroot_creds; 181186570Sed 182186570Sed if (setpcred(pw->pw_name, creds) == -1) 183186570Sed fatal("Failed to set process credentials"); 184186570Sed } 185186570Sed#endif /* HAVE_SETPCRED */ 186186570Sed#ifdef WITH_SELINUX 187186570Sed ssh_selinux_setup_exec_context(pw->pw_name); 188186570Sed#endif 189186570Sed} 190186570Sed 191186570Sedchar * 192186570Sedplatform_krb5_get_principal_name(const char *pw_name) 193186570Sed{ 194186570Sed#ifdef USE_AIX_KRB_NAME 195186570Sed return aix_krb5_get_principal_name(pw_name); 196186570Sed#else 197186570Sed return NULL; 198186570Sed#endif 199186570Sed} 200186570Sed 201186570Sed/* 202186570Sed * return 1 if the specified uid is a uid that may own a system directory 203186570Sed * otherwise 0. 204186570Sed */ 205186570Sedint 206186570Sedplatform_sys_dir_uid(uid_t uid) 207186570Sed{ 208186570Sed if (uid == 0) 209186570Sed return 1; 210186570Sed#ifdef PLATFORM_SYS_DIR_UID 211186570Sed if (uid == PLATFORM_SYS_DIR_UID) 212186570Sed return 1; 213186570Sed#endif 214186570Sed return 0; 215186570Sed} 216186570Sed