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