Provided by: dacs_1.4.38a-2build1_amd64 bug

NAME

       dacs_acs - DACS access control service

SYNOPSIS

       dacs_acs [dacsoptions[1]] [-dcc] [-proxy-static] [-proxy-exec]
                        dacs_acs-test

DESCRIPTION

       This program is part of the DACS suite.

       The DACS access control service, dacs_acs (or simply ACS) is responsible for making access
       control decisions on web service requests. It is run by a web server. In the current
       implementation, dacs_acs is executed by the web server as an external program.  ACS
       provides attribute- and role-based access control using the DACS rule-processing engine,
       which consults access control rules (also referred to as ACLs) provided with DACS or
       written by a DACS administrator. Because access control is performed on URIs, ACS can
       control access to arbitrary resources, such as web pages, files, or programs.

       A generic interface to DACS's rule processing engine is given by dacscheck(1)[2].

       A web server runs dacs_acs to determine whether a particular service request is
       authorized. Although in theory any web server that provides appropriate hooks could call
       dacs_acs, at present only Apache 2.x and 2.2.x web servers are supported. A DACS-aware
       Apache module called mod_auth_dacs[3] is configured using custom Apache directives and
       runs dacs_acs. A web server having mod_auth_dacs[3] functionality is said to be
       DACS-enhanced and web services that are under the control of mod_auth_dacs[3] are said to
       be DACS-wrapped.

       When Apache receives a DACS-wrapped service request, the mod_auth_dacs module is run,
       which in turn runs dacs_acs to determine whether the request should be granted. The module
       provides dacs_acs with the name of the requested service ("What is being accessed?"),
       parameters that were passed in the request ("How is it being accessed?"), the identity of
       the client ("Who is making the request?"), and other context associated with the request.
       With this information at hand, dacs_acs consults a set of access control rules (the
       ruleset) (see dacs.acls(5)[4]). Additional contextual information, such as DACS
       configuration directives and build-time options, and the run-time environment, is also
       available. The information returned by dacs_acs to the module either causes Apache to
       grant permission, possibly with a constraint that specifies additional, service-specific
       information, or denies permission, possibly with a reason for denial.  dacs_acs may also
       instruct the web server to redirect the client.

       All DACS services must be under the control of dacs_acs, even those that do not require
       the client to be authenticated. Also, a web server must be configured such that only
       DACS-controlled services and no other services can be invoked through URLs associated with
       its DACS jurisdiction.

       It is not a requirement that all of a web server's resources be under the control of DACS.
       That is, it is not necessary to DACS-wrap everything, but it is certainly possible.

       Please refer to the documentation for mod_auth_dacs[3] for information on configuring the
       DACS Apache module.

           Security
           A dacs_acs process, which is created by httpd, should ordinarily run as the same user
           id as httpd. File and directory ownership and modes must be set so that it can read
           its configuration files, access control rules, and so on. The DACS expression language
           includes functions that can execute an arbitrary program and perform file system
           operations, so care must be taken to ensure that files used by DACS cannot be edited
           or replaced by non-privileged users. In some circumstances, it may be necessary for
           dacs_acs to run as root, in which case a DACS administrator must be extra careful in
           this regard.

           Tip
           One way to understand what dacs_acs is doing, or to debug it, is to enable the most
           detailed level of logging[5]. This will emit a copious quantity of output to the DACS
           log file, so be sure to reduce the logging level and delete the log file when you are
           finished.

           Setting the LOG_LEVEL[6] directive to "debug" or "trace" will produce detailed output
           (although it can be moderated using the LOG_FILTER[7] directive).  LOG_LEVEL has the
           disadvantage that it cannot take effect until after configuration processing.

           To enable logging output at the earliest possible time, you can add the desired
           dacsoptions[1] flags to Apache's AddDACSAuth[8] directive; for example, by using a
           directive like the following in httpd.conf:

               AddDACSAuth dacs-acs /usr/local/dacs/bin/dacs_acs "-t -v"

           Note that httpd must be restarted before changes to this directive take effect.

           An alternative method of enabling detailed logging, equivalent to using the -t and -v
           flags if neither has been specified, is to create a file in the DACS_HOME[9] directory
           with the name debug_progname. For example, to enable detailed logging for dacs_acs,
           the following command might be used:

               % touch /usr/local/dacs/debug_dacs_acs

           This method takes effect immediately and applies to any DACS web service or command
           that accepts dacsoptions[1] at the time they begin execution. It overrides the current
           value of LOG_LEVEL, is more selective because it applies only to progname (unlike
           LOG_LEVEL), is easily turned on by creating the file and turned off by removing the
           file, and neither requires changes to httpd.conf nor an httpd restart.

   Module-to-ACS Protocol
       DACS's mod_auth_dacs[3] module for Apache invokes the dacs_acs program to do the hard part
       of deciding whether a request should be granted or denied. The module is responsible for
       configuring itself using new Apache directives, gathering information required to make the
       access control decision, passing that information to dacs_acs, and receiving the access
       control decision from dacs_acs, together with either environment information (if access is
       granted to an executable request) or error handling directives (if access is denied).

       To prevent potentially sensitive information from becoming visible, mod_auth_dacs[3]
       passes information to dacs_acs over an interprocess communication channel (pipe(2)[10]).
       dacs_acs reads its standard input, makes the access control decision, and writes either
       environment information or an optional error handling directive to its standard output.
       The exit status of dacs_acs communicates its decision: zero means the request should be
       granted, anything else means the request should be denied.

           Important
           The module provides dacs_acs with its DACS version number to ensure that it is
           compatible.  dacs_acs will deny all access to DACS-wrapped resources if its version
           number does not exactly match the module's. This requirement helps to protect against
           build or installation mistakes.

       The information passed to dacs_acs from Apache is in the format:

           variable-name="variable-value"

       each of which is terminated by a newline character. These variables are listed below. For
       details about how to reference these values, see Variables Available To Rules[11].

       SERVICE_ARGS
           The query arguments (if any and whether GET or POST method is being used) followed by
           POST arguments (if any and to the maximum length configured), base-64 encoded.

       SERVICE_ARGS_TRUNCATED
           For POST method requests, if the POST data stream (i.e., the request's entity-body)
           was not completely captured, such as if the maximum length was reached, this variable
           will be present and assigned the value 1.

       SERVICE_AUTHORIZATION
           The value of the Authorization HTTP header field, if present.

       SERVICE_CONTENT_ENCODING
           The value of the Content-Encoding HTTP header field, if present.

       SERVICE_CONTENT_LENGTH
           The value of the Content-Length HTTP header field, if present.

       SERVICE_CONTENT_TYPE
           The value of the Content-Type HTTP header field, if present.

       SERVICE_COOKIE
           The value of the Cookie HTTP header field, if present.

       SERVICE_FILENAME
           The name of the file, as determined by Apache, corresponding to this response.

       SERVICE_HOSTNAME
           The name of the host as set by the full URI or Host HTTP header field, as determined
           by Apache.

       SERVICE_HTTPS
           If the request came over SSL/TLS (HTTPS), this variable will be present and set to
           "on".

       SERVICE_METHOD
           The request method, as set by Apache (e.g., "GET").

       SERVICE_MOD_AUTH_DACS_VERSION
           The DACS version number string associated with the mod_auth_dacs[3] module.

       SERVICE_PATH_INFO
           The PATH_INFO part of the URI, as set by Apache.

       SERVICE_POSTDATA
           When available, the POST data stream (the HTTP message body) (or part of it: see the
           description of the SetDACSAuthPostBuffer directive to mod_auth_dacs[12]). It is MIME
           base-64 encoded.

       SERVICE_PROXY_AUTH
           The value of the DACS-Proxy-Authorization HTTP header field, if present. (Not
           currently used).

       SERVICE_PROXYREQ
           If the current request involves proxy processing on this server, this identifies the
           type of processing as "proxy" (for "forward proxying"), "proxy_reverse" (for "reverse
           proxying"), or "proxy_response".

       SERVICE_QUERY
           The value of the query string component of the URI.

       SERVICE_REMOTE_ADDR
           The client's IP address.

       SERVICE_REMOTE_HOST
           The client's DNS name, if known by Apache.

       SERVICE_SERVER_PORT
           The TCP/IP port on which the request was received by Apache.

       SERVICE_URI
           The path portion of the URI, as determined by Apache.

       SERVICE_USER_AGENT
           The value of the User-Agent HTTP header field, if present.

       If access is granted, dacs_acs may provide a set of control directives for
       mod_auth_dacs[3] to interpret, followed by a set of environment variables for
       mod_auth_dacs[3] to introduce into the environment of an executable request. Each control
       directive starts with a "=" character and is terminated by a newline. Environment
       variables are specified in the format:

           variable-name=variable-value

       each of which is terminated by a newline character.

       If access is denied, dacs_acs may instead provide an error handling directive, newline
       terminated, in the form expected as the third argument to Apache's ap_custom_response()
       function.

   Credentials
       DACS credentials can be passed to dacs_acs in several ways, but they have the following
       representation:

           DACS:federation-name::[jurisdiction-name]:[username]=value[; ...]

       If the jurisdiction-name is omitted, the username must also be omitted (see
       COOKIE_NAME_TERMINATORS[13]). The string is URL encoded. If there are multiple
       credentials, they are separated by any combination of spaces and ";" characters.

       Credentials are passed from mod_auth_dacs[3] to dacs_acs using the SERVICE_COOKIE variable
       (transmitted over a pipe(2)[10])

       Because a process's environment is public on some systems, DACS takes care not to pass
       credentials using environment variables. Passing credentials through the HTTP_COOKIE
       environment variable is forbidden unless enabled by the ALLOW_HTTP_COOKIE[14] directive.
       When specifically enabled by a rule's attribute, they can be passed using the DACS_COOKIE
       environment variable (see the pass_credentials attribute described in dacs.acls(5)[4]).

       If an HTTP Authorization header is used with the "DACS" authentication scheme, the
       "basic-credentials" component of the header may contain DACS credentials. Please refer to
       RFC 2617[15]. These credentials have the format given above but are also base-64 encoded.

           Security
           It is forbidden to submit multiple credentials for the same identity to DACS and such
           a request will trigger an error.

           It is also forbidden to submit multiple DACS authentication cookies with the same
           cookie name.

       Please refer to dacs_authenticate(8)[16] for additional information.

   Rlinks
       DACS provides an alternate authentication and authorization mechanism. An Rlink (rule
       link) is a special URL that includes an Rname component, which is essentially the name of
       an access control rule. Instead of matching the name of a requested resource against
       rules, as is normally done by DACS, the request itself (indirectly) specifies
       authorization constraints that DACS must apply to the request. Optionally, a DACS identity
       and other information can be included in the Rlink.

       During authorization processing, the Rname is resolved to an access control rule that is
       processed the same as any other access control rule and the requested resource must be
       DACS-wrapped. In other words, a request that is recognized as an Rlink essentially says
       "use the rule identified by this request's Rname to decide whether or not to grant access
       and do not consider any other rule". Subsequent access control processing is identical to
       the normal case.

       In typical usage, an Rlink is created (probably, but not necessarily by dacsrlink(1)[17])
       and the resulting URL is distributed (e.g., by email) to those parties intended to be able
       to access the resource. Similar mechanisms are widely used by web-based applications. For
       example, consider the case where a customer has purchased a digital resource and it is
       time to make the item (e.g., a file) available for downloading. A new Rlink is created for
       the item and given to the customer. The customer invokes the URL to obtain the item. Each
       customer receives a unique Rlink but there only needs to be one instance of the resource.
       Only those with a valid Rlink can access the resource. No traditional account needs to be
       created for the customer, and the Rlink does not authorize the customer to access any
       other secure resource. When the resource has been accessed, a log record will be created
       that identifies the customer and confirms the download.

       The main advantage of Rlinks is that they make controlled file sharing and web service
       access simple. An Rlink is created and disseminated, and all recipients can access the
       named resource (subject to the Rlink's rule) using any web browser. Any number of
       different rules can be created for the same resource, with each one having a different
       Rname. An Rlink's rule can be changed or deleted by its owner at any time, even after it
       has been distributed.

       Rlinks also offer an alternative way to make exceptions to the rule normally applicable.
       Rather than revising the "normal" rule for a resource or set of resources to take account
       for the exceptions, one or more Rlinks can be created to handle the special cases and the
       normal rules need not be touched.

       Another application of Rlinks is as a short representation of an arbitrary URL. Someone
       accessing an Rlink that has been configured in this way is redirected to a specified URL;
       see the redirect()[18] function. The URL can be changed at will simply by editing the
       Rlink's rule. The Rlink need not be kept secret when it is used for this purpose.

       The main disadvantage of Rlinks is that security may rely on keeping Rnames secret, and
       because an Rlink may be visible in a URL, this can be difficult to keep up. Anyone who can
       capture an Rname and use it properly with a resource to which it applies can potentially
       gain access to that resource. An Rname might be found in a log file, or in a browser's
       history or bookmark list. Although this method is convenient for users, the requirement
       for secrecy means that it might not be appropriate in some situations. At the expense of
       some convenience, however, a password can be bound to an Rlink when it is created; for the
       Rlink to be valid when it is invoked, the same password must be presented as an argument.
       Furthermore, because the access control rule associated with an Rname is the same as any
       other rule, it may express any conditions it likes, so it can still require authentication
       to have been performed, restrict the user's IP address, and so on. Also, an Rlink cannot
       be used to gain access to a resource that is not described by its rule's services element.

       Rlink Details
           When an Rlink is used as a kind of "secret URL" that grants access to anyone who uses
           it, an Rname is a randomly generated identifier that is unique, with very high
           probability, relative to its namespace at a jurisdiction. By default, an Rname
           consists of eight symbols from the set of upper- and lower-case alphabetics and
           digits, yielding a namespace in excess of 10^14 identifiers. This makes guessing a
           valid Rname highly unlikely. The characteristics of new Rnames can be changed at will;
           the alphabet from which they are generated should be considered carefully, however, to
           avoid problems that might arise when they are embedded within a URL or used as a
           filename.  RLINK[19] directives can map Rnames to the same or different namespaces,
           depending on the filestore selected by a directive.

               Note
               An Rlink does not have to be used as a secret URL though, and its creator can
               choose any Rname that will work with the mechanism described here.

               If a rule contains the optional name attribute, the attribute value must exactly
               match the Rname.

               The base name of a file containing an Rlink will be its Rname. This naming scheme
               is different from the one used for normal rules[20].

           This feature allows multiple versions of an Rlink to be created, each bound to a
           different identity. By attaching an identity to an Rlink, its creator can confer
           different rights to different users, or simply track who has used the Rlink. These
           identities may or may not correspond to "real" identities that are associated with
           DACS authentication (i.e., there may or may not be an account associated with them);
           DACS administrators should keep this mind to avoid any confusion.

           An Rname may be followed by a suffix that directly or indirectly associates a DACS
           identity with the Rlink. For want of a better name, this composite identifier is
           called an RnameIdent and has the following syntax:

                 RnameIdent  -> Rname ':' ident | Rname ';' iptr

           In the direct mode of identity attachment, the Rname is followed by a separator (a
           colon, which cannot appear in an Rname) and ident, a cryptographically protected and
           base-64 encoded concise user identity[21] that is created by dacsrlink(1)[17]. These
           encrypted identities are not the same as encrypted credentials. Different encrypted
           identifiers may represent exactly the same identity. If DACS recognizes the Rname,
           when it performs authorization checking it will do so assuming the specified identity,
           ignoring any other credentials that might have accompanied the request.

           In the indirect mode, the Rname is followed by a different separator (a semi-colon,
           which cannot appear in an Rname) and an arbitrary string, called an iptr (identity
           pointer) that is safe to embed in a URI. The same character set from which an Rname
           can be generated is safe for an iptr: any number of alphanumerics, hyphens, and
           underscores. The rule that is specified by the Rname is expected to map the string to
           an identity, probably by using the identity element[22], and the identity is used in
           the same way as in the direct mode. Like an Rname, in typical usage an iptr must be
           difficult to guess and be kept secret, otherwise a valid Rlink might easily be
           constructed that is associated with a chosen identity. The indirect mode has the
           advantages of keeping the URL relatively short, is immune to changes of the encryption
           key, and allows identities to be modified after an Rlink is shared.

           An identity obtained using either attachment mode is tested for revocation.

           The Rname, specified identity, and identity pointer are accessible in the DACS
           namespace[11], when they are available, as ${DACS::RNAME}, ${DACS::RIDENT}, and
           ${DACS::RIPTR}, respectively.

           Rlinks can easily be created manually or by a custom program, but the dacsrlink(1)[17]
           utility provides a simple interface to create and administer them. Rules created by
           dacsrlink can be manually edited and deleted just like any other rule. There is no a
           priori limit on the lifetime of an Rlink; it continues to exist as far as DACS is
           concerned if the Rname is recognized by an RLINK directive and the named rule exists
           and is valid. Deleting the rule corresponding to an Rname effectively invalidates that
           Rlink.

           An Rname can be presented as an ordinary web service argument, as a component of the
           request URI, or via the special DACS_ACS argument[23]:

               https://example.com/~alice/photos/myphoto.gif?RNAME=jigrFUwF
               https://example.com/cgi-bin/manage.cgi/jigrFUwF
               https://example.com/private/data?DACS_ACS=-rname+jigrFUwF

           Each of these approaches has advantages and disadvantages; the best choice depends on
           web site and application details. For example, embedding an Rname as a component of a
           URI is particularly well suited to CGI programs and web services (e.g.,
           https://example.com/cgi-bin/manage/jigrFUwF, where manage is the name of the program).
           Using the DACS_ACS argument allows the Rname to be used during access control testing
           but completely hidden from the requested resource.

           RLINK[19] directives are used to examine an incoming request, decide whether an Rname
           is present, extract the Rname, and specify where the rule can be found. If an Rname is
           present, normal access control processing is disabled and no search of the usual DACS
           rulesets for an applicable rule occurs. If no RLINK directive finds an Rname, normal
           access control processing occurs.

   HTTP Authentication
       dacs_acs can be configured to trigger HTTP authentication (see RFC 2617[15]) by returning
       a WWW-Authenticate response header in certain circumstances. This will usually cause a
       browser or other web user agent to use its built-in mechanism for prompting the user for a
       username and password that corresponds to a particular access realm (a label that
       identifies a URL path prefix belonging to the server).

       If dacs_acs denies access because the user is not authenticated (code 902,
       ACS_DENIAL_REASON_NO_AUTH), it checks to see if HTTP authentication has been enabled for
       the request. If not, processing of the denied request proceeds normally, otherwise DACS
       will try to use the RFC 2617[15] protocol to have dacs_authenticate authenticate the user.

       Also see autologin(8)[24].

           Tip
           This feature is configured through the HTTP_AUTH_ENABLE[25] and HTTP_AUTH[26]
           directives, some configuration variables, and Auth clause directives[27]. Please refer
           to them for details.

           When HTTP authentication is triggered in this way, no extra Apache configuration needs
           to be done or should be done. All that is required of Apache is that the resource that
           should trigger authentication be DACS-wrapped.

           Any password style authentication module, or the CAS authentication module, can be
           configured in conjunction with DACS's HTTP Basic authentication (RFC 2617[15]). That
           is, DACS can be configured to cause a browser to pop-up a username/password prompt and
           then use the values supplied by the user as if they were the USERNAME and PASSWORD
           arguments to dacs_authenticate. The authentication module on the backend of the
           authentication procedure can use any type of Apache password file or DACS password
           file, NTLM, CAS, etc.

           Besides authenticating against an Apache password file created by htpasswd, htdigest,
           or htdbm, this means that an ordinary browser can be used to capture a username and
           password for any DACS authentication module that requires it. Please refer to the
           description of the local_apache_authenticate[28] module for details.

       If the feature is enabled and applies to a request:

        1. any ACS_ERROR_HANDLER[29], AUTH_SUCCESS_HANDLER[30], and AUTH_ERROR_HANDLER[31]
           directives that would ordinarily apply are overridden.

        2. the HTTP_AUTH[26] directive that applies to the request specifies the authentication
           scheme, realm, and any additional authentication parameters.

        3. a WWW-Authenticate response header is returned to the browser. For example, for HTTP
           Basic authentication this header might look like:

               WWW-Authenticate: Basic realm="My Realm"

        4. an HTTP status value of 401 (RFC 2616[32]) is returned. If the variable
           ${Conf::http_auth_message} is defined, its value is used as the message body; if it is
           "", then no message body will be sent; if not provided, the string "902 Authentication
           by DACS is required" is used.

        5. if the variable ${Conf::http_auth_jurisdiction} is configured, it is expected to be
           the name of the jurisdiction (within the current federation) at which
           dacs_authenticate is to be invoked to authenticate the user; if the variable is
           undefined, the name of the current jurisdiction is used.

       The values of some of these variables are neither examined by DACS nor meaningful to it.
       For example, all that DACS requires of the realm string is that it be syntactically valid.

       When enabled, the following flow of control occurs:

        1. The user hits a DACS-wrapped URL when not authenticated; if dacs_acs is configured to
           perform HTTP authentication for the request, it returns a 401 ("Unauthorized") status
           code and a WWW-Authenticate header;

        2. The browser prompts for a username and password; the user enters the information and
           the browser re-submits the request, which this time includes an Authorization header;

        3. dacs_acs again denies the request because the user is not authenticated, but sees an
           Authorization header and redirects the user to dacs_authenticate (at
           ${Conf::http_auth_jurisdiction} or the current jurisdiction) with arguments necessary
           for the selected authentication scheme; dacs_authenticate maps the given username (and
           password, if available) to the USERNAME argument (and possibly the PASSWORD argument)
           and invokes authentication modules as necessary;

        4. If authentication succeeds, credentials are issued and the user is redirected to the
           original request (via the GET method);

        5. If authentication fails, the procedure is repeated from the beginning.

           Important
           The main advantages of HTTP Basic and Digest authentication (RFC 2617[15]) are its
           simplicity and near-universal support. It does have some serious drawbacks compared to
           a cookie-based (token) implementation, however. Here are a few:

           •   While various kludges exist, there is no standard way to de-authenticate, to tell
               a client to stop sending an Authorization request header. Consequently, if a user
               that has authenticated using HTTP Basic authentication signs out of DACS and in
               the same browser session visits a link that triggers authentication, DACS
               credentials may be automatically re-issued without prompting.

           •   In HTTP Basic authentication, there are more opportunities for an attacker to
               capture a username and password, on the client side (which must cache both
               parameters indefinitely), at a web server, or at a proxy server, even when SSL/TLS
               is used.

           •   Any method can be used by a web server to validate a username and password. In the
               common HTTP Basic authentication deployment, the web server must validate the
               Authorization request header each time it is sent by a client, perhaps with every
               request, meaning that an expensive authentication function may need to be executed
               many times with exactly the same parameters during a particular session.

           With Digest authentication, various aspects of the authentication protocol are subject
           to time limits as a security measure. The configuration variable
           ${Conf::http_auth_timeout_secs} can be set to the number of seconds for which a nonce
           is valid, thereby overriding the default; only advanced administrators familiar with
           RFC 2617[15] should change the default.

       The following is an example of configuration that might appear in the appropriate section
       (or sections) in DACS configuration files:

           HTTP_AUTH_ENABLE "yes"
           HTTP_AUTH "Basic \"Doggies\" /basic/*"

           EVAL ${Conf::http_auth_message} = \
             "902 https://example.com/cgi-bin/dacs/dacs_authenticate"

       Given this example configuration, whenever access is denied for a resource having a URL
       path that begins with "/basic/" because the user is not authenticated, the following
       response-headers will be returned:

           WWW-Authenticate: Basic realm="Doggies"
           Status: 401

       and the message body will contain the single line:

           902 https://example.com/cgi-bin/dacs/dacs_authenticate

       Instead of enabling the feature for all requests, the following example enables it only
       for those user agents that supply a User-Agent request-header that matches the regular
       expression "DACS-http/.*" (which happens to match the default User-Agent string sent by
       the DACS dacshttp(1)[33] utility).

           HTTP_AUTH_ENABLE = regmatch("${DACS::USER_AGENT}", "DACS-http/.*") ? "yes" : "no"

       A similar expression would enable the feature only for Internet Explorer, Mozilla, curl,
       dacshttp(1)[33], etc., or some combination of browsers. Simply obtain the User-Agent
       string(s) sent by the browser(s) and write the appropriate regular expression to match
       it/them.

       Although RFC 2617[15] allows multiple WWW-Authenticate response-headers to be returned,
       this mechanism can only send one.

       When provided by a user agent, dacs_acs makes the value of the Authorization
       request-header available to access control rules through the ${DACS::AUTHORIZATION}
       variable.  DACS credentials can also be passed using this request-header[34].

   Authorization Caching
       After a rule grants access, dacs_acs can be configured to save some context about its
       access control decision so that if the user makes a subsequent request for a resource
       managed by the same rule in a similar context, authorization can be granted quickly and
       without having to search for the applicable rule or re-evaluate it. Basically, the
       administrator tells DACS that if the rule grants access to a particular user, then it is
       safe for DACS to assume that future requests for the same resource by the same user should
       be granted without doing a complete authorization check.

       This mechanism offers improved performance in cases where:

       •   users tend to make many requests for the same resource, or for a set of resources that
           are managed by the same rule (such as CSS files or images);

       •   rule evaluation is relatively slow or expensive;

       •   there are a large number of rules and/or rule retrieval is relatively slow;

       •   re-evaluation of the rule is unnecessary (e.g., the rule does not update any state
           information)

       •   it is acceptable for changes to the ruleset to not immediately affect cachable
           decisions

           Security
           Pending further testing, this feature should be considered experimental. Use it in
           production situations only after you have satisfied yourself that it is working
           properly with your access control rules.

       Authorization caching is implemented using a special HTTP cookie, called an access token
       (not related to the tokens used in authentication), and a simple database maintained by
       dacs_acs. A cookie is returned to the user when caching is possible and the user does not
       already possess a valid cookie. An access token points to server-side data that describes
       the cached authorization, including the context in which it is valid. Immediately after
       revocation testing, dacs_acs checks if authorization caching applies to the current
       request; if it does, no access control rules are examined and access is immediately
       granted. If caching does not apply, processing continues as usual. If any invalid access
       tokens were sent with the request, dacs_acs will ask for them to be deleted (i.e., it
       unsets the cookies). These cookies have the following format:

           DACS:federation-name::jurisdiction-name::TOKEN-unique

       Here, unique is the "dacs64" encoding (see dacs.exprs(5)[35]) of a cryptographically
       strong pseudo-random 16 byte value. Also see the COOKIE_NAME_TERMINATORS[13] directive.
       Since access control is purely a jurisdictional responsibility in DACS, a cookie is
       meaningful only to the jurisdiction that issues it.

       These cookies are non-persistent (they are supposed to disappear when a browser session
       ends). The value of COOKIE_PATH[36], or "/", determines the cookie's path attribute. The
       COOKIE_NO_DOMAIN[37] and COOKIE_HTTP_ONLY[38] directives are also honoured.

       Here is a simple example of how DACS might be configured to enable authorization caching
       for a particular resource. The jurisdiction's dacs.conf would include directives similar
       to the following:

           ACS_ACCESS_TOKEN_ENABLE        "yes"
           ACS_ACCESS_TOKEN_LIFETIME_SECS "43200"
           VFS                            "[tokens]dacs-kwv-fs:/usr/local/dacs/conf/tokens"

       A rule for the resource might look like this:

           <acl_rule status="enabled">
              <services>
                <service url_pattern="/cgi-bin/database.cgi"/>
                <service url_pattern="/cgi-bin/someprog.cgi"/>
              </services>

              <rule order="allow,deny">
                <allow permit_caching="yes">
                  user("auth")
                </allow>
              </rule>
           </acl_rule>

       Given this configuration, the first time an authenticated user requests, say,
       https://example.com/cgi-bin/database.cgi, he will be issued an access token. This token
       will be valid for up to 12 hours, and its associated data will be stored as an entry in
       the file /usr/local/dacs/conf/tokens.

           Note
           In the current implementation, each access token is contained within its own cookie,
           rather than a jurisdiction collecting all of the user's tokens within a single cookie.
           A user might therefore simultaneously hold many access tokens from each jurisdiction.
           This should not be significant for middleware agents, but web browsers typically
           impose various kinds of limits on cookie "real estate". Administrators should take
           this into account when using this feature.

       Before it can be used, DACS must be built with the feature enabled (see
       --enable-access-tokens in dacs.install(7)[39]). The virtual filestore item type "tokens"
       must be configured to identify an indexed virtual storage method and location for storing
       cache entries. Also, the authorization caching mechanism must be configured (see
       ACS_ACCESS_TOKEN_ENABLE[40], ACS_ACCESS_TOKEN_LIFETIME_LIMIT[41], and
       ACS_ACCESS_TOKEN_LIFETIME_SECS[42]).

       Enabling the feature in a particular context also requires setting a rule's permit_caching
       attribute to "yes" (see dacs.acls(5)[43]). Whenever access is granted because of the rule,
       authorization caching of the rule is possible.

           Note
           Only the url_pattern of the rule's matching Service element (or the path derived from
           a url_expr attribute) is associated with the access token. This implies that when a
           rule has more than one service element, as in the example rule above, a single access
           token would be associated with only one of the two resources. Requests for different
           services could result in multiple access tokens being returned to a user, one for each
           service. A wildcard pattern is required if an access token is intended to grant access
           to more than one resource (this restriction may be lifted in future releases).

           Although a service request's arguments may be significant when initially granting
           access, they are not significant with respect to authorization caching applied to
           subsequent requests that use the access token. Once an access token is issued, the
           resource or resources named by it may therefore be invoked with different arguments
           without negating authorization caching.

           If any constraint, permit_chaining pass_credentials, or pass_http_cookie attributes
           are associated with the cachable rule, their values are also remembered and set if the
           access token subsequently causes access to be granted.

       Authorization caching is possible irrespective of whether a user has been authenticated.
       Caching is not allowed, however, in cases where the granting rule uses tail matching[44]
       and a rule exists for a subordinate URL (i.e., where there is a "more specific" rule for
       some other resource that should not be overridden by caching the "more general" rule).
       These cases are simply ignored; they are not considered to be errors. It is therefore not
       possible to cache the outcome of a rule with a url_pattern of "/*", for example, unless it
       is the only rule in the ruleset.

           Note
           A positive result will be cached regardless of whether the requested resource actually
           exists or is subsequently processed without error by the web server. It is therefore
           possible for an access token to be issued for a resource that does not exist at the
           time of issue but which is created at some later time.

       The store of tokens may be deleted or modified at any time. Any access token that points
       to an invalid or missing entry in the store becomes invalid.

       Over time, the server-side access token database tends to accumulate entries for access
       tokens that no longer exist or have expired. These should be garbage collected. (This is
       currently not automated, so the database needs to be truncated. There should also be way
       to list the entries and manually delete entries.) The dacsacl(1)[45] command and
       dacs_admin(8)[46] service can perform administrative functions on the entry database.

           Security
           Access tokens are created and used in such a way that it is practically impossible for
           an attacker to manufacture a valid access token or to convert an access token valid
           for one resource into one valid for a different resource.

           If a user is authenticated at the time an access token is generated, the token is
           "tied" to those credentials (all of them) and becomes invalid if any of the
           credentials become invalid or are not sent with the access token. If a user signs out
           or reauthenticates after being issued an access token, therefore, the access token
           will become invalid. Additional credentials, beyond what were present at the time an
           access token was generated, have no effect in this regard.

           As with cookies bearing DACS credentials, cookies containing access tokens must be
           kept private. For an authenticated user, an attacker would need to acquire an access
           token and all credentials to make use of the token. For an unauthenticated user, only
           the access token is needed; presumably (but not necessarily) in this case a lower
           level of security is being applied to the resource in any case.

           It is the administrator's responsibility to ensure that authorization caching does not
           break the intended semantics of a rule - DACS does not do any consistency or sanity
           checks. For instance, if a rule is written to grant access only between 12:00 and
           12:59 but an access token produced by the rule could continue to be valid beyond that
           time interval, authorization caching could violate the intent of the rule. Also, a
           rule that ordinarily produces side effects would not do so for any requests granted
           through authorization caching.

           As long as an authorization decision remains valid, changes to the ruleset will not
           cause a cached decision to be reversed. That is, a change to the ruleset that would
           ordinarily cause a request to be denied will have no effect on a cached decision. The
           revocation list[47] is, however, processed as usual, so it is possible for a cached
           decision to be denied due to revocation. An error encountered during processing would
           also cause access to be denied, regardless of authorization caching.

   XML Output
       When XML output has been enabled, dacs_acs will emit a document (conforming to
       dacs_acs.dtd[48]) when access is denied, a processing error occurs, or when an access
       testing mode has been requested using the DACS_ACS argument.

       dacs_acs associates an error code with each event or reason for which access might be
       denied (see the description of the ACS_ERROR_HANDLER directive in dacs.conf(5)[49]). The
       error code is itself sufficient for a client to know why access was denied. When access is
       denied, an appropriately named XML element is emitted. The element will include an
       explanatory text message, and optionally, the URI of a handler that the client might call
       to continue the workflow. This URI is obtained from the applicable ACS_ERROR_HANDLER
       directive, if any.

       The event905 element corresponds to the ACK_NEEDED (equivalent to error code 905) DACS
       error event. It is emitted if the client must acknowledge one or more notices before the
       request will be granted. Its handler attributes, which are optional, are obtained from the
       ACS_ERROR_HANDLER directive that applies to this error and the NOTICES_ACK_HANDLER
       directive. If the ack_handler attribute is absent, then the presentation_handler is
       expected to perform both presentation and acknowledgement handling functions. The
       notice_uris attribute is a comma-separated list of URIs of notices that must be
       acknowledged by the user. The resource_uris attribute is a comma-separated list of URIs of
       resources associated with this request; this will usually be only a single URI. The time
       and hmac attributes are used to enforce a secure workflow mode. Please refer to
       dacs_notices(8)[50] and dacs.conf(5)[49] for additional detail.

       A common_status element indicates that dacs_acs could not process the request. This might
       happen, for example, if dacs_acs were not properly configured.

   Variables Available To Rules
       dacs_acs predefines several variables that may be accessed by rules. Additionally,
       variables obtained from the request's credentials are exported into the environment of an
       invoked CGI program. In this way, services can know who is making the request, to retrieve
       user preferences, for example.

       In addition, parameters passed to a CGI program, whether through a query string or a
       message body (e.g., POST method data), may be accessed as variables. For example, for the
       service request:

            .../cgi-bin/foo?A=hello&B=world

       the variables ${Args::A} with the value hello and ${Args::B} with the value world will be
       defined at the time ACL rulesets are evaluated. Also, variables obtained from the
       authenticated credentials may be referenced (e.g., ${DACS::JURISDICTION}).

           Note
           Because at present a variable cannot be multi-valued, if a variable is set more than
           once its value at the time of evaluation is not predictable. For example, given this
           query string you cannot depend on which value is assigned to ${Args::ARG}:

                .../cgi-bin/foo?ARG=hello&ARG=world

           This also creates problems if you need to examine arguments produced by an HTML SELECT
           element within a form when the MULTIPLE attribute is used because each OPTION selected
           by the user will be associated with the same argument name. Syntactical and functional
           improvements are planned in this regard.

           Any "null" arguments in the query string (e.g., "&&") are ignored. A query string with
           a component that has a value but not a name (e.g., "&=foo") is considered to be
           invalid.

       From these sources, the execution environment, and from the DACS configuration, dacs_acs
       automatically creates four "classes" of variables: CGI parameter variables, configuration
       variables, environment variables, and request-specific variables created by DACS. These
       classes are called namespaces; please refer to dacs.exprs(5)[51] for details. For example,
       the value of a CGI parameter is accessed by ${Args::varname}, the value of a DACS context
       variable is accessed by ${DACS::varname} (e.g., ${DACS::JURISDICTION}), and the value of
       configuration variable is obtained using ${Conf::varname} (e.g.,
       ${Conf::FEDERATION_DOMAIN}).

       Standard Environment Variables
           For dacs_acs, the Env namespace is comprised of CGI variables exported by Apache,
           which includes HTTP request variables such as ${Env::HTTP_USER_AGENT}. The values of
           recognized headers that might compromise security are edited or deleted.  Apache will
           export unrecognized HTTP request headers by prefixing the header name with HTTP_ and
           mapping the header name to upper case; this example results in ${Env::AUGGIE} having
           the value "Doggie":

               % dacshttp -header Auggie Doggie https://example.com/cgi-bin/dacs/someprog

           For other programs, the Env namespace is populated from the program's normal
           environment.

           These namespaces are reserved from other uses and their contents are, for the most
           part, read-only.

           The only MIME content types currently supported with respect to capturing CGI
           parameters are application/x-www-form-urlencoded, which is the default used by
           browsers when submitting a form, and multipart/form-data. At present, only 7bit data
           encoding is supported. The methods by which values from forms can be returned to a
           server are described in RFC 1867[52], RFC 2388[53], and HTML 4[54].

               Note
               In some contexts, Apache's PATH_TRANSLATED environment variable is not passed to
               dacs_acs (it is still available as unusual to CGI programs).

       Exported DACS Variables
           The following variables are exported to the "DACS" namespace (e.g., ${DACS::QUERY}).
           Upper and lower case are distinct in variable names. These values are either obtained
           from Apache or are elements of the client's credentials.

           ACS
               If dacs_acs is requested to test access, this variable will be defined and have
               the value of the DACS_ACS argument.

           ARGS
               A string representing all of the parameters to a CGI program, excluding
               multipart/form-data, encoded as a query string. If the number or total size of the
               parameters exceeded the implementation-dependent limit, the variable
               ARGS_TRUNCATED will be defined and have a non-zero value.

           ARGS_TRUNCATED
               If this variable is defined and its value is non-zero, the argument list has been
               truncated. This means that not all arguments to the CGI program are accessible to
               dacs_acs and the value of one argument may have been truncated. See
               ACS_POST_EXCEPTION_MODE[55].

           ARG_COUNT
               The number of arguments available in the Args namespace. If there are four
               arguments in a request's query string and two arguments within its
               application/x-www-form-urlencoded message body, for instance, then the value of
               ${DACS::ARG_COUNT} will be six. These arguments will be available collectively as
               the value of ${DACS::ARGS} and individually in the Args namespace.

           AUTHORIZATION
               The value of the Authorization HTTP header field, if available.

           CONTENT_ENCODING
               The value of the Content-Encoding HTTP header field, if available.

           CONTENT_LENGTH
               The value of the Content-Length HTTP header field, if available.

           CONTENT_TYPE
               The value of the Content-Type HTTP header field, if available.

           CURRENT_URI
               The full URI for the requested resource, including any query component.

           CURRENT_URI_NO_QUERY
               The full URI for the requested resource, excluding any query component.

           FEDERATION
               The official name of the federation to which JURISDICTION belongs. If the user was
               not authenticated, this variable will be undefined.

           FILENAME
               The full path of the file corresponding to the URL being invoked, equivalent to
               Apache's SCRIPT_FILENAME environment variable or its REQUEST_FILENAME variable.

           IDENTITY
               The DACS identity (the username component plus federation and jurisdiction
               components) if the user was authenticated, otherwise undefined.

           INTERACTIVE
               If the standard input is a valid terminal type device, this variable is set to 1,
               otherwise it is undefined.

           IP
               The IP address, in standard numeric dot notation, associated with USERNAME. If the
               user was not authenticated, this variable will be undefined.

           JURISDICTION
               The official, abbreviated name of the jurisdiction that authenticated USERNAME. If
               the user was not authenticated, this variable will be undefined.

           METHOD
               The method used to invoke the URL, equivalent to Apache's REQUEST_METHOD
               environment variable.

           PATH_INFO
               The PATH_INFO part of the URI, as set by Apache.

           POSTDATA
               A MIME base-64 encoded string representing the data stream (message body) sent to
               a CGI program. If the number or total size of the parameters exceeded the
               configured limit, the variable ARGS_TRUNCATED will be defined and have a non-zero
               value. See the description of the SetDACSAuthPostBuffer directive to
               mod_auth_dacs[12]).

           PROXYREQ
               If set, the type of proxy processing performed for this request by Apache (from
               SERVICE_PROXYREQ).

           QUERY
               The query string, if any, that was appended to the URL.

           REMOTE_ADDR
               The REMOTE_ADDR, as set by Apache.

           REMOTE_HOST
               The REMOTE_HOST, as set by Apache.

           RIDENT
               The Rlink identity, if any, associated with the rule currently being evaluated.
               See Rlinks[56].

           RIPTR
               The Rlink identity pointer, if any, associated with the rule currently being
               evaluated. See Rlinks[56].

           RNAME
               The Rname, if any, associated with the rule currently being evaluated. This is
               also available as ${Args::RNAME}. See Rlinks[56].

           ROLES
               The role string associated with USERNAME. If the user was not authenticated, this
               variable will be undefined.

           URI and URL
               The URL being invoked.

           USERNAME
               The username (without any federation or jurisdiction component). If the user was
               not authenticated, this variable will be undefined.

           USER_AGENT
               When provided by the user agent, this is equivalent to the HTTP User-Agent
               request-header field and HTTP_USER_AGENT environment variable provided by Apache.
               When an actual value is unavailable, this variable is set to "unknown".

   Exported Environment Variables
       The normal execution environment of a CGI program or internally processed script (e.g.,
       mod_php) that is DACS-wrapped is augmented with environment variables instantiated from
       validated credentials, access control rules, configuration information, and so on. Through
       these variables, services have access to the identity of the user making the request to
       retrieve user preferences, for example, or make run-time decisions.

           Note
           Environment variables with the prefix "DACS_" are reserved for use by DACS and should
           not be used for other purposes by an application. Upper and lower case are distinct in
           variable names.

           Tip
           If PHP[57] is installed, a nice way to see the DACS environment variables that are
           passed to a CGI program is to run a DACS-wrapped script like this:

               <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
               <html><head>
               <meta http-equiv="Content-type" content="text/html;charset=ISO-8859-1">
               <title></title></head>
               <body>
               <p>
               <?php
               phpinfo();
               ?>
               </p>
               </body></html>

           Alternatively, you can use dacs_prenv(8)[58].

       The environment variables that are exported (when defined) are listed here. More detailed
       descriptions of these variables appear in other DACS documents.

       DACS_ACS_JURISDICTION
           This is the official DACS internal, abbreviated name for the jurisdiction that has
           granted access.

       DACS_APPROVAL
           A digitally signed message that confirms that DACS authorized the request. See
           dacs_acs(8)[59].

       DACS_CONCISE_IDENTITY
           This is the full DACS identity to which access was granted expressed in the concise
           syntax used by dacscheck(1)[2]. When available, the user's roles and IP address are
           included.

       DACS_CONF
           This is the full pathname of the DACS configuration file.

       DACS_CONSTRAINT
           A constraint string associated with a sub-component of the matching access control
           rule permitting the service request.

       DACS_DEFAULT_CONSTRAINT
           A constraint string associated with the matching access control rule.

       DACS_FEDERATION
           This is the federation name component of DACS_IDENTITY.

       DACS_IDENTITY
           This is the full DACS identity to which access was granted.  Apache's REMOTE_USER
           environment variable is also set to this value, so it is available for logging
           purposes and export to CGI programs.

       DACS_JURISDICTION
           This is the jurisdiction component of DACS_IDENTITY.

       DACS_MOD_AUTH_DACS
           This is the date and time mod_auth_dacs[3] was built.

       DACS_MOD_AUTH_DACS_VERSION
           This is the DACS version identification string for the mod_auth_dacs[3] being used
           (i.e., the DACS distribution that this module was built with).

       DACS_ROLES
           This is the role string associated with DACS_USERNAME within DACS_JURISDICTION.

       DACS_SITE_CONF
           This is the full pathname of the DACS site configuration file.

       DACS_USERNAME
           This is the username component of the identity to which access was granted.

       DACS_VERSION
           The major version number of DACS.

       About Servlets
               Note
               The details of how environment variables are passed from Apache to servlets are
               beyond the scope of DACS. But for what it's worth, the following illustrates how
               to export and access them from servlets that are under the control of DACS in
               conjunction with mod_jk[60] and Tomcat[61]. This used to work at one time but may
               no longer be correct.

           The following directives (which appear in, or are included in, the Apache
           configuration file) are used (this list may be expanded):

               <IfModule mod_jk.c>
                 JkEnvVar DACS_FEDERATION         NONE
                 JkEnvVar DACS_JURISDICTION       NONE
                 JkEnvVar DACS_ACS_JURISDICTION   NONE
                 JkEnvVar DACS_ROLES              NONE
                 JkEnvVar DACS_USERNAME           NONE
                 JkEnvVar DACS_CONSTRAINT         NONE
                 JkEnvVar DACS_DEFAULT_CONSTRAINT NONE
                 JkEnvVar DACS_COOKIE             NONE
                 JkEnvVar DACS_MOD_AUTH_DACS      NONE
               </IfModule mod_jk.c>

           From a servlet, the values of these variables can be obtained through the
           getAttribute() method, invoked on an HttpServletRequest object. For example:

               Object username = req.getAttribute("DACS_USERNAME");
               out.println("roles = " + req.getAttribute("DACS_ROLES"));

OPTIONS

       In addition to the standard dacsoptions[1], dacs_acs recognizes the following arguments:

       -dcc
           Disable the mod_auth_dacs[3] compatibility check. Use with care, normally only for
           testing and debugging.

       -proxy-static
           Reserved for future use.

       -proxy-exec
           Reserved for future use.

       -test
           Perform some self-tests, then exit. A non-zero exit status means an error occurred. If
           -test is the only argument (recommended), no configuration is necessary; otherwise,
           normal configuration processing will be performed before the self-tests.

   The DACS_ACS Argument
       Various aspects of the behaviour of dacs_acs can be controlled by an optional argument
       named DACS_ACS. This argument, which may be passed to any web service, is interpreted by
       dacs_acs rather than the web service that is being invoked. The value of this argument is
       parsed as a list of space-separated command line flags.

           Tip
           The space character(s) must be properly escaped; e.g., as %20 or +.

       One use of this feature is when an application or middleware would like to know whether
       DACS will grant or deny a service request without having to actually execute the service
       request. When building a menu, for instance, an application might want to exclude items
       involving service requests that would be denied to the user.  dacs_acs provides this
       capability.

       To check whether access would be granted or denied, the application invokes the
       DACS-wrapped service or resource exactly as it would normally except that it provides the
       DACS_ACS argument. In some situations, if access would be denied dacs_acs will return an
       indication of what must be done; e.g., the user must authenticate or a notice must be
       acknowledged. There can be multiple reasons for denying access, in which case an
       application may have to repeatedly request a check and address the reason for denial
       before access may be granted.

       The DACS_ACS argument can be a query argument or can appear in a message body with the
       content type application/x-www-form-urlencoded (as in the case of an HTML form submitted
       using the POST method, for example). The DACS_ACS argument may not be specified more than
       once. It is not always possible to escape this argument (see -invisible[62]).

       The following flags are recognized:

       -check_only
           The presence of this flag tells dacs_acs not to actually execute the web service or
           return the resource, but to merely return the access control decision. This flag and
           the -check_fail flag are mutually exclusive.

           If the access check was performed, HTTP status code 200 (OK) will be returned; any
           other result indicates that the check could not be executed (e.g., due to an Apache
           configuration problem or a DACS error). If the check is performed, a DACS-Status-Line
           HTTP extension header is included in the response by default (see below).

           The default response consists of a single line of text that gives the result. This
           line consists of a three decimal digit result code, followed by a space, an
           explanatory message, and a newline character; for example,

               797 Access denied
               798 Access granted
               799 Access error

           Inspecting the result code is sufficient to obtain the outcome of the check. Any
           Apache ErrorDocument[63] directive for "error-code" 200 is overridden. The -format
           flag (see below) can be used to select a different output format.

               Note
               The service or resource in question does not have to exist for dacs_acs to grant
               access; for instance, this can happen if a wildcard rule pattern is used. Also,
               keep in mind that access control rules can be written to be highly context
               specific. The result of a test for a particular resource need not be the same an
               instant later (access control rules can depend on the current date or time, for
               instance).

               Rules can be written such that their evaluation results in persistent changes; for
               example, a database might be updated. These kinds of changes will occur both in
               normal operation and when only checking access.  dacs_acs defines the variable
               ${DACS::ACS} only during the testing mode of operation so that, if necessary,
               rules can be written to differentiate between testing mode and normal operation.

       -check_fail
           This flag is like the -check_only flag, except if access is granted the request is
           allowed to proceed. If access is not granted and HTTP status code 200 is returned, a
           DACS-Status-Line HTTP extension header is included in the response by default (see
           below). The -check_fail flag is useful in situations where a -check_only test that
           indicates that access would be granted is always immediately followed by the actual
           request. This flag and the -check_only flag are mutually exclusive.

       -format fmt
           By default, the -check_only flag (and in the case where access is denied, also the
           -check_fail flag) results in a single line of text being output (equivalent to
           "-format text"). If more detail is required, an XML description can be produced by
           specifying any of the XML output formats. Refer to XML Output[64], the FORMAT CGI
           argument[65], and the -format[66] command line argument.

       -rname rname
           The string rname, which is assumed to be the name of an Rlink, is made available
           available as ${Args::RNAME} during evaluation of ACS_PRE_AUTH[67] directive
           expressions.

       -status_line
       -no-status_line
           The -status_line flag enables the DACS-Status-Line[68] header, overriding the setting
           of the STATUS_LINE[69] configuration directive. The -no_status_line flag always
           suppresses this header, regardless of the STATUS_LINE[69] directive and the
           -check_only and -check_fail flags.

       -visible
       -invisible
           If the DACS_ACS argument is passed as a query argument, the default behaviour is to
           delete it so that it cannot be seen after access control processing grants access.
           This deletion is explicitly enabled by the -invisible flag and disabled by the
           -visible flag. If DACS_ACS is not deleted, it will be passed to an invoked program and
           might affect subsequent processing.

               Important
               Deletion of the DACS_ACS argument is currently possible only if it is passed as a
               query argument.
           For example, consider the hypothetical URL:

               https://example.com/cgi-bin/myprog?DACS_ACS=-check_fail+-visible&foo=baz

           If the CGI program myprog is executed, it will not only see the foo=baz argument, but
           also the DACS_ACS=-check_fail+-visible argument, and this could trigger an error or
           incorrect behaviour when myprog processes it.

           All DACS web services ignore a DACS_ACS argument, however, so its presence will not
           affect them.

       The flag list is processed from left to right. Any flag may be repeated, with the value of
       a later occurrence overriding an earlier one. If some part of the DACS_ACS argument is
       invalid, the initial, valid part will still be effective; e.g., if the initial part is
       -format XML, the output format will be XML.

       dacs_acs removes the DACS_ACS argument from the rule-processing environment so as not to
       disturb access control processing.  DACS credentials may accompany the service request
       just as they would a real request and are incorporated into the check.

       Assuming the target resource is DACS-wrapped, instead of returning the resource, accessing
       the following URL would return an indication of whether an actual request to access the
       resource would be granted or denied:

           % dacshttp -v -v \
            'https://dacs.dss.ca/cgi-bin/dacs/dacs_version?DACS_ACS=-check_only%20-format+xml'

       The DACS-Status-Line header
           When the DACS_ACS=-check_only argument is present, the response from DACS includes an
           extension header named DACS-Status-Line. The format of this extension header follows
           that of the HTTP Status-Line (RFC 2616[32], section 6.1):

               DACS-Status-Line = "DACS-Status-Line" ":" DACS-Version SP ACS-Status-Code
                 SP Reason-Phrase CRLF

           Where:

               DACS-Version = "DACS-" Version

           and Version is the DACS_VERSION_RELEASE string (e.g., 1.4.8b), and where:

               ACS-Status-Code = "797" | "798" | "799"

           The status code 797 means that DACS denies access, 798 means that it grants access,
           and 799 means that an error occurred during processing.

           Here are some examples:

               DACS-Status-Line: DACS-1.4.8b 797 Access denied
               DACS-Status-Line: DACS-1.4.8b 798 Access granted
               DACS-Status-Line: DACS-1.4.8b 799 Access error

           The reason phrases in the examples are only recommendations; they may be replaced by
           local equivalents without affecting the protocol.

               Note
               The reason phrase may include additional information, such as an audit identifier
               that can be used to track the request in the DACS logs:

                   DACS-Status-Line: DACS-1.4.10 798 Access granted, unauth user (j10OXL2Z)

           This header is also returned when -check_fail is requested, but only if access is not
           granted.

       The DACS_APPROVAL environment variable
           If enabled by the ACS_EMIT_APPROVAL[70] directive, the DACS_APPROVAL environment
           variable will be passed to a DACS-wrapped program. If the program cares to verify that
           its execution has been authorized, it may validate the approval's signature (to ensure
           that the approval has not been forged) and validate the stamp (to ensure that the
           approval is not being replayed). If a man-in-the-middle attack is of concern,
           end-to-end encryption should always be used.

           With proper configuration, this feature can be used by a web-based program that is not
           DACS-wrapped but for which authorization has been obtained indirectly. For example,
           when dacs_uproxy(8)[71], invokes a program, dacs_uproxy will forward the value of
           DACS_APPROVAL (when available) to the invoked program, which can obtain the value in
           its HTTP_DACS_UPROXY_APPROVAL environment variable. If it is able to validate the
           value (or can trust it), the invoked program knows that its execution was authorized
           by DACS, even though DACS may not be configured or even installed on the host where
           the invoked program runs.

           A jurisdiction's cryptographic keys, identified by the virtual filestore item type
           jurisdiction_keys, must be configured so that the approval can be digitally signed.

           The value of DACS_APPROVAL has the following format:

               a="dacs64-approval-message", s="dacs64-signature"

           The dacs64-approval-message is a dacs64[35] encoded string, described below. The
           dacs64-signature is the dacs64 encoded RSA signature of the approval message, which is
           the unencoded dacs64-approval-message.

           An approval message has the following format:

               j="jurisdiction-name"<newline>
               h="digest-name"<newline>
               s="stamp"<newline>
               u="uri"<newline>
               m="method"<newline>
               i="ident"

           Here, jurisdiction-name is the name of the jurisdiction (including its federation
           name) that generated the approval. The name of the message digest (secure hash)
           algorithm used to sign the approval is digest-name. The unique stamp is stamp (as
           generated by ustamp()[72]) and the URI, including any query component, is uri. The
           HTTP method is method. The DACS identity of the user for which access was granted is
           ident (or "unauth", if none). The stamp and method are mapped to lowercase. Here is an
           example of an approval message:

               j="DSS::DSS-dacs"
               h="SHA1"
               s="1185565675:130",
               u="http://example.com/cgi-bin/dacs/dacs_current_credentials?FORMAT=HTML"
               m="get"
               i="unauth"

           The RSA signature is computed using the jurisdiction's private key and SHA-1 (by
           default) over the approval message. A different message digest algorithm can be used
           by setting the configuration variable ${Conf::dacs_approval_digest_name} (see
           digest()[73] for information about message digest algorithms):

               EVAL ${Conf::dacs_approval_digest_name} = "SHA256"

