This is cfengine-Reference.info, produced by makeinfo version 4.2 from
cfengine-Reference.texinfo.

INFO-DIR-SECTION System Utilities
START-INFO-DIR-ENTRY
* cfengine Reference: (cfengine-Reference.info).
                        Cfengine is a language based tool specifically
                        designed for configuring and maintaining BSD
                        and System-5-like operating systems attached
                        to a TCP/IP network.
END-INFO-DIR-ENTRY


File: cfengine-Reference.info,  Node: processes,  Next: packages,  Prev: mountables,  Up: Cfagent reference

processes
=========

   Using the processes facility, you can test for the existence of
processes, signal (kill) processes and optionally restart them again.
Cfengine opens a pipe from the system ps command and searches through
the output from this command using regular expressions to match the
lines of output from `ps'.  The regular expression does not have to be
an exact match, only a substring of the process line.  The form of a
process command is

     processes:
     
       CLASS::
     
         "QUOTED REGULAR EXPRESSION"
     
                             restart "SHELL COMMAND"
                             useshell=true/FALSE/DUMB
                             owner=RESTART-UID
                             group=RESTART-GID
                             chroot=DIRECTORY
                             chdir=DIRECTORY
                             umask=MASK
     
                             signal=SIGNAL NAME
                             matches=NUMBER
                             define=CLASSLIST
                             elsedefine=CLASSLIST
     
                             action=signal/DO/WARN/BYMATCH
                             include=LITERAL
                             exclude=LITERAL
                             filter=FILTER_NAME
     
                             syslog=TRUE/ON/FALSE/OFF
                             inform=TRUE/ON/FALSE/OFF
                             ifelapsed=MINS
                             expireafter=MINS
     
         SetOptionString "QUOTED OPTION STRING"

   By default, the options sent to ps are "-aux" for BSD systems and
"-ef" for System V.  You can use the `SetOptionString' command to
redefine the option string. Cfengine assumes only that the first
identifiable number on each line is the process identifier for the
processes, so you must not choose options for ps which change this
basic requirement (this is not a problem in practice). Cfengine reads
the output of the ps-command normally only once, and searches through
it in memory. The process table is only re-consulted if
`SetOptionString' is called. The options have the following meanings:

`signal=SIGNAL NAME'
     This option defines the name of a signal which is to be sent to
     all processes matching the quoted regular expression. If this
     option is omitted, no signal is sent. The signal names have the
     usual meanings. The full list, with largely standardized meanings,
     is

             hup       1   hang-up
             int       2   interrupt
             quit      3   quit
             ill       4   illegal instruction
             trap      5   trace trap
             iot       6   iot instruction
             emt       7   emt instruction
             fpe       8   floating point exception
             kill      9   kill signal
             bus      10   bus error
             segv     11   segmentation fault
             sys      12   bad argument to system call
             pipe     13   write to non existent pipe
             alrm     14   alarm clock
             term     15   software termination signal
             urg      16   urgent condition on I/O channel
             stop     17   stop signal (not from tty)
             tstp     18   stop from tty
             cont     19   continue
             chld     20   to parent on child exit/stop
             gttin    21   to readers pgrp upon background tty read
             gttou    22   like TTIN for output if (tp->t_local&LTOSTOP)
             io       23   input/output possible signal
             xcpu     24   exceeded CPU time limit
             xfsz     25   exceeded file size limit
             vtalrm   26   virtual time alarm
             prof     27   profiling time alarm
             winch    28   window changed
             lost     29   resource lost (eg, record-lock lost)
             usr1     30   user defined signal 1
             usr2     31   user defined signal 2

     Note that cfengine will not attempt to signal or restart processes
     0 to 3 on any system since such an attempt could bring down the
     system. The only exception is that the hangup (hup) signal may be
     sent to process 1 (init) which normally forces init to reread its
     terminal configuration files.

`restart "SHELL COMMAND"'
     Note the syntax: there is no equals sign here.  If the keyword
     `restart' appears, then the next quoted string is interpreted as a
     shell command which is to be executed after any signals have been
     sent.  This command is only issued if the number of processes
     matching the specified regular expression is zero, or if the
     signal sent was signal 9 (sigkill) or 15 (sigterm) , i.e.  the
     normal termination signals.  This could be used to restart a
     daemon for instance. Cfengine executes this command and _waits_
     for its completion so you should normally only use this feature to
     execute non-blocking commands, such as daemons which dissociate
     themselves from the I/O stream and place themselves in the
     background. Some unices leave a hanging pipe on restart (they never
     manage to detect the end of file condition). This occurs on
     POSIX.1 and SVR4 popen calls which use wait4. For some reason they
     fail to find and end-of-file for an exiting child process and go
     into a deadlock trying to read from an already dead process. This
     leaves a zombie behind (the parent daemon process which forked and
     was supposed to exit) though the child continues.  A way around
     this is to use a wrapper script which prints the line
     "cfengine-die" to STDOUT after restarting the process. This causes
     cfengine to close the pipe forcibly and continue.  Cfengine places
     a timeout on the restart process and attempts to clean up zombies,
     but you should be aware of this possibility.

`owner=,group='
     Sets the process uid and gid (setuid,gid) for processes which are
     restarted. This applies only to cfengine run by root.

`chroot'
     Changes the process root directory of the restarted process,
     creating a `sandbox' which the process cannot escape from. Best
     used together with a change of owner, since a root process can
     break out of such a confinement in principle.

`chdir'
     Change the current working directory of the restarted process.

