OpenSSH 2.1.1p2: /etc/nologin handling and related stuff

Niklas Edmundsson nikke at ing.umu.se
Mon Jul 10 04:04:10 EST 2000


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);


More information about the openssh-unix-dev mailing list