3 # $Id: update_sanesecurity.sh 706 2008-09-15 20:27:11Z mendel $
5 # A Modified version of the update script originally written by
8 # Modified by Rick Cooper: Contact sanescript@dwford.com
10 # Modified by Norbert Buchmuller <norbi@nix.hu>
13 # * split off changelog to a separate file
14 # * split off configuration to a separate file
15 # * support optional gzipping (if the downloaded file ends in .gz|.bz2, unzip it)
16 # * support for protocol (rsync://|http://|https://|ftp://) auto-detection (and call the appropriate download method)
17 # * support for more flexible download URLs (a list of them eg.)
18 # * support for external configuration file
19 # * support for additional DBs (securiteinfo.com, www.malware.com.br)
21 # Last updated Sep 15, 2008
23 # Looks for 'main.cld' in $clam_db_dir as new versions of ClamAV use
24 # '.cld' extension for virus definition files.
27 # Changed '--debug' to mean '--syslog-loglevel=none --stderr-loglevel=debug'.
28 # Added diagnostic message when tty is detected (and so random sleep is disabled).
31 # Fixed a grave bug: previously it failed to detect if the newly downloaded
32 # database was corrupt.
33 # Detects if the user runs the script from a terminal, and disables
34 # the random sleep if it is so.
37 # Fixed a bug: now it passes the log levels to the unprivileged child.
38 # Fixed a bug: now the unprivileged child does not attempt to reload ClamAV db.
39 # Prints usage message if asked for.
42 # Added SELinux support.
43 # Thanks Andrew Colin Kissa <kissaa@sentech.co.za>.
44 # Added support to run the script as root (the superuser privileges are only used
45 # when changing the owner:group and security context of the signature files,
46 # and when reloading clamd).
49 # Fixed a bug introduced by the 08/28/2007 change: the "SPAM.ndb" file was saved
50 # (incorrectly) with the name "SPAM.hdb" and thus ClamAV refused to load it.
51 # Thanks Keith Brazington <keith@quetz.co.uk>.
54 # Refactored logging to avoid code/text duplication.
55 # Refactored downloading to avoid code duplication.
56 # Split up the main function into smaller ones.
57 # Should be started as the clamav user, not root to avoid
58 # security implications.
59 # Uses proper temporary dir creation method (mktemp(1)) to avoid
60 # security implications.
61 # It is assured that a non-zero exit status is used when exiting because of an error.
62 # Uses 'mail' syslog facility.
63 # Different syslog log priorities are used for messages with different severity.
64 # Diagnostic messages (incl. debug messages) go to stderr instead of stdout.
65 # More careful quoting to allow spaces or other unexpected chars in variables.
66 # Checking carefully for the exit status of all the important commands.
67 # Rsync downloads the new signature file to a temporary directory
68 # and only installs it after it is verified that ClamAV accepts
69 # the signature file. (Note: This requires a relatively new version of Rsync
70 # because versions older than cca. 2.6.9 unconditionally download the file, even
71 # if it did not change.)
72 # Uses '-p' option of 'cp' to preserve modification times.
73 # No separate log files for each command, instead their output is logged if
74 # they return a non-zero exit status.
75 # PATH is appended to, not overwritten.
76 # Use 'type -P' instead of 'which'.
80 # Using new SaneSecurity URLs
83 # Removed the -h (human readable) option from the rsync command line
84 # as this was for the help option in older versions of rsync, and
85 # it's not worth maintaining two versions of the command based on
86 # rsync version. Thanks for the bug report Chris
87 # Changed the SCAM_SIGS_URL variable to point to the proper URL. The old one
88 # worked but this one is the correct/desired URL Thanks Steve Basford.
91 # Fixed incorrect check on CURL return code in phish.db section
92 # causing it to consider a success as a failure. Thanks
93 # Leonardo Rodrigues Magalhães
96 # Fixed a bug where downloading phish.ndb.gz for the first time results
97 # in an error and the downloaded file removed (Thanks Gary V)
100 # Now have option to log to system logger (notify)
101 # If you do not wish to use this logging function look below for
102 # SYSLOG_ON=1 and set to SYSLOG_ON=0. This also will not function
103 # if logger is not installed on your system for some reason
105 # Now logs each download stats regardless of debug status, but only outputs
106 # to console if in debugging mode, or error and doesn't output
108 # (as suggested by Gary V)
109 # Changed the clamdb grep to use extended pattern matching as suggested
111 # Altered the rsync portions to use --stats instead of --progress and
112 # look for number of files transfered for confirmation of an update
115 # Updated the MSRBL-* files to update vi rsync (tested version 2.6.9)
116 # the current db(s) will be saved before the update and if there is a
117 # problem with the download or clam db tests the old version is
118 # moved back into place, an error message is produced and the
119 # corrupt file is moved to filename.bad for the operator to look into
120 # Changed the detection of the clam db directory it's now very fast
121 # and will accommodate trailing slash (ie. /usr/local/share/clamav/) and
122 # will also check for main.cvd as well as the *.inc directories since
123 # apparently it's possible to have an install with only the main.cvd,
124 # at least temporarily
127 # Fixed a potential problem with the downloaded file size being zero
128 # Now test a small txt file using the downloaded sig file, if clam doesn't
129 # like it we don't move it or use it. Throw an error to the operator
130 # Fixed a possible issue with the log size being very large if the site is
131 # busy, now only return the last line from the transmission progress
132 # Changed the operation to find the clam database dir to checking for
133 # the standard /usr/local/share/clamav location first, and if not there
134 # ask clamscan. (save a few seconds)
138 # Make sure the path to your ClamAV binaries is in here, it should
139 # cover all normal installations
140 export PATH="$PATH":/bin:/usr/bin:/usr/local/bin
142 # The file names and URLs of the scam and phish signature files from SaneSecurity
144 SCAM_SIGS_URL="http://www.sanesecurity.com/clamav/scamsigs/scam.ndb.gz"
145 PHISH_SIGS="phish.ndb"
146 PHISH_SIGS_URL="http://www.sanesecurity.com/clamav/phishsigs/phish.ndb.gz"
148 # The URLs of the spam and image-spam signature files from MSRBL
149 MSRBL_SPAM_SIGS="MSRBL-SPAM.ndb"
150 MSRBL_SPAM_SIGS_URL="rsync://rsync.mirror.msrbl.com/msrbl/MSRBL-SPAM.ndb"
151 MSRBL_IMAGE_SIGS="MSRBL-Images.hdb"
152 MSRBL_IMAGE_SIGS_URL="rsync://rsync.mirror.msrbl.com/msrbl/MSRBL-Images.hdb"
154 # Log messages with this or greater severity to syslog
155 syslog_loglevel=error
157 # Log messages with this or greater severity to standard error
160 # Use this syslog facility
163 # The script will sleep for a random amount of time before starting the
164 # actual update. This evens out the load on the update servers when people
165 # have a tendency to set cron jobs on the hour, half hour or quarter hour.
166 # The extra padding keeps the servers from being hammered all at once.
167 # These are the minimum and maximum sleep times in seconds.
171 # Should the script reload the clamd service
172 # (Should not be necessary if you have "SelfCheck" enabled in clamd.conf
173 # and "NotifyClamd" enabled in freshclam.conf.)
176 # If the script is run as root, change the owner and group of
177 # the signature files to this user and group. (The username
178 # and group name should be separated by a colon.)
179 sigfile_owner_and_group=clamav:clamav
181 # If the script is run as root, perform downloading, checking and
182 # installation of the signature files as this user. (The SELinux
183 # security context fixing and the clamd reload need superuser
184 # privileges, so these will be performed as root.)
185 # Note: This user must be able to read and write signature files
187 unprivileged_user=${sigfile_owner_and_group%:*}
189 # Whether to preserve the temporary directory (for debugging purposes)
190 # on exit instead of deleting it (the default)
193 ####################################################################
194 # No user tunable variables below
195 ####################################################################
197 ####################################################################
201 # Return the numeric constant associated with the given
204 # Usage: numeric_loglevel=`numeric_log_severity $loglevel_name`
206 numeric_log_severity()
210 # The severity names (same as in syslog)
211 local -a severity_names=(
219 emerg,emergency,panic
225 while [ -n "${severity_names[i]}" ]; do
226 for levelname in ${severity_names[i]//,/ }; do
227 if [ "$name" == "$levelname" ]; then
234 if [ -z "$numeric_level" ]; then
235 numeric_level=`numeric_log_severity debug`
241 # Log the given message with the given priority.
242 # Logging includes printing to stderr and sending the message to
243 # syslog, depending on the debug level and syslog loglevel settings.
245 # Usage: log level message [message_continuation [...]]
250 local -a message_parts='("${@:2}")'
252 local message=`echo -e "${message_parts[@]}"`
254 if [ $(numeric_log_severity $level) -ge $(numeric_log_severity $stderr_loglevel) ]; then
255 echo "$program_invocation_short_name: [$level] $message" >&2
257 if [ $(numeric_log_severity $level) -ge $(numeric_log_severity $syslog_loglevel) ]; then
258 if [ -n "$logger" ]; then
259 "$logger" -p ${syslog_facility}.${level} -i -t "$program_invocation_short_name" -- "${message//$'\n'/\\n}"
264 ####################################################################
268 # Run the command silently. If the command exits with a
269 # non-zero exit status, log an error message including the command run,
270 # the exit status and and the collected output, otherwise swallow the output.
272 # Usage: run_cmd "$cmd" ["$arg1" [...]]
276 local -a cmd_and_args='("${@}")'
278 local output # must be a separate command, as 'local' always returns 0 exit status
279 output=`"${cmd_and_args[@]}" 2>&1`
281 if [ $exit_status -ne 0 ]; then
282 log err "Error executing command <<<${cmd_and_args[*]}>>>, exit status: $exit_status, output: <<<$output>>>"
288 # Push one or more elements to the end of the array.
290 # Usage: push array_name "$elem1" [...]
294 local -a array="$1" elems='("${@:2}")'
296 local len=`eval echo \\\${#$array[@]}`
297 for elem in "${elems[@]}"; do
298 eval "$array[$len]=$elem"
303 ####################################################################
304 # Signature file download/test/installation functions
307 # Check if ClamAV accepts the signature file,
308 # and moves it to the database dir if so.
310 # 0 - sigfile was updated successfully
311 # 1 - sigfile was up-to-date or an error occurred
313 # Usage: check_and_install_sigfile "$file_basename"
315 check_and_install_sigfile()
319 local sigfile="$clam_db_dir/$filename"
320 local new_sigfile="$tmp_dir/$filename"
322 local sigfile_updated=0
324 if [ -s "$new_sigfile" ]; then
325 # First we do a quick test of the downloaded file. If ClamAV doesn't
326 # like it we won't use it and issue an error to the operator
327 # renaming the file so they can inspect it themselves.
328 run_cmd "$clamscan" --quiet -d "$new_sigfile" "$test_file"
330 if [ $exit_status -eq 0 ]; then
331 if [ -s "$sigfile" ]; then
332 run_cmd cp -pf "$sigfile" "${sigfile}.bak"
334 run_cmd mv -f "$new_sigfile" "$sigfile"
336 if [ $exit_status -eq 0 ]; then
339 log err "Cannot move '$new_sigfile' to '$sigfile', 'mv' exit status: $exit_status"
342 log err "ClamAV had a problem using '$new_sigfile' (exit status: $exit_status)."
343 log err "We will NOT install '$new_sigfile' into the database directory."
344 run_cmd mv -f "$new_sigfile" "${sigfile}.bad"
346 if [ $exit_status -eq 0 ]; then
347 log err "Preserving the corrupt file as '${sigfile}.bad' for you to check."
349 log err "Cannot move the corrupt file from '$new_sigfile' to '${sigfile}.bad', 'mv' exit status: $exit_status."
352 elif [ -e "$new_sigfile" ]; then
353 log warning "'$new_sigfile' was zero bytes and will not be used!"
357 if [ $sigfile_updated -ne 0 ]; then
358 log info "'$sigfile' was updated"
361 log info "'$sigfile' was NOT updated"
368 # Update/download a gzip-compressed signature file using CURL,
369 # uncompress it, check if ClamAV accepts it, and install it in
370 # the database directory.
372 # 0 - sigfile was updated successfully
373 # 1 - sigfile was up-to-date or an error occurred
375 # Usage: update_sigfile_with_curl "$url" "$file_basename"
377 update_sigfile_with_curl()
379 local url="$1" filename="$2"
381 if [ -z "$url" ]; then
382 log info "Skipping '$filename' because no URL is configured for it"
386 local sigfile_gz="$clam_db_dir/${filename}.gz"
387 local new_sigfile_gz="$tmp_dir/${filename}.gz"
388 local sigfile="$clam_db_dir/$filename"
389 local new_sigfile="$tmp_dir/$filename"
391 local sigfile_gz_updated=0
393 declare -a curl_additional_flags
395 # If something happend to the sig file, or this is the first time
396 # this script has been run then we can't do the date test on the
397 # current file so we just grab what ever is current on the site
398 if [ -s "$sigfile_gz" ]; then
399 log debug "Checking for newer version of '$sigfile_gz'"
400 push curl_additional_flags "-z" "$sigfile_gz"
402 log debug "'$sigfile_gz' does not exist, so doing initial download"
405 if [ $stderr_loglevel != debug ]; then
406 push curl_additional_flags "-s"
409 run_cmd "$curl" -R "${curl_additional_flags[@]}" -o "$new_sigfile_gz" \
410 -f -v --referer ";auto" --location "$url"
412 if [ $exit_status -eq 0 -o $exit_status -eq 22 ]; then
413 # If we don't have the download or it's zero bytes
414 # something went wrong and we did not get an update.
415 if [ ! -s "$new_sigfile_gz" ]; then
416 if [ -e "$new_sigfile_gz" ]; then
417 rm -f "$new_sigfile_gz"
418 log warning "'$new_sigfile_gz' was zero bytes and will not be used!"
420 if [ $exit_status -eq 22 ]; then
421 log warning "CURL returned an error code 22 which results from a HTTP error 4xx"
422 log warning "This might be caused by the file not being updated (HTTP 412) but"
423 log warning "it could be something else."
427 log err "CURL had a problem getting '$new_sigfile_gz' from '$url', exit status: $exit_status"
428 rm -f "$new_sigfile_gz"
431 if [ -s "$new_sigfile_gz" ]; then
432 "$gunzip" -cdf "$new_sigfile_gz" > "$new_sigfile"
434 if [ $exit_status -eq 0 ]; then
435 run_cmd mv -f "$new_sigfile_gz" "$sigfile_gz"
437 if [ $exit_status -eq 0 ]; then
440 log err "Cannot move '$new_sigfile_gz' to '$sigfile_gz', 'mv' exit status: $exit_status"
443 rm -f "$new_sigfile_gz"
444 log err "Cannot uncompress '$new_sigfile_gz', 'gunzip' exit status: $exit_status"
448 if [ $sigfile_gz_updated -ne 0 ]; then
449 log info "'$sigfile_gz' was updated"
451 log info "'$sigfile_gz' was NOT updated"
454 check_and_install_sigfile "$filename"
457 # Update/download the signature file using Rsync,
458 # check if ClamAV accepts it, and and installs it in
459 # the database directory.
461 # 0 - sigfile was updated successfully
462 # 1 - sigfile was up-to-date or an error occurred
464 # Usage: update_sigfile_with_curl "$url" "$file_basename"
466 update_sigfile_with_rsync()
468 local url="$1" filename="$2"
470 if [ -z "$url" ]; then
471 log info "Skipping '$filename' because no URL is configured for it"
475 local sigfile="$clam_db_dir/$filename"
476 local new_sigfile="$tmp_dir/$filename"
478 if [ -s "$sigfile" ]; then
479 log debug "Checking for newer version of '$sigfile'"
481 log debug "'$sigfile' does not exist, so doing initial download"
484 # Rsync will download the file only if it is different from the one in
485 # $clam_db_dir. The downloaded file will be stored in $tmp_dir.
486 run_cmd "$rsync" --stats -t --compare-dest="$clam_db_dir/" \
487 "$url" "$new_sigfile"
489 if [ $exit_status -ne 0 ]; then
490 log err "Rsync had a problem getting '$new_sigfile' from '$url', exit status: $exit_status"
494 check_and_install_sigfile "$filename"
497 ####################################################################
501 # Check for the external programs/tools and
502 # set the corresponding variables to the found paths
504 # Usage: check_for_external_programs
506 check_for_external_programs()
508 # Look for the paths to the programs we are going to need
509 logger=`type -P logger`
510 clamscan=`type -P clamscan`
512 gunzip=`type -P gunzip`
513 rsync=`type -P rsync`
515 # Check if the 'logger' binary is missing
516 if [ -z "$logger" -o ! -x "$logger" ]; then
518 log err "Could not find the 'logger' program, no syslog will be attempted"
521 # If we did not find any of our external programs
522 # give an error message and exit
524 for prg in clamscan curl gunzip rsync; do
525 if [ -z ${!prg} ]; then
526 log err "Cannot find '$prg'"
533 # Print usage message.
539 echo -e "Downloads unofficial ClamAV signature files from sanesecurity.com and msrbl.com."
540 echo -e "Usage: $0 [options]"
542 echo -e " --syslog-loglevel=level\tSets the log level for syslog to 'level'."
543 echo -e " --stderr-loglevel=level\tSets the log level for stderr to 'level'."
544 echo -e " --debug\t\t\tShorthand for '--syslog-loglevel=none"
545 echo -e " \t\t\t\t--stderr-loglevel=debug'."
546 echo -e " --sleep\t\t\tEnable the (random length) sleep before"
547 echo -e " \t\t\t\tstarting the download. (this is the default)"
548 echo -e " --no-sleep\t\t\tDisable the (random length) sleep before"
549 echo -e " \t\t\t\tstarting the download. (default if stdin is"
550 echo -e " \t\t\t\ta tty)"
552 echo -e "Log level can be one of these:"
553 echo -e " debug, info, notice, warning, err, crit, alert, emerg"
556 # Parse options/arguments
558 # Usage: parse_arguments
564 # Parse options/arguments
565 while [ $# -ge 1 ]; do
567 --debug|-d|debug|Debug|DEBUG)
569 stderr_loglevel=debug
570 log debug "Debug mode is ON"
577 syslog_loglevel=${1#--*=}
584 stderr_loglevel=${1#--*=}
592 --unprivileged-child)
600 log err "Got command line argument of '$1' and I don't understand it!"
609 # Create a temporary directory and arrange to remove it on exit,
610 # plus create an empty file to use for testing ClamScan
612 # Usage: create_temp_dir
616 tmp_dir=`mktemp -d -t ${program_invocation_short_name}.XXXXXXXX` || (
617 log err "Cannot create temporary directory"
622 if [ $exit_status -ne 0 ]; then
623 log err "Error running mktemp(1), exit status: $exit_status"
627 log debug "Created temporary directory: '$tmp_dir'"
628 if [ $keep_temp_dir -eq 0 ]; then
629 trap 'rm -rf "$tmp_dir"' EXIT
632 # We create a file for ClamScan to test in debug mode.
633 test_file="$tmp_dir/test.file"
637 # Log a couple of debug messages with a summary on some parameters
639 # Usage: log_startup_summary
641 log_startup_summary()
643 log debug "PHISH_SIGS : $PHISH_SIGS_URL"
644 log debug "SCAM_SIGS : $SCAM_SIGS_URL"
645 log debug "SPAM_SIGS : $MSRBL_SPAM_SIGS_URL"
646 log debug "IMAGE_SIGS : $MSRBL_IMAGE_SIGS_URL"
647 log debug "ClamScan : $clamscan"
648 log debug "CURL : $curl"
649 log debug "GunZip : $gunzip"
650 log debug "RSync : $rsync"
651 log debug "ClamAV db dir : $clam_db_dir"
652 log debug "temp dir : $tmp_dir"
655 # Sleep for a random time (determined by $min_sleep_time and $max_sleep_time global variables)
657 # Usage: random_sleep
663 sleep_time=$(($RANDOM * $(($max_sleep_time-$min_sleep_time)) / 32767 + $min_sleep_time))
664 log debug "Sleeping for $sleep_time seconds..."
668 # Find the ClamAV db dir and set the $clam_db_dir global variable
670 # Usage: find_clam_db_dir
674 # Scan an empty test file with debug enabled to determine where ClamAV expects
675 # to find it's signature database
676 log debug "Checking for ClamAV database directory..."
677 clam_db_dir=`"$clamscan" --debug "$test_file" 2>&1 | \
678 sed -ne 's/\/$//; s/^.*loading databases from \(.*\)$/\1/ip' | head -1`
679 log debug "Found ClamAV database directory: $clam_db_dir"
681 # Check for either the daily.inc, the main.inc dirs or the main.cvd one of which
682 # must exist for a functional clamav installation
684 ! -d "$clam_db_dir/daily.inc" -a \
685 ! -d "$clam_db_dir/main.inc" -a \
686 ! -f "$clam_db_dir/main.cvd" -a \
687 ! -f "$clam_db_dir/main.cld" \
689 log err "None of '$clam_db_dir/daily.inc', '$clam_db_dir/main.inc',"
690 log err "'$clam_db_dir/main.cvd', '$clam_db_dir/main.cld' found"
691 log err "in your database directory. Either '$clam_db_dir' is NOT"
692 log err "the correct database path or there is something wrong with your"
693 log err "ClamAV installation. This path came from your '$clamscan' so I would guess"
694 log err "you need to check your clamd.conf file and/or '$clam_db_dir'"
701 # Change owner, group and security context of the signature files.
703 # Usage: chown_chcon sigfiles ...
707 local -a sigfiles='("$@")'
709 for i in "${sigfiles[@]}"; do
710 [ -f "$i" ] || continue
712 run_cmd chown $sigfile_owner_and_group "$i"
714 if [ $exit_status -ne 0 ]; then
715 log err "chown had a problem changing ownership of signature file '$i', exit status: $exit_status"
721 # SELinux fix: change security context
722 if [ -n "$(type -P sestatus 2>/dev/null)" ] && [ "$(sestatus | head -n 1 | awk '{ print $3 }')" == "enabled" ]; then
723 for i in "${sigfiles[@]}"; do
724 [ -f "$i" ] || continue
726 run_cmd chcon user_u:object_r:var_t "$i"
728 if [ $exit_status -ne 0 ]; then
729 log err "chcon had a problem changing security context of signature file '$i', exit status: $exit_status"
737 # Reload the ClamAV daemon
739 # Usage: reload_clamav_daemon
741 reload_clamav_daemon()
743 local -a clamd_reload_cmd
744 if [ -n "`type -P service`" ]; then
745 clamd_reload_cmd=(service clamd reload)
747 for init_script in /etc/{init,rc}.d/{clamd,clamav-daemon}; do
748 if [ -x "$init_script" ]; then
749 clamd_reload_cmd=("$init_script" reload-database)
754 if [ -n "${clamd_reload_cmd[*]}" ]; then
755 log info "Reloading ClamAV daemon"
756 run_cmd "${clamd_reload_cmd[@]}"
758 log err "Cannot reload ClamAV daemon because no initscript found"
763 ####################################################################
766 declare logger clamscan curl gunzip rsync
767 declare tmp_dir test_file
769 declare unprivileged_child=0
772 # Skip sleeping if run interactively
774 log debug "Disabling random sleep feature because stdin is a terminal."
778 # The short name of this script
779 readonly program_invocation_short_name=`basename "$0"`
781 # The absolute name of this script
782 readonly program_invocation_absolute_name=$(readlink -f "$0" || type -P "$0")
786 if [ "$unprivileged_child" -eq 0 ]; then
787 log debug "Starting."
789 check_for_external_programs
792 if [ "$unprivileged_child" -eq 0 ]; then
794 if [ "$no_sleep" -eq 0 ]; then
799 # Change current directory to ClamAV database directory
800 # but just for the sake of safety we will use
801 # absolute paths for copy/move operations
804 declare sigfile_updated=0
805 if [ "$unprivileged_child" -ne 0 -o $(id -u) -ne 0 ]; then
806 # Update/download the signature files
807 update_sigfile_with_curl "$SCAM_SIGS_URL" "$SCAM_SIGS" && sigfile_updated=1
808 update_sigfile_with_curl "$PHISH_SIGS_URL" "$PHISH_SIGS" && sigfile_updated=1
809 update_sigfile_with_rsync "$MSRBL_SPAM_SIGS_URL" "$MSRBL_SPAM_SIGS" && sigfile_updated=1
810 update_sigfile_with_rsync "$MSRBL_IMAGE_SIGS_URL" "$MSRBL_IMAGE_SIGS" && sigfile_updated=1
812 # Re-execute the script as the unprivileged user to do the download/check/install part.
813 # (It exits with 0 exit status only if at least on the signature file were updated.)
814 su -s $SHELL $unprivileged_user -c "'$program_invocation_absolute_name' --unprivileged-child --syslog-loglevel=$syslog_loglevel --stderr-loglevel=$stderr_loglevel" && sigfile_updated=1
816 # Change owner, group and security context.
817 chown_chcon "$SCAM_SIGS" "$PHISH_SIGS" "$MSRBL_SPAM_SIGS" "$MSRBL_IMAGE_SIGS"
821 if [ $reload_clamd -ne 0 -a $sigfile_updated -ne 0 -a "$unprivileged_child" -eq 0 ]; then
825 if [ "$unprivileged_child" -eq 0 ]; then
828 if [ $sigfile_updated -ne 0 ]; then
831 final_exit_status=100
833 exit $final_exit_status