Dodatne ispravke vezano za provjeru ispravnosti konfiguracije.
[xinetd-cn.git] / debian / postinst
index 8c2f033..7e01fae 100644 (file)
@@ -12,89 +12,140 @@ PKG=xinetd-cn
 CONF=/etc/xinetd.conf
 INETDCONF=/etc/inetd.conf
 DEFAULT=/etc/default/xinetd
+BACKUPDIR=/var/backups/xinetd-cn
 
-did_inetd_backup=0
-did_backup=0
 need_restart=0
+temp_files=
+xinetd_conf_did=0
 
-# First, we do backup (inetd, xinetd)
+# cleanup()
 #
-if cp_check_and_backup "$INETDCONF"; then
-       did_inetd_backup=1
-fi
-if cp_check_and_backup "$CONF"; then
-       did_backup=1
-fi
+#   Cleanup all temp files.
+#
+cleanup () {
+
+       local item
+       if [ -n "$temp_files" ]; then
+               for item in $temp_files; do
+                       if [ -e "$item" ]; then
+                               rm -f $item
+                       fi
+               done
+       fi
+}
+
+# backup_and_disable_service()
+#
+#   Backup and disable service with invalid configuration.
+#   Arguments:  service, services_file
+#
+backup_and_disable_service () {
+
+       local serv servfile out
+       serv="$1"
+       servfile="$2"
+
+       if cp_backup_conffile -r -d $BACKUPDIR -p /etc/xinetd.d/$servfile; then
+               cp_echo "CN: Old /etc/xinetd.d/$servfile saved as $BACKUPDIR/`basename /etc/xinetd.d/$servfile`.bak."
+       fi
+
+       cp_echo "CN: Disabling service '$serv' in configuration file /etc/xinetd.d/$servfile."
+
+       out=`mktemp /etc/xinetd.d/$servfile.tmp.XXXXXX`
+       temp_files="$temp_files $out"
+
+       sed -r "/^[[:space:]]*service[[:space:]]+$serv[[:space:]]*$/,/^}/ s/^(.*)/#\1/" \
+               /etc/xinetd.d/$servfile > $out
+       rm -f /etc/xinetd.d/$servfile
+       mv "$out" "/etc/xinetd.d/$servfile"
+       chmod 644 "/etc/xinetd.d/$servfile"
+}
 
-# Print backup information
+# Set trap for deleting all temp files.
 #
-cp_echo ""
-if [ $did_inetd_backup -eq 1 ]; then
-       cp_echo "CN: Old $INETDCONF saved as /var/backups/`basename $INETDCONF`.bak."
+trap cleanup 0 1 2 15
+
+# First, we do backup (inetd, xinetd)
+#
+if cp_backup_conffile -r -d $BACKUPDIR -p $INETDCONF; then
+       cp_echo "CN: Old $INETDCONF saved as $BACKUPDIR/`basename $INETDCONF`.bak."
 fi
-if [ $did_backup -eq 1 ]; then
-       cp_echo "CN: Old $CONF saved as /var/backups/`basename $CONF`.bak."
+if cp_backup_conffile -r -d $BACKUPDIR -p $CONF; then
+       cp_echo "CN: Old $CONF saved as $BACKUPDIR/`basename $CONF`.bak."
 fi
 
-# If there are some services enabled in /etc/inetd.conf, convert them to
-# temporary xinetd configuration file.
-#
-[ -f "$DEFAULT" ] && inetd_compat="`grep '^XINETD_OPTS.*=.*\-inetd_compat' "$DEFAULT"`" || true
 CONFTMP=`mktemp $CONF.tmp.XXXXXX`
+temp_files="$CONFTMP"
 
-if [ -f "$INETDCONF" ] && [ -n "$inetd_compat" ]; then
+if [ -f "$INETDCONF" ]; then
 
        # Convert inetd.conf to temporary xinetd.conf file using xconv.pl tool
-       /usr/sbin/xconv.pl < $INETDCONF > $CONFTMP
+       egrep -v "^#<off>#" $INETDCONF | /usr/sbin/xconv.pl > $CONFTMP || true
 fi
 
 # Parse /etc/xinetd.conf file and convert services' configuration to
 # separated configurations in /etc/xinetd.d/ directory
 #
-services_list="`cat $CONF $CONFTMP | grep "^service " | uniq | sed 's/service //g'`" || true
+conffile_list="$CONFTMP"
+if [ -f "$CONF" ]; then
+       if egrep -q "^[[:space:]]*service[[:space:]]+" "$CONF"; then
+               conffile_list="$CONF $conffile_list"
+               xinetd_conf_did=1
+       fi
+fi
+services_list="`sed -nr 's/^[[:space:]]*service[[:space:]]+//p' $conffile_list | uniq`"
 
 if [ -n "$services_list" ]; then