DIAGNOSTICS

       The program exits 0 if everything was fine, 1 if an error occurred.

NOTES

       It ought to be possible to add functionality to clear or modify the Authorization header
       associated with a particular resource by recognizing an argument much like -check_only.

SEE ALSO

       dacsacl(1)[45], dacscheck(1)[2], dacs.acls(5)[4], dacs.conf(5)[49], dacs_admin(8)[46]

BUGS

       While the DACS_ACS mechanism can be useful, it is still a kludge,

AUTHOR

       Distributed Systems Software (www.dss.ca[74])

COPYING

       Copyright2003-2016 Distributed Systems Software. See the LICENSE[75] file that accompanies
       the distribution for licensing information.

NOTES

        1. dacsoptions
           http://dacs.dss.ca/man/dacs.1.html#dacsoptions

        2. dacscheck(1)
           http://dacs.dss.ca/man/dacscheck.1.html

        3. mod_auth_dacs
           http://dacs.dss.ca/man/mod_auth_dacs.html

        4. dacs.acls(5)
           http://dacs.dss.ca/man/dacs.acls.5.html

        5. logging
           http://dacs.dss.ca/man/dacs.1.html#logging

        6. LOG_LEVEL
           http://dacs.dss.ca/man/dacs.conf.5.html#LOG_LEVEL

        7. LOG_FILTER
           http://dacs.dss.ca/man/dacs.conf.5.html#LOG_FILTER

        8. AddDACSAuth
           http://dacs.dss.ca/man/mod_auth_dacs.html#AddDACSAuth

        9. DACS_HOME
           http://dacs.dss.ca/man/dacs.conf.5.html#var_dacs_home

       10. pipe(2)
           http://www.freebsd.org/cgi/man.cgi?query=pipe&apropos=0&sektion=2&manpath=FreeBSD+10.1-RELEASE&format=html

       11. Variables Available To Rules
           http://dacs.dss.ca/man/#vars_in_rules

       12. mod_auth_dacs
           http://dacs.dss.ca/man/mod_auth_dacs.html#SetDACSAuthPostBuffer

       13. COOKIE_NAME_TERMINATORS
           http://dacs.dss.ca/man/dacs.conf.5.html#COOKIE_NAME_TERMINATORS

       14. ALLOW_HTTP_COOKIE
           http://dacs.dss.ca/man/dacs.conf.5.html#ALLOW_HTTP_COOKIE

       15. RFC 2617
           http://www.rfc-editor.org/rfc/rfc2617.txt

       16. dacs_authenticate(8)
           http://dacs.dss.ca/man/dacs_authenticate.8.html#credentials

       17. dacsrlink(1)
           http://dacs.dss.ca/man/dacsrlink.1.html

       18. redirect()
           http://dacs.dss.ca/man/dacs.exprs.5.html#redirect

       19. RLINK
           http://dacs.dss.ca/man/dacs.conf.5.html#RLINK

       20. the one used for normal rules
           http://dacs.dss.ca/man/dacs.acls.5.html#acl_files

       21. concise user identity
           http://dacs.dss.ca/man/dacs.1.html#concise_user_syntax

       22. identity element
           http://dacs.dss.ca/man/dacs.acls.5.html#elements

       23. DACS_ACS argument
           http://dacs.dss.ca/man/#dacs_acs_argument

       24. autologin(8)
           http://dacs.dss.ca/man/autologin.8.html

       25. HTTP_AUTH_ENABLE
           http://dacs.dss.ca/man/dacs.conf.5.html#HTTP_AUTH_ENABLE

       26. HTTP_AUTH
           http://dacs.dss.ca/man/dacs.conf.5.html#HTTP_AUTH

       27. Auth clause directives
           http://dacs.dss.ca/man/dacs_authenticate.8.html#auth_clause

       28. local_apache_authenticate
           http://dacs.dss.ca/man/dacs_authenticate.8.html#local_apache_authenticate

       29. ACS_ERROR_HANDLER
           http://dacs.dss.ca/man/dacs.conf.5.html#ACS_ERROR_HANDLER

       30. AUTH_SUCCESS_HANDLER
           http://dacs.dss.ca/man/dacs.conf.5.html#AUTH_SUCCESS_HANDLER

       31. AUTH_ERROR_HANDLER
           http://dacs.dss.ca/man/dacs.conf.5.html#AUTH_ERROR_HANDLER

       32. RFC 2616
           http://www.rfc-editor.org/rfc/rfc2616.txt

       33. dacshttp(1)
           http://dacs.dss.ca/man/dacshttp.1.html

       34. passed using this request-header
           http://dacs.dss.ca/man/#http_authentication

       35. dacs.exprs(5)
           http://dacs.dss.ca/man/dacs.exprs.5.html#encode

       36. COOKIE_PATH
           http://dacs.dss.ca/man/dacs.conf.5.html#COOKIE_PATH

       37. COOKIE_NO_DOMAIN
           http://dacs.dss.ca/man/dacs.conf.5.html#COOKIE_NO_DOMAIN

       38. COOKIE_HTTP_ONLY
           http://dacs.dss.ca/man/dacs.conf.5.html#COOKIE_HTTP_ONLY

       39. dacs.install(7)
           http://dacs.dss.ca/man/dacs.install.7.html#configure_options

       40. ACS_ACCESS_TOKEN_ENABLE
           http://dacs.dss.ca/man/dacs.conf.5.html#ACS_ACCESS_TOKEN_ENABLE

       41. ACS_ACCESS_TOKEN_LIFETIME_LIMIT
           http://dacs.dss.ca/man/dacs.conf.5.html#ACS_ACCESS_TOKEN_LIFETIME_LIMIT

       42. ACS_ACCESS_TOKEN_LIFETIME_SECS
           http://dacs.dss.ca/man/dacs.conf.5.html#ACS_ACCESS_TOKEN_LIFETIME_SECS

       43. dacs.acls(5)
           http://dacs.dss.ca/man/dacs.acls.5.html#acl_syntax

       44. tail matching
           http://dacs.dss.ca/man/dacs.acls.5.html#tail_matching

       45. dacsacl(1)
           http://dacs.dss.ca/man/dacsacl.1.html

       46. dacs_admin(8)
           http://dacs.dss.ca/man/dacs_admin.8.html

       47. revocation list
           http://dacs.dss.ca/man/dacs.acls.5.html#revocation_list

       48. dacs_acs.dtd
           http://dacs.dss.ca/man/../dtd-xsd/dacs_acs.dtd

       49. dacs.conf(5)
           http://dacs.dss.ca/man/dacs.conf.5.html

       50. dacs_notices(8)
           http://dacs.dss.ca/man/dacs_notices.8.html

       51. dacs.exprs(5)
           http://dacs.dss.ca/man/dacs.exprs.5.html#variables

       52. RFC 1867
           http://www.rfc-editor.org/rfc/rfc1867.txt

       53. RFC 2388
           http://www.rfc-editor.org/rfc/rfc2388.txt

       54. HTML 4
           http://www.w3.org/TR/html4

       55. ACS_POST_EXCEPTION_MODE
           http://dacs.dss.ca/man/dacs.conf.5.html#ACS_POST_EXCEPTION_MODE

       56. Rlinks
           http://dacs.dss.ca/man/#rlinks

       57. PHP
           http://www.php.net

       58. dacs_prenv(8)
           http://dacs.dss.ca/man/dacs_prenv.8.html

       59. dacs_acs(8)
           http://dacs.dss.ca/man/dacs_acs.8.html#dacs_approval

       60. mod_jk
           http://tomcat.apache.org/connectors-doc/generic_howto/quick.html

       61. Tomcat
           http://jakarta.apache.org

       62. -invisible
           http://dacs.dss.ca/man/#invisible_flag

       63. ErrorDocument
           http://httpd.apache.org/docs/2.2/mod/core.html#errordocument

       64. XML Output
           http://dacs.dss.ca/man/#XML-output

       65. FORMAT CGI argument
           http://dacs.dss.ca/man/dacs.1.html#FORMAT

       66. -format
           http://dacs.dss.ca/man/dacs.1.html#format-arg

       67. ACS_PRE_AUTH
           http://dacs.dss.ca/man/dacs.conf.5.html#ACS_PRE_AUTH

       68. DACS-Status-Line
           http://dacs.dss.ca/man/dacs_acs.8.html#dacs_status_line

       69. STATUS_LINE
           http://dacs.dss.ca/man/dacs.conf.5.html#STATUS_LINE

       70. ACS_EMIT_APPROVAL
           http://dacs.dss.ca/man/dacs.conf.5.html#ACS_EMIT_APPROVAL

       71. dacs_uproxy(8)
           http://dacs.dss.ca/man/dacs_uproxy.8.html

       72. ustamp()
           http://dacs.dss.ca/man/dacs.exprs.5.html#ustamp

       73. digest()
           http://dacs.dss.ca/man/dacs.exprs.5.html#digest

       74. www.dss.ca
           http://www.dss.ca

       75. LICENSE
           http://dacs.dss.ca/man/../misc/LICENSE