This is cfengine-Reference.info, produced by makeinfo version 4.0 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: Top,  Next: Command reference,  Prev: (dir),  Up: (dir)

Cfengine-Reference
******************

   Copyright (C) 1995/96/97/98/99/2000 Mark Burgess

   Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
preserved on all copies.

   Permission is granted to copy and distribute modified versions of
this manual under the conditions for verbatim copying, provided also
that the section entitled "GNU General Public License" is included
exactly as in the original, and provided that the entire resulting
derived work is distributed under the terms of a permission notice
identical to this one.

   Permission is granted to copy and distribute translations of this
manual into another language, under the above conditions for modified
versions, except that the section entitled "GNU General Public License"
may be included in a translation approved by the author instead of in
the original English.

   This manual corresponds to CFENGINE Edition 1.6.3 for version 1.6.3
as last updated 1 December 2000.

* Menu:

* Command reference::
* Writing scripts for cfengine::
* Problem solving::
* Using the help scripts::
* Example configuration file::
* Runtime Options::
* Network protocol specs::
* Variable Index::
* Concept Index::
* FAQ Index::


File: cfengine-Reference.info,  Node: Command reference,  Next: Writing scripts for cfengine,  Prev: Top,  Up: Top

Command reference
*****************

   In this section you will find each facet of a cfengine program listed
together with an appropriate explanation.  The commands are presented in
alphabetical order for ease of lookup. Use this section in conjunction
with the example program *Note Example configuration file::.

* Menu:

* acl::
* binservers::
* broadcast::
* control::
* classes::
* copy::
* defaultroute::
* disks::
* directories::
* disable::
* editfiles::
* files::
* filters::
* groups::
* homeservers::
* ignore::
* import::
* interfaces::
* links::
* mailserver::
* miscmounts::
* mountables::
* processes::
* required::
* resolve::
* shellcommands::
* tidy::
* unmount::


File: cfengine-Reference.info,  Node: acl,  Next: binservers,  Prev: Command reference,  Up: Command reference

acl
===


        acl:
     
           CLASS::
     
              { ACL-ALIAS
     
              ACTION
              }

Cfengine's `ACL' feature is a common interface for managing filesystem
access control lists (ACLs). An access control list is an extended file
permission. It allows you to open or close a file to a named list of
users (without having to create a group for those users); similarly, it
allows you to open or close a file for a list of groups.  Several
operating systems have access control lists, but each typically has a
different syntax and different user interface to this facility, making
it very awkward to use.  This part of a cfengine configuration
simplifies the management of ACLs by providing a more convenient user
interface for controlling them and--as far as possible--a common syntax.

   An ACL may, by its very nature, contain a lot of information.
Normally you would set ACLs in a `files' command, *Note files::, or a
`copy' command, *Note copy::. It would be too cumbersome to repeat all
of the information in every command in your configuration, so cfengine
simplifies this by first associating an alias together with a complex
list of ACL information. This alias is then used to represent the whole
bundle of ACL entries in a `files' or `copy' command.  The form of an
ACL is similar to the form of an `editfiles' command.  It is a bundle
of information concerning a file's permissions.


      { ACL-ALIAS
     
       method:overwrite/APPEND
       fstype:POSIX/SOLARIS/DFS/AFS/HPUX/NT
     
       ACL_TYPE:USER/GROUP:PERMISSIONS
       ACL_TYPE:USER/GROUP:PERMISSIONS
       ...
      }

The name ACL-ALIAS can be any identifier containing alphanumeric
characters and underscores. This is what you will use to refer to the
ACL entries in practice. The method entry tells cfengine how to
interpret the entries: should a file's ACLs be overwritten or only
adjusted?  Since the filesystems from different developers all use
different models for ACLs, you must also tell cfengine what kind of
filesystem the file resides on. Currently only solaris and DCE/DFS ACLs
are implemented.

   NOTE: if you set both file permissions and ACLs the file permissions
override the ACLs.

* Menu:

* ACEs::
* Solaris ACLs::
* DFS ACLs::
* NT ACLs::
* ACL Example::


File: cfengine-Reference.info,  Node: ACEs,  Next: Solaris ACLs,  Prev: acl,  Up: acl

Access control entries
----------------------

   An access control list is build of any number of individual access
control entries (ACEs). The ACEs has the following general syntax:

         ACL_TYPE:USER/GROUP:PERMISSIONS

The user or group is sometimes referred to as a _key_.

   For an explanation of ACL types and their use, refer to your local
manual page.  However, note that for each type of filesystem, there are
certain entries which must exist in an ACL. If you are creating a new
ACL from scratch, you must specify these.  For example, in solaris ACLs
you must have entries for `user', `group' and `other'.  Under DFS you
need what DFS calls a `user_obj', `group_obj' and an `other_obj', and
in some cases `mask_obj'. In cfengine syntax these are called
`user:*:', `other:*:' and `mask:*:', as described below.  If you are
appending to an existing entry, you do not have to re-specify these
unless you want to change them.

   Cfengine can overwrite (replace) or append to one or more ACL
entries.

`overwrite'
     `method:overwrite' is the default. This sets the ACL according to
     the specified entries which follow.  The existing ACL will be
     overwritten completely.