+
     for service in $services_list; do
 
        if [ -f "/etc/xinetd.d/$service" ]; then
-               cp_check_and_backup "/etc/xinetd.d/$service"
-               
-               if ! egrep -q "^# .* update by CARNet package" "/etc/xinetd.d/$service"; then
-                       rm -f /etc/xinetd.d/$service
+
+               if cp_backup_conffile -r -d $BACKUPDIR -p /etc/xinetd.d/$service; then
+                       cp_echo "CN: Old /etc/xinetd.d/$service saved as $BACKUPDIR/`basename /etc/xinetd.d/$service`.bak."
                fi
+
+               rm -f /etc/xinetd.d/$service
        fi
 
        touch /etc/xinetd.d/$service || true
        # cat "$CONF" "$CONFTMP" | sed -n "/^service $service/,/^}/p" | cp-update "$PKG" "/etc/xinetd.d/$service"
-       cat "$CONF" "$CONFTMP" | sed -n "/^service $service/,/^}/p" >> "/etc/xinetd.d/$service"
+       sed -rn "/^[[:space:]]*service[[:space:]]+$service[[:space:]]*$/,/^}/p" \
+               $conffile_list >> "/etc/xinetd.d/$service"
 
        need_restart=1
     done
 
-    cp_echo ""
-    cp_echo "CN: All services were converted from $CONF file to separated configuration"
-    cp_echo "CN: files located in /etc/xinetd.d/ directory."
-
-    if [ -n "$inetd_compat" ]; then
-       cp_echo "CN: Since -inetd_compat option was active, all services in $INETDCONF"
-       cp_echo "CN: file were also moved to /etc/xinetd.d/ directory."
+    if egrep -q "^[[:space:]]*service[[:space:]]+" "$CONFTMP"; then
+       cp_echo "CN: All services were converted from $INETDCONF file to separated"
+       cp_echo "CN: configuration files located in /etc/xinetd.d/ directory."
     fi
 
+    if [ $xinetd_conf_did -eq 1 ]; then
+       cp_echo "CN: All services were converted from $CONF file to separated"
+       cp_echo "CN: configuration files located in /etc/xinetd.d/ directory."
+    fi
 fi
 
 rm -f $CONFTMP
 
+# Configuration file /etc/xinetd.conf does not exist?
+#
+if [ ! -f "$CONF" ]; then
+       touch "$CONF"
+fi
+
 # Remove services from /etc/xinetd.conf file
 #
-cp_check_and_sed "^service " \
-       "/^service/,/^}/d" \
+cp_check_and_sed "^[[:space:]]*service[[:space:]]+" \
+       "/^[[:space:]]*service[[:space:]]/,/^}/d" \
        "$CONF" && need_restart=1 || true
 
 # Check if there is no defaults block in /etc/xinetd.conf
 #
 if ! egrep -q '^defaults' "$CONF"; then
 
-       echo -e "defaults\n{\n\n}" | cp-update "$PKG" "$CONF"
+       echo -e "defaults\n{\n\n}" | cp-update -m "$PKG" "$CONF"
        cp_echo "CN: Added defaults block to $CONF"
        
        need_restart=1
@@ -104,35 +155,112 @@ fi
 #
 if ! egrep -q '^includedir /etc/xinetd.d' "$CONF"; then
 
-       echo "includedir /etc/xinetd.d" | cp-update "$PKG" "$CONF"
+       echo "includedir /etc/xinetd.d" | cp-update -m "$PKG" "$CONF"
        cp_echo "CN: Added \"includedir /etc/xinetd.d\" line to $CONF"
        
        need_restart=1
 fi
 
