changed default value for NAT_INTERFACE_ from none to ""
[grml-terminalserver.git] / grml-terminalserver
1 #!/bin/sh
2 # Filename:      terminalserver
3 # Purpose:       Program to do something
4 # Authors:       grml-team (grml.org), (c) Michael Gebetsroither <gebi@grml.org>
5 # Bug-Reports:   see http://grml.org/bugs/
6 # License:       This file is licensed under the GPL v2.
7 # Latest change: Sat Aug 06 14:14:40 CEST 2005
8 ################################################################################
9
10
11 ###
12 ### __INCLUDES
13 ###
14 . /etc/grml/sh-lib
15 #. /etc/grml/sysexits-sh
16
17
18
19 ###
20 ### __VARIABLES
21 ###
22
23 FORCE_='false'
24 verbose_=0
25
26 # this file holds all variable definitions
27 SHARED_PROG_VARS_="/usr/share/grml-terminalserver/shared_prog_vars"
28 isExistent $SHARED_PROG_VARS_ die
29 . $SHARED_PROG_VARS_
30
31
32 ###
33 ### __FUNCTIONS
34 ###
35
36 function printUsage
37 {
38   cat <<EOT
39 Usage: "$PROG_NAME__" [OPTIONS] <command>
40
41 $PROG_NAME__ is the config program for the terminalserver
42 comming with grml.
43
44 COMMANDS:
45    help             This help text
46    start <service>  Start services (if all services are started, configs will be updated)
47    stop <service>   Stop services
48    config <service> Update config of given service (or from all if no services given)
49    clean            Stop all + remove config and boot files from services
50    <default>        interactive
51
52 SERVICES:
53   tftp        Tftp daemon
54   dhcp        Dhcp daemon
55   nfs         All necessary nfs daemons
56   <>          ALL services
57
58 OPTIONS:
59    -v         verbose (show what is going on, v++)
60    -h         this help text
61    -f         Force
62
63 EOT
64 }
65
66 function killPortmapper
67 {
68     /etc/init.d/portmap stop >/dev/null &>/dev/null
69     killall -9 portmap &>/dev/null
70 }
71
72 # DHCP SERVICE {{{
73 function createDhcpConf
74 {
75   if [ -e "$DHCPD_CONFIG_FILE_" ]; then
76     if grep $CONFIG_PATTERN_ $DHCPD_CONFIG_FILE_ &>/dev/null; then
77       execute "mv -fb \"$DHCPD_CONFIG_FILE_\" \"$DHCPD_CONFIG_FILE_.old\"" eprint &>/dev/null
78       execute "source $TEMPLATE_CONFIG_DIR_/dhcpd_config" die
79     else
80       if [[ $FORCE_ == "true" ]]; then
81         execute "mv -fb \"$DHCPD_CONFIG_FILE_\" \"$DHCPD_CONFIG_FILE_.old\"" eprint &>/dev/null
82         execute "source $TEMPLATE_CONFIG_DIR_/dhcpd_config" die
83       else
84         warn "Not updating user edited configfile $DHCPD_CONFIG_FILE_, user -f to override"
85       fi
86     fi
87   else
88     execute "source $TEMPLATE_CONFIG_DIR_/dhcpd_config" die
89   fi
90 }
91
92 function removeDhcpConf
93 {
94   if [ -e "$DHCPD_CONFIG_FILE_" ]; then
95     if grep $CONFIG_PATTERN_ $DHCPD_CONFIG_FILE_ &>/dev/null; then
96       rm -f "$DHCPD_CONFIG_FILE_"
97     else
98       if [[ $FORCE_ == "true" ]]; then
99         rm -f "$DHCPD_CONFIG_FILE_"
100       else
101         warn "Not deleting user edited configfile $DHCPD_CONFIG_FILE_, user -f to override"
102       fi
103     fi
104   fi
105 }
106
107
108 function stopDhcp
109 {
110   start-stop-daemon --stop --quiet --pidfile "$DHCPD_PID_"
111   rm -f $DHCPD_PID_
112   rm -f /var/lib/dhcp3/dhcpd.leases* 2>/dev/null    #FIXME
113   touch /var/lib/dhcp3/dhcpd.leases
114 }
115
116 function startDhcp
117 {
118   local conf_file_="$DHCPD_CONFIG_FILE_"
119
120   test -f $DHCPD_BIN_ || die "could not find dhcpd \"$DHCPD_BIN_\""
121   start-stop-daemon --start --quiet --pidfile "$DHCPD_PID_" \
122     --exec "$DHCPD_BIN_" -- -cf "$conf_file_" -q "$INTERFACE_" || warn "problems starting dhcpd"
123 }
124
125 function runDhcp
126 {
127   isExistent "$DHCPD_CONFIG_FILE_" || \
128     warn "no config for dhcpd: \"$DHCPD_CONFIG_FILE_\" => not starting dhcpd" || return 1
129
130   stopDhcp
131   sleep 1
132   startDhcp
133 }
134 # }}}
135
136 # IPTABLES {{{
137 function runIptables
138 {
139  if [ -x /sbin/iptables ] ; then
140     if [[ $NAT_INTERFACE_ != "" ]]; then
141        local nat_source_ip_=`netGetIp "$NAT_INTERFACE_" warn`
142
143        if iptables -t nat -vnL POSTROUTING | grep -q "SNAT.*${NAT_INTERFACE_}.*to:${nat_source_ip_}" ; then
144           echo "Rule for SNAT already present, nothing to be done."
145        else
146           echo "Setting up SNAT for terminalserver clients on ${NAT_INTERFACE_}:"
147           echo    "* iptables -t nat -F POSTROUTING"
148           echo -n "* iptables -t nat -A POSTROUTING -o $NAT_INTERFACE_ -j SNAT --to-source $nat_source_ip_ ... "
149           { iptables -t nat -F POSTROUTING && \
150             iptables -t nat -A POSTROUTING -o "$NAT_INTERFACE_" -j SNAT --to-source "$nat_source_ip_" ; } && \
151             echo done || echo failed
152        fi
153        if [ `cat /proc/sys/net/ipv4/ip_forward` -eq 1 ]; then
154           echo "IP-Forwarding already enabled, nothing to be done."
155        else
156           echo -n "Enabling IP-Forwarding: "
157           echo 1 > /proc/sys/net/ipv4/ip_forward && echo done || echo failed
158        fi
159     fi
160  else
161     warn "iptables executable not avilable"
162  fi
163 }
164 # }}}
165
166 # TFTP SERVICE {{{
167 function removeTftpConf
168 {
169   rm -rf $TFTPD_DATA_DIR_/*
170 }
171 function createTftpConf
172 {
173   removeTftpConf
174
175   execute "mkdir -p $TFTPD_DATA_DIR_/pxelinux.cfg" die
176   execute "install -m 644 /usr/lib/syslinux/pxelinux.0 $TFTPD_DATA_DIR_" die
177   execute "install -m 644 $PATH_/minirt26.gz $TFTPD_DATA_DIR_" die
178   execute "install -m 644 $KERNEL_IMAGE_ $TFTPD_DATA_DIR_/linux26" die
179   execute "install -m 644 $MEMTEST_IMAGE_ $TFTPD_DATA_DIR_/memtest" die
180   execute "install -m 644 $PXE_BOOT_MSG_ $TFTPD_DATA_DIR_" die
181   execute "install -m 644 $PXE_BOOT_LOGO_ $TFTPD_DATA_DIR_" die
182
183   execute "source $TEMPLATE_CONFIG_DIR_/grub-pxelinux_config" die
184 }
185
186 function stopTftp
187 {
188   start-stop-daemon --stop --quiet -p "$TFTPD_PID_"
189 }
190 function startTftp
191 {
192   test -f $TFTPD_BIN_ || die "could not find \"$TFTPD_BIN_\""
193   start-stop-daemon --start --quiet --exec "$TFTPD_BIN_" -- --daemon --no-multicast --pidfile "$TFTPD_PID_" --bind-address "$IP_" "$TFTPD_DATA_DIR_" || \
194     warn "problems starting tftpd server"
195 }
196 function runTftp
197 {
198   stopTftp
199   sleep 1
200   startTftp
201 }
202 # }}}
203
204
205 # NFS  {{{
206 function createNfsConfig
207 {
208   execute "exportfs -o ro,no_root_squash,async,nohide $NETWORK_/$NETMASK_:$MOUNT_POINT_" warn
209 }
210
211 function removeNfsConfig
212 {
213   execute "exportfs -u -o ro,no_root_squash,async,nohide $NETWORK_/$NETMASK_:$MOUNT_POINT_" warn
214 }
215
216 function startNfs
217 {
218   /etc/init.d/portmap start
219   /etc/init.d/nfs-common start
220   # FIXME /etc/init.d/nfs-kernel-server start
221   $USR_SHARE_/nfs-kernel-server start
222
223   createNfsConfig
224 }
225 function stopNfs
226 {
227   removeNfsConfig
228   if [[ `exportfs |wc -l` > 0 ]]; then
229     dprint "There are other exports, not stopping NFS serivces"
230   else
231     /etc/init.d/nfs-kernel-server stop >/dev/null 2>&1
232     /etc/init.d/nfs-common stop >/dev/null 2>&1
233     killPortmapper
234   fi
235 }
236 # }}}
237
238
239 function createConfig
240 {
241   # FIXME
242   execute "sed -i 's/^ALL/\#ALL/' /etc/hosts.deny" warn
243   execute "sed -i 's/^ALL : ALL@ALL : DENY/ALL : ALL@ALL : ALLOW/' /etc/hosts.allow" warn
244
245   createTftpConf
246   createDhcpConf
247 }
248
249 function actionStart
250 {
251   createConfig
252
253   echo -n "Starting tftpd: "
254   runTftp && echo done || echo failed
255
256   echo -n "Starting dhcpd: "
257   runDhcp && echo done || echo failed
258
259   #runIptables
260
261   echo "Finally starting nfs services..."
262   startNfs && echo "Sucessfully finished startup of grml-terminalserver." || echo 'Startup of grml-terminalserver-config failed!'
263 }
264
265 function actionStop
266 {
267   stopTftp
268   stopDhcp
269   stopNfs
270   notice "Terminal-server stopped"
271 }
272
273 function actionClean
274 {
275   actionStop
276   removeTftpConf
277   removeDhcpConf
278   stopNfs
279 }
280
281 function updateConfig
282 {
283   local service_="$1"
284
285   case "$service_" in
286     "") createConfig ;;
287     tftp) createTftpConf ;;
288     dhcp) createDhcpConf ;;
289     nfs) removeNfsConfig; createNfsConfig ;;
290     *) warn "Service $service_ not available" ;;
291   esac
292 }
293
294 # SERVICES {{{
295 function serviceStart
296 {
297   local service_="$1"   # service to start, if nothing => all
298
299   case "$service_" in
300     "") actionStart ;;
301     tftp) runTftp ;;
302     dhcp) runDhcp ;;
303     nfs) startNfs ;;
304     *) warn "Service $service_ not available" ;;
305   esac
306 }
307
308 function serviceStop
309 {
310   local service_="$1"   # service to stop, if nothing => all
311
312   case "$service_" in
313     "") actionStop ;;
314     tftp) stopTftp ;;
315     dhcp) stopDhcp ;;
316     nfs) stopNfs ;;
317     *) warn "Service $service_ not available" ;;
318   esac
319 }
320 # }}}
321
322 ###
323 ### __MAIN
324 ###
325
326 while getopts "fi:hv" opt; do
327   case "$opt" in
328     f) FORCE_='true' ;;
329     h) printUsage; exit ;;
330     v) let verbose_=$verbose_+1 ;;
331     ?) printUsage; exit 64 ;;
332   esac
333 done
334 shift $(($OPTIND - 1))  # set ARGV to the first not parsed commandline parameter
335 setVerbose $verbose_
336
337 case "$1" in
338   help)   printUsage; exit 0 ;;
339 esac
340
341 checkRoot die "You have to be root to use this program"
342 disableSyslog
343
344 isExistent $DEFAULT_CONFIG_ die
345 . $DEFAULT_CONFIG_
346 . $CONFIG_
347 # used config vars:
348 # MOUNT_POINT_
349 # KERNEL_IMAGE_
350 # MEMTEST_IMAGE_
351 # PXE_BOOT_MSG_
352 # PXE_BOOT_LOGO_
353 if [[ $MOUNT_POINT_ == "" || $KERNEL_IMAGE_ == "" || $MEMTEST_IMAGE_ == "" || \
354   $PXE_BOOT_MSG_ == "" || $PXE_BOOT_MSG_ == "" ]]; then
355   warn "MOUNT_POINT_=\"$MOUNT_POINT_\" \
356 KERNEL_IMAGE_=\"$KERNEL_IMAGE_\" \
357 MEMTEST_IMAGE_=\"$MEMTEST_IMAGE_\"
358 PXE_BOOT_MSG_=\"$PXE_BOOT_MSG_\"
359 PXE_BOOT_LOGO_=\"$PXE_BOOT_LOGO_\""
360   die "False configuration, please update $CONFIG_"
361 fi
362
363 case "$1" in
364   clean) actionClean; exit 0 ;;
365 esac
366
367
368 while true; do
369   isExistent "$CONF_FILE_" warn "sorry configfile \"$CONF_FILE_\" not found"
370   if [ $? -eq 1 ]; then
371     $CONFIG_PROG_ && continue
372     $DIALOG_ --clear --backtitle "$BACK_TITLE_" --title "Question" --yesno \
373       "grml-terminalserver-config returned an error, do you want to quit now?" 5 75 && exit 1
374   else
375     break
376   fi
377 done
378 source $CONF_FILE_
379
380 # check for necessary files
381 check_necessary_files_='no'
382 if [ "$1" == 'start' ]; then
383   case "$2" in
384     tftp|"") check_necessary_files_='yes' ;;
385   esac
386 fi
387 if [ $check_necessary_files_ == 'yes' ]; then
388   # test for files absolutly necessary for grml-terminalserver and created from -config
389   problem_=0
390   for i in $PATH_/minirt26.gz; do
391     isExistent $i warn || problem_=1
392   done
393   if [ $problem_ -eq 1 ]; then
394     die 'Some necessary files are missing, please rerun grml-terminalserver-config, or copy the files manually'
395   fi
396 fi
397
398
399 case "$1" in
400   start) serviceStart "$2" ;;
401   stop) serviceStop "$2" ;;
402   config) updateConfig "$2" ;;
403   "")  actionStart ;;
404   *)  printUsage ;;
405 esac
406
407 # END OF FILE
408 ################################################################################
409 # vim:foldmethod=marker tabstop=2 expandtab shiftwidth=2