`append'
     `method:append' adds or modifies one or more specified ACL entries.
     If an entry already exists for the specified type and user/group,
     the specified permission bits will be added to the old
     permissions. If there is no ACL entry for the given type and
     user/group, a new entry will be appended.

If the new ACL exactly matches the existing ACL, the ACL is not
replaced.

   The individual bits in an ACE may be either added subtracted or set
equal to a specified mask. The `+' symbol means add, the `-' symbol
subtract and `=' means set equal to.  Here are some examples:

       ACLTYPE:ID/*:MASK
     
       user:mark:+rx,-w
       user:ds:=r
       user:jacobs:noaccess
       user:forgiven:default
     
       user:*:rw
       group:*:r
       other:*:r

The keyword `noaccess' means set all access bits to zero for that user,
i.e. remove all permissions. The keyword `default' means remove the
named user from the access crontrol list altogether, so that the
default permissions apply. A star/asterisk in the centre field
indicates that the user or group ID is implicitly specified as of the
owner of the file, or that no ID is applicable at all (as is the case
for `other').


File: cfengine-Reference.info,  Node: Solaris ACLs,  Next: DFS ACLs,  Prev: ACEs,  Up: acl

Solaris ACLs
------------

   Under Solaris, the ACL type can be one of the following:

             user
             group
             mask
             other
             default_user
             default_group
             default_mask
             default_other

A user or group can be specified to the user, group, default_user and
default_group types.  Solaris ACL permissions are the normal UNIX
permissions bits `rwx', where:

         
             R - GRANTS READ PRIVILEGES.
             W - GRANTS WRITE PRIVILEGES.
             X - GRANTS EXECUTE PRIVILEGES.


File: cfengine-Reference.info,  Node: DFS ACLs,  Next: NT ACLs,  Prev: Solaris ACLs,  Up: acl

DFS ACLs
--------

In DCE, the ACL type can be one of the following:

             other
             mask
             any
             unauthenticated
             user
             group
             foreign_other
             foreign_user
             foreign_group

The `user', `group', `foreign_user' and `foreign_group'  types require
that you specify a user or group. The DCE documentation refers to types
`user_obj', `group_obj' and so on. In the cfengine implementation, the
ugly `_obj' suffix has been dropped to make these more in keeping with
the POSIX names. `user_obj::', is equivalent to `user:*:' is cfengine.
The star/asterisk implies that the ACL applies to the owner of the file
object.

   DFS permissions are comprised of the bits `crwxid', where:
             c - Grants control privileges, to modify an acl.
             r - Grants read  privileges.
             w - Grants write privileges.
             x - Grants execute privileges.
             i - Grants insert privileges.
             d - Grants delete privileges.

See the DCE/DFS documentation for more information about this.

   It is not possible to set ACLs in foreign cells currently using
cfengine, but you can still have all of your ACL definitions in the same
file. You must however arrange for the file to be executed on the server
for the cell concerned.  Note also that you must perform a DCE login
(normally as user `cell_admin') in order to set ACLs on files which are
not owned by the owner of the cfengine-process.  This is because you
must have a valid security ticket.


File: cfengine-Reference.info,  Node: NT ACLs,  Next: ACL Example,  Prev: DFS ACLs,  Up: acl

NT ACLs
-------

   NT ACEs are written as follows:
            acl_type:user/group:permissions:accesstype

   The actual change consists of the extra field containing the access
type. A star/asterisk in the field for USER/GROUP would normally imply
that the ACL applies to the owner of the file object. However this
functionality is as of today not yet implemented.

   In NT, the ACL type can be one of the following:
                user
                group
   Both types require that you specify the name of a user or a group.

   NT permissions are comprised of the bits `rwxdpo', where:
         r - Read privileges
         w - Write privileges
         x - Execute privileges
         d - Delete privileges
         p - Privileges to change the permissions on the file
         o - Privileges to take ownership of the file
   In addition to any combination of these bits, the word `noaccess' or
`default' can be used as explained in the previous section. NT comes
with some standard, predefined permissions. The standards are only a
predefined combination of the different bits specified above and are
provided with cfengine as well. You can use the standards by setting the
permission to `read', `change' or `all'. The bit implementation of each
standard is as on NT:
                read   - rx
                change - rwxd
                all    - rwxdpo
   where the bits follow the earlier definition. The keywords mentioned
above can only be used alone, and not in combination with `+', `-', `='
and/or other permission bits.

   NT defines several different access types, of which only two are
used in connection with the ACL type that is implemented in cfengine
for NT. The access type can be one of the following:
                allowed
                denied
   Intuitively, `allowed' access grants the specified permissions to
the user, whilst `denied' denies the user the specified permissions. If
no access type is specified, the default is `allowed'. This enables
cfengine's behaviour as on UNIX systems without any changes to the
configuration file. If the permissions `noaccess' or `default' is used,
the access type will be irrelevant.

ACL Example
===========

   Here is an example of a configuration file for an NT ACL:

     control:
             actionsequence = ( files )
             domain = ( iu.hioslo.no )
     
     files:
             $(HOME)/tt    acl=acl_alias1    action=fixall
     
     acl:
             { acl_alias1
     
             method:overwrite
             fstype:nt
     
             user:gustafb:rwx:allowed
             user:mark:all:allowed
             user:toreo:read:allowed
             user:torej:default:allowed
             user:ds2:+rwx:allowed
     
             group:dummy:all:denied
             group:iu:read:allowed
             group:root:all:allowed
             group:guest:dpo:denied
             }