-# Remove -inetd_compat option from /etc/default/xinetd
+# Validate services' configuration.
+#
+services_file_list="`ls -1 /etc/xinetd.d/`"
+if [ -n "$services_file_list" ]; then
+
+    for services_file in $services_file_list; do
+
+       # Get services list from $services_file
+       services_list="`sed -rn "s/^[[:space:]]*service[[:space:]]+(.*)[[:space:]]*$/\1/p" /etc/xinetd.d/$services_file`"
+
+       if [ -n "$services_list" ]; then
+
+           for service in $services_list; do
+
+               service_disable=0
+               service_block="`sed -rn "/^[[:space:]]*service[[:space:]]+$service[[:space:]]*$/,/^}/p" /etc/xinetd.d/$services_file`"
+
+               # Check service's user
+               service_user="`echo "$service_block" | sed -nr "s/^[[:space:]]*user[[:space:]]*=[[:space:]]*(.*)[[:space:]]*$/\1/p"`"
+               if [ -n "$service_user" ]; then
+
+                   for service_user_x in $service_user; do
+                       service_user_chk="`getent passwd $service_user_x`" || true
+                       if [ -z "$service_user_chk" ]; then
+                           cp_echo "CN: Error in /etc/xinetd.d/$services_file for service '$service' - user '$service_user_x' does not exist."
+                           service_disable=1
+                           break
+                       fi
+                   done
+               fi
+
+               # Check service's group
+               service_group="`echo "$service_block" | sed -nr "s/^[[:space:]]*group[[:space:]]*=[[:space:]]*(.*)[[:space:]]*$/\1/p"`"
+               if [ -n "$service_group" ]; then
+
+                   for service_group_x in $service_group; do
+                       service_group_chk="`getent passwd $service_group_x`" || true
+                       if [ -z "$service_group_chk" ]; then
+                           cp_echo "CN: Error in /etc/xinetd.d/$services_file for service '$service' - group '$service_group_x' does not exist."
+                           service_disable=1
+                           break
+                       fi
+                   done
+               fi
+
+               # Check service's binary
+               service_server="`echo "$service_block" | sed -nr "s/^[[:space:]]*server[[:space:]]*=[[:space:]]*(.*)[[:space:]]*$/\1/p"`"
+               if [ -n "$service_server" ]; then
+
+                   for service_server_x in $service_server; do
+                       if [ ! -x "$service_server_x" ]; then
+                           cp_echo "CN: Error in /etc/xinetd.d/$services_file for service '$service' - server '$service_server_x' does not exist."
+                           service_disable=1
+                           break
+                       fi
+                   done
+               fi
+
+               if [ $service_disable -eq 1 ]; then
+                   backup_and_disable_service "$service" "$services_file"
+                   need_restart=1
+               fi
+           done
+       fi
+    done
+fi
+
+# Remove -inetd_compat option and set INETD_COMPAT to 'No' in /etc/default/xinetd
 #
 if [ -f "$DEFAULT" ]; then
        
+       # File exists, set INETD_COMPAT to 'No'
+       cp_check_and_sed "^[[:space:]]*INETD_COMPAT.*[Yy][Ee][Ss]" \
+               "s/^[[:space:]]*INETD_COMPAT.*[Yy][Ee][Ss]/INETD_COMPAT=No/g" \
+               "$DEFAULT" && need_restart=1 || true
+
        # File exists, remove -inetd_compat option
-       cp_check_and_sed "^XINETD_OPTS.*\-inetd_compat" \
+       cp_check_and_sed "^[[:space:]]*XINETD_OPTS.*\-inetd_compat" \
                "s/\-inetd_compat//g" \
                "$DEFAULT" && need_restart=1 || true
 
-       # Just in case there is no active XINETD_OPTS line
-       if ! egrep -q '^XINETD_OPTS' "$DEFAULT"; then
+       # No INETD_COMPAT line?
+       if ! egrep -q '^[[:space:]]*INETD_COMPAT' "$DEFAULT"; then
+               echo 'INETD_COMPAT=No' | cp-update -m "$PKG" "$DEFAULT"
+               cp_echo "CN: Added 'INETD_COMPAT=No' to $DEFAULT."
+               need_restart=1
+       fi
 
-               echo 'XINETD_OPTS="-stayalive"' | cp-update "$PKG" "$DEFAULT"
+       # Just in case there is no active XINETD_OPTS line
+       if ! egrep -q '^[[:space:]]*XINETD_OPTS' "$DEFAULT"; then
+               echo 'XINETD_OPTS="-stayalive"' | cp-update -m "$PKG" "$DEFAULT"
                cp_echo "CN: Added -stayalive option to $DEFAULT."
-
                need_restart=1
        fi
 else
        # File wasn't there at all?
        touch $DEFAULT
-       echo 'XINETD_OPTS="-stayalive"' | cp-update "$PKG" "$DEFAULT"
-       cp_echo "CN: Created $DEFAULT file with -stayalive option."
-       
+       echo -e 'INETD_COMPAT=No\nXINETD_OPTS="-stayalive"' | cp-update "$PKG" "$DEFAULT"
+       cp_echo "CN: Created $DEFAULT file with -stayalive enabled and -inetd_compat disabled."
+
        need_restart=1
 fi
 
@@ -143,7 +271,6 @@ if [ $need_restart -eq 1 ]; then
 fi
 pgrep -u root -f /usr/sbin/xinetd > /dev/null || do=start
 
-cp_echo ""
 if [ -n "$do" ]; then
 
        # Restart xinetd.