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

Joachim Schipper joachim at joachimschipper.nl
Tue Jan 12 20:08:27 EST 2010


On Tue, Jan 12, 2010 at 05:36:56PM +1100, Darren Tucker wrote:
> 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.

This should work, but have you considered access(2)?

		Joachim

> 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);
>  }
>  
>  /*


More information about the openssh-unix-dev mailing list