File: cfengine-Reference.info,  Node: ACL Example,  Prev: NT ACLs,  Up: acl

ACL Example
-----------

   Here is an example of a configuration file for one Solaris ACL and
one DCE/DFS ACL:

     control:
             actionsequence = ( files )
             domain = ( iu.hioslo.no )
     
     files:
             $(HOME)/tt    acl=acl_alias1    action=fixall
             /:/bigfile    acl=acl_alias2    action=fixall
     
     acl:
             { acl_alias1
     
             method:overwrite
             fstype:posix
     
             user:*:rwx
             user:mark:=rwx
             user:sowille:=rx
             user:toreo:=rx
             user:torej:default
             user:ds2:+rwx
             group:*:rx
             group:iu:r
             group:root:x
             mask:*:rx
             other:*:rx
     
             default_user:*:=rw
             default_user:mark:+rwx
             default_user:ds:=rwx
             default_group::=r
             default_group:iu:+r
             default_mask::w
             default_other::rwx
             }
     
             { acl_alias2
     
             method:overwrite
             fstype:dfs
     
             user:*:rwxcid
             group:*:rxd
             other:*:wxir
             mask:*:rxw
             user:/.../iu.hioslo.no/cell_admin:rc
             group:/.../iu.hioslo.no/acct-admin:rwxcid
             user:/.../iu.hioslo.no/root:rx
             }


File: cfengine-Reference.info,  Node: binservers,  Next: broadcast,  Prev: acl,  Up: Command reference

binservers
==========

   The `binservers' declaration need only be used if you are using
cfengine's model for mounting NFS filesystems.  This declaration informs
hosts of which other hosts on the network possess filesystems containing
software (binary files) which client hosts should mount.  This includes
resources like programs in `/usr/local' and so on.  A host may have
several binary servers, since there may be several machines to which
disks are physically attached.  In most cases, on a well organized
network, there will be only one _architecture server_ per UNIX platform
type, for instance a SunOS server, an ULTRIX server and so on.

   Binary servers are defined as follows:


     binservers:
     
        physics.sun4::   sunserver sunserver2
        physics.linux::  linuxserver

The meaning of this declaration is the following.  All hosts of type
`sun4' which are members of the group `physics' should mount any
binaries declared in the `mountables' resource list which belong to
hosts `sunserver' or `sunserver2'.  Similarly all `linux' machines
should mount binary filesystems in the mountables list from
`linuxserver'.

   Cfengine knows the difference between binaries and home directories
in the `mountables' list, because home directories match the pattern
given by `homepattern'.  *Note homepattern::.  *Note homeservers::.

   Note that every host is a binary server for itself, so that the first
binary server (and that with highest priority) is always the current
host.  This ensures that local filesystems are always used in preference
to NFS mounted filesystems.  This is only relevant in connection with
the variable `$(binserver)'.


File: cfengine-Reference.info,  Node: broadcast,  Next: control,  Prev: binservers,  Up: Command reference

broadcast
=========

   This information is used to configure the network interface for each
host.

   Every local area network has a convention for determining which
internet address is used for broadcast requests.  Normally this is an
address of the form `aaa.bbb.ccc.255' or `aaa.bbb.ccc.0'.  The
difference between these two forms is whether all of the bits in the
last number are ones or zeroes respectively.  You must find out which
convention is used at your establishment and tell cfengine using a
declaration of the form:

     broadcast:
     
       any::
     
          ones     # or zeros, or zeroes

In most cases you can use the generic class `any', since all of the
hosts on the same subnet have to use the same convention.  If your
configuration file encompasses several different subnets with different
conventions then you will need to use a more specific.

   Cfengine computes the actual value of the broadcast address using the
value specified above and the netmask *Note netmask::.


File: cfengine-Reference.info,  Node: control,  Next: classes,  Prev: broadcast,  Up: Command reference

control
=======

   The fundamental piece of any cfengine script or configuration file is
the control section.  If you omit this part of a cfengine script, it
will not do anything! The control section is used to define certain
variables, set default values and define the order in which the various
actions you have defined will be carried out.  Because cfengine is a
declarative or descriptive language, the order in which actions appear
in the file does not necessarily reflect the order in which they are
executed. The syntax of declarations here is:

       control:
     
          CLASSES::
     
             VARIABLE = ( LIST OR VALUE )

   The control section is a sequence of declarations which looks
something like the following example:


     control:
     
       site     = ( univ )
       domain   = ( univ.edu )
       sysadm   = ( admin@computing.univ.edu )
       netmask  = ( 255.255.252.0 )
       timezone = ( EDT )
       nfstype  = ( nfs )
     
       sensiblesize  = ( 1000 )
       sensiblecount = ( 2 )
       editfilesize  = ( 4000 )
     
       actionsequence =
          (
          links.some
          mountall
          links.others
          files
          )
     
       myvariable = ( something )
       mymacro    = ( somethingelse )

Parentheses are required when making a declaring information in
cfengine.

   The meaning of each of these lines is described below.

* Menu:

* access::
* actionsequence::
* addclasses::
* addinstallable::
* BinaryPaddingChar::
* copylinks::
* defaultcopytype::
* deletenonusermail::
* deletenonownermail::
* domain::
* dryrun::
* editfilesize::
* excludecopy::
* excludelinks::
* ExpireAfter::
* homepattern::
* IfElapsed::
* Inform::
* interfacename::
* fileextension::
* LockDirectory::
* LogDirectory::
* linkcopies::
* moduledirectory::
* mountpattern::
* netmask::
* nonalphanumfiles::
* nfstype::
* repchar::
* repository::
* secureinput::
* sensiblecount::
* sensiblesize::
* showactions::
* site::
* SplayTime::
* split::
* suspiciousnames::
* sysadm::
* Syslog::
* timezone::
* TimeOut::
* Verbose::
* Warnings::
* warnnonusermail::
* warnnonownermail::


File: cfengine-Reference.info,  Node: access,  Next: actionsequence,  Prev: control,  Up: control

access
------

   The `access' list is a list of users who are to be allowed to
