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