- (dtucker) [acconfig.h auth.c configure.ac sshd.8] Bug #422 again: deny

any access to locked accounts.  ok djm@
This commit is contained in:
Darren Tucker 2003-08-25 11:51:19 +10:00
parent 5ade9abc37
commit e41bba5847
5 changed files with 84 additions and 11 deletions

View File

@ -6,6 +6,8 @@
- (bal) redo how we handle 'mysignal()'. Move it to - (bal) redo how we handle 'mysignal()'. Move it to
openbsd-compat/bsd-misc.c, s/mysignal/signal/ and #define signal to openbsd-compat/bsd-misc.c, s/mysignal/signal/ and #define signal to
be our 'mysignal' by default. OK djm@ be our 'mysignal' by default. OK djm@
- (dtucker) [acconfig.h auth.c configure.ac sshd.8] Bug #422 again: deny
any access to locked accounts. ok djm@
20030822 20030822
- (djm) s/get_progname/ssh_get_progname/g to avoid conflict with Heimdal - (djm) s/get_progname/ssh_get_progname/g to avoid conflict with Heimdal
@ -860,4 +862,4 @@
- Fix sshd BindAddress and -b options for systems using fake-getaddrinfo. - Fix sshd BindAddress and -b options for systems using fake-getaddrinfo.
Report from murple@murple.net, diagnosis from dtucker@zip.com.au Report from murple@murple.net, diagnosis from dtucker@zip.com.au
$Id: ChangeLog,v 1.2901 2003/08/25 01:16:21 mouring Exp $ $Id: ChangeLog,v 1.2902 2003/08/25 01:51:19 dtucker Exp $

View File

@ -1,4 +1,4 @@
/* $Id: acconfig.h,v 1.160 2003/08/02 12:24:49 dtucker Exp $ */ /* $Id: acconfig.h,v 1.161 2003/08/25 01:51:19 dtucker Exp $ */
/* /*
* Copyright (c) 1999-2003 Damien Miller. All rights reserved. * Copyright (c) 1999-2003 Damien Miller. All rights reserved.
@ -398,6 +398,11 @@
/* Define if cmsg_type is not passed correctly */ /* Define if cmsg_type is not passed correctly */
#undef BROKEN_CMSG_TYPE #undef BROKEN_CMSG_TYPE
/* Strings used in /etc/passwd to denote locked account */
#undef LOCKED_PASSWD_STRING
#undef LOCKED_PASSWD_PREFIX
#undef LOCKED_PASSWD_SUBSTR
/* Define if DNS support is to be activated */ /* Define if DNS support is to be activated */
#undef DNS #undef DNS

51
auth.c
View File