`useshell=TRUE/FALSE/DUMB'
     When restarting processes, cfengine normally uses a shell to
     interpret and execute the restart command. This has inherent
     security problems associated with it. If you set this option to
     false, cfengine executes restart commands without using a shell.
     This is recommended, but it does mean that you cannot use any
     shell operators or features in the restart command-line.

     Some programs (like cron) do not handle I/O properly when they fork
     their daemon parts, this causes a zombie process and normally
     hangs cfengine. By choosing the value `dumb' for this, cfengine
     ignores all output from a program and does not use a startup shell.
     This prevents programs like cron from hanging cfengine.

`matches=NUMBER'
     This option may be used to set a maximum, minimum or exact number
     of matches. If cfengine doesn't find a number of matches to the
     regular expression which is in accordance with this value it
     signals a warning.  The `<', `>' symbols are used  to specify
     upper and lower limits. For example,

            matches=<6  # warn number of matches is greater than or equal to 6
            matches=1   # warn if not exactly 1 matching process
            matches=>2  # warn if there are less than or equal to 2 matching processes

`include=LITERAL'
     Items listed as includes provide an extra level of selection after
     the regular expression matches have been expanded. If you include
     one include option, then only lines containing one or more of the
     literal strings or wildcards will be matched.

`exclude=LITERAL'
     Process lines containing literal strings or wildcards in exclude
     statements are not matched. Excludes are processed after regular
     expression matching and after includes.

`define=CLASSLIST'
     The colon, comma or dot separated list of classes becomes
     activated if the number of regular expression matches is non-zero.

`elsedefine=CLASSLIST'
     The colon, comma or dot separated list of classes becomes
     activated if the number of regular expression matches is zero.

`action=SIGNAL/DO/WARN/BYMATCH'
     The default value of this option is to silently send a signal (if
     one was defined using the `signal' option) to matching processes.
     This is equivalent to setting the value of this parameter to
     `signal' or `do'. If you set this option to `warn', cfengine sends
     no signal, but prints a message detailing the processes which
     match the regular expression.  If the option is set to `bymatch',
     then signals are only sent to the processes if the matches
     criteria fail.

   Here is an example script which sends the hang-up signal to cron,
forcing it to reread its crontab files:


     processes:
     
        "cron" signal=hup

Here is a second example which may be used to restart the nameservice
on a Solaris system:


     processes:
     
        solaris::
     
            "named" signal=kill restart "/usr/sbin/in.named"

A more complex match could be used to look for processes belonging to a
particular user. Here is a script which kills ftp related processes
belonging to a particular user who is known to spend the whole day
FTP-ing files:


     control:
     
         actionsequence = ( processes )
     
       #
       # Set a kill signal here for convenience
       #
     
         sig = ( kill )
     
       #
       # Better not find that dumpster here!
       #
     
         matches = ( 1 )
     
     processes:
     
        #
        #  Look for Johnny Mnemonic trying to dump his head, user = jmnemon
        #
     
        ".*jmnemon.*ftp.*" signal=$(sig) matches=<$(matches) action=$(do)
     
        # No mercy!

The regular expression `.*' matches any number of characters, so this
command searches for a line containing both the username and something
to do with ftp and sends these processes the kill signal.

   You can arrange for signals to be sent, only if the number of matches
fails the test. The `action=bymatch' option is used for this.  For
instance, to kill process `XXX' only if the number of matches is
greater than 20, one would write:


     processes:
     
     "XXX" matches=<20  action=bymatch signal=kill

   See also filters *Note filters::, for more complex searches.


File: cfengine-Reference.info,  Node: packages,  Next: rename,  Prev: processes,  Up: Cfagent reference

packages
========

   The packages action allows you to check for the existance of packages
on the system, as determined by the package database you select.
Optionally, if a package install command was specified, the package can
be installed if it is not there.

   This operation is set up such that it tries not to make assumptions
about the package manager in use.  For example, it should be possible
to use RPM on a Solaris box.

   The syntax summary is:


     packages:
     
        CLASS::
     
           PACKAGE-NAME
                             pkgmgr=none/RPM/DPKG/SUN
                             cmp=eq/LT/GT/GE/LE/NE
                             version=VERSION-STRING
                             define=CLASS-LIST(,:.)
                             elsedefine=CLASS-LIST(,:.)
                             action=none/INSTALL/REMOVE
     
                             ifelapsed=MINS
                             expireafter=MINS

`cmp'
     Determines how the version of the installed package will be
     compared to that specified by the `version' attribute.  Possible
     values include:

        * `eq' The version installed must be equal to `version'

        * `lt' The version installed must be less than `version'

        * `gt' The version installed must be greater than `version'

        * `le' The version installed must be less than or equal to
          `version'

        * `ge' The version installed must be creater than or equal to
          `version'

        * `ne' The version installed must not be equal to `version'

     The default value for this attribute is `eq'.

`version'
     Specifies the package manager specific version string to match.  If
     this is not specified, then any version matches, and the value of
     the `cmp' attribute is ignored.  See the allowed values of
     `pkgmgr' below for an explation of how each package manager will
     interpret this.

