11305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* $Id: platform.c,v 1.18 2011/01/11 06:02:25 djm Exp $ */
21305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
31305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
41305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 2006 Darren Tucker.  All rights reserved.
51305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *
61305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Permission to use, copy, modify, and distribute this software for any
71305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * purpose with or without fee is hereby granted, provided that the above
81305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * copyright notice and this permission notice appear in all copies.
91305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *
101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "includes.h"
201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/types.h>
221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdarg.h>
241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <unistd.h>
251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "log.h"
271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "buffer.h"
281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "servconf.h"
291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "key.h"
301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "hostfile.h"
311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "auth.h"
321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "auth-pam.h"
331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "platform.h"
341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "openbsd-compat/openbsd-compat.h"
361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodextern int use_privsep;
381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodextern ServerOptions options;
391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodplatform_pre_listen(void)
421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef LINUX_OOM_ADJUST
441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Adjust out-of-memory killer so listening process is not killed */
451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	oom_adjust_setup();
461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodplatform_pre_fork(void)
511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef USE_SOLARIS_PROCESS_CONTRACTS
531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	solaris_contract_pre_fork();
541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodplatform_post_fork_parent(pid_t child_pid)
591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef USE_SOLARIS_PROCESS_CONTRACTS
611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	solaris_contract_post_fork_parent(child_pid);
621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodplatform_post_fork_child(void)
671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef USE_SOLARIS_PROCESS_CONTRACTS
691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	solaris_contract_post_fork_child();
701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef LINUX_OOM_ADJUST
721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	oom_adjust_restore();
731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* return 1 if we are running with privilege to swap UIDs, 0 otherwise */
771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint
781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodplatform_privileged_uidswap(void)
791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_CYGWIN
811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* uid 0 is not special on Cygwin so always try */
821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return 1;
831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#else
841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return (getuid() == 0 || geteuid() == 0);
851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * This gets called before switching UIDs, and is called even when sshd is
901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * not running as root.
911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodplatform_setusercontext(struct passwd *pw)
941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef WITH_SELINUX
961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Cache selinux status for later use */
971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	(void)ssh_selinux_enabled();
981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef USE_SOLARIS_PROJECTS
1011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* if solaris projects were detected, set the default now */
1021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (getuid() == 0 || geteuid() == 0)
1031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		solaris_set_default_project(pw);
1041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
1051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#if defined(HAVE_LOGIN_CAP) && defined (__bsdi__)
1071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (getuid() == 0 || geteuid() == 0)
1081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		setpgid(0, 0);
1091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# endif
1101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#if defined(HAVE_LOGIN_CAP) && defined(USE_PAM)
1121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
1131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * If we have both LOGIN_CAP and PAM, we want to establish creds
1141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * before calling setusercontext (in session.c:do_setusercontext).
1151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
1161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (getuid() == 0 || geteuid() == 0) {
1171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (options.use_pam) {
1181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			do_pam_setcred(use_privsep);
1191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
1201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
1211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# endif /* USE_PAM */
1221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#if !defined(HAVE_LOGIN_CAP) && defined(HAVE_GETLUID) && defined(HAVE_SETLUID)
1241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (getuid() == 0 || geteuid() == 0) {
1251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Sets login uid for accounting */
1261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (getluid() == -1 && setluid(pw->pw_uid) == -1)
1271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			error("setluid: %s", strerror(errno));
1281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
1291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
1301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
1311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
1331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * This gets called after we've established the user's groups, and is only
1341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * called if sshd is running as root.
1351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
1361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
1371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodplatform_setusercontext_post_groups(struct passwd *pw)
1381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
1391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#if !defined(HAVE_LOGIN_CAP) && defined(USE_PAM)
1401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
1411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * PAM credentials may take the form of supplementary groups.
1421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * These will have been wiped by the above initgroups() call.
1431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * Reestablish them here.
1441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
1451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (options.use_pam) {
1461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		do_pam_setcred(use_privsep);
1471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
1481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* USE_PAM */
1491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#if !defined(HAVE_LOGIN_CAP) && (defined(WITH_IRIX_PROJECT) || \
1511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood    defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY))
1521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	irix_setusercontext(pw);
1531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */
1541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef _AIX
1561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	aix_usrinfo(pw);
1571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* _AIX */
1581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#if !defined(HAVE_LOGIN_CAP) && defined(USE_LIBIAF)
1601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (set_id(pw->pw_name) != 0) {
1611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		exit(1);
1621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
1631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# endif /* USE_LIBIAF */
1641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_SETPCRED
1661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
1671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * If we have a chroot directory, we set all creds except real
1681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * uid which we will need for chroot.  If we don't have a
1691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * chroot directory, we don't override anything.
1701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
1711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	{
1721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		char **creds = NULL, *chroot_creds[] =
1731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    { "REAL_USER=root", NULL };
1741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (options.chroot_directory != NULL &&
1761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    strcasecmp(options.chroot_directory, "none") != 0)
1771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			creds = chroot_creds;
1781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (setpcred(pw->pw_name, creds) == -1)
1801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			fatal("Failed to set process credentials");
1811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
1821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* HAVE_SETPCRED */
1831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef WITH_SELINUX
1841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	ssh_selinux_setup_exec_context(pw->pw_name);
1851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
1861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
1871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchar *
1891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodplatform_krb5_get_principal_name(const char *pw_name)
1901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
1911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef USE_AIX_KRB_NAME
1921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return aix_krb5_get_principal_name(pw_name);
1931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#else
1941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return NULL;
1951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
1961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
197