DACS.ACLS(5) | DACS Formats and Conventions | DACS.ACLS(5) |
dacs.acls — DACS access control rules
These files are part of the DACS suite.
When DACS receives a service request, expressed as a URL (see RFC 1738, RFC 2396, and RFC 3986), it invokes ACS (its access control service, dacs_acs(8)) 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)).
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.
The dacsacl(1) 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) must be run.
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) 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), dacs_auth_transfer(8), and dacs_auth_agent(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) or dacscheck(1) (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.
It is not currently possible to construct a single expression that tests multiple credentials. If this creates difficulties, consider using the ACS_CREDENTIALS_LIMIT or AUTH_SINGLE_COOKIE 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).
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")
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.
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.
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.
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".
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)
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
module allows its administrator to configure the maximum size
of parameter data provided by the POST
method that is made available to ACS.
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.
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".
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.
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
Although not currently enforced, an ACL file name should be composed of characters from the Portable Filename Character Set: 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
These two filename prefixes are defined at compile time. dacsacl(1) should be enhanced to notice simultaneously enabled and disabled files. FedAdmin, a contributed resource, 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.
Basically, an ACL rule compactly expresses the triple (What, Who, How).
the names of one or more services the rule applies to;
the set of users the rule applies to; and
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). 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.
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.
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.
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_authz_host 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.
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:
it can make it clear which user(s) the rule applies to;
it can improve by efficiency by avoiding having to evaluate potentially expensive expressions; and
it provides a way to have multiple rule elements, any of which might be enabled depending on the run-time context.
DACS employs expressions in access control
rules and in configuration files
(see dacs.exprs(5)).
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).
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.
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).
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))
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.
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 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:
<service url_pattern="/*"/>
<service url_pattern="/cgi-bin/*"/>
<service url_pattern="/cgi-bin/metalogic/*"/>
<service url_pattern="/cgi-bin/metalogic/metalogic_groups"/>
<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
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:
no rule clauses in this access control rule will be examined
any defaults specified in the acl_rule
element will be discarded
processing of the current ruleset is terminated
the ruleset identified by the
rule_uri
attribute will be consulted
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.
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.
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 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.
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() 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)).
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 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 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),
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.
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
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.
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
directive or when it automatically creates a directory index
(as by the Indexes
option of the
Options 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
for details.
Groups are discussed in a separately in dacs.groups(5).
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.
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.
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
.
If access is granted, default or specific attributes
associated with the matching acl_rule
,
rule
, or allow
elements will be
passed to S
.
For conciseness, some of the following examples omit the services element.
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>
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>
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.
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>
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.
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>
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>
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>
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>
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>
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>
Copyright © 2003-2018 Distributed Systems Software.
See the
LICENSE
file that accompanies the distribution
for licensing information.
DACS Version 1.4.52 | 24-Sep-2024 | DACS.ACLS(5) |
Table of Contents |
Font:
|
−− | Set | ++ |
$Id: dacs.acls.5.xml 3016 2018-08-17 18:12:46Z brachman $