[PATCH/cygwin]: Revised sshh-host-config script

Corinna Vinschen vinschen at redhat.com
Mon Feb 21 21:18:49 EST 2011


Hi,

could somebody with checkin rights please apply the below patch?

It would be helpful to have this in 5.9p1.

I revamped the Cygwin-specific service installer script ssh-host-config.
The actual functionality is the same, the revisited version is just more
exact when it comes to check for problems which disallow to run certain
aspects of the script.  So, part of this script and the also rearranged
service helper script library "csih" is to check if all the tools
required to run the script are available on the system.  The new script
also is more thorough to inform the user why the script failed.


TIA,
Corinna


Index: contrib/cygwin/ssh-host-config
===================================================================
RCS file: /cvs/openssh/contrib/cygwin/ssh-host-config,v
retrieving revision 1.30
diff -u -p -r1.30 ssh-host-config
--- contrib/cygwin/ssh-host-config	6 Feb 2011 02:31:25 -0000	1.30
+++ contrib/cygwin/ssh-host-config	21 Feb 2011 10:16:28 -0000
@@ -1,6 +1,6 @@
 #!/bin/bash
 #
-# ssh-host-config, Copyright 2000-2009 Red Hat Inc.
+# ssh-host-config, Copyright 2000-2011 Red Hat Inc.
 #
 # This file is part of the Cygwin port of OpenSSH.
 #
@@ -19,12 +19,39 @@
 # ======================================================================
 # Initialization
 # ======================================================================
-PROGNAME=$(basename $0)
-_tdir=$(dirname $0)
-PROGDIR=$(cd $_tdir && pwd)
 
 CSIH_SCRIPT=/usr/share/csih/cygwin-service-installation-helper.sh
 
+# List of apps used.  This is checkad for existance in csih_sanity_check
+# Don't use *any* transient commands before sourcing the csih helper script,
+# otherwise the sanity checks are short-circuited.
+declare -a csih_required_commands=(
+  /usr/bin/basename coreutils
+  /usr/bin/cat coreutils
+  /usr/bin/chmod coreutils
+  /usr/bin/dirname coreutils
+  /usr/bin/id coreutils
+  /usr/bin/mv coreutils
+  /usr/bin/rm coreutils
+  /usr/bin/cygpath cygwin
+  /usr/bin/mount cygwin
+  /usr/bin/ps cygwin
+  /usr/bin/setfacl cygwin
+  /usr/bin/umount cygwin
+  /usr/bin/cmp diffutils
+  /usr/bin/grep grep
+  /usr/bin/awk gawk
+  /usr/bin/ssh-keygen openssh
+  /usr/sbin/sshd openssh
+  /usr/bin/sed sed
+)
+csih_sanity_check_server=yes
+source ${CSIH_SCRIPT}
+
+PROGNAME=$(/usr/bin/basename $0)
+_tdir=$(/usr/bin/dirname $0)
+PROGDIR=$(cd $_tdir && pwd)
+
 # Subdirectory where the new package is being installed
 PREFIX=/usr
 
@@ -32,8 +59,6 @@ PREFIX=/usr
 SYSCONFDIR=/etc
 LOCALSTATEDIR=/var
 
-source ${CSIH_SCRIPT}
-
 port_number=22
 privsep_configured=no
 privsep_used=yes
@@ -46,29 +71,48 @@ opt_force=no
 # Routine: create_host_keys
 # ======================================================================
 create_host_keys() {
+  local ret=0
+
   if [ ! -f "${SYSCONFDIR}/ssh_host_key" ]
   then
     csih_inform "Generating ${SYSCONFDIR}/ssh_host_key"
-    ssh-keygen -t rsa1 -f ${SYSCONFDIR}/ssh_host_key -N '' > /dev/null
+    if ! /usr/bin/ssh-keygen -t rsa1 -f ${SYSCONFDIR}/ssh_host_key -N '' > /dev/null
+    then
+    	csih_warning "Generating ${SYSCONFDIR}/ssh_host_key failed!"
+	let ++ret
+    fi
   fi
 
   if [ ! -f "${SYSCONFDIR}/ssh_host_rsa_key" ]
   then
     csih_inform "Generating ${SYSCONFDIR}/ssh_host_rsa_key"
-    ssh-keygen -t rsa -f ${SYSCONFDIR}/ssh_host_rsa_key -N '' > /dev/null
+    if ! /usr/bin/ssh-keygen -t rsa -f ${SYSCONFDIR}/ssh_host_rsa_key -N '' > /dev/null
+    then
+    	csih_warning "Generating ${SYSCONFDIR}/ssh_host_key failed!"
+	let ++ret
+    fi
   fi
 
   if [ ! -f "${SYSCONFDIR}/ssh_host_dsa_key" ]
   then
     csih_inform "Generating ${SYSCONFDIR}/ssh_host_dsa_key"
-    ssh-keygen -t dsa -f ${SYSCONFDIR}/ssh_host_dsa_key -N '' > /dev/null
+    if ! /usr/bin/ssh-keygen -t dsa -f ${SYSCONFDIR}/ssh_host_dsa_key -N '' > /dev/null
+    then
+    	csih_warning "Generating ${SYSCONFDIR}/ssh_host_key failed!"
+	let ++ret
+    fi
   fi
 
   if [ ! -f "${SYSCONFDIR}/ssh_host_ecdsa_key" ]
   then
     csih_inform "Generating ${SYSCONFDIR}/ssh_host_ecdsa_key"
-    ssh-keygen -t ecdsa -f ${SYSCONFDIR}/ssh_host_ecdsa_key -N '' > /dev/null
+    if ! /usr/bin/ssh-keygen -t ecdsa -f ${SYSCONFDIR}/ssh_host_ecdsa_key -N '' > /dev/null
+    then
+    	csih_warning "Generating ${SYSCONFDIR}/ssh_host_key failed!"
+	let ++ret
+    fi
   fi
+  return $ret
 } # --- End of create_host_keys --- #
 
 # ======================================================================
