DACS.CONF(5) | DACS Formats Manual | DACS.CONF(5) |
NAME¶
dacs.conf - DACS configuration files and directivesDESCRIPTION¶
These files are part of the DACS suite.Nearly all DACS services and utilities consult a configuration file when they start up. Such things as the per-jurisdiction locations of access control files and log files, authentication processing, error handling, and run-time limits are specified in the configuration file. The recommended name for this file is dacs.conf and the DACS documentation will generally refer to it by that name. Site-wide configuration, which is optional, is typically put in a file named site.conf. Both files are XML documents, and consist of various sections, clauses, and directives, not unlike the httpd.conf configuration file used by Apache. Different federations and jurisdictions running on the same host may share these files or each might have its own separate configuration file; the former is more common since it reduces duplication and helps to prevent inconsistencies.
Federations, jurisdictions, and other important concepts are discussed in dacs(1)[1].
Note
Unlike the "passive" configuration files found in most systems, the DACS configuration files are "active"; that is, configuration directives are evaluated as expressions within a run-time context that includes information related to the current request, web server, operating system, and DACS itself. By specifying the value of a directive as an expression rather than a simple string, the configuration under which a request is processed can adapt to, or depend on, the context in which it is made. Administrators do not need to use this capability, but it is available when flexibility is needed.
Note
Each configuration file is completely read and processed once, each time a DACS web service or utility is executed. Changes to the files take effect the next time the files are read; no recompilation or special action needs to be taken, and neither Apache nor any other server needs to be restarted. It is usually safe to make minor updates to the configuration files while DACS is operational, but it is better to temporarily deny all access if the web server is busy and more complicated changes are being made. Because DACS components abort if they encounter a configuration error (e.g., leading to all access to be denied, all authentication to fail, or a utility to become non-operational), temporarily introducing a configuration error will not usually cause any serious problems. Under heavy load or if complex authentication methods have been configured, however, it is prudent to stop the web server briefly while the old configuration files are replaced with the new ones.
Tip
While it may at first seem that DACS is difficult to configure, in practice the default configuration that comes with the DACS distribution is sufficient in many cases, and leaves only a few straightforward, site-dependent directives to be specified. Many administrators will never need to use the more advanced configuration features.
Tip
Locating dacs.conf and site.conf¶
The locations of dacs.conf and site.conf may be specified with the web server configuration, in an environment variable, through a command line flag, or at compile time. A single configuration file can provide directives for multiple DACS jurisdictions. For example, if a machine is hosting more than one DACS jurisdiction, they can each use the same DACS binaries.Note
Most DACS commands and web services require the dacs.conf file to exist; the exceptions are a few "standalone" programs, such as dacshttp(1)[4]. The site.conf file is not required; if a location has been configured and the file exists, however, it must be readable and by convention should contain default values appropriate for the installed release.
Command line flags common to many DACS programs are described in dacs(1)[5].
So that dacs_acs(8)[6] (which is invoked by the mod_auth_dacs[7] module) can find its configuration, the location of dacs.conf can be specified in Apache's httpd.conf file using the SetDACSAuthConf directive. It may instead, however, be specified through the DACS_CONF environment variable, on the command line, or using a build-time default. Similarly, the location of site.conf can be specified in Apache's httpd.conf file using the SetDACSAuthSiteConf directive, through the DACS_SITE_CONF environment variable, on the command line, or using a build-time default.
If the location of dacs.conf (site.conf) is not given at run-time, a compile-time value of the symbol DACS_CONF (DACS_SITE_CONF) will be used if possible. This is the usual case for programs other than dacs_acs. It is a fatal error if a DACS service can't locate dacs.conf.
Regardless of how the location of dacs.conf is specified, DACS performs string interpolation on the pathname. If interpolation fails, DACS will encounter a fatal error because it will not be able to locate its configuration file.
Path Interpolation
Path interpolation is available using a syntax and method similar to Apache's mod_vhost_alias[8] module. Interpolation is always performed to determine the locations of several resources used by DACS, such as dacs.conf and site.conf, and with DACS's LOG_FILE[9] directive, regardless of the manner in which the location is provided to DACS. It is applied whether the location of dacs.conf is specified using the -u command line flag or the Apache (mod_auth_dacs) SetDACSAuthConf directive, for instance.
The functionality can also be accessed using the pathname()[10] function.
The strings that may be interpolated into the pathname are obtained from the execution environment, in particular the URI authority information (based on Apache's SERVER_NAME and SERVER_PORT environment variables), the URI service path (described below), build-time configuration, and the applicable Jurisdiction section's distinguishing URI.
Interpolation is controlled by printf-like format specifiers, as follows:
%%
%a
%bA
%bD
%p
%N.M
0 or 1+ or -1+
1
2
-1
-2
2+
-2+
%s[N.M]
Note
In cases where the character following %s should not be interpreted as part of the format, it must be escaped (e.g., %s%2).
%u[N.M]
Note
In cases where the character following %u should be interpolated verbatim and not interpreted as part of the specifier, it must be escaped (e.g., %u%2).
%U[N.M]
Note
Other format specifiers
Other characters
For example, if SERVER_NAME is dss.example.com and SERVER_PORT is 8080, then the Apache directive:
SetDACSAuthConf dacs-acs "/usr/local/apache2/conf/dacs/%2+/dacs.conf"
will expand the path to /usr/local/apache2/conf/dacs/example.com/dacs.conf. The command line flag:
-c /usr/local/dacs/%1%.%p/dacs.conf
specifies the location of the configuration file to be /usr/local/dacs/dss.8080/dacs.conf.
The %u specifier interpolates the URI service path, or portions thereof, which is the string HTTP_HOST/REQUEST_URI (without a query component). When a DACS service is invoked as a CGI, this will be the usual case; the URI service path is undefined if either of those environment variables is unavailable, however.
File Format¶
dacs.conf is an XML document that conforms to Configuration.dtd[12].A dacs.conf file consists of an optional Default section followed by zero or more Jurisdiction sections. Either type of section consists of DACS directives or XML elements, called clauses, that contain DACS directives. There are three kinds of clauses: Auth clauses, Roles clauses, and Transfer clauses.
Just to give its flavour, here's an incomplete dacs.conf file:
<Configuration> <Default> LOG_FILE "${Conf::DACS_HOME}/logs/logfile" FEDERATION_DOMAIN "example.com" FEDERATION_NAME "ROOT" LOG_LEVEL "notice" SSL_PROG "/usr/local/dacs/bin/sslclient" </Default> <!-- Configuration of first jurisdiction --> <Jurisdiction uri="dss.example.com"> JURISDICTION_NAME "DSS" <Auth id="auth_name"> URL "https://dss.example.com/cgi-bin/dacs/local_unix_authenticate" STYLE "pass" CONTROL "sufficient" </Auth> </Jurisdiction> <!-- Configuration of second jurisdiction --> <Jurisdiction uri="dss.example.com/foo"> JURISDICTION_NAME "FOO" </Jurisdiction> <!-- Configuration of third jurisdiction --> <Jurisdiction uri="metalogic.example.com"> JURISDICTION_NAME "METALOGIC" </Jurisdiction> </Configuration>
The structure of site.conf is only slightly different. The Default section is mandatory in site.conf and no Jurisdiction sections are allowed.
Note
Because the configuration files are XML documents, characters special to XML must be properly escaped. In particular, an ampersand character must always be written as & and a < character must be written as <.
Although the XML format of the DACS configuration files is easily understood and fairly readable, and they can be modified using any text editor, there is nothing to prevent a special-purpose tool from being used.
The Default Section¶
The purpose of the Default section in dacs.conf is to establish default values for directives that tend to be shared amongst all of the Jurisdiction sections that appear in dacs.conf. The Default section is optional; if present, it must appear before any Jurisdiction section in dacs.conf.The site.conf file, if it exists, consists of only a Default section. Directives that are common to all of a site's dacs.conf files might be put in site.conf.
Any configuration directive or clause may appear in the Default section.
The Jurisdiction Section¶
Each Jurisdiction section contains configuration directives that are associated with a particular jurisdiction. These directives override those found anywhere else, as described below.Section Merging and Directive Evaluation¶
The three types of configuration sections are merged as follows. First, directives and clauses that appear in the site.conf Default section are overridden by those that appear in the dacs.conf Default section. The resulting directives and clauses are in turn overridden by those that appear in the selected Jurisdiction section. Usually, site.conf will contain the standard default directives that come with the installed release of DACS, the dacs.conf Default section will contain directives common to all of the jurisdictions defined on the host that are in the same federation, and each Jurisdiction section will contain directives specific to that jurisdiction.The exception to this merging procedure is directives in the Stack category[13]. Instead of overriding, these directives accumulate.
The order in which directives (but not clauses) appear within a section is not significant, even with respect to references to variables in the Conf namespace[14], with the exception of the EVAL directive[15].
Only after directives in the three sections are merged are their right-hand sides evaluated (again, with the exception of EVAL[15]) to determine the value of each directive. Therefore, if a directive appears in both the Default section and the Jurisdiction section, the instances in the Default section will not have their directive values evaluated; they will simply be discarded (with the exception of the Stack directive category).
The undef() directive
As a special case, if a directive is given the special value returned by undef()[16], the instance of the directive is deleted. This provides a way to conditionally include or exclude a directive depending on the execution environment. For example, this directive increases the debugging level for DACS web services but not for commands:
LOG_LEVEL ${Env::REMOTE_ADDR:e} ? "TRACE" : undef()
Note
Because of the way configuration files are currently processed, the check for directive category satisfaction happens before right-hand side evaluation. This means that in any particular section only one instance of a given directive in the Required1 category may appear (see Directive Categories[13]), even if just one would be included after the evaluation step.
Fatal errors
It is a fatal error to reference an undefined variable unless the e or ? modifier flag[17] is used in the variable reference. Recursive variable references are detected and result in a fatal error. If a directive ends up not being evaluated, it does not matter whether its right-hand side is invalid (or would be if evaluated).
Note
When a fatal error occurs during configuration processing, a DACS web service tries to terminate gracefully. But because directives (including error handling directives) may not have been processed correctly, or even at all, there is no guarantee that an error handler (such as one defined by the ACS_ERROR_HANDLER[18] directive) will be invoked or a requested output format will be honoured during abnormal termination. A non-zero exit process status is always returned.
An example
Consider the following configuration excerpts:
# In site.conf: LOG_LEVEL "debug" # In the dacs.conf Default section: LOG_LEVEL "notice" # In the dacs.conf Jurisdiction section: LOG_LEVEL "trace"
After configuration processing, the directive LOG_LEVEL will be set to "trace", and the variable ${Conf::LOG_LEVEL} will have that value during configuration processing.
Here are some excerpts from a dacs.conf file:
# In the Default section: FEDERATION_DOMAIN "example.com" FEDERATION_NAME "EXAMPLE" # In the Jurisdiction section: JURISDICTION_NAME "DEMO" VFS "[abc]dacs-fs:${Conf::FEDERATIONS_ROOT}/${Conf::FEDERATION_DOMAIN}\ /${Conf::JURISDICTION_NAME}/abc"
When computing the VFS directive's value in the example above, the values of the FEDERATIONS_ROOT variable (determined at build-time) and the FEDERATION_DOMAIN and JURISDICTION_NAME configuration directives are interpolated. Directives in site.conf may reference configuration variables that are defined in dacs.conf.
Given the configuration:
# In site.conf: VFS "[dtds]dacs-fs:/usr/local/dacs/www/dtd-xsd" # In the dacs.conf Default section: VFS "[dtds]dacs-fs:/usr/local/dacs/dtd-xsd" # In the dacs.conf Jurisdiction section: VFS "[dtds]dacs-fs:/export/dacs/dtd-xsd" VFS "[xxx]dacs-fs:/export/dacs/xxx"
All four VFS directives will be in effect, but they will be ordered such that the first one in the Jurisdiction section is at the top of the stack, the second one in that section is next on the stack, the directive in the dacs.conf Default section follows, and the one from site.conf is last.
Jurisdiction Section Selection¶
DACS web services and commands do not have any federation or jurisdiction information compiled into them, so that a single set of DACS binaries can be shared by many jurisdictions (e.g., by multiple real or virtual web servers on the same host, or using NFS or some other file sharing mechanism). But it means that (most) web services and commands need a run-time mechanism to determine "who they are" - which federation and jurisdiction are they acting on behalf of? For web services, this usually depends on the server name, hostname, port, scheme, URI path, some other context associated with the request, or a combination of these things. But it is sometimes most convenient to specify a jurisdiction name and have DACS work out what the request URIs to that jurisdiction look like, if it needs to.Most DACS web services and commands need to obtain run-time configuration information for the jurisdiction they represent. Because dacs.conf may specify the configuration of more than one jurisdiction, how do they know which Jurisdiction section they should use? In cases where DACS does not know the jurisdiction name, it searches for the correct Jurisdiction section and then determines the name of the jurisdiction; in cases where it is given the jurisdiction name, it searches Jurisdiction sections to find one with a directive that identifies the jurisdiction that it was given.
The applicable Jurisdiction section to use for a particular web service request or command can be determined in a variety of ways, using:
Command line flags are described in dacs(1)[5], as is the DEFAULT_JURISDICTION environment variable.
These methods will be described individually shortly.
Tip
Because selection of the applicable Jurisdiction section is quite flexible, it may seem complicated. In practice, however, it is often rather simple, and particularly so if only one jurisdiction is being configured. It may be sufficient to read this section and skip the detail presented in the remainder of the discussion on how the Jurisdiction section is selected.
If there is only one jurisdiction, its uri attribute value can simply be the domain name associated with the jurisdiction. Any of the command line flags could then be used (or none). If the jurisdiction's domain name is foo.example.com, for instance, the Jurisdiction section in dacs.conf might look like:
<Configuration> <Jurisdiction uri="foo.example.com"> JURISDICTION_NAME "FOO" FEDERATION_DOMAIN "example.com" # And so on... </Jurisdiction> </Configuration>
In the Apache configuration file (httpd.conf), one might specify:
AddDACSAuth dacs-acs /usr/local/dacs/bin/dacs_acs "-u foo.example.com"
(which tells DACS that all web service requests from the web server or virtual host to which this directive applies should be associated with the domain foo.example.com for configuration purposes), or
AddDACSAuth dacs-acs /usr/local/dacs/bin/dacs_acs "-us"
(telling DACS that all web service requests from the web server or virtual host to which this directive applies should be associated with the only jurisdiction described in the configuration file, whatever that jurisdiction may be), or
AddDACSAuth dacs-acs /usr/local/dacs/bin/dacs_acs "-uj FOO"
(telling DACS that all web service requests from the web server or virtual host to which this directive applies should be associated with jurisdiction FOO), or simply
AddDACSAuth dacs-acs /usr/local/dacs/bin/dacs_acs
In the last case, DACS will match the request URI (which presumably looks like https://foo.example.com/...) against foo.example.com.
Multiple jurisdictions that are identified by distinct domain names are also easily configured once a DACS administrator decides how he would like request URIs to identify them. This is usually done much like this:
<Configuration> <Jurisdiction uri="foo.example.com"> JURISDICTION_NAME "FOO" FEDERATION_DOMAIN "example.com" # And so on... </Jurisdiction> <Jurisdiction uri="baz.example.com"> JURISDICTION_NAME "BAZ" FEDERATION_DOMAIN "example.com" # And so on... </Jurisdiction> </Configuration>
And so that the domain name in the request URI is matched against the jurisdiction's effective URI, one would use:
AddDACSAuth dacs-acs /usr/local/dacs/bin/dacs_acs
Multiple jurisdictions that share a domain name but are distinguished by a portion of the request URI pathname component, are often configured something like:
<Configuration> <Jurisdiction uri="example.com/foo"> JURISDICTION_NAME "FOO" FEDERATION_DOMAIN "example.com" # And so on... </Jurisdiction> <Jurisdiction uri="example.com/baz"> JURISDICTION_NAME "BAZ" FEDERATION_DOMAIN "example.com" # And so on... </Jurisdiction> </Configuration>
And again using:
AddDACSAuth dacs-acs /usr/local/dacs/bin/dacs_acs
With this style of configuration, a request for https://example.com/foo/cgi-bin/dacs/blah would be directed to the configuration for the FOO jurisdiction.
Similarly, port numbers can also be used for Jurisdiction section selection:
<Configuration> <Jurisdiction uri="example.com:443"> JURISDICTION_NAME "FOO" FEDERATION_DOMAIN "example.com" # And so on... </Jurisdiction> <Jurisdiction uri="example.com:8443"> JURISDICTION_NAME "BAZ" FEDERATION_DOMAIN "example.com" # And so on... </Jurisdiction> </Configuration>
Lastly, a hostname wildcard syntax can be useful:
<Configuration> <Jurisdiction uri="*.foo.example.com"> JURISDICTION_NAME "FOO" FEDERATION_DOMAIN "example.com" # And so on... </Jurisdiction> <Jurisdiction uri="*.baz.example.com"> JURISDICTION_NAME "BAZ" FEDERATION_DOMAIN "example.com" # And so on... </Jurisdiction> </Configuration>
Important
No check is made to ensure that the jurisdiction sections are unique. This is sometimes a useful feature but can also cause unexpected behaviour. It is probably best for all but the most advanced administrators to make sure that the same JURISDICTION_NAME directive doesn't appear in multiple Jurisdiction sections and that each section has a different effective jurisdictional URI.
If your particular requirement has been covered, it is probably safe to skip the detail that follows.
The Effective Jurisdictional URI
A Jurisdiction element must have either a uri attribute or a uri_expr attribute, but not both. If the latter is given, it specifies an expression[20] that is evaluated at configuration processing time. The effective jurisdictional URI (or the jurisdiction's effective URI) is either the value of the uri attribute or the value obtained by evaluating the uri_expr attribute. The effective jurisdictional URI can be matched against a request's URI or the -u flag's config-uri to find the applicable Jurisdiction section.
The standard set of configuration variables[21] in the Conf and Env namespace[14] (but no others) are accessible during evaluation of uri_expr. Consider this partial configuration:
<Jurisdiction uri_expr="${Env::SERVER_NAME}">
Here, the effective jurisdictional URI is the value of the SERVER_NAME environment variable.
Note
<Jurisdiction uri_expr="regmatch(${Env::SERVER_NAME}, '(foo.example.com)|(baz.example.com)')">
The effective jurisdictional URI has the following syntax:
Jurisdiction Selection by URI
Whether the Jurisdiction section is selected based on the -u flag's explicit config-uri or the request URI provided to DACS through environment variables, the effective jurisdictional URIs are matched against the provided URI.
An effective jurisdictional URI has the following semantics for matching against the provided URI:
Note
The matching algorithm does not consider domain names that map to the same IP address (i.e., aliases) to be equivalent.
The domain-spec can be an IP address, but in this case the provided URI must also use an IP address for the two to match. That is, no mapping between IP addresses and domain names is performed.
The matching algorithm first rejects any Jurisdiction section having an effective jurisdictional URI that does not satisfy the scheme-spec or the domain-spec. It looks for the section that contains a matching port-spec and that has the longest matching path-spec; the first such section will be selected. If no such section is found, however, it looks for the section that does not contain a port-spec and that has the longest matching path-spec; the first such section will be selected. It is a fatal error if no section can be selected.
Tip
While configuration of the uri attribute may appear to be complex, its value will typically be a simple hostname, or a simple hostname followed by a jurisdiction-distinguishing initial path element, as in the example above. The flexible syntax allows jurisdictions to be associated with requests based on port numbers, use of SSL/TLS, etc. and lets dissimilar requests map to the same jurisdiction.
For example, given the example configuration[22] above, if the request URL is:
then the second Jurisdiction section will be used.
If the request URL is:
then the first Jurisdiction section will be used.
If a DACS utility is invoked with the command line flag -u metalogic.example.com, the third Jurisdiction section will be used.
Jurisdiction Selection by Jurisdiction Name
The applicable Jurisdiction section can be selected by providing the jurisdiction's name. The -uj flag's jurisdiction-name argument is compared against the unevaluated value of each section's JURISDICTION_NAME directive until the first exact string match is found; the section containing the directive will be selected.
Note
Because the unevaluated value of the directive is used, if the value of a JURISDICTION_NAME is not a simple string, this option will not work unless jurisdiction-name is that expression, not its value. Appropriate quotes are implied around jurisdiction-name, so they should be omitted on the command line.
For example, given the (partial) configuration file entry:
<Jurisdiction uri="demo.example.com"> JURISDICTION_NAME "DEMO" ... </Jurisdiction>
the command line argument "-uj DEMO" would select that jurisdiction section. If instead JURISDICTION_NAME were an expression that evaluated to the string DEMO, the argument would not select that jurisdiction section.
Jurisdiction Selection by Default
If dacs.conf contains a single Jurisdiction section, the -us flag can be used to select it without regard to the jurisdiction's name or effective jurisdictional URI. This can be particularly useful during testing.
Should there be more than one Jurisdiction section when this flag is used, a fatal error will occur.
The Distinguishing URI
Regardless of how the Jurisdiction section is selected, that section's effective jurisdictional URI is matched against the -u flag's config-uri, if given, or the request URI according to the method described for Jurisdiction Selection by URI[23]. The resulting string is called the distinguishing URI. This string is another way of identifying the selected Jurisdiction section and can be used for string interpolation[24]. It is also related to the shared attribute used in access control rules[25].
For example, if the request URI is http://foo.example.com/a/b/c and the matching effective jurisdictional URI is *.example.com/a/b, then the distinguishing URI is foo.example.com/a/b.
Directives¶
Each directive consists of a directive name, followed by whitespace (spaces and/or tabs), followed by its value. Directive names are case-sensitive and comprised of printable characters, except the space character, and are upper case.A directive value is an expression or sequence of expressions (dacs.exprs(5)[20]) that is evaluated at run time during configuration processing. Here are some directives that are equivalent (on a Saturday):
AUTH_FAIL_DELAY_SECS 2 AUTH_FAIL_DELAY_SECS "2" AUTH_FAIL_DELAY_SECS 1 + 1 AUTH_FAIL_DELAY_SECS strftime("%a") eq:i "Sat" ? 2 : 17
Blank lines, leading white space, and lines whose first non-white space character is a # character (i.e., comments) are ignored.
Any directive line may be split over physical lines by escaping the newline character, for example:
ACS_ERROR_HANDLER "902 'Access denied, \ user not authenticated'"
Processing an unrecognized directive name causes a fatal error, as does an error encountered during expression evaluation.
Evaluated Directives
Some directive names end with a * character. By convention, this means that the directive's value will be evaluated a second time, in the context of a particular module or service request, but only if the directive value is actually needed. This allows a configuration directive to reference a variable that cannot be instantiated until normal configuration file processing has been performed, for instance. The values of these directives usually appear within single quotes so that they initially evaluate to the string between the quotes.
Consider this INIT*[26] directive, which might appear within an Auth clause[27]:
INIT* '${Auth::CURRENT_USERNAME} = "goa\\" . ${Auth::CURRENT_USERNAME}'
Because the directive's value appears within single quotes, the quoted expression is not evaluated during the first scan of the directive (or more accurately, it evaluates to an unquoted expression); this is as it should be because the value of the referenced variable is not known at that time, nor has it been determined whether the directive will even be needed. Later, if the Auth clause containing this directive is used, the variable's value is presumably known and the formerly quoted expression is evaluated, yielding a final value for the directive.
Directive Categories
After section merging[28] is performed, some directives must be specified while others are optional. Some may appear at most once and others may be repeated. The following labels are used to categorize directives:
Required1:
Required1-C:
Required:
Optional1:
Optional:
Stack:
Note
A directive marked Deprecated will be removed in a future version and should not be used.
Some directives have more complicated constraints on their usage; they might be allowed only in certain contexts or are required only in certain situations (e.g., directives associated with proxied operation are only required if that mode of operation is being used).
Required directives must be present and assigned a valid value, although the validity of a value is only checked if the directive is actually used. It is okay to define directives that are not used; for example, directives related to InfoCards may appear in a configuration file even if InfoCard support is not enabled at the time DACS is built. Some configuration directives may appear multiple times, others only once. The order in which configuration directives appear within a section is not usually significant, although it may be in cases where the directive is repeated (e.g., ACS_ERROR_HANDLER) and for clauses (e.g., the Auth clause).
Note
Directives that expect to be assigned a value of yes, no, on, or off recognize these keywords case-insensitively.
General Directives
The following general directives are provided. If present, they must appear within any Default section or Jurisdiction section, but outside of any clauses.
Directive Index:
ACCEPT_ALIEN_CREDENTIALS (Optional1)
Security
In federations where dacs_auth_transfer(8)[29] is used, jurisdictions will likely enable this capability.
ACS_ACCESS_TOKEN_ENABLE (Optional1)
ACS_ACCESS_TOKEN_LIFETIME_LIMIT (Required1-C)
ACS_ACCESS_TOKEN_LIFETIME_SECS (Required1-C)
ACS_AUTHENTICATED_ONLY (Optional1)
Note
Since this restriction also applies to DACS services, if this mode is enabled an unauthenticated user will not be able to access DACS services by which he might authenticate himself. Users must therefore have authenticated before this directive is enabled, authenticate using an off-line method (such as dacscookie(1)[31] or dacsauth(1)[32]), or authenticate at some other jurisdiction.
ACS_CREDENTIALS_LIMIT (Optional1)
Probably the most common application of this directive is to limit each request to being associated with at most one identity. The standard site configuration sets ACS_CREDENTIALS_LIMIT to one. This eliminates confusion about which identity invoked a web service (i.e., which identity REMOTE_USER should be set to, for instance) and ambiguity regarding the semantics of rules, and in some cases may simplify access control rules and log file audits.
A user denied access at a jurisdiction due to this directive will be denied access to dacs_signout(8)[33] at the jurisdiction. To regain access to the jurisdiction, the user will either need to signout from a different jurisdiction or delete one or more sets of credentials (cookies) from his browser, either using the browser's cookie manager or by terminating the browser session.
Note
It is possible for a user that is not denied access at a jurisdiction due to this directive to successfully authenticate, after which he will have "too many" credentials and subsequently be denied access. Similarly, a DACS administrator may reduce the limit at any time, potentially causing access to be denied to users holding a number of credentials in excess of the limit.
Security
This directive only limits the number of credentials associated with a single request. It does not prevent the same individual from sending different requests, from the same browser or different browsers, each associated with a different identity. Also, it does not limit the number of concurrent logins of the same identity (such as by different individuals sharing the same account).
DACS does not limit a user's number of concurrent logins or the number of concurrent logins of the same identity because of the inherent drawbacks of a general implementation of such a feature. In simple cases, however, an administrator may be able to add a custom solution to DACS.
ACS_EMIT_APPROVAL (Optional1)
ACS_ERROR_HANDLER (Stack)
In some situations following denial of a request, however, it is desirable to initiate an action that depends on the reason for denial. For example, if access is denied because the user is not authenticated, the DACS administrator might want users to be redirected to a login page; if access is denied because an access control rule denies access although the user is authenticated, the administrator might want users to be redirected to a page that displays a custom error message. It is sometimes useful for the action to depend on the resource being requested.
The ACS_ERROR_HANDLER directive defines (or overrides) Apache's behaviour with respect to an ErrorDocument directive for 403 errors if DACS denies a service request. The syntax and meaning of this directive are similar to that of Apache's ErrorDocument directive. Please refer to the Apache documentation for a description of the ErrorDocument directive[35].
Also refer to the description of the redirect()[36] function.
The syntax of the directive is:
[url_pattern] error-code [handler-type] [error-action]
The optional url_pattern is a URI path component that is matched against the request for which access was denied. It must begin with a '/'. It is like the url_pattern used in access control rules[37] in that it can require an exact match or end in "/*"; no query argument component is allowed. If it is absent, the url_pattern defaults to "/*", which matches any path.
The error-code is either a numeric error code, an equivalent case-insensitive error-name, or the special symbol "*", which means the directive applies to any DACS error code for which there is no explicit directive.
The following error-name and error-code values are defined:
NO_RULE (900)
Access denied, no applicable rule
BY_RULE (901)
Access denied, forbidden by rule
NO_AUTH (902)
Access denied, user not authenticated
REVOKED (903)
Access denied, user access revoked
BY_REDIRECT (904)
Access denied, redirect
ACK_NEEDED (905)
Access denied, acknowledgement needed
LOW_AUTH (906)
Access denied, low authentication level
BY_SIMPLE_REDIRECT (907)
Access denied, simple redirect
CREDENTIALS_LIMIT (908)
Access denied, too many credentials were submitted
INACTIVITY (909)
Access denied, inactivity timeout
ADMIN_REQUIRED (910)
Access denied, administrator credentials required
UNKNOWN (998)
Access denied, reason unknown
DEFAULT (*)
Control symbol
No blanks may precede the code, any number of blanks may follow it. The descriptive-text consists only of printable characters (e.g., no tabs or newlines) and may not contain a colon. The descriptive-text is subject to change, but the meaning of the code number is fixed. When DACS returns a numeric error code, a program only needs to examine the three digit code to determine why access was denied. Optionally, the standard text may be followed by a single space, a colon, at least one space, and a more detailed error message.
If a handler-type keyword appears, it selects the action the handler should take and disables the heuristics that would otherwise be used to decide the type based on the syntax of the error-action. The reason and default keywords are the only handler-type keyword that are not followed by an error-action.
The following handler-type keywords and error-action arguments are recognized:
DACS will cause Apache to display the DACS error code that identifies the reason for denying access followed by the corresponding textual message. Apache might display messages like the following:
900 Access denied, no applicable access control rule 998 Access denied, internal error: Cookie parse error
This form instructs DACS not to alter Apache's behaviour (as if there was no ACS_ERROR_HANDLER specified at all).
This form will cause Apache to redirect the client to URL using the GET method. If the url keyword is absent, URL must begin with the four characters "http". An invalid URL may be rejected by Apache and treated as a message. The URL may contain a properly escaped query string; DACS will append the following parameters, in the order given, to URL (unless the error name is BY_SIMPLE_REDIRECT, in which case none of these parameters is passed):
Mozilla/3.01 (X11; U; Linux 2.4.2 i386)
This form is similar to the absolute URL form except that redirection is to a local URL-path. The error-action must begin with a slash. The URL may contain a properly escaped query string; DACS will append additional parameters as in the absolute URL form.
This form causes Apache to emit the given string as the error document. If the message keyword is absent, the string must be surrounded by double quote characters (the quotes do not appear in the final output message).
Note
Apache always sets the Content-Type for this message to text/html. Although reported quite some time ago, Bug 3641[40] is still open. There may be a bug in Apache 2.X that prevents the initial double quote in the message from being stripped; see Bug 42430[41].
The expr keyword, which cannot be omitted, indicates that the error-action is an expression. The expression is evaluated and its value (a string) is used as the Apache error response. If an error occurs during evaluation, the Apache ErrorDocument or default behaviour will be used.
This directive may appear multiple times. Because these directives are stacked, during handler processing directives are examined "backwards", starting from the last one that appears in the relevant jurisdiction section through to the first one that appears in the default section of dacs.conf and backwards through site.conf. The first directive having a url_pattern and error-code that match the error condition exactly is used. Otherwise, if no such exact match if found, the first directive encountered having the closest url_pattern match and exact error-code match is used; failing that, the first directive with the closest url_pattern match and default ("*") error-code match is used.
Consider these example directives:
ACS_ERROR_HANDLER "* reason" ACS_ERROR_HANDLER '903 "Your access has been revoked"' ACS_ERROR_HANDLER "/foo/* * /cgi-bin/dacs/foohandler" ACS_ERROR_HANDLER "/foo/foo.html NO_AUTH /cgi-bin/foo-login.cgi"
A request for /foo/foo.html that is denied because the user is not authenticated will cause a redirect to /cgi-bin/foo-login.cgi. If the request is denied for a different reason, the third directive will be used, causing a redirect to /cgi-bin/dacs/foohandler. A request for something not located under /foo that is denied because access is revoked will cause the message specified in the second directive to be displayed to the user, while any other type of error will cause an appropriate explanatory message to be displayed.
Here is an example of the expr handler form:
ACS_ERROR_HANDLER "* expr '\"<em>Today is</em> \" . strftime(\"%D\")'"
If triggered, this directive will emit a message similar to the following as Apache's custom error response:
<em>Today is</em> 05/16/07
As with all such messages, Apache forces the Content-Type to be text/html.
These two directives are equivalent:
ACS_ERROR_HANDLER "* message 'Hello world.'" ACS_ERROR_HANDLER "* \"Hello world.\""
The error response returned by Apache will be:
Hello world.
Any invalid directive will result in Apache following its configured behaviour. A directive with a syntactically valid but undefined error-code is ignored, however.
In the case where the service request was issued by Internet Explorer, if the length of the error response by the server isn't greater than some magic value and IE's "Show friendly HTTP error messages" is enabled, which it is by default, then IE will ignore the custom message. When the "message" and "reason" handler types are used, DACS adds some padding to thwart IE's "cleverness". For other handler types, the administrator is responsible for working around this problem.
Note
Care must be taken to avoid improper operation (such as a potentially infinite regress) if a CGI program invoked to handle an error is itself protected by DACS. One example is the situation where a user's access has been revoked and is therefore unable to access any DACS-protected resource. If an error occurs while DACS is processing a request for a handler, DACS will fall back to Apache's default behaviour, ignoring any normally applicable ACS_ERROR_HANDLER directives.
ACS_FAIL (Optional1)
ACS_INACTIVITY_LIMIT_SECS (Optional1)
There are two cases. If an activity tracking cookie is not sent with the current request (see ACS_TRACK_ACTIVITY[43]), the user is deemed to be inactive if the newest credentials are older than ACS_INACTIVITY_LIMIT_SECS seconds. If an activity tracking cookie is received, the user is deemed to be inactive if the date/time that it asserts is older than ACS_INACTIVITY_LIMIT_SECS seconds. If inactivity is detected by dacs_acs(8)[6], access is denied and an INACTIVITY error (909) is raised; see ACS_ERROR_HANDLER[18]. At present, the only way for a user to continue after an inactivity error is to explicitly delete DACS cookies or implicitly delete them by restarting the browser. A non-DACS-wrapped web page or CGI program might be invoked as an error handler to assist.
Different jurisdictions may independently configure different inactivity thresholds, disable inactivity detection, or disable activity tracking - the degree to which this feature improves security or is annoying to users depends on thoughtful cooperation amongst jurisdictions and adequate clock synchronization.
ACS_POST_BUFFER_LIMIT (Optional1)
ACS_POST_EXCEPTION_MODE (Optional1)
abort
default
discard
proceed
query
ACS_PRE_AUTH (Optional)
As a simple example, the following directive checks if the request includes a USERNAME argument, and if so, just uses it:
ACS_PRE_AUTH '${Args::USERNAME:e} ? ${Args::USERNAME} : ""'
Note the single quotes around the expression so that it is evaluated at access control time instead of configuration processing time.
The ACS_PRE_AUTH directives are processed if a request is received that does not include valid credentials and if not disabled by ACS_AUTHENTICATED_ONLY[49]. If more than one ACS_PRE_AUTH directive is given, they are evaluated in the order in which they appear until one returns a valid username. If that expression sets the variable ${Auth::ROLES} to a valid role string, it will be included in the credentials (see dacs_authenticate(8)[50]). Evaluation errors are ignored. If no expression returns a valid username, access control processing continues.
These directives are processed before any HTTP_AUTH directives; if a ACS_PRE_AUTH directive is successful, the user will effectively be authenticated and so no HTTP_AUTH directives will be processed.
If the request includes a -rname flag with the DACS_ACS[51] argument, its value is ${Args::RNAME}.
Unlike when authentication is done through dacs_authenticate(8)[52], credentials are not returned to the client. This means that no DACS session state exists outside of dacs_acs and therefore some DACS web services may be unavailable or may not operate in the same way they would if credentials were provided by the client. This mechanism may also be less efficient than one that returns credentials because authentication will be performed each and every time the client makes a request that triggers it.
ACS_SUCCESS (Optional)
Also see the on_success()[53] function.
Note
While it is typically true that if DACS grants a request, the web server will go on to process the request (and eventually return a web page to the user agent, execute a program, etc.), it is not necessarily so. For example, access may still be denied by the web server for other reasons, or an error can occur during subsequent processing. This may be relevant in situations where ACS_SUCCESS is used to decrement a counter[54], for instance, because it is possible that the user may not actually see a successful result, in which case the counter value should not have been changed and so corrective action would be required.
ACS_TRACK_ACTIVITY (Optional1)
If the directive's value is "yes", dacs_acs(8)[6] emits a federation-wide HTTP cookie that notes the jurisdiction and date/time at which each DACS-wrapped service request is processed. The cookie is emitted regardless of whether access was granted, although some error conditions may prevent a cookie from being sent. No cookie is set for an effectively unauthenticated request.
The name of the activity tracking cookie has the following format:
DACS:federation-name::::ACTIVITY
where federation-name is the official name assigned to the federation for which the cookie is valid (FEDERATION_NAME[57]). Activity tracking may be enabled without enabling inactivity detection (via ACS_INACTIVITY_LIMIT_SECS[56]). This feature depends on an appropriate level of clock synchronization at all participating jurisdictions.
ADMIN_IDENTITY (Optional)
Some DACS services call an internal version of this function to ensure certain operations are limited to a DACS administrator.
Security
Consider requiring more secure authentication for administrator identities, such as using a two-factor authentication method or combining two different authentication methods.
ALLOW_HTTP_COOKIE (Optional1)
AUTH_AGENT_ALLOW_ADMIN_IDENTITY (Optional1)
AUTH_CREDENTIALS_ADMIN_LIFETIME_SECS (Optional1)
AUTH_CREDENTIALS_DEFAULT_LIFETIME_SECS (Required1)
Security
The lifetime should be chosen such that it strikes a balance between security and user convenience that is appropriate for the jurisdiction and federation.
AUTH_ERROR_HANDLER (Stack)
Note
This feature is activated only if dacs_authenticate is passed an ENABLE_AUTH_HANDLERS parameter that has a value of 1.
800 Authentication failed, invalid authenticating information 801 Authentication failed, invalid argument 802 Authentication failed, internal error 899 Authentication failed, reason unknown
When this type of response is returned, a program needs to only examine the three digit code to determine why access was denied. No blanks may precede the code, any number of blanks may follow it. The descriptive-text consists only of printable characters (e.g., no tabs or newlines) and may not contain a colon. The descriptive-text is subject to change, but the meaning of the code number is fixed. Optionally, the standard text may be followed by a single space, a colon, at least one space, and a more detailed error message.
The dacs_authenticate service recognizes a FORMAT argument that is used to select between an XML-aware user agent (FORMAT=XML) and an HTML capable user agent (FORMAT is not specified or is not XML). In the case of an XML result, dacs_auth_reply.dtd[60] is used. The behaviour of this directive with respect to FORMAT is described below on a case-by-case basis.
The following directives are supported:
DACS will return an HTML (or XML, if FORMAT=XML) document that describes why authentication failed, such as the following:
800 Authentication failed, invalid authenticating information
This is the default behaviour.
This form causes DACS to redirect the client to the specified URL, which may be a relative or absolute URL. If the keyword url is absent, URL must begin with the four characters http. The GET method will be used. The URL may contain a properly escaped query string; DACS will append the following parameters, in the order given, to the URL:
The values of these parameters are URL encoded.
This form causes the contents of the file named by full-pathname to be returned without regard to the presence of a FORMAT argument.
Note
The file must include any header lines it requires, such as a Content-Type line, a header-terminating blank line, and then the document content. Note also that the "full-pathname" usage differs from the "local-URL" usage of the ACS_ERROR_HANDLER directive, though both elements begin with a slash character; the former specifies the absolute pathname of a file, while the latter specifies a URL local to the receiving web server.
This form causes the given message, surrounded by escaped double quote characters, to be returned as HTML (or XML if FORMAT=XML).
The optional keywords are treated case-insensitively.
The AUTH-error-code is either a defined authentication error code (listed above) or the special symbol "*", which means the directive applies to any authentication error code for which there is no explicit directive.
This directive may appear multiple times, although multiple directives for the same AUTH-error-code are not allowed. Any invalid directive will generally be treated as a fatal error. A directive with a syntactically valid but undefined AUTH-error-code is ignored, however.
AUTH_FAIL (Optional1)
AUTH_FAIL_DELAY_SECS (Optional1)
AUTH_SINGLE_COOKIE (Optional1)
This directive also controls cookie names associated with credentials generated by dacscookie(1)[31], dacs_auth_agent(8)[63], and dacs_auth_transfer(8)[29]. Also see ACS_CREDENTIALS_LIMIT[64].
By setting AUTH_SINGLE_COOKIE to "jurisdiction" (case insensitive), the username component of an authentication cookie issued by the jurisdiction is suppressed. This means that every authentication cookie it creates will have the same name. By setting it to "federation" (case insensitive), the jurisdiction and username components of an authentication cookie issued by the jurisdiction are suppressed. This means that every authentication cookie that it creates will have the same name, but also that any two jurisdictions that use this configuration will create cookies with the same name. Any other value results in the default behaviour, which is to include both the jurisdiction name and the username in the names of authentication cookies. The directive has no effect on the name of the identity encapsulated within an HTTP cookie.
If an authentication cookie is received that was created by the jurisdiction and has a cookie name with a component that it has been configured to suppress, the cookie is ignored. A cookie issued by a different jurisdiction with a suppressed cookie name component is acceptable regardless of how this directive is configured at this jurisdiction. DACS will reject all credentials if a request includes more than one cookie with the same cookie name.
In typical use, each jurisdiction that performs authentication will configure this directive identically. To limit each user to associating a single identity with their request, simply set AUTH_SINGLE_COOKIE to "federation" at each jurisdiction in the federation.
Security
This directive indirectly limits the number of credentials that can be associated with a single request. It does not prevent the same individual from sending different requests, from the same browser or different browsers, each associated with a different identity. Also, it does not limit the number of concurrent logins of the same identity (such as by different individuals sharing the same account).
Changing this directive's value may render existing credentials invalid at this jurisdiction. For example, after changing the directive it is possible for a user to obtain two authentication cookies with different names for the same identity. DACS does not allow a request to include multiple credentials for the same identity.
AUTH_SUCCESS (Optional)
Also see the on_success()[53] function.
As an example, the following directive will run a web service after every successful login:
AUTH_SUCCESS 'https://internal.example.com/cgi-bin/userlogin?USERNAME=${Auth::IDENTITY}'
AUTH_SUCCESS_HANDLER (Optional1)
Note
This feature is enabled only if dacs_authenticate is passed an ENABLE_AUTH_HANDLERS parameter that has a value of 1.
The following syntaxes are supported:
This form causes DACS to redirect the client to URL, which may be a relative or absolute URL. If the keyword url is absent, URL must begin with the four characters http. The GET method will be used. The URL may contain a properly escaped query string; DACS will append the following parameters, in the order given, to the URL:
DACS_VERSION
DACS_FEDERATION
DACS_JURISDICTION
DACS_USERNAME
FORMAT
The values of these parameters are URL encoded.
This form causes the contents of the file named by full-pathname to be returned without regard to the presence of a FORMAT argument. The file must include any header lines it requires, such as a Content-Type line, a header-terminating blank line, and then the document content.
Note
The "full-pathname" usage differs from the "local-URL" usage of the ACS_ERROR_HANDLER directive, though both elements begin with a slash character; the former specifies the absolute pathname of a file, while the latter specifies a URL local to the receiving web server. To specify a relative URL, use the url keyword.
This form causes the given message, surrounded by escaped double quote characters, to be returned as HTML (or XML if FORMAT=XML).
This form causes the user's credentials to be displayed, either as an HTML or XML (if FORMAT=XML) document. This is the default behaviour.
The optional keywords are treated case-insensitively.
AUTH_TRANSFER_EXPORT (Optional)
AUTH_TRANSFER_TOKEN_LIFETIME_SECS (Optional1)
COMPAT_MODE (Optional1)
Important
This directive is not intended to provide complete interoperability among DACS releases and in fact it does not in certain situations. Old releases of DACS may contain security-related bugs, or may rely on third-party software that contains security-related bugs. DACS installations are urged to upgrade rather than to depend on the limited backward compatibility supplied by this directive. There is no guarantee that any particular level of backward compatibility will be carried forward in subsequent releases of DACS.
COOKIE_HTTPONLY (Optional1)
Security
Methods of defeating this attribute are known[67], so administrators may need to take additional precautions against XSS attacks.
COOKIE_NAME_TERMINATORS (Optional1)
Any other directive value is rejected. It is not possible to escape a comma in the directive value. No terminator may be the null string. This directive is honoured in all contexts where DACS produces or parses an HTTP cookie name, such as by dacscookie(1)[31]. See COOKIE_SYNTAX[69] for additional information.
Important
No other validity checks are performed, so it is possible to configure a cookie name syntax that is non-conformant, unacceptable to DACS, or unacceptable to some clients. Changing the cookie name format will cause previously issued cookies to not be recognized by DACS until the format is switched back. Since the value of the directive can be determined at run-time, however, considerable flexibility is possible. Jurisdictions will not recognize each other's HTTP cookies if they produce cookies with differently formatted names. Changing the cookie name format does not affect the similar syntax used to specify jurisdictions, users, and so on.
COOKIE_NAME_TERMINATORS "~"
This will result in cookie names that look like:
DACS~federation-name~~[jurisdiction-name]~[username][~special]
Here is another example:
COOKIE_NAME_TERMINATORS "~,::,~,:"
This will result in cookie names that look like:
DACS~federation-name::[jurisdiction-name]~[username][:special]
COOKIE_NO_DOMAIN (Optional1)
This directive is sometimes useful when DACS is deployed in an environment where fully qualified domain names are not used. In this case, FEDERATION_DOMAIN must still be configured, although it will not be used in conjunction with the domain of cookies.
The default is "no".
COOKIE_PATH (Optional1)
Security
The default value is "/", which means that the cookie will be sent by a user agent along with every request sent to the jurisdiction's host. The value should be set to the most specific URL path under which all DACS-wrapped services appear so that DACS credentials will only be sent with requests to those URLs. It is critical to do this if your server runs arbitrary user CGI programs because a malicious user might be able to cause a DACS-authenticated user to visit a service that is not DACS-wrapped and capture cookies that represent DACS identities. For example, if a jurisdiction segregated its DACS-wrapped static content under /dacs/content and its DACS-wrapped CGI programs under /dacs/cgi-bin, then COOKIE_PATH should have the value "/dacs".
CSS_PATH (Optional1)
If this directive is not used, a compile-time default of "/css" is used, which assumes that an Apache directive like this one is used:
Alias /css "/usr/local/dacs/www/css/"
Please refer to dacs.install(7)[73] for additional information about use of the Alias directive.
DTD_BASE_URL (Optional1)
<!DOCTYPE foo SYSTEM "http://example.com/dacs/dtd-xsd/foo.dtd">
If DTD_BASE_URL is not configured, an internal DTD will be emitted. Also see the description of the FORMAT web service argument[74].
EVAL (Optional)
EVAL ${Conf::a_special_path} = "/my/path"
FEDERATION_DOMAIN (Required1)
FEDERATION_NAME (Required1)
HTTP_AUTH (Stack)
Other than by placing the resource or resources specified by this directive under the control of DACS, no additional Apache configuration needs to be done to use this feature.
Please refer to the section on HTTP Authentication[82] for additional information about this feature and how it is used. Also refer to the HTTP_AUTH_ENABLE[83] directive.
Two different mechanisms are available: pre-authorization testing and post-authorization testing. The HTTP_AUTH_ENABLE directive is used to enable one or both mechanisms.
The pre-authorization testing mechanism is used if:
This mechanism can be useful with simple user agents that understand Basic authentication but cannot handle redirection or sometimes even the WWW-Authenticate response header. It may also be appropriate in situations where a user agent cannot or will not handle HTTP cookies. If dacs_acs is allowed to respond with a WWW-Authenticate response header, the configuration variable ${Conf::http_auth_401} must be set to "yes".
The post-authorization testing mechanism is used if:
One important difference between the two mechanisms is that while the post-authorization mechanism works by redirecting the user to dacs_authenticate(8)[52] after authorization checking denies a request, the pre-authorization mechanism does not involve any redirection and dacs_authenticate is not used. Instead, dacs_acs performs authentication internally (by calling dacsauth as a function) and credentials are not returned to the client; credentials are created that (normally) exist only for the duration of the authorization check, which means that no DACS session state exists outside of dacs_acs and therefore some DACS web services will either be unavailable or not operate in the same way they would if credentials were provided by the client. Pre-authorization may also be less efficient than returning credentials because authentication will be performed each and every time the client makes a request that triggers it. Note that only authentication modules that implement the password or expr authentication styles[86] can be used by this mechanism, and only if no redirection of the client is necessary. Because web browsers only prompt for a username and password, if an AUXILIARY argument is also required it must be entered with either the username or password (i.e., combined in some way, perhaps separated by punctuation) and then parsed into an AUXILIARY argument using a run-time configuration directive. With pre-authorization, roles can be assigned to the temporary credentials (refer to the description of the -r flag and the role-module-spec in dacsauth(1)[32] for details).
Security
Like dacsauth and dacs_authenticate, if dacs_acs uses a built-in module to perform authentication, it must run setuid or setgid (chmod(2)[87]). to obtain sufficient privileges to access the required files; this is true for Unix password authentication, for example. Programs should run at the lowest level of authorization that is necessary, however, and it is generally preferable to only run authentication modules at a higher authorization level.
The value of the HTTP_AUTH directive follows any one of the following three forms:
auth_scheme auth_realm url_pattern+
auth_scheme auth_realm url_pattern+ -pre [[-param] param-string] {-m auth-module-spec [auth-flag]*}+ {-r roles-module-spec}*
except url_pattern+
The first syntactical form is for the post-authentication mechanism:
The second syntactical form is for the pre-authentication mechanism. Its first three components are like those for the first form, and must appear in the order specified above. The following components are then added, and may follow the three initial components in any order:
In the third syntactical form, the except keyword identifies portions of the URL space that should not trigger HTTP authentication.
The HTTP_AUTH directives "stack", like the ACS_ERROR_HANDLER[18] directive. DACS will search for the first exact url_pattern that matches or will select the closest wildcard url_pattern. Two or more directives with the same url_pattern should not be configured.
The first of the two directives in the following example may trigger Basic authentication for the realm called "Info Realm" when either /cgi-bin/dacs/dacs_prenv or /cgi-bin/dacs/dacs_version (relative to the current jurisdiction[48]) is requested. The second directive may trigger Basic authentication for the realm called "CGI Realm" for any other resource subordinate to /cgi-bin/dacs. The first directive will override the second because an exact match overrides a wildcard match.
HTTP_AUTH "basic \"Info Realm\" /cgi-bin/dacs/dacs_prenv /cgi-bin/dacs/dacs_version" HTTP_AUTH "basic \"CGI Realm\" /cgi-bin/dacs/*"
In the next example, the two directives associate the Basic authentication scheme with everything under /cgi-bin/dacs/, except for /cgi-bin/dacs/dacs_prenv (because the second directive is an exact match, which overrides the first directive):
HTTP_AUTH "basic \"CGI Realm\" /cgi-bin/dacs/*" HTTP_AUTH "except /cgi-bin/dacs/dacs_prenv"
Tip
An administrator can take advantage of DACS's active configuration processing to decide at run-time which auth_scheme, auth_realm, or password file to use, for instance, perhaps depending on the request's arguments.
HTTP_AUTH_ENABLE "pre_acs_only" EVAL ${Conf::http_auth_401} = "no" HTTP_AUTH "basic \"dacs_prenv Realm\" /cgi-bin/dacs/dacs_prenv -m unix passwd suff"
The first directive above enables this feature. The second directive disables responding with a WWW-Authenticate header; changing its value to "yes" enables the response. The third directive associates the DACS dacs_prenv(8)[88] service with the built-in Basic authentication feature at pre-authorization testing time. Given this configuration, if a client requests dacs_prenv but does not include credentials:
Tip
You can create an Authorization header by constructing a string consisting of an account name, a colon, and the account's password. MIME encode the resulting string - you can use dacsexpr(1)[89] and the encode()[90] function:
% dacsexpr > encode(mime, "guest:apassword") "Z3Vlc3Q6YXBhc3N3b3Jk"
The header for the example above would look like:
Authorization: Basic Z3Vlc3Q6YXBhc3N3b3Jk
And using dacshttp(1)[4], you could use the flag:
-header Authorization "Basic Z3Vlc3Q6YXBhc3N3b3Jk"
HTTP_AUTH_ENABLE "pre_acs_only" HTTP_AUTH "basic \"LDAP Login Using Your Common Name\" /basic/* -pre \ -m https://example.example.com/cgi-bin/dacs/local_ldap_authenticate \ password sufficient -Of /usr/local/dacs/ldap/ldap_auth_options_direct"
In the file /usr/local/dacs/ldap/ldap_auth_options_direct (which must be readable at run-time by dacs_acs(8)[6]), we might put:
LDAP_BIND_METHOD=direct LDAP_USERNAME_URL*="ldap://windex.example.com/CN=" . encode(url,${Args::USERNAME}) . ",CN=Users,DC=example,DC=com" LDAP_USERNAME_EXPR*="${LDAP::sAMAccountName}"
Note the use of the LDAP_USERNAME_EXPR* directive. Because authentication against the directory uses a Common Name attribute in the example, and a Common Name may not be a valid DACS username, it must be replaced by (or mapped to) an acceptable DACS username. The first time a user attempts to access a resource that matches the URL pattern /basic/*, he will prompted by his web browser for a username (in this case, a Common Name must be provided) and password. The directory on windex.example.com will be used by the local_ldap_authenticate module to validate the information provided by the user.
To also obtain the user's roles from the directory, the set_roles style modifier and an LDAP_ROLES_SELECTOR* directive can be added to the configuration:
HTTP_AUTH_ENABLE "pre_acs_only" HTTP_AUTH "basic \"LDAP Login Using Your Common Name\" /basic/* -pre \ -m https://example.example.com/cgi-bin/dacs/local_ldap_authenticate \ password,set_roles sufficient -Of /usr/local/dacs/ldap/ldap_auth_options_direct"
And to /usr/local/dacs/ldap/ldap_auth_options_direct:
LDAP_BIND_METHOD=direct LDAP_USERNAME_URL*="ldap://windex.example.com/CN=" . encode(url,${Args::USERNAME}) . ",CN=Users,DC=example,DC=com" LDAP_ROLES_SELECTOR*="${LDAP::attrname}" eq "memberOf" ? strtr(ldap(rdn_attrvalu e, ldap(dn_index, "${LDAP::attrvalue}", 1)), " ", "_") : "" LDAP_USERNAME_EXPR*="${LDAP::sAMAccountName}"
Tip
Since the pre-authorization mechanism does not return DACS credentials to the user's web browser, a subsequent invocation of dacs_current_credentials(8)[92] will not display information that resulted from the authentication procedure. If the URL that triggers pre-authorization is for a script or other program that is executable by Apache with access permitted by DACS, however, the program can display its environment, which will include DACS_USERNAME, DACS_ROLES, and so on. For example, dacs_prenv(8)[88] can be used for this, as can this simple PHP script (phpinfo.php):
<html><head></head><body> <p> <?php phpinfo(); ?> </p> </body> </html>
HTTP_AUTH_ENABLE "pre_acs_only" HTTP_AUTH "basic \"Login Using Your Unix Account\" /basic/* -pre \ -m https://example.example.com/cgi-bin/dacs/local_unix_authenticate \ password sufficient -Of /usr/local/dacs/ldap/ldap_auth_options_direct \ -r https://example.example.com/cgi-bin/dacs/local_unix_roles"
Note that local_unix_authenticate must run with sufficient privileges to validate the username/password pair.
HTTP_AUTH_ENABLE (Optional1)
Refer to HTTP_AUTH[46] for additional details.
HTTP_PROG (Required1)
INFOCARD_AUDIENCE (Optional)
function [space+ arg-to-match-against-Audience]
function is case insensitive.
uri match-URI
INFOCARD_AUDIENCE "uri http://DACS.DSS.CA/infocard-demo"
any
INFOCARD_AUDIENCE "any"
regex match-regex
regex/flags match-regex
INFOCARD_AUDIENCE "regex/i ^https://dacs.dss.ca:8443"
The following directives are equivalent:
INFOCARD_AUDIENCE "regex .*" INFOCARD_AUDIENCE "any"
host match-hostname
INFOCARD_AUDIENCE "host dacs.dss.ca"
prefix match-URI
INFOCARD_AUDIENCE "prefix https://dacs.dss.ca/infocards"
INFOCARD_AUDIENCE_RESTRICTION (Optional)
INFOCARD_CARD_DATETIME_EXPIRES (Optional1)
INFOCARD_CARD_DATETIME_EXPIRES "2010-06-15T09:46:31-08:00"
Also see INFOCARD_CARD_LIFETIME_SECS[97].
INFOCARD_CARD_DEFS_URL (Optional1)
INFOCARD_CARD_FILL_URL (Optional1)
INFOCARD_CARD_IMAGE_BASE_URL (Required1-C)
An image should be in the range of 60 pixels wide by 45 pixels high and 200 pixels wide by 150 pixels high. Only certain image formats are allowed by the specification; the image format is deduced from the filename extension (case insensitively): ".png", ".gif", ".tiff" (or ".tif"), ".bmp", and ".jpeg" (or ".jpg"). If the format cannot be deduced, PNG is assumed.
INFOCARD_CARD_LIFETIME_SECS (Optional1)
INFOCARD_CARD_OUTPUTDIR (Optional1)
INFOCARD_CARD_VERSION (Optional1)
INFOCARD_CARDID_BASE_URL (Required1-C)
INFOCARD_CARDID_SUFFIX (Optional1)
identity
username
random
default
If the value of INFOCARD_CARDID_SUFFIX does not match (case-insensitively) any of these strings, it is interpolated verbatim. Regardless of how it was derived, the result string must be a syntactically valid URI path segment (RFC 2396[104]).
INFOCARD_DIGEST (Optional1)
INFOCARD_IP_PRIVACY_URL (Required1-C)
INFOCARD_IP_PRIVACY_VERSION (Optional1)
INFOCARD_ISSUER_INFO_ENTRY (Optional)
INFOCARD_MEX_URL (Required1-C)
INFOCARD_REQUIRE_APPLIES_TO (Optional1)
no
yes
true
false
INFOCARD_STRONG_RP_IDENTITY (Optional1)
INFOCARD_STS_AUTH_TYPE (Required1-C)
password
passwd
cert
card
kerberos
Note
Although the specification allows an ordered list of STS endpoints to appear, at present only a single endpoint may be configured.
INFOCARD_STS_CACERTFILE (Required1-C)
Note
File permissions and ownership must be set appropriately to allow run-time access.
INFOCARD_STS_CERTFILE (Required1-C)
Note
File permissions and ownership must be set appropriately to allow run-time access. If a self-signed certificate is being used, the appropriate root certificate must be installed on the system that is running the Identity Selector.
INFOCARD_STS_KEYFILE (Required1-C)
Note
File permissions and ownership must be set appropriately to allow run-time access.
INFOCARD_STS_KEYFILE_PASSWORD (Required1-C)
INFOCARD_STS_PASSWORD_METHOD (Required1-C)
empty
ignore
sts
account:id
INFOCARD_STS_RP_ENDPOINT (Optional)
INFOCARD_STS_URL (Required1-C)
INFOCARD_TOKEN_DRIFT_SECS (Optional1)
INFOCARD_TOKEN_ISSUER (Required1-C)
Note
If your Identity Selector does not let you choose a managed InfoCard when you think that it ought to (i.e., the value of this directive in effect when the managed InfoCard was created matches the web page's issuer parameter), it seems that the INFOCARD_TOKEN_ISSUER is ignored by an Identity Selector in preference to the name in the Identity Provider's SSL certificate. It has been noted that if a Relying Party uses a wildcard certificate[117], an Identity Selector may have trouble matching the issuer parameter in an HTML OBJECT request with an InfoCard; it may be necessary for the Relying Party to specify the value of the issuer parameter as the empty string.
INFOCARD_TOKEN_LIFETIME_SECS (Optional1)
INFOCARD_TOKEN_MAX_LENGTH (Optional1)
INFOCARD_USERNAME_SELECTOR (Optional1)
credentials
webpage
JURISDICTION_NAME (Required1)
LOGINGEN_FILE (Optional1)
LOGINGEN_PROG (Optional1)
LOG_FILE (Optional1)
The result after interpolation must either be the absolute pathname of a file to write log information to, or the word "syslog". In the latter case, syslog(3)[119] is used, with an ident argument of "dacs" and a facility of "user". Each DACS logging level is mapped to the corresponding syslog level, with the trace level mapped to syslog's debug level.
While DACS is starting and before it reads and processes its configuration files, this directive is not yet available to it; until DACS knows what LOG_FILE is, or should LOG_FILE not be writable, the value of LOG_FILE is obtained from the value of DACS_LOG. A compile-time specified value, DACS_LOG can be specified when DACS is built (the default is equivalent to ${Conf::DACS_HOME}/logs/error_log). If DACS_LOG is unusable, stderr is used.
LOG_FILTER (Stack)
Because this directive is in the Stack category[13], "later" directives supercede earlier ones. When a directive is found that allows a message to be logged, no additional directives are examined for the message. If this directive is not given, the default filtering is done based on the LOG_LEVEL and LOG_SENSITIVE directives.
The syntax is one of:
LOG_FILTER "type flag[,flag]* level name [[+|-]file]" LOG_FILTER "any flag[,flag]* level [[+|-]file]"
The type, which is one of the keywords program, module, filename, or function (case insensitive), specifies the type of the event source to which this filter applies; i.e., it indicates what name is to be matched against. If type is filename, for instance, it means that for this filter to be applicable to a particular log message, the name must match the filename from which the log message is generated.
A list of comma-separated, case-insensitive modifier flags specifies how matching of type is done against name. A flag can have the value exact, regex, icase, sensitive, user, audit, or normal.
The name is matched against type case sensitively, unless the icase flag is present. Matching is performed using regex(3)[121] regular expression matching if the regex flag is present, or using a string comparison if the exact flag is present (these two flags are mutually exclusive).
A message can have no attributes associated with it, or any combination of the attributes sensitive, user, and audit. Messages with the sensitive attribute might include potentially private information, such as a password. Messages with the audit attribute include relatively high-level events, such as successful and unsuccessful authentication results, signouts, and access control decisions. The user attribute is associated with messages produced by the print()[122] and printf()[123] functions.
Modifier flags are used to select (or deselect) messages to be logged. By default, only normal messages are logged; these are messages without any attributes. The LOG_SENSITIVE[124] directive can change the default to enable sensitive messages.
If the audit flag is given, a message is logged only if it has that attribute. Messages with the sensitive attribute are not logged unless the sensitive flag is given, and messages with the user attribute are not logged unless the user flag is given.
Assuming the type and level do not deselect the message, here are some example cases:
If the directive's value begins with the keyword any, the filter matches any source, so there is no name and the modifier flags related to matching name are ignored.
In order of increasing importance and decreasing amount of detail, level is one of the following case-insensitive keywords:
Any log message having a lower importance than level will not satisfy the filter. If the logging level is set to info, for example, messages having a lower level (debug and trace) will not be recorded. These levels are intended to have semantics similar to those of the logging levels used by Apache and syslog(3)[119].
The file field, which is optional, is used instead of (or in addition to) LOG_FILE and interpolation is performed in the same way. If file is syslog, all messages matching the filter will be written using syslog(3) instead of to LOG_FILE. If file is prefixed with a '+', output will be written to both LOG_FILE and the expansion of file; if it is prefixed with nothing or -, the default behaviour results; the initial character can be escaped using a backslash. In some situations, using /dev/null for file is useful to discard unhelpful messages.
Without regard to how LOG_LEVEL and LOG_SENSITIVE are configured, this directive says that all messages generated by any function located within the DACS source file named crypto.c having a level of at least debug, should be logged, including those marked as sensitive:
LOG_FILTER 'filename exact,sensitive debug crypto.c'
Tip
The directive:
LOG_FILTER 'any audit trace +syslog'
causes all log messages with the audit modifier having level trace or higher to be written to both syslog(3) and LOG_FILE. If you want to use the syslog feature in this way, you will need a section in the syslog(3) configuration file (typically /etc/syslog.conf) that looks something like the following, depending on the flavour of syslog(3) that your system uses:
!dacs *.* /usr/local/dacs/logs/audit_log
The following directive is similar except that it causes log messages classified as either audit or sensitive (or both) to be written to both LOG_FILE and the file logs/Audit_log, relative to the root of the DACS installation directory:
LOG_FILTER 'any audit,sensitive TRACE +%bD/logs/Audit_log'
By removing the '+' character, the log messages would not be written to LOG_FILE.
LOG_FORMAT (Optional1)
%%
%a
%c
%F
%fn
%fd
%j
%l
%p
%sF
%sf
%sl
%sm
%sp
%t
If a % is followed by any other character, that character is printed. Other characters in the format specifier are interpolated verbatim. If a requested value is not available, nothing is interpolated.
Tip
When debugging, it is often helpful to compare log messages produced when slightly different configurations are used to service a given request. With the default prefix, log messages tend to be unique. To make it easier to compare two sequences of log messages (e.g., using diff(1)[126]), append a special character (such as a tab) or a readily distinguished character string to the LOG_FORMAT format string. This will simplify stripping the prefix from log messages (e.g., using sed(1)[127]). Alternatively, set an empty prefix string, or write a conditional directive that eliminates the prefix only when debugging.
LOG_LEVEL (Optional1)
Briefly, in order of increasing importance, the names of the levels are: trace, debug, info, notice, warn, error, critical, alert, and emerg. The trace logging level emits the most detail and the emerg level emits the least. Refer to the LOG_FILTER[128] directive for additional information.
The LOG_LEVEL overrides the compile-time default, which is obtained using the LOG_DEFAULT_LEVEL symbol.
By default, informational log messages are emitted almost immediately when most DACS web services begin execution. To suppress these messages, without regard to any other logging configuration, build DACS with --enable-hush-startup-logging[129].
The "verbose" command line flag (-v) or the VERBOSE_LEVEL directive overrides this directive, which are in turn overridden by the -t command line flag ("trace") or the TRACE_LEVEL directive. A verbose level of one is equivalent to the info level; a verbose level greater than one is equivalent to the debug level. Enabling a trace level, with any value, is equivalent to requesting the trace logging level.
Also see debug_dacs[130].
LOG_SENSITIVE (Optional1)
Note
Sensitive messages may include passwords and other authentication material that should remain private. This directive will not suppress potentially sensitive messages generated by third-party support packages (e.g., Samba or OpenLDAP), Apache (including mod_auth_dacs), or the operating system. For example, requests for CGI programs invoked using the GET method will be logged in the Apache Access Log, and the request's query string will typically be printed; password parameters may be present in the log (see mod_log_config[131] for details of how to change the log format. If sensitive messages are being logged, make doubly-sure that log files have appropriate permissions. Also, unencrypted logging messages directed over a network (e.g., through syslog(3)[119]) may be visible to an attacker.
NAME_COMPARE (Optional1)
Security
The selected comparison method applies to all components of DACS names; if this is not desired, the strtr() function might be helpful. Note that this directive does not alter the DACS name determined by authentication, only the way the name is compared. While it's unlikely (and bad practice) for federation names (or jurisdiction names) to differ only in their case, it is not unusual for usernames to be treated case-insensitively for authentication purposes and for this reason this feature should be used with care. When case-insensitive comparisons are used, the usernames bob and BOB will be considered to be equivalent, for example; sometimes this is useful but it can also be a security hole, depending on how authentication is configured.
Changing the comparison method from case-insensitive back to case-sensitive may have undesirable consequences; identities that were formerly equivalent might suddenly become distinct, which at the very least may confuse users.
The recommended practice is to not define NAME_COMPARE or set it to case because of its system-wide effects. When needed, use the user() function with an appropriate comparison method argument.
NOTICES_ACCEPT_HANDLER (Optional1)
NOTICES_ACK_HANDLER (Optional1)
NOTICES_DECLINE_HANDLER (Optional1)
NOTICES_NAT_NAME_PREFIX (Optional1)
NOTICES_SECURE_HANDLER (Optional1)
NOTICES_WORKFLOW_LIFETIME_SECS (Optional1)
PAMD_HOST (Optional1)
PAMD_PORT (Optional1)
PASSWORD_CONSTRAINTS (Optional1)
Important
Each system usually imposes its own constraints on the characters that may be used in password, minimum and maximum password lengths, and so on. These constraints are external to DACS. With respect to the PASSWORD parameter passed to DACS web services (e.g., local_ldap_authenticate[91]) and used with DACS accounts (e.g., dacspasswd(1)[137]), it is safest to stick to printable ASCII characters. A compile-time maximum length of 128 characters is imposed on the PASSWORD parameter. Limits are also imposed on the USERNAME and AUXILIARY parameters (see Web Service Arguments[139]). These limits are more-or-less arbitrary but necessary.
The format of the constraint string is a set of zero or more comma-separated terms. Each term consists of an unsigned integer (zero or greater) followed immediately by a single character (case sensitive) that indicates a constraint type:
A constraint type may not appear more than once. Not all constraint types need to be specified. If this directive is not given, or is the empty string, or the word "none" (case insensitive), a minimum password length of any six characters is used. If a constraint type is missing, a minimum of zero is used. In no event is a password of fewer than six characters allowed for a non-administrator, however.
Security
No check is made for constraints that are impossible to satisfy.
For example, the following directive says that passwords must be at least eight characters long and include at least one digit and one upper case and one lower case character, with no punctuation characters required:
PASSWORD_CONSTRAINTS "8L,1D,1C,0P"
PASSWORD_DIGEST (Optional1)
In most cases only the name of the function is required, but functions that are parameterized (e.g., SCRYPT) require all configurable variables to be provided - there are no defaults.
The syntax for specifying a cryptographic digest is as follows:
digest-descriptor ::= dn ws* [ '[' arg-list ']' ] arg-list ::= name '=' value [, arg-list ]
A digest-descriptor is a digest name (dn), optionally followed by whitespace, optionally followed by an argument string (arg-list) within square brackets. The argument string consists of one or more name=value pairs, separated by a comma. The order of the pairs is not significant. A name may not appear more than once and an unrecognized parameter name is not allowed. Nothing can follow the closing square bracket. Whitespace may precede a name, but everything following the '=' is part of the value. The value ends at a comma or the closing bracket, so embedded whitespace is possible (but should be avoided). Whitespace following a comma is ignored. A value may be surrounded by single or double quotes, but escaping is not allowed. Examples:
PASSWORD_DIGEST "scrypt[N=1024, r='8', p=16, dklen=32]" PASSWORD_DIGEST "sha512/t[t=72]" PASSWORD_DIGEST "pbkdf2[a=sha256,count=4098, dklen=20]"
The digest name is matched against available password digest functions case-insensitively. Non-consecutive hyphens, underscores, and slashes in the digest name are treated as equivalent separators. A separator may be omitted if doing so would not join two digits. An initial or trailing separator is disallowed. For example:
"Sha224" matches "SHA-224" "SHA/512" matches "SHA-512" "pbkdf2sha512" matches "PBKDF2-SHA512"
Use the digests subcommand of dacs(1)[144] to list available algorithms and checkdigest to validate a digest descriptor:
% dacs digests % dacs checkdigest "pbkdf2[a=sha256,count=80000,dklen=32]"
The following cryptographic digest algorithms are available:
CRYPT
MD5
SHA-1
SHA-224
SHA-256
SHA-384
SHA-512
SHA-512/224
SHA-512/256
SHA-512/t
SHA3-224
SHA3-256
SHA3-384
SHA3-512
The following password-based key derivation algorithms are available:
ARGON2
y
v
m
t
p
T
X
S
Example:
PASSWORD_DIGEST "argon2[y=i,v=19,m=32,t=3,p=4,T=32,X='000102',S='']"
PBKDF2
a
count
dklen
PBKDF2-SHA1
count
dklen
PBKDF2-SHA256
count
dklen
PBKDF2-SHA512
count
dklen
SCRYPT
N
r
p
dklen
The PBKDF2, scrypt, and Argon2 functions should be carefully parameterized to be computationally intensive and memory intensive, if applicable, for the platform on which the password-based authentication module is run. The goal is to make password hashing unavoidably inefficient. This makes it more difficult for an attacker that accesses a copy of a password file to guess passwords because each guess takes longer or requires more resources than a comparatively efficient algorithm. For additional information about these algorithms and their parameters, see argon2()[151], pbkdf2()[152], and scrypt()[153].
Security
Apart from using an authentication method stronger than one based solely on passwords, it is considered best practice to use a key derivation function such as pbkdf2 or scrypt rather than a plain cryptographic digest for the PASSWORD_DIGEST.
These key derivation functions are intended to be inherently inefficient yet as efficient as possible. They are used for this purpose to provide additional resistance against brute force methods, even those that employ special hardware, should an attacker obtain a password file. But they do not help much if users are allowed to choose weak passwords, if the key derivation function is not properly parameterized, or if the function has exploitable properties. In these cases, it will still not be much of a challenge for an attacker to determine the original passwords. On the other hand, if only strong passwords are allowed and a good cryptographic digest function is used, a key derivation function is unnecessary. A key derivation function is most suitable for protecting passwords that are neither very weak nor particularly strong.
Memory-hard functions are a relatively new idea and many designs have not yet received much scrutiny. It should also be noted that significantly increasing the memory and CPU resources needed for each authentication operation could pose a problem for sites that must be prepared to handle many concurrent sign-ons. Running several memory-hard functions simultaneously on a server could cause it to run out of resources, which may provide an opportunity for denial of service attacks.
The selected password digest algorithm and its parameters should be reviewed periodically. If changes are made to PASSWORD_DIGEST, they will apply to new accounts but existing password entries will not be invalidated, so it may be necessary to force users to reset their passwords.
The system crypt() function may have platform-dependent limitations on the number of characters that are significant in a password or the maximum length of a password, but all other algorithms use all of the characters and impose no maximum password length.
PASSWORD_OPS_NEED_PASSWORD (Optional1)
PASSWORD_SALT_PREFIX (Optional1)
PERMIT_CHAINING (Optional1)
Security
Enabling this feature weakens security because it may allow misappropriated DACS identities to be used at a jurisdiction that has enabled PERMIT_CHAINING. Use of this feature is discouraged but is sometimes necessary; use with care. Refer to the description of the permit_chaining attribute in dacs.acls(5)[25].
PROXY_EXEC_DOCUMENT_ROOT (Optional1)
PROXY_EXEC_MAPPER_DEFAULT_ACTION (Optional1)
PROXY_EXEC_MAPPER_LOGGING (Optional1)
PROXY_EXEC_MAPPER_LOG_FILE (Optional1)
PROXY_EXEC_MAPPER_RULES_FILE (Optional1)
PROXY_EXEC_PROG_URI (Optional1)
RLINK (Optional)
If the expression evaluates to the empty string or an error occurs, the directive is ignored and the next one, if any, is processed. Example:
RLINK '"${Args::RNAME:?}" /usr/local/dacs/rlinks'
In the example above, the directive specifies that if the current request includes a non-empty argument called RNAME, then its value is an Rname, Rlink processing is enabled, and the Rlink can be found in the /usr/local/dacs/rlinks directory.
ROLE_STRING_MAX_LENGTH (Optional1)
Warning
A role string that is too long may cause the user to experience strange and possibly incorrect behaviour from DACS because the browser may discard cookies produced by DACS.
SECURE_MODE (Optional1)
Security
Always use the secure mode of operation unless you fully understand the consequences of disabling it. For DACS to be a secure system, secure mode should be disabled only for testing purposes or if all HTTP traffic is protected by some secure means other than SSL/TLS.
SIGNOUT_HANDLER (Optional1)
The following syntaxes are supported:
This form will cause DACS to redirect the client to the specified URL, which may be a relative or absolute URL. If the keyword url is absent, URL must begin with the four characters http. Whether the GET method is used depends on the context of the original request. The URL may contain a properly escaped query string; DACS will append the following parameters, URL encoded and in the order given:
DACS_VERSION
DACS_FEDERATION
DACS_JURISDICTION
DACS_SIGNOUT_RESULT
The following directive will redirect the user's browser to a relative URL:
SIGNOUT_HANDLER "url /dacs/handlers/signout_ok.html?FOO=bar"
This form is like that of the url syntax except that a URL given by a DACS_SIGNOUT_HANDLER parameter will be used if it is passed to dacs_signout(8)[33]. A DACS_SIGNOUT_HANDLER parameter is ignored in the other forms of the SIGNOUT_HANDLER directive. If that parameter is absent, the URL specified by this directive is used. As in the url form, DACS will append parameters to the DACS_SIGNOUT_HANDLER URL. Note that the defaulturl keyword is not optional.
This form causes the contents of the file named by full-pathname to be returned. The file must include any header lines it requires, such as a Content-Type line, a header-terminating blank line, and then the document content.
Note
The "full-pathname" usage differs from the "local-URL" usage of the ACS_ERROR_HANDLER directive, though both elements begin with a slash character; the former specifies the absolute pathname of a file, while the latter specifies a URL local to the receiving web server. To specify a relative URL, use the url keyword.
This form causes the given message, surrounded by escaped double quote characters, to be returned as HTML.
SIGNOUT_HANDLER "message \"You're outta here!\""
This form causes the user's remaining credentials to be displayed as an HTML document. This is the default behaviour.
The optional keywords are treated case-insensitively.
SSL_PROG (Optional1)
SSL_PROG_ARGS (Optional1)
Note
This directive is "global" in that it applies to all internal invocations of SSL_PROG. SSL/TLS options should probably be more flexibly configurable (e.g., from within Auth and Roles clauses).
SSL_PROG_CA_CRT (Optional1)
SSL_PROG_CLIENT_CRT (Optional1)
STATUS_LINE (Optional1)
TEMP_DIRECTORY (Optional1)
TOKEN_REQUIRES_PIN (Optional1)
TOKEN_HOTP_ACCEPT_WINDOW (Optional1)
TRACE_LEVEL (Optional1)
UNAUTH_ROLES (Optional1)
If a jurisdiction configures this directive:
UNAUTH_ROLES "anonymous"
then the following predicates would both return True when applied to an unauthenticated user:
user("unauth") user("%:anonymous")
A useful application of this directive is to classify unauthenticated users based on contextual elements. Consider this directive:
UNAUTH_ROLES from("10.0.0.0/24") ? "user" : ""
If an unauthenticated user submits a request from a local IP address between 10.0.0.0 and 10.0.0.255, the user would be treated as having the role user, otherwise the user would have no roles. This might be used to conveniently grant limited access to "local" users without them having to authenticate. A rule could be written to grant access based on having the role user, for example, without needing to consider whether or not the user has authenticated.
Unlike roles assigned to credentials, roles specified in this way are strictly local to the jurisdiction that configures them. Some form of coordination is required if different jurisdictions need to assign the same roles to unauthenticated users. These roles are not reported by dacs_current_credentials(8)[92].
UPROXY_APPROVED (Stack)
[{'http' | 'https'} '://'] hostname [:port] [path]
dacs_uproxy is invoked with a URI with the following syntax:
.../dacs_uproxy/proxied-hostname[:proxied-port][proxied-path-prefix]
A proxied-hostname is matched against the hostname of each entry in the list, according to the stacked directive ordering, until a (case insensitive) match is found. If the proxied-hostname is followed by a port number, that port number must be explicitly specified in a directive for a match to occur. If no scheme is specified, http is used, regardless of what protocol the port may imply. If a path is given, it is appended to the proxied-path-prefix.
For example, consider the directives:
UPROXY_APPROVED "example.com" UPROXY_APPROVED "https://foo.example.com" UPROXY_APPROVED "http://bar.example.com:8080" UPROXY_APPROVED "https://baz.example.com:8443/some/path"
A request for the proxied hostname foo.example.com, such as this:
.../dacs_uproxy/foo.example.com/a/b/c.cgi
will be forwarded by dacs_uproxy as the URI:
And the proxied request:
.../dacs_uproxy/baz.example.com/a/b/c.cgi
will be forwarded by dacs_uproxy as the URI:
This request would fail because there is no approved entry for bar.example.com:80:
.../dacs_uproxy/bar.example.com:80/a/b/c.cgi
VERBOSE_LEVEL (Optional1)
VERIFY_IP (Required1)
# Only credentials that were issued to an address on this subnet # are acceptable VERIFY_IP "10.0.0.0/24"
Tip
Verification might be turned off, for example, in an environment where a user might legitimately submit service requests associated with different IP addresses. Refer to dacs_authenticate(8)[62] for additional information.
VERIFY_UA (Optional1)
Security
In typical use of DACS, this feature should be enabled because it makes it somewhat more difficult for misappropriated DACS credentials to be used. It is not a foolproof measure, however, because a sophisticated attacker may be able to obtain or guess a user agent string and use it with stolen credentials, although guesses may draw attention by causing log messages to be emitted.
Some user agents, including dacshttp(1)[4], Mozilla, Firefox, curl, wget, and Konqueror, allow the user agent string to be set. Including a random or unusual component in the string will strengthen this feature. Also, middleware may be able to take advantage of its ability to send a string of its choosing in the User-Agent header field.
Verification might be turned off, for example, in proxying situations or if credentials are cached by middleware and then legitimately used with different user agents. The feature should be disabled for backward compatibility with releases earlier than DACS 1.4.14.
VFS (Stack)
The value of this directive (a vfs_uri) has the following syntax:
vfs_uri -> [ '[' item_type ']' ] URI
As specified in RFC 2396[104] and RFC 3986[165], the general form of the URI syntax is:
scheme : [ // authority] [path] [query] [fragment]
The item_type (see dacs(1)[166]) is optional in some cases - it can usually be omitted if the directive will not be referenced and if it does not refer to an indexed object. It is a case-sensitive label that associates this directive with a class of objects used by DACS. Some labels are reserved and have predefined meaning to DACS; these are always lowercase; dacsconf(1)[2] can list them. Any label can be defined by a DACS administrator, but a reserved item type should only be defined for its intended use; user-defined item types should therefore include at least one uppercase letter. For example, here are a few reserved item types: passwds (used by dacspasswd(1)[137] and others), federation_keys and jurisdiction_keys (used by dacskey(1)[167] and others), revocations (used by dacs.acls(5)[25] and others), and stdin (used by get()[168] and others).
Although the scheme is case-insensitive, the canonical form is lowercase. The authority, query, and fragment URI components are often absent. The query component is used to specify options.
The path component of a URI has the format:
[ naming_context ] [ "," rel-path ]
For paths that have a separate key relative to the naming context, its start is delimited by a comma.
The scheme may be:
dacs-db
dacs-ndbm
dacs-fs
fs
file
dacs-sqlite
http
https
VFS "[revocations]https://example.com/dacs/revocation_list"
dacs-kwv
For example, components of DACS expect the passwds item type to be defined. Taken together, the following pair of directives specify that the plain file /usr/local/dacs/passwd consists of keyword-value pairs:
VFS "[password_file]dacs-fs:/usr/local/dacs/passwd" VFS "[passwds]dacs-kwv:password_file"
To specify a space as the separator character instead of the colon (which is the default), use the directives:
VFS "[password_file]dacs-fs:/usr/local/dacs/passwd" VFS "[passwds]dacs-kwv:password_file?field_sep=+"
Because these are URIs, they must be properly encoded and the '+' character represents a space. If the passwords are to be stored in a Berkeley DB database, the directive would be:
VFS "[passwds]dacs-db:/usr/local/dacs/passwd.db"
dacs-kwv-subscheme
This configuration directive is almost equivalent to the pair of directives described in the example above:
VFS "[passwds]dacs-kwv-fs:/usr/local/dacs/passwd"
The following configuration directive states that the password file used by dacspasswd(1)[137] is to be accessed at the URL https://example.com/dacs/passwds using the standard HTTP methods:
VFS "[passwds]dacs-kwv-https://example.com/dacs/passwds"
dacs-vfs
For example, this directive causes DACS to look for password entries used by local_passwd_authenticate[174] to be accessed through the virtual filestore at example.com:
VFS "[passwds]dacs-vfs:https://example.com/cgi-bin/dacs/dacs_vfs"
A vfs-ref is a reference to a virtual filestore definition and can be a vfs_uri or an item_type defined by a VFS directive. In some situations it can also be an absolute pathname.
Note
At present, the VFS does not implement much in the way of concurrency control. Some DACS components use coarse-grained locking to ensure that only a single user can access resources, however, and databases may implement their own concurrency control. Only a few of these resources are not used in a read-only fashion; administrators should adopt appropriate data management practices for them to ensure concurrent updates cannot occur.
XSD_BASE_URL (Optional1)
<foo xmlns="http://example.com/dacs/v1.4" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://example.com/dacs/v1.4 http://example.com/dacs/dtd-xsd/foo.xsd">
If XSD_BASE_URL is not configured, only the default xmlns attribute is emitted.
The Auth Clause¶
Each Auth clause configures an authentication module. The Auth clause and its directives are described in dacs_authenticate(8)[27].Note that the order of these clauses is significant - they are processed in the order in which they appear in the applicable configuration section.
The Roles Clause¶
Each Roles clause configures a roles module. Roles clause and its directives are described in dacs_authenticate(8)[175].The clauses are processed in the order in which they appear. Authentication modules may return roles, to improve efficiency, but roles are usually obtained through a roles module. Roles modules are processed only if authentication is successful.
The Transfer Clause¶
Each Transfer clause configures dacs_auth_transfer(8)[29] for importing from one or more federations specified within the clause. The clauses are processed in the order in which they appear. No clause should apply to more than one initial federation, although this is not enforced.Each Transfer element has an id attribute. Its value is merely a label (an alphabetic followed by zero or more alphanumerics, hyphens, and underscores) that allows the clause to be referenced; the syntax is the same as that of a groupname[80]. The attribute values must be unique (case-sensitively). Transfer clause directives are described in dacs_auth_transfer(8)[29].
Advanced Techniques¶
Configuration processing is ordinarily quite straightforward, but to accommodate more complicated situations it also supports a few advanced techniques.Configuration Variables
After configuration processing determines which directives have been overridden, those that are in effect have their right hand sides (which are expressions) evaluated. These expressions are usually simple strings but they can be any DACS expression.
Tip
When configuration processing begins, variables in the DACS and Args namespaces[14] can by referenced by configuration directives.
Security
The ability to reference an argument during configuration processing can be useful and powerful when used carefully but since argument values are completely in the hands of the user constructing a request, it is a potential security weakness, particularly in DACS deployments that are exposed to the Internet.
For example, an argument might be missing or duplicated, accidentally have a problematic value (such as containing non-printable or otherwise invalid characters), or be specifically constructed in an attempt to misconfigure DACS to thwart security. For this reason, variables in the Args namespace should be referenced in configuration files only when specifically indicated in the documentation, or by advanced DACS administrators in appropriate circumstances and with caution.
As each expression is evaluated to determine the value of the directive, a variable in the Conf namespace (see dacs.exprs(5)[14]) is created and assigned the value, and can then be referenced in subsequent expressions. Variables in this namespace can be referenced within access control rules, permitting rules to be written that depend on how the particular site, federation, and jurisdiction have been configured. In addition, during the remainder of the configuration processing stage, the variable's value can be modified, effectively changing the value associated with the directive. After completion of configuration processing, the variables in the Conf namespace become read-only. It is these variables that are displayed by the -vars option of dacsconf(1)[2].
For example, if the directive
FEDERATION_DOMAIN "example.com"
is in effect when directive evaluation begins, the variable ${Conf::FEDERATION_DOMAIN} will be created and assigned the value "example.com".
Variables within the Conf namespace[14] can be created as needed within expressions (using the EVAL directive, for example). Care should be taken not to unintentionally modify the value of a DACS directive, however.
A standard set of variables is always instantiated when available:
APACHE_HOME
CGI_SUFFIX
DACS_CONF
DACS_CONF_SPEC
DACS_HOME
Important
This directory should be writable only by an administrator.
DACS_CGIBINDIR
DACS_RELEASE
DACS_BINDIR
DACS_SBINDIR
DACS_SITE_CONF
DACS_SITE_CONF_SPEC
DACS_VERSION
DOCUMENT_ROOT
EXE_SUFFIX
FEDERATIONS_ROOT
HTTP_HOST
JURISDICTION_URI
JURISDICTION_URI_PREFIX
OPENSSL_PROG
SERVER_ADDR
SERVER_NAME
SERVER_PORT
URI_SCHEME
Authentication and Roles
This section unfortunately left blank.
SEE ALSO¶
dacsconf(1)[2], dacs_conf(8)[3], dacs.exprs(5)[20]BUGS¶
There's no way to turn off inherited defaults in a jurisdiction section or Default section; i.e., one cannot turn off all Auth or handler directives for just one jurisdiction section.AUTHOR¶
Distributed Systems Software (http://www.dss.ca)COPYING¶
Copyright © 2003-2018 Distributed Systems Software. See the LICENSE[176] file that accompanies the distribution for licensing information.NOTES¶
- 1.
- dacs(1)
- 2.
- dacsconf(1)
- 3.
- dacs_conf(8)
- 4.
- dacshttp(1)
- 5.
- dacs(1)
- 6.
- dacs_acs(8)
- 7.
- mod_auth_dacs
- 8.
- mod_vhost_alias
- 9.
- LOG_FILE
- 10.
- pathname()
- 11.
- Jurisdiction section's
- 12.
- Configuration.dtd
- 13.
- Stack category
- 14.
- namespace
- 15.
- EVAL directive
- 16.
- undef()
- 17.
- modifier flag
- 18.
- ACS_ERROR_HANDLER
- 19.
- effective jurisdictional URIs
- 20.
- expression
- 21.
- configuration variables
- 22.
- example configuration
- 23.
- Jurisdiction Selection by URI
- 24.
- string interpolation
- 25.
- access control rules
- 26.
- INIT*
- 27.
- Auth clause
- 28.
- section merging
- 30.
- Authorization Caching
- 31.
- dacscookie(1)
- 32.
- dacsauth(1)
- 33.
- dacs_signout(8)
- 34.
- The DACS_APPROVAL environment variable
- 35.
- description of the ErrorDocument directive
- 36.
- redirect()
- 37.
- access control rules
- 38.
- dacs_admin()
- 39.
- ADMIN_IDENTITY
- 40.
- Bug 3641
- 41.
- Bug 42430
- 43.
- ACS_TRACK_ACTIVITY
- 44.
- SetDACSAuthPostBuffer
- 45.
- SERVICE_ARGS_TRUNCATED
- 46.
- HTTP_AUTH
- 47.
- syntactically valid username
- 48.
- current jurisdiction
- 49.
- ACS_AUTHENTICATED_ONLY
- 51.
- DACS_ACS
- 53.
- on_success()
- 54.
- counter
- 55.
- current federation
- 56.
- ACS_INACTIVITY_LIMIT_SECS
- 57.
- FEDERATION_NAME
- 58.
- NAME_COMPARE
- 59.
- auth_reply.dtd
- 60.
- dacs_auth_reply.dtd
- 61.
- AUTH_ERROR_HANDLER
- 62.
- cookie name
- 64.
- ACS_CREDENTIALS_LIMIT
- 65.
- AUTH_SUCCESS_HANDLER
- 66.
- mitigate the risk of information disclosure with a cross-site scripting (XSS) attack
- 67.
- are known
- 68.
- a particular syntax
- 69.
- COOKIE_SYNTAX
- 70.
- Netscape HTTP Cookies Specification
- 71.
- RFC 2965
- 72.
- RFC 6265
- 73.
- dacs.install(7)
- 74.
- FORMAT web service argument
- 75.
- Advanced Techniques
- 76.
- RFC 1035
- 77.
- dacs.groups(5)
- 78.
- dacs.conf(5)
- 79.
- JURISDICTION_NAME
- 80.
- dacs(1)
- 81.
- RFC 2617
- 82.
- HTTP Authentication
- 83.
- HTTP_AUTH_ENABLE
- 84.
- ACS_PRE_AUTH
- 85.
- see below
- 86.
- authentication styles
- 87.
- chmod(2)
- 88.
- dacs_prenv(8)
- 89.
- dacsexpr(1)
- 90.
- encode()
- 91.
- LDAP authentication
- 93.
- regex(3)
- 94.
- dacs_sts(8)
- 96.
- XML Schema Part 2: Datatypes Second Edition
- 97.
- INFOCARD_CARD_LIFETIME_SECS
- 98.
- VFS URI
- 99.
- CARD_IMAGE_URL
- 00.
- INFOCARD_CARD_DATETIME_EXPIRES
- 01.
- INFOCARD_CARDID_BASE_URL
- 02.
- INFOCARD_CARD_OUTPUTDIR
- 03.
- INFOCARD_CARDID_SUFFIX
- 04.
- RFC 2396
- 05.
- dacs_infocard(8)
- 06.
- PASSWORD_DIGEST
- 07.
- INFOCARD_IP_PRIVACY_URL
- 08.
- dacs_mex(8)
- 09.
- INFOCARD_STS_PASSWORD_METHOD
- 10.
- INFOCARD_STS_CERTFILE
- 11.
- dacsinfocard(1)
- 12.
- local_infocard_authenticate
- 13.
- INFOCARD_STS_KEYFILE_PASSWORD
- 14.
- INFOCARD_STS_KEYFILE
- 15.
- INFOCARD_REQUIRE_APPLIES_TO
- 16.
- INFOCARD_AUDIENCE
- 17.
- wildcard certificate
- 18.
- mod_vhost_alias
- 19.
- syslog(3)
- 20.
- LOG_LEVEL
- 21.
- regex(3)
- 22.
- print()
- 23.
- printf()
- 24.
- LOG_SENSITIVE
- 25.
- dacs(1)
- 26.
- diff(1)
- 27.
- sed(1)
- 28.
- LOG_FILTER
- 29.
- --enable-hush-startup-logging
- 30.
- debug_dacs
- 31.
- mod_log_config
- 32.
- dacs_notices(8)
- 33.
- Secure Mode
- 34.
- local_pam_authenticate
- 35.
- pamd(8)
- 36.
- dacs_passwd(8)
- 37.
- dacspasswd(1)
- 38.
- dacstoken(1)
- 39.
- Web Service Arguments
- 40.
- PASSWORD_AUDIT
- 41.
- ispunct(3)
- 42.
- dacs_token(8)
- 43.
- dacs_admin(8)
- 44.
- dacs(1)
- 45.
- crypt(3)
- 46.
- MD5 function
- 47.
- FIPS 180-4
- 48.
- FIPS PUB 202, August/2015
- 49.
- Argon2
- 50.
- RFC 2898
- 51.
- argon2()
- 52.
- pbkdf2()
- 53.
- scrypt()
- 54.
- Rlink
- 55.
- VFS specification
- 56.
- sslclient(1)
- 57.
- DACS-Status-Line
- 58.
- DACS_HOME
- 59.
- role descriptor string
- 60.
- user()
- 61.
- dacs_uproxy(8)
- 62.
- from()
- 63.
- dacs.vfs(5)
- 64.
- dacsvfs(1)
- 65.
- RFC 3986
- 66.
- dacs(1)
- 67.
- dacskey(1)
- 68.
- get()
- 69.
- Berkeley DB
- 70.
- dbm(3)
- 71.
- GNU gdbm
- 72.
- SQLite
- 73.
- dacs_vfs(8)
- 74.
- local_passwd_authenticate
- 76.
- LICENSE
02/19/2019 | DACS 1.4.40 |