platform.c revision 262566
1/* $Id: platform.c,v 1.21 2014/01/21 01:59:29 tim Exp $ */ 2 3/* 4 * Copyright (c) 2006 Darren Tucker. All rights reserved. 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19#include "includes.h" 20 21#include <sys/types.h> 22 23#include <stdarg.h> 24#include <unistd.h> 25 26#include "log.h" 27#include "buffer.h" 28#include "servconf.h" 29#include "key.h" 30#include "hostfile.h" 31#include "auth.h" 32#include "auth-pam.h" 33#include "platform.h" 34 35#include "openbsd-compat/openbsd-compat.h" 36 37extern int use_privsep; 38extern ServerOptions options; 39 40void 41platform_pre_listen(void) 42{ 43#ifdef LINUX_OOM_ADJUST 44 /* Adjust out-of-memory killer so listening process is not killed */ 45 oom_adjust_setup(); 46#endif 47} 48 49void 50platform_pre_fork(void) 51{ 52#ifdef USE_SOLARIS_PROCESS_CONTRACTS 53 solaris_contract_pre_fork(); 54#endif 55} 56 57void 58platform_pre_restart(void) 59{ 60#ifdef LINUX_OOM_ADJUST 61 oom_adjust_restore(); 62#endif 63} 64 65void 66platform_post_fork_parent(pid_t child_pid) 67{ 68#ifdef USE_SOLARIS_PROCESS_CONTRACTS 69 solaris_contract_post_fork_parent(child_pid); 70#endif 71} 72 73void 74platform_post_fork_child(void) 75{ 76#ifdef USE_SOLARIS_PROCESS_CONTRACTS 77 solaris_contract_post_fork_child(); 78#endif 79#ifdef LINUX_OOM_ADJUST 80 oom_adjust_restore(); 81#endif 82} 83 84/* return 1 if we are running with privilege to swap UIDs, 0 otherwise */ 85int 86platform_privileged_uidswap(void) 87{ 88#ifdef HAVE_CYGWIN 89 /* uid 0 is not special on Cygwin so always try */ 90 return 1; 91#else 92 return (getuid() == 0 || geteuid() == 0); 93#endif 94} 95 96/* 97 * This gets called before switching UIDs, and is called even when sshd is 98 * not running as root. 99 */ 100void 101platform_setusercontext(struct passwd *pw) 102{ 103#ifdef WITH_SELINUX 104 /* Cache selinux status for later use */ 105 (void)ssh_selinux_enabled(); 106#endif 107 108#ifdef USE_SOLARIS_PROJECTS 109 /* if solaris projects were detected, set the default now */ 110 if (getuid() == 0 || geteuid() == 0) 111 solaris_set_default_project(pw); 112#endif 113 114#if defined(HAVE_LOGIN_CAP) && defined (__bsdi__) 115 if (getuid() == 0 || geteuid() == 0) 116 setpgid(0, 0); 117# endif 118 119#if defined(HAVE_LOGIN_CAP) && defined(USE_PAM) 120 /* 121 * If we have both LOGIN_CAP and PAM, we want to establish creds 122 * before calling setusercontext (in session.c:do_setusercontext). 123 */ 124 if (getuid() == 0 || geteuid() == 0) { 125 if (options.use_pam) { 126 do_pam_setcred(use_privsep); 127 } 128 } 129# endif /* USE_PAM */ 130 131#if !defined(HAVE_LOGIN_CAP) && defined(HAVE_GETLUID) && defined(HAVE_SETLUID) 132 if (getuid() == 0 || geteuid() == 0) { 133 /* Sets login uid for accounting */ 134 if (getluid() == -1 && setluid(pw->pw_uid) == -1) 135 error("setluid: %s", strerror(errno)); 136 } 137#endif 138} 139 140/* 141 * This gets called after we've established the user's groups, and is only 142 * called if sshd is running as root. 143 */ 144void 145platform_setusercontext_post_groups(struct passwd *pw) 146{ 147#if !defined(HAVE_LOGIN_CAP) && defined(USE_PAM) 148 /* 149 * PAM credentials may take the form of supplementary groups. 150 * These will have been wiped by the above initgroups() call. 151 * Reestablish them here. 152 */ 153 if (options.use_pam) { 154 do_pam_setcred(use_privsep); 155 } 156#endif /* USE_PAM */ 157 158#if !defined(HAVE_LOGIN_CAP) && (defined(WITH_IRIX_PROJECT) || \ 159 defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY)) 160 irix_setusercontext(pw); 161#endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */ 162 163#ifdef _AIX 164 aix_usrinfo(pw); 165#endif /* _AIX */ 166 167#ifdef HAVE_SETPCRED 168 /* 169 * If we have a chroot directory, we set all creds except real 170 * uid which we will need for chroot. If we don't have a 171 * chroot directory, we don't override anything. 172 */ 173 { 174 char **creds = NULL, *chroot_creds[] = 175 { "REAL_USER=root", NULL }; 176 177 if (options.chroot_directory != NULL && 178 strcasecmp(options.chroot_directory, "none") != 0) 179 creds = chroot_creds; 180 181 if (setpcred(pw->pw_name, creds) == -1) 182 fatal("Failed to set process credentials"); 183 } 184#endif /* HAVE_SETPCRED */ 185#ifdef WITH_SELINUX 186 ssh_selinux_setup_exec_context(pw->pw_name); 187#endif 188} 189 190char * 191platform_krb5_get_principal_name(const char *pw_name) 192{ 193#ifdef USE_AIX_KRB_NAME 194 return aix_krb5_get_principal_name(pw_name); 195#else 196 return NULL; 197#endif 198} 199 200/* 201 * return 1 if the specified uid is a uid that may own a system directory 202 * otherwise 0. 203 */ 204int 205platform_sys_dir_uid(uid_t uid) 206{ 207 if (uid == 0) 208 return 1; 209#ifdef PLATFORM_SYS_DIR_UID 210 if (uid == PLATFORM_SYS_DIR_UID) 211 return 1; 212#endif 213 return 0; 214} 215