xref: /dragonfly/crypto/openssh/platform.c (revision 36e94dc5)
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