execute a cfengine program.  If the list does not exist then all users
are allowed to run a program.

        access = ( USER1 USER2 ...  )

The list may consist of either numerical user identifiers or valid
usernames from the password database.  For example:

        access = ( mark aurora 22 456 )

would restrict a script to users mark, aurora and user id 22 and 456.


File: cfengine-Reference.info,  Node: actionsequence,  Next: addclasses,  Prev: access,  Up: control

actionsequence
--------------

   The action sequence determines the order in which collective actions
are carried out.  Here is an example containing the full list of
possibilities:

        actionsequence =
           (
           mountall               # mount filesystems in fstab
           mountinfo              # scan mounted filesystems
           checktimezone          # check timezone
           netconfig              # check net interface config
           resolve                # check resolver setup
           unmount                # unmount any filesystems
           shellcommands          # execute shell commands
           editfiles              # edit files
           addmounts              # add new filesystems to system
           directories            # make any directories
           links                  # check and maintain links (single and child)
           simplelinks            # check only single links (separate from childlinks)
           childlinks             # check only childlinks (separate from singlelinks)
           mailcheck              # check mailserver
           mountall               # (again)
           required               # check required filesystems
           tidy                   # tidy files
           disable                # disable files
           files                  # check file permissions
           copy                   # make a copy/image of a master file
           processes              # signal / check processes
           module:name            # execute a user-defined module
           )

Here is a more complete description of the meaning of these keywords.

`addmounts'
     causes cfengine to compute which NFS filesystems are missing from
     the current host and add them. This includes editing the
     filesystem table, creating the mount-directory, if required.  This
     command relies on information provided by `mountinfo', so it
     should normally only be called after `mountinfo'. If the
     filesystem already appears to be in the filesystem table, a
     warning is issued.

`checktimezone'
     runs a check on the timezone defined for the shell running
     cfengine.

`directories'
     executes all the commands defined under the `directories' section
     of the program. It builds new directories.

`disable'
     executes all the commands defined under the `disable' section of
     the program.

`editfiles'
     executes all the commands defined under the `editfiles' section of
     the program.

`files'
     executes all the commands defined under the `files' section of the
     program.

`links'
     executes all the commands defined under the `links' section of the
     program. Here one can also write `singlelinks' which checks only
     single (not multiply linked) objects, or `childlinks' which checks
     the remainder (multiply linked) objects. In this way one can
     separate these two actions if required, though normally this is
     not necessary.

`mailcheck'
     tests for the presence of the NFS-mounted mail spooling directory
     on the current host. The name of the mail spool directory is
     defined in the `mailserver' section of the cfengine program. If
     the current host is the same as the mailserver (the host which has
     the physical spool directory disk) nothing is done. Otherwise the
     filesystem table is edited so as to include the mail directory.

`module'
     Normally cfengine's ability to detect the systems condition is
     limited to what it is able to determine while excuting predefined
     actions. Classes may be switched on as a result of actions cfengine
     takes to correct a problem. To increase the flexibility of
     cfengine, a mechanism has been introduced in version 1.5 which
     allows you to include a module of your own making in order to
     define or undefine a number of classes.  The syntax
            module:mytests.CLASS1.CLASS2.CLASS3
          
            "module:mytests.CLASS1.CLASS2.CLASS3 arg1 arg2 .."
     declares a user defined module which can potentially set the
     classes CLASS1 etc. Classes returned by the module must be
     declared so that cfengine knows to pay attention to rules which
     use these classes when parsing. Note might actually be preferable
     to define classes returned by modules under `AddInstallables'
     which is equivalent. If arguments are passed to the module, the
     whole string must be quoted like a shellcommand.  *Note Writing
     plugin modules: (cfengine-Tutorial)Writing plugin modules.
     Whether or not these classes become set or not depends on the
     behaviour of your module. The classes continue to apply for all
     actions which occur after the module's execution. The module must
     be owned by the user executing cfengine or root (for security
     reasons), it must be named `module:MODULE-NAME' and must lie in a
     special directory, *Note moduledirectory::.

`mountall'
     mounts all filesystems defined in the hosts filesystem table.  This
     causes new NFS filesystems added by `addmounts' and `mailcheck' to
     be actually mounted. This should probably be called both before
     `mountinfo' and after `addmounts' etc.  A short timeout is placed
     on this operation to avoid hanging RPC connections when parsing
     NFS mounted file systems.

