xref: /dragonfly/crypto/openssh/platform.c (revision ee116499)
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>
21*ee116499SAntonio Huete Jimenez #include <string.h>
229f304aafSPeter Avalos #include <unistd.h>
239f304aafSPeter Avalos 
249f304aafSPeter Avalos #include "log.h"
2536e94dc5SPeter Avalos #include "misc.h"
269f304aafSPeter Avalos #include "servconf.h"
27664f4763Szrj #include "sshkey.h"
289f304aafSPeter Avalos #include "hostfile.h"
299f304aafSPeter Avalos #include "auth.h"
309f304aafSPeter Avalos #include "auth-pam.h"
3118de8d7fSPeter Avalos #include "platform.h"
3218de8d7fSPeter Avalos 
3318de8d7fSPeter Avalos #include "openbsd-compat/openbsd-compat.h"
3418de8d7fSPeter Avalos 
359f304aafSPeter Avalos extern int use_privsep;
369f304aafSPeter Avalos extern ServerOptions options;
379f304aafSPeter Avalos 
3818de8d7fSPeter Avalos void
platform_pre_listen(void)39856ea928SPeter Avalos platform_pre_listen(void)
40856ea928SPeter Avalos {
41856ea928SPeter Avalos #ifdef LINUX_OOM_ADJUST
42856ea928SPeter Avalos 	/* Adjust out-of-memory killer so listening process is not killed */
43856ea928SPeter Avalos 	oom_adjust_setup();
44856ea928SPeter Avalos #endif
45856ea928SPeter Avalos }
46856ea928SPeter Avalos 
47856ea928SPeter Avalos void
platform_pre_fork(void)4818de8d7fSPeter Avalos platform_pre_fork(void)
4918de8d7fSPeter Avalos {
5018de8d7fSPeter Avalos #ifdef USE_SOLARIS_PROCESS_CONTRACTS
5118de8d7fSPeter Avalos 	solaris_contract_pre_fork();
5218de8d7fSPeter Avalos #endif
5318de8d7fSPeter Avalos }
5418de8d7fSPeter Avalos 
5518de8d7fSPeter Avalos void
platform_pre_restart(void)5636e94dc5SPeter Avalos platform_pre_restart(void)
5736e94dc5SPeter Avalos {
5836e94dc5SPeter Avalos #ifdef LINUX_OOM_ADJUST
5936e94dc5SPeter Avalos 	oom_adjust_restore();
6036e94dc5SPeter Avalos #endif
6136e94dc5SPeter Avalos }
6236e94dc5SPeter Avalos 
6336e94dc5SPeter Avalos void
platform_post_fork_parent(pid_t child_pid)6418de8d7fSPeter Avalos platform_post_fork_parent(pid_t child_pid)
6518de8d7fSPeter Avalos {
6618de8d7fSPeter Avalos #ifdef USE_SOLARIS_PROCESS_CONTRACTS
6718de8d7fSPeter Avalos 	solaris_contract_post_fork_parent(child_pid);
6818de8d7fSPeter Avalos #endif
6918de8d7fSPeter Avalos }
7018de8d7fSPeter Avalos 
7118de8d7fSPeter Avalos void
platform_post_fork_child(void)7218de8d7fSPeter Avalos platform_post_fork_child(void)
7318de8d7fSPeter Avalos {
7418de8d7fSPeter Avalos #ifdef USE_SOLARIS_PROCESS_CONTRACTS
7518de8d7fSPeter Avalos 	solaris_contract_post_fork_child();
7618de8d7fSPeter Avalos #endif
77856ea928SPeter Avalos #ifdef LINUX_OOM_ADJUST
78856ea928SPeter Avalos 	oom_adjust_restore();
79856ea928SPeter Avalos #endif
80856ea928SPeter Avalos }
81856ea928SPeter Avalos 
829f304aafSPeter Avalos /* return 1 if we are running with privilege to swap UIDs, 0 otherwise */
839f304aafSPeter Avalos int
platform_privileged_uidswap(void)849f304aafSPeter Avalos platform_privileged_uidswap(void)
859f304aafSPeter Avalos {
869f304aafSPeter Avalos #ifdef HAVE_CYGWIN
879f304aafSPeter Avalos 	/* uid 0 is not special on Cygwin so always try */
889f304aafSPeter Avalos 	return 1;
899f304aafSPeter Avalos #else
909f304aafSPeter Avalos 	return (getuid() == 0 || geteuid() == 0);
919f304aafSPeter Avalos #endif
929f304aafSPeter Avalos }
939f304aafSPeter Avalos 
949f304aafSPeter Avalos /*
959f304aafSPeter Avalos  * This gets called before switching UIDs, and is called even when sshd is
969f304aafSPeter Avalos  * not running as root.
979f304aafSPeter Avalos  */
989f304aafSPeter Avalos void
platform_setusercontext(struct passwd * pw)999f304aafSPeter Avalos platform_setusercontext(struct passwd *pw)
1009f304aafSPeter Avalos {
1019f304aafSPeter Avalos #ifdef WITH_SELINUX
1029f304aafSPeter Avalos 	/* Cache selinux status for later use */
1039f304aafSPeter Avalos 	(void)ssh_selinux_enabled();
1049f304aafSPeter Avalos #endif
1059f304aafSPeter Avalos 
1069f304aafSPeter Avalos #ifdef USE_SOLARIS_PROJECTS
107e9778795SPeter Avalos 	/*
108e9778795SPeter Avalos 	 * If solaris projects were detected, set the default now, unless
109e9778795SPeter Avalos 	 * we are using PAM in which case it is the responsibility of the
110e9778795SPeter Avalos 	 * PAM stack.
111e9778795SPeter Avalos 	 */
112e9778795SPeter Avalos 	if (!options.use_pam && (getuid() == 0 || geteuid() == 0))
1139f304aafSPeter Avalos 		solaris_set_default_project(pw);
1149f304aafSPeter Avalos #endif
1159f304aafSPeter Avalos 
1169f304aafSPeter Avalos #if defined(HAVE_LOGIN_CAP) && defined (__bsdi__)
1179f304aafSPeter Avalos 	if (getuid() == 0 || geteuid() == 0)
1189f304aafSPeter Avalos 		setpgid(0, 0);
1199f304aafSPeter Avalos # endif
1209f304aafSPeter Avalos 
1219f304aafSPeter Avalos #if defined(HAVE_LOGIN_CAP) && defined(USE_PAM)
1229f304aafSPeter Avalos 	/*
1239f304aafSPeter Avalos 	 * If we have both LOGIN_CAP and PAM, we want to establish creds
1249f304aafSPeter Avalos 	 * before calling setusercontext (in session.c:do_setusercontext).
1259f304aafSPeter Avalos 	 */
1269f304aafSPeter Avalos 	if (getuid() == 0 || geteuid() == 0) {
1279f304aafSPeter Avalos 		if (options.use_pam) {
1289f304aafSPeter Avalos 			do_pam_setcred(use_privsep);
1299f304aafSPeter Avalos 		}
1309f304aafSPeter Avalos 	}
1319f304aafSPeter Avalos # endif /* USE_PAM */
1329f304aafSPeter Avalos 
1339f304aafSPeter Avalos #if !defined(HAVE_LOGIN_CAP) && defined(HAVE_GETLUID) && defined(HAVE_SETLUID)
1349f304aafSPeter Avalos 	if (getuid() == 0 || geteuid() == 0) {
1359f304aafSPeter Avalos 		/* Sets login uid for accounting */
1369f304aafSPeter Avalos 		if (getluid() == -1 && setluid(pw->pw_uid) == -1)
1379f304aafSPeter Avalos 			error("setluid: %s", strerror(errno));
1389f304aafSPeter Avalos 	}
1399f304aafSPeter Avalos #endif
1409f304aafSPeter Avalos }
1419f304aafSPeter Avalos 
1429f304aafSPeter Avalos /*
1439f304aafSPeter Avalos  * This gets called after we've established the user's groups, and is only
1449f304aafSPeter Avalos  * called if sshd is running as root.
1459f304aafSPeter Avalos  */
1469f304aafSPeter Avalos void
platform_setusercontext_post_groups(struct passwd * pw)1479f304aafSPeter Avalos platform_setusercontext_post_groups(struct passwd *pw)
1489f304aafSPeter Avalos {
1499f304aafSPeter Avalos #if !defined(HAVE_LOGIN_CAP) && defined(USE_PAM)
1509f304aafSPeter Avalos 	/*
1519f304aafSPeter Avalos 	 * PAM credentials may take the form of supplementary groups.
1529f304aafSPeter Avalos 	 * These will have been wiped by the above initgroups() call.
1539f304aafSPeter Avalos 	 * Reestablish them here.
1549f304aafSPeter Avalos 	 */
1559f304aafSPeter Avalos 	if (options.use_pam) {
1569f304aafSPeter Avalos 		do_pam_setcred(use_privsep);
1579f304aafSPeter Avalos 	}
1589f304aafSPeter Avalos #endif /* USE_PAM */
1599f304aafSPeter Avalos 
1609f304aafSPeter Avalos #if !defined(HAVE_LOGIN_CAP) && (defined(WITH_IRIX_PROJECT) || \
1619f304aafSPeter Avalos     defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY))
1629f304aafSPeter Avalos 	irix_setusercontext(pw);
1639f304aafSPeter Avalos #endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */
1649f304aafSPeter Avalos 
1659f304aafSPeter Avalos #ifdef _AIX
1669f304aafSPeter Avalos 	aix_usrinfo(pw);
1679f304aafSPeter Avalos #endif /* _AIX */
1689f304aafSPeter Avalos 
1699f304aafSPeter Avalos #ifdef HAVE_SETPCRED
1709f304aafSPeter Avalos 	/*
1719f304aafSPeter Avalos 	 * If we have a chroot directory, we set all creds except real
1729f304aafSPeter Avalos 	 * uid which we will need for chroot.  If we don't have a
1739f304aafSPeter Avalos 	 * chroot directory, we don't override anything.
1749f304aafSPeter Avalos 	 */
1759f304aafSPeter Avalos 	{
1769f304aafSPeter Avalos 		char **creds = NULL, *chroot_creds[] =
1779f304aafSPeter Avalos 		    { "REAL_USER=root", NULL };
1789f304aafSPeter Avalos 
1799f304aafSPeter Avalos 		if (options.chroot_directory != NULL &&
1809f304aafSPeter Avalos 		    strcasecmp(options.chroot_directory, "none") != 0)
1819f304aafSPeter Avalos 			creds = chroot_creds;
1829f304aafSPeter Avalos 
1839f304aafSPeter Avalos 		if (setpcred(pw->pw_name, creds) == -1)
1849f304aafSPeter Avalos 			fatal("Failed to set process credentials");
1859f304aafSPeter Avalos 	}
1869f304aafSPeter Avalos #endif /* HAVE_SETPCRED */
1879f304aafSPeter Avalos #ifdef WITH_SELINUX
1889f304aafSPeter Avalos 	ssh_selinux_setup_exec_context(pw->pw_name);
1899f304aafSPeter Avalos #endif
1909f304aafSPeter Avalos }
1919f304aafSPeter Avalos 
192856ea928SPeter Avalos char *
platform_krb5_get_principal_name(const char * pw_name)193856ea928SPeter Avalos platform_krb5_get_principal_name(const char *pw_name)
194856ea928SPeter Avalos {
195856ea928SPeter Avalos #ifdef USE_AIX_KRB_NAME
196856ea928SPeter Avalos 	return aix_krb5_get_principal_name(pw_name);
197856ea928SPeter Avalos #else
198856ea928SPeter Avalos 	return NULL;
199856ea928SPeter Avalos #endif
20018de8d7fSPeter Avalos }
201*ee116499SAntonio Huete Jimenez 
202*ee116499SAntonio Huete Jimenez /* returns 1 if account is locked */
203*ee116499SAntonio Huete Jimenez int
platform_locked_account(struct passwd * pw)204*ee116499SAntonio Huete Jimenez platform_locked_account(struct passwd *pw)
205*ee116499SAntonio Huete Jimenez {
206*ee116499SAntonio Huete Jimenez 	int locked = 0;
207*ee116499SAntonio Huete Jimenez 	char *passwd = pw->pw_passwd;
208*ee116499SAntonio Huete Jimenez #ifdef USE_SHADOW
209*ee116499SAntonio Huete Jimenez 	struct spwd *spw = NULL;
210*ee116499SAntonio Huete Jimenez #ifdef USE_LIBIAF
211*ee116499SAntonio Huete Jimenez 	char *iaf_passwd = NULL;
212*ee116499SAntonio Huete Jimenez #endif
213*ee116499SAntonio Huete Jimenez 
214*ee116499SAntonio Huete Jimenez 	spw = getspnam(pw->pw_name);
215*ee116499SAntonio Huete Jimenez #ifdef HAS_SHADOW_EXPIRE
216*ee116499SAntonio Huete Jimenez 	if (spw != NULL && auth_shadow_acctexpired(spw))
217*ee116499SAntonio Huete Jimenez 		return 1;
218*ee116499SAntonio Huete Jimenez #endif /* HAS_SHADOW_EXPIRE */
219*ee116499SAntonio Huete Jimenez 
220*ee116499SAntonio Huete Jimenez 	if (spw != NULL)
221*ee116499SAntonio Huete Jimenez #ifdef USE_LIBIAF
222*ee116499SAntonio Huete Jimenez 		iaf_passwd = passwd = get_iaf_password(pw);
223*ee116499SAntonio Huete Jimenez #else
224*ee116499SAntonio Huete Jimenez 		passwd = spw->sp_pwdp;
225*ee116499SAntonio Huete Jimenez #endif /* USE_LIBIAF */
226*ee116499SAntonio Huete Jimenez #endif
227*ee116499SAntonio Huete Jimenez 
228*ee116499SAntonio Huete Jimenez 	/* check for locked account */
229*ee116499SAntonio Huete Jimenez 	if (passwd && *passwd) {
230*ee116499SAntonio Huete Jimenez #ifdef LOCKED_PASSWD_STRING
231*ee116499SAntonio Huete Jimenez 		if (strcmp(passwd, LOCKED_PASSWD_STRING) == 0)
232*ee116499SAntonio Huete Jimenez 			locked = 1;
233*ee116499SAntonio Huete Jimenez #endif
234*ee116499SAntonio Huete Jimenez #ifdef LOCKED_PASSWD_PREFIX
235*ee116499SAntonio Huete Jimenez 		if (strncmp(passwd, LOCKED_PASSWD_PREFIX,
236*ee116499SAntonio Huete Jimenez 		    strlen(LOCKED_PASSWD_PREFIX)) == 0)
237*ee116499SAntonio Huete Jimenez 			locked = 1;
238*ee116499SAntonio Huete Jimenez #endif
239*ee116499SAntonio Huete Jimenez #ifdef LOCKED_PASSWD_SUBSTR
240*ee116499SAntonio Huete Jimenez 		if (strstr(passwd, LOCKED_PASSWD_SUBSTR))
241*ee116499SAntonio Huete Jimenez 			locked = 1;
242*ee116499SAntonio Huete Jimenez #endif
243*ee116499SAntonio Huete Jimenez 	}
244*ee116499SAntonio Huete Jimenez #ifdef USE_LIBIAF
245*ee116499SAntonio Huete Jimenez 	if (iaf_passwd != NULL)
246*ee116499SAntonio Huete Jimenez 		freezero(iaf_passwd, strlen(iaf_passwd));
247*ee116499SAntonio Huete Jimenez #endif /* USE_LIBIAF */
248*ee116499SAntonio Huete Jimenez 
249*ee116499SAntonio Huete Jimenez 	return locked;
250*ee116499SAntonio Huete Jimenez }
251