`pkgmgr'
     Selects the package manager database to query.  This defaults to
     either the value of the `DefaultPkgMgr' variable, or if that is
     not set, there is no default.  In that case, no checking will be
     done unless `pkgmgr' is set explicitly for each package.  Note
     that the default value '`none'' listed is merely a pseudo-value,
     and cannot actually be used, since it would make no sense anyway.

     Each package manager will interpret the `version' and `cmp'
     attributes in its own way.  So, for example, when you use
     `pkgmgr=rpm', the comparison will be done with the same rules that
     RPM use if it were not being run through cfengine.

     Currently, the following values are accepted:

    `rpm'
          This uses the rpm command, which cfengine expects to find as
          `/bin/rpm' to query the machine's RPM database.  The `rpm'
          check assumes that you are using a version of RPM that
          understands the concept of an epoch, which means that you
          will want to use RPM version 3.0.3 or greater.  Versions as
          early as 2.5.6 may work, but it is doubtful.  If multiple
          packages of the same name are installed (i.e. kernel), then
          the check considers the package to be installed at the
          specified version if at least one of them satisifies the
          criteria specified by `cmp' and `version'.

          The format of a RPM version string is:
          [epoch:]version[-release].  The version[-release] can be seen
          by simply running: `rpm -q <pkg>'.  In order to see the
          epoch, you must use a query format, like this: `rpm -q
          --queryformat "%{EPOCH}:%{VERSION}-%{RELEASE}\n" <pkg>'.
          Most packages do not have an epoch, and will print `(none)'
          in the epoch space.  In recent incarnations of RPM, the
          absense of an epoch is interpreted as 0.  This is also how
          cfengine will interpret it.  _Be careful with this.  If the
          installed version of a package has an epoch greater than 0,
          and you do not specify the epoch, unexpected results may
          happen._  For example, if you have a package installed,
          `foo-1:2.0-1', and you specify a `version=3.0-1' and a
          `cmp=gt', the check will be true, because the installed
          version has an epoch of 1, and you did not specify an epoch,
          which implies you wanted an epoch of 0.  The rule here is
          basically to always check the epoch of the package you really
          want, and specify it.  It may take a few extra extra seconds
          to check, but it will save you lots of headaches later.

    `dpkg'
          Please document me!

    `sun'
          Please document me!

`define'
     Specifies the list of classes to define if the specified package is
     installed.

`elsedefine'
     Specifies the list of classes to define if the specified package
     is not installed.

`action'
     Specifies whether the packages should actually do anything about
     the situation it finds.  The default for this is to do nothing.
     Of course, the classes in `define' and `elsedefine' will alwass be
     defined, as applicable, regardless of the action specified.

    `install'
          Installs the package using the command associated with the
          selected package manager, if it is not currently on the
          system at the requested version, as follows:

             * RPM - RPMInstallCommand

             * DPKG - DPKGInstallCommand

             * SUN - SUNInstallCommand

          Each variable is of the format:

               FOOInstallCommand = ( "/usr/bin/foo --args %s --more-args" )

          The --args are of course optional.  The %s is replaced with a
          space-separated list of the package names that were checked,
          and found to not be installed.

    `remove'
          CURRENTLY PARSED BUT NOT IMPLEMENTED

NOTE: classes are defined according to the result of the check, not any
action performed as a result of that check.  In otherwords, if for
example you have a situation where a package is not installed, and the
action= is set to install, the classes in `elsedefine' will be defined
regardless of whether or not the install was successful.  Assuming the
package installed, the next run of cfagent will pick up that fact.
This has to be done since the package installs are batched, so there is
no reliable way to know if a given package was installed.

Examples:

     packages:
     
         redhat_8_0::
             m4  version=0:1.4.1-11 cmp=eq pkgmgr=rpm elsedefine=needsm4

In this first example, we are looking for the m4 package at exactly
version 0:1.4.1-11.  The installed m4 package on a redhat_8_0 box has
no epoch which is the same as zero.  Specifying it will keep you out of
trouble.  This check will cause `needsm4' to be defined if the exact
version of m4 specified is not installed.

     control:
         redhat:;
             DefaultPkgMgr = ( rpm )
     
     packages:
         redhat_8_0::
             make version=0:4.5-2 cmp=ge define=hasmake elsedefine=needsmake

In the second example, we use the DefaultPkgMgr variable to set the
default for the `pkgmgr' attribute to `rpm'.  The actual version of make
installed on recent redhat_8_0 machine is 1:3.79.1-14.  Since the check
is for greater than or equal to this version, the hasmake class will be
defined.

     control:
         redhat:;
             DefaultPkgMgr = ( rpm )
             RPMInstallCommand = ( "/usr/sbin/up2date %s" )
     
     packages:
         redhat_8_0::
             make define=hasmake elsedefine=needsmake action=install

This example is much like the second example, except that if the
package is not installed, cfengine will attempt to install it using the
command in RPMInstallCommand, replacing the %s with the package name,
`make'.  If there were multiple packages specified in this way, the
package installation would occur at the end of the package checks, and
one command would be run, with %s replaced with a list of all package
names.  In this example we chose not to use a version spec, but it is
allowed, and as always, is optional.

NOTE here that if make was not installed when the check is made,
`needsmake' is defined, regardless of whether or not the install
succeeds.  If the install is successful, the next cfagent run will
define `hasmake'.


File: cfengine-Reference.info,  Node: rename,  Next: required,  Prev: packages,  Up: Cfagent reference

rename
======

   As of version 2.1.0 rename is a synonym for disable, *Note disable::.


File: cfengine-Reference.info,  Node: required,  Next: resolve,  Prev: rename,  Up: Cfagent reference

required
========

   This is a synonym for disks, *Note disks::.  This action tests for
the existence of a file or filesystem.  It should be called after all
NFS filesystems have been mounted.  You may use the special variable
`$(binserver)' here.


       required:
     
         /FILESYSTEM freespace=SIZE-LIMIT define=CLASS-LIST(,:.)
     
          ifelapsed=MINS expireafter=MINS

   Files or filesystems which you consider to be essential to the
