[PATCH] contrip/cygwin: Reworking the installation support

Corinna Vinschen vinschen at redhat.com
Thu Nov 6 03:15:48 EST 2003


Hi,

the below patch to contrib/cygwin is a major rework to allow various
changes in the installation process on Cygwin machines.  The important
changes are:

- New Makefile, providing a `cygwin-postinstall' target which allows
  to create a base installation as in the Cygwin distribution, which
  should be run right after a `make install'.

- Additional information given in the README file, reworking some old
  information which wasn't accurate anymore.

- Changing ssh-user-config to create file and directory permissions
  as correct as possible, also under Windows 2003 Server.

- ssh-host-config:

  - Supporting the changes in Windows 2003 Server, which basically
    requires to create a new privileged account.  The description
    *why* that's necessary is given in the script itself and in the
    README and is too boring to explain it in this mailing list ;-)

  - Try hard to create file and directory permissions and ownership
    as correct as possible.

  - Add two new command line options to allow full automated host
    configuration.

  - Don't create /etc/ssh_config and /etc/sshd_config from here scripts
    which are part of the ssh-host-config scipt itself, but instead
    create them from skeleton files, stored in /etc/defaults/etc.

  - Requires /bin/bash now instead of /bin/sh.  This allows reading
    user input with readline support.

  - Removing an old configuration from /usr/local is removed from the
    script.  This old style installation would be very old and should
    have gone already long ago.

Well... I think that's it, basically.  It would be nice if these
changes could be applied to the contrib/cygwin directory.  The new
Makefile is given as diff against /dev/null, I hope that's ok.

Thanks in advance,
Corinna


