/etc/nologin must be world-readable which is not totally clear

Darren Tucker dtucker at zip.com.au
Tue Jan 12 17:36:56 EST 2010


On Tue, Jan 12, 2010 at 04:34:04PM +1100, Darren Tucker wrote:
> On Tue, Jan 12, 2010 at 04:29:05AM +0300, Dmitry V. Levin wrote:
> > On Tue, Jan 12, 2010 at 12:24:20PM +1100, Darren Tucker wrote:
> [...]
> > > The simple solution is to check errno for EPERM.  I'm about to apply the
> > > following patch which should cover it.
> > 
> > Please check for EACCES, too.
> 
> Jan Pechanec pointed this out too.  After thinking about it some more I'm
> mildly concerned about failure scenarios involving the other path
> components (eg root accidentally chmods /etc or something).  After
> discussing it with Damien I thing we should add an explict stat().

Gah, wrong diff.  This is the one I meant to send.

Index: session.c
===================================================================
RCS file: /cvs/src/usr.bin/ssh/session.c,v
retrieving revision 1.250
diff -u -p -r1.250 session.c
--- session.c	12 Jan 2010 01:31:05 -0000	1.250
+++ session.c	12 Jan 2010 04:27:37 -0000
@@ -1100,22 +1100,27 @@ static void
 do_nologin(struct passwd *pw)
 {
 	FILE *f = NULL;
-	char buf[1024];
+	char buf[1024], *nl, *def_nl =  _PATH_NOLOGIN;
+	struct stat sb;
 
-	if (!login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid)
-		f = fopen(login_getcapstr(lc, "nologin", _PATH_NOLOGIN,
-		    _PATH_NOLOGIN), "r");
-	if (f != NULL || errno == EPERM) {
-		/* /etc/nologin exists.  Print its contents and exit. */
-		logit("User %.100s not allowed because %s exists",
-		    pw->pw_name, _PATH_NOLOGIN);
-		if (f == NULL)
-			exit(254);
+	if (login_getcapbool(lc, "ignorenologin", 0) && pw->pw_uid)
+		return;
+	nl = login_getcapstr(lc, "nologin", def_nl, def_nl);
+
+	if (stat(nl, &sb) == -1) {
+		if (nl != def_nl)
+			xfree(nl);
+		return;
+	}
+
+	/* /etc/nologin exists.  Print its contents if we can and exit. */
+	logit("User %.100s not allowed because %s exists", pw->pw_name, nl);
+	if ((f = fopen(nl, "r")) != NULL) {
 		while (fgets(buf, sizeof(buf), f))
 			fputs(buf, stderr);
 		fclose(f);
-		exit(254);
 	}
+	exit(254);
 }
 
 /*

-- 
Darren Tucker (dtucker at zip.com.au)
GPG key 8FF4FA69 / D9A3 86E9 7EEE AF4B B2D4  37C9 C982 80C7 8FF4 FA69
    Good judgement comes with experience. Unfortunately, the experience
usually comes from bad judgement.


More information about the openssh-unix-dev mailing list