operation of the system can be declared as `required'.  Cfengine will
warn if such files are not found, or if they look funny.

   Suppose you mount your filesystem `/usr/local' via NFS from some
binary server.  You might want to check that this filesystem is not
empty! This might occur if the filesystem was actually _not_ mounted as
expected, but failed for some reason.  It is therefore not enough to
check whether the directory `/usr/local' exists, one must also check
whether it contains anything sensible.

   Cfengine uses two variables: `sensiblesize' and `sensiblecount' to
figure out whether a file or filesystem is sensible or not.  You can
change the default values of these variables (which are 1000 and 2
respectively) in the `control' section.  *Note control::.

   If a file is smaller than `sensiblesize' or does not exist, it fails
the `required' test.  If a directory does not exist, or contains fewer
than `sensiblecount' files, then it also fails the test and a warning
is issued.


     required:
     
        any::
     
           /$(site)/$(binserver)/local

   If you set the `freespace' variable to a value (the default units
are kilobytes, but you may specify bytes or megabytes), e.g.


     required:
     
       /site/host/home1 freespace=50mb define=dotidy
       /site/host/home2 freespace=10% define=dotidy

then cfengine will warn when the filesystem concerned has less than this
amount of free space. By adding a `define' tag, you can switch on any
number of classes if this happens. This allows you to activate special
measures for dealing with a filesystem which is in danger of becoming
full.


File: cfengine-Reference.info,  Node: resolve,  Next: shellcommands,  Prev: required,  Up: Cfagent reference

resolve
=======

   The file `/etc/resolv.conf' specifies the default nameserver for
each host, as well as the local domain name.  This file can also contain
other information, but these are the only two things cfengine currently
cares about.  In specifying nameservers you should use the dotted
numerical form of the IP addresses since your system may not understand
the text form if it is not correctly configured.  You may list as many
nameservers as you wish, with the default server at the top of the list.
The resolver normally ignores entries if you add more than three.  The
statement:


     resolve:
     
       mygroup::
     
          129.240.22.35
          129.240.22.222
          129.240.2.3

declares a list of nameservers for hosts in the group or class
`mygroup'.  When you add the `resolve' command to the `actionsequence',
this declaration together with the `domain' variable (set here to
`uio.no') results in a `/etc/resolv.conf' file of the form:


     domain uio.no
     nameserver 129.240.22.35
     nameserver 129.240.22.222
     nameserver 129.240.2.3

Note that the `resolve' action does not delete anything from the file
`/etc/resolv.conf' unless the `EmptyResolveConf' variable is set to
'true' .  It adds nameservers which do not previously exist and
reorders the lines of servers which do exist.

   As of version 1.3.11, you may use a quoted string to add
non-nameserver lines to this file. For example:


     resolve:
     
       mygroup::
     
          129.240.22.35
          129.240.22.222
          "# Comment line"
          "order bind, files"

If the line begins with a non-numeric character, the word `nameserver'
is not added to the line.


File: cfengine-Reference.info,  Node: shellcommands,  Next: strategies,  Prev: resolve,  Up: Cfagent reference

shellcommands
=============

   Cfengine focuses on fairly simple-minded tasks in order to be as
general as possible.  In many cases, you will therefore want to write a
script to do something special on your system.  You can still take
advantage of the classes you have defined by executing these scripts or
shell commands from this section.

   The syntax is simply to quote the command you wish to be executed.

     shellcommands:
     
       CLASS::
     
         "COMMAND-STRING"
     
               timeout=SECONDS
               useshell=true/FALSE
               umask=OCTAL NUMBER
               owner=UID
               group=GID
     
               background=false/TRUE
               chdir=DIRECTORY
               chroot=DIRECTORY
               preview=TRUE/false
               inform=false/TRUE
     
               noabspath=false/TRUE
     
               ifelapsed=MINS
               expireafter=MINS
     
               define=CLASS-LIST
               elsedefine=CLASS-LIST

`COMMAND-STRING'
     This is the command to be executed.

`TIMEOUT'
     If you set the optional TIMEOUT parameter, then cfengine will
     abort the specified shellcommand if it exceeds the given
     time-limit (specified in seconds).  This can be useful for
     avoiding hung programs caused by hung network connections, etc.

`USESHELL'
     Some program lines, especially those that do not use any
     shell-specific capabilities (such as redirection and wildcard
     expansion) can be run without the shell.  This is typically more
     secure, as the command line is not altered by the user or by the
     system.  It is also faster, as the shell does not have to be
     spawned in order to run the given command.  Use the USESHELL
     parameter to tell cfengine to not use the shell to run this
     shellcommand.

`UMASK'
     The umask affects the permissions given to a file created by this
     shellcommand.  The umask specifies, specifically, the permissions
     that are to be taken away.

`OWNER'