--- /dev/null	2003-11-05 17:11:29.944000000 +0100
+++ Makefile	2003-10-30 15:15:07.277580000 +0100
@@ -0,0 +1,56 @@
+srcdir=../..
+prefix=/usr
+exec_prefix=$(prefix)
+bindir=$(prefix)/bin
+datadir=$(prefix)/share
+docdir=$(datadir)/doc
+sshdocdir=$(docdir)/openssh
+cygdocdir=$(docdir)/Cygwin
+sysconfdir=/etc
+defaultsdir=$(sysconfdir)/defaults/etc
+PRIVSEP_PATH=/var/empty
+INSTALL=/usr/bin/install -c
+
+DESTDIR=
+
+all:
+	@echo
+	@echo "Use \`make cygwin-postinstall DESTDIR=[package directory]'"
+	@echo "Be sure having DESTDIR set correctly!"
+	@echo
+
+move-config-files: $(DESTDIR)$(sysconfdir)/ssh_config $(DESTDIR)$(sysconfdir)/sshd_config
+	$(srcdir)/mkinstalldirs $(DESTDIR)$(defaultsdir)
+	mv $(DESTDIR)$(sysconfdir)/ssh_config $(DESTDIR)$(defaultsdir)
+	mv $(DESTDIR)$(sysconfdir)/sshd_config $(DESTDIR)$(defaultsdir)
+
+remove-empty-dir:
+	rm -rf $(DESTDIR)$(PRIVSEP_PATH)
+
+install-sshdoc:
+	$(srcdir)/mkinstalldirs $(DESTDIR)$(sshdocdir)
+	$(INSTALL) -m 644 $(srcdir)/CREDITS $(DESTDIR)$(sshdocdir)/CREDITS
+	$(INSTALL) -m 644 $(srcdir)/ChangeLog $(DESTDIR)$(sshdocdir)/ChangeLog
+	$(INSTALL) -m 644 $(srcdir)/LICENCE $(DESTDIR)$(sshdocdir)/LICENCE
+	$(INSTALL) -m 644 $(srcdir)/OVERVIEW $(DESTDIR)$(sshdocdir)/OVERVIEW
+	$(INSTALL) -m 644 $(srcdir)/README $(DESTDIR)$(sshdocdir)/README
+	$(INSTALL) -m 644 $(srcdir)/README.dns $(DESTDIR)$(sshdocdir)/README.dns
+	$(INSTALL) -m 644 $(srcdir)/README.privsep $(DESTDIR)$(sshdocdir)/README.privsep
+	$(INSTALL) -m 644 $(srcdir)/README.smartcard $(DESTDIR)$(sshdocdir)/README.smartcard
+	$(INSTALL) -m 644 $(srcdir)/RFC.nroff $(DESTDIR)$(sshdocdir)/RFC.nroff
+	$(INSTALL) -m 644 $(srcdir)/TODO $(DESTDIR)$(sshdocdir)/TODO
+	$(INSTALL) -m 644 $(srcdir)/WARNING.RNG $(DESTDIR)$(sshdocdir)/WARNING.RNG
+
+install-cygwindoc: README
+	$(srcdir)/mkinstalldirs $(DESTDIR)$(cygdocdir)
+	$(INSTALL) -m 644 README $(DESTDIR)$(cygdocdir)/openssh.README
+
+install-doc: install-sshdoc install-cygwindoc
+
+install-scripts: ssh-host-config ssh-user-config
+	$(srcdir)/mkinstalldirs $(DESTDIR)$(bindir)
+	$(INSTALL) -m 755 ssh-host-config $(DESTDIR)$(bindir)/ssh-host-config
+	$(INSTALL) -m 755 ssh-user-config $(DESTDIR)$(bindir)/ssh-user-config
+
+cygwin-postinstall: move-config-files remove-empty-dir install-doc install-scripts
+	@echo "Cygwin specific configuration finished."
Index: README
===================================================================
RCS file: /cvs/openssh_cvs/contrib/cygwin/README,v
retrieving revision 1.11
diff -p -u -r1.11 README
--- README	22 Sep 2003 02:32:00 -0000	1.11
+++ README	5 Nov 2003 16:11:37 -0000
@@ -1,4 +1,49 @@
-This package is the actual port of OpenSSH to Cygwin 1.5.
+This package describes important Cygwin specific stuff concerning OpenSSH.
+
+The binary package is usually built for recent Cygwin versions and might
+not run on older versions.  Please check http://cygwin.com/ for information
+about current Cygwin releases.
+
+Build instructions are at the end of the file.
+
+===========================================================================
+Important change since 3.7.1p2-2:
+
+The ssh-host-config file doesn't create the /etc/ssh_config and
+/etc/sshd_config files from builtin here-scripts anymore, but it uses
+skeleton files installed in /etc/defaults/etc.
+
+Also it now tries hard to create appropriate permissions on files.
+Same applies for ssh-user-config.
+
+After creating the sshd service with ssh-host-config, it's advisable to
+call ssh-user-config for all affected users, also already exising user
+configurations.  In the latter case, file and directory permissions are
+checked and changed, if requireed to match the host configuration.
+
+Important note for Windows 2003 Server users:
+---------------------------------------------
+
+2003 Server has a funny new feature.  When starting services under SYSTEM
+account, these services have nearly all user rights which SYSTEM holds... 
+except for the "Create a token object" right, which is needed to allow
+public key authentication :-(
+
+There's no way around this, except for creating a substitute account which
+has the appropriate privileges.  Basically, this account should be member
+of the administrators group, plus it should have the following user rights:
+
+	Create a token object
+	Logon as a service
+	Replace a process level token
+	Increase Quota
+
+The ssh-host-config script asks you, if it should create such an account,
+called "sshd_server".  If you say "no" here, you're on your own.  Please
+follow the instruction in ssh-host-config exactly if possible.  Note that
+ssh-user-config sets the permissions on 2003 Server machines dependent of
+whether a sshd_server account exists or not.
+===========================================================================
 
 ===========================================================================
 Important change since 3.4p1-2:
@@ -114,54 +159,6 @@ ${SYSTEMROOT}/system32/drivers/etc/servi
 
    ssh         22/tcp          #SSH daemon
 
-===========================================================================
-The following restrictions only apply to Cygwin versions up to 1.3.1
-===========================================================================
-
-Authentication to sshd is possible in one of two ways.
-You'll have to decide before starting sshd!
-
-- If you want to authenticate via RSA and you want to login to that
-  machine to exactly one user account you can do so by running sshd
-  under that user account. You must change /etc/sshd_config
-  to contain the following:
-
-  RSAAuthentication yes
-
-  Moreover it's possible to use rhosts and/or rhosts with
-  RSA authentication by setting the following in sshd_config:
-
-  RhostsAuthentication yes
-  RhostsRSAAuthentication yes
-
-- If you want to be able to login to different user accounts you'll
-  have to start sshd under system account or any other account that
-  is able to switch user context. Note that administrators are _not_
-  able to do that by default! You'll have to give the following
-  special user rights to the user:
-  "Act as part of the operating system"
-  "Replace process level token"
-  "Increase quotas"
-  and if used via service manager
-  "Logon as a service".
-
-  The system account does of course own that user rights by default.
-
-  Unfortunately, if you choose that way, you can only logon with
-  NT password authentification and you should change
-  /etc/sshd_config to contain the following:
-
-    PasswordAuthentication yes
-    RhostsAuthentication no
-    RhostsRSAAuthentication no
-    RSAAuthentication no
-
-  However you can login to the user which has started sshd with
-  RSA authentication anyway. If you want that, change the RSA
-  authentication setting back to "yes":
-     
-    RSAAuthentication yes
-
 Please note that OpenSSH does never use the value of $HOME to
 search for the users configuration files! It always uses the
 value of the pw_dir field in /etc/passwd as the home directory.
@@ -169,7 +166,7 @@ If no home diretory is set in /etc/passw
 is used instead!
 
 You may use all features of the CYGWIN=ntsec setting the same
-way as they are used by the `login' port on sources.redhat.com:
+way as they are used by Cygwin's login(1) port:
 
   The pw_gecos field may contain an additional field, that begins
   with (upper case!) "U-", followed by the domain and the username
@@ -186,6 +183,8 @@ way as they are used by the `login' port
 
     locuser::1104:513:John Doe,U-user,S-1-5-21-...
 
+Note that the CYGWIN=ntsec setting is required for public key authentication.
+
 SSH2 server and user keys are generated by the `ssh-*-config' scripts
 as well.
 
@@ -194,15 +193,30 @@ configure are used for the Cygwin binary
 
 	--prefix=/usr \
 	--sysconfdir=/etc \
-	--libexecdir='${exec_prefix}/sbin'
-
-You must have installed the zlib and openssl packages to be able to
+	--libexecdir='$(sbindir)' \
+	--localstatedir=/var \
+	--datadir='$(prefix)/share' \
+	--mandir='$(datadir)/man' \
+	--with-tcp-wrappers
+
+If you want to create a Cygwin package, equivalent to the one
+in the Cygwin binary distribution, install like this:
+
+	mkdir /tmp/cygwin-ssh
+	cd $(builddir)
+	make install DESTDIR=/tmp/cygwin-ssh
+	cd $(srcdir)/contrib/cygwin
+	make cygwin-postinstall DESTDIR=/tmp/cygwin-ssh
+	cd /tmp/cygwin-ssh
+	find * \! -type d | tar cvjfT my-openssh.tar.bz2 -
+	
+You must have installed the zlib and openssl-devel packages to be able to
 build OpenSSH!
 
 Please send requests, error reports etc. to cygwin at cygwin.com.
 
 Have fun,
 
-Corinna Vinschen <vinschen at redhat.com>
+Corinna Vinschen
 Cygwin Developer
 Red Hat Inc.
Index: ssh-host-config
===================================================================
RCS file: /cvs/openssh_cvs/contrib/cygwin/ssh-host-config,v
retrieving revision 1.12
diff -p -u -r1.12 ssh-host-config
--- ssh-host-config	3 Nov 2003 07:59:29 -0000	1.12
+++ ssh-host-config	5 Nov 2003 16:11:37 -0000
@@ -1,6 +1,6 @@
-#!/bin/sh
+#!/bin/bash
 #
-# ssh-host-config, Copyright 2000, Red Hat Inc.
+# ssh-host-config, Copyright 2000, 2001, 2002, 2003 Red Hat Inc.
 #
 # This file is part of the Cygwin port of OpenSSH.
 
@@ -9,10 +9,7 @@ PREFIX=/usr
 
 # Directory where the config files are stored
 SYSCONFDIR=/etc
-
-# Subdirectory where an old package might be installed
-OLDPREFIX=/usr/local
-OLDSYSCONFDIR=${OLDPREFIX}/etc
+LOCALSTATEDIR=/var
 
 progname=$0
 auto_answer=""
@@ -27,9 +24,11 @@ request()
 {
   if [ "${auto_answer}" = "yes" ]
   then
+    echo "$1 (yes/no) yes"
     return 0
   elif [ "${auto_answer}" = "no" ]
   then
+    echo "$1 (yes/no) no"
     return 1
   fi
 
@@ -37,7 +36,7 @@ request()
   while [ "X${answer}" != "Xyes" -a "X${answer}" != "Xno" ]
   do
     echo -n "$1 (yes/no) "
-    read answer
+    read -e answer
   done
   if [ "X${answer}" = "Xyes" ]
   then
@@ -60,7 +59,7 @@ do
   option=$1
   shift
 
-  case "$option" in
+  case "${option}" in
   -d | --debug )
     set -x
     ;;
@@ -73,21 +72,33 @@ do
     auto_answer=no
     ;;
 
+  -c | --cygwin )
+    cygwin_value="$1"
+    shift
+    ;;
+
   -p | --port )
     port_number=$1
     shift
     ;;
 
+  -w | --pwd )
+    password_value="$1"
+    shift
+    ;;
+
   *)
     echo "usage: ${progname} [OPTION]..."
     echo
     echo "This script creates an OpenSSH host configuration."
     echo
     echo "Options:"
-    echo "    --debug  -d     Enable shell's debug output."
-    echo "    --yes    -y     Answer all questions with \"yes\" automatically."
-    echo "    --no     -n     Answer all questions with \"no\" automatically."
-    echo "    --port   -p <n> sshd listens on port n."
+    echo "  --debug  -d            Enable shell's debug output."
+    echo "  --yes    -y            Answer all questions with \"yes\" automatically."
+    echo "  --no     -n            Answer all questions with \"no\" automatically."
+    echo "  --cygwin -c <options>  Use \"options\" as value for CYGWIN environment var."
+    echo "  --port   -p <n>        sshd listens on port n."
+    echo "  --pwd    -w <passwd>   Use \"pwd\" as password for user 'sshd_server'."
     echo
     exit 1
     ;;
@@ -96,8 +107,13 @@ do
 done
 
 # Check if running on NT
-_sys="`uname -a`"
-_nt=`expr "$_sys" : "CYGWIN_NT"`
+_sys="`uname`"
+_nt=`expr "${_sys}" : "CYGWIN_NT"`
+# If running on NT, check if running under 2003 Server or later
+if [ ${_nt} -gt 0 ]
+then
+  _nt2003=`uname | awk -F- '{print ( $2 >= 5.2 ) ? 1 : 0;}'`
+fi
 
 # Check for running ssh/sshd processes first. Refuse to do anything while
 # some ssh processes are still running
@@ -137,87 +153,33 @@ fi
 
 # Create /var/log and /var/log/lastlog if not already existing
 
-if [ -f /var/log ]
+if [ -f ${LOCALSTATEDIR}/log ]
 then
-  echo "Creating /var/log failed\!"
+  echo "Creating ${LOCALSTATEDIR}/log failed!"
 else
-  if [ ! -d /var/log ]
+  if [ ! -d ${LOCALSTATEDIR}/log ]
   then
-    mkdir -p /var/log
+    mkdir -p ${LOCALSTATEDIR}/log
   fi
-  if [ -d /var/log/lastlog ]
+  if [ -d ${LOCALSTATEDIR}/log/lastlog ]
   then
-    echo "Creating /var/log/lastlog failed\!"
-  elif [ ! -f /var/log/lastlog ]
+    chmod 777 ${LOCALSTATEDIR}/log/lastlog
+  elif [ ! -f ${LOCALSTATEDIR}/log/lastlog ]
   then
-    cat /dev/null > /var/log/lastlog
+    cat /dev/null > ${LOCALSTATEDIR}/log/lastlog
+    chmod 666 ${LOCALSTATEDIR}/log/lastlog
   fi
 fi
 
 # Create /var/empty file used as chroot jail for privilege separation
-if [ -f /var/empty ]
+if [ -f ${LOCALSTATEDIR}/empty ]
 then
-  echo "Creating /var/empty failed\!"
+  echo "Creating ${LOCALSTATEDIR}/empty failed!"
 else
-  mkdir -p /var/empty
-  # On NT change ownership of that dir to user "system"
-  if [ $_nt -gt 0 ]
+  mkdir -p ${LOCALSTATEDIR}/empty
+  if [ ${_nt} -gt 0 ]
   then
-    chmod 755 /var/empty
-    chown system.system /var/empty
-  fi
-fi
-
-# Check for an old installation in ${OLDPREFIX} unless ${OLDPREFIX} isn't
-# the same as ${PREFIX}
-
-old_install=0
-if [ "${OLDPREFIX}" != "${PREFIX}" ]
-then
-  if [ -f "${OLDPREFIX}/sbin/sshd" ]
-  then
-    echo
-    echo "You seem to have an older installation in ${OLDPREFIX}."
-    echo
-    # Check if old global configuration files exist
-    if [ -f "${OLDSYSCONFDIR}/ssh_host_key" ]
-    then
-      if request "Do you want to copy your config files to your new installation?"
-      then
-        cp -f ${OLDSYSCONFDIR}/ssh_host_key ${SYSCONFDIR}
-        cp -f ${OLDSYSCONFDIR}/ssh_host_key.pub ${SYSCONFDIR}
-        cp -f ${OLDSYSCONFDIR}/ssh_host_dsa_key ${SYSCONFDIR}
-        cp -f ${OLDSYSCONFDIR}/ssh_host_dsa_key.pub ${SYSCONFDIR}
-        cp -f ${OLDSYSCONFDIR}/ssh_config ${SYSCONFDIR}
-        cp -f ${OLDSYSCONFDIR}/sshd_config ${SYSCONFDIR}
-      fi
-    fi
-    if request "Do you want to erase your old installation?"
-    then
-      rm -f ${OLDPREFIX}/bin/ssh.exe
-      rm -f ${OLDPREFIX}/bin/ssh-config
-      rm -f ${OLDPREFIX}/bin/scp.exe
-      rm -f ${OLDPREFIX}/bin/ssh-add.exe
-      rm -f ${OLDPREFIX}/bin/ssh-agent.exe
-      rm -f ${OLDPREFIX}/bin/ssh-keygen.exe
-      rm -f ${OLDPREFIX}/bin/slogin
-      rm -f ${OLDSYSCONFDIR}/ssh_host_key
-      rm -f ${OLDSYSCONFDIR}/ssh_host_key.pub
-      rm -f ${OLDSYSCONFDIR}/ssh_host_dsa_key
-      rm -f ${OLDSYSCONFDIR}/ssh_host_dsa_key.pub
-      rm -f ${OLDSYSCONFDIR}/ssh_config
-      rm -f ${OLDSYSCONFDIR}/sshd_config
-      rm -f ${OLDPREFIX}/man/man1/ssh.1
-      rm -f ${OLDPREFIX}/man/man1/scp.1
-      rm -f ${OLDPREFIX}/man/man1/ssh-add.1
-      rm -f ${OLDPREFIX}/man/man1/ssh-agent.1
-      rm -f ${OLDPREFIX}/man/man1/ssh-keygen.1
-      rm -f ${OLDPREFIX}/man/man1/slogin.1
-      rm -f ${OLDPREFIX}/man/man8/sshd.8
-      rm -f ${OLDPREFIX}/sbin/sshd.exe
-      rm -f ${OLDPREFIX}/sbin/sftp-server.exe
-    fi
-    old_install=1
+    chmod 755 ${LOCALSTATEDIR}/empty
   fi
 fi
 
@@ -255,52 +217,16 @@ then
   fi
 fi
 
-# Create default ssh_config from here script
+# Create default ssh_config from skeleton file in /etc/defaults/etc
 
 if [ ! -f "${SYSCONFDIR}/ssh_config" ]
 then
   echo "Generating ${SYSCONFDIR}/ssh_config file"
-  cat > ${SYSCONFDIR}/ssh_config << EOF
-# This is the ssh client system-wide configuration file.  See
-# ssh_config(5) for more information.  This file provides defaults for
-# users, and the values can be changed in per-user configuration files
-# or on the command line.
-
-# Configuration data is parsed as follows:
-#  1. command line options
-#  2. user-specific file
-#  3. system-wide file
-# Any configuration value is only changed the first time it is set.
-# Thus, host-specific definitions should be at the beginning of the
-# configuration file, and defaults at the end.
-
-# Site-wide defaults for various options
-
-# Host *
-#   ForwardAgent no
-#   ForwardX11 no
-#   RhostsRSAAuthentication no
-#   RSAAuthentication yes
-#   PasswordAuthentication yes
-#   HostbasedAuthentication no
-#   BatchMode no
-#   CheckHostIP yes
-#   AddressFamily any
-#   ConnectTimeout 0
-#   StrictHostKeyChecking ask
-#   IdentityFile ~/.ssh/identity
-#   IdentityFile ~/.ssh/id_dsa
-#   IdentityFile ~/.ssh/id_rsa
-#   Port 22
-#   Protocol 2,1
-#   Cipher 3des
-#   Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc
-#   EscapeChar ~
-EOF
-  if [ "$port_number" != "22" ]
+  cp ${SYSCONFDIR}/defaults/etc/ssh_config ${SYSCONFDIR}/ssh_config
+  if [ "${port_number}" != "22" ]
   then
     echo "Host localhost" >> ${SYSCONFDIR}/ssh_config
-    echo "    Port $port_number" >> ${SYSCONFDIR}/ssh_config
+    echo "    Port ${port_number}" >> ${SYSCONFDIR}/ssh_config
   fi
 fi
 
@@ -322,35 +248,35 @@ fi
 
 # Prior to creating or modifying sshd_config, care for privilege separation
 
-if [ "$privsep_configured" != "yes" ]
+if [ "${privsep_configured}" != "yes" ]
 then
-  if [ $_nt -gt 0 ]
+  if [ ${_nt} -gt 0 ]
   then
     echo "Privilege separation is set to yes by default since OpenSSH 3.3."
     echo "However, this requires a non-privileged account called 'sshd'."
-    echo "For more info on privilege separation read /usr/doc/openssh/README.privsep."
+    echo "For more info on privilege separation read /usr/share/doc/openssh/README.privsep."
     echo
-    if request "Shall privilege separation be used?"
+    if request "Should privilege separation be used?"
     then
       privsep_used=yes
       grep -q '^sshd:' ${SYSCONFDIR}/passwd && sshd_in_passwd=yes
       net user sshd >/dev/null 2>&1 && sshd_in_sam=yes
-      if [ "$sshd_in_passwd" != "yes" ]
+      if [ "${sshd_in_passwd}" != "yes" ]
       then
-        if [ "$sshd_in_sam" != "yes" ]
+        if [ "${sshd_in_sam}" != "yes" ]
 	then
 	  echo "Warning: The following function requires administrator privileges!"
-	  if request "Shall this script create a local user 'sshd' on this machine?"
+	  if request "Should this script create a local user 'sshd' on this machine?"
 	  then
-	    dos_var_empty=`cygpath -w /var/empty`
-	    net user sshd /add /fullname:"sshd privsep" "/homedir:$dos_var_empty" /active:no > /dev/null 2>&1 && sshd_in_sam=yes
-	    if [ "$sshd_in_sam" != "yes" ]
+	    dos_var_empty=`cygpath -w ${LOCALSTATEDIR}/empty`
+	    net user sshd /add /fullname:"sshd privsep" "/homedir:${dos_var_empty}" /active:no > /dev/null 2>&1 && sshd_in_sam=yes
+	    if [ "${sshd_in_sam}" != "yes" ]
 	    then
 	      echo "Warning: Creating the user 'sshd' failed!"
 	    fi
 	  fi
 	fi
-	if [ "$sshd_in_sam" != "yes" ]
+	if [ "${sshd_in_sam}" != "yes" ]
 	then
 	  echo "Warning: Can't create user 'sshd' in ${SYSCONFDIR}/passwd!"
 	  echo "         Privilege separation set to 'no' again!"
@@ -365,117 +291,41 @@ then
     fi
   else
     # On 9x don't use privilege separation.  Since security isn't
-    # available it just adds useless addtional processes.
+    # available it just adds useless additional processes.
     privsep_used=no
   fi
 fi
 
-# Create default sshd_config from here script or modify to add the
-# missing privsep configuration option
+# Create default sshd_config from skeleton files in /etc/defaults/etc or
+# modify to add the missing privsep configuration option
 
 if [ ! -f "${SYSCONFDIR}/sshd_config" ]
 then
   echo "Generating ${SYSCONFDIR}/sshd_config file"
-  cat > ${SYSCONFDIR}/sshd_config << EOF
-# This is the sshd server system-wide configuration file.  See
-# sshd_config(5) for more information.
-
-# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin
-
-# The strategy used for options in the default sshd_config shipped with
-# OpenSSH is to specify options with their default value where
-# possible, but leave them commented.  Uncommented options change a
-# default value.
-
-Port $port_number
-#Protocol 2,1
-#ListenAddress 0.0.0.0
-#ListenAddress ::
-
-# HostKey for protocol version 1
-#HostKey ${SYSCONFDIR}/ssh_host_key
-# HostKeys for protocol version 2
-#HostKey ${SYSCONFDIR}/ssh_host_rsa_key
-#HostKey ${SYSCONFDIR}/ssh_host_dsa_key
-
-# Lifetime and size of ephemeral version 1 server key
-#KeyRegenerationInterval 1h
-#ServerKeyBits 768
-
-# Logging
-#obsoletes QuietMode and FascistLogging
-#SyslogFacility AUTH
-#LogLevel INFO
-
-# Authentication:
-
-#LoginGraceTime 2m
-#PermitRootLogin yes
-# The following setting overrides permission checks on host key files
-# and directories. For security reasons set this to "yes" when running
-# NT/W2K, NTFS and CYGWIN=ntsec.
-StrictModes no
-
-#RSAAuthentication yes
-#PubkeyAuthentication yes
-#AuthorizedKeysFile     .ssh/authorized_keys
-
-# For this to work you will also need host keys in ${SYSCONFDIR}/ssh_known_hosts
-#RhostsRSAAuthentication no
-# similar for protocol version 2
-#HostbasedAuthentication no
-# Change to yes if you don't trust ~/.ssh/known_hosts for
-# RhostsRSAAuthentication and HostbasedAuthentication
-#IgnoreUserKnownHosts no
-# Don't read the user's ~/.rhosts and ~/.shosts files
-#IgnoreRhosts yes
-
-# To disable tunneled clear text passwords, change to no here!
-#PasswordAuthentication yes
-#PermitEmptyPasswords no
-
-# Change to no to disable s/key passwords
-#ChallengeResponseAuthentication yes
-
-#AllowTcpForwarding yes
-#GatewayPorts no
-#X11Forwarding no
-#X11DisplayOffset 10
-#X11UseLocalhost yes
-#PrintMotd yes
-#PrintLastLog yes
-#KeepAlive yes
-#UseLogin no
-UsePrivilegeSeparation $privsep_used
-#PermitUserEnvironment no
-#Compression yes
-#ClientAliveInterval 0
-#ClientAliveCountMax 3
-#UseDNS yes
-#PidFile /var/run/sshd.pid
-#MaxStartups 10
-
-# no default banner path
-#Banner /some/path
-
-# override default of no subsystems
-Subsystem      sftp    /usr/sbin/sftp-server
-EOF
-elif [ "$privsep_configured" != "yes" ]
+  sed -e "s/^#UsePrivilegeSeparation yes/UsePrivilegeSeparation ${privsep_used}/
+	  s/^#Port 22/Port ${port_number}/
+	  s/^#StrictModes yes/StrictModes no/" \
+      < ${SYSCONFDIR}/defaults/etc/sshd_config \
+      > ${SYSCONFDIR}/sshd_config
+elif [ "${privsep_configured}" != "yes" ]
 then
   echo >> ${SYSCONFDIR}/sshd_config
-  echo "UsePrivilegeSeparation $privsep_used" >> ${SYSCONFDIR}/sshd_config
+  echo "UsePrivilegeSeparation ${privsep_used}" >> ${SYSCONFDIR}/sshd_config
 fi
 
 # Care for services file
 _my_etcdir="/ssh-host-config.$$"
-if [ $_nt -gt 0 ]
+if [ ${_nt} -gt 0 ]
 then
   _win_etcdir="${SYSTEMROOT}\\system32\\drivers\\etc"
   _services="${_my_etcdir}/services"
+  # On NT, 27 spaces, no space after the hash
+  _spaces="                           #"
 else
   _win_etcdir="${WINDIR}"
   _services="${_my_etcdir}/SERVICES"
+  # On 9x, 18 spaces (95 is very touchy), a space after the hash
+  _spaces="                  # "
 fi
 _serv_tmp="${_my_etcdir}/srv.out.$$"
 
@@ -494,29 +344,28 @@ then
     then
       echo "Removing sshd from ${_wservices}"
     else
-      echo "Removing sshd from ${_wservices} failed\!"
+      echo "Removing sshd from ${_wservices} failed!"
     fi 
     rm -f "${_serv_tmp}"
   else
-    echo "Removing sshd from ${_wservices} failed\!"
+    echo "Removing sshd from ${_wservices} failed!"
   fi
 fi
 
 # Add ssh 22/tcp  and ssh 22/udp to services
 if [ `grep -q 'ssh[ \t][ \t]*22' "${_services}"; echo $?` -ne 0 ]
 then
-  awk '{ if ( $2 ~ /^23\/tcp/ ) print "ssh                22/tcp                           #SSH Remote Login Protocol\nssh                22/udp                           #SSH Remote Login Protocol"; print $0; }' < "${_services}" > "${_serv_tmp}"
-  if [ -f "${_serv_tmp}" ]
+  if awk '{ if ( $2 ~ /^23\/tcp/ ) print "ssh                22/tcp'"${_spaces}"'SSH Remote Login Protocol\nssh                22/udp'"${_spaces}"'SSH Remote Login Protocol"; print $0; }' < "${_services}" > "${_serv_tmp}"
   then
     if mv "${_serv_tmp}" "${_services}"
     then
       echo "Added ssh to ${_wservices}"
     else
-      echo "Adding ssh to ${_wservices} failed\!"
+      echo "Adding ssh to ${_wservices} failed!"
     fi
     rm -f "${_serv_tmp}"
   else
-    echo "Adding ssh to ${_wservices} failed\!"
+    echo "WARNING: Adding ssh to ${_wservices} failed!"
   fi
 fi
 
@@ -541,11 +390,11 @@ then
       then
         echo "Removed sshd from ${_inetcnf}"
       else
-        echo "Removing sshd from ${_inetcnf} failed\!"
+        echo "Removing sshd from ${_inetcnf} failed!"
       fi
       rm -f "${_inetcnf_tmp}"
     else
-      echo "Removing sshd from ${_inetcnf} failed\!"
+      echo "Removing sshd from ${_inetcnf} failed!"
     fi
   fi
 
@@ -563,33 +412,180 @@ then
 fi
 
 # On NT ask if sshd should be installed as service
-if [ $_nt -gt 0 ]
+if [ ${_nt} -gt 0 ]
 then
-  echo
-  echo "Do you want to install sshd as service?"
-  if request "(Say \"no\" if it's already installed as service)"
+  # But only if it is not already installed
+  if ! cygrunsrv -Q sshd > /dev/null 2>&1
   then
     echo
-    echo "Which value should the environment variable CYGWIN have when"
-    echo "sshd starts? It's recommended to set at least \"ntsec\" to be"
-    echo "able to change user context without password."
-    echo -n "Default is \"binmode ntsec tty\".  CYGWIN="
-    read _cygwin
-    [ -z "${_cygwin}" ] && _cygwin="binmode ntsec tty"
-    if cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd -a -D -e "CYGWIN=${_cygwin}"
+    echo
+    echo "Warning: The following functions require administrator privileges!"
+    echo
+    echo "Do you want to install sshd as service?"
+    if request "(Say \"no\" if it's already installed as service)"
     then
-      chown system ${SYSCONFDIR}/ssh*
-      echo
-      echo "The service has been installed under LocalSystem account."
+      if [ $_nt2003 -gt 0 ]
+      then
+	grep -q '^sshd_server:' ${SYSCONFDIR}/passwd && sshd_server_in_passwd=yes
+	if [ "${sshd_server_in_passwd}" = "yes" ]
+	then
+	  # Drop sshd_server from passwd since it could have wrong settings
+	  grep -v '^sshd_server:' ${SYSCONFDIR}/passwd > ${SYSCONFDIR}/passwd.$$
+	  rm -f ${SYSCONFDIR}/passwd
+	  mv ${SYSCONFDIR}/passwd.$$ ${SYSCONFDIR}/passwd
+	  chmod g-w,o-w ${SYSCONFDIR}/passwd
+	fi
+	net user sshd_server >/dev/null 2>&1 && sshd_server_in_sam=yes
+	if [ "${sshd_server_in_sam}" != "yes" ]
+	then
+	  echo
+	  echo "You appear to be running Windows 2003 Server or later.  On 2003 and"
+	  echo "later systems, it's not possible to use the LocalSystem account"
+	  echo "if sshd should allow passwordless logon (e. g. public key authentication)."
+	  echo "If you want to enable that functionality, it's required to create a new"
+	  echo "account 'sshd_server' with special privileges, which is then used to run"
+	  echo "the sshd service under."
+	  echo
+	  echo "Should this script create a new local account 'sshd_server' which has"
+	  if request "the required privileges?"
+	  then
+	    _admingroup=`awk -F: '{if ( $2 == "S-1-5-32-544" ) print $1;}' ${SYSCONFDIR}/group`
+	    if [ -z "${_admingroup}" ]
+	    then
+	      echo "There's no group with SID S-1-5-32-544 (Local administrators group) in"
+	      echo "your ${SYSCONFDIR}/group file.  Please regenerate this entry using 'mkgroup -l'"
+	      echo "and restart this script."
+	      exit 1
+	    fi
+	    dos_var_empty=`cygpath -w ${LOCALSTATEDIR}/empty`
+	    while [ "${sshd_server_in_sam}" != "yes" ]
+	    do
+	      if [ -n "${password_value}" ]
+	      then
+	        _password="${password_value}"
+		# Allow to ask for password if first try fails
+		password_value=""
+	      else
+		echo
+		echo "Please enter a password for new user 'sshd_server'.  Please be sure that"
+		echo "this password matches the password rules given on your system."
+		echo -n "Entering no password will exit the configuration.  PASSWORD="
+		read -e _password
+		if [ -z "${_password}" ]
+		then
+		  echo
+		  echo "Exiting configuration.  No user sshd_server has been created,"
+		  echo "no sshd service installed."
+		  exit 1
+		fi
+	      fi
+	      net user sshd_server "${_password}" /add /fullname:"sshd server account" "/homedir:${dos_var_empty}" /yes > /tmp/nu.$$ 2>&1 && sshd_server_in_sam=yes
+	      if [ "${sshd_server_in_sam}" != "yes" ]
+	      then
+		echo "Creating the user 'sshd_server' failed!  Reason:"
+		cat /tmp/nu.$$
+		rm /tmp/nu.$$
+	      fi
+	    done
+	    net localgroup "${_admingroup}" sshd_server /add > /dev/null 2>&1 && sshd_server_in_admingroup=yes
+	    if [ "${sshd_server_in_admingroup}" != "yes" ]
+	    then
+	      echo "WARNING: Adding user sshd_server to local group ${_admingroup} failed!"
+	      echo "Please add sshd_server to local group ${_admingroup} before"
+	      echo "starting the sshd service!"
+	      echo
+	    fi
+	    passwd_has_expiry_flags=`passwd -v | awk '/^passwd /{print ( $3 >= 1.5 ) ? "yes" : "no";}'`
+	    if [ "${passwd_has_expiry_flags}" != "yes" ]
+	    then
+	      echo
+	      echo "WARNING: User sshd_server has password expiry set to system default."
+	      echo "Please check that password never expires or set it to your needs."
+	    elif ! passwd -e sshd_server
+	    then
+	      echo
+	      echo "WARNING: Setting password expiry for user sshd_server failed!"
+	      echo "Please check that password never expires or set it to your needs."
+	    fi
+	    editrights -a SeAssignPrimaryTokenPrivilege -u sshd_server &&
+	    editrights -a SeCreateTokenPrivilege -u sshd_server &&
+	    editrights -a SeDenyInteractiveLogonRight -u sshd_server &&
+	    editrights -a SeDenyNetworkLogonRight -u sshd_server &&
+	    editrights -a SeDenyRemoteInteractiveLogonRight -u sshd_server &&
+	    editrights -a SeIncreaseQuotaPrivilege -u sshd_server &&
+	    editrights -a SeServiceLogonRight -u sshd_server &&
+	    sshd_server_got_all_rights="yes"
+	    if [ "${sshd_server_got_all_rights}" != "yes" ]
+	    then
+	      echo
+	      echo "Assigning the appropriate privileges to user 'sshd_server' failed!"
+	      echo "Can't create sshd service!"
+	      exit 1
+	    fi
+	    echo
+	    echo "User 'sshd_server' has been created with password '${_password}'."
+	    echo "If you change the password, please keep in mind to change the password"
+	    echo "for the sshd service, too."
+	    echo
+	    echo "Also keep in mind that the user sshd_server needs read permissions on all"
+	    echo "users' .ssh/authorized_keys file to allow public key authentication for"
+	    echo "these users!.  (Re-)running ssh-user-config for each user will set the"
+	    echo "required permissions correctly."
+	    echo
+	  fi
+	fi
+	if [ "${sshd_server_in_sam}" = "yes" ]
+	then
+	  mkpasswd -l -u sshd_server | sed -e 's/bash$/false/' >> ${SYSCONFDIR}/passwd
+	fi
+      fi
+      if [ -n "${cygwin_value}" ]
+      then
+        _cygwin="${cygwin_value}"
+      else
+	echo
+	echo "Which value should the environment variable CYGWIN have when"
+	echo "sshd starts? It's recommended to set at least \"ntsec\" to be"
+	echo "able to change user context without password."
+	echo -n "Default is \"ntsec\".  CYGWIN="
+	read -e _cygwin
+      fi
+      [ -z "${_cygwin}" ] && _cygwin="ntsec"
+      if [ $_nt2003 -gt 0 -a "${sshd_server_in_sam}" = "yes" ]
+      then
+	if cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd -a -D -u sshd_server -w "${_password}" -e "CYGWIN=${_cygwin}"
+	then
+	  echo
+	  echo "The service has been installed under sshd_server account."
+	  echo "To start the service, call \`net start sshd' or \`cygrunsrv -S sshd'."
+	fi
+      else
+	if cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd -a -D -e "CYGWIN=${_cygwin}"
+	then
+	  echo
+	  echo "The service has been installed under LocalSystem account."
+	  echo "To start the service, call \`net start sshd' or \`cygrunsrv -S sshd'."
+	fi
+      fi
+    fi
+    # Now check if sshd has been successfully installed.  This allows to
+    # set the ownership of the affected files correctly.
+    if cygrunsrv -Q sshd > /dev/null 2>&1
+    then
+      if [ $_nt2003 -gt 0 -a "${sshd_server_in_sam}" = "yes" ]
+      then
+        _user="sshd_server"
+      else
+        _user="system"
+      fi
+      chown "${_user}" ${SYSCONFDIR}/ssh*
+      chown "${_user}".544 ${LOCALSTATEDIR}/empty
+      if [ -f ${LOCALSTATEDIR}/log/sshd.log ]
+      then
+	chown "${_user}".544 ${LOCALSTATEDIR}/log/sshd.log
+      fi
     fi
   fi
-fi
-
-if [ "${old_install}" = "1" ]
-then
-  echo
-  echo "Note: If you have used sshd as service or from inetd, don't forget to"
-  echo "      change the path to sshd.exe in the service entry or in inetd.conf."
 fi
 
 echo
Index: ssh-user-config
===================================================================
RCS file: /cvs/openssh_cvs/contrib/cygwin/ssh-user-config,v
retrieving revision 1.2
diff -p -u -r1.2 ssh-user-config
--- ssh-user-config	22 Aug 2003 08:43:48 -0000	1.2
+++ ssh-user-config	5 Nov 2003 16:11:37 -0000
@@ -1,9 +1,12 @@
 #!/bin/sh
 #
-# ssh-user-config, Copyright 2000, Red Hat Inc.
+# ssh-user-config, Copyright 2000, 2001, 2002, 2003, Red Hat Inc.
 #
 # This file is part of the Cygwin port of OpenSSH.
 
+# Directory where the config files are stored
+SYSCONFDIR=/etc
+
 progname=$0
 auto_answer=""
 auto_passphrase="no"
@@ -33,6 +36,15 @@ request()
   fi
 }
 
+# Check if running on NT
+_sys="`uname -a`"
+_nt=`expr "$_sys" : "CYGWIN_NT"`
+# If running on NT, check if running under 2003 Server or later
+if [ $_nt -gt 0 ]
+then
+  _nt2003=`uname | awk -F- '{print ( $2 >= 5.2 ) ? 1 : 0;}'`
+fi
+
 # Check options
 
 while :
@@ -84,27 +96,27 @@ done
 
 # Ask user if user identity should be generated
 
-if [ ! -f /etc/passwd ]
+if [ ! -f ${SYSCONFDIR}/passwd ]
 then
-  echo '/etc/passwd is nonexistant. Please generate an /etc/passwd file'
+  echo "${SYSCONFDIR}/passwd is nonexistant. Please generate an ${SYSCONFDIR}/passwd file"
   echo 'first using mkpasswd. Check if it contains an entry for you and'
   echo 'please care for the home directory in your entry as well.'
   exit 1
 fi
 
 uid=`id -u`
-pwdhome=`awk -F: '{ if ( $3 == '${uid}' ) print $6; }' < /etc/passwd`
+pwdhome=`awk -F: '{ if ( $3 == '${uid}' ) print $6; }' < ${SYSCONFDIR}/passwd`
 
 if [ "X${pwdhome}" = "X" ]
 then
-  echo 'There is no home directory set for you in /etc/passwd.'
+  echo "There is no home directory set for you in ${SYSCONFDIR}/passwd."
   echo 'Setting $HOME is not sufficient!'
   exit 1
 fi
 
 if [ ! -d "${pwdhome}" ]
 then
-  echo "${pwdhome} is set in /etc/passwd as your home directory"
+  echo "${pwdhome} is set in ${SYSCONFDIR}/passwd as your home directory"
   echo 'but it is not a valid directory. Cannot create user identity files.'
   exit 1
 fi
@@ -114,7 +126,7 @@ fi
 if [ "X${pwdhome}" = "X/" ]
 then
   # But first raise a warning!
-  echo 'Your home directory in /etc/passwd is set to root (/). This is not recommended!'
+  echo "Your home directory in ${SYSCONFDIR}/passwd is set to root (/). This is not recommended!"
   if request "Would you like to proceed anyway?"
   then
     pwdhome=''
@@ -123,6 +135,17 @@ then
   fi
 fi
 
+if [ -d "${pwdhome}" -a $_nt -gt 0 -a -n "`chmod -c g-w,o-w "${pwdhome}"`" ]
+then
+  echo
+  echo 'WARNING: group and other have been revoked write permission to your home'
+  echo "         directory ${pwdhome}."
+  echo '         This is required by OpenSSH to allow public key authentication using'
+  echo '         the key files stored in your .ssh subdirectory.'
+  echo '         Revert this change ONLY if you know what you are doing!'
+  echo
+fi
+
 if [ -e "${pwdhome}/.ssh" -a ! -d "${pwdhome}/.ssh" ]
 then
   echo "${pwdhome}/.ssh is existant but not a directory. Cannot create user identity files."
@@ -139,6 +162,21 @@ then
   fi
 fi
 
+if [ $_nt -gt 0 ]
+then
+  _user="system"
+  if [ $_nt2003 -gt 0 ]
+  then
+    grep -q '^sshd_server:' ${SYSCONFDIR}/passwd && _user="sshd_server"
+  fi
+  if ! setfacl -m "u::rwx,u:${_user}:r--,g::---,o::---" "${pwdhome}/.ssh"
+  then
+    echo "${pwdhome}/.ssh couldn't be given the correct permissions."
+    echo "Please try to solve this problem first."
+    exit 1
+  fi
+fi
+
 if [ ! -f "${pwdhome}/.ssh/identity" ]
 then
   if request "Shall I create an SSH1 RSA identity file for you?"
@@ -193,6 +231,18 @@ then
       echo "Adding to ${pwdhome}/.ssh/authorized_keys"
       cat "${pwdhome}/.ssh/id_dsa.pub" >> "${pwdhome}/.ssh/authorized_keys"
     fi
+  fi
+fi
+
+if [ $_nt -gt 0 -a -e "${pwdhome}/.ssh/authorized_keys" ]
+then
+  if ! setfacl -m "u::rw-,u:${_user}:r--,g::---,o::---" "${pwdhome}/.ssh/authorized_keys"
+  then
+    echo
+    echo "WARNING: Setting correct permissions to ${pwdhome}/.ssh/authorized_keys"
+    echo "failed.  Please care for the correct permissions.  The minimum requirement"
+    echo "is, the owner and ${_user} both need read permissions."
+    echo
   fi
 fi
 

-- 
Corinna Vinschen
Cygwin Developer
Red Hat, Inc.




More information about the openssh-unix-dev mailing list