
How to write activation criteria:

An activation criteria is essentially a boolean expression, an arrow,
and the name of a wrapper that should be activated by the WSS if the
expression evaluates to TRUE at exec-time.  Actually, a single
activation critiera may contain a number of such "boolean ==> wrapper"
clauses.  An activation criteria can be invalid in three ways:

	1) parse-time: it doesn't parse (our code parses it into C), or it
		referrs to system variables that aren't available to
		activation criteria, or users/groups that don't exist
		on the system doing the parsing,
	2) compile-time: the generated C-code doesn't compile (e.g.,
		because a constant value passed through to C is not
		legal C), and
	3) load-time: it references wrappers that don't exist in the WSS.

This note explains how to write valid activation criteria.  A simple
activation criterion is:

(user == badger) ==> foo

It means, if the user is badger, activate the foo wrapper.  This
activation criterion contains one "rule."  It is invalid if the system
doesn't have a "badger" user or if there is no foo wrapper.  A similar
activation criterion contains two rules:

(user == badger) ==> foo &&
(user == cvance) ==> bar

If the user is badger, the criterion will start foo; if the user is
cvance, the criterion will start bar.  An activation criterion
evaluates all rules.  The "&&" is there for clarity (i.e., it's not
doing short-circuit evaluation); we can remove it if it doesn't
clarify.  A single activation criterion may have any number of
clauses.

Within each clause, the boolean expression compares literal values in
the activation criterion to system state variables.  For example, the
following activates foo if the user is either badger or cvance:

(user == badger) || (user == cvance) ==> foo

The boolean-valued subparts of the boolean expression can be combined
using either && or ||.  The following activation criterion, which uses
&&, never activates the wrapper because the current user can't be both
badger and cvance:

(user == badger) && (user == cvance) ==> foo

Additionally, a boolean can be negated; the following activates foo at
every exec:

!((user == badger) && (user == cvance)) ==> foo

There are four central string-valued attributes that can be referred to
within an activation criterion:
	user:	the current user
	prog:	the path of the program currently being run (abs or rel)
	pprog:	the path of the previous program (absolute or relative)
	cwd:	the current working directory (absolute)

In general, the following binary operators work on these: ==, !=, and,
TBD, regular expression matching (=~ m|xxx| is TBD because I'm not
sure we want regexp(3) in the kernel).  For example:

(user != badger) ==> foo

activates foo if the current user is not badger.  We can combine such
expressions to do thing like: run a wrapper only if the user is not a
member of a trusted group:

(user != uecker) &&
(user != cvance) &&
(user != kaos) &&
(user != feldman) &&
(user != badger) ==> foo

Or use the equality operator to define untrusted groups:

(user == uecker) ||
(user == cvance) ||
(user == kaos) ||
(user == feldman) ||
(user == badger) ==> foo

If we use this feature a lot, we may wish to add sets to our
expressions and a membership operator.  This wouldn't be hard.

We can reference as many variables as makes sense:

(user == badger) && (pprog == rlogin) && (prog == vi) ==> foo


----------------------------------------------------------------------
The rest this file is notes.

(cwd =~ m|^/etc|) 

The following, TBD:

When the variable is a program, the parser converts based on whether
you specified an absolute or relative path name.

children, cputime, descriptors, memoryuse, niceval

And then, some boolean functions:
	setuid
	setuid(user)
	setuid_from(user)

We may want parameters for wrapper activation: this way, the context
of activation could be understood by the wrapper.
