From: dtucker Date: Mon, 25 Aug 2003 01:51:19 +0000 (+0000) Subject: - (dtucker) [acconfig.h auth.c configure.ac sshd.8] Bug #422 again: deny X-Git-Tag: BEFORE_KRB5_GSSAPI_MERGE~4 X-Git-Url: http://andersk.mit.edu/gitweb/openssh.git/commitdiff_plain/3e6e3da046a052260cb9d59d49d9e81f2c27320b - (dtucker) [acconfig.h auth.c configure.ac sshd.8] Bug #422 again: deny any access to locked accounts. ok djm@ --- diff --git a/ChangeLog b/ChangeLog index cb40cc15..39398fc4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,8 @@ - (bal) redo how we handle 'mysignal()'. Move it to openbsd-compat/bsd-misc.c, s/mysignal/signal/ and #define signal to 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 - (djm) s/get_progname/ssh_get_progname/g to avoid conflict with Heimdal diff --git a/acconfig.h b/acconfig.h index 39ca97d9..d5d5d1ce 100644 --- a/acconfig.h +++ b/acconfig.h @@ -398,6 +398,11 @@ /* Define if cmsg_type is not passed correctly */ #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 */ #undef DNS diff --git a/auth.c b/auth.c index d4768a15..9a59e270 100644 --- a/auth.c +++ b/auth.c @@ -73,23 +73,25 @@ int allowed_user(struct passwd * pw) { struct stat st; - const char *hostname = NULL, *ipaddr = NULL; + const char *hostname = NULL, *ipaddr = NULL, *passwd; char *shell; int i; -#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) && \ - defined(HAS_SHADOW_EXPIRE) - struct spwd *spw; - time_t today; +#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) + struct spwd *spw = NULL; #endif /* Shouldn't be called if pw is NULL, but better safe than sorry... */ if (!pw || !pw->pw_name) return 0; -#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) && \ - defined(HAS_SHADOW_EXPIRE) +#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) + if (!options.use_pam) + spw = getspnam(pw->pw_name); +#ifdef HAS_SHADOW_EXPIRE #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; debug3("allowed_user: today %d sp_expire %d sp_lstchg %d" " sp_max %d", (int)today, (int)spw->sp_expire, @@ -117,8 +119,41 @@ allowed_user(struct passwd * pw) 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 + /* 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 * legal, and means /bin/sh. diff --git a/configure.ac b/configure.ac index e0f2a1cf..17415f6d 100644 --- a/configure.ac +++ b/configure.ac @@ -141,6 +141,7 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) AC_DEFINE(LOGIN_NEEDS_UTMPX) AC_DEFINE(DISABLE_SHADOW) AC_DEFINE(DISABLE_UTMP) + AC_DEFINE(LOCKED_PASSWD_STRING, "*") AC_DEFINE(SPT_TYPE,SPT_PSTAT) LIBS="$LIBS -lsec -lsecpw" 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(DISABLE_SHADOW) AC_DEFINE(DISABLE_UTMP) + AC_DEFINE(LOCKED_PASSWD_STRING, "*") AC_DEFINE(SPT_TYPE,SPT_PSTAT) LIBS="$LIBS -lsec" 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(DISABLE_SHADOW) AC_DEFINE(DISABLE_UTMP) + AC_DEFINE(LOCKED_PASSWD_STRING, "*") AC_DEFINE(SPT_TYPE,SPT_PSTAT) LIBS="$LIBS -lsec" 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" AC_DEFINE(BROKEN_INET_NTOA) AC_DEFINE(WITH_ABBREV_NO_TTY) + AC_DEFINE(LOCKED_PASSWD_STRING, "*LK*") ;; *-*-irix6*) 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_DEFINE(BROKEN_INET_NTOA) AC_DEFINE(WITH_ABBREV_NO_TTY) + AC_DEFINE(LOCKED_PASSWD_STRING, "*LK*") ;; *-*-linux*) no_dev_ptmx=1 @@ -198,6 +203,7 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) check_for_openpty_ctty_bug=1 AC_DEFINE(DONT_TRY_OTHER_AF) AC_DEFINE(PAM_TTY_KLUDGE) + AC_DEFINE(LOCKED_PASSWD_PREFIX, "!!") AC_DEFINE(SPT_TYPE,SPT_REUSEARGV) inet6_default_4in6=yes case `uname -r` in @@ -237,6 +243,7 @@ mips-sony-bsd|mips-sony-newsos4) AC_DEFINE(LOGIN_NEEDS_UTMPX) AC_DEFINE(LOGIN_NEEDS_TERM) AC_DEFINE(PAM_TTY_KLUDGE) + AC_DEFINE(LOCKED_PASSWD_STRING, "*LK*") # Pushing STREAMS modules will cause sshd to acquire a controlling tty. AC_DEFINE(SSHD_ACQUIRES_CTTY) # hardwire lastlog location (can't detect it on some versions) @@ -362,6 +369,7 @@ mips-sony-bsd|mips-sony-newsos4) fi fi AC_DEFINE(DISABLE_FD_PASSING) + AC_DEFINE(LOCKED_PASSWD_SUBSTR, "Nologin") ;; *-*-nto-qnx) diff --git a/sshd.8 b/sshd.8 index 4749fab8..0eeea666 100644 --- a/sshd.8 +++ b/sshd.8 @@ -114,6 +114,29 @@ authentication combined with RSA host authentication, RSA challenge-response authentication, or password based authentication. .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 because it is fundamentally insecure, but can be enabled in the server configuration file if desired.