`mountinfo'
     builds internal information about which filesystems are presently
     mounted on the current host.  Cfengine assumes that
     required-filesystems which are not found need to be mounted. A
     short timeout is placed on this operation to avoid hanging RPC
     connections when parsing NFS mounted file systems. If this times
     out, no further mount operations are considered reliable and are
     summarily cancelled.

`netconfig'
     checks the netmask, hostname, IP address and broadcast address for
     the current host. The correct values for the netmask and broadcast
     address are set if there is an error. The defaultroute is also
     added to the static routing table. This does not apply to DHCP
     clients.

`required'
     executes all the commands defined under the `required' section of
     the program. It checks for the absence of important NFS resources.

`resolve'
     checks and corrects the DNS domain name and the order of
     nameservers in the file `/etc/resolv.conf'.

`shellcommands'
     executes all the commands defined under the `shellcommands'
     section of the program.

`tidy'
     executes all the commands defined under the `tidy' section of the
     program.

`unmount'
     executes all the commands defined under the `unmount' section of
     the program. The filesystem table is edited so as to remove the
     unwanted filesystems and the unmount operation is executed.

`processes'
     executes commands defined under the `processes' section of the
     program.

   Under normal circumstances this coarse ordering is enough to suit
most purposes.  In some cases you might want to, say, only perform half
the link operations before mounting filesystems and then, say, perform
the remainder.  You can do this (and similar things) by using the idea
of defining and undefining classes. *Note Defining classes:
(cfengine-Tutorial)Defining classes.

   The syntax


     actionsequence =
        (
        links.firstpass.include
        ...
        links.secondpass
        )

means that cfengine first executes `links' with the classes `firstpass'
and `include' _defined_.  Later it executes `links' with `secondpass'
defined.  You can use this method of adding classes to distinguish more
finely the flow of control in programs.

   A note about style: if you define and undefine lots of classes to do
what you want to do, you might stop and ask yourself if your `groups'
are defined as well as they should be.  *Note groups::.  Programming in
cfengine is about doing a lot for only a little writing.  If you find
yourself writing a lot, you are probably not going about things in the
right way.


File: cfengine-Reference.info,  Node: addclasses,  Next: addinstallable,  Prev: actionsequence,  Up: control

AddClasses
----------

        AddClasses  = ( LIST OF IDENTIFIERS )

   The `AddClasses' directive is used to define a list of class
attributes for the current host.  Normally only the hard classes defined
by the system are `true' for a given host.  It is convenient though to
be able to define classes of your own to label certain actions, mainly
so that they can later be excluded so as to cut short or filter out
certain actions.  This can be done in two ways.  *Note actionsequence::.

   To define a list of classes for the current session, you write:

     AddClasses = ( exclude shortversion )

This is equivalent to (though more permanent than) defining classes on
the command line with the `-D' option.  You can now use these to
qualify actions.  For example


       any.exclude::
           ...

   Under normal circumstances `exclude' is always true -- because you
have defined it to be so, but you can _undefine_ it in two ways so as
to prevent the action from being carried out.  One way is to undefine a
class on the command line when you invoke cfengine:

     host#  cfengine -N exclude

or

     host#  cfengine -N exclude.shortversion
     
     host#  cfengine -N a.b.c.d

These commands run cfengine with the named classes _undefined_.  That
means that actions labelled with these classes are excluded during that
run.

   Another way to restrict classes is to add a list of classes to be
undefined in the actionsequence.  See next section.


File: cfengine-Reference.info,  Node: addinstallable,  Next: BinaryPaddingChar,  Prev: addclasses,  Up: control

AddInstallable
--------------

        AddInstallable  = ( LIST OF IDENTIFIERS )

   Some actions in your cfengine program will be labelled by classes
which only become defined at run time using a `define=' option. Cfengine
is not always able to see these classes until it meets them and tries to
save space by only loading actions for classes which is believes will
become defined at some point in the program. This can lead to some
actions being missed if the action is parsed before the place where the
class gets switched on, since cfengine is a one-pass interpreter,.  To
help cfengine determine classes which _might become defined_ during a
run, you can declare them in this list. It does no harm to declare
classes here anyway.  Here is an example where you need to declare a
class because of the ordering of the actions.


     control:
     
         AddInstallable  = ( myclass )
     
     files:
     
        myclass::
     
          /tmp/test mode=644 action=fixall
     
     copy:
     
          /tmp/foo dest=/tmp/test define=myclass

If we remove the declaration, then when cfengine meets the files
command, it skips it because it knows nothing about the class
`myclass'--when the copy command follows, it is too late.  Remember
that imported files are always parsed after the main program so
definitions made in imported files always come later than things in the
main program.


File: cfengine-Reference.info,  Node: BinaryPaddingChar,  Next: copylinks,  Prev: addinstallable,  Up: control

BinaryPaddingChar
-----------------

     BinaryPaddingChar = ( \0 )
   This specifies the type of character used to pad strings of unequal
length in `editfiles' during binary editing.  The default value is the
space character, since this is normally used to edit filenames or text
messages within program code.


File: cfengine-Reference.info,  Node: copylinks,  Next: defaultcopytype,  Prev: BinaryPaddingChar,  Up: control

CopyLinks
---------

   This list is used to define a global list of names or patterns which
are to be copied rather than linked symbolically. For example

     CopyLinks = ( *.config )
   The same facility can be specified for each individual link
