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 See Example configuration file.
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, See files, or a
copy command, See 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.
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').
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.
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.
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.
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
}
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
}
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. See homepattern. See 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).
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 See netmask.
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.
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.
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
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
directories
directories
section of the program. It builds new directories.
disable
disable
section of the program.
editfiles
editfiles
section of the program.
files
files
section of the program.
links
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
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
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. See 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,
See moduledirectory.
mountall
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
netconfig
required
required
section of the program. It checks for the absence of
important NFS resources.
resolve
/etc/resolv.conf.
shellcommands
shellcommands
section of the program.
tidy
tidy
section of the program.
unmount
unmount
section of the program. The filesystem table is edited
so as to remove the unwanted filesystems and the unmount
operation is executed.
processes
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. See 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. See 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.
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. See 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.
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.
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.
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 See 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.
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 )
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.
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.
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.
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 )
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.
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 See 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.
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 See 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.
This parameter controls the global value of the ExpireAfter parameter. See 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.
HomePattern = ( list of wildcards )
The homepattern variable is used by the cfengine model for
mounting nfs filesystems. See NFS resources. It is also used in the evaluation of the
pseudo variable home, See files, 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. See 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 )
This parameter controls the global value of the IfElapsed parameter, See 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.
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 )
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, See cfrc resource file.
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 )
Specify an alternative directory for keeping cfengine's
lock data. This defaults to /var/run/cfengine or
/etc/cfengine.
LockDirectory = ( /etc/cfengine )
Specify an alternative directory for keeping cfengine's
log data. This defaults to /var/run/cfengine or
/etc/cfengine.
LogDirectory = ( /etc/cfengine )
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 See 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.
moduledirectory = ( directory for plugin modules )
This is the directory where cfengine will look for plug-in modules for the actionsequence, See actionsequence. Plugin modules may be used to activate classes using special algorithms. See Writing plugin modules.
mountpattern = ( mount-point )
The mountpattern list is used by the cfengine model for mounting
nfs filesystems. See NFS resources. It is also used in the evaluation of the
pseudo variable home, See files, 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 )
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.
See 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 See broadcast. Cfengine works out the value of the broadcast address using the value of the netmask.
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.
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.
RepChar = ( character )
The value of this variable determines the characters which is used by
cfengine in creating the unique filenames in the file
repository. Normally, its value is set to _ and each / in
the path name of the file is changed to _ and stored in the
repository. If you prefer a different character, define it here. Note
that the character can be quoted with either single or double quotes in
order to encompass spaces etc.
Repository = ( directory )
Defines a special directory where all backup and junk
files are collected. Files are assigned a unique filename
which identifies the path from which they originate.
This affects files saved using disable, copy,
links and editfiles See Disabling and the file repository.
SecureInput = ( on )
If this is set cfengine will not import files which are not owned by the uid running the program, or which are writable by groups or others.
SensibleCount = ( count )
This variable is used by the action required. It defines for
cfengine what you consider to be the minimum number of files in a
`required' directory. If you declare a directory as being required,
cfengine will check to see if it exists. Then, if the directory
contains fewer than the value of sensiblecount files, a warning
is issued. The default value for this variable is 2.
SensibleSize = ( size )
This variable is used by the action required. It defines for
cfengine what you consider to be the minimum size for a `required' file.
If you declare a file as being required, cfengine will check to see if
the file exists. Of course, the file may exist but be empty, so the
size of the file is also checked against this constant. If the file is
smaller than the value of sensiblesize a warning is issued. The
default value for this variable is 1000 bytes.
ShowActions = ( on )
This causes cfengine to produce detailed output of what action is being carried out as part of the prefix information during output. This is intended only for third party tools which collect and parse the cfengine output. It will be of little interest to humans.
site = ( sitename ) faculty = ( facultyname )
This variable defines a convenient name for your site configuration. It is useful for making generic rules later on, because it means for instance that you can define the name of a directory to be
/$(site)/$(host)/local
without having to redefine the rule for a specific site. This is a handy trick for making generic rules in your files which can be imported into a configuration for any site.
faculty is a synonym for site. The two names
may be used interchangeably.
SplayTime = ( time-in-minutes )
This variable is used to set the maximum time over which cfengine will share its load on a server, See Splaying host times.
Split = ( character )
The value of this variable is used to define the list separator in
variables which are expected to be treated as lists. The default value
of this variable is the colon :. Cfengine treats variables
containing this character as lists to be broken up and iterated over in
the following cases:
This typically allows communication with PATH-like environment variables in the shell.
SuspiciousNames = ( .mo lrk3 )
Filenames in this list are treated as suspicious and generate a warning as cfengine scans directories. This might be used to detect hacked systems or concealed programs. Checks are only made in directories which cfengine scans in connection with a command such as files, tidy or copy.
sysadm = ( mail address )
The mail address of your system administrator should be placed here.
This is used in two instances. If cfengine is invoked with the option
-a, then it simply prints out this value. This is a handy
feature for making scripts. See Using the help scripts.
The administrators mail address is also written into the personal log files which cfengine creates for each user after tidying files, so you should make this an address which users can mail if they have troubles.
Syslog = ( on/off )
This variable activates syslog logging of cfengine output at the `inform' level.
To set this output level one writes:
classes:: Syslog = ( on )
timezone = ( 3-character timezone )
The timezone variable is a list of character strings which define your local timezone. Normally you will only need a single timezone, but sometimes there are several aliases for a given timezone e.g. MET and CET are synonymous. Currently only the first three characters of this string are checked against the timezone which cfengine manages to glean from the system. If a mismatch is detected a warning message is printed. cfengine does not attempt to configure the timezone. This feature works only as a reminder, since the timezone should really be set once and for all at the time the system is installed. On some systems you can set the timezone by editing a file, a procedure which you can automate with cfengine See editfiles.
The value of the timezone can be accessed by variable substitution
in the usual way. It expands to the first item in your list.
shellcommands:
"echo ${timezone} | mail ${sysadm}"
TimeOut = ( 10 )
The default timeout for network connections is 10 seconds. This is too short on some routed networks. It is not permitted to set this variable smaller than 3 seconds or larger than 60 seconds.
Verbose = ( on/off )
This variable switches on the output level whereby cfengine reports everything it does during a run in great detail. Normally only urgent messages or clear errors are printed, See Inform. This option is almost equivalent to using the --verbose of -v command-line options. The only difference is that system environment reporting information, which is printed prior to parsing, is not shown. To set this output level on selected hosts one writes:
classes:: Verbose = ( on )
For related more limited output, See Inform.
Warnings = ( on/off )
This variable switches on the parser-output level whereby cfengine reports non-fatal warnings. This is equivalent to setting the command line switch --no-warn, or -w. To set this output level on selected hosts one writes:
classes:: Warnings = ( on )
If this parameter is set to true, cfengine will warn about mail files on mailservers which do not have a name belonging to a known user id. This does not include lock files.
If this parameter is set to true, cfengine will warn about files on mailservers whose names do not correspond to a known user name, but might be owned by a known user.
The classes keyword is an alias for groups as of
version 1.4.0 of cfengine.
Cfengine copies files between locally mounted filesystems and via the
network from registered servers. The copy algorithm avoids
race-conditions which can occur due to network and system latencies by
copying first to a file called file.cfnew on the local
filesystem, and then renaming this quickly into place. The aim of this
roundabout procedure is to avoid situations where the direct rewriting
of a file is interrupted midway, leaving a partially written file to be
read by other processes. Cfengine attempts to preserve hard links to
non-directory file-objects, but see the caution below.
Caution should be exercised in copying files which change rapidly in size. This can lead to file corruption, if the size changes during copying. Cfengine attempts to prevent this during remote copies.
The syntax summary is:
copy:
class::
master-file
dest=destination-file
mode=mode
owner=owner
group=group
action=silent/fix
backup=true/false
repository=backup directory
stealth=true/on/false/off
timestamps=preserve/keep
symlink=pattern
include=pattern
exclude=pattern
ignore=pattern
filter=filteralias
recurse=number/inf/0
type=ctime/mtime/checksum/sum/byte/binary
linktype=absolute/symbolic/relative/hard/none/copy
typecheck=true/on/false/off
define=class-list(,:.)
elsedefine=class-list(,:.)
force=true/on/false/off
size=size limits
server=server-host
secure=true/false
purge=true/false
syslog=true/on/false/off
inform=true/on/false/off
dest
mode, owner, group
files function
See files.
action
warn or
silent. The default action is fix, i.e. copy files. If warn
is specified, only a warning is issued about files which require
updating. If silent is given, then cfengine will copy the files
but not report the fact.
force
backup
backup option is set to "false", cfengine
will not make a backup copy of the file before copying.
repository
Repository variable, on an item
by item basis. If set to "off" or "none" it cancels the value of a global repository.
Copy makes a literal image of the master file at the destination,
checking whether the master is newer than the image. If the image needs
updating it is copied. Existing files are saved by appending
.cfsaved to the filename.
stealth
timestamps
tar command.
recurse
inf.
Cfengine crosses device boundaries or mounted filesystems when
descending recursively through file trees. To prevent
this it is simplest to specify a maximum level of recursion.
symlink
ignore
include
exclude
type
checksum or sum, then a secure MD5 checksum is used to
determine whether the source and destination files are identical. If
byte or binary is specified, a byte by byte comparison is
initiated. An mtime comparison does not take into account
changes of file permissions, only modifications to the contents of the
files.
server
cfd daemon, and you must make sure that you
have defined the variable domain in the control section
of the cfengine.conf file. If you don't define a domain
you will probably receive an error of the form `cfengine: Hey! cannot
stat file'.
secure
size
numberbytes numberkbytes numbermbytes
Only the first characters of these strings are significant, so they may be written however is convenient: e.g. 14kB, 14k, 14kilobytes etc. Examples are:
size=<400 # copy if file size is < 400 bytes size=400 # copy if file size is equal to 400 bytes size=>400 # copy if file size > 400 bytes
linktype
symlink. The default type is a direct symbolic
link. The values relative or absolute may be used, but
hard links may not be created in place of copied files, since hard links
must normally reside on the same filesystem as their files, and it
is assumed that most links will be between filesystems. If this value
is set to copy or none, symbolic links will be replaced
by actual copies of the files they point to. Note that for directories,
this option is ignored.
typecheck
define
purge
Example:
copy:
/local/etc/aliases dest=/etc/aliases m=644 o=root g=other
/local/backup-etc dest=/etc
solaris::
/local/etc/nsswitch.conf dest=/etc/nsswitch.conf
In the first example, a global aliases file is copied from the master
site file /local/etc/aliases to /etc/aliases, setting the
owner and protection as specified. The file gets installed if
/etc/aliases doesn't exist and updated if /local/etc/aliases
is newer than /etc/aliases. In the second example, backup-etc
is a directory containing master configuration files (for instance, services,
aliases, passwd...). Each of the files in backup-etc
is installed or updated under /etc. Finally, a global
nsswitch.conf file is kept up to date for solaris systems.
The home directive can be used as a destination, in which
case cfengine will copy files to every user on the system. This is
handy for distributing setup files and keeping them updated:
copy: /local/masterfiles/.cshrc dest=home/.cshrc mode=0600
You can force the copying of files, regardless of the date stamps
by setting the option force=true or force=on. The default
is force=false or force=off.
Hard links are not like symbolic links, they are not merely pointers to other files, but alternative names for the same file. The name of every file is a hard link, the first so to speak. You can add additional names which really are the file, they are not just pointers. For the technically minded, they are not separate inodes, they are additional directory references to the same inode. When you perform a copy operation on multiple files, cfengine attempts to preserve hard links but this is a difficult task.
Because a hard link just looks like an ordinary file (it cannot be distingiushed from the original, the way a symbolic link can) there is a danger that any copy operation will copy two hard links to the same file as two separate copies of the same file. The difference is that changes a hard-linked file propagate to the links, whereas two copies of a file are completely independent thereafter. In order to faithfully reproduce all hardlinks to all files, cfengine needs to examine every file on the same filesystem and check whether they have the same inode-number. This would be an enourmous overhead, so it is not done. Instead what happens is that cfengine keeps track of only the files which it is asked to examine, for each atomic copy-command, and makes a note of any repeated inodes within this restricted set. It does not try to go off, wandering around file systems looking to other files which might be hardlinks.
To summarize, cfengine preserves hardlinks during copying, only within the scope of the present search. No backups are made of hard links, only of the first link or name of the file is backed up. This is a necessary precaution to avoid dangling references in the inode table. As a general rule, hard links are to be avoided because they are difficult to keep track of.
In long recursive copies, where you descend into many levels of diretories, you can quickly run out of file descriptors. The number of file descriptors is a resource which you can often set in the shell. It is a good idea to set this limit to a large number on a host which will be copying a lot of files. For instance, in the C shell you would write,
limit descriptors 1024
Most systems should have adequate defaults for this parameter, but on some systems it appears to be set to a low value such as 64, which is not sufficient for large recursive tree searches.
Dynamical routing is not configurable in cfengine, but for machines with static routing tables it is useful to check that a default route is configured to point to the nearest gateway or router. The syntax for this statement is simply:
defaultroute:
class::
my_gateway
For example:
defaultroute:
most::
129.240.22.1
rest::
small_gw
Gateways and routers usually have internet address aaa.bbb.ccc.1
-- i.e. the first address on the subnet. You may use the numerical
form or a hostname for the gateway.
This is a synonyn for required, See required.
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.
disks:
/filesystem freespace=size-limit define=class-list(,:.)
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.
See 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.
disks:
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.
Directories declarations consist of a number of directories to be
created. Directories and files may also be checked and created using
the touch option in the files actions. See files.
The form of a declaration is:
directories:
classes::
/directory
mode=mode
owner=uid
group=gid
define=classlist
syslog=true/on/false/off
inform=true/on/false/off
For example
directories:
class::
/usr/local/bin mode=755 owner=root group=wheel
The form of the command is similar to that of files but this
command is only used to create new directories. Valid options are
mode, owner, group and are described under
files See files. This interface is only for convenience.
It is strictly a part of the `files' functionality and is performed
together with other `files' actions at run time.
The creation of a path will fail if one of the links in the path is a plain file or device node. A list of classes may optionally be defined here if a directory is created.
Disabling a file means renaming it so that it becomes harmless. This feature is useful if you want to prevent certain dangerous files from being around, but you don't want to delete them-- a deleted file cannot be examined later. The syntax is
disable:
class::
/filename
type=plain/file/link/links
rotate=empty/truncate/numerical-value
size=numerical-value
define=classlist
syslog=true/on/false/off
inform=true/on/false/off
repository=destination directory
Cfengine renames a given file by appending the name of the file with the
suffix .cfdisabled. A typical example of a file you would
probably want to disable would be the /etc/hosts.equiv file which
is often found with the + symbol written in it, opening the
system concerned to the entire NIS universe without password protection!
Here is an example:
disable:
/etc/hosts.equiv
/etc/nologin
/usr/lib/sendmail.fc
sun4::
/var/spool/cron/at.allow
Hint: The last example disables a file which restricts access to the
at utility. Such a command could be followed by a file action,
See files,
files:
some::
/var/spool/cron/at.allow =0644 N [root] [wheel] touch
which would create an empty security file at.allow.
See also your system manual pages for the at command if you don't
understand why this could be useful.
Disabling a link deletes the link. If you wish you may use the optional syntax
disable:
/directory/name type=file
to specify that a file object should only be disabled if it is a plain
file. The optional element type= can take the values
plain, file, link or links. If one of
these is specified, cfengine checks the type and only disables
the object if there is a match. This allows you to disable a file
and replace it by a link to another file for instance.
NOTE that if you regularly disable a file which then gets recreated by
some process, the disabled file filename.cfdisabled will
be overwritten each time cfengine disables the file and therefore the
contents of the original are lost each time. The rotate facility
was created for just this contingency.
The disable feature can be used to control the size of system log files,
such as /var/adm/messages using a further option rotate.
If the value rotate is set to 4, say,
disable:
filename rotate=4
then cfengine renames the file concerned by appending `.1' to it and a new, empty file is created in its place with the same owner and permissions. The next time disable is executed `.1' is renamed to `.2' and the file is renamed `.1' and a new empty file is created with the same permissions. Cfengine continues to rotate the files like this keeping a maximum of four files. This is similar to the behaviour of syslog.
If you simply want to empty the contents of a log file, without
retaining a copy then you can use rotate=empty or
rotate=truncate. For instance,
to keep control of your World Wide Web server logs:
disable:
Sunday|Wednesday::
/usr/local/httpd/logs/access_log rotate=empty
This keeps a running log which is emptied each Sunday and Wednesday.
The size= option in disable allows you to carry out a disable
operation only if the size of the file is less than, equal to or greater
than some specified size. Sizes are in bytes by default, but
may also be quoted in kilobytes or megabytes using the notation:
numberbytes numberkbytes numbermbytes
Only the first characters of these strings are significant, so they may be written however is convenient: e.g. 14kB, 14k, 14kilobytes etc. Examples are:
size=<400 # disable if file size is < 400 bytes size=400 # disable if file size is equal to 400 bytes size=>400 # disable if file size > 400 bytes
This options works with rotate or normal disabling; it is just
an extra condition which must be satisfied.
If a disable command results in action being taken by cfengine, an optional
list of classes becomes can be switched on with the aid of a statement
define=classlist in order to trigger knock-on actions.
The repository declaration allows a local override of the
Repository variable, on an item by item basis. If set to "off" or
"none" it cancels the value of a global repository and leaves the disabled
file in the same directory.
Performs ascii (line-based) editing on text-files or limited binary
editing of files.
If editing a file which has hard links to it, be aware that
editing the file will destroy the hard link references. This is also the
case with shell commands. You should avoid hard links whenever possible.
The form of an editing command is
editfiles can also search directories recursively through directories
and edit all files matching a pattern, using Include, Exclude, and
Ignore (see Recursive File Sweeps in the tutorial).
editfiles:
class::
{ file-to-be-edited
action "quoted-string..."
}
{ directory-to-be-edited
Recurse "inf"
Filter "filteralias"
Include ".cshrc"
Ignore "bin"
Ignore ".netscape"
action "quoted-string..."
}
Here are some examples:
editfiles:
sun4::
{ /etc/netmasks
DeleteLinesContaining "255.255.254.0"
AppendIfNoSuchLine "128.39 255.255.255.0"
}
PrintServers::
{ /etc/hosts.lpd
AppendIfNoSuchLine "tor"
AppendIfNoSuchLine "odin"
AppendIfNoSuchLine "borg"
}
The first of these affects the file /etc/netmasks on all SunOS 4
systems, deleting any lines containing the string "255.255.254.0" and
Appending a single line to the file containing "128.39 255.255.255.0"
if none exists already. The second affects only hosts in the class
`PrintServers' and adds the names of three hosts: tor, odin and borg to
the file /etc/hosts.lpd which specifies that they are allowed to
connect to the printer services on any host in the class `PrintServers'.
Note that single or double quotes may be used to enclose strings in cfengine. If you use single quotes, your strings may contain double quotes and vice-versa. Otherwise a double quoted string may not currently contain double quotes and likewise for single quoted strings.
As of version 1.3.0, you can use the home directive in
edit filenames, enabling you to edit files for every user
on the system, provided they exist. For example, to edit
every user's login files, you would write
{ home/.cshrc
AppendIfNoSuchLine "setenv PRINTER default-printer"
AppendIfNoSuchLine "set path = ( $path /new/directory )"
}
If a user does not possess the named file, cfengine just skips that user. A new file is not created.
The meanings of the file-editing actions should be self-explanatory.
Commands containing the word 'comment' are used to `comment out' certain
lines in a file rather than deleting them. Hash implies a shell
comment of the type
# comment
Slash implies a comment of the C++ type:
// comment
Percent implies a comment of the type:
% comment
More general comment types may be defined using the
SetCommentStart, SetCommentEnd and
CommentLinesMatching, CommentLinesStarting
functions.
A special group of editing commands is based on the GNU Regular
Expression package. These use GNU regular expressions to search line by
line through text and perform various editing functions. Some of these
commands are based on the concept of a file pointer. The pointer starts
at line one of the file and can be reset by 'locating' a certain line,
or by using the reset-pointer commands. The current position of the
pointer is used by commands such as InsertLine to allow a
flexible way of editing the middle of files.
A simple decision mechanism is incorporated to allow certain editing actions to be excluded. For instance, to insert a number of lines in a file once only, you could write:
{ file
LocateLineMatching "insert point..."
IncrementPointer "1"
BeginGroupIfNoMatch "# cfengine - 2/Jan/95"
InsertLine "# cfengine - 2/Jan/95"
InsertLine "/local/bin/start-xdm"
EndGroup
}
Since the first inserted line matches the predicate on subsequent calls, the grouped lines will only be carried out once.
The full list of editing actions is given below in alphabetical order.
Note that some commands refer to regular expressions and some refer to
'literal strings' (i.e. any string which is not a regular
expression). Variable substitution is performed on all strings. Be
aware that symbols such as ., * and so on are
meta-characters in regular expressions and a backslash must be used to
make them literal. The regular expression matching functions are
POSIX extended regular expressions.
See Regular expressions.
AbortAtLineMatching quoted-regex
FixEndOfLine and GotoLastLine) which involve multiple
replacements and searches, this expression marks a boundary
beyond which cfengine will cease to look any further. In other
words, if cfengine encounters a line matching this regular
expression, it aborts the current action. BE CAREFUL with this
feature: once set, the string remains set for the remainder of
the current file. It might therefore interact in unsuspected ways
with other search parameters. Editing actions are always aborted
as soon as the abort expression is matched.
Use UnsetAbort to unset the feature.
Append quoted-string
BeginGroupIfNoLineMatching and
BreakIfLineMatches.
AppendIfNoSuchLine quoted-string
AppendIfNoLineMatching quoted-regex
AppendIfNoSuchLine
which uses a regular expression instead of a literal
string. The line which gets appended must be set
previously using SetLine.
AppendToLineIfNotContains quoted-string
AutoCreate
AutomountDirectResources quoted-string
"-nosuid" for non setuid mounting (of all the
mountables). Note that this is added to the current file and not to a
file named /etc/auto_direct.
Backup quoted-string
Repository quoted string
Repository variable, on an item
by item basis. If set to "off" or "none" it cancels the value of a global repository.
BeginGroupIfFileExists quoted-string
EndGroup
are executed if the quoted filename exists (can be statted).
Files which are not readable by the running process are
for all intents and purposes non-existent.
BeginGroupIfFileIsNewer quoted-string
EndGroup
are executed if the quoted filename is newer than the file being
edited.
BeginGroupIfNoLineContaining quoted-string
EndGroup
are executed if the quoted string does not appear in
any line in the file.
BeginGroupIfNoLineMatching quoted-regex
EndGroup
are executed if the quoted regular expression
does not match any line in the file.
BeginGroupIfNoMatch quoted-regex
EndGroup
are executed if the quoted regular expression does
not match the current line.
BeginGroupIfNoSuchLine quoted-string
EndGroup
are executed if the quoted literal string
does not match any line in the file.
BreakIfLineMatches quoted-regex
CatchAbort
LocateLineMatching)
will jump to the first instance of this marker instead of completely
aborting an edit if this keyword occurs in an editing script.
You can catch the exceptions thrown by the following commands:
CommentNLines,CommentToLineMatching,DeleteNLines,DeleteToLineMatching,
HashCommentToLineMatching,IncrementPointer,
LocateLineMatching,PercentCommentToLineMatching,
RunScriptIf(No)LineMatching,UnCommentNLines.
CommentLinesMatching quoted-regex
SetCommentStart and SetCommentEnd to comment
out lines matching the given regular expression in quotes.
CommentLinesStarting quoted-string
SetCommentStart and SetCommentEnd to comment
out lines starting with the quoted literal string.
CommentNLines quoted-string
SetCommentStart).
After the operation the pointer points to the line after the
commented lines.
CommentToLineMatching quoted-regex
SetCommentStart and SetCommentEnd to comment out lines
from the current position in a file to a line matching the given regular
expression in quotes.
DefineClasses "class1:class2:..."
DeleteLinesAfterThisMatching quoted-regex
DeleteLinesContaining quoted-string
DeleteLinesMatching quoted-regex
DeleteLinesStarting quoted-string
DeleteNLines quoted-string
DeleteToLineMatching quoted-regex
EmptyEntireFilePlease
ElseDefineClasses
DefineClasses
EndGroup
EndLoop
ForEachLineIn
Filter filteralias
FixEndOfLine
dos
or unix to fix the end of line character conventions
to match these systems. This command should be executed
last of all, since cfengine appends new lines with the conventions
of the system on which is was complied during edit operations.
ForEachLineIn quoted-filename
SetLine
for each line in the file. Nested loops are not permitted.
GotoLastLine
HashCommentLinesContaining quoted-string
# to the start of any line containing the quoted string.
HashCommentLinesMatching quoted-regex
# to the start of any line exactly matching the quoted regular expression.
HashCommentLinesStarting quoted-string
# to the start of any line starting with the quoted string.
IncrementPointer quoted-number
"4".
Negative values are equivalent to decrementing the
pointer. If a request is made to increment/decrement
outside of the file boundaries the pointer `bumps'
into the boundary and remains there, i.e. either at
start of file or end of file.
Inform quoted-string
InsertFile quoted-string
InsertLine quoted-string
LocateLineMatching quoted-string
WarnIfNoLineMatching
so that you can get an explicit warning, even
out of verbose mode.
PercentCommentLinesContaining quoted-string
% to the start of any line containing the quoted string.
PercentCommentLinesMatching quoted-regex
% to the start of any line exactly matching the quoted regular.
PercentCommentLinesStarting quoted-string
% to the start of any line starting with the quoted string.
Prepend quoted-string
BeginGroupIfNoLineMatching and
BreakIfLineMatches.
PrependIfNoLineMatching quoted-regex
PrependIfNoSuchLine
with uses a regular expression instead of a literal string.
The string prepended is the one set using SetLine.
PrependIfNoSuchLine quoted-string
Recurse digit/inf
ReplaceLineWith quoted-string
ReplaceAll quoted-regex With quoted-string
cf.* with CFENGINE
and cfengine encounters a line hello cfengine cfengine, then this
will be replaced with hello CFENGINE even though two possible
strings match the regular expression. On the other hand if the
expression is not ambiguous, say replacing cfengine with
CFENGINE, then the result would be hello CFENGINE CFENGINE.
ReplaceLinesMatchingField quoted-number
SetLine or ForEachLineIn, if the lines
are split into fields (e.g. the password file) separated by the
SplitOn character (':' by default), and the corresponding
fields match.
The idea behind this command was to be able to override global
passwords (from a file which gets distributed) by new passwords
in a local file. Rather than maintaining the files separately,
this simply overrides the entries with the new ones See FAQS and Tips.
ResetSearch quoted-string
EOF indicates the end of
the file.
RunScript quoted-string
CAUTION: cfengine knows nothing about
the success or failure of anything that is done during the
execution of user scripts. This feature is to be
used at the users own peril!
RunScriptIfLineMatching quoted-string
SetScript
command only if the current file contains a line matching
the quoted regular expression.
CAUTION: cfengine knows nothing about
the success or failure of anything that is done during the
execution of user scripts. This feature is to be
used at the users own peril!
RunScriptIfNoLineMatching quoted-regex
SetScript
command if the current file contains no line matching
the quoted regular expression.
CAUTION: cfengine knows nothing about
the success or failure of anything that is done during the
execution of user scripts. This feature is to be
used at the users own peril!
SetCommentStart quoted-string
CommentLineMatching
and CommentLineStarting. The default is the hash
symbol # followed by a single space.
SetCommentEnd quoted-string
CommentLineMatching
and CommentLineStarting. The default is the empty
string. For example, you could make C style comments
by setting CommentStart to /* and comment
end to */.
SetLine quoted-string
AppendIfNoLineMatching using a regular expression.
SetScript quoted-string
SlashCommentLinesContaining quoted-string
// to the start of any line containing the quoted string.
SlashCommentLinesMatching quoted-regex
// to the start of any line exactly matching the quoted regular expression.
SlashCommentLinesStarting quoted-string
// to the start of any line starting with the quoted string.
SplitOn quoted-string
:, as is used in the password and group files.
It is used in conjunction with ReplaceLinesMatchingField.
Syslog quoted-string
Umask quote mode
UnCommentLinesContaining quoted-string
UnCommentLinesMatching quoted-regex
UnCommentNLines quoted-string
/* and */
comments, the command UnCommentNLines "3" would
uncomment
/* 1 */ /* 2 */ /* 3 */
and also
/* 1
2
3 */
UnsetAbort quoted-string
AbortAtLineMatching.
WarnIfLineContaining quoted-string
WarnIfLineMatching quoted-regex
WarnIfLineStarting quoted-string
WarnIfNoLineContaining quoted-string
WarnIfNoLineMatching reg-ex
WarnIfNoLineStarting quoted-string
WarnIfNoSuchLine quoted-regex
A limited number of operations can also be performed on purely binary files, e.g.
compiled programs, in order to search for strings or viral code, or to modify
strings within a program. Binary mode is a mutually exclusive, separate mode to normal
editing. The limit on the size of binary files is set by editbinaryfilesize
in control.
ReplaceAll regex With literal
BinaryPaddingChar in control.
Padding with a null byte would lead to corruption of text within a program.
WarnIfContainsString regex/literal
WarnIfContainsFile filename
It is suggested that you use these editing functions with caution. Although all possible safeguards have been incorporated into them, it is still possible through carelessness to do damage to important files on your system. Always test editing programs carefully before committing them to your global site configuration.
The files facility allows you to touch (create), check for the
existence, owner and permissions of files, change the permissions and
test for setuid root programs.
A files-statement can have several options. We can begin by examining the form of the statement in pseudo-code:
files:
classes::
/file-object
mode=mode
owner=uid-list
group=gid-list
action=fixall/other-options/warnall
links=false/stop/traverse/follow/tidy
ignore=pattern
include=pattern
exclude=pattern
filter=filter alias
define=classlist
elsedefine=classlist
checksum=md5
flags=BSD flags
syslog=true/on/false/off
inform=true/on/false/off
An example would be the following:
any::
/var/spool/printQ mode=0775 r=0 o=daemon g=daemon act=fixdirs
The meaning of these item is sketched out below and becomes clearer on
looking at a number of examples. Note that, each of the options below
can be written in either upper or lower case and abbreviated by any
unique abbreviation.
A file object is interpreted as a directory if you write it in the
following form: /directory-path/.. i.e. a trailing dot signifies
a directory. This then becomes the same as the directory command.
/directory
home may also be
used. See home directive.
mode=modestring
action
option determines what will be done about it. The modestring should
consist of either a three digit octal numbers with +, - or
= symbols, or a text string like that used by the command
chmod. For instance: mode=u=rwx,og+rx would mean set the
read/write and execute flags for the user (file owner) and add the
read/execute flags for others and group bits. An example of the
numerical form might be -002 which would mean that the
read-for-others flag should either not be set or should be unset,
depending on the action you choose. +2000 would mean that the
setuid flag should be present or set, depending on the action.
+2000,-002 would be a combination of these. The = sign
sets to an absolute value, so =755 would set the file mode to
mode 755.
flags=BSD flags
chflags documentation for this. For
example,
/tmp/flags.01 mode=0600 owner=0 group=0
flags=uappnd,uchg,uunlnk,nodump,opaque,sappnd,schg,sunlnk
action=touch
recurse=number/inf
inf then cfengine opens all subdirectories and files beginning
from the specified filename.See Recursion.
owner=owner list
root,2,3,sysadm. In cases where you ask
cfengine to fix the ownership automatically, the owner will be set to
the first owner in the list if and only if it is not one of the named
uids in the list.
group=group list
wheel,2,3,sysadm. In cases where you ask
cfengine to fix the ownership automatically, the group will be set to
the first group in the list if and only if it is not one of the named
gids in the list.
action=action
warnall warndirs warnplain fixall fixdirs fixplain touch linkchildren create compress alert
The upper line results only in warnings being issued. The actions
beginning `fix' prompt cfengine to fix encountered problems without
bothering the user. No message is issued unless in verbose mode. The
special features on the third line will be explained separately. Alert
is like -print in the find command, it triggers on the existence
of files which have not been ignored, excluded or filtered. This should
normally be used together filter, in order to locate files of particular types.
include=wildcard/pattern