NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

bin/43390: shutdown does not remove /etc/nologin when called with -r, -h or -p

>Number:         43390
>Category:       bin
>Synopsis:       shutdown does not remove /etc/nologin when called with -r, -h 
>or -p
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun May 30 15:50:00 +0000 2010
>Originator:     Ian D. Leroux
>Release:        amd64 5.0.2-RELEASE
NetBSD 5.0.2 NetBSD 5.0.2 (GENERIC) #0: Sat Feb  6 13:44:19 
UTC 2010
If shutdown(8) is called with any of the -r, -h, or -p options on a system 
where / is marked read-only in /etc/fstab but is currently writable, then 
non-root logins are disabled at the next boot.

Provided the root file system is currently writable, shutdown(8) creates the 
file /etc/nologin to prevent inadvertant logins just before the system goes 
down.  Normally this file is removed just before shutdown(8) exits in the 
finish() function.  However, if shutdown(8) is called with any of the flags -r, 
-h, or -p it execs reboot(8), poweroff(8), or halt(8); the finish() function is 
never called, and /etc/nologin is never removed.  This prevents login as a 
non-root user at the next boot.

This behaviour is noticeable if / is marked ro in /etc/fstab; otherwise 
/etc/rc.d/mountcritlocal independently removes /etc/nologin at boot time, if 

Thanks to Robert Elz for helping me understand the cause of the problem.
# Mark / as readonly in /etc/fstab, thus preventing the 
# /etc/rc.d/mountcritlocal script from removing /etc/nologin during boot.

mount -u -w /
shutdown -r now

# attempt to login as a normal user
The following patch /usr/src/sbin/shutdown/shutdown.c corrects the problem

--- shutdown.c.orig     2010-05-30 08:03:19.000000000 -0400
+++ shutdown.c  2010-05-30 08:11:26.000000000 -0400
@@ -395,6 +395,7 @@
                        *arg++ = bootstr;
                *arg++ = 0;
 #ifndef DEBUG
+               (void)unlink(_PATH_NOLOGIN);
                (void)execve(path, __UNCONST(args), NULL);
                serrno = errno;
                syslog(LOG_ERR, "Can't exec `%s' (%m)", path);

Home | Main Index | Thread Index | Old Index