operation using the `copy' option *Note links::.  Copying is performed
using a file age comparison.

   Note that all entries defined under a specified class are valid only
as long as that class is defined. For instance
       CLASS::
     
           CopyLinks = ( PATTERN )

would define a pattern which was only valid when CLASS is defined.


File: cfengine-Reference.info,  Node: defaultcopytype,  Next: deletenonusermail,  Prev: copylinks,  Up: control

DefaultCopyType
---------------

   This parameter determines the default form of copying for all copy
operations parsed after this variable. The legal values are `ctime'
(intial default), `mtime', `checksum' and `binary'.  e.g.


      DefaultCopyType = ( mtime )


File: cfengine-Reference.info,  Node: deletenonusermail,  Next: deletenonownermail,  Prev: defaultcopytype,  Up: control

DeleteNonUserMail
-----------------

   If this parameter is set to true, cfengine will delete mail files on
mailservers which do not have a name belonging to a known user id. This
does not include lock files.


File: cfengine-Reference.info,  Node: deletenonownermail,  Next: domain,  Prev: deletenonusermail,  Up: control

DeleteNonOwnerMail
------------------

   If this parameter is set to true, cfengine will delete files on
mailservers whose names do not correspond to a known user name, but
might be owned by a known user.


File: cfengine-Reference.info,  Node: domain,  Next: dryrun,  Prev: deletenonownermail,  Up: control

domain
------

       domain = ( DOMAIN NAME )

   This variable defines the domainname for your site.  You must define
it here, because your system might not know its domainname when you run
cfengine for the first time.  The domainname can be used as a cfengine
variable subsequently by referring to $(domain).  The domainname
variable is used by the action `resolve'. The domain is also used
implicitly by other matching routines. You should define the domain as
early as possible in your configuration file so as to avoid problems,
especially if you have the strange practice of naming hosts with their
fully qualified host names since groups which use fully qualified names
can fail to be defined if cfengine is not able to figure out the domain
name.


File: cfengine-Reference.info,  Node: dryrun,  Next: editfilesize,  Prev: domain,  Up: control

DryRun
------


       DryRun = ( ON/off )

   This variable has the same effect as the command line options
`--dry-run' or `-n'. It tells cfengine to only report what it should do
without actually doing it.

      CLASSES::
     
        DryRun = ( on )


File: cfengine-Reference.info,  Node: editfilesize,  Next: excludecopy,  Prev: dryrun,  Up: control

editfilesize
------------

        EditfileSize  = ( SIZE )

   This variable is used by cfengine every time it becomes necessary to
edit a file.  Since file editing applies only to text files, the files
are probably going to be relatively small in most cases.  Asking to edit
a very large (perhaps binary) file could therefore be the result of an
error.

   A check is therefore made as a security feature.  Cfengine will
refuse to edit a file which is larger than the value of `editfilesize'
in bytes.  This is to prevent possible accidents from occurring.  The
default value for this variable is 10000 bytes.  If you don't like this
feature, simply set the value to be a very large number or to zero.  If
the value is zero, cfengine will ignore it.


File: cfengine-Reference.info,  Node: excludecopy,  Next: excludelinks,  Prev: editfilesize,  Up: control

ExcludeCopy
-----------

   This list is used to define a global list of names or patterns which
are to be excluded from copy operations. For example

      ExcludeCopy = ( *~ *% core )
   The same facility can be specified for each individual link
operation using the `exclude' option *Note copy::.

   Note that all entries defined under a specified class are valid only
as long as that class is defined. For instance
       CLASS::
     
           ExcludeCopy = ( PATTERN )

would define a pattern which was only valid when CLASS is defined.


File: cfengine-Reference.info,  Node: excludelinks,  Next: ExpireAfter,  Prev: excludecopy,  Up: control

ExcludeLinks
------------

   This list is used to define a global list of names or patterns which
are to be excluded from linking operations. For example

      ExcludeLinks = ( *~ *% core )
   The same facility can be specified for each individual link
operation using the `exclude' option *Note links::.

   Note that all entries defined under a specified class are valid only
as long as that class is defined. For instance
       CLASS::
     
           ExcludeLinks = ( PATTERN )

would define a pattern which was only valid when CLASS is defined.


File: cfengine-Reference.info,  Node: ExpireAfter,  Next: homepattern,  Prev: excludelinks,  Up: control

ExpireAfter
-----------

   This parameter controls the global value of the ExpireAfter
parameter.  *Note Spamming and security: (cfengine-Tutorial)Spamming
and security. This parameter controls the maximum time in minutes which
a cfengine action is allowed to live. After this time cfengine will try
to kill the cfengine which seems to have hung and attempt to restart
the action.


      ExpireAfter = ( TIME-IN-MINUTES )

This parameter may also be set per action in the action sequence by
appending a pseudo-class called `ExpireAfterTIME'.  For instance,


      actionsequence = ( copy.ExpireAfter15 )

sets the expiry time parameter to 15 minutes for this copy command.


File: cfengine-Reference.info,  Node: homepattern,  Next: IfElapsed,  Prev: ExpireAfter,  Up: control

