1761efaa7SDag-Erling Smørgrav /* 2761efaa7SDag-Erling Smørgrav * Copyright (c) 2006 Darren Tucker. All rights reserved. 3761efaa7SDag-Erling Smørgrav * 4761efaa7SDag-Erling Smørgrav * Permission to use, copy, modify, and distribute this software for any 5761efaa7SDag-Erling Smørgrav * purpose with or without fee is hereby granted, provided that the above 6761efaa7SDag-Erling Smørgrav * copyright notice and this permission notice appear in all copies. 7761efaa7SDag-Erling Smørgrav * 8761efaa7SDag-Erling Smørgrav * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9761efaa7SDag-Erling Smørgrav * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10761efaa7SDag-Erling Smørgrav * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11761efaa7SDag-Erling Smørgrav * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12761efaa7SDag-Erling Smørgrav * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13761efaa7SDag-Erling Smørgrav * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14761efaa7SDag-Erling Smørgrav * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15761efaa7SDag-Erling Smørgrav */ 16761efaa7SDag-Erling Smørgrav 174a421b63SDag-Erling Smørgrav #include "includes.h" 184a421b63SDag-Erling Smørgrav 194a421b63SDag-Erling Smørgrav #include <stdarg.h> 2019261079SEd Maste #include <stdio.h> 21*87c1498dSEd Maste #include <string.h> 224a421b63SDag-Erling Smørgrav #include <unistd.h> 234a421b63SDag-Erling Smørgrav 244a421b63SDag-Erling Smørgrav #include "log.h" 25a0ee8cc6SDag-Erling Smørgrav #include "misc.h" 264a421b63SDag-Erling Smørgrav #include "servconf.h" 27190cef3dSDag-Erling Smørgrav #include "sshkey.h" 284a421b63SDag-Erling Smørgrav #include "hostfile.h" 294a421b63SDag-Erling Smørgrav #include "auth.h" 304a421b63SDag-Erling Smørgrav #include "auth-pam.h" 31761efaa7SDag-Erling Smørgrav #include "platform.h" 32761efaa7SDag-Erling Smørgrav 33761efaa7SDag-Erling Smørgrav #include "openbsd-compat/openbsd-compat.h" 34761efaa7SDag-Erling Smørgrav 354a421b63SDag-Erling Smørgrav extern int use_privsep; 364a421b63SDag-Erling Smørgrav extern ServerOptions options; 374a421b63SDag-Erling Smørgrav 38761efaa7SDag-Erling Smørgrav void 39b15c8340SDag-Erling Smørgrav platform_pre_listen(void) 40b15c8340SDag-Erling Smørgrav { 41b15c8340SDag-Erling Smørgrav #ifdef LINUX_OOM_ADJUST 42b15c8340SDag-Erling Smørgrav /* Adjust out-of-memory killer so listening process is not killed */ 43b15c8340SDag-Erling Smørgrav oom_adjust_setup(); 44b15c8340SDag-Erling Smørgrav #endif 45b15c8340SDag-Erling Smørgrav } 46b15c8340SDag-Erling Smørgrav 47b15c8340SDag-Erling Smørgrav void 48761efaa7SDag-Erling Smørgrav platform_pre_fork(void) 49761efaa7SDag-Erling Smørgrav { 50761efaa7SDag-Erling Smørgrav #ifdef USE_SOLARIS_PROCESS_CONTRACTS 51761efaa7SDag-Erling Smørgrav solaris_contract_pre_fork(); 52761efaa7SDag-Erling Smørgrav #endif 53761efaa7SDag-Erling Smørgrav } 54761efaa7SDag-Erling Smørgrav 55761efaa7SDag-Erling Smørgrav void 56f7167e0eSDag-Erling Smørgrav platform_pre_restart(void) 57f7167e0eSDag-Erling Smørgrav { 58f7167e0eSDag-Erling Smørgrav #ifdef LINUX_OOM_ADJUST 59f7167e0eSDag-Erling Smørgrav oom_adjust_restore(); 60f7167e0eSDag-Erling Smørgrav #endif 61f7167e0eSDag-Erling Smørgrav } 62f7167e0eSDag-Erling Smørgrav 63f7167e0eSDag-Erling Smørgrav void 64761efaa7SDag-Erling Smørgrav platform_post_fork_parent(pid_t child_pid) 65761efaa7SDag-Erling Smørgrav { 66761efaa7SDag-Erling Smørgrav #ifdef USE_SOLARIS_PROCESS_CONTRACTS 67761efaa7SDag-Erling Smørgrav solaris_contract_post_fork_parent(child_pid); 68761efaa7SDag-Erling Smørgrav #endif 69761efaa7SDag-Erling Smørgrav } 70761efaa7SDag-Erling Smørgrav 71761efaa7SDag-Erling Smørgrav void 72761efaa7SDag-Erling Smørgrav platform_post_fork_child(void) 73761efaa7SDag-Erling Smørgrav { 74761efaa7SDag-Erling Smørgrav #ifdef USE_SOLARIS_PROCESS_CONTRACTS 75761efaa7SDag-Erling Smørgrav solaris_contract_post_fork_child(); 76761efaa7SDag-Erling Smørgrav #endif 77b15c8340SDag-Erling Smørgrav #ifdef LINUX_OOM_ADJUST 78b15c8340SDag-Erling Smørgrav oom_adjust_restore(); 79b15c8340SDag-Erling Smørgrav #endif 80b15c8340SDag-Erling Smørgrav } 81b15c8340SDag-Erling Smørgrav 824a421b63SDag-Erling Smørgrav /* return 1 if we are running with privilege to swap UIDs, 0 otherwise */ 834a421b63SDag-Erling Smørgrav int 844a421b63SDag-Erling Smørgrav platform_privileged_uidswap(void) 854a421b63SDag-Erling Smørgrav { 864a421b63SDag-Erling Smørgrav #ifdef HAVE_CYGWIN 874a421b63SDag-Erling Smørgrav /* uid 0 is not special on Cygwin so always try */ 884a421b63SDag-Erling Smørgrav return 1; 894a421b63SDag-Erling Smørgrav #else 904a421b63SDag-Erling Smørgrav return (getuid() == 0 || geteuid() == 0); 914a421b63SDag-Erling Smørgrav #endif 924a421b63SDag-Erling Smørgrav } 934a421b63SDag-Erling Smørgrav 944a421b63SDag-Erling Smørgrav /* 954a421b63SDag-Erling Smørgrav * This gets called before switching UIDs, and is called even when sshd is 964a421b63SDag-Erling Smørgrav * not running as root. 974a421b63SDag-Erling Smørgrav */ 984a421b63SDag-Erling Smørgrav void 994a421b63SDag-Erling Smørgrav platform_setusercontext(struct passwd *pw) 1004a421b63SDag-Erling Smørgrav { 1014a421b63SDag-Erling Smørgrav #ifdef WITH_SELINUX 1024a421b63SDag-Erling Smørgrav /* Cache selinux status for later use */ 1034a421b63SDag-Erling Smørgrav (void)ssh_selinux_enabled(); 1044a421b63SDag-Erling Smørgrav #endif 1054a421b63SDag-Erling Smørgrav 1064a421b63SDag-Erling Smørgrav #ifdef USE_SOLARIS_PROJECTS 107076ad2f8SDag-Erling Smørgrav /* 108076ad2f8SDag-Erling Smørgrav * If solaris projects were detected, set the default now, unless 109076ad2f8SDag-Erling Smørgrav * we are using PAM in which case it is the responsibility of the 110076ad2f8SDag-Erling Smørgrav * PAM stack. 111076ad2f8SDag-Erling Smørgrav */ 112076ad2f8SDag-Erling Smørgrav if (!options.use_pam && (getuid() == 0 || geteuid() == 0)) 1134a421b63SDag-Erling Smørgrav solaris_set_default_project(pw); 1144a421b63SDag-Erling Smørgrav #endif 1154a421b63SDag-Erling Smørgrav 1164a421b63SDag-Erling Smørgrav #if defined(HAVE_LOGIN_CAP) && defined (__bsdi__) 1174a421b63SDag-Erling Smørgrav if (getuid() == 0 || geteuid() == 0) 1184a421b63SDag-Erling Smørgrav setpgid(0, 0); 1194a421b63SDag-Erling Smørgrav # endif 1204a421b63SDag-Erling Smørgrav 1214a421b63SDag-Erling Smørgrav #if defined(HAVE_LOGIN_CAP) && defined(USE_PAM) 1224a421b63SDag-Erling Smørgrav /* 1234a421b63SDag-Erling Smørgrav * If we have both LOGIN_CAP and PAM, we want to establish creds 1244a421b63SDag-Erling Smørgrav * before calling setusercontext (in session.c:do_setusercontext). 1254a421b63SDag-Erling Smørgrav */ 1264a421b63SDag-Erling Smørgrav if (getuid() == 0 || geteuid() == 0) { 1274a421b63SDag-Erling Smørgrav if (options.use_pam) { 1284a421b63SDag-Erling Smørgrav do_pam_setcred(use_privsep); 1294a421b63SDag-Erling Smørgrav } 1304a421b63SDag-Erling Smørgrav } 1314a421b63SDag-Erling Smørgrav # endif /* USE_PAM */ 1324a421b63SDag-Erling Smørgrav 1334a421b63SDag-Erling Smørgrav #if !defined(HAVE_LOGIN_CAP) && defined(HAVE_GETLUID) && defined(HAVE_SETLUID) 1344a421b63SDag-Erling Smørgrav if (getuid() == 0 || geteuid() == 0) { 1354a421b63SDag-Erling Smørgrav /* Sets login uid for accounting */ 1364a421b63SDag-Erling Smørgrav if (getluid() == -1 && setluid(pw->pw_uid) == -1) 1374a421b63SDag-Erling Smørgrav error("setluid: %s", strerror(errno)); 1384a421b63SDag-Erling Smørgrav } 1394a421b63SDag-Erling Smørgrav #endif 1404a421b63SDag-Erling Smørgrav } 1414a421b63SDag-Erling Smørgrav 1424a421b63SDag-Erling Smørgrav /* 1434a421b63SDag-Erling Smørgrav * This gets called after we've established the user's groups, and is only 1444a421b63SDag-Erling Smørgrav * called if sshd is running as root. 1454a421b63SDag-Erling Smørgrav */ 1464a421b63SDag-Erling Smørgrav void 1474a421b63SDag-Erling Smørgrav platform_setusercontext_post_groups(struct passwd *pw) 1484a421b63SDag-Erling Smørgrav { 1494a421b63SDag-Erling Smørgrav #if !defined(HAVE_LOGIN_CAP) && defined(USE_PAM) 1504a421b63SDag-Erling Smørgrav /* 1514a421b63SDag-Erling Smørgrav * PAM credentials may take the form of supplementary groups. 1524a421b63SDag-Erling Smørgrav * These will have been wiped by the above initgroups() call. 1534a421b63SDag-Erling Smørgrav * Reestablish them here. 1544a421b63SDag-Erling Smørgrav */ 1554a421b63SDag-Erling Smørgrav if (options.use_pam) { 1564a421b63SDag-Erling Smørgrav do_pam_setcred(use_privsep); 1574a421b63SDag-Erling Smørgrav } 1584a421b63SDag-Erling Smørgrav #endif /* USE_PAM */ 1594a421b63SDag-Erling Smørgrav 1604a421b63SDag-Erling Smørgrav #if !defined(HAVE_LOGIN_CAP) && (defined(WITH_IRIX_PROJECT) || \ 1614a421b63SDag-Erling Smørgrav defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY)) 1624a421b63SDag-Erling Smørgrav irix_setusercontext(pw); 1634a421b63SDag-Erling Smørgrav #endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */ 1644a421b63SDag-Erling Smørgrav 1654a421b63SDag-Erling Smørgrav #ifdef _AIX 1664a421b63SDag-Erling Smørgrav aix_usrinfo(pw); 1674a421b63SDag-Erling Smørgrav #endif /* _AIX */ 1684a421b63SDag-Erling Smørgrav 1694a421b63SDag-Erling Smørgrav #ifdef HAVE_SETPCRED 1704a421b63SDag-Erling Smørgrav /* 1714a421b63SDag-Erling Smørgrav * If we have a chroot directory, we set all creds except real 1724a421b63SDag-Erling Smørgrav * uid which we will need for chroot. If we don't have a 1734a421b63SDag-Erling Smørgrav * chroot directory, we don't override anything. 1744a421b63SDag-Erling Smørgrav */ 1754a421b63SDag-Erling Smørgrav { 1764a421b63SDag-Erling Smørgrav char **creds = NULL, *chroot_creds[] = 1774a421b63SDag-Erling Smørgrav { "REAL_USER=root", NULL }; 1784a421b63SDag-Erling Smørgrav 1794a421b63SDag-Erling Smørgrav if (options.chroot_directory != NULL && 1804a421b63SDag-Erling Smørgrav strcasecmp(options.chroot_directory, "none") != 0) 1814a421b63SDag-Erling Smørgrav creds = chroot_creds; 1824a421b63SDag-Erling Smørgrav 1834a421b63SDag-Erling Smørgrav if (setpcred(pw->pw_name, creds) == -1) 1844a421b63SDag-Erling Smørgrav fatal("Failed to set process credentials"); 1854a421b63SDag-Erling Smørgrav } 1864a421b63SDag-Erling Smørgrav #endif /* HAVE_SETPCRED */ 1874a421b63SDag-Erling Smørgrav #ifdef WITH_SELINUX 1884a421b63SDag-Erling Smørgrav ssh_selinux_setup_exec_context(pw->pw_name); 1894a421b63SDag-Erling Smørgrav #endif 1904a421b63SDag-Erling Smørgrav } 1914a421b63SDag-Erling Smørgrav 192b15c8340SDag-Erling Smørgrav char * 193b15c8340SDag-Erling Smørgrav platform_krb5_get_principal_name(const char *pw_name) 194b15c8340SDag-Erling Smørgrav { 195b15c8340SDag-Erling Smørgrav #ifdef USE_AIX_KRB_NAME 196b15c8340SDag-Erling Smørgrav return aix_krb5_get_principal_name(pw_name); 197b15c8340SDag-Erling Smørgrav #else 198b15c8340SDag-Erling Smørgrav return NULL; 199b15c8340SDag-Erling Smørgrav #endif 200761efaa7SDag-Erling Smørgrav } 201*87c1498dSEd Maste 202*87c1498dSEd Maste /* returns 1 if account is locked */ 203*87c1498dSEd Maste int 204*87c1498dSEd Maste platform_locked_account(struct passwd *pw) 205*87c1498dSEd Maste { 206*87c1498dSEd Maste int locked = 0; 207*87c1498dSEd Maste char *passwd = pw->pw_passwd; 208*87c1498dSEd Maste #ifdef USE_SHADOW 209*87c1498dSEd Maste struct spwd *spw = NULL; 210*87c1498dSEd Maste #ifdef USE_LIBIAF 211*87c1498dSEd Maste char *iaf_passwd = NULL; 212*87c1498dSEd Maste #endif 213*87c1498dSEd Maste 214*87c1498dSEd Maste spw = getspnam(pw->pw_name); 215*87c1498dSEd Maste #ifdef HAS_SHADOW_EXPIRE 216*87c1498dSEd Maste if (spw != NULL && auth_shadow_acctexpired(spw)) 217*87c1498dSEd Maste return 1; 218*87c1498dSEd Maste #endif /* HAS_SHADOW_EXPIRE */ 219*87c1498dSEd Maste 220*87c1498dSEd Maste if (spw != NULL) 221*87c1498dSEd Maste #ifdef USE_LIBIAF 222*87c1498dSEd Maste iaf_passwd = passwd = get_iaf_password(pw); 223*87c1498dSEd Maste #else 224*87c1498dSEd Maste passwd = spw->sp_pwdp; 225*87c1498dSEd Maste #endif /* USE_LIBIAF */ 226*87c1498dSEd Maste #endif 227*87c1498dSEd Maste 228*87c1498dSEd Maste /* check for locked account */ 229*87c1498dSEd Maste if (passwd && *passwd) { 230*87c1498dSEd Maste #ifdef LOCKED_PASSWD_STRING 231*87c1498dSEd Maste if (strcmp(passwd, LOCKED_PASSWD_STRING) == 0) 232*87c1498dSEd Maste locked = 1; 233*87c1498dSEd Maste #endif 234*87c1498dSEd Maste #ifdef LOCKED_PASSWD_PREFIX 235*87c1498dSEd Maste if (strncmp(passwd, LOCKED_PASSWD_PREFIX, 236*87c1498dSEd Maste strlen(LOCKED_PASSWD_PREFIX)) == 0) 237*87c1498dSEd Maste locked = 1; 238*87c1498dSEd Maste #endif 239*87c1498dSEd Maste #ifdef LOCKED_PASSWD_SUBSTR 240*87c1498dSEd Maste if (strstr(passwd, LOCKED_PASSWD_SUBSTR)) 241*87c1498dSEd Maste locked = 1; 242*87c1498dSEd Maste #endif 243*87c1498dSEd Maste } 244*87c1498dSEd Maste #ifdef USE_LIBIAF 245*87c1498dSEd Maste if (iaf_passwd != NULL) 246*87c1498dSEd Maste freezero(iaf_passwd, strlen(iaf_passwd)); 247*87c1498dSEd Maste #endif /* USE_LIBIAF */ 248*87c1498dSEd Maste 249*87c1498dSEd Maste return locked; 250*87c1498dSEd Maste } 251