`GROUP'
     The user and group ID's of the process can be set (using the OWNER
     and GROUP parameters respectively) to restrict the permissions of
     the shellcommand. This can only be done if cfengine is executed by
     root; otherwise, the user and group will remain that of the the
     user who started cfengine.

`BACKGROUND'
     Run this command in the background if this is specified true.
     This will make cfengine run faster, but no tests can be made (at
     least directly) on the results of this command.

`CHDIR'
     Change to the specified directory before running this command.

`CHROOT'
     The `chroot' option changes the process root directory of the
     command, creating a `sandbox' which the process cannot escape
     from. Best used together with a change of owner (using the `owner'
     parameter), since a root process can break out of a chrooted
     environment.

`PREVIEW'
     The `preview' option means that the shellcommand will also be
     executed during the `--dry-run' (`-n') options. This allows
     cfengine to be more aware of the results of scripts which define
     classes. This option should be used with care.

     Scripts should conform to the protocol of not executing
     unnecessary commands when the classes `opt_dry_run' is defined.

`INFORM'

`NOABSPATH'
     Normally, cfagent requires the command string to begin with a `/'
     since it is dangerous to rely on an implicit path. However,
     sometimes it it is appropriate to override this.  This behavior
     can be overridden using the NOABSPATH parameter.

`IFELAPSED'
     The shellcommand specified will not be run unless the specified
     amount of time (in minutes) has elapsed since the command was
     previously run.

`EXPIREAFTER'
     If this amount of time (in minutes) has elapsed since the command
     started, then the command is aborted.

`DEFINE'
     Define the specified classes if the command finishes successfully.

`ELSEDEFINE'
     Define the specified classes if the command does not finish
     successfully.

Variable substitution works within the strings.  Here are some examples.


     shellcommands:
     
        sun4::
     
            "/usr/lib/find/updatedb"
     
        AllHomeServers.Sunday::
     
            "/dir/noseyparker /$(site)/$(host)/u1 $(sysadm) nomail"
     
        AllBinaryServers.sun4.Saturday::
     
           "/usr/etc/catman -w -M /usr/local/man"
           "/usr/etc/catman -w -M /usr/local/X11R5/man"
           "/usr/etc/catman -w -M /usr/man"
           "/usr/etc/catman -w -M /usr/local/gnu/man"

If you need to write more advanced scripts which make detailed use of
the classes defined by cfengine, use the `$(allclasses)' variable to
send a complete list of classes to your script.  An enviornment
variable, CFALLCLASSES, is set and is in the format


     CFALLCLASSES=class1:class2:class3...

This variable is kept up-to-date at any given time with only the classes
which are defined.  The command line option `-u' or `--use-env' can be
used to define an environment variable which will be inherited by all
scripts and contains the same information.  This is not the standard
approach, since some systems cannot cope with this rapid change of
environment and generate a Bus Error.

   Commands can be iterated over variable lists, provided there is at
least one space between each variable. For example:


     control:
     
           actionsequence =
              (
              shellcommands
              )
     
      var1 = ( a:b:c )
      var2 = ( x:y:z )
     
     shellcommands:
     
        "/bin/echo $(var1) $(var2)"

This iterates over all values of the list variables. *Note Iterating
over lists: (cfengine-Tutorial)Iterating over lists.  If you are
iterating over a list, the time limit (in seconds) which is specified
in the TIMEOUT parameter applies to each separate iteration, not to the
sum total of all the iterations.


File: cfengine-Reference.info,  Node: strategies,  Next: tidy,  Prev: shellcommands,  Up: Cfagent reference

strategies
==========

   Strategies (introduced in cfengine version 2.0) are a way of picking
from a set of classes randomly.  Each class is a possible course of
action.  A strategy group (of classes) is defined as follows:

     strategies:
     
       { my_strategy_alias
     
       class1: "2"
       class2: "3"
       class3: "$(value)"
       class4: "6"
       class5: "1"
       }
     
     tidy:
     
      class1.Hr00::
     
        /home pat=*.mp3 age=0
     
      class2.Hr02::
     
        /home pat=*.wav age=0

   The idea here is to randomly pick from a selected set of classes.

   Specifically, each strategy is a class which is defined with a
