]> andersk Git - gssapi-openssh.git/blob - openssh/contrib/cygwin/ssh-host-config
f90af8d2a5e1e59d387ed6136abbacdd2776b2a5
[gssapi-openssh.git] / openssh / contrib / cygwin / ssh-host-config
1 #!/bin/bash
2 #
3 # ssh-host-config, Copyright 2000, 2001, 2002, 2003 Red Hat Inc.
4 #
5 # This file is part of the Cygwin port of OpenSSH.
6
7 # Subdirectory where the new package is being installed
8 PREFIX=/usr
9
10 # Directory where the config files are stored
11 SYSCONFDIR=/etc
12 LOCALSTATEDIR=/var
13
14 progname=$0
15 auto_answer=""
16 port_number=22
17
18 privsep_configured=no
19 privsep_used=yes
20 sshd_in_passwd=no
21 sshd_in_sam=no
22
23 request()
24 {
25   if [ "${auto_answer}" = "yes" ]
26   then
27     echo "$1 (yes/no) yes"
28     return 0
29   elif [ "${auto_answer}" = "no" ]
30   then
31     echo "$1 (yes/no) no"
32     return 1
33   fi
34
35   answer=""
36   while [ "X${answer}" != "Xyes" -a "X${answer}" != "Xno" ]
37   do
38     echo -n "$1 (yes/no) "
39     read -e answer
40   done
41   if [ "X${answer}" = "Xyes" ]
42   then
43     return 0
44   else
45     return 1
46   fi
47 }
48
49 # Check options
50
51 while :
52 do
53   case $# in
54   0)
55     break
56     ;;
57   esac
58
59   option=$1
60   shift
61
62   case "${option}" in
63   -d | --debug )
64     set -x
65     ;;
66
67   -y | --yes )
68     auto_answer=yes
69     ;;
70
71   -n | --no )
72     auto_answer=no
73     ;;
74
75   -c | --cygwin )
76     cygwin_value="$1"
77     shift
78     ;;
79
80   -p | --port )
81     port_number=$1
82     shift
83     ;;
84
85   -w | --pwd )
86     password_value="$1"
87     shift
88     ;;
89
90   *)
91     echo "usage: ${progname} [OPTION]..."
92     echo
93     echo "This script creates an OpenSSH host configuration."
94     echo
95     echo "Options:"
96     echo "  --debug  -d            Enable shell's debug output."
97     echo "  --yes    -y            Answer all questions with \"yes\" automatically."
98     echo "  --no     -n            Answer all questions with \"no\" automatically."
99     echo "  --cygwin -c <options>  Use \"options\" as value for CYGWIN environment var."
100     echo "  --port   -p <n>        sshd listens on port n."
101     echo "  --pwd    -w <passwd>   Use \"pwd\" as password for user 'sshd_server'."
102     echo
103     exit 1
104     ;;
105
106   esac
107 done
108
109 # Check if running on NT
110 _sys="`uname`"
111 _nt=`expr "${_sys}" : "CYGWIN_NT"`
112 # If running on NT, check if running under 2003 Server or later
113 if [ ${_nt} -gt 0 ]
114 then
115   _nt2003=`uname | awk -F- '{print ( $2 >= 5.2 ) ? 1 : 0;}'`
116 fi
117
118 # Check for running ssh/sshd processes first. Refuse to do anything while
119 # some ssh processes are still running
120
121 if ps -ef | grep -v grep | grep -q ssh
122 then
123   echo
124   echo "There are still ssh processes running. Please shut them down first."
125   echo
126   exit 1
127 fi
128
129 # Check for ${SYSCONFDIR} directory
130
131 if [ -e "${SYSCONFDIR}" -a ! -d "${SYSCONFDIR}" ]
132 then
133   echo
134   echo "${SYSCONFDIR} exists but is not a directory."
135   echo "Cannot create global configuration files."
136   echo
137   exit 1
138 fi
139
140 # Create it if necessary
141
142 if [ ! -e "${SYSCONFDIR}" ]
143 then
144   mkdir "${SYSCONFDIR}"
145   if [ ! -e "${SYSCONFDIR}" ]
146   then
147     echo
148     echo "Creating ${SYSCONFDIR} directory failed"
149     echo
150     exit 1
151   fi
152 fi
153
154 # Create /var/log and /var/log/lastlog if not already existing
155
156 if [ -e ${LOCALSTATEDIR}/log -a ! -d ${LOCALSTATEDIR}/log ]
157 then
158   echo
159   echo "${LOCALSTATEDIR}/log exists but is not a directory."
160   echo "Cannot create ssh host configuration."
161   echo
162   exit 1
163 fi
164 if [ ! -e ${LOCALSTATEDIR}/log ]
165 then
166   mkdir -p ${LOCALSTATEDIR}/log
167 fi
168
169 if [ -e ${LOCALSTATEDIR}/log/lastlog -a ! -f ${LOCALSTATEDIR}/log/lastlog ]
170 then
171   echo 
172   echo "${LOCALSTATEDIR}/log/lastlog exists, but is not a file."
173   echo "Cannot create ssh host configuration."
174   echo 
175   exit 1
176 fi
177 if [ ! -e ${LOCALSTATEDIR}/log/lastlog ]
178 then
179   cat /dev/null > ${LOCALSTATEDIR}/log/lastlog
180   chmod 644 ${LOCALSTATEDIR}/log/lastlog
181 fi
182
183 # Create /var/empty file used as chroot jail for privilege separation
184 if [ -e ${LOCALSTATEDIR}/empty -a ! -d ${LOCALSTATEDIR}/empty ]
185 then
186   echo
187   echo "${LOCALSTATEDIR}/empty exists but is not a directory."
188   echo "Cannot create ssh host configuration."
189   echo
190   exit 1
191 if [ ! -e ${LOCALSTATEDIR}/empty ]
192 then
193   if ! mkdir -p ${LOCALSTATEDIR}/empty
194   then
195     echo
196     echo "Creating ${LOCALSTATEDIR}/empty directory failed."
197     echo "Cannot create ssh host configuration."
198     echo
199     exit 1
200   fi
201   if [ ${_nt} -gt 0 ]
202   then
203     chmod 755 ${LOCALSTATEDIR}/empty
204   fi
205 fi
206
207 # First generate host keys if not already existing
208
209 if [ ! -f "${SYSCONFDIR}/ssh_host_key" ]
210 then
211   echo "Generating ${SYSCONFDIR}/ssh_host_key"
212   ssh-keygen -t rsa1 -f ${SYSCONFDIR}/ssh_host_key -N '' > /dev/null
213 fi
214
215 if [ ! -f "${SYSCONFDIR}/ssh_host_rsa_key" ]
216 then
217   echo "Generating ${SYSCONFDIR}/ssh_host_rsa_key"
218   ssh-keygen -t rsa -f ${SYSCONFDIR}/ssh_host_rsa_key -N '' > /dev/null
219 fi
220
221 if [ ! -f "${SYSCONFDIR}/ssh_host_dsa_key" ]
222 then
223   echo "Generating ${SYSCONFDIR}/ssh_host_dsa_key"
224   ssh-keygen -t dsa -f ${SYSCONFDIR}/ssh_host_dsa_key -N '' > /dev/null
225 fi
226
227 # Check if ssh_config exists. If yes, ask for overwriting
228
229 if [ -f "${SYSCONFDIR}/ssh_config" ]
230 then
231   if request "Overwrite existing ${SYSCONFDIR}/ssh_config file?"
232   then
233     rm -f "${SYSCONFDIR}/ssh_config"
234     if [ -f "${SYSCONFDIR}/ssh_config" ]
235     then
236       echo "Can't overwrite. ${SYSCONFDIR}/ssh_config is write protected."
237     fi
238   fi
239 fi
240
241 # Create default ssh_config from skeleton file in /etc/defaults/etc
242
243 if [ ! -f "${SYSCONFDIR}/ssh_config" ]
244 then
245   echo "Generating ${SYSCONFDIR}/ssh_config file"
246   cp ${SYSCONFDIR}/defaults/etc/ssh_config ${SYSCONFDIR}/ssh_config
247   if [ "${port_number}" != "22" ]
248   then
249     echo "Host localhost" >> ${SYSCONFDIR}/ssh_config
250     echo "    Port ${port_number}" >> ${SYSCONFDIR}/ssh_config
251   fi
252 fi
253
254 # Check if sshd_config exists. If yes, ask for overwriting
255
256 if [ -f "${SYSCONFDIR}/sshd_config" ]
257 then
258   if request "Overwrite existing ${SYSCONFDIR}/sshd_config file?"
259   then
260     rm -f "${SYSCONFDIR}/sshd_config"
261     if [ -f "${SYSCONFDIR}/sshd_config" ]
262     then
263       echo "Can't overwrite. ${SYSCONFDIR}/sshd_config is write protected."
264     fi
265   else
266     grep -q UsePrivilegeSeparation ${SYSCONFDIR}/sshd_config && privsep_configured=yes
267   fi
268 fi
269
270 # Prior to creating or modifying sshd_config, care for privilege separation
271
272 if [ "${privsep_configured}" != "yes" ]
273 then
274   if [ ${_nt} -gt 0 ]
275   then
276     echo "Privilege separation is set to yes by default since OpenSSH 3.3."
277     echo "However, this requires a non-privileged account called 'sshd'."
278     echo "For more info on privilege separation read /usr/share/doc/openssh/README.privsep."
279     echo
280     if request "Should privilege separation be used?"
281     then
282       privsep_used=yes
283       grep -q '^sshd:' ${SYSCONFDIR}/passwd && sshd_in_passwd=yes
284       net user sshd >/dev/null 2>&1 && sshd_in_sam=yes
285       if [ "${sshd_in_passwd}" != "yes" ]
286       then
287         if [ "${sshd_in_sam}" != "yes" ]
288         then
289           echo "Warning: The following function requires administrator privileges!"
290           if request "Should this script create a local user 'sshd' on this machine?"
291           then
292             dos_var_empty=`cygpath -w ${LOCALSTATEDIR}/empty`
293             net user sshd /add /fullname:"sshd privsep" "/homedir:${dos_var_empty}" /active:no > /dev/null 2>&1 && sshd_in_sam=yes
294             if [ "${sshd_in_sam}" != "yes" ]
295             then
296               echo "Warning: Creating the user 'sshd' failed!"
297             fi
298           fi
299         fi
300         if [ "${sshd_in_sam}" != "yes" ]
301         then
302           echo "Warning: Can't create user 'sshd' in ${SYSCONFDIR}/passwd!"
303           echo "         Privilege separation set to 'no' again!"
304           echo "         Check your ${SYSCONFDIR}/sshd_config file!"
305           privsep_used=no
306         else
307           mkpasswd -l -u sshd | sed -e 's/bash$/false/' >> ${SYSCONFDIR}/passwd
308         fi
309       fi
310     else
311       privsep_used=no
312     fi
313   else
314     # On 9x don't use privilege separation.  Since security isn't
315     # available it just adds useless additional processes.
316     privsep_used=no
317   fi
318 fi
319
320 # Create default sshd_config from skeleton files in /etc/defaults/etc or
321 # modify to add the missing privsep configuration option
322
323 if [ ! -f "${SYSCONFDIR}/sshd_config" ]
324 then
325   echo "Generating ${SYSCONFDIR}/sshd_config file"
326   sed -e "s/^#UsePrivilegeSeparation yes/UsePrivilegeSeparation ${privsep_used}/
327           s/^#Port 22/Port ${port_number}/
328           s/^#StrictModes yes/StrictModes no/" \
329       < ${SYSCONFDIR}/defaults/etc/sshd_config \
330       > ${SYSCONFDIR}/sshd_config
331 elif [ "${privsep_configured}" != "yes" ]
332 then
333   echo >> ${SYSCONFDIR}/sshd_config
334   echo "UsePrivilegeSeparation ${privsep_used}" >> ${SYSCONFDIR}/sshd_config
335 fi
336
337 # Care for services file
338 _my_etcdir="/ssh-host-config.$$"
339 if [ ${_nt} -gt 0 ]
340 then
341   _win_etcdir="${SYSTEMROOT}\\system32\\drivers\\etc"
342   _services="${_my_etcdir}/services"
343   # On NT, 27 spaces, no space after the hash
344   _spaces="                           #"
345 else
346   _win_etcdir="${WINDIR}"
347   _services="${_my_etcdir}/SERVICES"
348   # On 9x, 18 spaces (95 is very touchy), a space after the hash
349   _spaces="                  # "
350 fi
351 _serv_tmp="${_my_etcdir}/srv.out.$$"
352
353 mount -t -f "${_win_etcdir}" "${_my_etcdir}"
354
355 # Depends on the above mount
356 _wservices=`cygpath -w "${_services}"`
357
358 # Remove sshd 22/port from services
359 if [ `grep -q 'sshd[ \t][ \t]*22' "${_services}"; echo $?` -eq 0 ]
360 then
361   grep -v 'sshd[ \t][ \t]*22' "${_services}" > "${_serv_tmp}"
362   if [ -f "${_serv_tmp}" ]
363   then
364     if mv "${_serv_tmp}" "${_services}"
365     then
366       echo "Removing sshd from ${_wservices}"
367     else
368       echo "Removing sshd from ${_wservices} failed!"
369     fi
370     rm -f "${_serv_tmp}"
371   else
372     echo "Removing sshd from ${_wservices} failed!"
373   fi
374 fi
375
376 # Add ssh 22/tcp  and ssh 22/udp to services
377 if [ `grep -q 'ssh[ \t][ \t]*22' "${_services}"; echo $?` -ne 0 ]
378 then
379   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}"
380   then
381     if mv "${_serv_tmp}" "${_services}"
382     then
383       echo "Added ssh to ${_wservices}"
384     else
385       echo "Adding ssh to ${_wservices} failed!"
386     fi
387     rm -f "${_serv_tmp}"
388   else
389     echo "WARNING: Adding ssh to ${_wservices} failed!"
390   fi
391 fi
392
393 umount "${_my_etcdir}"
394
395 # Care for inetd.conf file
396 _inetcnf="${SYSCONFDIR}/inetd.conf"
397 _inetcnf_tmp="${SYSCONFDIR}/inetd.conf.$$"
398
399 if [ -f "${_inetcnf}" ]
400 then
401   # Check if ssh service is already in use as sshd
402   with_comment=1
403   grep -q '^[ \t]*sshd' "${_inetcnf}" && with_comment=0
404   # Remove sshd line from inetd.conf
405   if [ `grep -q '^[# \t]*sshd' "${_inetcnf}"; echo $?` -eq 0 ]
406   then
407     grep -v '^[# \t]*sshd' "${_inetcnf}" >> "${_inetcnf_tmp}"
408     if [ -f "${_inetcnf_tmp}" ]
409     then
410       if mv "${_inetcnf_tmp}" "${_inetcnf}"
411       then
412         echo "Removed sshd from ${_inetcnf}"
413       else
414         echo "Removing sshd from ${_inetcnf} failed!"
415       fi
416       rm -f "${_inetcnf_tmp}"
417     else
418       echo "Removing sshd from ${_inetcnf} failed!"
419     fi
420   fi
421
422   # Add ssh line to inetd.conf
423   if [ `grep -q '^[# \t]*ssh' "${_inetcnf}"; echo $?` -ne 0 ]
424   then
425     if [ "${with_comment}" -eq 0 ]
426     then
427       echo 'ssh  stream  tcp     nowait  root    /usr/sbin/sshd sshd -i' >> "${_inetcnf}"
428     else
429       echo '# ssh  stream  tcp     nowait  root    /usr/sbin/sshd sshd -i' >> "${_inetcnf}"
430     fi
431     echo "Added ssh to ${_inetcnf}"
432   fi
433 fi
434
435 # On NT ask if sshd should be installed as service
436 if [ ${_nt} -gt 0 ]
437 then
438   # But only if it is not already installed
439   if ! cygrunsrv -Q sshd > /dev/null 2>&1
440   then
441     echo
442     echo
443     echo "Warning: The following functions require administrator privileges!"
444     echo
445     echo "Do you want to install sshd as service?"
446     if request "(Say \"no\" if it's already installed as service)"
447     then
448       if [ $_nt2003 -gt 0 ]
449       then
450         grep -q '^sshd_server:' ${SYSCONFDIR}/passwd && sshd_server_in_passwd=yes
451         if [ "${sshd_server_in_passwd}" = "yes" ]
452         then
453           # Drop sshd_server from passwd since it could have wrong settings
454           grep -v '^sshd_server:' ${SYSCONFDIR}/passwd > ${SYSCONFDIR}/passwd.$$
455           rm -f ${SYSCONFDIR}/passwd
456           mv ${SYSCONFDIR}/passwd.$$ ${SYSCONFDIR}/passwd
457           chmod g-w,o-w ${SYSCONFDIR}/passwd
458         fi
459         net user sshd_server >/dev/null 2>&1 && sshd_server_in_sam=yes
460         if [ "${sshd_server_in_sam}" != "yes" ]
461         then
462           echo
463           echo "You appear to be running Windows 2003 Server or later.  On 2003 and"
464           echo "later systems, it's not possible to use the LocalSystem account"
465           echo "if sshd should allow passwordless logon (e. g. public key authentication)."
466           echo "If you want to enable that functionality, it's required to create a new"
467           echo "account 'sshd_server' with special privileges, which is then used to run"
468           echo "the sshd service under."
469           echo
470           echo "Should this script create a new local account 'sshd_server' which has"
471           if request "the required privileges?"
472           then
473             _admingroup=`mkgroup -l | awk -F: '{if ( $2 == "S-1-5-32-544" ) print $1;}' `
474             if [ -z "${_admingroup}" ]
475             then
476               echo "mkgroup -l produces no group with SID S-1-5-32-544 (Local administrators group)."
477               exit 1
478             fi
479             dos_var_empty=`cygpath -w ${LOCALSTATEDIR}/empty`
480             while [ "${sshd_server_in_sam}" != "yes" ]
481             do
482               if [ -n "${password_value}" ]
483               then
484                 _password="${password_value}"
485                 # Allow to ask for password if first try fails
486                 password_value=""
487               else
488                 echo
489                 echo "Please enter a password for new user 'sshd_server'.  Please be sure that"
490                 echo "this password matches the password rules given on your system."
491                 echo -n "Entering no password will exit the configuration.  PASSWORD="
492                 read -e _password
493                 if [ -z "${_password}" ]
494                 then
495                   echo
496                   echo "Exiting configuration.  No user sshd_server has been created,"
497                   echo "no sshd service installed."
498                   exit 1
499                 fi
500               fi
501               net user sshd_server "${_password}" /add /fullname:"sshd server account" "/homedir:${dos_var_empty}" /yes > /tmp/nu.$$ 2>&1 && sshd_server_in_sam=yes
502               if [ "${sshd_server_in_sam}" != "yes" ]
503               then
504                 echo "Creating the user 'sshd_server' failed!  Reason:"
505                 cat /tmp/nu.$$
506                 rm /tmp/nu.$$
507               fi
508             done
509             net localgroup "${_admingroup}" sshd_server /add > /dev/null 2>&1 && sshd_server_in_admingroup=yes
510             if [ "${sshd_server_in_admingroup}" != "yes" ]
511             then
512               echo "WARNING: Adding user sshd_server to local group ${_admingroup} failed!"
513               echo "Please add sshd_server to local group ${_admingroup} before"
514               echo "starting the sshd service!"
515               echo
516             fi
517             passwd_has_expiry_flags=`passwd -v | awk '/^passwd /{print ( $3 >= 1.5 ) ? "yes" : "no";}'`
518             if [ "${passwd_has_expiry_flags}" != "yes" ]
519             then
520               echo
521               echo "WARNING: User sshd_server has password expiry set to system default."
522               echo "Please check that password never expires or set it to your needs."
523             elif ! passwd -e sshd_server
524             then
525               echo
526               echo "WARNING: Setting password expiry for user sshd_server failed!"
527               echo "Please check that password never expires or set it to your needs."
528             fi
529             editrights -a SeAssignPrimaryTokenPrivilege -u sshd_server &&
530             editrights -a SeCreateTokenPrivilege -u sshd_server &&
531             editrights -a SeTcbPrivilege -u sshd_server &&
532             editrights -a SeDenyInteractiveLogonRight -u sshd_server &&
533             editrights -a SeDenyNetworkLogonRight -u sshd_server &&
534             editrights -a SeDenyRemoteInteractiveLogonRight -u sshd_server &&
535             editrights -a SeIncreaseQuotaPrivilege -u sshd_server &&
536             editrights -a SeServiceLogonRight -u sshd_server &&
537             sshd_server_got_all_rights="yes"
538             if [ "${sshd_server_got_all_rights}" != "yes" ]
539             then
540               echo
541               echo "Assigning the appropriate privileges to user 'sshd_server' failed!"
542               echo "Can't create sshd service!"
543               exit 1
544             fi
545             echo
546             echo "User 'sshd_server' has been created with password '${_password}'."
547             echo "If you change the password, please keep in mind to change the password"
548             echo "for the sshd service, too."
549             echo
550             echo "Also keep in mind that the user sshd_server needs read permissions on all"
551             echo "users' .ssh/authorized_keys file to allow public key authentication for"
552             echo "these users!.  (Re-)running ssh-user-config for each user will set the"
553             echo "required permissions correctly."
554             echo
555           fi
556         fi
557         if [ "${sshd_server_in_sam}" = "yes" ]
558         then
559           mkpasswd -l -u sshd_server | sed -e 's/bash$/false/' >> ${SYSCONFDIR}/passwd
560         fi
561       fi
562       if [ -n "${cygwin_value}" ]
563       then
564         _cygwin="${cygwin_value}"
565       else
566         echo
567         echo "Which value should the environment variable CYGWIN have when"
568         echo "sshd starts? It's recommended to set at least \"ntsec\" to be"
569         echo "able to change user context without password."
570         echo -n "Default is \"ntsec\".  CYGWIN="
571         read -e _cygwin
572       fi
573       [ -z "${_cygwin}" ] && _cygwin="ntsec"
574       if [ $_nt2003 -gt 0 -a "${sshd_server_in_sam}" = "yes" ]
575       then
576         if cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd -a -D -u sshd_server -w "${_password}" -e "CYGWIN=${_cygwin}" -y tcpip
577         then
578           echo
579           echo "The service has been installed under sshd_server account."
580           echo "To start the service, call \`net start sshd' or \`cygrunsrv -S sshd'."
581         fi
582       else
583         if cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd -a -D -e "CYGWIN=${_cygwin}" -y tcpip
584         then
585           echo
586           echo "The service has been installed under LocalSystem account."
587           echo "To start the service, call \`net start sshd' or \`cygrunsrv -S sshd'."
588         fi
589       fi
590     fi
591     # Now check if sshd has been successfully installed.  This allows to
592     # set the ownership of the affected files correctly.
593     if cygrunsrv -Q sshd > /dev/null 2>&1
594     then
595       if [ $_nt2003 -gt 0 -a "${sshd_server_in_sam}" = "yes" ]
596       then
597         _user="sshd_server"
598       else
599         _user="system"
600       fi
601       chown "${_user}" ${SYSCONFDIR}/ssh*
602       chown "${_user}".544 ${LOCALSTATEDIR}/empty
603       chown "${_user}".544 ${LOCALSTATEDIR}/log/lastlog
604       if [ -f ${LOCALSTATEDIR}/log/sshd.log ]
605       then
606         chown "${_user}".544 ${LOCALSTATEDIR}/log/sshd.log
607       fi
608     fi
609     if ! ( mount | egrep -q 'on /(|usr/(bin|lib)) type system' )
610     then
611       echo
612       echo "Warning: It appears that you have user mode mounts (\"Just me\""
613       echo "chosen during install.)  Any daemons installed as services will"
614       echo "fail to function unless system mounts are used.  To change this,"
615       echo "re-run setup.exe and choose \"All users\"."
616       echo
617       echo "For more information, see http://cygwin.com/faq/faq0.html#TOC33"
618     fi
619   fi
620 fi
621
622 echo
623 echo "Host configuration finished. Have fun!"
This page took 0.074928 seconds and 3 git commands to generate.