1*36e94dc5SPeter Avalos /* $Id: platform.c,v 1.22 2014/07/18 04:11:26 djm Exp $ */ 218de8d7fSPeter Avalos 318de8d7fSPeter Avalos /* 418de8d7fSPeter Avalos * Copyright (c) 2006 Darren Tucker. All rights reserved. 518de8d7fSPeter Avalos * 618de8d7fSPeter Avalos * Permission to use, copy, modify, and distribute this software for any 718de8d7fSPeter Avalos * purpose with or without fee is hereby granted, provided that the above 818de8d7fSPeter Avalos * copyright notice and this permission notice appear in all copies. 918de8d7fSPeter Avalos * 1018de8d7fSPeter Avalos * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 1118de8d7fSPeter Avalos * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1218de8d7fSPeter Avalos * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 1318de8d7fSPeter Avalos * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1418de8d7fSPeter Avalos * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1518de8d7fSPeter Avalos * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1618de8d7fSPeter Avalos * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1718de8d7fSPeter Avalos */ 1818de8d7fSPeter Avalos 199f304aafSPeter Avalos #include "includes.h" 209f304aafSPeter Avalos 219f304aafSPeter Avalos #include <sys/types.h> 229f304aafSPeter Avalos 239f304aafSPeter Avalos #include <stdarg.h> 249f304aafSPeter Avalos #include <unistd.h> 259f304aafSPeter Avalos 269f304aafSPeter Avalos #include "log.h" 279f304aafSPeter Avalos #include "buffer.h" 28*36e94dc5SPeter Avalos #include "misc.h" 299f304aafSPeter Avalos #include "servconf.h" 309f304aafSPeter Avalos #include "key.h" 319f304aafSPeter Avalos #include "hostfile.h" 329f304aafSPeter Avalos #include "auth.h" 339f304aafSPeter Avalos #include "auth-pam.h" 3418de8d7fSPeter Avalos #include "platform.h" 3518de8d7fSPeter Avalos 3618de8d7fSPeter Avalos #include "openbsd-compat/openbsd-compat.h" 3718de8d7fSPeter Avalos 389f304aafSPeter Avalos extern int use_privsep; 399f304aafSPeter Avalos extern ServerOptions options; 409f304aafSPeter Avalos 4118de8d7fSPeter Avalos void 42856ea928SPeter Avalos platform_pre_listen(void) 43856ea928SPeter Avalos { 44856ea928SPeter Avalos #ifdef LINUX_OOM_ADJUST 45856ea928SPeter Avalos /* Adjust out-of-memory killer so listening process is not killed */ 46856ea928SPeter Avalos oom_adjust_setup(); 47856ea928SPeter Avalos #endif 48856ea928SPeter Avalos } 49856ea928SPeter Avalos 50856ea928SPeter Avalos void 5118de8d7fSPeter Avalos platform_pre_fork(void) 5218de8d7fSPeter Avalos { 5318de8d7fSPeter Avalos #ifdef USE_SOLARIS_PROCESS_CONTRACTS 5418de8d7fSPeter Avalos solaris_contract_pre_fork(); 5518de8d7fSPeter Avalos #endif 5618de8d7fSPeter Avalos } 5718de8d7fSPeter Avalos 5818de8d7fSPeter Avalos void 59*36e94dc5SPeter Avalos platform_pre_restart(void) 60*36e94dc5SPeter Avalos { 61*36e94dc5SPeter Avalos #ifdef LINUX_OOM_ADJUST 62*36e94dc5SPeter Avalos oom_adjust_restore(); 63*36e94dc5SPeter Avalos #endif 64*36e94dc5SPeter Avalos } 65*36e94dc5SPeter Avalos 66*36e94dc5SPeter Avalos void 6718de8d7fSPeter Avalos platform_post_fork_parent(pid_t child_pid) 6818de8d7fSPeter Avalos { 6918de8d7fSPeter Avalos #ifdef USE_SOLARIS_PROCESS_CONTRACTS 7018de8d7fSPeter Avalos solaris_contract_post_fork_parent(child_pid); 7118de8d7fSPeter Avalos #endif 7218de8d7fSPeter Avalos } 7318de8d7fSPeter Avalos 7418de8d7fSPeter Avalos void 7518de8d7fSPeter Avalos platform_post_fork_child(void) 7618de8d7fSPeter Avalos { 7718de8d7fSPeter Avalos #ifdef USE_SOLARIS_PROCESS_CONTRACTS 7818de8d7fSPeter Avalos solaris_contract_post_fork_child(); 7918de8d7fSPeter Avalos #endif 80856ea928SPeter Avalos #ifdef LINUX_OOM_ADJUST 81856ea928SPeter Avalos oom_adjust_restore(); 82856ea928SPeter Avalos #endif 83856ea928SPeter Avalos } 84856ea928SPeter Avalos 859f304aafSPeter Avalos /* return 1 if we are running with privilege to swap UIDs, 0 otherwise */ 869f304aafSPeter Avalos int 879f304aafSPeter Avalos platform_privileged_uidswap(void) 889f304aafSPeter Avalos { 899f304aafSPeter Avalos #ifdef HAVE_CYGWIN 909f304aafSPeter Avalos /* uid 0 is not special on Cygwin so always try */ 919f304aafSPeter Avalos return 1; 929f304aafSPeter Avalos #else 939f304aafSPeter Avalos return (getuid() == 0 || geteuid() == 0); 949f304aafSPeter Avalos #endif 959f304aafSPeter Avalos } 969f304aafSPeter Avalos 979f304aafSPeter Avalos /* 989f304aafSPeter Avalos * This gets called before switching UIDs, and is called even when sshd is 999f304aafSPeter Avalos * not running as root. 1009f304aafSPeter Avalos */ 1019f304aafSPeter Avalos void 1029f304aafSPeter Avalos platform_setusercontext(struct passwd *pw) 1039f304aafSPeter Avalos { 1049f304aafSPeter Avalos #ifdef WITH_SELINUX 1059f304aafSPeter Avalos /* Cache selinux status for later use */ 1069f304aafSPeter Avalos (void)ssh_selinux_enabled(); 1079f304aafSPeter Avalos #endif 1089f304aafSPeter Avalos 1099f304aafSPeter Avalos #ifdef USE_SOLARIS_PROJECTS 1109f304aafSPeter Avalos /* if solaris projects were detected, set the default now */ 1119f304aafSPeter Avalos if (getuid() == 0 || geteuid() == 0) 1129f304aafSPeter Avalos solaris_set_default_project(pw); 1139f304aafSPeter Avalos #endif 1149f304aafSPeter Avalos 1159f304aafSPeter Avalos #if defined(HAVE_LOGIN_CAP) && defined (__bsdi__) 1169f304aafSPeter Avalos if (getuid() == 0 || geteuid() == 0) 1179f304aafSPeter Avalos setpgid(0, 0); 1189f304aafSPeter Avalos # endif 1199f304aafSPeter Avalos 1209f304aafSPeter Avalos #if defined(HAVE_LOGIN_CAP) && defined(USE_PAM) 1219f304aafSPeter Avalos /* 1229f304aafSPeter Avalos * If we have both LOGIN_CAP and PAM, we want to establish creds 1239f304aafSPeter Avalos * before calling setusercontext (in session.c:do_setusercontext). 1249f304aafSPeter Avalos */ 1259f304aafSPeter Avalos if (getuid() == 0 || geteuid() == 0) { 1269f304aafSPeter Avalos if (options.use_pam) { 1279f304aafSPeter Avalos do_pam_setcred(use_privsep); 1289f304aafSPeter Avalos } 1299f304aafSPeter Avalos } 1309f304aafSPeter Avalos # endif /* USE_PAM */ 1319f304aafSPeter Avalos 1329f304aafSPeter Avalos #if !defined(HAVE_LOGIN_CAP) && defined(HAVE_GETLUID) && defined(HAVE_SETLUID) 1339f304aafSPeter Avalos if (getuid() == 0 || geteuid() == 0) { 1349f304aafSPeter Avalos /* Sets login uid for accounting */ 1359f304aafSPeter Avalos if (getluid() == -1 && setluid(pw->pw_uid) == -1) 1369f304aafSPeter Avalos error("setluid: %s", strerror(errno)); 1379f304aafSPeter Avalos } 1389f304aafSPeter Avalos #endif 1399f304aafSPeter Avalos } 1409f304aafSPeter Avalos 1419f304aafSPeter Avalos /* 1429f304aafSPeter Avalos * This gets called after we've established the user's groups, and is only 1439f304aafSPeter Avalos * called if sshd is running as root. 1449f304aafSPeter Avalos */ 1459f304aafSPeter Avalos void 1469f304aafSPeter Avalos platform_setusercontext_post_groups(struct passwd *pw) 1479f304aafSPeter Avalos { 1489f304aafSPeter Avalos #if !defined(HAVE_LOGIN_CAP) && defined(USE_PAM) 1499f304aafSPeter Avalos /* 1509f304aafSPeter Avalos * PAM credentials may take the form of supplementary groups. 1519f304aafSPeter Avalos * These will have been wiped by the above initgroups() call. 1529f304aafSPeter Avalos * Reestablish them here. 1539f304aafSPeter Avalos */ 1549f304aafSPeter Avalos if (options.use_pam) { 1559f304aafSPeter Avalos do_pam_setcred(use_privsep); 1569f304aafSPeter Avalos } 1579f304aafSPeter Avalos #endif /* USE_PAM */ 1589f304aafSPeter Avalos 1599f304aafSPeter Avalos #if !defined(HAVE_LOGIN_CAP) && (defined(WITH_IRIX_PROJECT) || \ 1609f304aafSPeter Avalos defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY)) 1619f304aafSPeter Avalos irix_setusercontext(pw); 1629f304aafSPeter Avalos #endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */ 1639f304aafSPeter Avalos 1649f304aafSPeter Avalos #ifdef _AIX 1659f304aafSPeter Avalos aix_usrinfo(pw); 1669f304aafSPeter Avalos #endif /* _AIX */ 1679f304aafSPeter Avalos 1689f304aafSPeter Avalos #ifdef HAVE_SETPCRED 1699f304aafSPeter Avalos /* 1709f304aafSPeter Avalos * If we have a chroot directory, we set all creds except real 1719f304aafSPeter Avalos * uid which we will need for chroot. If we don't have a 1729f304aafSPeter Avalos * chroot directory, we don't override anything. 1739f304aafSPeter Avalos */ 1749f304aafSPeter Avalos { 1759f304aafSPeter Avalos char **creds = NULL, *chroot_creds[] = 1769f304aafSPeter Avalos { "REAL_USER=root", NULL }; 1779f304aafSPeter Avalos 1789f304aafSPeter Avalos if (options.chroot_directory != NULL && 1799f304aafSPeter Avalos strcasecmp(options.chroot_directory, "none") != 0) 1809f304aafSPeter Avalos creds = chroot_creds; 1819f304aafSPeter Avalos 1829f304aafSPeter Avalos if (setpcred(pw->pw_name, creds) == -1) 1839f304aafSPeter Avalos fatal("Failed to set process credentials"); 1849f304aafSPeter Avalos } 1859f304aafSPeter Avalos #endif /* HAVE_SETPCRED */ 1869f304aafSPeter Avalos #ifdef WITH_SELINUX 1879f304aafSPeter Avalos ssh_selinux_setup_exec_context(pw->pw_name); 1889f304aafSPeter Avalos #endif 1899f304aafSPeter Avalos } 1909f304aafSPeter Avalos 191856ea928SPeter Avalos char * 192856ea928SPeter Avalos platform_krb5_get_principal_name(const char *pw_name) 193856ea928SPeter Avalos { 194856ea928SPeter Avalos #ifdef USE_AIX_KRB_NAME 195856ea928SPeter Avalos return aix_krb5_get_principal_name(pw_name); 196856ea928SPeter Avalos #else 197856ea928SPeter Avalos return NULL; 198856ea928SPeter Avalos #endif 19918de8d7fSPeter Avalos } 200*36e94dc5SPeter Avalos 201*36e94dc5SPeter Avalos /* 202*36e94dc5SPeter Avalos * return 1 if the specified uid is a uid that may own a system directory 203*36e94dc5SPeter Avalos * otherwise 0. 204*36e94dc5SPeter Avalos */ 205*36e94dc5SPeter Avalos int 206*36e94dc5SPeter Avalos platform_sys_dir_uid(uid_t uid) 207*36e94dc5SPeter Avalos { 208*36e94dc5SPeter Avalos if (uid == 0) 209*36e94dc5SPeter Avalos return 1; 210*36e94dc5SPeter Avalos #ifdef PLATFORM_SYS_DIR_UID 211*36e94dc5SPeter Avalos if (uid == PLATFORM_SYS_DIR_UID) 212*36e94dc5SPeter Avalos return 1; 213*36e94dc5SPeter Avalos #endif 214*36e94dc5SPeter Avalos return 0; 215*36e94dc5SPeter Avalos } 216