1 /* 2 * Copyright (c) 2006 Darren Tucker. All rights reserved. 3 * 4 * Permission to use, copy, modify, and distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 #include "includes.h" 18 19 #include <stdarg.h> 20 #include <unistd.h> 21 22 #include "log.h" 23 #include "misc.h" 24 #include "servconf.h" 25 #include "sshkey.h" 26 #include "hostfile.h" 27 #include "auth.h" 28 #include "auth-pam.h" 29 #include "platform.h" 30 31 #include "openbsd-compat/openbsd-compat.h" 32 33 extern int use_privsep; 34 extern ServerOptions options; 35 36 void 37 platform_pre_listen(void) 38 { 39 #ifdef LINUX_OOM_ADJUST 40 /* Adjust out-of-memory killer so listening process is not killed */ 41 oom_adjust_setup(); 42 #endif 43 } 44 45 void 46 platform_pre_fork(void) 47 { 48 #ifdef USE_SOLARIS_PROCESS_CONTRACTS 49 solaris_contract_pre_fork(); 50 #endif 51 } 52 53 void 54 platform_pre_restart(void) 55 { 56 #ifdef LINUX_OOM_ADJUST 57 oom_adjust_restore(); 58 #endif 59 } 60 61 void 62 platform_post_fork_parent(pid_t child_pid) 63 { 64 #ifdef USE_SOLARIS_PROCESS_CONTRACTS 65 solaris_contract_post_fork_parent(child_pid); 66 #endif 67 } 68 69 void 70 platform_post_fork_child(void) 71 { 72 #ifdef USE_SOLARIS_PROCESS_CONTRACTS 73 solaris_contract_post_fork_child(); 74 #endif 75 #ifdef LINUX_OOM_ADJUST 76 oom_adjust_restore(); 77 #endif 78 } 79 80 /* return 1 if we are running with privilege to swap UIDs, 0 otherwise */ 81 int 82 platform_privileged_uidswap(void) 83 { 84 #ifdef HAVE_CYGWIN 85 /* uid 0 is not special on Cygwin so always try */ 86 return 1; 87 #else 88 return (getuid() == 0 || geteuid() == 0); 89 #endif 90 } 91 92 /* 93 * This gets called before switching UIDs, and is called even when sshd is 94 * not running as root. 95 */ 96 void 97 platform_setusercontext(struct passwd *pw) 98 { 99 #ifdef WITH_SELINUX 100 /* Cache selinux status for later use */ 101 (void)ssh_selinux_enabled(); 102 #endif 103 104 #ifdef USE_SOLARIS_PROJECTS 105 /* 106 * If solaris projects were detected, set the default now, unless 107 * we are using PAM in which case it is the responsibility of the 108 * PAM stack. 109 */ 110 if (!options.use_pam && (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 */ 144 void 145 platform_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 190 char * 191 platform_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