]> andersk Git - gssapi-openssh.git/blob - openssh/contrib/cygwin/ssh-host-config
e2ad69f19f81146d58d2fdc229781a67b036ffd7
[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} is existant but 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 is existant but 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 [ -f ${LOCALSTATEDIR}/empty ]
185 then
186   echo "Creating ${LOCALSTATEDIR}/empty failed!"
187 else
188   mkdir -p ${LOCALSTATEDIR}/empty
189   if [ ${_nt} -gt 0 ]
190   then
191     chmod 755 ${LOCALSTATEDIR}/empty
192   fi
193 fi
194
195 # First generate host keys if not already existing
196
197 if [ ! -f "${SYSCONFDIR}/ssh_host_key" ]
198 then
199   echo "Generating ${SYSCONFDIR}/ssh_host_key"
200   ssh-keygen -t rsa1 -f ${SYSCONFDIR}/ssh_host_key -N '' > /dev/null
201 fi
202
203 if [ ! -f "${SYSCONFDIR}/ssh_host_rsa_key" ]
204 then
205   echo "Generating ${SYSCONFDIR}/ssh_host_rsa_key"
206   ssh-keygen -t rsa -f ${SYSCONFDIR}/ssh_host_rsa_key -N '' > /dev/null
207 fi
208
209 if [ ! -f "${SYSCONFDIR}/ssh_host_dsa_key" ]
210 then
211   echo "Generating ${SYSCONFDIR}/ssh_host_dsa_key"
212   ssh-keygen -t dsa -f ${SYSCONFDIR}/ssh_host_dsa_key -N '' > /dev/null
213 fi
214
215 # Check if ssh_config exists. If yes, ask for overwriting
216
217 if [ -f "${SYSCONFDIR}/ssh_config" ]
218 then
219   if request "Overwrite existing ${SYSCONFDIR}/ssh_config file?"
220   then
221     rm -f "${SYSCONFDIR}/ssh_config"
222     if [ -f "${SYSCONFDIR}/ssh_config" ]
223     then
224       echo "Can't overwrite. ${SYSCONFDIR}/ssh_config is write protected."
225     fi
226   fi
227 fi
228
229 # Create default ssh_config from skeleton file in /etc/defaults/etc
230
231 if [ ! -f "${SYSCONFDIR}/ssh_config" ]
232 then
233   echo "Generating ${SYSCONFDIR}/ssh_config file"
234   cp ${SYSCONFDIR}/defaults/etc/ssh_config ${SYSCONFDIR}/ssh_config
235   if [ "${port_number}" != "22" ]
236   then
237     echo "Host localhost" >> ${SYSCONFDIR}/ssh_config
238     echo "    Port ${port_number}" >> ${SYSCONFDIR}/ssh_config
239   fi
240 fi
241
242 # Check if sshd_config exists. If yes, ask for overwriting
243
244 if [ -f "${SYSCONFDIR}/sshd_config" ]
245 then
246   if request "Overwrite existing ${SYSCONFDIR}/sshd_config file?"
247   then
248     rm -f "${SYSCONFDIR}/sshd_config"
249     if [ -f "${SYSCONFDIR}/sshd_config" ]
250     then
251       echo "Can't overwrite. ${SYSCONFDIR}/sshd_config is write protected."
252     fi
253   else
254     grep -q UsePrivilegeSeparation ${SYSCONFDIR}/sshd_config && privsep_configured=yes
255   fi
256 fi
257
258 # Prior to creating or modifying sshd_config, care for privilege separation
259
260 if [ "${privsep_configured}" != "yes" ]
261 then
262   if [ ${_nt} -gt 0 ]
263   then
264     echo "Privilege separation is set to yes by default since OpenSSH 3.3."
265     echo "However, this requires a non-privileged account called 'sshd'."
266     echo "For more info on privilege separation read /usr/share/doc/openssh/README.privsep."
267     echo
268     if request "Should privilege separation be used?"
269     then
270       privsep_used=yes
271       grep -q '^sshd:' ${SYSCONFDIR}/passwd && sshd_in_passwd=yes
272       net user sshd >/dev/null 2>&1 && sshd_in_sam=yes
273       if [ "${sshd_in_passwd}" != "yes" ]
274       then
275         if [ "${sshd_in_sam}" != "yes" ]
276         then
277           echo "Warning: The following function requires administrator privileges!"
278           if request "Should this script create a local user 'sshd' on this machine?"
279           then
280             dos_var_empty=`cygpath -w ${LOCALSTATEDIR}/empty`
281             net user sshd /add /fullname:"sshd privsep" "/homedir:${dos_var_empty}" /active:no > /dev/null 2>&1 && sshd_in_sam=yes
282             if [ "${sshd_in_sam}" != "yes" ]
283             then
284               echo "Warning: Creating the user 'sshd' failed!"
285             fi
286           fi
287         fi
288         if [ "${sshd_in_sam}" != "yes" ]
289         then
290           echo "Warning: Can't create user 'sshd' in ${SYSCONFDIR}/passwd!"
291           echo "         Privilege separation set to 'no' again!"
292           echo "         Check your ${SYSCONFDIR}/sshd_config file!"
293           privsep_used=no
294         else
295           mkpasswd -l -u sshd | sed -e 's/bash$/false/' >> ${SYSCONFDIR}/passwd
296         fi
297       fi
298     else
299       privsep_used=no
300     fi
301   else
302     # On 9x don't use privilege separation.  Since security isn't
303     # available it just adds useless additional processes.
304     privsep_used=no
305   fi
306 fi
307
308 # Create default sshd_config from skeleton files in /etc/defaults/etc or
309 # modify to add the missing privsep configuration option
310
311 if [ ! -f "${SYSCONFDIR}/sshd_config" ]
312 then
313   echo "Generating ${SYSCONFDIR}/sshd_config file"
314   sed -e "s/^#UsePrivilegeSeparation yes/UsePrivilegeSeparation ${privsep_used}/
315           s/^#Port 22/Port ${port_number}/
316           s/^#StrictModes yes/StrictModes no/" \
317       < ${SYSCONFDIR}/defaults/etc/sshd_config \
318       > ${SYSCONFDIR}/sshd_config
319 elif [ "${privsep_configured}" != "yes" ]
320 then
321   echo >> ${SYSCONFDIR}/sshd_config
322   echo "UsePrivilegeSeparation ${privsep_used}" >> ${SYSCONFDIR}/sshd_config
323 fi
324
325 # Care for services file
326 _my_etcdir="/ssh-host-config.$$"
327 if [ ${_nt} -gt 0 ]
328 then
329   _win_etcdir="${SYSTEMROOT}\\system32\\drivers\\etc"
330   _services="${_my_etcdir}/services"
331   # On NT, 27 spaces, no space after the hash
332   _spaces="                           #"
333 else
334   _win_etcdir="${WINDIR}"
335   _services="${_my_etcdir}/SERVICES"
336   # On 9x, 18 spaces (95 is very touchy), a space after the hash
337   _spaces="                  # "
338 fi
339 _serv_tmp="${_my_etcdir}/srv.out.$$"
340
341 mount -t -f "${_win_etcdir}" "${_my_etcdir}"
342
343 # Depends on the above mount
344 _wservices=`cygpath -w "${_services}"`
345
346 # Remove sshd 22/port from services
347 if [ `grep -q 'sshd[ \t][ \t]*22' "${_services}"; echo $?` -eq 0 ]
348 then
349   grep -v 'sshd[ \t][ \t]*22' "${_services}" > "${_serv_tmp}"
350   if [ -f "${_serv_tmp}" ]
351   then
352     if mv "${_serv_tmp}" "${_services}"
353     then
354       echo "Removing sshd from ${_wservices}"
355     else
356       echo "Removing sshd from ${_wservices} failed!"
357     fi
358     rm -f "${_serv_tmp}"
359   else
360     echo "Removing sshd from ${_wservices} failed!"
361   fi
362 fi
363
364 # Add ssh 22/tcp  and ssh 22/udp to services
365 if [ `grep -q 'ssh[ \t][ \t]*22' "${_services}"; echo $?` -ne 0 ]
366 then
367   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}"
368   then
369     if mv "${_serv_tmp}" "${_services}"
370     then
371       echo "Added ssh to ${_wservices}"
372     else
373       echo "Adding ssh to ${_wservices} failed!"
374     fi
375     rm -f "${_serv_tmp}"
376   else
377     echo "WARNING: Adding ssh to ${_wservices} failed!"
378   fi
379 fi
380
381 umount "${_my_etcdir}"
382
383 # Care for inetd.conf file
384 _inetcnf="${SYSCONFDIR}/inetd.conf"
385 _inetcnf_tmp="${SYSCONFDIR}/inetd.conf.$$"
386
387 if [ -f "${_inetcnf}" ]
388 then
389   # Check if ssh service is already in use as sshd
390   with_comment=1
391   grep -q '^[ \t]*sshd' "${_inetcnf}" && with_comment=0
392   # Remove sshd line from inetd.conf
393   if [ `grep -q '^[# \t]*sshd' "${_inetcnf}"; echo $?` -eq 0 ]
394   then
395     grep -v '^[# \t]*sshd' "${_inetcnf}" >> "${_inetcnf_tmp}"
396     if [ -f "${_inetcnf_tmp}" ]
397     then
398       if mv "${_inetcnf_tmp}" "${_inetcnf}"
399       then
400         echo "Removed sshd from ${_inetcnf}"
401       else
402         echo "Removing sshd from ${_inetcnf} failed!"
403       fi
404       rm -f "${_inetcnf_tmp}"
405     else
406       echo "Removing sshd from ${_inetcnf} failed!"
407     fi
408   fi
409
410   # Add ssh line to inetd.conf
411   if [ `grep -q '^[# \t]*ssh' "${_inetcnf}"; echo $?` -ne 0 ]
412   then
413     if [ "${with_comment}" -eq 0 ]
414     then
415       echo 'ssh  stream  tcp     nowait  root    /usr/sbin/sshd sshd -i' >> "${_inetcnf}"
416     else
417       echo '# ssh  stream  tcp     nowait  root    /usr/sbin/sshd sshd -i' >> "${_inetcnf}"
418     fi
419     echo "Added ssh to ${_inetcnf}"
420   fi
421 fi
422
423 # On NT ask if sshd should be installed as service
424 if [ ${_nt} -gt 0 ]
425 then
426   # But only if it is not already installed
427   if ! cygrunsrv -Q sshd > /dev/null 2>&1
428   then
429     echo
430     echo
431     echo "Warning: The following functions require administrator privileges!"
432     echo
433     echo "Do you want to install sshd as service?"
434     if request "(Say \"no\" if it's already installed as service)"
435     then
436       if [ $_nt2003 -gt 0 ]
437       then
438         grep -q '^sshd_server:' ${SYSCONFDIR}/passwd && sshd_server_in_passwd=yes
439         if [ "${sshd_server_in_passwd}" = "yes" ]
440         then
441           # Drop sshd_server from passwd since it could have wrong settings
442           grep -v '^sshd_server:' ${SYSCONFDIR}/passwd > ${SYSCONFDIR}/passwd.$$
443           rm -f ${SYSCONFDIR}/passwd
444           mv ${SYSCONFDIR}/passwd.$$ ${SYSCONFDIR}/passwd
445           chmod g-w,o-w ${SYSCONFDIR}/passwd
446         fi
447         net user sshd_server >/dev/null 2>&1 && sshd_server_in_sam=yes
448         if [ "${sshd_server_in_sam}" != "yes" ]
449         then
450           echo
451           echo "You appear to be running Windows 2003 Server or later.  On 2003 and"
452           echo "later systems, it's not possible to use the LocalSystem account"
453           echo "if sshd should allow passwordless logon (e. g. public key authentication)."
454           echo "If you want to enable that functionality, it's required to create a new"
455           echo "account 'sshd_server' with special privileges, which is then used to run"
456           echo "the sshd service under."
457           echo
458           echo "Should this script create a new local account 'sshd_server' which has"
459           if request "the required privileges?"
460           then
461             _admingroup=`mkgroup -l | awk -F: '{if ( $2 == "S-1-5-32-544" ) print $1;}' `
462             if [ -z "${_admingroup}" ]
463             then
464               echo "mkgroup -l produces no group with SID S-1-5-32-544 (Local administrators group)."
465               exit 1
466             fi
467             dos_var_empty=`cygpath -w ${LOCALSTATEDIR}/empty`
468             while [ "${sshd_server_in_sam}" != "yes" ]
469             do
470               if [ -n "${password_value}" ]
471               then
472                 _password="${password_value}"
473                 # Allow to ask for password if first try fails
474                 password_value=""
475               else
476                 echo
477                 echo "Please enter a password for new user 'sshd_server'.  Please be sure that"
478                 echo "this password matches the password rules given on your system."
479                 echo -n "Entering no password will exit the configuration.  PASSWORD="
480                 read -e _password
481                 if [ -z "${_password}" ]
482                 then
483                   echo
484                   echo "Exiting configuration.  No user sshd_server has been created,"
485                   echo "no sshd service installed."
486                   exit 1
487                 fi
488               fi
489               net user sshd_server "${_password}" /add /fullname:"sshd server account" "/homedir:${dos_var_empty}" /yes > /tmp/nu.$$ 2>&1 && sshd_server_in_sam=yes
490               if [ "${sshd_server_in_sam}" != "yes" ]
491               then
492                 echo "Creating the user 'sshd_server' failed!  Reason:"
493                 cat /tmp/nu.$$
494                 rm /tmp/nu.$$
495               fi
496             done
497             net localgroup "${_admingroup}" sshd_server /add > /dev/null 2>&1 && sshd_server_in_admingroup=yes
498             if [ "${sshd_server_in_admingroup}" != "yes" ]
499             then
500               echo "WARNING: Adding user sshd_server to local group ${_admingroup} failed!"
501               echo "Please add sshd_server to local group ${_admingroup} before"
502               echo "starting the sshd service!"
503               echo
504             fi
505             passwd_has_expiry_flags=`passwd -v | awk '/^passwd /{print ( $3 >= 1.5 ) ? "yes" : "no";}'`
506             if [ "${passwd_has_expiry_flags}" != "yes" ]
507             then
508               echo
509               echo "WARNING: User sshd_server has password expiry set to system default."
510               echo "Please check that password never expires or set it to your needs."
511             elif ! passwd -e sshd_server
512             then
513               echo
514               echo "WARNING: Setting password expiry for user sshd_server failed!"
515               echo "Please check that password never expires or set it to your needs."
516             fi
517             editrights -a SeAssignPrimaryTokenPrivilege -u sshd_server &&
518             editrights -a SeCreateTokenPrivilege -u sshd_server &&
519             editrights -a SeTcbPrivilege -u sshd_server &&
520             editrights -a SeDenyInteractiveLogonRight -u sshd_server &&
521             editrights -a SeDenyNetworkLogonRight -u sshd_server &&
522             editrights -a SeDenyRemoteInteractiveLogonRight -u sshd_server &&
523             editrights -a SeIncreaseQuotaPrivilege -u sshd_server &&
524             editrights -a SeServiceLogonRight -u sshd_server &&
525             sshd_server_got_all_rights="yes"
526             if [ "${sshd_server_got_all_rights}" != "yes" ]
527             then
528               echo
529               echo "Assigning the appropriate privileges to user 'sshd_server' failed!"
530               echo "Can't create sshd service!"
531               exit 1
532             fi
533             echo
534             echo "User 'sshd_server' has been created with password '${_password}'."
535             echo "If you change the password, please keep in mind to change the password"
536             echo "for the sshd service, too."
537             echo
538             echo "Also keep in mind that the user sshd_server needs read permissions on all"
539             echo "users' .ssh/authorized_keys file to allow public key authentication for"
540             echo "these users!.  (Re-)running ssh-user-config for each user will set the"
541             echo "required permissions correctly."
542             echo
543           fi
544         fi
545         if [ "${sshd_server_in_sam}" = "yes" ]
546         then
547           mkpasswd -l -u sshd_server | sed -e 's/bash$/false/' >> ${SYSCONFDIR}/passwd
548         fi
549       fi
550       if [ -n "${cygwin_value}" ]
551       then
552         _cygwin="${cygwin_value}"
553       else
554         echo
555         echo "Which value should the environment variable CYGWIN have when"
556         echo "sshd starts? It's recommended to set at least \"ntsec\" to be"
557         echo "able to change user context without password."
558         echo -n "Default is \"ntsec\".  CYGWIN="
559         read -e _cygwin
560       fi
561       [ -z "${_cygwin}" ] && _cygwin="ntsec"
562       if [ $_nt2003 -gt 0 -a "${sshd_server_in_sam}" = "yes" ]
563       then
564         if cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd -a -D -u sshd_server -w "${_password}" -e "CYGWIN=${_cygwin}" -y tcpip
565         then
566           echo
567           echo "The service has been installed under sshd_server account."
568           echo "To start the service, call \`net start sshd' or \`cygrunsrv -S sshd'."
569         fi
570       else
571         if cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd -a -D -e "CYGWIN=${_cygwin}" -y tcpip
572         then
573           echo
574           echo "The service has been installed under LocalSystem account."
575           echo "To start the service, call \`net start sshd' or \`cygrunsrv -S sshd'."
576         fi
577       fi
578     fi
579     # Now check if sshd has been successfully installed.  This allows to
580     # set the ownership of the affected files correctly.
581     if cygrunsrv -Q sshd > /dev/null 2>&1
582     then
583       if [ $_nt2003 -gt 0 -a "${sshd_server_in_sam}" = "yes" ]
584       then
585         _user="sshd_server"
586       else
587         _user="system"
588       fi
589       chown "${_user}" ${SYSCONFDIR}/ssh*
590       chown "${_user}".544 ${LOCALSTATEDIR}/empty
591       chown "${_user}".544 ${LOCALSTATEDIR}/log/lastlog
592       if [ -f ${LOCALSTATEDIR}/log/sshd.log ]
593       then
594         chown "${_user}".544 ${LOCALSTATEDIR}/log/sshd.log
595       fi
596     fi
597     if ! ( mount | egrep -q 'on /(|usr/(bin|lib)) type system' )
598     then
599       echo
600       echo "Warning: It appears that you have user mode mounts (\"Just me\""
601       echo "chosen during install.)  Any daemons installed as services will"
602       echo "fail to function unless system mounts are used.  To change this,"
603       echo "re-run setup.exe and choose \"All users\"."
604       echo
605       echo "For more information, see http://cygwin.com/faq/faq0.html#TOC33"
606     fi
607   fi
608 fi
609
610 echo
611 echo "Host configuration finished. Have fun!"
This page took 0.323575 seconds and 3 git commands to generate.