@ -73,23 +73,25 @@ int
allowed_user(struct passwd * pw) allowed_user(struct passwd * pw)
{ {
struct stat st; struct stat st;
const char *hostname = NULL, *ipaddr = NULL; const char *hostname = NULL, *ipaddr = NULL, *passwd;
char *shell; char *shell;
int i; int i;
#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) && \ #if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
defined(HAS_SHADOW_EXPIRE) struct spwd *spw = NULL;
struct spwd *spw;
time_t today;
#endif #endif
/* Shouldn't be called if pw is NULL, but better safe than sorry... */ /* Shouldn't be called if pw is NULL, but better safe than sorry... */
if (!pw || !pw->pw_name) if (!pw || !pw->pw_name)
return 0; return 0;
#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) && \ #if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
defined(HAS_SHADOW_EXPIRE) if (!options.use_pam)
spw = getspnam(pw->pw_name);
#ifdef HAS_SHADOW_EXPIRE
#define DAY (24L * 60 * 60) /* 1 day in seconds */ #define DAY (24L * 60 * 60) /* 1 day in seconds */
if (!options.use_pam && (spw = getspnam(pw->pw_name)) != NULL) { if (!options.use_pam && spw != NULL) {
time_t today;
today = time(NULL) / DAY; today = time(NULL) / DAY;
debug3("allowed_user: today %d sp_expire %d sp_lstchg %d" debug3("allowed_user: today %d sp_expire %d sp_lstchg %d"
" sp_max %d", (int)today, (int)spw->sp_expire, " sp_max %d", (int)today, (int)spw->sp_expire,
@ -117,8 +119,41 @@ allowed_user(struct passwd * pw)
return 0; return 0;
} }
} }
#endif /* HAS_SHADOW_EXPIRE */
#endif /* defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) */
/* grab passwd field for locked account check */
#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
if (spw != NULL)
passwd = spw->sp_pwdp;
#else
passwd = pw->pw_passwd;
#endif #endif
/* check for locked account */
if (passwd && *passwd) {
int locked = 0;
#ifdef LOCKED_PASSWD_STRING
if (strcmp(passwd, LOCKED_PASSWD_STRING) == 0)
locked = 1;
#endif
#ifdef LOCKED_PASSWD_PREFIX
if (strncmp(passwd, LOCKED_PASSWD_PREFIX,
strlen(LOCKED_PASSWD_PREFIX)) == 0)
locked = 1;
#endif
#ifdef LOCKED_PASSWD_SUBSTR
if (strstr(passwd, LOCKED_PASSWD_SUBSTR))
locked = 1;
#endif
if (locked) {
logit("User %.100s not allowed because account is locked",
pw->pw_name);
return 0;
}
}
/* /*
* Get the shell from the password data. An empty shell field is * Get the shell from the password data. An empty shell field is
* legal, and means /bin/sh. * legal, and means /bin/sh.

View File

@ -1,4 +1,4 @@
# $Id: configure.ac,v 1.140 2003/08/21 07:58:29 dtucker Exp $ # $Id: configure.ac,v 1.141 2003/08/25 01:51:19 dtucker Exp $
AC_INIT AC_INIT
AC_CONFIG_SRCDIR([ssh.c]) AC_CONFIG_SRCDIR([ssh.c])
@ -141,6 +141,7 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
AC_DEFINE(LOGIN_NEEDS_UTMPX) AC_DEFINE(LOGIN_NEEDS_UTMPX)
AC_DEFINE(DISABLE_SHADOW) AC_DEFINE(DISABLE_SHADOW)
AC_DEFINE(DISABLE_UTMP) AC_DEFINE(DISABLE_UTMP)
AC_DEFINE(LOCKED_PASSWD_STRING, "*")
AC_DEFINE(SPT_TYPE,SPT_PSTAT) AC_DEFINE(SPT_TYPE,SPT_PSTAT)
LIBS="$LIBS -lsec -lsecpw" LIBS="$LIBS -lsec -lsecpw"
AC_CHECK_LIB(xnet, t_error, ,AC_MSG_ERROR([*** -lxnet needed on HP-UX - check config.log ***])) AC_CHECK_LIB(xnet, t_error, ,AC_MSG_ERROR([*** -lxnet needed on HP-UX - check config.log ***]))
@ -157,6 +158,7 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
AC_DEFINE(LOGIN_NEEDS_UTMPX) AC_DEFINE(LOGIN_NEEDS_UTMPX)
AC_DEFINE(DISABLE_SHADOW) AC_DEFINE(DISABLE_SHADOW)
AC_DEFINE(DISABLE_UTMP) AC_DEFINE(DISABLE_UTMP)
AC_DEFINE(LOCKED_PASSWD_STRING, "*")
AC_DEFINE(SPT_TYPE,SPT_PSTAT) AC_DEFINE(SPT_TYPE,SPT_PSTAT)
LIBS="$LIBS -lsec" LIBS="$LIBS -lsec"
AC_CHECK_LIB(xnet, t_error, ,AC_MSG_ERROR([*** -lxnet needed on HP-UX - check config.log ***])) AC_CHECK_LIB(xnet, t_error, ,AC_MSG_ERROR([*** -lxnet needed on HP-UX - check config.log ***]))
@ -170,6 +172,7 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
AC_DEFINE(LOGIN_NEEDS_UTMPX) AC_DEFINE(LOGIN_NEEDS_UTMPX)
AC_DEFINE(DISABLE_SHADOW) AC_DEFINE(DISABLE_SHADOW)
AC_DEFINE(DISABLE_UTMP) AC_DEFINE(DISABLE_UTMP)
AC_DEFINE(LOCKED_PASSWD_STRING, "*")
AC_DEFINE(SPT_TYPE,SPT_PSTAT) AC_DEFINE(SPT_TYPE,SPT_PSTAT)
LIBS="$LIBS -lsec" LIBS="$LIBS -lsec"
AC_CHECK_LIB(xnet, t_error, ,AC_MSG_ERROR([*** -lxnet needed on HP-UX - check config.log ***])) AC_CHECK_LIB(xnet, t_error, ,AC_MSG_ERROR([*** -lxnet needed on HP-UX - check config.log ***]))
@ -180,6 +183,7 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
PATH="$PATH:/usr/etc" PATH="$PATH:/usr/etc"
AC_DEFINE(BROKEN_INET_NTOA) AC_DEFINE(BROKEN_INET_NTOA)
AC_DEFINE(WITH_ABBREV_NO_TTY) AC_DEFINE(WITH_ABBREV_NO_TTY)
AC_DEFINE(LOCKED_PASSWD_STRING, "*LK*")
;; ;;
*-*-irix6*) *-*-irix6*)
CPPFLAGS="$CPPFLAGS -I/usr/local/include" CPPFLAGS="$CPPFLAGS -I/usr/local/include"
@ -191,6 +195,7 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
AC_CHECK_FUNC(jlimit_startjob, [AC_DEFINE(WITH_IRIX_JOBS)]) AC_CHECK_FUNC(jlimit_startjob, [AC_DEFINE(WITH_IRIX_JOBS)])
AC_DEFINE(BROKEN_INET_NTOA) AC_DEFINE(BROKEN_INET_NTOA)
AC_DEFINE(WITH_ABBREV_NO_TTY) AC_DEFINE(WITH_ABBREV_NO_TTY)
AC_DEFINE(LOCKED_PASSWD_STRING, "*LK*")
;; ;;
*-*-linux*) *-*-linux*)
no_dev_ptmx=1 no_dev_ptmx=1
@ -198,6 +203,7 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
check_for_openpty_ctty_bug=1 check_for_openpty_ctty_bug=1
AC_DEFINE(DONT_TRY_OTHER_AF) AC_DEFINE(DONT_TRY_OTHER_AF)
AC_DEFINE(PAM_TTY_KLUDGE) AC_DEFINE(PAM_TTY_KLUDGE)
AC_DEFINE(LOCKED_PASSWD_PREFIX, "!!")
AC_DEFINE(SPT_TYPE,SPT_REUSEARGV) AC_DEFINE(SPT_TYPE,SPT_REUSEARGV)
inet6_default_4in6=yes inet6_default_4in6=yes
case `uname -r` in case `uname -r` in
@ -237,6 +243,7 @@ mips-sony-bsd|mips-sony-newsos4)
AC_DEFINE(LOGIN_NEEDS_UTMPX) AC_DEFINE(LOGIN_NEEDS_UTMPX)
AC_DEFINE(LOGIN_NEEDS_TERM) AC_DEFINE(LOGIN_NEEDS_TERM)
AC_DEFINE(PAM_TTY_KLUDGE) AC_DEFINE(PAM_TTY_KLUDGE)
AC_DEFINE(LOCKED_PASSWD_STRING, "*LK*")
# Pushing STREAMS modules will cause sshd to acquire a controlling tty. # Pushing STREAMS modules will cause sshd to acquire a controlling tty.
AC_DEFINE(SSHD_ACQUIRES_CTTY) AC_DEFINE(SSHD_ACQUIRES_CTTY)
# hardwire lastlog location (can't detect it on some versions) # hardwire lastlog location (can't detect it on some versions)
@ -362,6 +369,7 @@ mips-sony-bsd|mips-sony-newsos4)
fi fi
fi fi
AC_DEFINE(DISABLE_FD_PASSING) AC_DEFINE(DISABLE_FD_PASSING)
AC_DEFINE(LOCKED_PASSWD_SUBSTR, "Nologin")
;; ;;
*-*-nto-qnx) *-*-nto-qnx)

23
sshd.8
View File

@ -114,6 +114,29 @@ authentication combined with RSA host
authentication, RSA challenge-response authentication, or password authentication, RSA challenge-response authentication, or password
based authentication. based authentication.
.Pp .Pp
Regardless of the authentication type, the account is checked to
ensure that it is accessible. An account is not accessible if it is
locked, listed in
.Cm DenyUsers
or its group is listed in
.Cm DenyGroups
\&. The definition of a locked account is system dependant. Some platforms
have their own account database (eg AIX) and some modify the passwd field (
.Ql \&*LK\&*
on Solaris,
.Ql \&*
on HP-UX, containing
.Ql Nologin
on Tru64 and a leading
.Ql \&!!
on Linux). If there is a requirement to disable password authentication
for the account while allowing still public-key, then the passwd field
should be set to something other than these values (eg
.Ql NP
or
.Ql \&*NP\&*
).
.Pp
Rhosts authentication is normally disabled Rhosts authentication is normally disabled
because it is fundamentally insecure, but can be enabled in the server because it is fundamentally insecure, but can be enabled in the server
configuration file if desired. configuration file if desired.