Web lists-archives.com

Summary(openssh: privilege separation NO longer supported on Cygwin)


Hi Larry, Marco, ...

On May 26/27 I reported that my sshd daemon worked flawlessly on W7 ... Read here:

 - https://cygwin.com/ml/cygwin/2017-05/msg00441.html
    = Installing sshd on W7 reveals errors in CSIH_SCRIPT
    = Date: Fri, 26 May 2017 21:35:32 +0200
 - https://cygwin.com/ml/cygwin/2017-05/msg00456.html
    = Re: Installing sshd on W7 reveals errors in CSIH_SCRIPT -- patch file against master
    = Date: Sat, 27 May 2017 23:23:57 +0200

My sshd daemon worked/works with and without "files" (/etc/{passwd,group}) ...

Whether one uses "files" or not, is completely irrelevant from a logical point
of view (with one exception. More later).

Do not call using "files" an additional "layer"; it only provides "cosmetics".

On May 29 I expressed surprise about 2 things ... Read here:

 - https://cygwin.com/ml/cygwin/2017-05/msg00463.html
    = openssh: privilege separation no longer supported on Cygwin?
    = Date: Mon, 29 May 2017 07:23:09 +0200
 - https://cygwin.com/ml/cygwin/2017-05/msg00468.html
    = Re: openssh: privilege separation no longer supported on Cygwin?
    = Date: Mon, 29 May 2017 11:48:30 +0200

I expressed surprise about:

 1. getting an ELEVATED shell after executing ssh from an UNelevated shell of
    which the user is privileged (i.e. the starting shell is NOT elevated)
 2. cyg_server being the user of the grandchild of the listener process (i.e.
    the child of sshd monitor process), and not being user sshd

Now Cygwin has never supported privilege separation completely; it supported
only the pre-authentication stage. That is, in the pre-authentication stage the
child of the monitor process shpuld be UNprivileged one (run by user sshd).

I replied to my FIRST question myself ... Read here:

 - https://cygwin.com/ml/cygwin/2017-05/msg00476.html
    = Re: openssh: privilege separation no longer supported on Cygwin? SURPRISE!
    = Date: Mon, 29 May 2017 19:14:30 +0200

The elevated shell is by design (Corinna implemented it that way!).

Consequently, I was only left with the second question ...

A long time ago, Cygwin did support privilege separation during the stage of
the process in which the user STILL had to authenticate himself/herself.
(the pre-authentication stage)

You can read about it here:

 - https://cygwin.com/ml/cygwin-announce/2002-06/msg00018.html
    = Updated: OpenSSH-3.3p1-2
    = Date: Tue, 25 Jun 2002 19:46:55 +0200

As a last resort I downloaded the source code from a Cygwin mirror. It appears
that Corinna uses the stock "portable version of openssh".

Corinna did not modify the stack version ...

Studying the source code (sshd.c), it became clear to me, that user cyg_server
had to present itself with "zero" (0) to the executable.

static void
        /* Demote the child */
        if (getuid() == 0 || geteuid() == 0) {

     Do you remember this thread on the mailing list?
      - https://cygwin.com/ml/cygwin/2014-07/msg00274.html
       = The eternal uid issue
       = Date: Wed, 23 Jul 2014 10:06:04 +0200

After I had set the uid to "0" in /etc/passwd for user cyg_server, the debug
output of sshd started to show simularity with the one on Linux. Furthermore,
the ps command showed sshd as the user of the grandchild.

However Windows still thinks cyg_server is the user of that process. That is,
privilege separation is _no_longer_supported by Cygwin.

Neither in the pre-authentication stage nor in the post-authentication stage.

(yes, a lot has changed since v3.3p of openssh)




Returning to my remark about the use of /etc/{passwd,group}.

At the start of the program (sshd), it checks whether or not user sshd exist; it
will fail if it does not (i.e if one does not use "files").

However, user sshd is not required to exist if privilege separation is NOT used.

The program works flawlessly as long as /etc/passwd lists user sshd ...

main(int argc, char argv[]) // well, actually it reads: main(int ac, char **av)
        /* Store privilege separation user for later use if required. */
        if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) {
                if (use_privsep || options.kerberos_authentication)
                        fatal("Privilege separation user %s does not exist",


Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple