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: Writing scripts for cfengine,  Next: Problem solving,  Prev: Command reference,  Up: Top

Cfengine script gallery
***********************

   Here is a gallery of simple-minded scripts to give you ideas for
making your own.  The absence of explicit testing in cfengine programs
also makes these scripts transparent while offering a higher level of
checking for no cost to the programmer.  Similar shell scripts with this
property would be complex indeed.

* Menu:

* Old files::
* Sharing files::
* Disk clearing::
* Script for making links::
* Ftp server::


File: cfengine-Reference.info,  Node: Old files,  Next: Sharing files,  Prev: Writing scripts for cfengine,  Up: Writing scripts for cfengine

User scripts for tidying old files
==================================

   Here is an example script for tidying old files in your own login
area.  If you want a long diagnostic, add the option `-v' to the first
line of the script, before `-f'.

     #!/usr/local/bin/cfengine -f
     #
     # Tidy
     #
     
     control:
     
        actionsequence =
           (
           tidy
           )
     
     
     tidy:
     
           $(HOME)        pat=core   r=inf  age=0
           $(HOME)        pat=*~     r=inf  age=1
           $(HOME)        pat=#*     r=inf  age=7
           $(HOME)/code   pat=*.o    r=inf  age=7
           $(HOME)/tex    pat=*.dvi  r=inf  age=7
           $(HOME)/tex    pat=*.log  r=inf  age=7
           $(HOME)/tex    pat=*.aux  r=inf  age=7
     
           $(HOME)/ftp    pat=*.zip  r=inf  age=7


File: cfengine-Reference.info,  Node: Sharing files,  Next: Disk clearing,  Prev: Old files,  Up: Writing scripts for cfengine

Controlled opening of files for friends and colleagues
======================================================

     #!/local/gnu/bin/cfengine -f
     #
     # Open my shared directory for others in my group
     #
     #
     
     
     control:
     
       actionsequence =
          (
          files
          )
     
       gr = ( myshare )
     
     
     files:
     
           $(HOME)       mode=0755 action=fixdirs r=0
           $(HOME)/share mode=0664 action=fixall  r=inf group=$(gr)