@@ -81,61 +125,58 @@ update_services_file() {
   local _spaces
   local _serv_tmp
   local _wservices
+  local ret=0
 
-  if csih_is_nt
-  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
+  _win_etcdir="${SYSTEMROOT}\\system32\\drivers\\etc"
+  _services="${_my_etcdir}/services"
+  _spaces="                           #"
   _serv_tmp="${_my_etcdir}/srv.out.$$"
 
-  mount -o text,posix=0,noacl -f "${_win_etcdir}" "${_my_etcdir}"
+  /usr/bin/mount -o text,posix=0,noacl -f "${_win_etcdir}" "${_my_etcdir}"
 
   # Depends on the above mount
   _wservices=`cygpath -w "${_services}"`
 
   # Remove sshd 22/port from services
-  if [ `grep -q 'sshd[ \t][ \t]*22' "${_services}"; echo $?` -eq 0 ]
+  if [ `/usr/bin/grep -q 'sshd[ \t][ \t]*22' "${_services}"; echo $?` -eq 0 ]
   then
-    grep -v 'sshd[ \t][ \t]*22' "${_services}" > "${_serv_tmp}"
+    /usr/bin/grep -v 'sshd[ \t][ \t]*22' "${_services}" > "${_serv_tmp}"
     if [ -f "${_serv_tmp}" ]
     then
-      if mv "${_serv_tmp}" "${_services}"
+      if /usr/bin/mv "${_serv_tmp}" "${_services}"
       then
 	csih_inform "Removing sshd from ${_wservices}"
       else
 	csih_warning "Removing sshd from ${_wservices} failed!"
+	let ++ret
       fi
-      rm -f "${_serv_tmp}"
+      /usr/bin/rm -f "${_serv_tmp}"
     else
       csih_warning "Removing sshd from ${_wservices} failed!"
+      let ++ret
     fi
   fi
 
   # Add ssh 22/tcp  and ssh 22/udp to services
-  if [ `grep -q 'ssh[ \t][ \t]*22' "${_services}"; echo $?` -ne 0 ]
+  if [ `/usr/bin/grep -q 'ssh[ \t][ \t]*22' "${_services}"; echo $?` -ne 0 ]
   then
-    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}"
+    if /usr/bin/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}"
+      if /usr/bin/mv "${_serv_tmp}" "${_services}"
       then
 	csih_inform "Added ssh to ${_wservices}"
       else
 	csih_warning "Adding ssh to ${_wservices} failed!"
+	let ++ret
       fi
-      rm -f "${_serv_tmp}"
+      /usr/bin/rm -f "${_serv_tmp}"
     else
       csih_warning "Adding ssh to ${_wservices} failed!"
+      let ++ret
     fi
   fi
-  umount "${_my_etcdir}"
+  /usr/bin/umount "${_my_etcdir}"
+  return $ret
 } # --- End of update_services_file --- #
 
 # ======================================================================