HomePattern
-----------

        HomePattern  = ( LIST OF WILDCARDS )

   The `homepattern' variable is used by the cfengine model for
mounting nfs filesystems.  *Note NFS resources: (cfengine-Tutorial)NFS
resources.  It is also used in the evaluation of the pseudo variable
`home', See *Note files::, *Note tidy::.

   `homepattern' is in fact a list and is used like a wildcard or
_pattern_ to determine which filesystems in the list of mountables are
home directories.  *Note mountables::.  This relies on your sticking to
a rigid naming convention as described in the first reference above.

   For example, you might wish to mount (or locate directly if you are
not using a separate partition for home directories) your home
directories under `mountpattern' in directories `u1', `u2' and so on.
In this case you would define `homepattern' to match these numbers:

     homepattern = ( u? )

Cfengine now regards any directory matching `$(mountpattern)/u?' as
being a user login directory.

   Suppose you want to create mount home directories under
`$(mountpattern)/home' and make subdirectories for staff and students.
Then you would be tempted to write:

      HomePattern = ( home/staff home/students )

Unfortunately this is not presently possible. (This is, in principle, a
bug which should be fixed in the future.) What you can do instead is to
achieve the same this as follows:

      MountPattern = ( /$(site)/$(host) /$(site)/$(host)/home )
      HomePattern = ( staff students )


File: cfengine-Reference.info,  Node: IfElapsed,  Next: Inform,  Prev: homepattern,  Up: control

IfElapsed
---------

   This parameter controls the global value of the IfElapsed parameter,
*Note Spamming and security: (cfengine-Tutorial)Spamming and security.
This parameter controls the minimum time which must have elapsed for an
action in the action sequence before which it will be executed again.


      IfElapsed = ( TIME-IN-MINUTES )

This parameter may also be set per action in the action sequence by
appending a pseudo-class called `IfElapsedTIME'.  For instance,


      ActionSequence = ( copy.IfElapsed15 )

sets the elapsed time parameter to 15 minutes for this copy command.


File: cfengine-Reference.info,  Node: Inform,  Next: interfacename,  Prev: IfElapsed,  Up: control

Inform
------


       Inform = ( ON/off )

   This variable switches on the output level whereby cfengine reports
changes it makes during a run. Normally only urgent messages or clear
errors are printed. Setting `Inform' to `on' makes cfengine report on
all actions not explicitly cancelled with a `silent' option.  To set
this output level one writes:


      CLASSES::
     
        Inform = ( on )


File: cfengine-Reference.info,  Node: interfacename,  Next: fileextension,  Prev: Inform,  Up: control

InterfaceName
-------------

   If you have an operating system which is installed on some
non-standard hardware, you might have to specifically set the name of
the network interface. For example:


       control:
     
         nextstep.some::
     
            InterfaceName = ( en0 )
     
         nextstep.others::
     
            InterfaceName = ( ec0 )

It is only necessary to set the interface name in this fashion if you
have an operating system which is running on special hardware. Most
users will not need this.  The choice set here overrides the system
defaults and the choices made in the `cfrc' file, *Note cfrc resource
file::.


File: cfengine-Reference.info,  Node: fileextension,  Next: LockDirectory,  Prev: interfacename,  Up: control

FileExtensions
--------------

   This list may be used to define a number of extensions which are
regarded as being plain files by the system.  As part of the general
security checking cfengine will warn about any directories which have
names using these extensions. They may be used to conceal directories.


       FileExtensions = ( c o gif jpg html )


File: cfengine-Reference.info,  Node: LockDirectory,  Next: LogDirectory,  Prev: fileextension,  Up: control

LockDirectory
-------------

   Specify an alternative directory for keeping cfengine's lock data.
This defaults to `/var/run/cfengine' or `/etc/cfengine'.


       LockDirectory = ( /etc/cfengine )


File: cfengine-Reference.info,  Node: LogDirectory,  Next: linkcopies,  Prev: LockDirectory,  Up: control

LogDirectory
------------

   Specify an alternative directory for keeping cfengine's log data.
This defaults to `/var/run/cfengine' or `/etc/cfengine'.


       LogDirectory = ( /etc/cfengine )


File: cfengine-Reference.info,  Node: linkcopies,  Next: moduledirectory,  Prev: LogDirectory,  Up: control

LinkCopies
----------

   This list is used to define a global list of names or patterns which
are to be linked symbolically rather than copied. For example

     excludelinks = ( *.gif *.jpg )
   The same facility can be specified for each individual link
operation using the `symlink' option *Note copy::.

   Note that all entries defined under a specified class are valid only
as long as that class is defined. For instance
       CLASS::
     
           LinkCopies = ( PATTERN )

would define a pattern which was only valid when CLASS is defined.


File: cfengine-Reference.info,  Node: moduledirectory,  Next: mountpattern,  Prev: linkcopies,  Up: control

moduledirectory
---------------

        moduledirectory  = ( DIRECTORY FOR PLUGIN MODULES )

   This is the directory where cfengine will look for plug-in modules
for the actionsequence, *Note actionsequence::. Plugin modules may be
used to activate classes using special algorithms.  *Note Writing
plugin modules: (cfengine-Tutorial)Writing plugin modules.


File: cfengine-Reference.info,  Node: mountpattern,  Next: netmask,  Prev: moduledirectory,  Up: control

mountpattern
------------

        mountpattern  = ( MOUNT-POINT )

   The `mountpattern' list is used by the cfengine model for mounting
