Provided by: dacs_1.4.28b-3ubuntu2_amd64 

NAME
dacs.acls - DACS access control rules
DESCRIPTION
These files are part of the DACS suite.
When DACS receives a service request, expressed as a URL (see RFC 1738[1], RFC 2396[2], and RFC 3986[3]),
it invokes ACS (its access control service, dacs_acs(8)[4]) to determine whether the request should be
carried out. ACS defines a language in which access control specifications are written to describe the
conditions under which access to a resource is to be granted or denied.
When it is invoked, ACS is provided with the service request URI, its parameters (if any), the current
credentials of the client, and certain environment-dependent variables. A simple protocol defines how the
web server passes this information to ACS and how ACS passes its access control decision back to the web
server (see dacs_acs(8)[4]).
If access is not revoked for the client, ACS proceeds to search for an applicable ACL rule for the given
request and client. It first searches through custom files (those configured for the jurisdiction through
the virtual filestore's item type "acls"); if necessary, it will also look through a set of standard
access control rules (those configured through the virtual filestore's item type "dacs_acls") in an
attempt to find a closer match.
This document describes access control rules and the DACS authorization procedure.
Tip
The dacsacl(1)[5] command is used to validate the syntax of the rulesets and to rebuild indexes.
After changing a ruleset by adding, removing, or modifying a rule, dacsacl(1)[5] must be run.
Revoking Access and Disabling Authentication: The Revocation List
It is sometimes useful to have the administrative capability to "pull the plug" on a particular user,
class of users, or depending on other context. This can be done in a "global" way by configuring a
revocation list. The revocation list is consulted during authorization checking and by various
authentication related components. The revocation list is processed by dacs_acs(8)[4] before the
rulesets, thereby overriding all access control rules, to see if a request should be denied based on the
current credentials (if any) associated with the user making the request. The revocation list is also
used by dacs_authenticate(8)[6], dacs_auth_transfer(8)[7], and dacs_auth_agent(8)[8] immediately after a
tentatively successful authentication to check if access has been revoked for the DACS identity
established through the normal authentication procedure. Note that the revocation list is not used by
dacsauth(1)[9] or dacscheck(1)[10] (although it arguably it should be, at least optionally).
A revocation list must be configured through the item type "revocations" and must be readable, although
it can be empty.
The list consists of a sequence of lines, evaluated in the order in which they appear, each of which may
contain:
• deny expression
If the expression evaluates to True, 1) access is denied and the user's request is not performed and
2) revocation list processing terminates
• revoke expression
The expression is evaluated once for each set of credentials; if the expression evaluates to True, 1)
those credentials will be ignored in all subsequent processing of the current request (as if they did
not exist), including the remainder of revocation list processing, 2) access is not necessarily
denied, and 3) revocation list processing continues with the next line; in the case of an
unauthenticated user, revoke has the same meaning as deny. Revoking all credentials makes the user
unauthenticated with respect to this request. Note that this revocation does not affect any
credentials held by the user, it only temporarily "hides" them.
Note
It is not currently possible to construct a single expression that tests multiple credentials. If
this creates difficulties, consider using the ACS_CREDENTIALS_LIMIT[11] or AUTH_SINGLE_COOKIE[12]
directive.
• disable expression
The expression is evaluated in a context that includes the tentative credentials. If it evaluates to
True, the account is deemed to be disabled and the credentials will not be issued. This is the only
keyword used specifically for disabling authentication and is ignored during access control
processing.
• block expression
This form combines deny and disable behaviour to both deny access and disable authentication,
effectively blocking all access that satisfies the expression.
• a comment, where the first non-whitespace character, if any, is a '#'
The keywords are case insensitive and one or more whitespace characters appear between a keyword and the
expression. A line can be continued by ending it with a backslash. Any line may be preceded by whitespace
characters.
DACS expressions are described in dacs.exprs(5)[13].
Examples:
# Deny access to all
deny user("any")
# Deny access to any user not already authenticated
# (subsequently no one will be able to authenticate)
deny user("unauth")
# Revoke all identities, making all users effectively unauthenticated
revoke user("any")
# Deny access to any user not authenticated by this jurisdiction
deny user("unauth") or not user("${Conf::JURISDICTION_NAME}:")
# Revoke the identity DSS:rmorriso
revoke user("DSS:rmorriso")
# Deny all access on the weekend
deny time("wday") eq 6 or time("wday") eq 0
# Deny any request not originating from a local network
deny not (from("10.0.0.0/8") or from("192.168.2.0/24"))
# Do not issue credentials to anyone from 10.0.0.124 but access is
# still possible
disable from("10.0.0.124")
# Do not issue credentials to DSS:bobo
disable user("DSS:bobo")
# Neither issue credentials nor grant access to DSS:bobo
block user("DSS:bobo")
URL Paths and Service Name Matching
While matching a service request against ACL rules, ACS recognizes a hierarchical structure for service
names based on the path component of an HTTP (or HTTPS) URL. The URL path "/cgi-bin", for example, is
considered to be an ancestor or parent of the path "/cgi-bin/program". The former URL path has two
components, the latter has three components. The one-component URL path "/" is considered to be the
ancestor of all other paths.
The * operator, which matches zero or more components that follow it, has special meaning only when it
appears as a path component at the end of a URL path pattern specified by a rule. A system administrator
can use the tail matching (wildcard) capability to establish default rules for portions of the name space
of service requests. For instance the URL path pattern "/cgi-bin/*" is considered to be the ancestor of
all paths having the prefix "/cgi-bin/" and matches service requests for "/cgi-bin/printenv",
"/cgi-bin/", and "/cgi-bin".
Before matching a service request against the ruleset, ACS converts the service request into a canonical
form. It strips any trailing / characters off of the service name (although the URL path pattern "/" is
unchanged). Only absolute URLs can be specified in an ACL rule. The URL expressing the service request
must also be absolute when received by DACS; typically, a web server will canonicalize the pathname
corresponding to static content before ACS is invoked.
Note
It is the URL-encoded request URI (passed by Apache as ${DACS::URI}) that is matched against access
control rules. Path components of URLs used for matching in rules are URL-decoded before being
compared against the path components of the request URI, which are also URL-decoded.
ACS searches the ruleset for the rule having the most specific URL path pattern that applies to a given
request URI; that is, it examines the rules to find the one that has the greatest number of components in
common with the service request's. If no exact match is found, it will search for increasingly general
rules that apply. Only the most specific matching rule will be applied to the request; if it fails, no
other (less specific) matching rule will be considered. If two or more rules "tie" (e.g., because of
duplicate rules), one rule will be chosen arbitrarily. If no suitable match if found, ACS will deny
access.
Note
The URL path pattern may not contain a query component; this may be changed in future versions.
ACS does not recognize alternate names for the same resource (e.g., achieved using symbolic links), so it
is possible for each of several names for the identical resource to be associated with different access
control rules.
Security
It is not necessarily the case that permission to access a parent or any ancestor is required to
access a descendent path.
It should be emphasized that the service request URL received by the web server is textually matched
against ACL rules without any interpretation on the part of ACS. Other than whether it will be mapped to
static content or a CGI program, what the URL represents or how it will be processed by the web server is
not taken into account by ACS.
For example, a service request for "/weekly" is not the same as a service request for
"/weekly/index.html", even if "/weekly" is a directory and the web server would map the request to a file
named "/weekly/index.html" and return its contents. A rule with the URL path pattern "/weekly/index.html"
or "/weekly/*" (or perhaps "/*") is needed to control access to the file "/weekly/index.html".
Service Parameters
A user agent may optionally pass parameters to CGI programs. With the HTTP GET method, the parameters are
appended to the URL sent to the web server (the "query string") and the CGI program. While the HTTP
specification (RFC 2616[14]) does not impose a limit on the length of a URL, a browser or web server may
impose a maximum. (Recent versions of Internet Explorer have a maximum URL length of 2,083 bytes and the
Apache web server imposes a limit of about 8192 bytes.) In the case of the HTTP POST method, the
parameters are streamed from the user agent to the web server and then to the CGI program, so the
potential number of parameters and their combined size is unbounded. ACS can optionally provide a finer
granularity of access control by inspecting the parameters passed with a service request. By examining
parameters, an ACL rule can be used to prevent certain users from gaining particular kinds of access. A
rule might restrict a parameter value to be within a certain allowed range, for example. ACS supports
expressions that may test whether particular service parameters are present or reference their values.
Because in the case of the POST method it is impractical, in general, to pass ACS all parameters and
their values, a web server may impose limits on the number of parameters and aggregate size of parameters
that it will make available to ACS. An invoked CGI program is unaffected by this limitation, however.
Apache's mod_auth_dacs[15] module allows its administrator to configure the maximum size of parameter
data provided by the POST method that is made available to ACS.
Constraints
In some cases, merely testing parameter values is insufficient to determine whether access should be
granted. Consider the case where a service is a program, a request's parameters represent the coordinates
of a geographic area to be displayed, and some areas are not to be shown to some users, perhaps because
they are "top secret". Examination of the parameters alone may be insufficient to determine whether the
area they describe is within such a restricted area and perhaps ought not to be displayed. That
determination might also depend on the contents of a database or complex calculations, for example. It
is, therefore, beyond the scope of ACS to make access control decisions in such cases.
ACS addresses this problem by allowing constraints to be attached to an ACL rule and by passing them, and
the identity of the client, to the service. A constraint may be thought of as a tag or additional
argument that a service recognizes. If an ACL rule permits the service to be invoked, it is the
responsibility of the service to take any constraints into consideration and make the final decision
about granting access, which it is much better qualified to do than is ACS. In the case previously
described, a constraint might notify the service that the particular user should be granted access only
if the request does not involve a restricted area.
Of course, the purpose and meaning of a constraint depends on the implementation of a particular service.
Different services might interpret the same constraint in completely different ways. For example, a
service that performs both read-only operations and update operations might be implemented to recognize
the constraint string "read-only" as meaning that it should only perform read-only operations.
Alternatively, that same service might instead handle a request accompanied by the constraint string
"updates-allowed" by permitting any operation for the user making the request; the absence of that
constraint would restrict its functionality to read-only operations.
For additional detail, please refer to descriptions of the DACS_CONSTRAINT and DACS_DEFAULT_CONSTRAINT
environment variables.
ACL Files
Each access control rule is stored in a virtual filestore under the item types acls and dacs_acls. The
acls must be configured, and ordinarily consists of site-specific or jurisdiction-specific rules; the
latter (dacs_acls) is optional and is intended to configure rules for the standard DACS web services.
The default configuration (from site.conf-std) is:
VFS "[acls]dacs-fs:${Conf::FEDERATIONS_ROOT}/\
${Conf::FEDERATION_DOMAIN}/${Conf::JURISDICTION_NAME}/acls"
VFS "[dacs_acls]dacs-fs:${Conf::DACS_HOME}/acls"
Most installations store ACLs as ordinary files. This is reflected in the default configuration directive
shown above and is why they are imprecisely referred to as "ACL files".
Tip
To make upgrading easier, avoid adding access control rules to dacs_acls (default location:
/usr/local/dacs/acls) or modifying the default rules for DACS web services that appear there.
Instead, put all customizations where acls has been configured. By following this practice, your
customizations will not be lost when you install a new version of DACS.
ACL Naming
The names of ACL files (more precisely, the names of items within a virtual filestore) follow a
particular convention: they must begin with the characters "acl-" (note: the fourth character is a
hyphen, not an underscore) and end with a period followed by an unsigned integer value. At least one
character must appear between the prefix and the suffix that begins with the period character. For
example, any of the following names might be used:
acl-photos.0
acl-photos.1
acl-files.40
Tip
Although not currently enforced, an ACL file name should be composed of characters from the
Portable Filename Character Set[16]: any alphanumeric character, period, hyphen, or underscore.
An ACL file may be disabled (not used by ACS) if a valid ACL filename is preceded by the characters
"disabled-". The three ACLs above would be disabled if they were renamed as follows:
disabled-acl-photos.0
disabled-acl-photos.1
disabled-acl-files.40
Note
These two filename prefixes are defined at compile time. dacsacl(1)[5] should be enhanced to
notice simultaneously enabled and disabled files. FedAdmin, a contributed resource[17], is an
administrative interface that can manage ACLs, including enabling, disabling, fetching, and
deleting them.
The numeric suffix is significant. It is used to order the evaluation of the rules by the access
control service; the rules are evaluated in ascending order.
Optionally, "subdirectories" (to any depth) can be created to help organize the access control rules.
The naming convention for these subdirectories is the same as for ACL files. Disabling a subdirectory
effectively disables all ACL files and subdirectories beneath it. The ordering process at each level
is still based on the integer suffixes. Here is an example ordering of access control rules, from
first to last:
/usr/local/dacs/federations/dss/acls/acl-x.0
/usr/local/dacs/federations/dss/acls/acl-x.2
/usr/local/dacs/federations/dss/acls/acl-x.3/acl-y.7
/usr/local/dacs/federations/dss/acls/acl-x.4
/usr/local/dacs/federations/dss/acls/acl-x.5
/usr/local/dacs/federations/dss/acls/acl-x.6/acl-x.1
All ACL files and subdirectories that have invalid names are silently ignored, as are all files that
are not regular files or directories (e.g., symbolic links). The behaviour is undefined if, for
example, files named "acl-foo.0" and "disabled-acl-foo.0" exist simultaneously.
Note
Access control rules are ordinarily not placed in a location where a web server could serve them.
If access control rules are themselves DACS-wrapped, however, care must be taken to structure the
rules to avoid an infinite regress.
ACL Syntax
Basically, an ACL rule compactly expresses the triple (What, Who, How).
What:
the names of one or more services the rule applies to;
Who
the set of users the rule applies to; and
How
predicates and constraints that describe the conditions under which access will be allowed.
Although it's certainly possible to write complicated access control rules, you needn't be intimidated.
Rules are typically quite simple and easy to understand, such as the following rule which applies to a
URL that has a path component ending in /cgi-bin/dacs/myprog.php and grants access to any authenticated
user:
<acl_rule status="enabled">
<services>
<service url_pattern="/cgi-bin/dacs/myprog.php"/>
</services>
<rule order="allow,deny">
<allow>
user("auth")
</allow>
</rule>
</acl_rule>
An access control rule is written and stored externally as an XML document with the following DTD
(acl.dtd[18]). Management of ACL rules can be done using a standard text editor, web-based interface, or
special-purpose GUI. An administrator might only see a user-friendly description of the rules and need
never see a lower-level representation such as this XML representation.
<!ELEMENT acl_rule (services, (identity)*, (rule)+)>
<!ATTLIST acl_rule
status (enabled | disabled) #IMPLIED
name CDATA #IMPLIED
expires_expr CDATA #IMPLIED
constraint CDATA #IMPLIED
permit_chaining (yes | no) #IMPLIED
pass_credentials (none | matched | all) #IMPLIED
pass_http_cookie (yes | no) #IMPLIED
permit_caching (yes | no) #IMPLIED
>
<!ELEMENT services (service | delegate)+>
<!ATTLIST services
shared (yes | no) #IMPLIED
>
<!ELEMENT service EMPTY>
<!ATTLIST service
id CDATA #IMPLIED
url_pattern CDATA #IMPLIED
url_expr CDATA #IMPLIED
>
<!ELEMENT delegate EMPTY>
<!ATTLIST delegate
id CDATA #IMPLIED
url_pattern CDATA #IMPLIED
url_expr CDATA #IMPLIED
rule_uri CDATA #REQUIRED
>
<!ELEMENT identity EMPTY>
<!ATTLIST identity
id CDATA #IMPLIED
iptr CDATA #REQUIRED
ident CDATA #REQUIRED
selector_expr CDATA #REQUIRED
>
<!ELEMENT rule ((precondition)?, (allow | deny)*) >
<!ATTLIST rule
id CDATA #IMPLIED
order CDATA #REQUIRED
<!-- order is either of: "allow,deny" or "deny,allow" -->
constraint CDATA #IMPLIED
permit_chaining (yes | no) #IMPLIED
pass_credentials (none | matched | all) #IMPLIED
pass_http_cookie (yes | no) #IMPLIED
permit_caching (yes | no) #IMPLIED
>
<!ELEMENT precondition ((user_list)?, (predicate)?)>
<!ELEMENT user_list (user)*>
<!ELEMENT user EMPTY>
<!ATTLIST user
id CDATA #IMPLIED
name CDATA #REQUIRED
>
<!ELEMENT predicate (#PCDATA)>
<-- The allow element allows (grants) access, subject to the -->
<-- allow,deny/deny,allow order, if the enclosed expression is TRUE -->
<-- Note: any '<' and '&' characters appearing within an allow element -->
<-- must be escaped as < and &, respectively -->
<!ELEMENT allow (#PCDATA)>
<!ATTLIST allow
id CDATA #IMPLIED
constraint CDATA #IMPLIED
permit_chaining (yes | no) #IMPLIED
pass_credentials (none | matched | all) #IMPLIED
pass_http_cookie (yes | no) #IMPLIED
permit_caching (yes | no) #IMPLIED
>
<-- The deny element denies access, subject to the allow,deny/deny,allow -->
<-- order, if the enclosed expression is TRUE -->
<-- Note: any '<' and '&' characters appearing within an allow element -->
<-- must be escaped as < and &, respectively -->
<!ELEMENT deny (#PCDATA)>
<!ATTLIST deny
id CDATA #IMPLIED
>
The optional id attribute assigns a unique label (within its acl_rule) to an element so that it can be
identified conveniently and unambiguously. Attribute values consist of one or more alphanumerics and
underscores. At present, no other semantics are assigned to this attribute, but this may change in future
releases. Labels that begin with an underscore are reserved for DACS-generated labels.
General Structure
An access control rule can be divided into two parts: an ordered list of service specifications (the
services element) that are matched against service requests, and an ordered list of rule
specifications (the rule elements) that are processed if and only if one of the service elements is
applicable. In the event that the access control rule grants access, various aspects of subsequent
processing can be controlled and defaults can be established.
Services
This part of the rule is used during rule selection. Each service element specifies a service to
which this access control rule applies. The delegate element identifies a service that is handled by
an access control rule specified elsewhere. Delegation is useful if parts of the URL space are
managed by different users or if rules are stored in different locations.
Rule Clause Processing
An access control rule consists of one or more rule elements, also called rule clauses. A rule clause
consists of allow and deny elements. The allow element allows (grants) access if the enclosed
expression is True, subject to the rule's order attribute. The deny element denies access if the
enclosed expression is True, subject to the rule's order attribute.
Each rule must have an order attribute that says whether the evaluation order is "allow,deny" or
"deny,allow". This attribute serves much the same purpose as, and has semantics similar to, the
Apache mod_access[19] module's Order directive.
The allow,deny ordering denies access by default and causes allow elements to be evaluated before
deny elements. A request that does not satisfy an allow element or does satisfy a deny element will
be denied. Equivalently, a request must satisfy an allow element but not satisfy any deny element for
access to be granted. If a rule element has no allow element, it is processed as if it had an allow
element that evaluated to False. If a rule element has no deny element, access is granted only if an
allow element evaluates to True.
The deny,allow ordering permits access by default and causes deny elements to be evaluated before
allow elements. A request that does not satisfy a deny element or does satisfy an allow element will
be allowed. Equivalently, a request must satisfy a deny element but not satisfy any allow element for
access to be denied. If a rule element has no deny element, it is processed as if it had an deny
element that evaluated to False. If a rule element has no allow element, access is granted only if no
deny element evaluated to True.
As soon as one allow (deny) element evaluates to True, no other elements of the same type are
evaluated.
Note
Any '<' and '&' characters appearing within an allow element or a deny element must be escaped as
"<" and "&", respectively.
The Precondition Element
A rule may optionally have exactly one precondition element. The precondition element is a "guard" to
enable or disable a particular rule. This might be used, for example, to write one rule for weekdays
and another for weekends. It can specify a list of users, an expression, or both. For the rule to be
enabled for evaluation, its expression must first evaluate to True; if the user_list element is
present, the user making the request must be among those listed and if the predicate is present, it
must evaluate to True. The precondition primarily serves three purposes:
1. it can make it clear which user(s) the rule applies to;
2. it can improve by efficiency by avoiding having to evaluate potentially expensive expressions;
and
3. it provides a way to have multiple rule elements, any of which might be enabled depending on the
run-time context.
Expressions
DACS employs expressions in access control rules and in configuration files (see dacs.exprs(5)[13]).
For example, an expression or sequence of statements may appear within predicate, allow, and deny
elements of an access control rule. If an expression (or sequence) evaluates to zero, the null
string, or an error occurs, the result is False. If it evaluates to non-zero or a non-null string and
no error occurs, the result of the expression (or sequence) is True. In general, arithmetic overflow
and underflow, rounding, and other similar conditions will not be detected or considered as errors.
The particular context within which a service request is being evaluated is made available to an
expression through a set of variables. They are described with the dacs_acs(8)[4].
Rules are examined in the order in which they are specified. If a precondition is False, processing
continues with the next rule. The first rule with a True precondition will be used; no other rule
will be examined. If no precondition element is given for a rule, it is equivalent to a precondition
that evaluates to True. If no rule satisfies its precondition, access is denied.
ACL Rule Elements
The various syntactical components of access control rules are now described. When a request is being
processed, ACS examines a ruleset, which is a collection of acl_rule elements that are located and
accessed depending on the jurisdiction's configuration.
DACS expressions are described in dacs.exprs(5)[13].
acl_rule
<!ELEMENT acl_rule (services, (identity)*, (rule)+)>
<!ATTLIST acl_rule
status (enabled | disabled) #IMPLIED
name CDATA #IMPLIED
expires_expr CDATA #IMPLIED
constraint CDATA #IMPLIED
permit_chaining (yes | no) #IMPLIED
pass_credentials (none | matched | all) #IMPLIED
pass_http_cookie (yes | no) #IMPLIED
permit_caching (yes | no) #IMPLIED
>
An acl_rule specifies, for a given set of services, the conditions under which a request for one
of those services is to be granted (or denied). It may also establish new default behaviours
(overriding compile-time or configuration defaults) that will be used unless they are in turn
overridden during processing of this rule. The name attribute can be used to assign a symbolic
name to the rule; some programs (e.g., dacsrlink(1)[20]) use this name to catch errors. The
expires_expr attribute determines if the ACL should be ignored (and potentially deleted, although
no DACS programs currently implement this). If the expression expires_expr evaluates to True, the
rule should be deleted.
identity
<!ELEMENT identity EMPTY>
<!ATTLIST identity
id CDATA #IMPLIED
iptr CDATA #REQUIRED
ident CDATA #REQUIRED
selector_expr CDATA #REQUIRED
>
This element associates a specified identity (ident) with the request during processing of this
acl_rule only. This "assigned identity" overrides any identity or identities that were submitted
with the request and is not tested for revocation. The iptr attribute is essentially a unique
label for this element.
The identity elements are examined, in the order in which they appear, until one element is
selected; no other elements will be processed. An element is selected if its attribute
(selector_expr), which is an expression, evaluates to True, in which case the identity specified
by the ident attribute is used; its value must be a syntactically valid identity in the concise
user syntax[21]. Access will be denied if an invalid identity is produced, and rule processing
will proceed normally if no element is selected.
The primary purpose of this element is to support an operational mode of the Rlinks[22] feature,
but the capability may eventually be generalized. This element is subject to change. A future
enhancement may allow the identity to alternatively be determined by expression evaluation.
services
<!ELEMENT services (service | delegate)+>
<!ATTLIST services
shared (yes | no) #IMPLIED
>
This element groups service and delegate elements.
service
<!ELEMENT service EMPTY>
<!ATTLIST service
id CDATA #IMPLIED
url_pattern CDATA #IMPLIED
url_expr CDATA #IMPLIED
>
To decide whether this acl_rule might apply to a request, ACS examines the set of one or more
service elements. Each service element has either a url_pattern attribute or a url_expr attribute
(but not both); the only difference is that the url_expr attribute is an expression that is
evaluated and converted to a string that is used internally as the url_pattern (it is a fatal
error if the evaluation results in an error or the null string). Each effective url_pattern,
whether given as a url_pattern attribute value or derived from a url_expr, is a simple pattern
that may be matched against the URL of a service request. With the exception of the special '*'
pattern, an effective url_pattern must begin with a '/'; its last component may be a '/*' to
indicate that the pattern matches zero or more components of the service request URL that follow.
The special '*' pattern always results in a successful exact match, causing rule searching to
terminate immediately. It is useful as the value of a url_expr that has determined that its rule
should be selected. Note that the semantics of this pattern are different from those of the
pattern '/*', which results in a successful match only if no closer match is found.
During matching, the URL of the service request is first stripped up to and including the
hostname part, and parameters, if any, are excluded (starting with a '?' character and extending
to the end). Any trailing '/' characters are removed.
Consider the service request "/cgi-bin/metalogic/metalogic_groups" being matched against the
following set of service elements:
1. <service url_pattern="/*"/>
2. <service url_pattern="/cgi-bin/*"/>
3. <service url_pattern="/cgi-bin/metalogic/*"/>
4. <service url_pattern="/cgi-bin/metalogic/metalogic_groups"/>
5. <service url_pattern="/tmp/foo.gif"/>
The first four prefixes match the service request URL, but the fourth url_pattern is selected
since it is the most specific match, with the third url_pattern being the next most specific
match.
When a single site is home to more than one jurisdiction, it is often handy to be able to share
access control rules among the jurisdictions. The shared attribute controls this behaviour. This
is best described through an example. Consider the following (partial) Jurisdiction sections:
<Jurisdiction uri="dss.ca">
JURISDICTION_NAME "ANIMAL"
</Jurisdiction>
<Jurisdiction uri="dss.ca/dog">
JURISDICTION_NAME "DOG"
</Jurisdiction>
<Jurisdiction uri="dss.ca/cat">
JURISDICTION_NAME "CAT"
</Jurisdiction>
With this feature enabled for a set of services, a request for dss.ca/cat/foo... will only
consider the /foo... substring when searching the url_pattern attributes to find a matching
rule.
The syntax for the shared attribute is as follows:
<!-- Share all services among -->
<!-- path-differentiated jurisdictions -->
<services shared="yes">
<!-- Do not share services among -->
<!-- path-differentiated jurisdictions -->
<services shared="no">
<!-- Default: share all services among -->
<!-- path-differentiated jurisdictions -->
<services>
Here are some examples, given the configuration above:
Partial request URI Matched url_pattern
dss.ca/cgi-bin/dacs/dacs_prenv --> /cgi-bin/dacs/dacs_prenv
dss.ca/dog/cgi-bin/dacs/dacs_prenv --> /cgi-bin/dacs/dacs_prenv
dss.ca/cat/cgi-bin/dacs/dacs_prenv --> /cgi-bin/dacs/dacs_prenv
Tip
The default behaviour is the same as if shared="yes" were specified. When this feature is
enabled, dss.ca/cat/cgi-bin/dacs/dacs_prenv will not match dss.ca/cgi-bin/dacs/dacs_prenv in
the example configuration above.
The default rules for DACS services assume the default behaviour with respect to sharing.
delegate
<!ELEMENT delegate EMPTY>
<!ATTLIST delegate
id CDATA #IMPLIED
url_pattern CDATA #IMPLIED
url_expr CDATA #IMPLIED
rule_uri CDATA #REQUIRED
>
The delegate element functions exactly like the service element with respect to matching. Its
purpose, however, is to redirect responsibility for subsequent access control processing for the
request to another ruleset.
There are many applications for this feature, but a common one is for a DACS administrator to
"carve up" the URL space by delegating parts of it such that individual users are responsible for
the rules governing their portion of the space. For example, URL paths that begin with /bob,
/ted, and /ann might be delegated to rulesets found in /u/bob/.dacs/acls, /u/ted/.dacs/acls, and
/u/ann/.dacs/acls, respectively, and a request like https://example.com/bob/index.html would be
fielded by the ruleset found in /u/bob/.dacs/acls.
If a delegate element is matched:
1. no rule clauses in this access control rule will be examined
2. any defaults specified in the acl_rule element will be discarded
3. processing of the current ruleset is terminated
4. the ruleset identified by the rule_uri attribute will be consulted
5. no default system ACLs (dacs_acls) will be examined
Processing of a delegated ruleset is performed in the same way as a non-delegated ruleset. A
delegated ruleset may delegate some or all of its services to another ruleset; a maximum depth of
three is enforced.
Any error encountered during processing will cause access to be denied.
Note
Despite the attribute name, the value of the rule_uri attribute must currently be a defined
item type or a URL that identifies a directory or a supported database (i.e., having a URL
scheme of file, dacs-db, or dacs-ndbm) The semantics of this attribute are still being
considered.
For example, an ACL with the elements:
<delegate url_pattern="/cgi-bin/myprog" rule_uri="my_acls"/>
<delegate url_pattern="/*" rule_uri="file:/u/bob/delegated"/>
and the configuration:
VFS "[my_acls]dacs-db:/u/bob/my_acls.db"
will delegate service requests matching the first element to rules found in the Berkeley DB file
/u/bob/my_acls.db and all other service requests to a ruleset found in the directory
/u/bob/delegated.
Security
Delegated access control rules have access to all functions (including exec()) and all
configuration information. Note that dacs_acs runs at the privilege level of Apache. For this
reason, be very careful how delegation is used. Log messages identify selection of delegated
rules and can be used to detect improper use. A future version of DACS should provide a way
to optionally restrict the abilities of delegated rules.
rule
<!ELEMENT rule ((precondition)?, (allow | deny)*) >
<!ATTLIST rule
id CDATA #IMPLIED
order CDATA #REQUIRED
<!-- order is either of: "allow,deny" or "deny,allow" -->
constraint CDATA #IMPLIED
permit_chaining (yes | no) #IMPLIED
pass_credentials (none | matched | all) #IMPLIED
pass_http_cookie (yes | no) #IMPLIED
permit_caching (yes | no) #IMPLIED
>
Assuming that ACS has determined that this acl_rule is the one that best matches a request, it
will then examine one or more of its rule elements and use the first one that has been enabled
(that is, satisfies its precondition). An enabled rule element may establish new default
behaviours (overriding compile-time, configuration, or acl_rule defaults) that will be used
unless they are in turn overridden during processing of this rule.
Information regarding rule clause processing[23] appeared earlier.
precondition
<!ELEMENT precondition ((user_list)?, (predicate)?)>
A precondition element is used to specify a set of users that includes the user making the
request, a condition that must evaluate to True, or both. ACS will examine the rule elements
from top to bottom, selecting the first rule having a precondition that is satisfied. That rule
is said to be enabled and no other rule will be considered. If no rule is enabled, access will be
denied.
Note
A precondition element must contain a predicate element, a user_list element, or both.
user_list, user
<!ELEMENT user_list (user)*>
<!ELEMENT user EMPTY>
<!ATTLIST user
id CDATA #IMPLIED
name CDATA #REQUIRED
>
A user_list element consists of zero or more user elements, each of which has a name attribute
that is matched against the client's current credentials. Please refer to the description of the
user()[24] function for details. A user_list that is absent or empty is effectively one that
satisfies the precondition. It does not matter to ACS whether a mentioned user, group, or
jurisdiction actually exists or is defined.
The following is an example of a user_list (group names are prefixed by a '%' character):
<user_list>
<user name="DSS:smith"/>
<user name="%METALOGIC:admin/>
<user name="10.0.0.118"/>
<user name="192.168.0.0/24"/>
<user name="DACS:"/>
<user name="unauth"/>
</user_list>
predicate
<!ELEMENT predicate (#PCDATA)>
A predicate contains an expression (or sequence of statements) that is evaluated in the context
of a particular request and client's current credentials. A predicate having no expression
evaluates to True. Expressions are described with dacs.exprs(5)[13]).
allow
<!ELEMENT allow (#PCDATA)>
<!ATTLIST allow
id CDATA #IMPLIED
constraint CDATA #IMPLIED
permit_chaining (yes | no) #IMPLIED
pass_credentials (none | matched | all) #IMPLIED
pass_http_cookie (yes | no) #IMPLIED
permit_caching (yes | no) #IMPLIED
>
An allow element contains an expression (or sequence of statements) that is evaluated in the
context of a particular request and client's current credentials. If it evaluates to True, an
allow element may establish particular behaviours (overriding compile-time or configuration
defaults or encompassing acl_rule or rule element defaults). Information regarding rule clause
processing[23] appeared earlier.
deny
<!ELEMENT deny (#PCDATA)>
<!ATTLIST deny
id CDATA #IMPLIED
>
A deny element contains an expression (or sequence of statements) that is evaluated in the
context of a particular request and client's current credentials. Information regarding rule
clause processing[23] appeared earlier.
If ACS grants access, various aspects of subsequent behaviour can be controlled through attributes of
acl_rule elements, with attributes specified at a "deeper" level overriding ones encountered earlier
during ruleset processing.
A constraint can optionally be specified. If access is granted and a constraint has been provided by
the particular allow element that evaluated to True, it is made available as the value of an
environment variable named DACS_CONSTRAINT exported to the invoked CGI program. If access is granted
and a default constraint has been provided, it is similarly made available as the value of an
environment variable named DACS_DEFAULT_CONSTRAINT. Neither variable is defined if no value for it
has been specified.
If access is granted, ACS can be told through the pass_credentials attribute whether it should pass
the user's current credentials on to the invoked service. For security reasons, it does not pass
credentials ("none") by default. It can be instructed to pass all current credentials ("all"); a
service such as dacs_current_credentials(8)[25], for example, needs to receive all of the current
credentials. A third alternative is to pass only the current credentials of the identity that was
used to grant access by having satisfied a user element ("matched"); in the case of multiple current
credentials, it may not be possible to predict which current credentials will be matched. When
permitted, credentials are passed in the same HTTP cookie format in which they were received as the
value of the DACS_COOKIE environment variable. DACS will look for the user's DACS cookies in that
variable before checking the HTTP_COOKIE environment variable.
Security
Because environment variables are typically visible to all programs on a system, ACS "hobbles" or
"weakens" credentials exported through them such that they can only be used in a few limited
ways. Using them for access control purposes is not one of those ways, otherwise a DACS identity
could easily be stolen by any user having access to the variables.
In addition to the environment variable problem, a user might be tricked into invoking a service,
though DACS-wrapped, that is under the control of an attacker. Weakening the credentials that are
available to the service makes it difficult for the attacker to do any harm with them.
A DACS administrator who understands the implications of visible credentials, and who still
insists on proceeding at his own risk, can disable the DACS security measures by setting the
permit_chaining attribute to yes. Any jurisdiction that should honor such credentials for access
control purposes must set the configuration directive PERMIT_CHAINING[26] to yes. This will allow
the credentials passed to a service invoked at that jurisdiction to be used for access control
purposes. By default, this "chaining" or "cascading" behaviour is not permitted and the
credentials are invalid for access control purposes.
If the pass_credentials attribute is all or matched for the matching rule, unaltered credentials
will be exported through the DACS_COOKIE environment variable.
If access is granted, DACS can be told whether it should pass the Cookie header field to the invoked
service. By default, pass_http_cookie is "no" to reduce the risk of cookies being exposed. Unless
DACS has been configured with ALLOW_HTTP_COOKIE set to "yes", DACS services will refuse to operate if
they receive a Cookie header field. If pass_http_cookie is "yes", however, the Cookie header field
will be retained.
Tip
Setting pass_http_cookie to "yes" is often necessary in cases where Apache does an internal
redirect, as when it invokes scripts through the Action[27] directive or when it automatically
creates a directory index (as by the Indexes option of the Options[28] directive). If this
attribute is not enabled, Apache will lose track of the identity associated with the request when
the redirection occurs, and it will appear to DACS as if the user making the redirected request
is not authenticated.
The permit_caching attribute is used to indicate that positive access control decisions associated
with the rule are eligible for caching. Please see Authorization Caching[29] for details.
Groups are discussed in a separately in dacs.groups(5)[30].
The ACL Selection and Evaluation Algorithm
The following algorithm is used by ACS to determine if a particular service request (S, in canonical
form) with optional parameters (P) should be granted for a user with verified credentials (C) within a
particular execution environment (E). At this point, ACS has already determined that the revocation list
has not denied access.
1. ACS searches the ruleset for an acl_rule (R) that lists a service or delegation (using url_pattern or
by evaluation of a url_expr) that most closely matches S. The list of services is examined in the
order in which they appear.
• If any acl_rule matches exactly, it is selected and the search for an acl_rule is terminated; no
other acl_rule in the current ruleset will be examined. Otherwise, the next acl_rule
specification will be examined.
• The acl_rule elements in the ruleset are examined in increasing order of the integer suffix of
each rule's name.
• A particular url_pattern should appear exactly once within the entire ruleset.
ACS does not treat a duplicated url_pattern as an error, however, nor is it required to check for
duplicates.
If the closest match delegates responsibility to another ruleset, the procedure restarts by searching
that ruleset.
2. Each rule element in R is examined, from top to bottom, until all have been examined or until one is
found that is enabled. An enabled rule either has no precondition element or has a precondition that
evaluates to True. If an enabled rule is found, no other rule will be considered. If no enabled rule
is found, access is denied.
• A precondition is True if the user is identified by a user element (or if there is no user_list
element or no user element) and if the predicate element evaluates to True (or if there is no
predicate element).
• During user_list processing, for each set of current credentials, the credentials are compared
against the list of user elements in the order in which the user elements appear in the
user_list.
• If there is more than one set of credentials accompanying the request, C is considered to be the
union of all of the credentials.
• If the enabled rule specifies the order allow,deny, then allow elements are examined before deny
elements; if the order is deny,allow, then deny elements are examined before allow elements.
• Evaluation of allow elements always stops when one evaluates to True.
• Evaluation of deny elements always stops when one evaluates to True.
• In the case of an allow,deny ordering, access is denied by default and allow elements are
evaluated before deny elements; a request that does not satisfy an allow element or does satisfy
a deny element will be denied.
• In the case of a deny,allow ordering, access is granted by default and causes deny elements to be
evaluated before allow elements; a request that does not satisfy a deny element or does satisfy
an allow element will be allowed.
• If any predicate evaluates to True, the user will be granted access to S with P.
3. If access is granted, default or specific attributes associated with the matching acl_rule, rule, or
allow elements will be passed to S.
Security
It is possible to construct rules such that more than one rule, allow, or deny element applies to a
particular user or are contradictory. Such conditions are neither detected nor considered an error.
EXAMPLES
For conciseness, some of the following examples omit the services element.
1. This rule grants access to everyone because it establishes "allow" as the default and there is no
satisfied deny element.
<rule order="deny,allow"></rule>
2. This rule denies access to everyone because it establishes "deny" as the default and there is no
satisfied allow element.
<rule order="allow,deny"></rule>
3. This rule establishes the evaluation order allow,deny and there are two allow elements and no deny
elements, which means that access will only be granted if one of the allow elements evaluates to
True. The second allow element evaluates to True if 1) the variable SCALE is greater than 1000 and
the user is authenticated or 2) the variable SCALE is greater than 10000 and the user is not
authenticated.
<rule order="allow,deny">
<allow>
user("METALOGIC:rmorriso") or user("DSS:brachman")
</allow>
<allow>
(${Args::SCALE} gt 1000 and user("auth"))
or (${Args::SCALE} gt 10000 and user("unauth"))
</allow>
</rule>
If the evaluation order deny,allow were selected instead, access would always be granted (since there
is no deny element and the default is to grant access). If neither of the allow elements evaluates to
True, however, default attributes (if present) would be in effect.
4. If SCALE is less than 10000 and LAYER-ELEMENT is one of the listed layers and the user is not in the
forest-inventory group, then deny. Otherwise, if the user is authenticated, allow.
<rule order="allow,deny">
<deny>
${Args::SCALE} lt 10000
and (${Args::LAYER-ELEMENT} eq "BC_ORTHO"
or ${Args::LAYER-ELEMENT} eq "BC_FC50K"
or ${Args::LAYER-ELEMENT} eq "AB_FC50K"
or ${Args::LAYER-ELEMENT} eq "SK_FC50K"
or ${Args::LAYER-ELEMENT} eq "MV_FC50K")
and (not user("%METALOGIC:forest-inventory-"))
</deny>
<allow>
user(auth)
</allow>
</rule>
5. The first of these rules is selected only for requests coming from members of the group
METALOGIC:forest-inventory. Access is granted to any member, except METALOGIC:rmorriso. The second of
these rules is selected for requests not coming from members of that group. Access is granted only if
the condition is True.
<rule order="allow,deny">
<precondition>
<user_list>
<user name="%METALOGIC:forest-inventory"/>
</user_list>
</precondition>
<allow>
not user("METALOGIC:rmorriso")
</allow>
</rule>
<rule order="allow,deny">
<allow>
( ${Args::SCALE} gt 1000 and user("auth") )
or ( ${Args::SCALE} gt 10000 and user("unauth") )
</allow>
</rule>
If the first rule's precondition were instead:
<precondition>
<predicate>
user("%METALOGIC:forest-inventory") and user("DSS:")
</predicate>
</precondition>
then the first rule would only be considered if the user belonged to that group and he was
authenticated by the DSS jurisdiction.
6. This rule establishes a default for all CGI programs under the cgi-bin URL space. Only users
authenticated by the jurisdiction METALOGIC will have access and CGI programs will be invoked with
the environment variable DACS_DEFAULT_CONSTRAINT set to "MODE=execute-only".
<acl_rule status="enabled" constraint="MODE=execute-only">
<services>
<service url_pattern="/cgi-bin/*"/>
</services>
<rule order="allow,deny">
<precondition>
<user_list>
<user name="METALOGIC:"/>
</user_list>
</precondition>
<allow>
</allow>
</rule>
</acl_rule>
7. This rule establishes a default behaviour that denies all access.
<acl_rule status="enabled">
<services>
<service url_pattern="/*"/>
</services>
<rule order="allow,deny">
<deny>
</deny>
</rule>
</acl_rule>
8. This rule establishes a default behaviour that grants access to the URL space under /any-user to any
authenticated user. CGI programs will be invoked with the environment variable DACS_CONSTRAINT set to
"read-only".
<acl_rule status="enabled">
<services>
<service url_pattern="/any-user/*"/>
</services>
<rule order="allow,deny">
<allow constraint="read-only">
user("auth")
</allow>
</rule>
</acl_rule>
9. This rule establishes a default for all CGI programs under the cgi-bin/gis and cgi-bin/metalogic URL
space. Access is granted to members of the groups BC:gis and NF:gis only if the value of parameter X
is greater than 10 and the value of parameter Y is greater than 17. CGI programs invoked by those
users will have the environment variable DACS_DEFAULT_CONSTRAINT set to "MODE=read-only". Members of
the group ON:gis have no constraints on the parameters and will invoke CGI programs with the
environment variable DACS_CONSTRAINT set to "read-write". Requests that do not meet either allow
element will be denied.
<acl_rule status="enabled" constraint="read-only">
<services>
<service url_pattern="/cgi-bin/gis/*"/>
<service url_pattern="/cgi-bin/metalogic/*"/>
</services>
<rule order="allow,deny">
<allow>
${Args::X} gt 10 and ${Args::Y} gt 17
and (user("%BC:gis") or user("%NF:gis")
</allow>
<allow constraint="read-write">
user("%ON:gis")
</allow>
</rule>
</acl_rule>
10. Only bob@dss.ca, authenticated by jurisdiction DSS, will have access to the service
/cgi-bin/bob-prog.cgi.
<acl_rule status="enabled">
<services>
<service url_pattern="/cgi-bin/bob-prog.cgi"/>
</services>
<rule order="allow,deny">
<allow>
user("DSS:bob@dss.ca")
</allow>
</rule>
</acl_rule>
11. Every user will be able to invoke the service /cgi-bin/metalogic/group if CGI parameter OP is
LIST_GROUPS or SHOW_GROUP. If OP is ADD_GROUP, DELETE_GROUP, or MODIFY_GROUP, only a member of the
group DSS:admin can invoke the program. String comparisons are performed without regard to case. If
OP has any other value, access will be denied.
<acl_rule status="enabled">
<services>
<service url_pattern="/cgi-bin/metalogic/group"/>
</services>
<rule order="allow,deny">
<allow>
${Args::OP} eq:i "LIST_GROUPS"
or ${Args::OP} eq:i "SHOW_GROUP"
</allow>
<allow>
(${Args::OP} eq:i "ADD_GROUP"
or ${Args::OP} eq:i "DELETE_GROUP"
or ${Args::OP} eq:i "MODIFY_GROUP")
and user("%DSS:admin")
</allow>
</rule>
</acl_rule>
SEE ALSO
dacsacl(1)[5], dacs_admin(8)[31]
AUTHOR
Distributed Systems Software (www.dss.ca[32])
COPYING
Copyright2003-2013 Distributed Systems Software. See the LICENSE[33] file that accompanies the
distribution for licensing information.
NOTES
1. RFC 1738
http://www.rfc-editor.org/rfc/rfc1738.txt
2. RFC 2396
http://www.rfc-editor.org/rfc/rfc2396.txt
3. RFC 3986
http://www.rfc-editor.org/rfc/rfc3986.txt
4. dacs_acs(8)
http://dacs.dss.ca/man/dacs_acs.8.html
5. dacsacl(1)
http://dacs.dss.ca/man/dacsacl.1.html
6. dacs_authenticate(8)
http://dacs.dss.ca/man/dacs_authenticate.8.html
7. dacs_auth_transfer(8)
http://dacs.dss.ca/man/dacs_auth_transfer.8.html
8. dacs_auth_agent(8)
http://dacs.dss.ca/man/dacs_auth_agent.8.html
9. dacsauth(1)
http://dacs.dss.ca/man/dacsauth.1.html
10. dacscheck(1)
http://dacs.dss.ca/man/dacscheck.1.html
11. ACS_CREDENTIALS_LIMIT
http://dacs.dss.ca/man/dacs.conf.5.html#ACS_CREDENTIALS_LIMIT
12. AUTH_SINGLE_COOKIE
http://dacs.dss.ca/man/dacs.conf.5.html#AUTH_SINGLE_COOKIE
13. dacs.exprs(5)
http://dacs.dss.ca/man/dacs.exprs.5.html
14. RFC 2616
http://www.rfc-editor.org/rfc/rfc2616.txt
15. mod_auth_dacs
http://dacs.dss.ca/man/mod_auth_dacs.html
16. Portable Filename Character Set
http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap03.html#tag_03_276
17. contributed resource
http://sourceforge.net/projects/dacs-contrib/
18. acl.dtd
http://dacs.dss.ca/man/../dtd-xsd/acl.dtd
19. mod_access
http://httpd.apache.org/docs-2.2/mod/mod_access.html
20. dacsrlink(1)
http://dacs.dss.ca/man/dacsrlink.1.html
21. concise user syntax
http://dacs.dss.ca/man/dacs.1.html#concise_user_syntax
22. Rlinks
http://dacs.dss.ca/man/dacs_acs.8.html#rlinks
23. rule clause processing
http://dacs.dss.ca/man/#ordering
24. user()
http://dacs.dss.ca/man/dacs.exprs.5.html#user
25. dacs_current_credentials(8)
http://dacs.dss.ca/man/dacs_current_credentials.8.html
26. PERMIT_CHAINING
http://dacs.dss.ca/man/dacs.conf.5.html#PERMIT_CHAINING
27. Action
http://httpd.apache.org/docs/2.2/mod/mod_actions.html#action
28. Options
http://httpd.apache.org/docs/2.2/mod/core.html#options
29. Authorization Caching
http://dacs.dss.ca/man/dacs_acs.8.html#authorization_caching
30. dacs.groups(5)
http://dacs.dss.ca/man/dacs.groups.5.html
31. dacs_admin(8)
http://dacs.dss.ca/man/dacs_admin.8.html
32. www.dss.ca
http://www.dss.ca
33. LICENSE
http://dacs.dss.ca/man/../misc/LICENSE
DACS 1.4.28b 04/07/2016 DACS.ACLS(5)