@@ -144,51 +185,57 @@ update_services_file() {
 # ======================================================================
 sshd_privsep() {
   local sshdconfig_tmp
+  local ret=0
 
   if [ "${privsep_configured}" != "yes" ]
   then
-    if csih_is_nt
+    csih_inform "Privilege separation is set to yes by default since OpenSSH 3.3."
+    csih_inform "However, this requires a non-privileged account called 'sshd'."
+    csih_inform "For more info on privilege separation read /usr/share/doc/openssh/README.privsep."
+    if csih_request "Should privilege separation be used?"
     then
-      csih_inform "Privilege separation is set to yes by default since OpenSSH 3.3."
-      csih_inform "However, this requires a non-privileged account called 'sshd'."
-      csih_inform "For more info on privilege separation read /usr/share/doc/openssh/README.privsep."
-      if csih_request "Should privilege separation be used?"
+      privsep_used=yes
+      if ! csih_create_unprivileged_user sshd
       then
-	privsep_used=yes
-	if ! csih_create_unprivileged_user sshd
-	then
-  	  csih_warning "Couldn't create user 'sshd'!"
-	  csih_warning "Privilege separation set to 'no' again!"
-	  csih_warning "Check your ${SYSCONFDIR}/sshd_config file!"
-  	  privsep_used=no
-	fi
-      else
+	csih_error_recoverable "Couldn't create user 'sshd'!"
+	csih_error_recoverable "Privilege separation set to 'no' again!"
+	csih_error_recoverable "Check your ${SYSCONFDIR}/sshd_config file!"
+	let ++ret
 	privsep_used=no
       fi
     else
-      # On 9x don't use privilege separation.  Since security isn't
-      # available it just adds useless additional processes.
       privsep_used=no
     fi
   fi
 
   # Create default sshd_config from skeleton files in /etc/defaults/etc or
   # modify to add the missing privsep configuration option
-  if cmp "${SYSCONFDIR}/sshd_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/sshd_config" >/dev/null 2>&1
+  if /usr/bin/cmp "${SYSCONFDIR}/sshd_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/sshd_config" >/dev/null 2>&1
   then
     csih_inform "Updating ${SYSCONFDIR}/sshd_config file"
     sshdconfig_tmp=${SYSCONFDIR}/sshd_config.$$
-    sed -e "s/^#UsePrivilegeSeparation yes/UsePrivilegeSeparation ${privsep_used}/
+    /usr/bin/sed -e "s/^#UsePrivilegeSeparation yes/UsePrivilegeSeparation ${privsep_used}/
   	  s/^#Port 22/Port ${port_number}/
   	  s/^#StrictModes yes/StrictModes no/" \
 	< ${SYSCONFDIR}/sshd_config \
 	> "${sshdconfig_tmp}"
-    mv "${sshdconfig_tmp}" ${SYSCONFDIR}/sshd_config
+    if ! /usr/bin/mv "${sshdconfig_tmp}" ${SYSCONFDIR}/sshd_config
+    then
+	csih_warning "Setting privilege separation to 'yes' failed!"
+	csih_warning "Check your ${SYSCONFDIR}/sshd_config file!"
+	let ++ret
+    fi
   elif [ "${privsep_configured}" != "yes" ]
   then
     echo >> ${SYSCONFDIR}/sshd_config
-    echo "UsePrivilegeSeparation ${privsep_used}" >> ${SYSCONFDIR}/sshd_config
+    if ! echo "UsePrivilegeSeparation ${privsep_used}" >> ${SYSCONFDIR}/sshd_config
+    then
+	csih_warning "Setting privilege separation to 'yes' failed!"
+	csih_warning "Check your ${SYSCONFDIR}/sshd_config file!"
+	let ++ret
+    fi
   fi
+  return $ret
 } # --- End of sshd_privsep --- #
 
 # ======================================================================
@@ -201,72 +248,82 @@ update_inetd_conf() {
   local _sshd_inetd_conf="${_inetcnf_dir}/sshd-inetd"
   local _sshd_inetd_conf_tmp="${_inetcnf_dir}/sshd-inetd.$$"
   local _with_comment=1
+  local ret=0
 
   if [ -d "${_inetcnf_dir}" ]
   then
     # we have inetutils-1.5 inetd.d support
     if [ -f "${_inetcnf}" ]
     then
-      grep -q '^[ \t]*ssh' "${_inetcnf}" && _with_comment=0
+      /usr/bin/grep -q '^[ \t]*ssh' "${_inetcnf}" && _with_comment=0
 
       # check for sshd OR ssh in top-level inetd.conf file, and remove
       # will be replaced by a file in inetd.d/
-      if [ `grep -q '^[# \t]*ssh' "${_inetcnf}"; echo $?` -eq 0 ]
+      if [ `/usr/bin/grep -q '^[# \t]*ssh' "${_inetcnf}"; echo $?` -eq 0 ]
       then
-	grep -v '^[# \t]*ssh' "${_inetcnf}" >> "${_inetcnf_tmp}"
+	/usr/bin/grep -v '^[# \t]*ssh' "${_inetcnf}" >> "${_inetcnf_tmp}"
 	if [ -f "${_inetcnf_tmp}" ]
 	then
-	  if mv "${_inetcnf_tmp}" "${_inetcnf}"
+	  if /usr/bin/mv "${_inetcnf_tmp}" "${_inetcnf}"
 	  then
   	    csih_inform "Removed ssh[d] from ${_inetcnf}"
 	  else
   	    csih_warning "Removing ssh[d] from ${_inetcnf} failed!"
+	    let ++ret
 	  fi
-	  rm -f "${_inetcnf_tmp}"
+	  /usr/bin/rm -f "${_inetcnf_tmp}"
 	else
 	  csih_warning "Removing ssh[d] from ${_inetcnf} failed!"
+	  let ++ret
 	fi
       fi
     fi
 
     csih_install_config "${_sshd_inetd_conf}"   "${SYSCONFDIR}/defaults"
-    if cmp "${SYSCONFDIR}/defaults${_sshd_inetd_conf}" "${_sshd_inetd_conf}" >/dev/null 2>&1
+    if /usr/bin/cmp "${SYSCONFDIR}/defaults${_sshd_inetd_conf}" "${_sshd_inetd_conf}" >/dev/null 2>&1
     then
       if [ "${_with_comment}" -eq 0 ]
       then
-	sed -e 's/@COMMENT@[ \t]*//' < "${_sshd_inetd_conf}" > "${_sshd_inetd_conf_tmp}"
+	/usr/bin/sed -e 's/@COMMENT@[ \t]*//' < "${_sshd_inetd_conf}" > "${_sshd_inetd_conf_tmp}"
+      else
+	/usr/bin/sed -e 's/@COMMENT@[ \t]*/# /' < "${_sshd_inetd_conf}" > "${_sshd_inetd_conf_tmp}"
+      fi
+      if /usr/bin/mv "${_sshd_inetd_conf_tmp}" "${_sshd_inetd_conf}"
+      then
+	csih_inform "Updated ${_sshd_inetd_conf}"
       else
-	sed -e 's/@COMMENT@[ \t]*/# /' < "${_sshd_inetd_conf}" > "${_sshd_inetd_conf_tmp}"
+	csih_warning "Updating ${_sshd_inetd_conf} failed!"
+	let ++ret
       fi
-      mv "${_sshd_inetd_conf_tmp}" "${_sshd_inetd_conf}"
-      csih_inform "Updated ${_sshd_inetd_conf}"
     fi
 
   elif [ -f "${_inetcnf}" ]
   then
-    grep -q '^[ \t]*sshd' "${_inetcnf}" && _with_comment=0
+    /usr/bin/grep -q '^[ \t]*sshd' "${_inetcnf}" && _with_comment=0
 
     # check for sshd in top-level inetd.conf file, and remove
     # will be replaced by a file in inetd.d/
-    if [ `grep -q '^[# \t]*sshd' "${_inetcnf}"; echo $?` -eq 0 ]
+    if [ `/usr/bin/grep -q '^[# \t]*sshd' "${_inetcnf}"; echo $?` -eq 0 ]
     then
-      grep -v '^[# \t]*sshd' "${_inetcnf}" >> "${_inetcnf_tmp}"
+      /usr/bin/grep -v '^[# \t]*sshd' "${_inetcnf}" >> "${_inetcnf_tmp}"
       if [ -f "${_inetcnf_tmp}" ]
       then
-	if mv "${_inetcnf_tmp}" "${_inetcnf}"
+	if /usr/bin/mv "${_inetcnf_tmp}" "${_inetcnf}"
 	then
 	    csih_inform "Removed sshd from ${_inetcnf}"
 	else
 	    csih_warning "Removing sshd from ${_inetcnf} failed!"
+	    let ++ret
 	fi
-	rm -f "${_inetcnf_tmp}"
+	/usr/bin/rm -f "${_inetcnf_tmp}"
       else
 	csih_warning "Removing sshd from ${_inetcnf} failed!"
+	let ++ret
       fi
     fi
 
     # Add ssh line to inetd.conf
-    if [ `grep -q '^[# \t]*ssh' "${_inetcnf}"; echo $?` -ne 0 ]
+    if [ `/usr/bin/grep -q '^[# \t]*ssh' "${_inetcnf}"; echo $?` -ne 0 ]
     then
       if [ "${_with_comment}" -eq 0 ]
       then
@@ -274,115 +331,186 @@ update_inetd_conf() {
       else
 	echo '# ssh  stream  tcp     nowait  root    /usr/sbin/sshd sshd -i' >> "${_inetcnf}"
       fi
-      csih_inform "Added ssh to ${_inetcnf}"
+      if [ $? -eq 0 ]
+      then
+	csih_inform "Added ssh to ${_inetcnf}"
+      else
+	csih_warning "Adding ssh to ${_inetcnf} failed!"
+	let ++ret
+      fi
     fi
   fi
+  return $ret
 } # --- End of update_inetd_conf --- #
 
 # ======================================================================
+# Routine: check_service_files_ownership
+#   Checks that the files in /etc and /var belong to the right owner
+# ======================================================================
+check_service_files_ownership() {
+  local run_service_as=$1
+  local ret=0
+
+  if [ -z "${run_service_as}" ]
+  then
+    accnt_name=$(/usr/bin/cygrunsrv -VQ sshd | /usr/bin/sed -ne 's/^Account *: *//gp')
+    if [ "${accnt_name}" = "LocalSystem" ]
+    then
+      # Convert "LocalSystem" to "SYSTEM" as is the correct account name
+      accnt_name="SYSTEM:"
+    elif [[ "${accnt_name}" =~ ^\.\\ ]]
+    then
+      # Convert "." domain to local machine name
+      accnt_name="U-${COMPUTERNAME}${accnt_name#.},"
+    fi
+    run_service_as=$(/usr/bin/grep -Fi "${accnt_name}" /etc/passwd | /usr/bin/awk -F: '{print $1;}')
+    if [ -z "${run_service_as}" ]
+    then
+      csih_warning "Couldn't determine name of user running sshd service from /etc/passwd!"
+      csih_warning "As a result, this script cannot make sure that the files used"
+      csih_warning "by the sshd service belong to the user running the service."
+      csih_warning "Please re-run the mkpasswd tool to make sure the /etc/passwd"
+      csih_warning "file is in a good shape."
+      return 1
+    fi
+  fi
+  for i in "${SYSCONFDIR}"/ssh_config "${SYSCONFDIR}"/sshd_config "${SYSCONFDIR}"/ssh_host_*key "${SYSCONFDIR}"/ssh_host_*key.pub
+  do
+    if [ -f "$i" ]
+    then
+      if ! chown "${run_service_as}".544 "$i" >/dev/null 2>&1
+      then
+	csih_warning "Couldn't change owner of $i!"
+	let ++ret
+      fi
+    fi
+  done
+  if ! chown "${run_service_as}".544 ${LOCALSTATEDIR}/empty >/dev/null 2>&1
+  then
+    csih_warning "Couldn't change owner of ${LOCALSTATEDIR}/empty!"
+    let ++ret
+  fi
+  if ! chown "${run_service_as}".544 ${LOCALSTATEDIR}/log/lastlog >/dev/null 2>&1
+  then
+    csih_warning "Couldn't change owner of ${LOCALSTATEDIR}/log/lastlog!"
+    let ++ret
+  fi
+  if [ -f ${LOCALSTATEDIR}/log/sshd.log ]
+  then
+    if ! chown "${run_service_as}".544 ${LOCALSTATEDIR}/log/sshd.log >/dev/null 2>&1
+    then
+      csih_warning "Couldn't change owner of ${LOCALSTATEDIR}/log/sshd.log!"
+      let ++ret
+    fi
+  fi
+  if [ $ret -ne 0 ]
+  then
+    csih_warning "Couldn't change owner of important files to ${run_service_as}!"
+    csih_warning "This may cause the sshd service to fail!  Please make sure that"
+    csih_warning "you have suufficient permissions to change the ownership of files"
+    csih_warning "and try to run the ssh-host-config script again."
+  fi
+  return $ret
+} # --- End of check_service_files_ownership --- #
+
+# ======================================================================
 # Routine: install_service
 #   Install sshd as a service
 # ======================================================================
 install_service() {
   local run_service_as
   local password
+  local ret=0
 
-  if csih_is_nt
+  echo
+  if /usr/bin/cygrunsrv -Q sshd >/dev/null 2>&1
   then
-    if ! cygrunsrv -Q sshd >/dev/null 2>&1
+    csih_inform "Sshd service is already installed."
+    check_service_files_ownership "" || let ret+=$?
+  else
+    echo -e "${_csih_QUERY_STR} Do you want to install sshd as a service?"
+    if csih_request "(Say \"no\" if it is already installed as a service)"
     then
-      echo
-      echo
-      csih_warning "The following functions require administrator privileges!"
-      echo
-      echo -e "${_csih_QUERY_STR} Do you want to install sshd as a service?"
-      if csih_request "(Say \"no\" if it is already installed as a service)"
+      csih_get_cygenv "${cygwin_value}"
+
+      if ( csih_is_nt2003 || [ "$csih_FORCE_PRIVILEGED_USER" = "yes" ] )
       then
-	csih_get_cygenv "${cygwin_value}"
+	csih_inform "On Windows Server 2003, Windows Vista, and above, the"
+	csih_inform "SYSTEM account cannot setuid to other users -- a capability"
+	csih_inform "sshd requires.  You need to have or to create a privileged"
+	csih_inform "account.  This script will help you do so."
+	echo
+
+	[ "${opt_force}" = "yes" ] && opt_f=-f
+	[ -n "${user_account}" ] && opt_u="-u ""${user_account}"""
+	csih_select_privileged_username ${opt_f} ${opt_u} sshd
 
-	if ( csih_is_nt2003 || [ "$csih_FORCE_PRIVILEGED_USER" = "yes" ] )
+	if ! csih_create_privileged_user "${password_value}"
 	then
-	  csih_inform "On Windows Server 2003, Windows Vista, and above, the"
-	  csih_inform "SYSTEM account cannot setuid to other users -- a capability"
-	  csih_inform "sshd requires.  You need to have or to create a privileged"
-	  csih_inform "account.  This script will help you do so."
-	  echo
-
-	  [ "${opt_force}" = "yes" ] && opt_f=-f
-	  [ -n "${user_account}" ] && opt_u="-u ""${user_account}"""
-	  csih_select_privileged_username ${opt_f} ${opt_u} sshd
-
-	  if ! csih_create_privileged_user "${password_value}"
-	  then
-	    csih_error_recoverable "There was a serious problem creating a privileged user."
-	    csih_request "Do you want to proceed anyway?" || exit 1
-	  fi
+	  csih_error_recoverable "There was a serious problem creating a privileged user."
+	  csih_request "Do you want to proceed anyway?" || exit 1
+	  let ++ret
 	fi
+      fi
 
-	# never returns empty if NT or above
-	run_service_as=$(csih_service_should_run_as)
+      # Never returns empty if NT or above
+      run_service_as=$(csih_service_should_run_as)
 
-	if [ "${run_service_as}" = "${csih_PRIVILEGED_USERNAME}" ]
+      if [ "${run_service_as}" = "${csih_PRIVILEGED_USERNAME}" ]
+      then
+	password="${csih_PRIVILEGED_PASSWORD}"
+	if [ -z "${password}" ]
 	then
-	  password="${csih_PRIVILEGED_PASSWORD}"
-	  if [ -z "${password}" ]
-	  then
-	    csih_get_value "Please enter the password for user '${run_service_as}':" "-s"
-	    password="${csih_value}"
-	  fi
+	  csih_get_value "Please enter the password for user '${run_service_as}':" "-s"
+	  password="${csih_value}"
 	fi
+      fi
 
-	# at this point, we either have $run_service_as = "system" and $password is empty,
-	# or $run_service_as is some privileged user and (hopefully) $password contains
-	# the correct password.  So, from here out, we use '-z "${password}"' to discriminate
-	# the two cases.
+      # At this point, we either have $run_service_as = "system" and
+      # $password is empty, or $run_service_as is some privileged user and
+      # (hopefully) $password contains the correct password.  So, from here
+      # out, we use '-z "${password}"' to discriminate the two cases.
 
-	csih_check_user "${run_service_as}"
+      csih_check_user "${run_service_as}"
 
-	if [ -n "${csih_cygenv}" ]
+      if [ -n "${csih_cygenv}" ]
+      then
+	cygwin_env=( -e "CYGWIN=${csih_cygenv}" )
+      fi
+      if [ -z "${password}" ]
+      then
+	if /usr/bin/cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd \
+			      -a "-D" -y tcpip "${cygwin_env[@]}"
 	then
-	  cygwin_env=( -e "CYGWIN=${csih_cygenv}" )
+	  echo
+	  csih_inform "The sshd service has been installed under the LocalSystem"
+	  csih_inform "account (also known as SYSTEM). To start the service now, call"
+	  csih_inform "\`net start sshd' or \`cygrunsrv -S sshd'.  Otherwise, it"
+	  csih_inform "will start automatically after the next reboot."
 	fi
-	if [ -z "${password}" ]
+      else
+	if /usr/bin/cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd \
+			      -a "-D" -y tcpip "${cygwin_env[@]}" \
+			      -u "${run_service_as}" -w "${password}"
 	then
-	  if cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd \
-			    -a "-D" -y tcpip "${cygwin_env[@]}"
-	  then
-	    echo
-	    csih_inform "The sshd service has been installed under the LocalSystem"
-	    csih_inform "account (also known as SYSTEM). To start the service now, call"
-	    csih_inform "\`net start sshd' or \`cygrunsrv -S sshd'.  Otherwise, it"
-	    csih_inform "will start automatically after the next reboot."
-	  fi
-	else
-	  if cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd \
-			    -a "-D" -y tcpip "${cygwin_env[@]}" \
-			    -u "${run_service_as}" -w "${password}"
-	  then
-	    echo
-	    csih_inform "The sshd service has been installed under the '${run_service_as}'"
-	    csih_inform "account.  To start the service now, call \`net start sshd' or"
-	    csih_inform "\`cygrunsrv -S sshd'.  Otherwise, it will start automatically"
-	    csih_inform "after the next reboot."
-	  fi
+	  echo
+	  csih_inform "The sshd service has been installed under the '${run_service_as}'"
+	  csih_inform "account.  To start the service now, call \`net start sshd' or"
+	  csih_inform "\`cygrunsrv -S sshd'.  Otherwise, it will start automatically"
+	  csih_inform "after the next reboot."
 	fi
+      fi
 
-	# now, if successfully installed, set ownership of the affected files
-	if cygrunsrv -Q sshd >/dev/null 2>&1
-	then
-	  chown "${run_service_as}" ${SYSCONFDIR}/ssh*
-	  chown "${run_service_as}".544 ${LOCALSTATEDIR}/empty
-	  chown "${run_service_as}".544 ${LOCALSTATEDIR}/log/lastlog
-	  if [ -f ${LOCALSTATEDIR}/log/sshd.log ]
-	  then
-	    chown "${run_service_as}".544 ${LOCALSTATEDIR}/log/sshd.log
-	  fi
-	else
-	  csih_warning "Something went wrong installing the sshd service."
-	fi
-      fi # user allowed us to install as service
-    fi # service not yet installed
-  fi # csih_is_nt
+      if /usr/bin/cygrunsrv -Q sshd >/dev/null 2>&1
+      then
+	check_service_files_ownership "${run_service_as}" || let ret+=$?
+      else
+	csih_error_recoverable "Installing sshd as a service failed!"
+	let ++ret
+      fi
+    fi # user allowed us to install as service
+  fi # service not yet installed
+  return $ret
 } # --- End of install_service --- #
 
 # ======================================================================
@@ -494,21 +622,71 @@ done
 
 # Check for running ssh/sshd processes first. Refuse to do anything while
 # some ssh processes are still running
-if ps -ef | grep -q '/sshd\?$'
+if /usr/bin/ps -ef | /usr/bin/grep -q '/sshd\?$'
 then
   echo
   csih_error "There are still ssh processes running. Please shut them down first."
 fi
 
+# Make sure the user is running in an administrative context
+admin=$(/usr/bin/id -G | /usr/bin/grep -Eq '\<544\>' && echo yes || echo no)
+if [ "${admin}" != "yes" ]
+then
+  echo
+  csih_warning "Running this script typically requires administrator privileges!"
+  csih_warning "However, it seems your account does not have these privileges."
+  csih_warning "Here's the list of groups in your user token:"
+  echo
+  for i in $(/usr/bin/id -G)
+  do
+    /usr/bin/awk -F: "/[^:]*:[^:]*:$i:/{ print \"    \" \$1; }" /etc/group
+  done
+  echo
+  csih_warning "This usually means you're running this script from a non-admin"
+  csih_warning "desktop session, or in a non-elevated shell under UAC control."
+  echo
+  csih_warning "Make sure you have the appropriate privileges right now,"
+  csih_warning "otherwise parts of this script will probably fail!"
+  echo
+  echo -e "${_csih_QUERY_STR} Are you sure you want to continue?  (Say \"no\" if you're not sure"
+  if ! csih_request "you have the required privileges)"
+  then
+    echo
+    csih_inform "Ok.  Exiting.  Make sure to switch to an administrative account"
+    csih_inform "or to start this script from an elevated shell."
+    exit 1
+  fi
+fi
+
+echo
+
+warning_cnt=0
+
 # Check for ${SYSCONFDIR} directory
 csih_make_dir "${SYSCONFDIR}" "Cannot create global configuration files."
-chmod 775 "${SYSCONFDIR}"
-setfacl -m u:system:rwx "${SYSCONFDIR}"
+if ! /usr/bin/chmod 775 "${SYSCONFDIR}" >/dev/null 2>&1
+then
+  csih_warning "Can't set permissions on ${SYSCONFDIR}!"
+  let ++warning_cnt
+fi
+if ! /usr/bin/setfacl -m u:system:rwx "${SYSCONFDIR}" >/dev/null 2>&1
+then
+  csih_warning "Can't set extended permissions on ${SYSCONFDIR}!"
+  let ++warning_cnt
+fi
 
 # Check for /var/log directory
 csih_make_dir "${LOCALSTATEDIR}/log" "Cannot create log directory."
-chmod 775 "${LOCALSTATEDIR}/log"
-setfacl -m u:system:rwx "${LOCALSTATEDIR}/log"
+if ! /usr/bin/chmod 775 "${LOCALSTATEDIR}/log" >/dev/null 2>&1
+then
+  csih_warning "Can't set permissions on ${LOCALSTATEDIR}/log!"
+  let ++warning_cnt
+fi
+if ! /usr/bin/setfacl -m u:system:rwx "${LOCALSTATEDIR}/log" >/dev/null 2>&1
+then
+  csih_warning "Can't set extended permissions on ${LOCALSTATEDIR}/log!"
+  let ++warning_cnt
+fi
 
 # Create /var/log/lastlog if not already exists
 if [ -e ${LOCALSTATEDIR}/log/lastlog -a ! -f ${LOCALSTATEDIR}/log/lastlog ]
@@ -519,26 +697,33 @@ then
 fi
 if [ ! -e ${LOCALSTATEDIR}/log/lastlog ]
 then
-  cat /dev/null > ${LOCALSTATEDIR}/log/lastlog
-  chmod 644 ${LOCALSTATEDIR}/log/lastlog
+  /usr/bin/cat /dev/null > ${LOCALSTATEDIR}/log/lastlog
+  if ! /usr/bin/chmod 644 ${LOCALSTATEDIR}/log/lastlog >/dev/null 2>&1
+  then
+    csih_warning "Can't set permissions on ${LOCALSTATEDIR}/log/lastlog!"
+    let ++warning_cnt
+  fi
 fi
 
 # Create /var/empty file used as chroot jail for privilege separation
 csih_make_dir "${LOCALSTATEDIR}/empty" "Cannot create ${LOCALSTATEDIR}/empty directory."
-chmod 755 "${LOCALSTATEDIR}/empty"
-setfacl -m u:system:rwx "${LOCALSTATEDIR}/empty"
+if ! /usr/bin/chmod 755 "${LOCALSTATEDIR}/empty" >/dev/null 2>&1
+then
+  csih_warning "Can't set permissions on ${LOCALSTATEDIR}/empty!"
+  let ++warning_cnt
+fi
+if ! /usr/bin/setfacl -m u:system:rwx "${LOCALSTATEDIR}/empty" >/dev/null 2>&1
+then
+  csih_warning "Can't set extended permissions on ${LOCALSTATEDIR}/empty!"
+  let ++warning_cnt
+fi
 
 # host keys
-create_host_keys
-
-# use 'cmp' program to determine if a config file is identical
-# to the default version of that config file
-csih_check_program_or_error cmp diffutils
-
+create_host_keys || let warning_cnt+=$?
 
 # handle ssh_config
-csih_install_config "${SYSCONFDIR}/ssh_config"   "${SYSCONFDIR}/defaults"
-if cmp "${SYSCONFDIR}/ssh_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/ssh_config" >/dev/null 2>&1
+csih_install_config "${SYSCONFDIR}/ssh_config" "${SYSCONFDIR}/defaults" || let ++warning_cnt
+if /usr/bin/cmp "${SYSCONFDIR}/ssh_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/ssh_config" >/dev/null 2>&1
 then
   if [ "${port_number}" != "22" ]
   then
@@ -549,19 +734,24 @@ then
 fi
 
 # handle sshd_config (and privsep)
-csih_install_config "${SYSCONFDIR}/sshd_config"   "${SYSCONFDIR}/defaults"
-if ! cmp "${SYSCONFDIR}/sshd_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/sshd_config" >/dev/null 2>&1
+csih_install_config "${SYSCONFDIR}/sshd_config" "${SYSCONFDIR}/defaults" || let ++warning_cnt
+if ! /usr/bin/cmp "${SYSCONFDIR}/sshd_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/sshd_config" >/dev/null 2>&1
 then
-  grep -q UsePrivilegeSeparation ${SYSCONFDIR}/sshd_config && privsep_configured=yes
+  /usr/bin/grep -q UsePrivilegeSeparation ${SYSCONFDIR}/sshd_config && privsep_configured=yes
 fi
-sshd_privsep
-
+sshd_privsep || let warning_cnt+=$?
 
-
-update_services_file
-update_inetd_conf
-install_service
+update_services_file || let warning_cnt+=$?
+update_inetd_conf || let warning_cnt+=$?
+install_service || let warning_cnt+=$?
 
 echo
-csih_inform "Host configuration finished. Have fun!"
-
+if [ $warning_cnt -eq 0 ]
+then
+  csih_inform "Host configuration finished. Have fun!"
+else
+  csih_warning "Host configuration exited with ${warning_cnt} errors or warnings!"
+  csih_warning "Make sure that all problems reported are fixed,"
+  csih_warning "then re-run ssh-host-config."
+fi
+exit $warning_cnt


-- 
Corinna Vinschen
Cygwin Project Co-Leader
Red Hat


More information about the openssh-unix-dev mailing list