xref: /freebsd/crypto/openssh/platform.c (revision 0fdf8fae8b569bf9fff3b5171e669dcd7cf9c79e)
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>
2187c1498dSEd 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 ServerOptions options;
364a421b63SDag-Erling Smørgrav 
374a421b63SDag-Erling Smørgrav /* return 1 if we are running with privilege to swap UIDs, 0 otherwise */
384a421b63SDag-Erling Smørgrav int
platform_privileged_uidswap(void)394a421b63SDag-Erling Smørgrav platform_privileged_uidswap(void)
404a421b63SDag-Erling Smørgrav {
414a421b63SDag-Erling Smørgrav #ifdef HAVE_CYGWIN
424a421b63SDag-Erling Smørgrav 	/* uid 0 is not special on Cygwin so always try */
434a421b63SDag-Erling Smørgrav 	return 1;
444a421b63SDag-Erling Smørgrav #else
454a421b63SDag-Erling Smørgrav 	return (getuid() == 0 || geteuid() == 0);
464a421b63SDag-Erling Smørgrav #endif
474a421b63SDag-Erling Smørgrav }
484a421b63SDag-Erling Smørgrav 
494a421b63SDag-Erling Smørgrav /*
504a421b63SDag-Erling Smørgrav  * This gets called before switching UIDs, and is called even when sshd is
514a421b63SDag-Erling Smørgrav  * not running as root.
524a421b63SDag-Erling Smørgrav  */
534a421b63SDag-Erling Smørgrav void
platform_setusercontext(struct passwd * pw)544a421b63SDag-Erling Smørgrav platform_setusercontext(struct passwd *pw)
554a421b63SDag-Erling Smørgrav {
564a421b63SDag-Erling Smørgrav #ifdef WITH_SELINUX
574a421b63SDag-Erling Smørgrav 	/* Cache selinux status for later use */
584a421b63SDag-Erling Smørgrav 	(void)ssh_selinux_enabled();
594a421b63SDag-Erling Smørgrav #endif
604a421b63SDag-Erling Smørgrav 
614a421b63SDag-Erling Smørgrav #ifdef USE_SOLARIS_PROJECTS
62076ad2f8SDag-Erling Smørgrav 	/*
63076ad2f8SDag-Erling Smørgrav 	 * If solaris projects were detected, set the default now, unless
64076ad2f8SDag-Erling Smørgrav 	 * we are using PAM in which case it is the responsibility of the
65076ad2f8SDag-Erling Smørgrav 	 * PAM stack.
66076ad2f8SDag-Erling Smørgrav 	 */
67076ad2f8SDag-Erling Smørgrav 	if (!options.use_pam && (getuid() == 0 || geteuid() == 0))
684a421b63SDag-Erling Smørgrav 		solaris_set_default_project(pw);
694a421b63SDag-Erling Smørgrav #endif
704a421b63SDag-Erling Smørgrav 
714a421b63SDag-Erling Smørgrav #if defined(HAVE_LOGIN_CAP) && defined (__bsdi__)
724a421b63SDag-Erling Smørgrav 	if (getuid() == 0 || geteuid() == 0)
734a421b63SDag-Erling Smørgrav 		setpgid(0, 0);
744a421b63SDag-Erling Smørgrav # endif
754a421b63SDag-Erling Smørgrav 
764a421b63SDag-Erling Smørgrav #if defined(HAVE_LOGIN_CAP) && defined(USE_PAM)
774a421b63SDag-Erling Smørgrav 	/*
784a421b63SDag-Erling Smørgrav 	 * If we have both LOGIN_CAP and PAM, we want to establish creds
794a421b63SDag-Erling Smørgrav 	 * before calling setusercontext (in session.c:do_setusercontext).
804a421b63SDag-Erling Smørgrav 	 */
814a421b63SDag-Erling Smørgrav 	if (getuid() == 0 || geteuid() == 0) {
824a421b63SDag-Erling Smørgrav 		if (options.use_pam) {
83*0fdf8faeSEd Maste 			do_pam_setcred();
844a421b63SDag-Erling Smørgrav 		}
854a421b63SDag-Erling Smørgrav 	}
864a421b63SDag-Erling Smørgrav # endif /* USE_PAM */
874a421b63SDag-Erling Smørgrav 
884a421b63SDag-Erling Smørgrav #if !defined(HAVE_LOGIN_CAP) && defined(HAVE_GETLUID) && defined(HAVE_SETLUID)
894a421b63SDag-Erling Smørgrav 	if (getuid() == 0 || geteuid() == 0) {
904a421b63SDag-Erling Smørgrav 		/* Sets login uid for accounting */
914a421b63SDag-Erling Smørgrav 		if (getluid() == -1 && setluid(pw->pw_uid) == -1)
924a421b63SDag-Erling Smørgrav 			error("setluid: %s", strerror(errno));
934a421b63SDag-Erling Smørgrav 	}
944a421b63SDag-Erling Smørgrav #endif
954a421b63SDag-Erling Smørgrav }
964a421b63SDag-Erling Smørgrav 
974a421b63SDag-Erling Smørgrav /*
984a421b63SDag-Erling Smørgrav  * This gets called after we've established the user's groups, and is only
994a421b63SDag-Erling Smørgrav  * called if sshd is running as root.
1004a421b63SDag-Erling Smørgrav  */
1014a421b63SDag-Erling Smørgrav void
platform_setusercontext_post_groups(struct passwd * pw)1024a421b63SDag-Erling Smørgrav platform_setusercontext_post_groups(struct passwd *pw)
1034a421b63SDag-Erling Smørgrav {
1044a421b63SDag-Erling Smørgrav #if !defined(HAVE_LOGIN_CAP) && defined(USE_PAM)
1054a421b63SDag-Erling Smørgrav 	/*
1064a421b63SDag-Erling Smørgrav 	 * PAM credentials may take the form of supplementary groups.
1074a421b63SDag-Erling Smørgrav 	 * These will have been wiped by the above initgroups() call.
1084a421b63SDag-Erling Smørgrav 	 * Reestablish them here.
1094a421b63SDag-Erling Smørgrav 	 */
1104a421b63SDag-Erling Smørgrav 	if (options.use_pam) {
111*0fdf8faeSEd Maste 		do_pam_setcred();
1124a421b63SDag-Erling Smørgrav 	}
1134a421b63SDag-Erling Smørgrav #endif /* USE_PAM */
1144a421b63SDag-Erling Smørgrav 
1154a421b63SDag-Erling Smørgrav #if !defined(HAVE_LOGIN_CAP) && (defined(WITH_IRIX_PROJECT) || \
1164a421b63SDag-Erling Smørgrav     defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY))
1174a421b63SDag-Erling Smørgrav 	irix_setusercontext(pw);
1184a421b63SDag-Erling Smørgrav #endif /* defined(WITH_IRIX_PROJECT) || defined(WITH_IRIX_JOBS) || defined(WITH_IRIX_ARRAY) */
1194a421b63SDag-Erling Smørgrav 
1204a421b63SDag-Erling Smørgrav #ifdef _AIX
1214a421b63SDag-Erling Smørgrav 	aix_usrinfo(pw);
1224a421b63SDag-Erling Smørgrav #endif /* _AIX */
1234a421b63SDag-Erling Smørgrav 
1244a421b63SDag-Erling Smørgrav #ifdef HAVE_SETPCRED
1254a421b63SDag-Erling Smørgrav 	/*
1264a421b63SDag-Erling Smørgrav 	 * If we have a chroot directory, we set all creds except real
1274a421b63SDag-Erling Smørgrav 	 * uid which we will need for chroot.  If we don't have a
1284a421b63SDag-Erling Smørgrav 	 * chroot directory, we don't override anything.
1294a421b63SDag-Erling Smørgrav 	 */
1304a421b63SDag-Erling Smørgrav 	{
1314a421b63SDag-Erling Smørgrav 		char **creds = NULL, *chroot_creds[] =
1324a421b63SDag-Erling Smørgrav 		    { "REAL_USER=root", NULL };
1334a421b63SDag-Erling Smørgrav 
1344a421b63SDag-Erling Smørgrav 		if (options.chroot_directory != NULL &&
1354a421b63SDag-Erling Smørgrav 		    strcasecmp(options.chroot_directory, "none") != 0)
1364a421b63SDag-Erling Smørgrav 			creds = chroot_creds;
1374a421b63SDag-Erling Smørgrav 
1384a421b63SDag-Erling Smørgrav 		if (setpcred(pw->pw_name, creds) == -1)
1394a421b63SDag-Erling Smørgrav 			fatal("Failed to set process credentials");
1404a421b63SDag-Erling Smørgrav 	}
1414a421b63SDag-Erling Smørgrav #endif /* HAVE_SETPCRED */
1424a421b63SDag-Erling Smørgrav #ifdef WITH_SELINUX
1434a421b63SDag-Erling Smørgrav 	ssh_selinux_setup_exec_context(pw->pw_name);
1444a421b63SDag-Erling Smørgrav #endif
1454a421b63SDag-Erling Smørgrav }
1464a421b63SDag-Erling Smørgrav 
147b15c8340SDag-Erling Smørgrav char *
platform_krb5_get_principal_name(const char * pw_name)148b15c8340SDag-Erling Smørgrav platform_krb5_get_principal_name(const char *pw_name)
149b15c8340SDag-Erling Smørgrav {
150b15c8340SDag-Erling Smørgrav #ifdef USE_AIX_KRB_NAME
151b15c8340SDag-Erling Smørgrav 	return aix_krb5_get_principal_name(pw_name);
152b15c8340SDag-Erling Smørgrav #else
153b15c8340SDag-Erling Smørgrav 	return NULL;
154b15c8340SDag-Erling Smørgrav #endif
155761efaa7SDag-Erling Smørgrav }
15687c1498dSEd Maste 
15787c1498dSEd Maste /* returns 1 if account is locked */
15887c1498dSEd Maste int
platform_locked_account(struct passwd * pw)15987c1498dSEd Maste platform_locked_account(struct passwd *pw)
16087c1498dSEd Maste {
16187c1498dSEd Maste 	int locked = 0;
16287c1498dSEd Maste 	char *passwd = pw->pw_passwd;
16387c1498dSEd Maste #ifdef USE_SHADOW
16487c1498dSEd Maste 	struct spwd *spw = NULL;
16587c1498dSEd Maste #ifdef USE_LIBIAF
16687c1498dSEd Maste 	char *iaf_passwd = NULL;
16787c1498dSEd Maste #endif
16887c1498dSEd Maste 
16987c1498dSEd Maste 	spw = getspnam(pw->pw_name);
17087c1498dSEd Maste #ifdef HAS_SHADOW_EXPIRE
17187c1498dSEd Maste 	if (spw != NULL && auth_shadow_acctexpired(spw))
17287c1498dSEd Maste 		return 1;
17387c1498dSEd Maste #endif /* HAS_SHADOW_EXPIRE */
17487c1498dSEd Maste 
17587c1498dSEd Maste 	if (spw != NULL)
17687c1498dSEd Maste #ifdef USE_LIBIAF
17787c1498dSEd Maste 		iaf_passwd = passwd = get_iaf_password(pw);
17887c1498dSEd Maste #else
17987c1498dSEd Maste 		passwd = spw->sp_pwdp;
18087c1498dSEd Maste #endif /* USE_LIBIAF */
18187c1498dSEd Maste #endif
18287c1498dSEd Maste 
18387c1498dSEd Maste 	/* check for locked account */
18487c1498dSEd Maste 	if (passwd && *passwd) {
18587c1498dSEd Maste #ifdef LOCKED_PASSWD_STRING
18687c1498dSEd Maste 		if (strcmp(passwd, LOCKED_PASSWD_STRING) == 0)
18787c1498dSEd Maste 			locked = 1;
18887c1498dSEd Maste #endif
18987c1498dSEd Maste #ifdef LOCKED_PASSWD_PREFIX
19087c1498dSEd Maste 		if (strncmp(passwd, LOCKED_PASSWD_PREFIX,
19187c1498dSEd Maste 		    strlen(LOCKED_PASSWD_PREFIX)) == 0)
19287c1498dSEd Maste 			locked = 1;
19387c1498dSEd Maste #endif
19487c1498dSEd Maste #ifdef LOCKED_PASSWD_SUBSTR
19587c1498dSEd Maste 		if (strstr(passwd, LOCKED_PASSWD_SUBSTR))
19687c1498dSEd Maste 			locked = 1;
19787c1498dSEd Maste #endif
19887c1498dSEd Maste 	}
19987c1498dSEd Maste #ifdef USE_LIBIAF
20087c1498dSEd Maste 	if (iaf_passwd != NULL)
20187c1498dSEd Maste 		freezero(iaf_passwd, strlen(iaf_passwd));
20287c1498dSEd Maste #endif /* USE_LIBIAF */
20387c1498dSEd Maste 
20487c1498dSEd Maste 	return locked;
20587c1498dSEd Maste }
206