certain probability. An integer weight is provided in quotes to
represent the probability weight of the associated class. When cfengine
is run, it randomly picks one of the classes from each strategy.  Using
strategies, you can choose different ways of configuring or protecting
a system, at random, thus confounding environmental attempts to break
into the system.

   Note that each strategy has a formal name (such as
`my_strategy_alias' in the example), but this name is not used to
attach a strategy to an action the same way that filters or ACLs are.


File: cfengine-Reference.info,  Node: tidy,  Next: unmount,  Prev: strategies,  Up: Cfagent reference

tidy
====

   The tidy function is used to delete (remove permanently) unwanted
files from a system.  It is useful for tidying up in `/tmp' or cleaning
out `core' files from users' home directories.  The form of an entry is:

     tidy:
     
       CLASS::
     
           /DIRECTORY
                            pattern/include=WILDCARD
     
                            recurse=NUMBER/INF
                            age=DAYS
                            size=NUMBER/EMPTY
                            type=CTIME/MTIME/atime
                            dirlinks=KEEP/TIDY/DELETE
                            rmdirs=[TRUE/ALL]/[FALSE/NONE]/SUB
                            links=stop/keep/TRAVERSE/TIDY
     
                            define=CLASSLIST
                            elsedefine=CLASSLIST
     
                            syslog=TRUE/ON/FALSE/OFF
                            inform=TRUE/ON/FALSE/OFF
                            ifelapsed=MINS
                            expireafter=MINS
     
                            filter=FILTER ALIAS
                            ignore=PATTERN
                            exclude=PATTERN
                            xdev=TRUE/ON/false/off

Note that, each of the options below can be written in either upper or
lower case and abbreviated by any unique abbreviation.

`/DIRECTORY'
     This is the directory name to directories which mark the start of a
     search for files matching certain wildcards.  The wildcard `home'
     may be used instead of an explicit directory, in which case
     cfengine iterates over all home directories.  It is compulsory to
     specify a directory.

`pattern=WILDCARD or include=WILDCARD'
     A wildcard or filename to match the files you wish to be deleted.
     The pattern may contain the special symbols `?' which matches a
     single character and `*' which matches any number of characters as
     in the shell. These two options are synonymous, as of version
     2.0.x.  Note that, this pattern is processed as a filter before
     any other filter and, for safety reasons, it defaults to nothing.
     Thus, if you want to use a filter to select the files, you should
     set `pattern=*', else the filter will not see any files at all.

`exclude=WILDCARD'
     This does not work for the home directive; use the global ignore
     list for this.

`ignore=WILDCARD'
     This does not work for the home directive; use the global ignore
     list for this.

`recurse=NUMBER/INF'
     This specifier tells cfengine whether or not to recurse into
     subdirectories.  If the value is zero, only the named file or
     directory is affected.  If the value is 1, it will open at most
     one level of subdirectory and affect the files within this scope.
     If the value is `inf' then cfengine opens all subdirectories and
     files beginning from the specified filename. *Note Recursion::.

`age=DAYS'
     The age of a file in days represents a minimum _access_ time
     elapsed before the file will be deleted.  In other word a file
     will be deleted if it has not been accessed for DAYS days.

`links=STOP/TRAVERSE/TIDY'
     Normally cfengine does not descend into subdirectories which are
     pointed to by symbolic links.  If you wish to force it to do so
     (without using the `-l' command line option) you may give this
     option the value `true', or `traverse', or `follow'.  To specify no
     recursion you set the value `false' or `stop'.  Note that the
     value set here in the cfengine program _always overrides_ the
     value set by the `-l' command line option, so you can protect
     certain actions from this command line option by specifying a
     negative value here.  If you specify no value here, the behaviour
     is determined by what you specify on the command line.

     The value `links=tidy' has the same effect as the `-L' command
     line option except that here it may be specified per item rather
     than globally.  Setting this value causes links which point to
     non-existent files to be deleted. This feature will not work on
     commands with the `home' wildcard feature.  If you want to clean
     up old links you should either user a `files' command or the
     command line option which sets the tidy feature globally.

`size=>NUMBER/EMPTY'
     Old syntax `size=NUMBER/EMPTY'.  The value of this parameter
     decides the size of files to be deleted.  Files larger than this
     value will be deleted if they also are older than the time
     specified in `age'. The default size is zero so that any file
     which gets matched by another critereon is deleted. However, if you
     want to single out only totally empty files, the `empty' may be
     used.  With this option only empty files, nevery files with
     anything in them,  will be deleted, if older than `age'. By
     default, the filesizes are in kilobytes, but kilobytes and
     megabytes may also be specified by appending b,k,m to the numbers.
     Only the first character after the number is significant so you
     may write the numbers however it might be convenient, e.g. `14k',
     `14kB', `14kilobytes', the same as for `disable'.

`type=CTIME/MTIME/ATIME'
     This value is used to set the type of time comparison made using
     `age'. The default is to compare access times (atime) or the last
     time the file was read. A comparison by modification time (mtime)
     uses the last time the contents of the file was changed. The ctime
     parameter is the last time the contents, owner or permissions of
     the file were changed. Note that on directories, mtime is always
     used for comparisons, since the very act of stat'ing alters atime
     and makes this comparison meaningless.

`dirlinks=KEEP/TIDY/DELETE'
     This value is used to decide whether cfengine will delete links
     which point to directories. The default value is to keep the
     links. Note that, if the `travlinks' option is switched on,
     cfengine will not tidy or delete links which point to directories,
     instead it follows them into the subdirectory. This is a supplement
     to the `rmdirs' option. You need both to make links to directories
     disappear. Note that, even if `travlinks' is set to true, cfagent
     will not follow symbolic links that are not owned by the agent
     user ID; this is to prevent link race attacks, in which users with
     write access could divert the agent to another part of the
     filesystem,

`rmdirs=TRUE/FALSE/ALL/SUB'
     Normally cfengine will not delete directories. If this option is
     set to `true' then cfengine will delete any directories which are
     _empty_. Non-empty directories will not be touched and no message
     will be given unless in verbose mode. Note that this option
     overrides the above option `dirlinks', so that even links which
     point to empty directories will be removed.  If this is set to
     `sub' then the topmost directory will not be removed, only
     sub-directories.

`define=CLASSLIST'
     The colon, comma or dot separated list of classes becomes defined
     if any file matching the specified pattern is deleted.

`xdev'
     Prevents cfengine from descending into file systems that are not
     on the same device as the root of the rescurion path.

   Take a look at the following example:

     tidy:
     
        AllHomeServers::
     
            home     pattern=core   R=inf age=0
            home     pattern=*~     R=inf age=7
            home     pattern=#*     R=inf age=30
     
     
        any::
     
            /tmp/    pat=*            R=inf   age=1
            /        pat=core         R=2     age=0
            /etc     pat=hosts.equiv  r=0     age=0

   In the first example, all hosts in the group `AllHomeServers'
iterate a search over all user home directories looking for `core' files
(older than zero days) and `emacs' backup files `*~', `#*' older than
seven days.

   The default values for these options are the empty string for the
wildcard pattern, zero for the recursion and a specification of the age
is compulsory.

   When cfengine tidies users' home directories, it keeps a log of all
the files it deletes each time it is run.  This means that, in case of
accidents, the user can see that the file has been deleted and restore
it from backup.  The log file is called `.cfengine.rm' and it is placed
in the home directory of each user.  The file is owned by root, but is
readable to the user concerned.


File: cfengine-Reference.info,  Node: unmount,  Prev: tidy,  Up: Cfagent reference

unmount
=======

   The unmount function unmounts non-required filesystems and removes
the appropriate entry from the filesystem table (`/etc/fstab' or
equivalent).  The syntax is simply

     unmount:
     
        CLASS::
     
           MOUNTHOST:FILESYSTEM
     
             deletedir=TRUE/FALSE
             deletefstab=TRUE/FALSE
             force=TRUE/FALSE
             ifelapsed=MINS
             expireafter=MINS

