NAME

filewatcher - archive system files and generate change alerts


SYNOPSIS

filewatcher -config file [-debug level]

filewatcher -version


DESCRIPTION

filewatcher maintains an archive of critical system files and generates reports that describe what changes have taken place, including file additions, deletions, or changes. Detailed change reports for modified files are produced via rcsdiff.

filewatcher is designed so that multiple people can watch different (possibly overlapping) sets of files with a minimum of maintenance hassle. This is made possible by the configuration file include function, which will be described in CONFIGURATION.


REQUIRED SOFTWARE

The following modules that are not included with Perl by default must be installed for proper operation of this program:

Mail::Internet;
filewatcher uses the Mail::Internet send notifications via e-mail.

RCS
filewatcher uses RCS to manage its archive. If it is in a non-standard location, you can adjust your path with the 'option path --prepend /path/to/rcs' directive in your configuration file. It is recommended that you also install the latest diffutils package since some vendor-supplied diff programs aren't very current.


CONFIGURATION

filewatcher begins by loading a configuration file that may contain a series of directives and option definitions.

CONFIGURATION DIRECTIVES

watch
The watch directive defines one or more files, directories, or glob patterns to be included in the archive operation. All arguments to watch are first examined for embedded variable references (e.g., $HOME), all of which are expanded. Next, unless glob suppression is enabled, each argument is replaced with multiple names determined by using standard shell glob expansion (e.g. *.c might become the list foo.c, bar.c, and bot.c). If a specific file is referenced multiple times, the last reference in the overall configuration (including all associated option settings) will be used.

Options

ARCHIVE
If the single argument ARCHIVE is given to watch, it will be automatically expanded to the list of all filenames currently in the archive that do not exist in the filesystem. In order to detect that they are in fact missing, the warn-if-missing option should be set in the watch context.

EXEC
By preceding a single filename watch target with EXEC, that filename will be treated specially. Rather than comparing and archiving the contents of the file, filewatcher will execute the file and compare/archive the results. Because it may be desirable to archive the target itself, the results will be stored in a separate parallel area of the regular file archive.

except
The except directive defines a file, directory, or glob pattern to be excluded in the archive operation. Note that except will only affect files that have already been added to the watch list, thus the order of watch and except directives is significant.

option
The option directive is used to set the value of a configuration option. Immediately following the option name, one or more flags may be specified:
--default
If the --default flag is supplied after an option name, the value specified for the option is set and the new value is retained as the option's new default value. This means that if the clear directive is used, the option value will revert to the new default rather than the original default value.

--append
If the --append flag is supplied after an option name, the value specified for the option will be appended to the current option value. How the value is appended depends on the option type. For 'path' options, the original and new values will be joined with a colon. For 'string' options, the original and new values will be joined with a space. It is not legal specify this flag with any other option type.

--prepend
If the --prepend flag is supplied after an option name, the value specified for the option will be prepended to the current option value. How the value is prepended depends on the option type. For 'path' options, the original and new values will be joined with a colon. For 'string' options, the original and new values will be joined with a space. It is not legal specify this flag with any other option type.

NOTE: If the option value itself is a string that begins with a hyphen, the option value must be preceded by an empty flag, that is, -- by itself, so that the value is not mistaken for an option flag such as those described above. For example, if you are replacing the diff program options passed to rcsdiff, you must do so as follows:

option diff-flags -- ``-c -b''

Specific options are described in CONFIGURATION OPTIONS.

push
The push directive saves all current option values. Typically, this will be used at the beginning of an included file to ensure that the included file does not affect the values of options in the parent file.

pop
The pop directive restores all configuration options to the values they had just prior to the most recent push directive. Typically, this will be used at the end of an included file to ensure that the included file does not affect the values of options in the parent file.

clear
The clear directive restores one or more or all option values to their default values. Note that the option-default directive can affect option defaults! To clear specific options, provide them as arguments to clear. If no options are listed, all options are reset to default values.

include
This directive takes as a single argument either a filename or directory. If the argument is a filename, then it specifies another configuration file to include. If the argument is a directory, then each file within that directory (subdirectories will not be considered) will be included as though each had been specified individually.

