#! /bin/sh # # Copyright (c) 2000-2002 SuSE GmbH Nuernberg, Germany. All rights reserved. # # Author: Marius Tomaschewski , 2000-2002 # # $Id: rc.script.in,v 1.2.2.2 2004/03/30 12:04:16 mt Exp $ # # etc/init.d/ftp-proxy -- LSB compliant(?) run level script # # see also ftp-proxy(8) and ftp-proxy.conf(5) manual pages. # ### BEGIN INIT INFO # Provides: ftp-proxy # Required-Start: $network $remote_fs $syslog $named # Required-Stop: # Default-Start: 3 5 # Default-Stop: 0 1 2 6 # Description: starts SuSE ftp-proxy ### END INIT INFO # # Return values acc. to LSB for all commands but status: # 0 - success # 1 - generic or unspecified error # 2 - invalid or excess argument(s) # 3 - unimplemented feature (e.g. "reload") # 4 - insufficient privilege # 5 - program is not installed # 6 - program is not configured # 7 - program is not running # # Note that starting an already running service, stopping # or restarting a not-running service as well as the restart # with force-reload (in case signalling is not supported) are # considered a success. # # default values... # FTP_PROXY_CAPS="no" FTP_PROXY_NAME="ftp-proxy" FTP_PROXY_BIN="@SBINDIR@/${FTP_PROXY_NAME}" FTP_PROXY_CFG="@SYSCONFDIR@/proxy-suite/${FTP_PROXY_NAME}.conf" # # common utils... # ldd="/usr/bin/ldd" awk="/bin/awk" grep="/bin/grep" logger="/bin/logger" compartment="/usr/sbin/compartment" LOGGER="${logger} -i -t ${FTP_PROXY_NAME}-boot" LOG_INF="${LOGGER} -p info" LOG_ERR="${LOGGER} -p err" # # handle SuSE systems < 8.x # if [ -f /etc/SuSE-release ] ; then while read line ; do if [ -z "${line%VERSION*}" ] ; then case "${line#VERSION = }" in [5-7]*) # Source SuSE rc.config . /etc/rc.config # SuSE < 8.0 uses START variables base=${0##*/} link=${base#*[SK][0-9][0-9]} [ $link = $base ] && START_FTP_PROXY=yes [ "$START_FTP_PROXY" = yes ] || exit 0 ;; *) # SuSE >= 8.0 uses sysconfig/NAME [ -f /etc/sysconfig/clock ] && \ . /etc/sysconfig/clock [ -f /etc/sysconfig/${FTP_PROXY_NAME} ] && \ . /etc/sysconfig/${FTP_PROXY_NAME} ;; esac fi done < /etc/SuSE-release fi # else use defaults ... # LSB compliant helper shell functions sourced from /etc/rc.status: # rc_check check and set local and overall rc status # rc_status check and set local and overall rc status # rc_status -v ditto but be verbose in local rc status # rc_status -v -r ditto and clear the local rc status # rc_failed set local and overall rc status to failed # rc_failed set local and overall rc status to # rc_reset clear local rc status (overall remains) # rc_exit exit appropriate to overall rc status # # I assume, the /etc/rc.status script is SuSE specific... # -> port this script or copy rc.status from SuSE system... # if [ -f /etc/rc.status ] ; then . /etc/rc.status else echo "$0: unable to find /etc/rc.status - you may port this script" 1>&2 exit 1 fi # # check if binary and config installed... # if [ ! -x "${FTP_PROXY_BIN}" ] ; then echo "$0: unable to find ftp-proxy binary: $FTP_PROXY_BIN" 1>&2 exit 5 fi if [ ! -f "${FTP_PROXY_CFG}" ] ; then echo "$0: unable to find ftp-proxy config: $FTP_PROXY_CFG" 1>&2 exit 6 fi # # check if we should use compartment # if [ "$FTP_PROXY_CAPS" = yes ] ; then [ -x "$compartment" ] || { echo "$0: unable to find compartment tool: $compartment" 1>&2 exit 5 } else compartment="" fi # # ftp-proxy.conf parsing function... # # remember: this script works case-sensitive, # the proxy-suite itself not... # read_config () { get_value () { key=${1} shift val=${@} echo "$key=\"$val\"" } if [ -n "$FTP_PROXY_CFG" ] && [ -f "$FTP_PROXY_CFG" ] ; then while read line ; do case "$line" in \#*|"") ;; AllowTransProxy*) eval $(get_value $line) # may be: yes, on, true, >0 case "${AllowTransProxy}" in [Yy]*|[Oo]*|[Tt]*|[1-9]*) AllowTransProxy="yes" ;; *) AllowTransProxy="no" ;; esac ;; LogDestination*) eval $(get_value $line) if [ "${LogDestination}" != ${LogDestination#|*} ] ; then echo "$0: unable to handle a pipe as LogDestination" 1>&2 return 1 fi ;; User*) eval $(get_value $line) ;; Group*) eval $(get_value $line) ;; PidFile*) eval $(get_value $line) ;; TCPWrapper*) eval $(get_value $line) ;; LDAPServer*) eval $(get_value $line) ;; ServerRoot*) eval $(get_value $line) ;; ServerType*) eval $(get_value $line) ;; DenyMessage*) eval $(get_value $line) ;; MaxClientsMessage*) eval $(get_value $line) ;; WelcomeMessage*) eval $(get_value $line) ;; *) ;; esac done < "$FTP_PROXY_CFG" return 0 else return 1 fi } mk_chroot () { dir_mode="-m0755" state_mode="0775" owner=${User:-root} group=${Group:-root} if [ -n "${ServerRoot}" ] ; then if [ ! -d "${ServerRoot}" ] ; then [ -e "${ServerRoot}" ] && rm -f "${ServerRoot}" $LOG_INF "creating missing ServerRoot directory '$ServerRoot'" mkdir -p $dir_mode "${ServerRoot}" || return 1 fi else $LOG_ERR "chroot directory not configured" return 1 fi cpifnewer () { for src in $1; do dst=$2/$(basename $src) if [ -e $src -a ! -f $src -a ! -L $src ]; then $LOG_INF "copying missing $dst" cp -fpR $src $dst || return 1 elif [ $src -nt $dst -o $src -ot $dst ]; then [ -e "$dst" ] && rm -f "$dst" $LOG_INF "updating $dst" cp -fp $src $dst || return 1 fi done return 0 } # # list of directories that should be writeable # STATE_DIR="" DIRS="dev etc lib usr/sbin usr/lib" # add config directory DIRS="$DIRS "$(dirname "$FTP_PROXY_CFG") # add message direcrories [ -n "$DenyMessage" ] && DIRS="$DIRS "$(dirname "$DenyMessage") [ -n "$WelcomeMessage" ] && DIRS="$DIRS "$(dirname "$WelcomeMessage") [ -n "$MaxClientsMessage" ] && DIRS="$DIRS "$(dirname "$MaxClientsMessage") # add Pid-Directory if [ -n "$PidFile" ] ; then dir=$(dirname "$PidFile") DIRS="$DIRS $dir" STATE_DIR="$STATE_DIR $dir" else DIRS="$DIRS var/run" STATE_DIR="$STATE_DIR var/run" fi # add Log-Directory if a log file is used... if [ -n "$LogDestination" ] && \ [ "${LogDestination}" != ${LogDestination#/*} ] ; then dir=$(dirname "$LogDestination") DIRS="$DIRS $dir" STATE_DIR="$STATE_DIR $dir" fi # ok, create the dirs [ -n "$DIRS" ] && for dir in $DIRS ; do [ -d "${ServerRoot}/${dir}" ] && continue [ -e "${ServerRoot}/${dir}" ] && rm -f "${ServerRoot}/${dir}" $LOG_INF "creating missing directory ${ServerRoot}/${dir}" mkdir -p $dir_mode "${ServerRoot}/${dir}" || return 1 done # make sure, state-dirs are writeable after cap's chroot [ -n "$STATE_DIR" ] && for dir in $STATE_DIR ; do chmod $state_mode "${ServerRoot}/${dir}" chown "$owner:$group" "${ServerRoot}/${dir}" done # create a null device if [ ! -c "${ServerRoot}/dev/null" ] ; then [ -e "${ServerRoot}/dev/null" ] && \ rm -f "${ServerRoot}/dev/null" $LOG_INF "creating missing device '${ServerRoot}/dev/null" cpifnewer /dev/null "${ServerRoot}/dev" || return 1 chmod 0666 "${ServerRoot}/dev/null" || return 1 fi # BSD: create ipnat/pf natlook device if needed if [ -n "$AllowTransProxy" ] && [ "$AllowTransProxy" = yes ] ; then if [ -c /dev/ipnat ] && [ ! -c "${ServerRoot}/dev/ipnat" ] ; then [ -e "${ServerRoot}/dev/ipnat" ] && \ rm -f "${ServerRoot}/dev/ipnat" $LOG_INF "creating missing device '${ServerRoot}/dev/ipnat" cpifnewer /dev/ipnat "${ServerRoot}/dev" || return 1 chmod 0440 "${ServerRoot}/dev/ipnat" || return 1 chown "$owner:$group" "${ServerRoot}/dev/ipnat" || return 1 fi if [ -c /dev/pf ] && [ ! -c "${ServerRoot}/dev/pf" ] ; then [ -e "${ServerRoot}/dev/pf" ] && \ rm -f "${ServerRoot}/dev/pf" $LOG_INF "creating missing device '${ServerRoot}/dev/pf" cpifnewer /dev/pf "${ServerRoot}/dev" || return 1 chmod 0440 "${ServerRoot}/dev/pf" || return 1 chown "$owner:$group" "${ServerRoot}/dev/pf" || return 1 fi fi # copy binaries BINS="$FTP_PROXY_BIN" [ -n "$BINS" ] && for bin in $BINS ; do if [ -n "$bin" ] && [ -x "$bin" ] ; then bdir=$(dirname $bin) if [ ! -d "${ServerRoot}/${bdir}" ] ; then [ -e "${ServerRoot}/${bdir}" ] && rm -f "${ServerRoot}/${bdir}" $LOG_INF "creating missing directory ${ServerRoot}/${bdir}" mkdir -p $dir_mode "${ServerRoot}/${bdir}" || return 1 fi cpifnewer "$bin" "${ServerRoot}/${bdir}" || return 1 # # copy all libs ldd says they are needed for the binary # LIB=$($ldd "$bin" 2> /dev/null | $grep -v "not "| $awk '{print$ 3}') for lib in $LIB ; do ldir=$(dirname $lib) if [ ! -d "${ServerRoot}/${ldir}" ] ; then [ -e "${ServerRoot}/${ldir}" ] && rm -f "${ServerRoot}/${ldir}" $LOG_INF "creating missing directory ${ServerRoot}/${ldir}" mkdir -p $dir_mode "${ServerRoot}/${ldir}" || return 1 fi cpifnewer "$lib" "${ServerRoot}/${ldir}" || return 1 done else $LOG_ERR "no such file or directory '$bin'" return 1 fi done # handle /etc/localtime link if [ -L /etc/localtime ]; then ZONEDIR="/usr/share/zoneinfo" ZONEDST="$ZONEDIR" [ -n "$TIMEZONE" ] || TIMEZONE=GMT if [ $(dirname "$TIMEZONE") != "." ] ; then ZONEDST="${ZONEDST}/"$(dirname "$TIMEZONE") fi [ -d "${ServerRoot}/${ZONEDST}" ] || \ mkdir -p $dir_mode "${ServerRoot}/${ZONEDST}" cpifnewer "${ZONEDIR}/${TIMEZONE}" "$ServerRoot/${ZONEDST}" ln -sf "../${ZONEDIR}/${TIMEZONE}" "${ServerRoot}/etc/localtime" else cpifnewer /etc/localtime "${ServerRoot}/etc" fi # copy proxy config if [ -f "$FTP_PROXY_CFG" ] ; then if [ -e "${ServerRoot}/${FTP_PROXY_CFG}" ] ; then rm -f "${ServerRoot}/${FTP_PROXY_CFG}" fi if [ -n "$compartment" ] ; then # # remove chroot-stuff compartment is used # while read line ; do case "$line" in \#*|"") ;; Group*) ;; User*) ;; ServerRoot*) ;; *) echo $line ;; esac done < "$FTP_PROXY_CFG" > "${ServerRoot}/${FTP_PROXY_CFG}" else cp -f "$FTP_PROXY_CFG" "${ServerRoot}/${FTP_PROXY_CFG}" fi fi if [ ! -f "${ServerRoot}/etc/ld.so.conf" ] ; then touch "${ServerRoot}/etc/ld.so.conf" fi CONF="/etc/host.conf /etc/resolv.conf /etc/hosts" CONF="$CONF /etc/services /etc/protocols" CONF="$CONF /etc/passwd /etc/group" [ -f /etc/nsswitch.conf ] && CONF="$CONF /etc/nsswitch.conf" if [ -n "$TCPWrapper" ] && [ "$TCPWrapper" = yes ] ; then CONF="$CONF /etc/hosts.allow /etc/hosts.deny" fi [ -n "$DenyMessage" ] && CONF="$CONF $DenyMessage" [ -n "$WelcomeMessage" ] && CONF="$CONF $WelcomeMessage" [ -n "$MaxClientsMessage" ] && CONF="$CONF $MaxClientsMessage" # copy/update (config) files [ -n "$CONF" ] && for cfg in $CONF ; do if [ -n "$cfg" ] && [ -f "$cfg" ] ; then cdir=$(dirname $cfg) if [ ! -d "${ServerRoot}/${cdir}" ] ; then [ -e "${ServerRoot}/${cdir}" ] && rm -f "${ServerRoot}/${cdir}" $LOG_INF "creating missing directory ${ServerRoot}/${cdir}" mkdir -p $dir_mode "${ServerRoot}/${cdir}" || return 1 fi cpifnewer "$cfg" "${ServerRoot}/${cdir}" || return 1 else $LOG_ERR "no such file or directory '$cfg'" return 1 fi done # copy/update nss libraries if [ -f /etc/nsswitch.conf ] ; then LIBS="/lib/libnss* /lib/libnsl* /lib/libresolv* /lib/libdb*" fi [ -n "$LIBS" ] && for lib in $LIBS ; do if [ -n "$lib" ] && [ -x "$lib" ] ; then ldir=$(dirname $lib) if [ ! -d "${ServerRoot}/${ldir}" ] ; then [ -e "${ServerRoot}/${ldir}" ] && rm -f "${ServerRoot}/${ldir}" $LOG_INF "creating missing directory ${ServerRoot}/${ldir}" mkdir -p $dir_mode "${ServerRoot}/${ldir}" || return 1 fi cpifnewer "$lib" "${ServerRoot}/${ldir}" || return 1 else $LOG_ERR "no such file or directory '$lib'" return 1 fi done # # rebuild /etc/ld.so.cache # ldconfig -X -r "${ServerRoot}" 2>&1 | $LOG_INF return 0 } # # mk_chroot call-helper # do_chroot () { # chroot is useless if daemon runs with UID 0... if [ -z "$User" ] ; then echo "$0: set the User variable in $FTP_PROXY_CFG" 1>&2 return 1 fi [ -x "$grep" -a -x "$logger" -a -x "$ldd" -a -x "$awk" ] || { echo "$0: unable to find all needed utilities" 1>&2 return 1 } # prepare/update chroot dir mk_chroot || return 1 # if syslog is used, a log socket should # be avaliable as ${ServerRoot}/dev/log if [ -n "${LogDestination}" ] && \ [ "${LogDestination}" = "${LogDestination#/*}" ] && \ [ ! -S "${ServerRoot}/dev/log" ] ; then echo "$0: add ${ServerRoot}/dev/log socket to syslog config" 2>&1 return 1 fi return 0 } # # initialize relevant config variables # User="" Group="" PidFile="" TCPWrapper="" LDAPServer="" ServerRoot="" ServerType="" LogDestination="" DenyMessage="" MaxClientsMessage="" WelcomeMessage="" # # read proxy configuration # read_config || exit 1 # reset status of this service rc_reset case "$1" in chroot) # prepare chroot... do_chroot || exit 1 ;; start) # check if daemon configured if [ "${ServerType}" != standalone ] ; then echo "$0: ServerType is not standalone in $FTP_PROXY_CFG" 1>&2 exit 1 fi # prepare/update chroot dir if used if [ -n "${ServerRoot}" ] ; then do_chroot || exit 1 fi if test -n "$compartment" ; then echo -n "Starting $FTP_PROXY_NAME (in ${ServerRoot})" [ -n $Group ] && chroot_group="--group $Group" PATH="/bin:/sbin:/usr/bin:/usr/sbin" \ $compartment --fork --cap CAP_NET_BIND_SERVICE \ --chroot "$ServerRoot" $chroot_group \ "${FTP_PROXY_BIN}" -f "${FTP_PROXY_CFG}" rc_status -v else if test -n "$ServerRoot" ; then echo -n "Starting $FTP_PROXY_NAME (in ${ServerRoot})" else echo -n "Starting $FTP_PROXY_NAME" fi startproc "$FTP_PROXY_BIN" -f "$FTP_PROXY_CFG" rc_status -v fi ;; stop) ## Stop the service echo -n "Shutting down $FTP_PROXY_NAME" [ -n "$compartment" -a -n "${ServerRoot}" ] || ServerRoot="" killproc -TERM "${ServerRoot}/${FTP_PROXY_BIN}" rc_status -v ;; try-restart) ## Stop the service and if this succeeds (i.e. ## the service was running before), start it again. ## Note: try-restart is not (yet) part of LSB (as of 0.7.5) $0 status >/dev/null && $0 restart rc_status ;; restart) ## Stop the service and regardless of whether it was ## running or not, start it again. $0 stop $0 start rc_status ;; force-reload) ## Signal the daemon to reload its config. ## If it does not support it, restart. echo -n "Reload the $FTP_PROXY_NAME configuration" [ -n "$compartment" -a -n "${ServerRoot}" ] || ServerRoot="" killproc -HUP "${ServerRoot}/${FTP_PROXY_BIN}" rc_status -v ;; reload) ## Like force-reload, but if daemon does not ## support signalling, do nothing (!) echo -n "Reload the $FTP_PROXY_NAME configuration" [ -n "$compartment" -a -n "${ServerRoot}" ] || ServerRoot="" killproc -HUP "${ServerRoot}/${FTP_PROXY_BIN}" rc_status -v ;; status) echo -n "Checking for $FTP_PROXY_NAME" ## Check status with checkproc(8), if process is running ## checkproc will return with exit status 0. [ -n "$compartment" -a -n "${ServerRoot}" ] || ServerRoot="" checkproc "${ServerRoot}/${FTP_PROXY_BIN}" rc_status -v ;; probe) ## Optional: Probe for the necessity of a reload, ## give out the argument which is required for a reload. [ -n "$compartment" -a -n "${ServerRoot}" ] || ServerRoot="" test "${ServerRoot}/${FTP_PROXY_CFG}" -nt \ "${ServerRoot}/${PidFile}" && echo reload ;; *) echo "Usage: $0 {start|stop|status|try-restart|restart|force-reload|reload|probe|chroot}" exit 1 ;; esac # Inform the caller not only verbosely and set an exit status. rc_exit