The options allow you to temporarily unmount a directory without
actually removing it from the filesystem table. The option `force' is
not currently implemented and will likely have to be system dependent.
For example:

     unmount:
     
        physics::
     
           libraryserver:/$(site)/libraryserver/data

If the device is busy then the actual unmount will not take place until
it becomes free, or the machine is rebooted.  This feature should work
on AIX systems, in spite of these machines inherent peculiarities in the
form of the filesystem table.

   Some users do not mount filesystems on a directory of the same name
as the source directory. This can lead to confusion.  Note, if you have
problems removing a mounted filesystem, try using the mountpoint of the
filesystem, rather than the name of the filesystem itself, in the
unmount command.


File: cfengine-Reference.info,  Node: Cfservd.conf and cfrun reference,  Next: Cfexecd reference,  Prev: Cfagent reference,  Up: Top

Cfservd and cfrun reference
***************************

* Menu:

* cfservd control::
* admit grant and deny::
* cfrun::
* Firewalls and NATs::

   The server daemon is controlled by a file called `cfservd.conf'.
The syntax of this configuration file is deliberately modelled on
cfengine's own configuration file, but despite the similarities, they
are separate.

   You can use `groups' and `import' in both files to break up files
into convenient modules and to import common resources, such as lists
of groups.

   Note that the classes in the `cfservd.conf' file do not tell you the
classes of host which have access to files and directories, but rather
which classes of host pay attention to the access and deny commands when
the file is parsed.

   Authentication is not by class or group but by hostname, like the
`/etc/exports' file on most Unix systems. The syntax for the file is as
follows:


      control:
     
        CLASSES::
     
            domain = ( DNS-DOMAIN-NAME )
     
            cfrunCommand = ( "SCRIPT/FILENAME" )  # Quoted
     
            MaxConnections = ( MAXIMUM NUMBER OF FORKED DAEMONS )
     
            ChecksumDatabase = ( FILENAME )
     
            IfElapsed = ( TIME-IN-MINUTES )
     
            DenyBadClocks = ( FALSE )
     
            AllowConnectionsFrom = ( IP NUMBERS )
     
            DenyConnectionsFrom = ( IP NUMBERS )
     
            AllMultipleConnectionsFrom = ( IP NUMBERS )
     
            TrustKeysFrom  = ( IP NUMBERS )
     
            AllowUsers = ( mark systemuser )
     
            LogAllConnections = ( FALSE/TRUE )
     
            SkipVerify = ( IP NUMBERS )
     
            DynamicAddresses = ( IP NUMBERS )
     
            BindToInterface = ( IP NUMBER/HOSTNAME )
     
            HostnameKeys = ( TRUE/FALSE )
     
      groups:
     
        GROUP DEFINITIONS
     
      import:
     
        FILES TO IMPORT
     
      admit: | grant:
     
        CLASSES::
     
           /FILE-OR-DIRECTORY
     
             WILDCARDS/HOSTNAMES
     
      deny:
     
        CLASSES::
     
           /FILE-OR-DIRECTORY
     
             WILDCARDS/HOSTNAMES root=HOSTLIST encrypt=TRUE/ON


   Iteration of variables is allowed, hence:

     	control:
     	  Split = ( " " )
     	  hostlist = ( "10.10.10.1 10.10.10.2 10.10.10.3" )
     	  dirs =  ( "bin etc lib" )
     	  base = ( /usr )
     
     	#########################################################
     
     	admit:
     	   $(base)/$(dirs)   $(hostlist)
results in:

     	Path: /usr/bin (encrypt=0)
     	   Admit: 10.10.10.1 10.10.10.2 10.10.10.3 root=
     	Path: /usr/etc (encrypt=0)
     	   Admit: 10.10.10.1 10.10.10.2 10.10.10.3 root=
     	Path: /usr/lib (encrypt=0)
     	   Admit: 10.10.10.1 10.10.10.2 10.10.10.3 root=

   The file consists of a control section and access information.


File: cfengine-Reference.info,  Node: cfservd control,  Next: admit grant and deny,  Prev: Cfservd.conf and cfrun reference,  Up: Cfservd.conf and cfrun reference

control
=======

* Menu:

