xref: /dragonfly/crypto/openssh/platform.c (revision 0cbfa66c)
118de8d7fSPeter Avalos /*
218de8d7fSPeter Avalos  * Copyright (c) 2006 Darren Tucker.  All rights reserved.
318de8d7fSPeter Avalos  *
418de8d7fSPeter Avalos  * Permission to use, copy, modify, and distribute this software for any
518de8d7fSPeter Avalos  * purpose with or without fee is hereby granted, provided that the above
618de8d7fSPeter Avalos  * copyright notice and this permission notice appear in all copies.
718de8d7fSPeter Avalos  *
818de8d7fSPeter Avalos  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
918de8d7fSPeter Avalos  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1018de8d7fSPeter Avalos  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1118de8d7fSPeter Avalos  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1218de8d7fSPeter Avalos  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1318de8d7fSPeter Avalos  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1418de8d7fSPeter Avalos  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1518de8d7fSPeter Avalos  */
1618de8d7fSPeter Avalos 
179f304aafSPeter Avalos #include "includes.h"
189f304aafSPeter Avalos 
199f304aafSPeter Avalos #include <stdarg.h>
200cbfa66cSDaniel Fojt #include <stdio.h>
219f304aafSPeter Avalos #include <unistd.h>
229f304aafSPeter Avalos 
239f304aafSPeter Avalos #include "log.h"
2436e94dc5SPeter Avalos #include "misc.h"
259f304aafSPeter Avalos #include "servconf.h"
26664f4763Szrj #include "sshkey.h"
279f304aafSPeter Avalos #include "hostfile.h"
289f304aafSPeter Avalos #include "auth.h"
299f304aafSPeter Avalos #include "auth-pam.h"
3018de8d7fSPeter Avalos #include "platform.h"
3118de8d7fSPeter Avalos 
3218de8d7fSPeter Avalos #include "openbsd-compat/openbsd-compat.h"
3318de8d7fSPeter Avalos 
349f304aafSPeter Avalos extern int use_privsep;
359f304aafSPeter Avalos extern ServerOptions options;
369f304aafSPeter Avalos 
3718de8d7fSPeter Avalos void
38856ea928SPeter Avalos platform_pre_listen(void)
39856ea928SPeter Avalos {
40856ea928SPeter Avalos #ifdef LINUX_OOM_ADJUST
41856ea928SPeter Avalos 	/* Adjust out-of-memory killer so listening process is not killed */
42856ea928SPeter Avalos 	oom_adjust_setup();
43856ea928SPeter Avalos #endif
44856ea928SPeter Avalos }
45856ea928SPeter Avalos 
46856ea928SPeter Avalos void
4718de8d7fSPeter Avalos platform_pre_fork(void)
4818de8d7fSPeter Avalos {
4918de8d7fSPeter Avalos #ifdef USE_SOLARIS_PROCESS_CONTRACTS
5018de8d7fSPeter Avalos 	solaris_contract_pre_fork();
5118de8d7fSPeter Avalos #endif
5218de8d7fSPeter Avalos }
5318de8d7fSPeter Avalos 
5418de8d7fSPeter Avalos void
5536e94dc5SPeter Avalos platform_pre_restart(void)
5636e94dc5SPeter Avalos {
5736e94dc5SPeter Avalos #ifdef LINUX_OOM_ADJUST
5836e94dc5SPeter Avalos 	oom_adjust_restore();
5936e94dc5SPeter Avalos #endif
6036e94dc5SPeter Avalos }
6136e94dc5SPeter Avalos 
6236e94dc5SPeter Avalos void
6318de8d7fSPeter Avalos platform_post_fork_parent(pid_t child_pid)
6418de8d7fSPeter Avalos {
6518de8d7fSPeter Avalos #ifdef USE_SOLARIS_PROCESS_CONTRACTS
6618de8d7fSPeter Avalos 	solaris_contract_post_fork_parent(child_pid);
6718de8d7fSPeter Avalos #endif
6818de8d7fSPeter Avalos }
6918de8d7fSPeter Avalos 
7018de8d7fSPeter Avalos void
7118de8d7fSPeter Avalos platform_post_fork_child(void)
7218de8d7fSPeter Avalos {
7318de8d7fSPeter Avalos #ifdef USE_SOLARIS_PROCESS_CONTRACTS
7418de8d7fSPeter Avalos 	solaris_contract_post_fork_child();
7518de8d7fSPeter Avalos #endif
76856ea928SPeter Avalos #ifdef LINUX_OOM_ADJUST
77856ea928SPeter Avalos 	oom_adjust_restore();
78856ea928SPeter Avalos #endif
79856ea928SPeter Avalos }
80856ea928SPeter Avalos 
819f304aafSPeter Avalos /* return 1 if we are running with privilege to swap UIDs, 0 otherwise */
829f304aafSPeter Avalos int
839f304aafSPeter Avalos platform_privileged_uidswap(void)
849f304aafSPeter Avalos {
859f304aafSPeter Avalos #ifdef HAVE_CYGWIN
869f304aafSPeter Avalos 	/* uid 0 is not special on Cygwin so always try */
879f304aafSPeter Avalos 	return 1;
889f304aafSPeter Avalos #else
899f304aafSPeter Avalos 	return (getuid() == 0 || geteuid() == 0);
909f304aafSPeter Avalos #endif
919f304aafSPeter Avalos }
929f304aafSPeter Avalos 
939f304aafSPeter Avalos /*
949f304aafSPeter Avalos  * This gets called before switching UIDs, and is called even when sshd is
959f304aafSPeter Avalos  * not running as root.
969f304aafSPeter Avalos  */
979f304aafSPeter Avalos void
989f304aafSPeter Avalos platform_setusercontext(struct passwd *pw)
999f304aafSPeter Avalos {
1009f304aafSPeter Avalos #ifdef WITH_SELINUX
1019f304aafSPeter Avalos 	/* Cache selinux status for later use */
1029f304aafSPeter Avalos 	(void)ssh_selinux_enabled();
1039f304aafSPeter Avalos #endif
1049f304aafSPeter Avalos 
1059f304aafSPeter Avalos #ifdef USE_SOLARIS_PROJECTS
106e9778795SPeter Avalos 	/*
107e9778795SPeter Avalos 	 * If solaris projects were detected, set the default now, unless
108e9778795SPeter Avalos 	 * we are using PAM in which case it is the responsibility of the
109e9778795SPeter Avalos 	 * PAM stack.
110e9778795SPeter Avalos 	 */
111e9778795SPeter Avalos 	if (!options.use_pam && (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