By default, each included file must exist or an error will be generated. That behavior can be modified by using the include-must-exist configuration option (described below).

By default, the values of all options are saved prior to evaluating directives within an included file and they are restored afterward. That behavior can be modified by using the include-autopush configuration option (described below).

transform name
This directive defines a transformation sequence that will be applied to one or more files via the archive-transform or report-transorm options (described below).

A transform is a sequence of one or more commands from the following list:

delete-if regex
Each line in the change report is examined and if the line matches the given regex, the line is omitted from the final report.

replace regex string
Each line in the change report is examined and if the line matches the given regex, the matched portion is replaced with the specified string. Note that regex is a Perl regular expression and that backreferences may be used in string via standard $1, $2, etc. variables. Matching is not anchored unless so specified in the regex.

CONFIGURATION OPTIONS

Each of the options described in this section have various types associated with them. These are:

boolean
Simple boolean value, that is, true or false.

string
Simple string value.

path
Same as a string, but embedded environment variables (of the form $VAR or ${VAR}) will first be expanded.

integer
Simple numerical value.

duration
Time duration, defined as a combination of Ns, Nm, Nh, and Nd, where N is some positive integer and s, m, h, and d, represent seconds, minutes, hours, and days, respectively. If a number is given without s, m, h, or d, then that number will be considered to be seconds.

The remainder of this section describes each of the available options that may be specified with the option directive.

archive-root (global; path: no default)
The archive-root is the path to the directory under which all archived files will be stored. For example, if an archived file is named /etc/rc, then the archived version will be saved in archive-root/etc/rc,v. For dynamic files generated from watch EXEC, a parallel archive will be maintained by adding a -exec suffix to the archive-root path, so the command watch EXEC /usr/local/bin/somescript will have its results archived in archive-root-exec/usr/local/bin/somescript,v.

NOTE: This option may only be defined once.

ci-uses-euid (per-file; boolean: default=true)
If this variable is true, the `ci' command will set the user to the effective user, so that a manual checkin while su'ed or equivalent will cause the effective UID to be entered into the RCS metadata rather than the default real UID.

ci-uses-mtime (per-file; boolean: default=true)
If this variable is true, the `ci' command will set the checkin date to the mtime of the file rather than the default current time. This is useful since the file may be checked in much later than its last change time if it is scanned infrequently.

diff-flags (per-file; string: default=``-u -B'')
This defines the flags that will be passed to the rcsdiff command in order to display changes from one version to the next. The default, which outputs unified diff and ignores whitespace only changes, may not work in all versions of diff.

descend (global; boolean: default=false)
If this variable is true, any directories specified in a watch or an except directive will be recursively considered. Otherwise, only the directory's immediate contents will be considered.