* IP address ranges::
* AllowConnectionsFrom::
* AllowMultipleConnectionsFrom::
* AllowUsers::
* AutoExecCommand::
* AutoExecInterval::
* BindToInterface::
* ChecksumDatabase in cfservd::
* cfrunCommand::
* DenyBadClocks::
* DenyConnectionsFrom::
* cfservd HostnameKeys::
* cfservd IfElapsed::
* LogAllConnections::
* MaxConnections::
* TrustKeysFrom::
* DynamicAddresses::


File: cfengine-Reference.info,  Node: IP address ranges,  Next: AllowConnectionsFrom,  Prev: cfservd control,  Up: cfservd control

IP address ranges
-----------------

   In the access control lists below, host ranges can be specified in a
number of ways i) as substrings, ii) as address ranges denoted by the
"-" hyphen, or iii) as CIDR (Classless Inter Domain Routing) notation.
For example

     128.39.73
     128.39.74.10/23
     128.39.74-75.10-22
     2001:700:700:3:290:27ff:fea2:4730-4790
     2001:700:700:3:290:27ff:fea2:4730/64
   In the CIDR notation, the slash followed by a number indicates the
netmask, or the number of bits which are common to a group of hosts.
Normally, this is connected to a specific subnet, but here it simply
represents the number of bits from the left which are fixed for
matching; all remaining bits are wildcards.  The following forms are
equivalent:

     128.39.74.
     128.39.74.10/24
     128.39.74.1-254


File: cfengine-Reference.info,  Node: AllowConnectionsFrom,  Next: AllowMultipleConnectionsFrom,  Prev: IP address ranges,  Up: cfservd control

AllowConnectionsFrom
--------------------

   This variable allows a list of numerical IP masks to be specified,
which cfservd will allow connections from.  If the list is not empty
and a host whose IP address is not specified attempts to connect to the
daemon, its connection will be closed immediately.    This can be used
to prevent hanging connection attacks from malicous hosts and other
denial of service attacks which would bind thread resources.

          control:
     
           AllowConnectionsFrom = ( 128.39.89  192.2.0.10 )


File: cfengine-Reference.info,  Node: AllowMultipleConnectionsFrom,  Next: AllowUsers,  Prev: AllowConnectionsFrom,  Up: cfservd control

AllowMultipleConnectionsFrom
----------------------------

   This variable should contain a list of IP wildcards to hosts which
are allowed simultaneous sessions on the server. Hosts which are not in
this list are allowed to connect only once, i.e. they must terminate and
reconnect in order to establish a new session. This is to prevent a
possible attacker from opening multiple sockets and never closing them,
resulting in a denial of service attack. Hosts IP's can be placed here
if they could have overlapping copy sessions (e.g. long backup transfers
which can run over time). This prevents the error message "Multiple
connections denied/spam shield".


File: cfengine-Reference.info,  Node: AllowUsers,  Next: AutoExecCommand,  Prev: AllowMultipleConnectionsFrom,  Up: cfservd control

AllowUsers
----------

   This list determines which users are to be allowed to connect to the
daemon.  Note that there is no way of identifying users except by their
public keys.  If a malicious asserts their identity, when no public key
for the named user is known to the server, then they could spoof the
identity of that user.  All users who should be allowed to connect need
to be here.  This applies to use of cfrun.


     AllowUsers = ( mark root )

   In other words, this is a "security by obscurity" first defence
against picking up bad keys, when the server is in trust mode, with
respect to a host. The attacker must know a valid user name in order to
even try their luck entering into a key dialogue.

   This reduces the probability that spoofing can be successful. The
only real defence against spoofing is to make sure that all required
public keys are installed in advance, and to switch off trust.


File: cfengine-Reference.info,  Node: AutoExecCommand,  Next: AutoExecInterval,  Prev: AllowUsers,  Up: cfservd control

AutoExecCommand
---------------

   This variable no longer exists in cfengine version 2.


File: cfengine-Reference.info,  Node: AutoExecInterval,  Next: BindToInterface,  Prev: AutoExecCommand,  Up: cfservd control

AutoExecInterval
----------------

   This variable no longer exists in version 2 of cfengine.


File: cfengine-Reference.info,  Node: BindToInterface,  Next: ChecksumDatabase in cfservd,  Prev: AutoExecInterval,  Up: cfservd control

BindToInterface
---------------

   If this is set to a specific IP address of an IP configured
interface, cfservd will listen for connections only on that interface.
On Multi-homed hosts this allows one to restrict the traffic to one
interface. Note, Unix only allows one or all interfaces to be selected.
An interface must be configured with an IP address in order to be bound.


File: cfengine-Reference.info,  Node: ChecksumDatabase in cfservd,  Next: cfrunCommand,  Prev: BindToInterface,  Up: cfservd control

ChecksumDatabase
----------------

   This is the path and filename to a database which will cache MD5
checksum values server-side. This optimization is only available if you
have the Berkeley database library `libdb' on your system. If this
variable is not defined, no database caching will be used and checksum
values will be computed directly on request. The utility of this
solution is a trade-off between the time it takes to compute the
checksum versus the time for a disk-based lookup.


File: cfengine-Reference.info,  Node: cfrunCommand,  Next: DenyBadClocks,  Prev: ChecksumDatabase in cfservd,  Up: cfservd control

cfrunCommand
------------

   This string is the command which you would like to be executed
remotely by the `cfrun' command.