In this example, first your home directory is opened for the world, then
all files in the subdirectory `share' and subdirectories are opened to
the group `myshare'.  This script could be made to run from a
login/logout script of some kind (either `.login' or `.xsession') so
that any new files would automatically be controlled.


File: cfengine-Reference.info,  Node: Disk clearing,  Next: Script for making links,  Prev: Sharing files,  Up: Writing scripts for cfengine

Root script for emergency disk clearing
=======================================

   A straightforward script could be used to clear space in cases where
the disk hits the overflow level.  This script tidies the whole system,
not just the affected disk.

     #!/local/gnu/bin/cfengine -f
     #
     # Emergency tidyup!
     #
     # (Users read their cfengine.rm files to see what got deleted!)
     #
     
     control:
     
     site = ( mysite )
     
     mountpattern = ( $(site)/$(host) )
     homepattern   = ( u? )
     
     actionsequence =
        (
        tidy
        )
     
     
     tidy:
     
           home            pattern=core   R=inf   age=0
           home            pattern=*~     R=inf   age=0
           home            pattern=*.dvi  R=inf   age=1
           home            pattern=*.o    R=inf   age=0
           /tmp            pattern=*      R=inf   age=0  # could be risky
           /usr/tmp        pattern=*      R=inf   age=0  #      "
     
     ignore:
     
          .X11


File: cfengine-Reference.info,  Node: Script for making links,  Next: Ftp server,  Prev: Disk clearing,  Up: Writing scripts for cfengine

Script for making links
=======================

   The following script could be used as part of a software
installation procedure.  Note that the link types can be made relative
to the from-link by using `type=relative' *Note links::.

     #!/tmp/cfengine -v -f
     #
     # Simple example script to make links
     #
     
     control:
     
       actionsequence = ( links )
     
     links:
     
      host::
     
        /usr/local/bin                  +> /usr/local/lib/soft/bin
        /usr/local/X11/lib/app-defaults +> /usr/local/lib/soft/app-defaults

It makes links from every binary file in the packages `bin' directory to
the more standard binary directory `/usr/local/bin'.  This avoids
having to place another search directory into the users' `path'
variable.  The second statement links the package's application defaults
files (for the X-windows system) to a directory in the `XAPPLRESDIR'
search path.

   This script provides only one way of making the necessary files
available to users.  It is not the only solution to the problem.


File: cfengine-Reference.info,  Node: Ftp server,  Prev: Script for making links,  Up: Writing scripts for cfengine

Ftp server
==========

   This script carries out the necessary for setting up a safe anonymous
ftp server on a sun workstation running SunOS4.1.

     #!/local/gnu/bin/cfengine -f
     ##############################################################
     #
     # Cfengine script to set up an outgoing ftp server under
     # SunOS 4.1.*.  Suitable for anonymous access.
     #
     ###############################################################
     
     control:
     
      addclasses = ( local global )
     
      actionsequence =
         (
         editfiles.global
         directories
         shellcommands
         files
         editfiles.local
         )
     
      ftp_root = ( /oih/saga/local/ftp )   # macro for convenience
      ftp_id   = ( 99 )                    # uid/gid for ftp
     
     ################################################################
     
     editfiles:
     
      # Note the file /etc/ftpusers can contain a list of users
      # who can NOT use ftp to access files.
     
      global::
     
      { /etc/passwd
     
      AppendIfNoSuchLine "ftp:*:$(ftp_id):$(ftp_id): _(line continues)_
     Anonymous ftp:$(ftp_root):/usr/ucb/ftp"
      }
     
      { /etc/group
     
      AppendIfNoSuchLine "ftp:*:$(ftp_id):"
      }
     
     ################################################################
     
     directories:
     
       $(ftp_root)           mode=0555 owner=ftp
       $(ftp_root)/pub       mode=0555 owner=ftp
       $(ftp_root)/bin       mode=0555 owner=root
       $(ftp_root)/usr       mode=0555 owner=root
       $(ftp_root)/dev       mode=0555 owner=root
       $(ftp_root)/etc       mode=0555 owner=root
       $(ftp_root)/dev       mode=0555 owner=root
       $(ftp_root)/usr/lib   mode=0555 owner=root
     
     ###############################################################
     
     shellcommands:
     
       "/bin/cp /bin/ls $(ftp_root)/bin/ls"
       "/bin/cp /lib/libc.so.1.8* $(ftp_root)/usr/lib"
       "/bin/cp /usr/lib/ld.so  $(ftp_root)/usr/lib"
       "/bin/cp /usr/lib/libdl.so.1.0 $(ftp_root)/usr/lib/libdl.so.1.0"
       "/usr/etc/mknod $(ftp_root)/dev/zero c 3 12 > /dev/null 2>&1"
     
     ##########################################################################
     
     files:
     
      $(ftp_root)/bin/ls     mode=111 owner=root action=fixall
      $(ftp_root)/usr/lib    mode=555 owner=root action=fixall r=1
      $(ftp_root)/etc/passwd mode=444 owner=root action=touch
      $(ftp_root)/etc/group  mode=444 owner=root action=touch
      $(ftp_root)/pub        mode=644 owner=root action=fixall
     
     ################################################################
     
     editfiles:
     
      local::
     
      { $(ftp_root)/etc/passwd
     
      AppendIfNoSuchLine "ftp:*:$(ftp_id):$(ftp_id): _(line continues)_
     Anonymous ftp:$(ftp_root):/usr/ucb/ftp"
      }
     
      { $(ftp_root)/etc/group
     
      AppendIfNoSuchLine "ftp:*:$(ftp_id):"
      }


File: cfengine-Reference.info,  Node: Problem solving,  Next: Using the help scripts,  Prev: Writing scripts for cfengine,  Up: Top

Problem solving, bugs, FAQs and tips
************************************

* Menu:

* cf.preconf bootstrap file::
* cfrc resource file::
* Problems with compilation and installation::
* Bug reports and suggestions::
* FAQS and Tips::


File: cfengine-Reference.info,  Node: cf.preconf bootstrap file,  Next: cfrc resource file,  Prev: Problem solving,  Up: Problem solving

`cf.preconf' bootstrap file
===========================

   In some cases you will want to run cfengine on a system to configure
it from scratch.  If the system is in a very bad way, it might not even
be able to parse the cfengine configuration file, perhaps because the
network was not properly configured or the DNS (Domain Name Service) was
out of action.  To help prevent this situation, cfengine looks for a
script called `cf.preconf' which gets executed prior to parsing and can
be used to perform any emergency tests.  This file needs only contain
enough to get the system to parse the configuration files.

   `cf.preconf' may be any script in any language.  It need not exist
at all! It is fed one argument by cfengine, namely the system hard-class
for the current system (e.g.  `ultrix').  Here is an example:

     #!/bin/sh
     #
     # cf.preconf is an emergency/bootstrap file to get things going
     # in case cfengine is unable to parse its config file
     #
     
     backupdir=/iu/nexus/local/iu/etc
     
      #
      # If these files don't exist, you might not be able to parse cfengine.conf
      #
     
     if [ ! -s /etc/resolv.conf ]; then
     
      echo Patching basics resolv.conf file
      cat > /etc/resolv.conf << XX
     domain iu.hioslo.no
     nameserver 128.39.89.10
     XX
     
     fi
     
     #
     # SVR4
     #
     
     if [ "$1" = "solaris" ]; then
     
       if [ ! -s "/etc/passwd" ]; then
     
       echo Patching missing passwd file
         /bin/cp $backupdir/passwd /etc/passwd
       fi
     
       if [ ! -s "/etc/shadow" ]; then
     
        echo Patching missing passwd file
        /bin/cp $backupdir/shadow /etc/shadow
       fi
     fi
     
     #
     # BSD 4.3
     #
     
     if [ "$1" = "linux" ]; then
     
        if [ ! -s "/etc/passwd"  ]
        then
     
         echo Patching missing passwd file
         /bin/cp $backupdir/passwd.linux /etc/passwd
        fi
     fi


File: cfengine-Reference.info,  Node: cfrc resource file,  Next: Problems with compilation and installation,  Prev: cf.preconf bootstrap file,  Up: Problem solving

`cfrc' resource file
====================

   If, for some reason you are not satisfied with the defaults which
cfengine uses, then you can change them by making an entry in the
resource file.  The default values are defined in the source code file
`classes.c' in the distribution.  The format of the resource file is:

     hardclass.variable: value

For example, you might want to forget about where your HPUX system
mounts its mail directory and mount it under `/usr/spool/mail'.  In
this case you would add the line:

     hpux.maildir: /usr/spool/mail

To redefine the filesystem table for GNU/linux, you would write:
     linux.fstab: /etc/linuxfstab

The full list of re-definable resources is:

        mountcomm       # command used to mount filesystems
        unmountcomm     # command used to unmount filesystems
        ethernet        # name of the ethernet device
        mountopts       # options to above mount command
        fstab           # the name of the filesystemtable
        maildir         # the location of the mail directory
        netstat         # the full path to netstat and options
        pscomm          # the path to the system's ps command
        psopts          # the options used by ps (default aux/ef)

   You should never need to redefine resources unless you decide to do
something non-standard.  Interested readers are referred to the values
in `classes.c'.

   Cfengine is easily extensible so as to support a variety of
architectures.  You can even add your own.  To do so you need, first of
all, to define a new class for the operating system concerned.  The file
_classes.c_ has been separated off from the remainder of the source
code so that you can easily see which data structures need to be
extended.

   To make life as straightforward as possible, three unused classes
have been defined.  They are called (unremarkably) _unused1_, _unused2_
and _unused3_.  If you add any further classes, it will be necessary to
increase the constant _clssattr_ defined in _cf.defs.h_ by one for
every new addition.  You do not need to change _clssattr_ if you simple
replace one of the unused classes by a real class.

   To see fully the impact of what you need to do, you should make a
search for the strings _unused?_ in all of the source files.  Certain
special cases need to be handled for each operating system.  For
example, the form of the filesystem table is quite radically different
on some systems such as AIX.  One thing you must do is to fill in the
default values for the new operating system in the file _classes.c_.

   If you fill in the details for a new operating system before it finds
its way into a new release, you might consider sending the details to
the bug list in the next paragraph.


File: cfengine-Reference.info,  Node: Problems with compilation and installation,  Next: Bug reports and suggestions,  Prev: cfrc resource file,  Up: Problem solving

Problems with compilation and installation
==========================================

   Although every effort has been made to make the compilation of
cfengine trouble free, you might still encounter some problems where
non-standard features are concerned. The differences between systems is
still a major headache.

   Earlier versions of the GNU/Linux operating system do not have
support for some of the facilities which cfengine uses.  In particular,
the ability to use NIS netgroups is absent from earlier versions.
During the installation procedure, the `configure' script tests for this
possibility and advises you if the facility cannot be used.  You can
still use cfengine in this case but netgroups will not be expanded.
Another problem with GNU/Linux concerns a special socket call to the
TCP/IP network interface.  This is a command which configures the static
routing table and appears to be absent from all versions of Linux and
newer IRIX versions.  There are also problems with NetBSD.  These
features are undocumented and will be fixed as soon as they have been
understood! If you are running in verbose mode a warning message is
printed, otherwise cfengine will ignore attempts to set a default route
on the system.

   A number of users have experienced a problem using flex and bison in
place of lex and yacc. There appears to be a bug in one of these
programs which causes cfengine to compile correctly but misinterpret
its configuration files, generating an error of the form

     cfengine:10:action contains invalid statement

for every line! The cure is to collect the latest versions of flex and
bison from your nearest GNU site.

   On really old systems, the configure program is not able to guess
what kind of system you are working on. This is true of SunOS versions
4.0.* and also of BSD 4.3 systems. In such cases, you might be able to
compile cfengine by using the autoconf option `host' to specify the
host-type.


     configure --host=sparc-sun-sunos4.0

Some other systems which will compile if forced are:
     m68k-hp-bsd4.3
     ?-?-bsd4.3
     romp-ibm-aos
     ?-?-aos

   On some systems, problems arise when using flex. Flex might generate
a lexer file lex.yy.c which defines malloc or some other function to be
of a type which conflicts with the system definition.  If you obtain
such a culture crash, edit the lexer file manually and simply delete
the offending definitions, then run make again.

   As of version 1.4.0 cfengine tries to link in features based on the
Berkeley database library `libdb' and the TCP wrappers library
`libwrap'.  If you want to use these facilities, you will have to
collect them and install them before compiling cfengine.  Some problems
have been experienced with the linux version of TCP wrappers. If you
experience compilation problems, the best thing to do is to edit
`src/conf.h' after configuration and remove the line beginning `#define
HAVE_LIBWRAP'.

   Newer solaris systems have ACLs. The ACL features only matured in
version 2.5 of solaris however, and there have been some problems with
the partial implementation in 2.4. If you obtain error messages about
unknown ACL functions, edit the `config.cache' file in the cfengine root
directory and set the value:
     ac_cv_header_sys_acl_h=${ac_cv_header_sys_acl_h='no'}

   If you use the DCE (Distributed computing environment) cfengine will
try to compile the ACL extension for DFS. This requires the DCE library
to be present on the system on which you are compiling. On some systems
it also requires thread libraries to be present. Unfortunately, the
autoconf program which generates the Makefiles cannot detect shared
libraries, only archive libraries. This means that you need to edit the
`config.cache' file to compile in this support. Set the following
values:
     ac_cv_lib_dce_main=${ac_cv_lib_dce_main='yes'}
     ac_cv_lib_dce_main=${ac_cv_lib_thread_main='yes'}

   Finally, although the autoconfiguration program appends the same
libraries to each executable, the following libraries are required only
by the following programs.

      cfengine   -ldce -lthread -lm
     
      cfd        -ldb -lpthread


File: cfengine-Reference.info,  Node: Bug reports and suggestions,  Next: FAQS and Tips,  Prev: Problems with compilation and installation,  Up: Problem solving

Bug reports and suggestions
===========================

   If you experience a problem with cfengine, find a bug or have another
suggestion which you wish to air, you can send your thoughts to the
special mail address <bug-cfengine@gnu.org>.

   Always think a bit before sending a message to the list. This helps
to keep down the traffic improves the signal to noise ratio of your
thoughts! Try to solve the problem yourself first and look particularly
to see whether your system is clean or whether you have installed
software or patches which might conflict with cfengine (I can't really
imagine how this would happen--but it might). Always be clear about
what type of operating system you are running and whether or not it is
a complete installation.

   Some vendors have begun the practice of distributing systems without
key programs like the C compiler, lex and yacc. If you have this
problem, you can pick up GNU replacements gcc, flex and bison from any
GNU site.


File: cfengine-Reference.info,  Node: FAQS and Tips,  Prev: Bug reports and suggestions,  Up: Problem solving

FAQs and Tips
=============

   Here is a problem solver: an encyclopaedia of suggestions and uses
for cfengine as accumulated over the years. If you have a contribution
to make, please send it to <help-cfengine@gnu.org>. Format your
submission like this:

_Q:_
     _How do I do...._

_A:_
     Very well thank-you....

   The table below is updated as the tips occur to me, or as others
contribute their own. Please note that any focusing on particular
operating systems is purely a matter of personal usage/experience and
should not be interpreted as a reflection of how many `bugs' these
systems may or may not contain.

* Menu:

* General::
* AIX::
* BSDI::
* HPUX::
* IRIX::
* LINUX::
* OSF::
* SUN (4.1.*)::
* SOLARIS 2::
* FreeBSD::


File: cfengine-Reference.info,  Node: General,  Next: AIX,  Prev: FAQS and Tips,  Up: FAQS and Tips

General
-------

_Q:_
     How can I check to see what cfengine will do without going through
     the whole program using `-n'?

_A:_
     Run cfengine with options:


            cfengine -p -d3

     This just parses the file and dumps the contents of the parser to
     the output.

_Q:_
     _Why doesn't cfengine have classes for each hour, instead of just
     for days?_

_A:_
     It does from version 1.3.20 and upward. The hours are denoted in
     24 hour clock notation by `Hr00'--`Hr23'. Other time classes are
     also possible *Note Using cfengine as a front-end for cron:
     (cfengine-Tutorial)Using cfengine as a front-end for cron.

_Q:_
     _How can I replace the stupid version of sendmail my vendor ships
     with my OS with, say, Berkeley sendmail?_

_A:_
     First of all, compile your new sendmail in a filesystem which is
     held separate from the OS, for example `/local/mail'. You can keep
     all the files under this new file tree. Now you need to replace
     `/usr/lib/sendmail' with the new version and `/etc/sendmail.cf' or
     `/etc/mail/sendmail' with the new files, so that the system can
     find them.


             links:
                /usr/lib/sendmail ->! /local/mail/bin/sendmail
                /etc/sendmail.cf  ->! /local/mail/etc/sendmail.cf

_Q:_
     _How can I prevent big log-files like `/var/adm/wtmpx' and
     `httpd/access_log' from filling up my partitions?_

_A:_
     Add a line to disable the files once a week. That way you still
     get a chance to look at them, but you keep the size down:


             disable::
          
                Sunday::
          
                   #
                   # Do this to throw away old entries
                   #
          
                   /var/adm/wtmpx rotate=truncate
          
                   #
                   # Or this to keep the last lot
                   #
          
                   /var/adm/wtmpx rotate=1

     An alternative to using `disable' would be to use `tidy', but then
     you lose the file once and for all. Note though, that `wtmpx' gets
     updated all the time, so an age `age=0' is necessary to have any
     effect at all. Some daemons, like `httpd', lose their ability to
     write to a log file if you rename and create a new file. The
     `rotate' feature in cfengine preserves the open file handle,
     fixing this problem.

_Q:_
     _How can I fix exports in cfengine?_

_A:_
     This is a complicated matter. There are lots of ways to do it. The
     key is either to edit the file `/etc/exports' (`/etc/dfs/dfstab'
     in solaris), or to execute an export (share) command directly from
     `shellcommands'. Under Solaris 2 this is quite easy owing to the
     fact that the file `dfstab' is just a script itself, rather than a
     configuration file like the old `/etc/exports' file. Since editing
     is limited and you need to specify a list of hosts which might
     change in time, one of the following is probably the best bet:


          shellcommands:
          
             solaris::
          
                "/usr/sbin/share -F nfs -o rw=NETGROUP /var/mail"

     On non-solaris systems:


          editfiles:
          
             { /etc/exports
          
             AppendIfNoSuchLine "/SITE/HOST/FS -access=NETGROUP"
             }

_Q:_
     _How can I distribute key setup files to users and keep them up to
     date?_

_A:_
     The copy facility will distribute to all users if you use the
     `home' directive. For instance, to copy a basic `.cshrc' file or
     `.xsession', you could write


          copy:
          
             /local/masterfiles/.cshrc     dest=home/.cshrc
             /local/masterfiles/.xsession  dest=home/.xsession

_Q:_
     _Some users set up their own IRC listen services called "eggdrop"
     which fill up the disk with all kinds of garbage.  How can I kill
     all these processes?_

_A:_

          processes:
          
            #
            # Most users
            #
          
            "eggdrop"  signal=kill
          
            #
            # One wise-guy has renamed the daemon!
            #
          
            ".*wiseguy.*myegg.*"  signal=kill

_Q:_
     _My license server keeps crashing!  How can I check that it's ok?_

_A:_

          processes:
          
            #
            # BSD - often need long descriptive lines
            #       to find this daemon
            #
          
            SetOptionString "-ax"
          
            # Exactly one should be running
          
            "lmgrd" matches=1

_Q:_
     _I want to use cfengine to keep DNS tables up to date, using
     editfiles. How can I make cfengine automatically restart the name
     server after the edits?_

_A:_
     This can be done in two ways. Probably, you need to update a
     serial number as well as restarting the daemon.  You might use a
     Makefile to simplify this.


          control:
          
            actionsequence = ( editfiles control )
          
            solaris::
                     named = ( /usr/sbin/in.named)
            linux:
            freebsd:
                     named = ( /usr/sbin/named )
            sun4:
                     named = ( /usr/etc/named )
          
          editfiles:
          
           # edit files here
          
          shellcommands:
          
             #
             # If you use make to sort out the details
             #
          
            "/local/gnu/bin/make -f /local/named/Makefile > /dev/null"

     Or if you need to explicitly restart the name daemon, you could
     supplement the above with an explicit restart command (this means
     you lose the cache),


          processes:
          
            "named" signal=kill restart "$(named)"

_Q:_
     _How can I edit all users' login files?_

_A:_
     You can use the 'home' pseudo-variable to iterate over all users'
     homedirectories:


          editfiles:
          
              { home/.cshrc
          
              # Local fixes
          
              AppendIfNoSuchLine "alias lp  special-print-command"
          
              # Security
          
              DeleteLinesMatching "xhost +"
              }

_Q:_
     How can I kill all processes except for root processes?

_A:_
     The following regular expression matches lines which do not
     contain the string root:


          processes:
          
           "\(root\)\{0\}"  signal=term # or kill

_Q:_
     How can I make cfengine distribute my `/etc/motd' file?

_A:_
     You will need a master file which contains the text you want to
     put on your servers. Let us define a variable `masterfile' which
     contains this. This master file needs to be available on all hosts
     on a common NFS filesystem, for instance.  (This will change when
     remote copying is implemented in cfengine.) Now you can do
     something like the following script. Note that we define a version
     number for motd which just prevents cfengine from editing the file
     every single time.  You have to change this version number
     yourself in the config file to force an update. If you don't care
     about this, just leave out the Begin..End parentheses.


          control:
          
          masterfile = ( /usr/local/admin/motd-master )
          
          editfiles:
          
            any::
          
               { /etc/motd
          
               BeginGroupIfFileIsNewer "$(masterfile)"
                 EmptyEntireFilePlease
                 InsertFile "$(masterfile)"
                 PrependIfNoSuchLine "This system is running $(class):$(arch)"
                 AppendIfNoSuchLine "$(motd_version)"
               EndGroup
               }

     Note that, if you want special messages added just for, say,
     linux, then you can single out linux using a special class, or add
     a special edit after this one.

     Note, if you want to keep the first kernel line in this file, you
     can change this to:

          editfiles:
          
             any::
          
             { /etc/motd
          
             BeginGroupIfFileIsNewer "$(masterfile)"
               IncrementPointer "1"
               DeleteLinesAfterThisMatching ".*"
               InsertFile "$(masterfile)"
               AppendIfNoSuchLine "$(motd_version)"
             EndGroup
             }

_bug-cfengine exchange: (Reply courtesy of David Masterson)._
     _I like cfengine a lot and it helps me very much, but I am a little
     concerned about security. I'm using cfengine to keep some files
     like /etc/hosts /etc/printcap /etc/mount etc. up to date. So
     cfengine is started by root in a cron job and reads its
     cfengine.conf file and all the other information from a filesystem
     which is common to all the systems.  If now somebody manage to
     alter the cfengine.conf file he can do everything he wants.
     Wouldn't it be a good idea to make the cfengine.conf file
     something like a pgp signed messages, so that cfengine can test if
     this file was created by the right person? Or are there other tips
     to make it more secure?_

     I'm not sure, but I think you're over-reacting or you need to be
     more specific about where you think the holes are in Cfengine's
     security.  If you follow the tips of any standard systems
     administrator using cfengine or not, there should be few issues
     concerning security (ie. if security broke, there would be little
     chance that cfengine could do anything about it anyway).

     Ask yourself some of the standard questions with respect to
     security on UNIX:

        * Who owns your script files?

        * Who can update those script files?

        * If those script files are updated by the wrong person, has
          your security   been purposely broken or does it just have a
          hole in it?

     If you're still worried about the security of your script (be it a
     cfengine script or not), you could always adjust your cron script
     to "decrypt" the script file before executing it (see crypt(1)).

     Personally, I think if you've set the permissions on your script
     files properly, then, if someone breaks into those scripts,
     they've already broken into your system to a point where they
     could do what they wanted anyway.

_Q:_
     How can I distribute password files in cfengine, but keep certain
     passwords different on some machines, like I can with NIS?

_A:_
     If you keep a file with special local passwords, you can override
     the password file using `editfiles'. First you use `copy' to get
     the distributed file, then you edit the file like this:

            editfiles:
          
              { /etc/passwd
          
              SplitOn ":"
          
          
              ForEachLineIn "/usr/local/etc/passwd.local"
          
                 ReplaceLinesMatchingField "1"
          
              EndLoop
              }

     This means, if the first field of each line in the files matches
     in both files (and both files have the same column format) then
     replace the line in `/etc/passwd' with the line from
     `/usr/local/etc/passwd.local'.

_Q:_
     How can I add entries to a list, like in the fiel `/etc/group'?

_A:_
     Okay, suppose you wanted to make sure that a special user was in
     the group `adm', you would use a construction like this:
            control:
          
                person = ( NEW-USER )
          
          
            editfiles:
          
             { /etc/group
          
             BeginGroupIfNoLineMatching "adm.*$(person).*"
               LocateLineMatching "adm.*"
               AppendToLineIfNotContains ",$(person)"
             EndGroup
             }

_Q:_
     How can I take backups with cfengine?

_A:_
     If you have a spare disk partition, you could make a mirror of the
     most important files. You would use something like this:


           control:
          
                excludecopy = ( *.mp3 *.o *.dvi *.ps *.zip *tar* *.lnk
                                 core a.out *.au *.wav .* *.exe *.tgz )
          
           copy:
          
             BackupHost.Hr21::
          
               /site/host/home dest=/site/host/backup2/u1 r=inf size=<4mb backup=false action=silent

     for each partition you want to back up.

_Q:_
     I am using SAMBA and have windows file system data on my unix
     machine. When I try to make a backup by remote copying files,
     cfengine goes into a recursive loop when it meets short cuts.

_A:_
     Short cuts do not seem to respect the unix file protocols. They
     look like directories to cfengine and this causes it problems
     since they do not parse like directories. Add `*.lnk' to the list
     of files to be excluded during the copy.

_Q:_
     Is it possible to force shellcommands to change its working
     directory?  separating the commands with ";" seems to be not
     possible. shellscripts should not be used for this purpose.

_A:_
     (By Rolf Ebert, ebert@pe-muc.de )

     I, too, have the need to pass variables to shellcommands and the
     shellcommands must be executed in a given directory.  Here is how
     most of my shellcommands look like:

                # generate MMC configs
                 '$(shell) "PUBLIC=$(public); export PUBLIC; cd $(public)/mmc/config; ./blinksrv.x.cfm.in > blinksrv.x.cfm"'

     `$(shell)' is defined as '/bin/sh -c'.  The actual script to be
     executed is `blinksrv.x.cfm.in' which is located in
     `$(public)/mmc/config'.  It generates a file in the same
     directory.  As an input parameter the script needs the environment
     variable `PUBLIC'.

_Q: Using cfengine with the AFS._
     We use AFS, therefore our directory structures look like this:
     `/afs/btv.ibm.com/system/current/rs_aix43/...' and so on.  I want
     to build a cf file that can pull what AFS calls the "sysname" into
     the equation so I can have one cf file that can get data from the
     proper rs_aix directory depending on what level of AIX, or SUN for
     that matter,  it happens to run on.  If I use cfengine's class
     structure I would have to have a cf file for each AIX/SUN level
     rather than one that can handle them all.  That is why I want exec
     to work.  Can anyone offer an answer to this type of scenario?

_A: Courtesy of Jeff Blaine_
     We reference @sys all the time in our cfengine files.  It expands
     to the current machine's AFS sysname on the fly.  It's part of
     AFS, use it!

          control:
            #
            # ... stuff deleted ...
            #
            rcf_repos = ( /afs/whatever/our_admin_area/config )
            #
            # ... stuff deleted ...
            #
          
          copy:
          
            # ... stuff deleted ...
            #
            #  SunOS 4 and IRIX automountd startup file to define /net -hosts
            #
            (sun4|irix|irix64)::
                $(rcf_repos)/@sys/etc/auto.master dest=/etc/auto.master mode=444 \
          owner=root group=1 type=checksum
            #
            # ... stuff deleted ...



File: cfengine-Reference.info,  Node: AIX,  Next: BSDI,  Prev: General,  Up: FAQS and Tips

AIX
---

_Q:_
     _Hints about AIX?_

_A:_
     Send then to <bug-cfengine@gnu.org>.

_Q: I get the error_
          ld: 0711-317 ERROR: Undefined symbol: .pthread_sigmask
          ld: 0711-317 ERROR: Undefined symbol: .pthread_mutex_init
          ld: 0711-317 ERROR: Undefined symbol: .pthread_mutex_lock
          ld: 0711-317 ERROR: Undefined symbol: .pthread_mutex_unlock

     on AIX 4.2

_A:_
     Only AIX 4.3 supports POSIX threads fully. You should compile
     without thread support.

_Q:_
     One of our Sysadmins has noted a limitation with line length under
     AIX. I'm not sure how easy it is to fix but it might be worth
     noting it somewhere in the cfengine docs.  It appears that on the
     AIX machines the maximum line length we can use for cfengine files
     is defined by the constant YYLMAX which is set to be 200.  On the
     Suns this constant is set to be the same as BUFSIZ which is
     currently set to be 1024.  This manifested itself by very unusual
     behavior as cfengine variables began to be overwritten when line
     lengths in the config file exceeded 200 bytes.  Peter can attest
     to this.  Be forewarned "keep line lengths in cfengine less than
     200 if you want them to work on AIX machines" Moral of the story
     "AIX users beware" Do you think we could just recompile cfengine
     and use larger buffer sizes all over, I don't know if this
     constant is all that should be tweaked or if it is somehow tied
     into the lexx implementation also, since lexx is used to create
     the parser for the config files.

_A:_
     This is a problem with lex and yacc, not with cfengine. The
     variable BUFSIZ is a system quantity, not related to cfengine's
     internal variable bufsize. I would recommend getting bison and
     flex and doing away with the old lex and yacc from the system.
     Michael Lachowski reports that this is also a problem with HPUX
     10's lex/yacc.


File: cfengine-Reference.info,  Node: BSDI,  Next: HPUX,  Prev: AIX,  Up: FAQS and Tips

BSDI
----

_Q:_
     The following error occurs while compiling:


          % ./configure
          loading cache ./config.cache
          checking host system type... i386-pc-bsdi3.1
          checking target system type... i386-pc-bsdi3.1
          checking build system type... i386-pc-bsdi3.1
          expr: syntax error, last argument was `'
          test: syntax error: Undefined error: 0
          expr: syntax error, last argument was `'
          test: syntax error: Undefined error: 0
          expr: syntax error, last argument was `'
          test: syntax error: Undefined error: 0
          checking whether make sets ${MAKE}... (cached) yes
          checking for gcc... (cached) gcc
          checking whether the C compiler (gcc  ) works... yes
          checking whether the C compiler (gcc  ) is a cross-compiler... no
          ...

_A:_

            To correct this for BSDI I replaced the following script fragment from
          configure:
          
          -------------------------------------------------------------------------
          #
          # Add to the default list of places in LDFLAGS to compensate for
          # ... the configure default value of LIBS on some systems
          #
          for x in /usr/local/gnu/lib /usr/local/gnulib /usr/local/lib /usr/lib /lib
          do
            if test -d "$x"; then
              y=`expr match "$LDFLAGS" ".*-L$x"`
              if test $y -eq 0; then
                LDFLAGS="$LDFLAGS -L$x"
              fi
            fi
          done
          
          #
          # Add to the default list of places in CPPFLAGS to match LDFLAGS above
          #
          for x in /usr/include /usr/local/gnu/include /usr/local/include
          do
            if test -d "$x"; then
              y=`expr match "$CPPFLAGS" ".*-I$x"`
              if test $y -eq 0; then
                CPPFLAGS="$CPPFLAGS -I$x"
              fi
            fi
          done
          ------------------------------------------------------------------------
          
             With this script fragment, which successfully executed:
          
          ------------------------------------------------------------------------
          
          #
          # Add to the default list of places in LDFLAGS to compensate for
          # ... the configure default value of LIBS on some systems
          #
          for x in /usr/local/gnu/lib /usr/local/gnulib /usr/local/lib /usr/lib /lib
          do
            if test -d "$x"; then
              case $LDFLAGS in
              .*-L$x)
                LDFLAGS="$LDFLAGS -L$x"
                ;;
              esac
            fi
          done
          
          #
          # Add to the default list of places in CPPFLAGS to match LDFLAGS above
          #
          for x in /usr/include /usr/local/gnu/include /usr/local/include
          do
            if test -d "$x"; then
              case $CPPFLAGS in
              .*-I$x)
                CPPFLAGS="$CPPFLAGS -I$x"
                ;;
              esac
            fi
          done
          -----------------------------------------------------------------------
          
             I have not completed compiling, installing, testing yet, but presume I
          should be fine from here. Thanks for the help.
          
          -Jeff
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              Jeff Reed
              Berkeley Software Design, Inc.
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


File: cfengine-Reference.info,  Node: HPUX,  Next: IRIX,  Prev: BSDI,  Up: FAQS and Tips

HPUX
----

_Q:_
     Problems with line length in lex/yacc.

_A:_
     See the FAQ for AIX.

_Q:_
     _What is the difference between the classes `hpux' and `hpux10'?_

_A:_
     In version 10 of HPUX, the file structure is reorganized to look
     more like SVR4. If you have an HPUX-10 system, the appropriate
     hardclass is `hpux10' rather than `hpux'.

_Q:_
     _I set up the new sendmail but the configuration file doesn't
     work._

_A:_
     There could be a frozen configuration file around.  Try:

          disable:
          
             hpux::
          
                /usr/lib/sendmail.fc

_Q:_
     _Why don't groups work in HPUX?_

_A:_
     HPUX uses the file `/etc/logingroup' not `/etc/group'. Make a link
     if you need to:

          links:
          
            hpux::
          
               /etc/logingroup -> /etc/group

__
     To encourage some cross-fertilization, here's a sanitized sendmail
     configuration script that I created for HPUX and HPUX10.  (From
     David Masterson, posted to gnu.cfengine.help). David's script is
     nice since sendmail was the inspiration for cfengine's name.

          #!/usr/local/bin/cfengine -f
          ####################################################
          #
          # File:		sendmail.conf
          #
          # Description: 	CFEngine script to setup the sendmail.cf.
          #
          ####################################################
          
          control:
          
          	access = ( root )
          
          #	Postmaster
          	sysadm = ( myPostmaster )
          
          #	NIS domain and group server
          	site = ( myserver )
          
          #	DNS domain
          	domain = ( myDNSdomain )
          
          #	our gateway host
          	gtwyhost = ( mygateway )
          
          #	sendmail.cf can be big
          	editfilesize = ( 1000000 )
          
          	actionsequence =
          		(
          		copy
          		files
          		editfiles
          		shellcommands
          		)
          
          #	disable unwanted classes with "--undefine" option
          	addclasses = ( maildom mailhst )
          
          ################
          #	bindir - location of sendmail
          #	libdir - location of current mail files
          #	cfgdir - location of initial mail files
          #	etcdir - location of hosts.smtp
          #	own    - who should own result files
          #	grp    - what group should result files be in
          ################
              hpux::
          	bindir = ( /usr/lib )
          	libdir = ( /usr/lib )
          	cfgdir = ( /etc/newconfig )
          	etcdir = ( /etc )
          	own = ( root )
          	grp = ( sys )
          
              hpux10::
          	bindir = ( /usr/sbin )
          	libdir = ( /etc/mail )
          	cfgdir = ( /usr/newconfig/etc/mail )
          	etcdir = ( /etc )
          	own = ( root )
          	grp = ( sys )
          
          #	disable with "--no-copy" option
          copy:
          
          	$(cfgdir)/sendmail.cf dest=$(libdir)/sendmail.cf type=checksum
          		mode=0644 owner=$(own) group=$(grp) force=true
          
          #	checks for other important files
          files:
          
          	$(libdir)/aliases mode=444 owner=$(own) group=$(grp) action=touch
          	$(libdir)/rev-aliases mode=444 owner=$(own) group=$(grp) action=touch
          	$(etcdir)/hosts.smtp mode=444 owner=$(own) group=$(grp) action=touch
          
          #	disable with "--no-edit" option
          editfiles:
          
              any::
          
          #	setup general part of sendmail.cf
          	{ $(libdir)/sendmail.cf
          
          	SetCommentStart '#'
          	SetCommentEnd ''
          	ResetSearch "1"
          	UnCommentLinesMatching "#OP.*"	# activate Postmaster
          	ResetSearch "1"
          	UnCommentLinesMatching "#DY.*"
          	ResetSearch "1"
          	LocateLineMatching "DY.*"
          	ReplaceLineWith "DY$(site).$(domain)"	# set site hiding
          	ResetSearch "1"
          	UnCommentLinesMatching "#DS.*"
          	ResetSearch "1"
          	LocateLineMatching "DS.*"
          	ReplaceLineWith "DS$(gtwyhost)"	# all-knowing SMTP host
          	# Ruleset 0 setups
          	ResetSearch "1"
          	UnCommentLinesMatching "#R.*user@domain to SMTP relay.*"
          	ResetSearch "1"
          	LocateLineMatching "# try to connect to any host for user@domain"
          	IncrementPointer "1"
          	CommentNLines "1"
          	}
          
          #	add Postmaster alias
          	{ $(libdir)/aliases
          
          	SetLine "Postmaster: $(sysadm)"
          	AppendIfNoLineMatching "Postmaster.*"
          	}
          
          #	setup processing of local domain hosts
              maildom::
          
          	{ $(libdir)/sendmail.cf
          
          	SetCommentStart '#'
          	SetCommentEnd ''
          	ResetSearch "1"
          	LocateLineMatching "DL.*"
          	ReplaceLineWith "DL$(domain)"
          	# Ruleset 0 setups
          	ResetSearch "1"
          	LocateLineMatching "# connect to hosts in local domain"
          	IncrementPointer "1"
          	UnCommentNLines "1"
          	}
          
          #	setup processing via class S
              mailhst::
          
          	{ $(libdir)/sendmail.cf
          
          	SetCommentStart '#'
          	SetCommentEnd ''
          	ResetSearch "1"
          	UnCommentLinesMatching "#FS.*"
          	# Ruleset 0 setups
          	ResetSearch "1"
          	LocateLineMatching "# connect to hosts in class S"
          	IncrementPointer "1"
          	UnCommentNLines "1"
          	}
          
          #	setup of list of hosts for class S
          	{ $(etcdir)/hosts.smtp
          
          	EmptyEntireFilePlease
          	Append "localhost1"
          	Append "localhost2"
          	}
          
          #	disable with "--no-commands" option
          shellcommands:
          
          	"$(bindir)/sendmail -bk"
          	"$(bindir)/sendmail -bi"
          	"$(bindir)/sendmail -bz"
          	"$(bindir)/sendmail -bd"
          
          ################
          # End of File
          ################


File: cfengine-Reference.info,  Node: IRIX,  Next: LINUX,  Prev: HPUX,  Up: FAQS and Tips

IRIX
----

_Q:_
     _Hints about IRIX?_

_A:_
     Send them to <bug-cfengine@gnu.org>.


File: cfengine-Reference.info,  Node: LINUX,  Next: OSF,  Prev: IRIX,  Up: FAQS and Tips

LINUX
-----

_Q:_
     When I try to compile `cfd' I get this error
           /usr/lib/libwrap.a(options.o): In function `twist_option':
           options.o(.text+0x5f7): undefined reference to `deny_severity'
           /usr/lib/libwrap.a(options.o): In function `severity_option':
           options.o(.text+0x808): undefined reference to `deny_severity'
           options.o(.text+0x81c): undefined reference to `deny_severity'
           options.o(.text+0x821): undefined reference to `deny_severity'
           options.o(.text+0x826): undefined reference to `deny_severity'
           options.o(.text+0x82b): undefined reference to `allow_severity'
           make[1]: *** [cfd] Error 1

_A:_
     There seems to be a problem with the distributed version of the
     TCP wrappers library. Edit the `src/conf.h' file and comment out
     the `#define HAVE_LIBWRAP 1' line.  This means that you will not
     be able to use TCP wrappers security however. You might prefer to
     collect and compile a new version of TCP wrappers.

_Q:_
     _Linux insists on rebuilding the message of the day file each time
     it boots, but that means I keep losing the messages I leave there._

_A:_
     Add the following to your configuration files to comment out the
     offending lines in the startup scripts:

          editfiles:
          
             linux::
          
              { /etc/rc.d/rc.S
          
              HashCommentLinesContaining "motd"
              }


File: cfengine-Reference.info,  Node: OSF,  Next: SUN (4.1.*),  Prev: LINUX,  Up: FAQS and Tips

OSF
---

_Q:_
     Hints about OSF/1?

_A:_
     Send them to <bug-cfengine@gnu.org>.


File: cfengine-Reference.info,  Node: SUN (4.1.*),  Next: SOLARIS 2,  Prev: OSF,  Up: FAQS and Tips

SUNOS (4.1.*)
-------------

_Q:_
     _How can I delete the `+' sign from the `/etc/hosts.equiv' file to
     improve security?_

_A:_
     Use editfiles to delete it:

          editfiles:
          
             sun4::
          
                { /etc/hosts.equiv
          
                DeleteLinesMatching "+"
                }