filter (global; string: default=``RCS SCCS *~ #*'')
Defines a list of glob patterns each of which is applied to each filename (after glob and environment variable expansion). If a filename matches any element in the filter list, that filename will be ignored, that is, not considered for watch or except directives.

include-autopush (global; boolean: default=true)
If this option is set, then included configuration files will implicitly be surrounded by a 'push' and 'pop' in order to automatically save and restore option values.

include-must-exist (global; boolean: default=true)
If this option is set, then an error will be raised when files referenced for inclusion do not exist. This would be typically set to false when including optional files that may or may not exist.

transform-archive (per-file; string: no default)
If this option is set, the named transform will be applied to the file contents prior to archiving the file.

transform-report (per-file; string: no default)
If this option is set, the named transform will be applied to the change report for a file prior to those changes being reported. NOTE: It is important to remember that the change report may contain extra characters at the start of the line based on the rcsdiff output options used.

notify (per-file; string: default=mailto:user)
This option is used to define who receives reports. The value is formatted as a URL. The protocols current supported include:
mailto
The 'mailto' protocol submits a report via normal SMTP e-mail (requires the Mail::Internet module). The default notification target is mailto:user where user is the name of the user running filewatcher. Note: The Mail::Internet Perl module is required to be installed in order to use this protocol.

stdout
The 'stdout' protocol submits a report via standard output.

fd
The 'fd' protocol submits a report via an already open file descriptor. The full usage is fd:N, where N is a positive integer. It is assumed that the file descriptor has been opened by the calling program so that different reports will be passed to different descriptors.

null
The 'null' protocol sends the report to the bit-bucket; this is useful when archiving files that contain sensitive data not fit for e-mail notification.

In the future, 'http' and 'https' will be supported, in which case the designated URI will need be bound to a report handler program. Another planned driver is 'pgp', which will work like 'mailto', but use PGP or GPG to encrypt reports.

A separate copy of the report will be submitted to each notify target. Each will receive information only for those files to for which it is defined, so the set of reports delivered may be different for each notification target. See the title option for further report separation posibilities.

path (global; path: default=``$ENV{PATH}'')
This option is used to setup the PATH environment variable. Use to append directories to the program search path.

retention (per-file; integer: default=0)
This option determines how many revisions of a file to retain in the archive. A value of 0 indicates that all revisions should be retained indefinitely.

scan-frequency (per-file; duration: default=10m)
This option dictates the minimum delay between successive change reports for specific files. Once a change is detected in a file, that file will not be checked for changes until the scan-frequency period has expired. Typically this will be set longer for files that might change frequently but do not need immediate notification, but just a periodic summary of changes. Other files might need to be scanned very frequently for security reasons. Note the minimum value for scan-frequency is based upon the process scheduler used (typically cron).

send-changes (per-file; global; boolean: default=true)
If this option is true, then file changes will be sent with the report, otherwise only the fact that the file changed will be reported.

skip-binary (global; boolean: default=true)
If this option is true, then files will be checked as to whether they appear to contain binary data, and if so, will not be considered for archiving. The method used to determine if a file contains binary data is the Perl '-B' builtin heuristic test.

state-file (global; path: no default)
Defines location of the filewatcher state file, which contains data that must be stored between invocations in order to make certain decisions.

NOTE: This option may only be defined once.

suppress-glob (global; boolean: default=false)
If this option is true, then names referenced in the watch and except directives will not be expanded via glob pattern expansion.

title (per-file; string: default=``[%h] filewatcher %f report'')
This option is used to define the form of the subject string used in reports sent by the mailto notification method. Note that since this is a per-file attribute, multiple reports may be sent based on this string being different across the change set. This is similar to what happens for the notify option.

The string may contain special ``percent-variables'' that expand to system dependent values:

%nH
fully qualified hostname -- if n is specified, then the hostname is modified as follows: if n is positive, then all but the first n hostname components are stripped; if n is negative, then the last n hostname components are stripped.

%h
bare hostname - no domain (same as %1H)

%f
base name of current configuration file -- this can be used to create a single subject specifier that changes based on which include file is currently being processed.

To insert a single percent sign, use the form ``%%'' within the format string.

warn-if-locked (global; duration: default=15m)
If another instance of filewatcher has locked the archive for too long, then this will cause a warning to be generated. Otherwise, the new process will silently exit.

warn-if-empty (per-file; boolean: default=false)
If this option is true, then a warning will be issued if a watch directive references a file that has zero size.

warn-if-missing (per-file; boolean: default=true)
If this option is true, then a warning will be issued if a watch directive references a file or directory name that does not exist. A warning will similarly be issued if a glob pattern is referenced and that pattern fails to expand to any existing file or directory names.

SAMPLE CONFIGURATION

    option archive-root /var/filewatcher/archive
    option state-file /var/filewatcher/state
    option warn-if-missing true
    option include-autopush true
    option skip-binary true
    # default notify via email to sysadm address
    option notify mailto:root
    # scan for archived files deleted from the filesystem
    option scan-frequency 4h
    watch ARCHIVE
    # system security files
    option scan-frequency 5m
    watch /etc/passwd
    watch /etc/group
    watch /etc/sudoers
    # filewatcher and its configuration files
    option scan-frequency 30m
    watch /var/filewatcher/conf/*.cf
    watch /usr/local/bin/filewatcher
    # sendmail
    option scan-frequency 30m
    watch /etc/sendmail.cf
    watch /etc/aliases
    watch /etc/mail
    except /etc/mail/*.db


AUTHOR

Mark D. Nagel <mnagel@willingminds.com>