1*4a421b63SDag-Erling Smørgrav /* $Id: platform.c,v 1.18 2011/01/11 06:02:25 djm Exp $ */ 2761efaa7SDag-Erling Smørgrav 3761efaa7SDag-Erling Smørgrav /* 4761efaa7SDag-Erling Smørgrav * Copyright (c) 2006 Darren Tucker. All rights reserved. 5761efaa7SDag-Erling Smørgrav * 6761efaa7SDag-Erling Smørgrav * Permission to use, copy, modify, and distribute this software for any 7761efaa7SDag-Erling Smørgrav * purpose with or without fee is hereby granted, provided that the above 8761efaa7SDag-Erling Smørgrav * copyright notice and this permission notice appear in all copies. 9761efaa7SDag-Erling Smørgrav * 10761efaa7SDag-Erling Smørgrav * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11761efaa7SDag-Erling Smørgrav * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12761efaa7SDag-Erling Smørgrav * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13761efaa7SDag-Erling Smørgrav * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14761efaa7SDag-Erling Smørgrav * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15761efaa7SDag-Erling Smørgrav * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16761efaa7SDag-Erling Smørgrav * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17761efaa7SDag-Erling Smørgrav */ 18761efaa7SDag-Erling Smørgrav 19*4a421b63SDag-Erling Smørgrav #include "includes.h" 20*4a421b63SDag-Erling Smørgrav 21*4a421b63SDag-Erling Smørgrav #include <sys/types.h> 22*4a421b63SDag-Erling Smørgrav 23*4a421b63SDag-Erling Smørgrav #include <stdarg.h> 24*4a421b63SDag-Erling Smørgrav #include <unistd.h> 25*4a421b63SDag-Erling Smørgrav 26*4a421b63SDag-Erling Smørgrav #include "log.h" 27*4a421b63SDag-Erling Smørgrav #include "buffer.h" 28*4a421b63SDag-Erling Smørgrav #include "servconf.h" 29*4a421b63SDag-Erling Smørgrav #include "key.h" 30*4a421b63SDag-Erling Smørgrav #include "hostfile.h" 31*4a421b63SDag-Erling Smørgrav #include "auth.h" 32*4a421b63SDag-Erling Smørgrav #include "auth-pam.h" 33761efaa7SDag-Erling Smørgrav #include "platform.h" 34761efaa7SDag-Erling Smørgrav 35761efaa7SDag-Erling Smørgrav #include "openbsd-compat/openbsd-compat.h" 36761efaa7SDag-Erling Smørgrav 37*4a421b63SDag-Erling Smørgrav extern int use_privsep; 38*4a421b63SDag-Erling Smørgrav extern ServerOptions options; 39*4a421b63SDag-Erling Smørgrav 40761efaa7SDag-Erling Smørgrav void 41b15c8340SDag-Erling Smørgrav platform_pre_listen(void) 42b15c8340SDag-Erling Smørgrav { 43b15c8340SDag-Erling Smørgrav #ifdef LINUX_OOM_ADJUST 44b15c8340SDag-Erling Smørgrav /* Adjust out-of-memory killer so listening process is not killed */ 45b15c8340SDag-Erling Smørgrav oom_adjust_setup(); 46b15c8340SDag-Erling Smørgrav #endif 47b15c8340SDag-Erling Smørgrav } 48b15c8340SDag-Erling Smørgrav 49b15c8340SDag-Erling Smørgrav void 50761efaa7SDag-Erling Smørgrav platform_pre_fork(void) 51761efaa7SDag-Erling Smørgrav { 52761efaa7SDag-Erling Smørgrav #ifdef USE_SOLARIS_PROCESS_CONTRACTS 53761efaa7SDag-Erling Smørgrav solaris_contract_pre_fork(); 54761efaa7SDag-Erling Smørgrav #endif 55761efaa7SDag-Erling Smørgrav } 56761efaa7SDag-Erling Smørgrav 57761efaa7SDag-Erling Smørgrav void 58761efaa7SDag-Erling Smørgrav platform_post_fork_parent(pid_t child_pid) 59761efaa7SDag-Erling Smørgrav { 60761efaa7SDag-Erling Smørgrav #ifdef USE_SOLARIS_PROCESS_CONTRACTS 61761efaa7SDag-Erling Smørgrav solaris_contract_post_fork_parent(child_pid); 62761efaa7SDag-Erling Smørgrav #endif 63761efaa7SDag-Erling Smørgrav } 64761efaa7SDag-Erling Smørgrav 65761efaa7SDag-Erling Smørgrav void 66761efaa7SDag-Erling Smørgrav platform_post_fork_child(void) 67761efaa7SDag-Erling Smørgrav { 68761efaa7SDag-Erling Smørgrav #ifdef USE_SOLARIS_PROCESS_CONTRACTS 69761efaa7SDag-Erling Smørgrav solaris_contract_post_fork_child(); 70761efaa7SDag-Erling Smørgrav #endif 71b15c8340SDag-Erling Smørgrav #ifdef LINUX_OOM_ADJUST 72b15c8340SDag-Erling Smørgrav oom_adjust_restore(); 73b15c8340SDag-Erling Smørgrav #endif 74b15c8340SDag-Erling Smørgrav } 75b15c8340SDag-Erling Smørgrav 76*4a421b63SDag-Erling Smørgrav /* return 1 if we are running with privilege to swap UIDs, 0 otherwise */ 77*4a421b63SDag-Erling Smørgrav int 78*4a421b63SDag-Erling Smørgrav platform_privileged_uidswap(void) 79*4a421b63SDag-Erling Smørgrav { 80*4a421b63SDag-Erling Smørgrav #ifdef HAVE_CYGWIN 81*4a421b63SDag-Erling Smørgrav /* uid 0 is not special on Cygwin so always try */ 82*4a421b63SDag-Erling Smørgrav return 1; 83*4a421b63SDag-Erling Smørgrav #else 84*4a421b63SDag-Erling Smørgrav return (getuid() == 0 || geteuid() == 0); 85*4a421b63SDag-Erling Smørgrav #endif 86*4a421b63SDag-Erling Smørgrav } 87*4a421b63SDag-Erling Smørgrav 88*4a421b63SDag-Erling Smørgrav /* 89*4a421b63SDag-Erling Smørgrav * This gets called before switching UIDs, and is called even when sshd is 90*4a421b63SDag-Erling Smørgrav * not running as root. 91*4a421b63SDag-Erling Smørgrav */ 92*4a421b63SDag-Erling Smørgrav void 93*4a421b63SDag-Erling Smørgrav platform_setusercontext(struct passwd *pw) 94*4a421b63SDag-Erling Smørgrav { 95*4a421b63SDag-Erling Smørgrav #ifdef WITH_SELINUX 96*4a421b63SDag-Erling Smørgrav /* Cache selinux status for later use */ 97*4a421b63SDag-Erling Smørgrav (void)ssh_selinux_enabled(); 98*4a421b63SDag-Erling Smørgrav #endif 99*4a421b63SDag-Erling Smørgrav 100*4a421b63SDag-Erling Smørgrav #ifdef USE_SOLARIS_PROJECTS 101*4a421b63SDag-Erling Smørgrav /* if solaris projects were detected, set the default now */ 102*4a421b63SDag-Erling Smørgrav if (getuid() == 0 || geteuid() == 0) 103*4a421b63SDag-Erling Smørgrav solaris_set_default_project(pw); 104*4a421b63SDag-Erling Smørgrav #endif 105*4a421b63SDag-Erling Smørgrav 106*4a421b63SDag-Erling Smørgrav #if defined(HAVE_LOGIN_CAP) && defined (__bsdi__) 107*4a421b63SDag-Erling Smørgrav if (getuid() == 0 || geteuid() == 0) 108*4a421b63SDag-Erling Smørgrav setpgid(0, 0); 109*4a421b63SDag-Erling Smørgrav # endif 110*4a421b63SDag-Erling Smørgrav 111*4a421b63SDag-Erling Smørgrav #if defined(HAVE_LOGIN_CAP) && defined(USE_PAM) 112*4a421b63SDag-Erling Smørgrav /* 113*4a421b63SDag-Erling Smørgrav * If we have both LOGIN_CAP and PAM, we want to establish creds 114*4a421b63SDag-Erling Smørgrav * before calling setusercontext (in session.c:do_setusercontext). 115*4a421b63SDag-Erling Smørgrav */ 116*4a421b63SDag-Erling Smørgrav if (getuid() == 0 || geteuid() == 0) { 117*4a421b63SDag-Erling Smørgrav if (options.use_pam) { 118*4a421b63SDag-Erling Smørgrav do_pam_setcred(use_privsep); 119*4a421b63SDag-Erling Smørgrav } 120*4a421b63SDag-Erling Smørgrav } 121*4a421b63SDag-Erling Smørgrav # endif /* USE_PAM */ 122*4a421b63SDag-Erling Smørgrav 123*4a421b63SDag-Erling Smørgrav #if !defined(HAVE_LOGIN_CAP) && defined(HAVE_GETLUID) && defined(HAVE_SETLUID) 124*4a421b63SDag-Erling Smørgrav if (getuid() == 0 || geteuid() == 0) { 125*4a421b63SDag-Erling Smørgrav /* Sets login uid for accounting */ 126*4a421b63SDag-Erling Smørgrav if (getluid() == -1 && setluid(pw->pw_uid) == -1) 127*4a421b63SDag-Erling Smørgrav error("setluid: %s", strerror(errno)); 128*4a421b63SDag-Erling Smørgrav } 129*4a421b63SDag-Erling Smørgrav #endif 130*4a421b63SDag-Erling Smørgrav } 131*4a421b63SDag-Erling Smørgrav 132*4a421b63SDag-Erling Smørgrav /* 133*4a421b63SDag-Erling Smørgrav * This gets called after we've established the user's groups, and is only 134*4a421b63SDag-Erling Smørgrav * called if sshd is running as root. 135*4a421b63SDag-Erling Smørgrav */ 136*4a421b63SDag-Erling Smørgrav void 137*4a421b63SDag-Erling Smørgrav platform_setusercontext_post_groups(struct passwd *pw) 138*4a421b63SDag-Erling Smørgrav { 139*4a421b63SDag-Erling Smørgrav #if !defined(HAVE_LOGIN_CAP) && defined(USE_PAM) 140*4a421b63SDag-Erling Smørgrav /* 141*4a421b63SDag-Erling Smørgrav * PAM credentials may take the form of supplementary groups. 142*4a421b63SDag-Erling Smørgrav * These will have been wiped by the above initgroups() call. 143*4a421b63SDag-Erling Smørgrav * Reestablish them here. 144*4a421b63SDag-Erling Smørgrav */ 145*4a421b63SDag-Erling Smørgrav if (options.use_pam) { 146*4a421b63SDag-Erling Smørgrav do_pam_setcred(use_privsep); 147*4a421b63SDag-Erling Smørgrav } 148*4a421b63SDag-Erling Smørgrav #endif /* USE_PAM */ 149*4a421b63SDag-Erling Smørgrav 150*4a421b63SDag-Erling Smørgrav #if !defined(HAVE_LOGIN_CAP) && (defined(WITH_IRIX_PROJECT) || \ 151*4a421b63SDag-Erling Smørgrav defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY)) 152*4a421b63SDag-Erling Smørgrav irix_setusercontext(pw); 153*4a421b63SDag-Erling Smørgrav #endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */ 154*4a421b63SDag-Erling Smørgrav 155*4a421b63SDag-Erling Smørgrav #ifdef _AIX 156*4a421b63SDag-Erling Smørgrav aix_usrinfo(pw); 157*4a421b63SDag-Erling Smørgrav #endif /* _AIX */ 158*4a421b63SDag-Erling Smørgrav 159*4a421b63SDag-Erling Smørgrav #if !defined(HAVE_LOGIN_CAP) && defined(USE_LIBIAF) 160*4a421b63SDag-Erling Smørgrav if (set_id(pw->pw_name) != 0) { 161*4a421b63SDag-Erling Smørgrav exit(1); 162*4a421b63SDag-Erling Smørgrav } 163*4a421b63SDag-Erling Smørgrav # endif /* USE_LIBIAF */ 164*4a421b63SDag-Erling Smørgrav 165*4a421b63SDag-Erling Smørgrav #ifdef HAVE_SETPCRED 166*4a421b63SDag-Erling Smørgrav /* 167*4a421b63SDag-Erling Smørgrav * If we have a chroot directory, we set all creds except real 168*4a421b63SDag-Erling Smørgrav * uid which we will need for chroot. If we don't have a 169*4a421b63SDag-Erling Smørgrav * chroot directory, we don't override anything. 170*4a421b63SDag-Erling Smørgrav */ 171*4a421b63SDag-Erling Smørgrav { 172*4a421b63SDag-Erling Smørgrav char **creds = NULL, *chroot_creds[] = 173*4a421b63SDag-Erling Smørgrav { "REAL_USER=root", NULL }; 174*4a421b63SDag-Erling Smørgrav 175*4a421b63SDag-Erling Smørgrav if (options.chroot_directory != NULL && 176*4a421b63SDag-Erling Smørgrav strcasecmp(options.chroot_directory, "none") != 0) 177*4a421b63SDag-Erling Smørgrav creds = chroot_creds; 178*4a421b63SDag-Erling Smørgrav 179*4a421b63SDag-Erling Smørgrav if (setpcred(pw->pw_name, creds) == -1) 180*4a421b63SDag-Erling Smørgrav fatal("Failed to set process credentials"); 181*4a421b63SDag-Erling Smørgrav } 182*4a421b63SDag-Erling Smørgrav #endif /* HAVE_SETPCRED */ 183*4a421b63SDag-Erling Smørgrav #ifdef WITH_SELINUX 184*4a421b63SDag-Erling Smørgrav ssh_selinux_setup_exec_context(pw->pw_name); 185*4a421b63SDag-Erling Smørgrav #endif 186*4a421b63SDag-Erling Smørgrav } 187*4a421b63SDag-Erling Smørgrav 188b15c8340SDag-Erling Smørgrav char * 189b15c8340SDag-Erling Smørgrav platform_krb5_get_principal_name(const char *pw_name) 190b15c8340SDag-Erling Smørgrav { 191b15c8340SDag-Erling Smørgrav #ifdef USE_AIX_KRB_NAME 192b15c8340SDag-Erling Smørgrav return aix_krb5_get_principal_name(pw_name); 193b15c8340SDag-Erling Smørgrav #else 194b15c8340SDag-Erling Smørgrav return NULL; 195b15c8340SDag-Erling Smørgrav #endif 196761efaa7SDag-Erling Smørgrav } 197