Niklas Edmundsson
2000-Jul-09 18:04 UTC
OpenSSH 2.1.1p2: /etc/nologin handling and related stuff
Attached is a patch to be applied with GNU patch -p0, notice that configure needs to be regenerated. The patch addresses the following annoyances: * On AIX there is a signal called SIGDANGER which is sent to all processes when the machine runs low on virtual memory. This patch makes sure that this signal is ignored, because the default on older AIX releases is to kill the running process (which is pretty bad). * On AIX loginrestrictions() is called to decide whether the user is allowed to log in. Since OpenSSH has the PermitRootLogin configuration option you don't want loginrestrictions() pertain to root (since you generally disable remote root logins and only enable root logins with 'PermitRootLogin without-password' ...). This patch ignores loginrestrictions() for root. * There is no pam_nologin on Solaris, thus the handling of /etc/nologin needs to be there even though PAM is used. This patch simply removes the #ifdef USE_PAM since it's better with two checks on some OS's instead of none on some, a more correct solution is probably not that hard to come up with though. * This patch introduces the configure option --with-nologin-allow=FILE which, when defined, specifies a file containing users that should be able to log in even though /etc/nologin exists. Additionally, we have noticed the following problems with OpenSSH: * On AIX, the message from loginrestrictions() isn't shown to the user, like it's supposed to, but instead stored in the log file of SSH. * Also, loginrestrictions() is called before the check of /etc/nologin, and since loginrestrictions() also checks for nologin the user isn't allowed to log in even though the user is in the nologin-allow file introduced in the attached patch. Since the user doesn't see the nologin (which instead is logged in the sshd log file) this is most confusing. * make install overwrites ssh_prng_cmds. Also, the script that generates ssh_prng_cmds doesn't seem to check for binaries in /usr/sbin/ where arp, ifconfig etc. resides on Solaris and others. A suggestion is also to parse /etc/syslog.conf to find out which log files there is instead of taking a stab at which files there might be. /bin/who -a dumps all information from utmp on AIX, Solaris and others, who -i doesn't work. Doing ls -l on /var/.../mail isn't that good when it's NFS mounted. * In general, there is very little documentation on ssh_prng_cmds (or I'm blind ;) * Running on an Sparc LX (ie. a very slow machine) on Solaris8 we sometimes get the following error message upon startup: # /usr/local/sbin/sshd fatal: Couldn't initialise builtin random number generator -- exiting. What failed? The entropy-stuff, or some random thing that went bezerk? Any hints on how to debug this is appreciated, since we don't want to run a daemon that sometimes just fails to start... * Also on Solaris8 we get the following message in the sshd log file when a user logs out: sshd[4692]: [ID 800047 auth.info] Cannot delete credentials: Permission denied This seems to be a PAM issue, but that's about all we've figured out... /Nikke - wants OpenSSH to be perfect :) -- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Niklas Edmundsson, Admin @ {acc,hpc2n,ing}.umu.se | nikke at ing.umu.se --------------------------------------------------------------------------- "I happen to like nice men." - Leia =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--------------- next part -------------- diff -ruw -x configure ../dist/acconfig.h ./acconfig.h --- ../dist/acconfig.h Sat Jul 1 08:52:55 2000 +++ ./acconfig.h Sat Jul 8 21:13:22 2000 @@ -214,6 +214,9 @@ /* Detect IPv4 in IPv6 mapped addresses and treat as IPv4 */ #undef IPV4_IN_IPV6 +/* File with users to allow even with /etc/nologin in place */ +#undef NOLOGIN_ALLOW_FILE + @BOTTOM@ /* ******************* Shouldn't need to edit below this line ************** */ diff -ruw -x configure ../dist/auth.c ./auth.c --- ../dist/auth.c Mon Jun 26 03:31:33 2000 +++ ./auth.c Sat Jul 8 19:53:37 2000 @@ -145,7 +145,8 @@ } #ifdef WITH_AIXAUTHENTICATE - if (loginrestrictions(pw->pw_name, S_RLOGIN, NULL, &loginmsg) != 0) { + if (loginrestrictions(pw->pw_name, S_RLOGIN, NULL, &loginmsg) != 0 && + pw->pw_uid != 0) { if (loginmsg && *loginmsg) { /* Remove embedded newlines (if any) */ char *p; diff -ruw -x configure ../dist/config.h.in ./config.h.in --- ../dist/config.h.in Sat Jul 1 11:43:08 2000 +++ ./config.h.in Sat Jul 8 21:13:53 2000 @@ -201,6 +201,9 @@ /* Detect IPv4 in IPv6 mapped addresses and treat as IPv4 */ #undef IPV4_IN_IPV6 +/* File with users to allow even with /etc/nologin in place */ +#undef NOLOGIN_ALLOW_FILE + /* The number of bytes in a char. */ #undef SIZEOF_CHAR diff -ruw -x configure ../dist/configure.in ./configure.in --- ../dist/configure.in Sat Jul 1 08:52:55 2000 +++ ./configure.in Sat Jul 8 21:12:27 2000 @@ -823,6 +823,17 @@ fi AC_SUBST(INSTALL_SSH_PRNG_CMDS) +# Check for nologin-allow file +AC_ARG_WITH(nologin-allow, + [ --with-nologin-allow=FILE File with users to allow during nologin (default none)], + [ + if test "x$withval" != "xno" ; then + NOLOGIN_ALLOW_FILE="$withval"; + AC_DEFINE_UNQUOTED(NOLOGIN_ALLOW_FILE, "$NOLOGIN_ALLOW_FILE") + fi + ] +) + AC_ARG_WITH(catman, [ --with-catman=man|cat Install preformatted manpages[no]], diff -ruw -x configure ../dist/session.c ./session.c --- ../dist/session.c Sat Jul 1 05:24:21 2000 +++ ./session.c Sun Jul 9 19:22:23 2000 @@ -816,17 +816,34 @@ if (options.use_login && command != NULL) options.use_login = 0; -#ifndef USE_PAM /* pam_nologin handles this */ f = fopen("/etc/nologin", "r"); if (f) { + char notallowed=1; /* /etc/nologin exists. Print its contents and exit. */ + fprintf(stderr, "\aLogins are currently disallowed:\n\n"); while (fgets(buf, sizeof(buf), f)) fputs(buf, stderr); + fprintf(stderr, "\n"); fclose(f); - if (pw->pw_uid != 0) +#ifdef NOLOGIN_ALLOW_FILE + if((f=fopen(NOLOGIN_ALLOW_FILE, "r"))) { + char *tmpend; + while (fgets(buf, sizeof(buf), f)) { + if(*buf=='\0' || *buf=='#' || *buf=='\n' || *buf=='\r') + continue; + if((tmpend=strchr(buf, '\n'))) + *tmpend='\0'; + if(!strcmp(buf, pw->pw_name)) { + notallowed=0; + break; + } + } + } + fclose(f); +#endif /* NOLOGIN_ALLOW_FILE */ + if (pw->pw_uid != 0 && notallowed != 0) exit(254); } -#endif /* USE_PAM */ #ifndef HAVE_OSF_SIA /* Set login name in the kernel. */ diff -ruw -x configure ../dist/sshd.c ./sshd.c --- ../dist/sshd.c Wed Jun 28 07:22:42 2000 +++ ./sshd.c Sun Jul 9 19:23:29 2000 @@ -746,6 +746,10 @@ signal(SIGHUP, sighup_handler); signal(SIGTERM, sigterm_handler); signal(SIGQUIT, sigterm_handler); +#ifdef SIGDANGER + /* Don't die on AIX when the machine runs low on memory */ + signal(SIGDANGER, SIG_IGN); +#endif /* Arrange SIGCHLD to be caught. */ signal(SIGCHLD, main_sigchld_handler);