nfs filesystems.  *Note NFS resources: (cfengine-Tutorial)NFS
resources.  It is also used in the evaluation of the pseudo variable
`home', See *Note files::, *Note tidy::.

   It is used together with the value of `homepattern' to locate and
identify what filesystems are local to a given host and which are
mounted over the network.  For this list to make sense you need to
stick to a rigid convention for mounting your filesystems under a single
naming scheme as described in the section mentioned above.  If you
follow the recommended naming scheme then you will want to set the value
of mountpattern to

     mountpattern = ( /$(site)/$(host) )

which implies that cfengine will look for local disk partitions under a
unique directory given by the name of the host and site.  Any
filesystems which are physically located on the current host lie in this
directory.  All mounted filesystems should lie elsewhere. If you insist
on keeping mounted file systems in more than one location, you can make
a list like this:

     mountpattern = ( /$(site)/users /$(site)/projects )


File: cfengine-Reference.info,  Node: netmask,  Next: nonalphanumfiles,  Prev: mountpattern,  Up: control

netmask
-------

        netmask = ( AAA.BBB.CCC.DDD )

   The netmask variable defines the partitioning of the subnet
addresses on your network.  Its value is defined by your network
administrator.  On most systems it is likely to be `255.255.255.0'.
This is used to configure the network interface in `netconfig'.  *Note
actionsequence::.

   Every host on the internet has its own unique address.  The addresses
are assigned hierarchically.  Each network gets a _domain name_ and can
attach something like 65,000 hosts to that network.  Since this is
usually too many to handle in one go, every such network may be divided
up into subnets.  The administrator of the network can decide how the
division into subnets is made.  The decision is a trade-off between
having many subnets with few hosts, or many hosts on few subnets.  This
choice is made by setting the value of a variable called `netmask'.
The netmask looks like an internet address.  It takes the form:


        aaa.bbb.ccc.mmm

The first two numbers `aaa.bbb' are the address of the domain.  The
remainder `ccc.mmm' specifies both the subnet and the hostname.  The
value of `netmask' tells all hosts on the network: how many of the bits
in the second half label different subnets and how many label different
hosts on each of the subnets?

   The most common value for the netmask is `255.255.255.0'.  It is
most helpful to think of the netmask in terms of bits.  Each base-10
number between 0-255 represents 8 bits which are either set or not set.
Every bit which is set is a network address and every bit which is zero
is part of a host address.  The first two parts of the address
`255.255' always takes these values.  If the third number is `255', it
means that the domain is divided up into 256 sub networks and then the
remaining bits which are zero can be used to give 255 different host
addresses on each of the subnets.

   If the value had been `255.255.255.254', the network would be
divided up into 2^15 subnets, since fifteen of the sixteen bits are
one.  The remaining bit leaves enough room for two addresses 0 and 1.
One of those is reserved for _broadcasts_ to all hosts, the other can
be an actual host -- there would only be room for one host per subnet.
This is a stupid example of course, the main point with the subnet mask
is that it can be used to trade subnets for hosts per subnet.  A value
of `255.255.254.0' would allow 128 different subnets with 2*256-1 = 511
hosts on each.

   We needn't be concerned with the details of the netmask here.
Suffice it to say that its value is determined for your entire domain
by the network administrator and each host has to be told what the
value is.

   Each host must also know what convention is used for the _broadcast
address_.  This is an address which hosts can send to if they wish to
send a message to every other host on their subnet simultaneously.  It
is used a lot by services like NIS to ask if any hosts are willing to
perform a particular service.  There are two main conventions for the
broadcast address: address zero (all host bits are zero) and the highest
address on the subnet (all host bits are ones).  The convention can be
different on every subnet and it is decided by the network
administrator.  When you write a cfengine program you just specify the
convention used on your subnet and cfengine works out the value of the
broadcast address from the netmask and the host address *Note
broadcast::.  Cfengine works out the value of the broadcast address
using the value of the netmask.


File: cfengine-Reference.info,  Node: nonalphanumfiles,  Next: nfstype,  Prev: netmask,  Up: control

NonAlphaNumFiles
----------------

   If enabled, this option causes cfengine to detect and disable files
which have purely non-alphanumeric filenames, i.e. files which might be
accidental or deliberately concealed. The files are then marked with a
suffix `.cf-nonalpha' and are rendered visible.


       NonAlphaNumFiles = ( on )

   These files can then be tidied by searching for the suffix. Note
that alphanumeric means ascii codes less than 32 and greater than 126.


File: cfengine-Reference.info,  Node: nfstype,  Next: repchar,  Prev: nonalphanumfiles,  Up: control

nfstype
-------

        nfstype = ( NFS-TYPE )

   This variable is included only for future expansion.  If you do not
define this variable, its value defaults to "nfs".

   At present cfengine operates only with NFS (the network file system).
When cfengine looks for network file systems to mount, it adds lines in
the filesystem table (`/etc/fstab',`/etc/checklist' etc.)  to try to
mount filesystems of type "nfs".  In principle you might want to use a
completely different system for mounting filesystems over the network,
in which case the `mount type' would not be "nfs" but something else.

   At the time of writing certain institutions are replacing NFS with
AFS (the Andrew filesystem) and DFS (from the distributed computing
environment).  The use of these filesystems really excludes the need to
use the mount protocol at all.  In other words if you are using AFS or
DFS, you don't need to use cfengine's mounting commands at all.

