Comment 8 for bug 687535

Revision history for this message
Clint Byrum (clint-fewbar) wrote :

In looking at the code in OpenSSH, the -D flag only affects this portion of sshd.c, around line 1740:

    /*
     * If not in debugging mode, and not started from inetd, disconnect
     * from the controlling terminal, and fork. The original process
     * exits.
     */
    if (!(debug_flag || inetd_flag || no_daemon_flag)) {
#ifdef TIOCNOTTY
        int fd;
#endif /* TIOCNOTTY */
        if (daemon(0, 0) < 0)
            fatal("daemon() failed: %.200s", strerror(errno));

        /* Disconnect from the controlling tty. */
#ifdef TIOCNOTTY
        fd = open(_PATH_TTY, O_RDWR | O_NOCTTY);
        if (fd >= 0) {
            (void) ioctl(fd, TIOCNOTTY, NULL);
            close(fd);
        }
#endif /* TIOCNOTTY */
    }

"no_daemon_flag" isn't used anywhere else in the code.

Consequently, this code is why the daemon forks on reload, because it re-execs itself, causing this code to be hit. When run with -D, there's no call to daemon.

The call to daemon should only chdir to / and close stdin/stdout/stderr, redirecting them to /dev/null. Given that upstart will already have done that, this is a non issue. The code then ioctl's on stdin to get rid of the controlling TTY, which also has no effect when run via upstart since it is connected to /dev/null. I believe this would change the behavior if we were using console owner, and sshd would exit on control-C in console if one was using that, but we're not going to do that, nor would be a reason to do that for sshd.

I tested this on natty and maverick, killing the daemon in various ways, making sure that user sessions stay alive, and that reloads keep track of the daemon. I'm confident that this change is safe and will not cause any operational issues with openssh-server.

I've submitted a merge proposal adding -D and dropping expect fork, which would fix this bug.