Home | History | Annotate | Download | only in cygwin
      1 #!/bin/bash
      2 #
      3 # ssh-host-config, Copyright 2000-2014 Red Hat Inc.
      4 #
      5 # This file is part of the Cygwin port of OpenSSH.
      6 #
      7 # Permission to use, copy, modify, and distribute this software for any
      8 # purpose with or without fee is hereby granted, provided that the above
      9 # copyright notice and this permission notice appear in all copies.
     10 #
     11 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  
     12 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               
     13 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   
     14 # IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   
     15 # DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    
     16 # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    
     17 # THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               
     18 
     19 # ======================================================================
     20 # Initialization
     21 # ======================================================================
     22 
     23 CSIH_SCRIPT=/usr/share/csih/cygwin-service-installation-helper.sh
     24 
     25 # List of apps used.  This is checkad for existance in csih_sanity_check
     26 # Don't use *any* transient commands before sourcing the csih helper script,
     27 # otherwise the sanity checks are short-circuited.
     28 declare -a csih_required_commands=(
     29   /usr/bin/basename coreutils
     30   /usr/bin/cat coreutils
     31   /usr/bin/chmod coreutils
     32   /usr/bin/dirname coreutils
     33   /usr/bin/id coreutils
     34   /usr/bin/mv coreutils
     35   /usr/bin/rm coreutils
     36   /usr/bin/cygpath cygwin
     37   /usr/bin/mkpasswd cygwin
     38   /usr/bin/mount cygwin
     39   /usr/bin/ps cygwin
     40   /usr/bin/umount cygwin
     41   /usr/bin/cmp diffutils
     42   /usr/bin/grep grep
     43   /usr/bin/awk gawk
     44   /usr/bin/ssh-keygen openssh
     45   /usr/sbin/sshd openssh
     46   /usr/bin/sed sed
     47 )
     48 csih_sanity_check_server=yes
     49 source ${CSIH_SCRIPT}
     50 
     51 PROGNAME=$(/usr/bin/basename $0)
     52 _tdir=$(/usr/bin/dirname $0)
     53 PROGDIR=$(cd $_tdir && pwd)
     54 
     55 # Subdirectory where the new package is being installed
     56 PREFIX=/usr
     57 
     58 # Directory where the config files are stored
     59 SYSCONFDIR=/etc
     60 LOCALSTATEDIR=/var
     61 
     62 sshd_config_configured=no
     63 port_number=22
     64 service_name=sshd
     65 strictmodes=yes
     66 cygwin_value=""
     67 user_account=
     68 password_value=
     69 opt_force=no
     70 
     71 # ======================================================================
     72 # Routine: update_services_file
     73 # ======================================================================
     74 update_services_file() {
     75   local _my_etcdir="/ssh-host-config.$$"
     76   local _win_etcdir
     77   local _services
     78   local _spaces
     79   local _serv_tmp
     80   local _wservices
     81   local ret=0
     82 
     83   _win_etcdir="${SYSTEMROOT}\\system32\\drivers\\etc"
     84   _services="${_my_etcdir}/services"
     85   _spaces="                           #"
     86   _serv_tmp="${_my_etcdir}/srv.out.$$"
     87 
     88   /usr/bin/mount -o text,posix=0,noacl -f "${_win_etcdir}" "${_my_etcdir}"
     89 
     90   # Depends on the above mount
     91   _wservices=`cygpath -w "${_services}"`
     92 
     93   # Add ssh 22/tcp  and ssh 22/udp to services
     94   if [ `/usr/bin/grep -q 'ssh[[:space:]][[:space:]]*22' "${_services}"; echo $?` -ne 0 ]
     95   then
     96     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}"
     97     then
     98       if /usr/bin/mv "${_serv_tmp}" "${_services}"
     99       then
    100 	csih_inform "Added ssh to ${_wservices}"
    101       else
    102 	csih_warning "Adding ssh to ${_wservices} failed!"
    103 	let ++ret
    104       fi
    105       /usr/bin/rm -f "${_serv_tmp}"
    106     else
    107       csih_warning "Adding ssh to ${_wservices} failed!"
    108       let ++ret
    109     fi
    110   fi
    111   /usr/bin/umount "${_my_etcdir}"
    112   return $ret
    113 } # --- End of update_services_file --- #
    114 
    115 # ======================================================================
    116 # Routine: sshd_strictmodes
    117 #  MODIFIES: strictmodes
    118 # ======================================================================
    119 sshd_strictmodes() {
    120   if [ "${sshd_config_configured}" != "yes" ]
    121   then
    122     echo
    123     csih_inform "StrictModes is set to 'yes' by default."
    124     csih_inform "This is the recommended setting, but it requires that the POSIX"
    125     csih_inform "permissions of the user's home directory, the user's .ssh"
    126     csih_inform "directory, and the user's ssh key files are tight so that"
    127     csih_inform "only the user has write permissions."
    128     csih_inform "On the other hand, StrictModes don't work well with default"
    129     csih_inform "Windows permissions of a home directory mounted with the"
    130     csih_inform "'noacl' option, and they don't work at all if the home"
    131     csih_inform "directory is on a FAT or FAT32 partition."
    132     if ! csih_request "Should StrictModes be used?"
    133     then
    134       strictmodes=no
    135     fi
    136   fi
    137   return 0
    138 }
    139 
    140 # ======================================================================
    141 # Routine: sshd_privsep
    142 # Try to create ssshd user account
    143 # ======================================================================
    144 sshd_privsep() {
    145   local ret=0
    146 
    147   if [ "${sshd_config_configured}" != "yes" ]
    148   then
    149     if ! csih_create_unprivileged_user sshd
    150     then
    151       csih_error_recoverable "Could not create user 'sshd'!"
    152       csih_error_recoverable "You will not be able to run an sshd service"
    153       csih_error_recoverable "under a privileged account successfully."
    154       csih_error_recoverable "Make sure to create a non-privileged user 'sshd'"
    155       csih_error_recoverable "manually before trying to run the service!"
    156       let ++ret
    157     fi
    158   fi
    159   return $ret
    160 } # --- End of sshd_privsep --- #
    161 
    162 # ======================================================================
    163 # Routine: sshd_config_tweak
    164 # ======================================================================
    165 sshd_config_tweak() {
    166   local ret=0
    167 
    168   # Modify sshd_config
    169   csih_inform "Updating ${SYSCONFDIR}/sshd_config file"
    170   if [ "${port_number}" -ne 22 ]
    171   then
    172     /usr/bin/sed -i -e "s/^#\?[[:space:]]*Port[[:space:]].*/Port ${port_number}/" \
    173       ${SYSCONFDIR}/sshd_config
    174     if [ $? -ne 0 ]
    175     then
    176       csih_warning "Setting listening port to ${port_number} failed!"
    177       csih_warning "Check your ${SYSCONFDIR}/sshd_config file!"
    178       let ++ret
    179     fi
    180   fi
    181   if [ "${strictmodes}" = "no" ]
    182   then
    183     /usr/bin/sed -i -e "s/^#\?[[:space:]]*StrictModes[[:space:]].*/StrictModes no/" \
    184       ${SYSCONFDIR}/sshd_config
    185     if [ $? -ne 0 ]
    186     then
    187       csih_warning "Setting StrictModes to 'no' failed!"
    188       csih_warning "Check your ${SYSCONFDIR}/sshd_config file!"
    189       let ++ret
    190     fi
    191   fi
    192   return $ret
    193 } # --- End of sshd_config_tweak --- #
    194 
    195 # ======================================================================
    196 # Routine: update_inetd_conf
    197 # ======================================================================
    198 update_inetd_conf() {
    199   local _inetcnf="${SYSCONFDIR}/inetd.conf"
    200   local _inetcnf_tmp="${SYSCONFDIR}/inetd.conf.$$"
    201   local _inetcnf_dir="${SYSCONFDIR}/inetd.d"
    202   local _sshd_inetd_conf="${_inetcnf_dir}/sshd-inetd"
    203   local _sshd_inetd_conf_tmp="${_inetcnf_dir}/sshd-inetd.$$"
    204   local _with_comment=1
    205   local ret=0
    206 
    207   if [ -d "${_inetcnf_dir}" ]
    208   then
    209     # we have inetutils-1.5 inetd.d support
    210     if [ -f "${_inetcnf}" ]
    211     then
    212       /usr/bin/grep -q '^[[:space:]]*ssh' "${_inetcnf}" && _with_comment=0
    213 
    214       # check for sshd OR ssh in top-level inetd.conf file, and remove
    215       # will be replaced by a file in inetd.d/
    216       if [ $(/usr/bin/grep -q '^[# \t]*ssh' "${_inetcnf}"; echo $?) -eq 0 ]
    217       then
    218 	/usr/bin/grep -v '^[# \t]*ssh' "${_inetcnf}" >> "${_inetcnf_tmp}"
    219 	if [ -f "${_inetcnf_tmp}" ]
    220 	then
    221 	  if /usr/bin/mv "${_inetcnf_tmp}" "${_inetcnf}"
    222 	  then
    223   	    csih_inform "Removed ssh[d] from ${_inetcnf}"
    224 	  else
    225   	    csih_warning "Removing ssh[d] from ${_inetcnf} failed!"
    226 	    let ++ret
    227 	  fi
    228 	  /usr/bin/rm -f "${_inetcnf_tmp}"
    229 	else
    230 	  csih_warning "Removing ssh[d] from ${_inetcnf} failed!"
    231 	  let ++ret
    232 	fi
    233       fi
    234     fi
    235 
    236     csih_install_config "${_sshd_inetd_conf}"   "${SYSCONFDIR}/defaults"
    237     if /usr/bin/cmp "${SYSCONFDIR}/defaults${_sshd_inetd_conf}" "${_sshd_inetd_conf}" >/dev/null 2>&1
    238     then
    239       if [ "${_with_comment}" -eq 0 ]
    240       then
    241 	/usr/bin/sed -e 's/@COMMENT@[[:space:]]*//' < "${_sshd_inetd_conf}" > "${_sshd_inetd_conf_tmp}"
    242       else
    243 	/usr/bin/sed -e 's/@COMMENT@[[:space:]]*/# /' < "${_sshd_inetd_conf}" > "${_sshd_inetd_conf_tmp}"
    244       fi
    245       if /usr/bin/mv "${_sshd_inetd_conf_tmp}" "${_sshd_inetd_conf}"
    246       then
    247 	csih_inform "Updated ${_sshd_inetd_conf}"
    248       else
    249 	csih_warning "Updating ${_sshd_inetd_conf} failed!"
    250 	let ++ret
    251       fi
    252     fi
    253 
    254   elif [ -f "${_inetcnf}" ]
    255   then
    256     /usr/bin/grep -q '^[[:space:]]*sshd' "${_inetcnf}" && _with_comment=0
    257 
    258     # check for sshd in top-level inetd.conf file, and remove
    259     # will be replaced by a file in inetd.d/
    260     if [ `/usr/bin/grep -q '^#\?[[:space:]]*sshd' "${_inetcnf}"; echo $?` -eq 0 ]
    261     then
    262       /usr/bin/grep -v '^#\?[[:space:]]*sshd' "${_inetcnf}" >> "${_inetcnf_tmp}"
    263       if [ -f "${_inetcnf_tmp}" ]
    264       then
    265 	if /usr/bin/mv "${_inetcnf_tmp}" "${_inetcnf}"
    266 	then
    267 	    csih_inform "Removed sshd from ${_inetcnf}"
    268 	else
    269 	    csih_warning "Removing sshd from ${_inetcnf} failed!"
    270 	    let ++ret
    271 	fi
    272 	/usr/bin/rm -f "${_inetcnf_tmp}"
    273       else
    274 	csih_warning "Removing sshd from ${_inetcnf} failed!"
    275 	let ++ret
    276       fi
    277     fi
    278 
    279     # Add ssh line to inetd.conf
    280     if [ `/usr/bin/grep -q '^[# \t]*ssh' "${_inetcnf}"; echo $?` -ne 0 ]
    281     then
    282       if [ "${_with_comment}" -eq 0 ]
    283       then
    284 	echo 'ssh  stream  tcp     nowait  root    /usr/sbin/sshd sshd -i' >> "${_inetcnf}"
    285       else
    286 	echo '# ssh  stream  tcp     nowait  root    /usr/sbin/sshd sshd -i' >> "${_inetcnf}"
    287       fi
    288       if [ $? -eq 0 ]
    289       then
    290 	csih_inform "Added ssh to ${_inetcnf}"
    291       else
    292 	csih_warning "Adding ssh to ${_inetcnf} failed!"
    293 	let ++ret
    294       fi
    295     fi
    296   fi
    297   return $ret
    298 } # --- End of update_inetd_conf --- #
    299 
    300 # ======================================================================
    301 # Routine: check_service_files_ownership
    302 #   Checks that the files in /etc and /var belong to the right owner
    303 # ======================================================================
    304 check_service_files_ownership() {
    305   local run_service_as=$1
    306   local ret=0
    307 
    308   if [ -z "${run_service_as}" ]
    309   then
    310     accnt_name=$(/usr/bin/cygrunsrv -VQ sshd |
    311     		 /usr/bin/sed -ne 's/^Account *: *//gp')
    312     if [ "${accnt_name}" = "LocalSystem" ]
    313     then
    314       # Convert "LocalSystem" to "SYSTEM" as is the correct account name
    315       run_service_as="SYSTEM"
    316     else
    317       dom="${accnt_name%%\\*}"
    318       accnt_name="${accnt_name#*\\}"
    319       if [ "${dom}" = '.' ]
    320       then
    321 	# Check local account
    322 	run_service_as=$(/usr/bin/mkpasswd -l -u "${accnt_name}" |
    323 			 /usr/bin/awk -F: '{print $1;}')
    324       else
    325       	# Check domain
    326 	run_service_as=$(/usr/bin/mkpasswd -d "${dom}" -u "${accnt_name}" |
    327 			 /usr/bin/awk -F: '{print $1;}')
    328       fi
    329     fi
    330     if [ -z "${run_service_as}" ]
    331     then
    332       csih_warning "Couldn't determine name of user running sshd service from account database!"
    333       csih_warning "As a result, this script cannot make sure that the files used"
    334       csih_warning "by the sshd service belong to the user running the service."
    335       return 1
    336     fi
    337   fi
    338   for i in "${SYSCONFDIR}"/ssh_config "${SYSCONFDIR}"/sshd_config "${SYSCONFDIR}"/ssh_host_*key "${SYSCONFDIR}"/ssh_host_*key.pub
    339   do
    340     if [ -f "$i" ]
    341     then
    342       if ! chown "${run_service_as}".544 "$i" >/dev/null 2>&1
    343       then
    344 	csih_warning "Couldn't change owner of $i!"
    345 	let ++ret
    346       fi
    347     fi
    348   done
    349   if ! chown "${run_service_as}".544 ${LOCALSTATEDIR}/empty >/dev/null 2>&1
    350   then
    351     csih_warning "Couldn't change owner of ${LOCALSTATEDIR}/empty!"
    352     let ++ret
    353   fi
    354   if ! chown "${run_service_as}".544 ${LOCALSTATEDIR}/log/lastlog >/dev/null 2>&1
    355   then
    356     csih_warning "Couldn't change owner of ${LOCALSTATEDIR}/log/lastlog!"
    357     let ++ret
    358   fi
    359   if [ -f ${LOCALSTATEDIR}/log/sshd.log ]
    360   then
    361     if ! chown "${run_service_as}".544 ${LOCALSTATEDIR}/log/sshd.log >/dev/null 2>&1
    362     then
    363       csih_warning "Couldn't change owner of ${LOCALSTATEDIR}/log/sshd.log!"
    364       let ++ret
    365     fi
    366   fi
    367   if [ $ret -ne 0 ]
    368   then
    369     csih_warning "Couldn't change owner of important files to ${run_service_as}!"
    370     csih_warning "This may cause the sshd service to fail!  Please make sure that"
    371     csih_warning "you have suufficient permissions to change the ownership of files"
    372     csih_warning "and try to run the ssh-host-config script again."
    373   fi
    374   return $ret
    375 } # --- End of check_service_files_ownership --- #
    376 
    377 # ======================================================================
    378 # Routine: install_service
    379 #   Install sshd as a service
    380 # ======================================================================
    381 install_service() {
    382   local run_service_as
    383   local password
    384   local ret=0
    385 
    386   echo
    387   if /usr/bin/cygrunsrv -Q ${service_name} >/dev/null 2>&1
    388   then
    389     csih_inform "Sshd service is already installed."
    390     check_service_files_ownership "" || let ret+=$?
    391   else
    392     echo -e "${_csih_QUERY_STR} Do you want to install sshd as a service?"
    393     if csih_request "(Say \"no\" if it is already installed as a service)"
    394     then
    395       csih_get_cygenv "${cygwin_value}"
    396 
    397       if ( csih_is_nt2003 || [ "$csih_FORCE_PRIVILEGED_USER" = "yes" ] )
    398       then
    399 	csih_inform "On Windows Server 2003, Windows Vista, and above, the"
    400 	csih_inform "SYSTEM account cannot setuid to other users -- a capability"
    401 	csih_inform "sshd requires.  You need to have or to create a privileged"
    402 	csih_inform "account.  This script will help you do so."
    403 	echo
    404 
    405 	[ "${opt_force}" = "yes" ] && opt_f=-f
    406 	[ -n "${user_account}" ] && opt_u="-u ""${user_account}"""
    407 	csih_select_privileged_username ${opt_f} ${opt_u} sshd
    408 
    409 	if ! csih_create_privileged_user "${password_value}"
    410 	then
    411 	  csih_error_recoverable "There was a serious problem creating a privileged user."
    412 	  csih_request "Do you want to proceed anyway?" || exit 1
    413 	  let ++ret
    414 	fi
    415       fi
    416 
    417       # Never returns empty if NT or above
    418       run_service_as=$(csih_service_should_run_as)
    419 
    420       if [ "${run_service_as}" = "${csih_PRIVILEGED_USERNAME}" ]
    421       then
    422 	password="${csih_PRIVILEGED_PASSWORD}"
    423 	if [ -z "${password}" ]
    424 	then
    425 	  csih_get_value "Please enter the password for user '${run_service_as}':" "-s"
    426 	  password="${csih_value}"
    427 	fi
    428       fi
    429 
    430       # At this point, we either have $run_service_as = "system" and
    431       # $password is empty, or $run_service_as is some privileged user and
    432       # (hopefully) $password contains the correct password.  So, from here
    433       # out, we use '-z "${password}"' to discriminate the two cases.
    434 
    435       csih_check_user "${run_service_as}"
    436 
    437       if [ -n "${csih_cygenv}" ]
    438       then
    439 	cygwin_env=( -e "CYGWIN=${csih_cygenv}" )
    440       fi
    441       if [ -z "${password}" ]
    442       then
    443 	if /usr/bin/cygrunsrv -I ${service_name} -d "CYGWIN ${service_name}" -p /usr/sbin/sshd \
    444 			      -a "-D" -y tcpip "${cygwin_env[@]}"
    445 	then
    446 	  echo
    447 	  csih_inform "The sshd service has been installed under the LocalSystem"
    448 	  csih_inform "account (also known as SYSTEM). To start the service now, call"
    449 	  csih_inform "\`net start sshd' or \`cygrunsrv -S sshd'.  Otherwise, it"
    450 	  csih_inform "will start automatically after the next reboot."
    451 	fi
    452       else
    453 	if /usr/bin/cygrunsrv -I ${service_name} -d "CYGWIN ${service_name}" -p /usr/sbin/sshd \
    454 			      -a "-D" -y tcpip "${cygwin_env[@]}" \
    455 			      -u "${run_service_as}" -w "${password}"
    456 	then
    457 	  /usr/bin/editrights -u "${run_service_as}" -a SeServiceLogonRight
    458 	  echo
    459 	  csih_inform "The sshd service has been installed under the '${run_service_as}'"
    460 	  csih_inform "account.  To start the service now, call \`net start ${service_name}' or"
    461 	  csih_inform "\`cygrunsrv -S ${service_name}'.  Otherwise, it will start automatically"
    462 	  csih_inform "after the next reboot."
    463 	fi
    464       fi
    465 
    466       if /usr/bin/cygrunsrv -Q ${service_name} >/dev/null 2>&1
    467       then
    468 	check_service_files_ownership "${run_service_as}" || let ret+=$?
    469       else
    470 	csih_error_recoverable "Installing sshd as a service failed!"
    471 	let ++ret
    472       fi
    473     fi # user allowed us to install as service
    474   fi # service not yet installed
    475   return $ret
    476 } # --- End of install_service --- #
    477 
    478 # ======================================================================
    479 # Main Entry Point
    480 # ======================================================================
    481 
    482 # Check how the script has been started.  If
    483 #   (1) it has been started by giving the full path and
    484 #       that path is /etc/postinstall, OR
    485 #   (2) Otherwise, if the environment variable
    486 #       SSH_HOST_CONFIG_AUTO_ANSWER_NO is set
    487 # then set auto_answer to "no".  This allows automatic
    488 # creation of the config files in /etc w/o overwriting
    489 # them if they already exist.  In both cases, color
    490 # escape sequences are suppressed, so as to prevent
    491 # cluttering setup's logfiles.
    492 if [ "$PROGDIR" = "/etc/postinstall" ]
    493 then
    494   csih_auto_answer="no"
    495   csih_disable_color
    496   opt_force=yes
    497 fi
    498 if [ -n "${SSH_HOST_CONFIG_AUTO_ANSWER_NO}" ]
    499 then
    500   csih_auto_answer="no"
    501   csih_disable_color
    502   opt_force=yes
    503 fi
    504 
    505 # ======================================================================
    506 # Parse options
    507 # ======================================================================
    508 while :
    509 do
    510   case $# in
    511   0)
    512     break
    513     ;;
    514   esac
    515 
    516   option=$1
    517   shift
    518 
    519   case "${option}" in
    520   -d | --debug )
    521     set -x
    522     csih_trace_on
    523     ;;
    524 
    525   -y | --yes )
    526     csih_auto_answer=yes
    527     opt_force=yes
    528     ;;
    529 
    530   -n | --no )
    531     csih_auto_answer=no
    532     opt_force=yes
    533     ;;
    534 
    535   -c | --cygwin )
    536     cygwin_value="$1"
    537     shift
    538     ;;
    539 
    540   -N | --name )
    541     service_name=$1
    542     shift
    543     ;;
    544 
    545   -p | --port )
    546     port_number=$1
    547     shift
    548     ;;
    549 
    550   -u | --user )
    551     user_account="$1"
    552     shift
    553     ;;
    554     
    555   -w | --pwd )
    556     password_value="$1"
    557     shift
    558     ;;
    559 
    560   --privileged )
    561     csih_FORCE_PRIVILEGED_USER=yes
    562     ;;
    563 
    564   *)
    565     echo "usage: ${progname} [OPTION]..."
    566     echo
    567     echo "This script creates an OpenSSH host configuration."
    568     echo
    569     echo "Options:"
    570     echo "  --debug  -d            Enable shell's debug output."
    571     echo "  --yes    -y            Answer all questions with \"yes\" automatically."
    572     echo "  --no     -n            Answer all questions with \"no\" automatically."
    573     echo "  --cygwin -c <options>  Use \"options\" as value for CYGWIN environment var."
    574     echo "  --name   -N <name>     sshd windows service name."
    575     echo "  --port   -p <n>        sshd listens on port n."
    576     echo "  --user   -u <account>  privileged user for service, default 'cyg_server'."
    577     echo "  --pwd    -w <passwd>   Use \"pwd\" as password for privileged user."
    578     echo "  --privileged           On Windows XP, require privileged user"
    579     echo "                         instead of LocalSystem for sshd service."
    580     echo
    581     exit 1
    582     ;;
    583 
    584   esac
    585 done
    586 
    587 # ======================================================================
    588 # Action!
    589 # ======================================================================
    590 
    591 # Check for running ssh/sshd processes first. Refuse to do anything while
    592 # some ssh processes are still running
    593 if /usr/bin/ps -ef | /usr/bin/grep -q '/sshd\?$'
    594 then
    595   echo
    596   csih_error "There are still ssh processes running. Please shut them down first."
    597 fi
    598 
    599 # Make sure the user is running in an administrative context
    600 admin=$(/usr/bin/id -G | /usr/bin/grep -Eq '\<544\>' && echo yes || echo no)
    601 if [ "${admin}" != "yes" ]
    602 then
    603   echo
    604   csih_warning "Running this script typically requires administrator privileges!"
    605   csih_warning "However, it seems your account does not have these privileges."
    606   csih_warning "Here's the list of groups in your user token:"
    607   echo
    608   /usr/bin/id -Gnz | xargs -0n1 echo "   "
    609   echo
    610   csih_warning "This usually means you're running this script from a non-admin"
    611   csih_warning "desktop session, or in a non-elevated shell under UAC control."
    612   echo
    613   csih_warning "Make sure you have the appropriate privileges right now,"
    614   csih_warning "otherwise parts of this script will probably fail!"
    615   echo
    616   echo -e "${_csih_QUERY_STR} Are you sure you want to continue?  (Say \"no\" if you're not sure"
    617   if ! csih_request "you have the required privileges)"
    618   then
    619     echo
    620     csih_inform "Ok.  Exiting.  Make sure to switch to an administrative account"
    621     csih_inform "or to start this script from an elevated shell."
    622     exit 1
    623   fi
    624 fi
    625 
    626 echo
    627 
    628 warning_cnt=0
    629 
    630 # Create /var/log/lastlog if not already exists
    631 if [ -e ${LOCALSTATEDIR}/log/lastlog -a ! -f ${LOCALSTATEDIR}/log/lastlog ]
    632 then
    633   echo
    634   csih_error_multi "${LOCALSTATEDIR}/log/lastlog exists, but is not a file." \
    635 		   "Cannot create ssh host configuration."
    636 fi
    637 if [ ! -e ${LOCALSTATEDIR}/log/lastlog ]
    638 then
    639   /usr/bin/cat /dev/null > ${LOCALSTATEDIR}/log/lastlog
    640   if ! /usr/bin/chmod 644 ${LOCALSTATEDIR}/log/lastlog >/dev/null 2>&1
    641   then
    642     csih_warning "Can't set permissions on ${LOCALSTATEDIR}/log/lastlog!"
    643     let ++warning_cnt
    644   fi
    645 fi
    646 
    647 # Create /var/empty file used as chroot jail for privilege separation
    648 csih_make_dir "${LOCALSTATEDIR}/empty" "Cannot create ${LOCALSTATEDIR}/empty directory."
    649 if ! /usr/bin/chmod 755 "${LOCALSTATEDIR}/empty" >/dev/null 2>&1
    650 then
    651   csih_warning "Can't set permissions on ${LOCALSTATEDIR}/empty!"
    652   let ++warning_cnt
    653 fi
    654 
    655 # generate missing host keys
    656 csih_inform "Generating missing SSH host keys"
    657 /usr/bin/ssh-keygen -A || let warning_cnt+=$?
    658 
    659 # handle ssh_config
    660 csih_install_config "${SYSCONFDIR}/ssh_config" "${SYSCONFDIR}/defaults" || let ++warning_cnt
    661 if /usr/bin/cmp "${SYSCONFDIR}/ssh_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/ssh_config" >/dev/null 2>&1
    662 then
    663   if [ "${port_number}" != "22" ]
    664   then
    665     csih_inform "Updating ${SYSCONFDIR}/ssh_config file with requested port"
    666     echo "Host localhost" >> ${SYSCONFDIR}/ssh_config
    667     echo "    Port ${port_number}" >> ${SYSCONFDIR}/ssh_config
    668   fi
    669 fi
    670 
    671 # handle sshd_config
    672 csih_install_config "${SYSCONFDIR}/sshd_config" "${SYSCONFDIR}/defaults" || let ++warning_cnt
    673 if ! /usr/bin/cmp "${SYSCONFDIR}/sshd_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/sshd_config" >/dev/null 2>&1
    674 then
    675   sshd_config_configured=yes
    676 fi
    677 sshd_strictmodes || let warning_cnt+=$?
    678 sshd_privsep || let warning_cnt+=$?
    679 sshd_config_tweak || let warning_cnt+=$?
    680 update_services_file || let warning_cnt+=$?
    681 update_inetd_conf || let warning_cnt+=$?
    682 install_service || let warning_cnt+=$?
    683 
    684 echo
    685 if [ $warning_cnt -eq 0 ]
    686 then
    687   csih_inform "Host configuration finished. Have fun!"
    688 else
    689   csih_warning "Host configuration exited with ${warning_cnt} errors or warnings!"
    690   csih_warning "Make sure that all problems reported are fixed,"
    691   csih_warning "then re-run ssh-host-config."
    692 fi
    693 exit $warning_cnt
    694