table of contents
DACS_AUTHENTICATE(8) | DACS Web Services Manual | DACS_AUTHENTICATE(8) |
NAME¶
dacs_authenticate - DACS authentication serviceSYNOPSIS¶
dacs_authenticate [dacsoptions[1]]
DESCRIPTION¶
This web service is part of the DACS suite. The dacs_authenticate web service is an authentication "driver" for DACS. When it receives a request to authenticate a user, it usually invokes one or more authentication modules, depending on its configuration. Successful authentication assigns a DACS user identity to the user and roles modules may be invoked to determine the roles with which the identity is associated; DACScredentials are generated and returned to the user. The caller of dacs_authenticate can be redirected to a configured URL, called the post-authentication handler (or just the handler), depending on whether authentication fails or succeeds. General DACS configuration directives are discussed in dacs.conf(5)[2]. Configuration directives specific to authentication are described here. DACS expressions are described in dacs.exprs(5)[3]. dacs_authenticate might be called from an HTML form (see the distribution's html/examples[4] directory for examples of simple login pages), directly through a link on a web page, indirectly by DACSHTTP Authentication[5], or from middleware. Command line authentication functionality is provided by dacsauth(1)[6]. Other authentication mechanisms are provided by dacs_auth_agent(8)[7], dacs_auth_transfer(8)[8], and dacscookie(1)[9].Authentication¶
Authentication is the procedure by which a claimed identity is confirmed. Following successful authentication, DACS credentials may be created that represent the identity. For maximum convenience and interoperability in a web environment, DACS credentials are usually encapsulated within an HTTP cookie and transmitted over a TCP/IP connection secured by SSL. Any secure method of transporting credentials can be used instead, however, such as the value of an HTTP extension-header entity-header field in a request message sent over a VPN. While dacs_authenticate provides powerful and flexible ways to combine and compose a variety of authentication methods, most DACS jurisdictions will configure only one method, or perhaps just a few methods, in simple ways. To help integrate DACS seamlessly within a web site, dacs_authenticate allows handlers to be configured. Handlers allow various exceptions to be caught and processed so that an appropriate flow of control can occur. For example, if authentication succeeds the user can be redirected to a specific page, including the one originally requested before the exception occurred. Authentication succeeds (and the user is authenticated) if and only if:•at least one Auth clause[10] has been
configured,
•the semantics of all CONTROL[11]
directives satisfy the requirements for success,
•the DACSusername[12] arrived at is
syntactically valid, and
•the identity's access has not been revoked or
denied (see dacs.acls(5)[13]).
An incorrect password, for instance, is not considered to be an error; it will
cause its Auth clause to fail but depending on the control directives that
have been configured, the user may still be successfully authenticated by some
other Auth clause. True errors are fatal and cause dacs_authenticate to
terminate without issuing credentials and possibly without invoking a handler.
If a DACS identity reauthenticates, the user agent is expected to replace
the old credentials with new ones; if re-authentication fails (e.g., the
password is incorrect), the old credentials should continue to exist. If a
user establishes multiple concurrent identities, the user agent is expected to
send all credentials with each service request in accordance with the relevant
standards. This is standard behaviour for most common web browsers.
As an efficiency measure, the authentication architecture allows an
authentication module to return roles.
Please refer to dacs(1)[14] for details about naming.
DACS credentials are cryptographically protected XML documents (
credentials.dtd[15]). They have been carefully designed to make it
extremely difficult for an attacker to generate valid credentials, modify
captured credentials to impersonate another user, or obtain greater access
rights without being detected. DACS is careful to not produce log
information or error messages that might benefit an attacker.
User agents and other software outside of DACS do not need to decrypt the
credentials and do not possess the required encryption key.
New credentials are created and returned to the user after successful
authentication. The lifetime of each set of credentials is independently
configurable, but they are intended to be fairly transitory. If a user
reauthenticates, new credentials different than previous credentials might
well be returned (e.g., with different roles).
DACS does not verify that a user's browser is configured to accept
cookies - this is the responsibility of the DACS administrator (by
supplying client-side code to test that cookies have been enabled, for
instance). Failure to accept cookies may cause some features to be unavailable
or work incorrectly. Also note that despite what DACS (or any other
program) tells a browser about the lifetime of an HTTP cookie, browsers may be
configured to impose a shorter lifetime and can delete a cookie at any time.
(Aside: Firefox 2.0.0.3 appears to show cookies that have been deleted.)
Security
All DACS jurisdictions within the same federation share an algorithm and
key to encrypt and decrypt credentials. A cryptographically secure, symmetric
encryption function, Rijndael (the Advanced Encryption Standard[20]
(AES) algorithm and Federal Information Processing Standard[21]), is
used. The same 128 bit key is used by all DACS jurisdictions. AES also
supports 192 and 256 bit key lengths and either can be configured at
build-time.
A cryptographically secure message authentication code (MAC) is employed to
detect modification of credentials. A key different from the encryption key is
used. The Keyed-Hash Message Authentication Code (HMAC, FIPS 198[22],
RFC 2104[23], RFC 4635[24], RFC 4868[25]), is employed
using the 160-bit NIST[26] secure hash standard, SHA-1 ( FIPS
180-1[27], RFC 4634[28]). In addition to SHA-1, SHA-224, SHA-256,
SHA-384, and SHA-512 ( FIPS 180-3[29]) can be used, although they must
be configured at build-time.
The AES key length and HMAC digest algorithm used by a federation can be changed
at any time, perhaps forcing some users to reauthenticate, but the same key
length and digest algorithm must be used throughout a federation.
Security
DACS can be configured to use the less secure but widely-used and
somewhat more efficient MD5 algorithm[30] instead, although it is
deprecated and it will eventually be removed.
The Netscape HTTP Cookies Specification[31] defines the syntax and
semantics of the HTTP response header that a web server sends to a client;
this syntax is used by default, but the COOKIE_SYNTAX[32]
argument can be used to request a different syntax. The Netscape format is as
follows:
DACS formulates these response headers as follows.
The NAME attribute of an authentication cookie returned to the user (e.g., by
dacs_authenticate) has the following format:
where federation-name is the official name assigned to the federation for
which the cookie is valid, jurisdiction-name is the name of the
authenticating jurisdiction, and username is the authenticated name of
the user. If the jurisdiction-name is omitted, the username must
also be omitted. Semicolons, commas, and whitespace within the name must be
URL-style encoded. Colons are not allowed in any of the name components. Here
is an example of a cookie name:
The VALUE attribute of a cookie is a printable text encoding of credentials.
Security
The value of the domain attribute associated with the cookie is dependent on the
uniform domain name scheme chosen for the jurisdictions. The value will be
configured to be the most specific tail string that tail matches all
participating domain names. For example, if the uniform domain name scheme has
hostnames of the form xxx.example.com, yyy.example.com, and zzz.example.com,
then the value of the attribute will be example.com. This will ensure that the
user agent sends the cookie with any service request directed to a hostname
ending in example.com.
Tip
The HTTP cookie specifications appear to say that a cookie having a domain
attribute of example.com should not be sent to a host of the same name,
yet both Mozilla and IE (and perhaps other browsers) do just that. Without
this behaviour, it would not be possible to use a single domain name with
multiple DACS jurisdictions below it; that is, given
domain=example.com, it is expected that jurisdictions can be identified by URI
path prefixes such as example.com/metalogic, example.com/test, and so on.
When operating securely (see the SECURE_MODE[35] directive in
dacs.conf(5)[2]) or when an authentication request is sent over SSL,
the secure attribute will be present so that the cookie will only be
transmitted if the communications channel with the host is a secure one. At
present, browsers define this to mean that secure cookies will only be sent to
HTTPS (HTTP over SSL) servers.
•For DACS to operate securely,
communication between a user (or middleware) and dacs_authenticate,
which may include information such as passwords, must only be transmitted
over a secure connection (SSL).
•Communication between dacs_authenticate
(and dacsauth) and an external (not built-in) authentication module may
include information such as passwords and therefore should only be
transmitted over a secure connection (SSL) or in a way that is not subject
to eavesdropping or attack.
•For DACS to operate securely, regardless
of how they are obtained, DACS credentials must only be transmitted
over a secure connection (SSL) so that they cannot easily be captured and
reused by an attacker.
•It is unwise to configure both SSL and non-SSL
communication. Besides providing an avenue for attack, it may cause
DACS to behave strangely (e.g., infinite loops may occur because
cookies obtained over an SSL connection are not subsequently forwarded over a
non-SSL connection).
•The apparent IP address of an authenticated user,
as provided by the web server, is stored in credentials. DACS can be
configured to consider credentials to be valid only for requests that come
from that address (refer to the VERIFY_IP[16] configuration directive),
making it more difficult for an attacker to replay captured credentials.
In some environments this constraint is a good idea, but in general it is of
dubious value so enable it with care. Where a user is behind a firewall or
router that has multiple IP addresses, successive service requests might
legitimately not appear to be coming from the same address and some requests
would be denied if this constraint were enabled. In situations where
credentials are being forwarded between web services they might be rejected.
In the case of dial-up Internet access, a user might be issued credentials,
lose the connection, and be assigned a different IP address upon reconnecting;
the user would be forced to reauthenticate. Also, more than one user may be
associated with a particular IP address, as when a Network Address Translation
(NAT) facility such as natd(8)[17] is used, so the check does not
guarantee uniqueness.
•Information associated with a user's browser can
be included in credentials created for that user to make it difficult to reuse
captured credentials with a different browser. Please refer to
VERIFY_UA[18] for details.
•Credentials have a limit on their lifetime that
is independent of the lifetime of the HTTP cookie that contains them; that is,
credentials can expire without their cookie having expired, and vice versa.
Expired credentials are recognized and will not be used by DACS. Refer
to the AUTH_CREDENTIALS_DEFAULT_LIFETIME_SECS[19] configuration
directive for details.
•Passwords do not appear in any credentials and
are not stored once the user has been authenticated.
•It is forbidden to submit multiple credentials
for the same identity to DACS and such a request will trigger an
error.
Set-Cookie: NAME=VALUE; expires=DATE; path=PATH; domain=DOMAIN_NAME; secure
DACS: federation-name::[jurisdiction-name]:[username]
DACS:EXAMPLE::METALOGIC:rick@example.com
•Although DACS performs validity tests on
cookie names, middleware should not rely on cookie names for any purpose. An
apparently valid DACS cookie can easily be crafted with any value.
Also, an apparently legitimate cookie might convey expired or otherwise
invalid credentials. Middleware should use
dacs_current_credentials(8)[33] to validate an authentication cookie
and not trust cookie names.
•No expires attribute is set; this will cause the
cookie to be automatically deleted by a conforming browser when the user's
browser session ends and not made persistent (i.e., not stored on disk for use
in a subsequent browser session), closing a potential security hole.
•By default, the value of the path attribute is
"/", meaning the cookie will be sent with every request to the
domain that created the cookie, whether it is for a DACS-wrapped
service request or not. The COOKIE_PATH[34] configuration directive can
specify an alternative value. Using a more restricted path can potentially
improve security. All of the jurisdiction's DACS-wrapped services must
appear under that path, of course, or the cookie will not be sent; ideally, no
non- DACS wrapped service would appear under that path.
Web Service Arguments¶
In addition to the standard CGI arguments[36], dacs_authenticate understands the following CGI arguments. Some arguments are optional, while others are required depending on the authentication configuration. An invalid argument value will usually cause authentication to fail immediately. Unrecognized arguments are ignored. AUTH_IDThis optional argument is used with the user_sufficient
keyword (refer to the CONTROL[11] directive).
AUTH_PROMPT_VAR_PREFIX
Reserved for use by
local_pam_authenticate[37].
AUTH_TRANSID
Reserved for use by
local_pam_authenticate[37].
AUTHORIZATION
Used internally with HTTP Authentication[5].
AUXILIARY
This argument can be used to pass additional
authentication material to authentication modules.
COOKIE_SYNTAX
By default, the de facto standard Netscape HTTP
Cookies Specification[31] syntax is followed when cookies are created
(COOKIE_SYNTAX=COOKIE_NETSCAPE). The value COOKIE_EXT_NETSCAPE selects an
"extended" Netscape spec syntax (it's not the Netscape syntax but
it's not fully RFC 2109 compliant either); instead of using the expires
attribute it will use the Max-Age attribute as defined in RFC 2109[38]
and RFC 2965[39]. Attribute values are not quoted and there is no
support for the Comment field. Parameter values COOKIE_RFC2109 and
COOKIE_RFC2965 are recognized but not implemented.
Note
RFC 2109[38] and RFC 2965[39] forbid the following characters from
appearing in the value of an HTTP cookie's NAME attribute:
Additionally, the space, tab, and all US-ASCII control characters (octets 0 -
31) and DEL (127) are disallowed. As DACS currently follows only the
Netscape spec syntax in this respect, it produces cookies that are invalid
with respect to RFC 2109 and RFC 2965. While this limitation does not appear
to cause problems for web browsers, it may be noteworthy for users of some
cookie handling APIs.
DACS_AUTH_SUCCESS_HANDLER
( ) < > @ , ; : \ " / [ ] ? = { }
This argument provides a way for the caller to specify
where the user agent should be redirected after successful authentication,
regardless of whether authentication handlers are configured or enabled. If
its value is DACS_ERROR_URL and an argument by that name is present, the user
agent will be redirected to the value of that argument; otherwise, the user
agent will be redirected to the value of DACS_AUTH_SUCCESS_HANDLER. The
DACS_ERROR_URL is passed to this web service by dacs_acs(8)[40]
as part of an authentication workflow initiated by a request that is denied
because no credentials were supplied; DACS_ERROR_URL should not be
generated by any non- DACS software.
DACS_BROWSER
If an argument named DACS_BROWSER is present and
has the value 1, it signifies that the request is coming from a browser rather
than middleware. If the request comes from a browser, DACS will return
a cookie using the Set-Cookie HTTP response header, otherwise it will
not.
DACS_DEBUG
If this argument is present, the web service will produce
more detailed log information.
ENABLE_AUTH_HANDLERS
The jurisdiction's authentication handler directives are
honoured if and only if this argument is present and has the value 1.
OPERATION
This is used with the identity selection mechanism
described by dacs_select_credentials(8)[41]. If the value of this
parameter is SELECT and authentication is successful, any currently selected
credentials are deselected and the new credentials are selected.
PASSWORD
This argument is the password that corresponds to
USERNAME.
USERNAME
This argument, which is (almost) always required, is the
name provided by the user and is usually the name being authenticated. It will
not necessarily be the same as the final DACS username. For example, if
the value of USERNAME is not a syntactically valid DACS
username, the authentication procedure must transform it into something
acceptable (using the strtr()[42] function, for instance; see
dacs.exprs(5)[3]).
WWW_AUTHENTICATE
Reserved for internal use by HTTP
Authentication[5].
Auth Clause Directives¶
Each Auth clause in a DACS configuration file contains directives that describe a procedure for authenticating users. Some of these directives are common to all authentication modules, while others are understood only by a certain module; for example, LDAP_USERNAME_URL[43] is only meaningful to the local_ldap_authenticate[44] module. The general-purpose OPTION[45] directive may sometimes be used to specify an argument to an authentication module. 1.CONTROL (Required1)
2.CREDENTIALS_LIFETIME_SECS (Optional1)
3.EXIT* (Optional1)
4.EXPR (Optional1)
5.FLAGS (Optional1)
6.INIT* (Optional1)
7.OPTION (Optional)
8.OPTION* (Optional)
9.PASSWORD_AUDIT (Optional)
10.PREDICATE (Optional1)
11.STYLE (Required1)
12.URL (Optional1)
13.URL* (Optional1)
CONTROL (Required1)
This directive specifies a PAM-like control keyword that
determines what will happen if the authentication module succeeds or fails;
see pam(3)[47] and the X/Open Single Sign-On Service (XSSO)
preliminary specification[48] (page 30), from which the description of
these directives was adapted. Although this control mechanism allows for
rather complicated authentication sequences to be described, in practice
jurisdictions tend to construct fairly simple configurations. Most processing
errors (other than errors encountered by a module) are considered fatal.
The first Auth clause that appears after configuration merging (see
dacs.conf(5)[49]) is the "top" or first module in the stack,
the next one is the second module in the stack, and so on.
The value of this directive is a case-insensitive keyword that can be
abbreviated up to the indicated minimum:
CREDENTIALS_LIFETIME_SECS (Optional1)
•require[d]
•requisite
•opt[ional]
•suff[icient]
•user_suff[icient]
For example, the keywords require and required are equivalent.
The control flow of authentication module processing is as follows:
1.If a requisite module fails, authentication fails and
dacs_authenticate stops processing the module stack, returning the
error reported by the requisite module;
2.If all requisite and required modules in the stack
succeed, then authentication succeeds (any errors reported by optional,
sufficient, and user_sufficient modules are ignored);
3.If one or more required modules fail, then the error
value from the first required module that failed is returned; unlike failure
of a requisite module, processing continues;
4.If none of the modules in the stack are designated as
required or requisite, then dacs_authenticate requires that at least
one optional, sufficient, or user_sufficient module succeed. If all fail, then
the error value from the first module in the stack is returned;
5.The first exception to the above is caused by the
sufficient keyword. If a module that is designated as sufficient succeeds,
then dacs_authenticate immediately returns success (all subsequent
modules are ignored, even required and requisite ones), given that all prior
required and requisite modules have also succeeded. If a prior required module
failed, then the error value from that module is returned;
6.The second exception to the above involves the
user_sufficient keyword, which enables at most one user_sufficientAuth clause
and disables all other user_sufficient andsufficientAuth clauses. This
control simplifies configuring user-selectable authentication methods. Note
that this mechanism will necessarily reveal additional information about a
jurisdiction's authentication configuration.
If the AUTH_ID argument is not given, then all Auth clauses with
the user_sufficient control are disabled - none of their directives are
evaluated - and any sufficient controlled clauses are processed normally. If
the AUTH_ID is present, then only an Auth clause with a user_sufficient
control and an exactly matching id attribute is used. There can be at
most one such Auth clause; all other Auth clauses having a user_sufficient
orsufficient control is disabled. In all other respects, an enabled
user_sufficientAuth clause is processed as for the sufficient control;
7.If an error occurs while processing a directive, then
dacs_authenticate fails immediately.
The lifetime, in seconds, of credentials returned after
successful authentication. This overrides the general directive of the same
name, and may in turn be overridden by setting the variable
${Auth::CREDENTIALS_LIFETIME_SECS}. Authentication will fail if this
value is invalid.
EXIT* (Optional1)
If authentication is successful, this expression is
evaluated immediately after the module's authentication processing is executed
(but refer to the FLAGS directive).
EXPR (Optional1)
This directive, which is required when STYLE is expr,
gives an expression that is evaluated to decide whether to grant credentials
and the DACS identity to use. See Authenticating Using an
Expression[50].
FLAGS (Optional1)
This directive gives control flags that are interpreted
by dacs_authenticate. Each directive consists of a whitespace-separated
list of values.
The only value currently recognized is the keyword ident.
Important
If there is more than one Auth clause, the ident flag should ordinarily be
specified in at least one of them to indicate that the username returned by
the module, if authentication is successful, is to become the
"current" username. Those Auth clauses without the ident flag will
not change the current username. After the last Auth clause is processed, the
current username is used in the resulting credentials.
The ${Auth::CURRENT_USERNAME} variable (see below) is updated only if
there is exactly one Auth clause or if the ident flag is given. This update
occurs immediately prior to execution of any EXIT* directive.
If ident is not specified in any successfully processed Auth clause (i.e., one
where authentication succeeds), the username returned by the last successfully
processed clause is used. If the ident flag is specified in one or more
successfully processed clauses, the username returned by the last such module
will be used.
INIT* (Optional1)
The given expression is evaluated immediately prior to
the URL* and EXPR expressions, all of which are evaluated before a module's
authentication processing is invoked.
OPTION (Optional)
The directive value is a name=value pair
that may be interpreted by dacs_authenticate or the authentication
module specified by the Auth clause. It causes a variable called name
to be put into the Options namespace, which only exists within the context of
the Auth clause containing this OPTION. The variables in this namespace are
passed as arguments to the authentication module. Whitespace may not precede
or follow the '=' and any quotes around the value are considered to be part of
the value. A given name may not be specified more than once within a
particular Auth clause. The Options namespace is initialized with
USERNAME, PASSWORD, AUXILIARY, DACS_JURISDICTION,
and DACS_VERSION variables. If these variables are specified by an
OPTION, the argument ordinarily used will be overridden.
For example, this directive causes SAMBA_PORT=139 to be passed as a POST method
parameter:
OPTION* (Optional)
OPTION "SAMBA_PORT=139"
The given expression is evaluated before the module is
called, and after all OPTION directives and all OPTION* directives that appear
earlier. The value of the expression must be a name=value pair,
as with the OPTION directive, and overrides any name in the Options
namespace.
PASSWORD_AUDIT (Optional)
This directive is used to audit password-type arguments
passed to authentication modules by dacs_authenticate, regardless of
the authentication method, against the criteria selected by the specified
constraint string, which is in the format used by
PASSWORD_CONSTRAINTS[51]. If any password does not meet the
requirements, a log message will be emitted (which does not include the
password itself). The message will be tagged as audit and sensitive; please
refer to the LOG_FILTER[52] directive. This feature can be used to
notify the administrator about weak passwords.
The directive value can be a variable name, which is matched exactly against the
PASSWORD or AUXILIARY arguments, or a keyword in one of the
OPTION directives within the same clause. In this form, the
PASSWORD_CONSTRAINTS directive must be configured and its value is used as the
constraint. In the second form, the directive value is a variable name as in
the first form, followed by spaces or tabs, followed by the constraint string
to use in the syntax of PASSWORD_CONSTRAINTS. Consider the following
directives:
Here, the PASSWORD argument must be at least ten characters long but
AUXILIARY must only be eight characters long and include an upper case
character and punctuation.
Note
Not all authentication modules require a PASSWORD argument, such as
local_cas_authenticate[53] in its interactive mode. This directive is
ignored if the argument is not passed to the module.
PREDICATE (Optional1)
PASSWORD_CONSTRAINTS "8L,1C,1P" <Auth id="auth1"> URL "https://foo.example.com/cgi-bin/dacs/local_woof_authenticate" STYLE "pass" CONTROL "sufficient" PASSWORD_AUDIT "PASSWORD 10L" PASSWORD_AUDIT "AUXILIARY" </Auth>
If provided, this expression is evaluated before any
other authentication module processing is done. If there is an evaluation
error or it returns False (zero or the empty string), processing
continues just as if the module were run and indicated that authentication
failed. Otherwise, processing of the clause continues normally.
This directive provides a way to effectively enable or disable a module based on
run time context. This can be used to configure layered authentication or
risk-based authentication because a predicate can examine various aspects of
an authentication request, such as the USERNAME, current date and time,
IP address from where the request originates, and so on.
STYLE (Required1)
Each authentication module implements one or more
authentication styles. The value of the STYLE directive is a comma-separated
list of case-insensitive style names and style options; the order is
insignificant. No whitespace is allowed. Keywords can be abbreviated up to the
indicated minimum.
cas
passwd
URL (Optional1)
This style selects username/password authentication using
the Central Authentication Service (CAS)[54] protocol through the
local_cas_authenticate[53] authentication module.
cert[ificate]
An X.509 client certificate, obtained from the SSL layer,
will be provided for authentication. The request must be sent using SSL and
the client certificate must be provided by Apache through the
SSL_CLIENT_CERT environment variable.
digest
This selects the RFC 2617[55] Digest Access
Authentication scheme as implemented by DACS in conjunction with the
local_apache_authenticate[56] authentication module. See HTTP
Authentication[5].
expr
No authentication module will be used; expression
evaluation[50] will be used instead.
infocard
A self-issued or managed Information Card[57]
(InfoCard) must be provided for authentication. To be recognized, the InfoCard
must have been previously registered at this jurisdiction using
dacsinfocard(1)[58], dacs_infocard(8)[59], or
dacs_managed_infocard(8)[60]. This style is implemented by the
local_infocard_authenticate[61] authentication module.
managed_infocard
A managed Information Card[57] (InfoCard) must be
provided for authentication. To be recognized, the InfoCard must have been
previously registered at this jurisdiction using
dacs_managed_infocard(8)[60]. This style is implemented by the
local_infocard_authenticate[61] authentication module.
nat[ive]
The user is expected to have already authenticated
through the web server's native authentication mechanism (e.g., HTTP Basic or
Digest authentication); DACS will import this identity without any
additional requirements. The AUTH_TYPE environment variable but be
available and have the value Basic or Digest (case insensitive), and the
REMOTE_USER environment variable must be set.
pass[word]
The username must be provided through a USERNAME
argument and the password must accompany the authentication request through a
PASSWORD argument.
prompt[ed]
A dialog-based interaction will be conducted, such as one
based on Pluggable Authentication Modules (PAM). See
local_pam_authenticate.
selfissued_infocard
A self-issued Information Card[57] (InfoCard) must
be provided for authentication. To be recognized, the InfoCard must have been
previously registered at this jurisdiction using dacsinfocard(1)[58] or
dacs_infocard(8)[59]. This style is implemented by the
local_infocard_authenticate[61] authentication module.
simple
This style of authentication merely requires a recognized
username, provided through a USERNAME argument and therefore offers
little security. Still, it can be used in appropriate situations to
authenticate a user that can provide a valid account name, which might be a
membership number or randomly generated (and perhaps hard to guess) username.
If a PASSWORD argument is provided, it is logged as sensitive data,
much as an anonymous FTP password might be logged. This style is implemented
by the local_simple_authenticate[62] authentication module.
set_roles
If the authentication module returns roles, this style
modifier says that they should override any other roles currently in effect
and no roles module should be executed. This option may appear at most once
among all Auth clauses and only if add_roles[63] is not used.
add_roles
If the authentication module returns roles, this style
modifier says that they should be appended to any other roles currently in
effect. Any configured roles modules will still be executed. This option may
be repeated in other Auth clauses but may not appear if the
set_roles[64] option also appears.
Exactly one of these two directives must be specified,
except when STYLE is expr, where neither directive is used. These directives
specify the URL to be used to invoke the authentication module; use of an
absolute URL is recommended.
The difference between the two directives is that the value of URL* is an
expression that is evaluated immediately before the module is invoked to
determine the URL to be used.
In the current implementation, the standard set of modules must run within the
context of a DACS jurisdiction. This is not an architectural
limitation, however.
Tip
Some authentication modules are available as built-in components of
dacs_authenticate and dacsauth. These modules are identified by
specific relative URLs; a module's description will provide its built-in name
when this capability is available. The built-in capability will automatically
be provided if the module has been enabled at build-time.
Although it will be more efficient (and possibly more secure) to use a built-in
module, they are executed on the same host as dacs_authenticate thereby
giving up some flexibility because access control rules are not applied to
them (other than the one for dacs_authenticate), and
dacs_authenticate may need to be executed setuid root or setgid www so
that it can access password files. The same applies for dacsauth.
Here is an example of a configuration that will authenticate using Unix user
names and passwords:
<Auth id="passwd"> URL "https://foo.example.com:8443/cgi-bin/dacs/local_unix_authenticate" STYLE "pass" CONTROL "sufficient" </Auth>
<Auth id="passwd"> URL "https://foo.example.com:8443/cgi-bin/dacs/local_unix_authenticate" STYLE "pass" CONTROL "sufficient" </Auth> <Auth id="passwd2"> URL "https://foo2.example.com/cgi-bin/dacs/local_passwd_authenticate" STYLE "pass" CONTROL "sufficient" </Auth>
<Auth id="passwd"> URL "https://foo.example.com:8443/cgi-bin/dacs/local_unix_authenticate" STYLE "pass" CONTROL "sufficient" PREDICATE '${Args::AUXILIARY} ne "guest"' </Auth> <Auth id="passwd2"> URL "https://foo2.example.com/cgi-bin/dacs/local_passwd_authenticate" STYLE "pass" CONTROL "sufficient" PREDICATE '${Args::AUXILIARY} eq "guest"' </Auth>
# For AUTH_ID=google <Auth id="google"> URL "local_http_authenticate" STYLE "password" CONTROL "user_sufficient" OPTION 'AUTH_URL="https://www.google.com/accounts/ClientLogin"' OPTION 'AUTH_METHOD=POST' OPTION 'USERNAME_PARAMETER="Email"' OPTION 'PASSWORD_PARAMETER="Passwd"' OPTION 'service=xapi' OPTION "source=DSS-DACS-1.4" </Auth> # For AUTH_ID=ntlm <Auth id="ntlm"> URL "local__ntlm_authenticate" STYLE "password" CONTROL "user_sufficient" OPTION 'SAMBA_SERVER="samba.example.com"' OPTION 'SAMBA_PORT="139"' EXIT* '${Auth::CURRENT_USERNAME}=strtr(${Auth::CURRENT_USERNAME}, "a-z", "A-Z")' </Auth> # For AUTH_ID=passwd <Auth id="passwd"> URL "local_passwd_authenticate" STYLE "password" CONTROL "user_sufficient" </Auth>
Initialization and the Auth Namespace¶
dacs_authenticate uses a variable namespace called Auth to make authentication-related context available to its configuration directives (see dacs.exprs(5)[65]). Aspects of dacs_authenticate's behaviour can be controlled by modifying these variables. This namespace disappears when dacs_authenticate terminates. The next section describes how these variables are used. Additionally, all environment variables are accessible through the Env namespace (e.g., ${Env::REMOTE_ADDR}) during authentication processing.Authentication Clause Control Flow¶
Auth clauses are processed in the order in which they appear in the configuration file, subject to the semantics of the CONTROL directives. dacs_authenticate is typically configured so that the last thing it does is to redirect its caller to an appropriate web page. If authentication is successful, any AUTH_SUCCESS[66] expression is evaluated and the AUTH_SUCCESS_HANDLER[67] directive is consulted; if authentication fails, the AUTH_ERROR_HANDLER[68] and AUTH_FAIL_DELAY_SECS[69] directives are used. This behaviour is partially under the control of the caller through the DACS_AUTH_SUCCESS_HANDLER[70] and ENABLE_AUTH_HANDLERS[71] arguments, however.AUTH_SUCCESS_HANDLER "url /cgi-bin/dacs/dacs_prenv"
1.If the clause has a PREDICATE directive, it is
evaluated in the current context. If the value is not True (including
cases where the expression was invalid), processing of the clause terminates
immediately with the same result as if its authentication had been
unsuccessful.
2.If a variable named ${Auth::ABORT} has the
value yes (case insensitive), authentication terminates. If the variable
${Auth::MODULE_SKIP} has the value yes (case insensitive), processing
of the clause terminates immediately with the same result as if its
authentication had been unsuccessful.
3.If the clause has an INIT* directive, it is evaluated;
if an error occurs, authentication terminates.
4.If the clause has a URL directive, it names the
authentication module to be invoked (or is the name of a built-in module).
If the URL* directive is used instead, it is evaluated to obtain the URL to be
invoked; if an error occurs, authentication terminates.
5.If a variable named ${Auth::ABORT} has the
value yes (case insensitive), authentication terminates. If the variable
${Auth::MODULE_SKIP} has the value yes (case insensitive), processing
of the clause terminates immediately with the same result as if its
authentication had been unsuccessful.
6.If the clause's STYLE is expr, the EXPR directive is
evaluated and is expected to either return False or a valid DACS
username. If the expression's value is False, processing of the clause
terminates immediately with the same result as if its authentication had been
unsuccessful; if its value is an invalid username, authentication terminates,
otherwise the module is deemed to have been successful. If an error occurs,
authentication terminates.
If the clause's STYLE is not expr, the authentication module is invoked.
7.If an error occurs while executing the authentication
module, authentication terminates. If the authentication module does not
authenticate the user, the CONTROL directive determines whether authentication
fails or continues.
The username passed to the module, or returned by the module, becomes the
tentative DACS username and the variable
${Auth::CURRENT_USERNAME} is set to it. If the variable
${Auth::ROLES} is set to a valid role descriptor, it becomes the
current tentative roles for the user.
8.The expression given by the EXIT* directive, if any,
is evaluated. If an error occurs, authentication terminates. The expression
may update ${Auth::CURRENT_USERNAME}. For instance, the directive:
completely ignores the username returned by the module and simply assigns one,
while this directive:
converts all upper case characters in the username returned by the module to
their lower case equivalents.
EXIT* '${Auth::CURRENT_USERNAME}="bobo"'
EXIT* '${Auth::CURRENT_USERNAME} = \ strtr(${Auth::CURRENT_USERNAME}, "A-Z", "a-z")'
9.If a variable named ${Auth::ABORT} has the
value yes (case insensitive), authentication terminates despite success of the
module. If the variable ${Auth::MODULE_SKIP} has the value yes (case
insensitive), processing of the clause terminates immediately with the same
result as if its authentication had been unsuccessful.
The value of ${Auth::CURRENT_USERNAME} when the last module has been
processed is the username that will be assigned to a successfully
authenticated user. If set, the value of
${Auth::CREDENTIALS_LIFETIME_SECS} will be used as the lifetime of the
generated credentials; if not set, the value returned by the last successful
authentication module is used (typically that of the module's
CREDENTIALS_LIFETIME_SECS directive), if available, or the jurisdiction's
CREDENTIALS_LIFETIME_SECS directive's value.
Authenticating Using an Expression¶
Rather than using an authentication module, the expr style of authentication involves evaluating an expression. The value of the expression is the DACS username to associate with the user. If no value is returned, an invalid value is returned, or an error occurs, the Auth clause fails. Here is a simple example that is unlikely to be used in practice. If the PASSWORD argument is "xyzzy", then authentication will succeed and the user will be assigned the DACS username bobo.<Auth id="expr1"> STYLE "expr" CONTROL "sufficient" EXPR '${Args::PASSWORD} eq "xyzzy" ? "bobo" : ""' </Auth>
<Auth id="expr5"> STYLE "expr" EXPR '${pwd} = get("/usr/local/dacs/pwd/pwd." . ${Args::USERNAME}); \ digest(${Args::PASSWORD}, 0, sha256) eq decode(hex, ${pwd}) \ ? ${Args::USERNAME} : ""' CONTROL "sufficient" </Auth>
<Auth id="expr2"> STYLE "expr,add_roles" CONTROL "sufficient" EXPR '${Auth::ROLES}="foo,bar"; ${Args::PASSWORD} eq \ "xyzzy" ? "bobo" : ""' </Auth>
<Auth id="expr3"> STYLE "expr" CONTROL "sufficient" EXPR '${Auth::SSL_CLIENT_VERIFY} eq "SUCCESS" and ${Auth::SSL_CLIENT_S_DN_Email:ei} \ ? ${Auth::SSL_CLIENT_S_DN_Email:i} : ""' </Auth>
<Auth id="expr4"> STYLE "expr" CONTROL "sufficient" EXPR '${Auth::CURRENT_USERNAME} = "user-${Env::REMOTE_ADDR}"' </Auth>
Middleware Support¶
As with most DACS web services, the FORMAT argument can be used to request a particular type of output (see dacs.services(8)[75]) from dacs_authenticate. If any XML type is specified, the reply from dacs_authenticate will conform to the DTD dacs_auth_reply.dtd[76]. The reply indicates whether the user has been successfully authenticated or not. If authentication was successful, a description of the new credentials is returned as a dacs_current_credentials element, (as described by dacs_current_credentials.dtd[77]). If authentication was unsuccessful because of a transient error condition, a reason may optionally be provided.Authentication Modules¶
•As a security measure, these modules should be
executable only by dacs_authenticate, which is the default.
•By default, access control rules are configured
to restrict access to all authentication and roles modules. This prevents an
attacker from calling an authentication module directly in an attempt to guess
account names, passwords, and so on.
•Modules may need to be installed setuid or setgid
as appropriate so that it is possible for them to read the password files that
they require or obtain encryption keys.
•Modules may need to be installed setuid or
setgid, and never run as the UID of a less-privileged user, so that it is
impossible to circumvent the module's functionality (e.g., by attaching to the
running module with a debugger).
The value of the AUXILIARY argument to
dacs_authenticate if one was given, otherwise the empty string.
DACS_JURISDICTION
The value of the DACS_JURISDICTION argument to
dacs_authenticate.
DACS_VERSION
The DACS_VERSION_NUMBER for this version of
dacs_authenticate.
PASSWORD
The value of the PASSWORD argument to
dacs_authenticate if one was given, otherwise the empty string.
USERNAME
The value of the USERNAME argument to
dacs_authenticate.
Directives
Each directive in the Auth section being processed and
its value is passed.
SSL environment variables
Each SSL environment variable passed to
dacs_authenticate is passed.
Transaction state data
With respect to the prompted style of authentication,
transaction state variables are passed.
Ordinarily, a particular argument may not appear more than once.
Authentication Module Index:
1.local_apache_authenticate: Password-protected accounts
maintained by Apache utilities
2.local_cas_authenticate: Central Authentication Service
(CAS)
3.local_cert_authenticate: SSL-based X.509 client
certificates
4.local_grid_authenticate: Grid-based one-time
passwords
5.local_http_authenticate: Generic authentication via
HTTP
6.local_infocard_authenticate: Information Card-based
accounts and identities
7.local_ldap_authenticate: Lightweight Directory Access
Protocol (LDAP) / Microsoft Active Directory
8.local_native_authenticate: Importing an identity
established by Apache
9.local_ntlm_authenticate: Microsoft Windows NT LAN
Manager usernames and passwords
10.local_pam_authenticate: Pluggable Authentication
Modules (PAM)
11.local_passwd_authenticate: Password-protected
DACS accounts
12.local_simple_authenticate: Account name without a
password
13.local_token_authenticate: One-time passwords,
two-factor authentication
14.local_unix_authenticate: Unix usernames and
passwords
The local_apache_authenticate module is used to authenticate against
password files used by the Apachemod_auth[80],
mod_auth_digest[81], or mod_auth_dbm[82] modules.
These password files are managed by Apache'shtpasswd(1)[83],
htdigest(1)[84], and htdbm(1)[85] utilities, respectively. An
administrator can configure DACS to use an existing htpasswd file, for
instance, and so avoid dealing with creating and managing a duplicate set of
usernames and passwords.
If Basic authentication is used, the STYLE should be password. If Digest
authentication is used, because no password is passed to DACS, the
STYLE for this module should be configured as digest.
The following configuration options are recognized by this module. They should
be provided using the OPTION directive.
AUTH_MODULE
Notes
Here is an example configuration that uses an htpasswd-managed file for
authentication:
If the passwords were kept in a Berkeley DB database instead, the configuration
might look like:
This example configuration is similar; the difference is that the username and
password obtained through HTTP Basic authentication are verified against a
Unix account:
This example configures HTTP Digest authentication and references an
htdigest-managed file:
Tip
A built-in version of this module can be selected by using the URL
local_apache_authenticate or just apache.
This must be "mod_auth" (or
"htpasswd"), "mod_auth_digest" (or "htdigest"),
or "mod_auth_dbm" (or "htdbm"), depending on which
module's authentication method is to be used. This value is
case-insensitive.
AUTH_FILE
This is the absolute pathname of the flat-file or
database file to use.
Note
This pathname is resolved on the host that runs this module. This should
eventually be extended to accept a DACS virtual filestore URI.
DBM_TYPE
Required only in conjunction with mod_auth_dbm
compatibility, this argument identifies the database format of AUTH_FILE. The
names "sdbm" (not yet implemented), "gdbm",
"ndbm", and "db" are recognized, although not all types
may be available on a particular platform.
•This module does not rely on any Apache
module (other than mod_auth_dacs).
•This module does not require any Apache
configuration with respect to authentication; only DACS needs to be
configured.
•It is not necessary to use DACS'sHTTP
Authentication[5] feature in order to use this module. For example, using
Basic authentication, the USERNAME and PASSWORD arguments can be
submitted from a site's login page and verified by this module against an
htpasswd file.
•htpasswd allows plaintext passwords to be
stored in a password file, although httpd apparently restricts the use
of these passwords. This module imposes no such restrictions. Under normal
circumstances passwords should not be stored in plaintext form.
•The major difference between this module and
local_native_authenticate[86] is that the latter "imports" an
identity already established by an Apache authentication module,
whereas this module authenticates using information that can also be used by
Apache and which is administered using Apache utiltities.
•DACS will access Apache password
files in read-only mode only; DACS never modifies those files.
•Some platforms may not support all possible
DBM-type databases and some types of database may not have been configured at
build-time.
HTTP_AUTH_ENABLE "yes" HTTP_AUTH "Basic \"DACS Basic Auth Area\" /restricted/*" <Auth id="apache-htpasswd"> URL "https://example.com/cgi-bin/dacs/local_apache_authenticate" STYLE "pass" CONTROL "sufficient" OPTION "AUTH_FILE=/usr/local/apache2/conf/passwords" OPTION "AUTH_MODULE=mod_auth" </Auth>
HTTP_AUTH_ENABLE "yes" HTTP_AUTH "Basic \"DACS Basic Auth Area\" /restricted/*" <Auth id="apache-htpasswd"> URL "https://example.com/cgi-bin/dacs/local_apache_authenticate" STYLE "pass" CONTROL "sufficient" OPTION "AUTH_FILE=/usr/local/apache2/conf/passwords.db" OPTION "AUTH_MODULE=mod_auth_dbm" OPTION "DBM_TYPE=db" </Auth>
HTTP_AUTH_ENABLE "yes" HTTP_AUTH "Basic \"DACS Basic Auth Area\" /private/*" <Auth id="basic"> URL "https://example.com/cgi-bin/dacs/local_unix_authenticate" STYLE "pass" CONTROL "sufficient" </Auth>
HTTP_AUTH_ENABLE "yes" HTTP_AUTH "Digest \"DACS Digest Auth Area\" /digest/*" <Auth id="apache-htdigest"> URL "apache" STYLE "digest" CONTROL "sufficient" OPTION "AUTH_FILE=/usr/local/apache2/conf/passwords.digest" OPTION "AUTH_MODULE=mod_auth_digest" </Auth>
This module coordinates with a specified Central Authentication Service
(CAS)[54] server to authenticate a user that is purportedly known to that
server. The module implements the client side of the CAS 2.0
Protocol[87] and can be used in two different modes: interactive and
non-interactive.
Interactive mode is employed if neither a USERNAME nor a PASSWORD
argument is given to dacs_authenticate. When dacs_authenticate
is called, whether directly or as the result of redirection after access was
denied to an unauthenticated user, it redirects the user to a CAS login page.
After successful CAS authentication (which may return a ticket granting cookie
to the user's browser), CAS redirects the user to dacs_authenticate,
passing it the CAS session ticket as an argument called ticket. After
successfully validating the session ticket at the CAS server, DACS
authentication succeeds.
Security
When interactive mode is used, DACS does not see the username and
password, only CAS does. The username is obtained by the module as part of the
session ticket validation protocol. This mode of operation is similar to, but
simpler than, the OpenID[88] Authentication protocol.
A variant of this flow of control can occur if the user has authenticated
against the CAS server outside of DACS and therefore holds a ticket
granting cookie. This cookie will automatically be sent by the user's browser
when it is redirected to the CAS server; as a result, the CAS server may not
prompt the user to authenticate.
In non-interactive mode, both a USERNAMEand a PASSWORD
argument are passed to dacs_authenticate. This module will use these
arguments to authenticate the user against the CAS server. In this mode, no
ticket granting cookie will be returned to the user. This mode can be used
with the DACSHTTP authentication[5] feature.
The STYLE should be configured as cas for this module.
The following module-specific OPTION directive value is understood:
CAS_SERVER_URI (Required1)
Note
The local_cas_authenticate module extends the response of the
validate service of the CAS protocol to allow a role descriptor string
( role_string) to be returned. If authentication succeeds, the standard
service returns the following text: yes\n username\n.PP This module
understands a third line, which is optional: yes\n
username\nrole_string\n An invalid role string is discarded. If
these roles should be used, it will be necessary to use either the
set_roles[64] or add_roles[63] style modifier with the
STYLE[89] directive.
Tip
The authentication procedure described by the CAS protocol is notable because
the authentication material provided by the user in interactive mode does
not flow through DACS; in particular, DACS does not
see a user's password when this module is used. This may be an important
consideration in some environments.
Because the protocol implemented by this module is general purpose and
relatively simple, writing middleware that implements a subset of the
server-side CAS protocol to interface with this module may be a sensible
solution for DACS administrators who require a CAS-like control flow
but do not want to use actual CAS server-side software. The user would be
redirected to the middleware component by local_cas_authenticate to
perform the /login service; then it would prompt and authenticate the user,
and redirect the user to a URL provided to it by
local_cas_authenticate; then local_cas_authenticate would call
the middleware component directly, this time to perform the /validate service.
The usual flow of control within DACS would follow.
A simple script for testing and working with local_cas_authenticate is
available in src/cas_middleware_test.
Tip
A built-in version of this module can be selected by using the URL
local_cas_authenticate or just cas.
This is the URI of the CAS server to authenticate
against. For example, dacs.conf might contain authentication configuration
similar to the following:
The module recognizes the following arguments (which are automatically passed to
it as necessary by dacs_authenticate):
CAS_TICKET (Required1-C)
<Auth id="CAS"> URL "cas" STYLE "cas" CONTROL "sufficient" OPTION "CAS_SERVER_URI=https://cas.example.com/castest" </Auth>
This is the session ticket returned by CAS via a callback
to dacs_authenticate (i.e., the ticket argument).
CAS_REDIRECT_ARGS (Optional1)
These are additional arguments to
dacs_authenticate that must be provided when CAS performs its callback
to dacs_authenticate to preserve user preferences. The
DACS_BROWSER, FORMAT, DACS_ERROR_URL, and
ENABLE_AUTH_HANDLERS arguments may be forwarded in this way.
CAS_SERVER_URI (Required1-C)
This argument has the value specified in the Auth
clause's OPTION directive. Note that HTTP redirects are not handled in this
context, so invoking GET on CAS_SERVER_URI must return a valid document.
The local_cert_authenticate module authenticates a user that supplies an
acceptable X.509 client certificate via SSL. Apache must be
appropriately configured to request and verify client certificates, check for
revocation, and so on (see SSLVerifyClient[90] and related directives).
As part of the SSL protocol, Apache's mod_ssl[74] module
verifies that the client possesses the private key that corresponds to the
client certificate. Apache will usually be configured to verify the
correctness and suitability of the client certificate. Apache
directives such as SSLRequire[91] might be used, for example.
The STYLE should be configured as certificate for this module.
The verification of the client certificate done by Apache may be
sufficient, in which case the only remaining configuration task for the Auth
clause is to assign a username and possibly extract role information from the
certificate; it may impose additional tests on the certificate, however, by
inspecting its fields. If verification beyond the ability of
mod_ssl[74] is required, or if it needs to be performed on a system
other than where the web server is running, local_cert_authenticate can
execute an external program to decide whether the client certificate is
suitable for authentication. This program is currently limited to
OpenSSL[92] but this may be generalized in future versions.
To ensure that local_cert_authenticate is able to obtain information
contained within the client certificate, Apache must be configured so
that StdEnvVars and ExportCertData are enabled in an appropriate
SSLOptions[93] directive, such as the following:
The following configuration directives are specific to this module:
CERT_CA_PATH (Required1)
Security
The lifetime of credentials obtained through the local authentication service
may be independent of the validity period of the certificate presented for
authentication. It is therefore possible for the certificate to expire before
the DACS credentials. The local authentication service might take this
into consideration before granting access and when computing a lifetime for
the resulting DACS credentials.
SSLOptions +StdEnvVars +ExportCertData
This is the absolute pathname of a directory that
contains trusted certificates. Refer to the -CApath argument to
OpenSSL's verify command.
CERT_DUMP_CLIENT (Optional1)
If configured, this gives the absolute pathname of a file
to which the client certificate is to be written in PEM format. The file is
created or truncated, as necessary. This is useful for debugging
purposes.
CERT_NAME_ATTR (Optional1)
If this directive is configured, it gives the name of an
SSL environment variable[73]. The value of that variable is used as a
key for the certnamemap item type (which must also be configured); the key's
value becomes the username returned by the module (if the environment variable
is not found or the lookup is unsuccessful, the module will fail to
authenticate the user). If the module is not fully configured for this lookup,
the value of the USERNAME is returned by the module.
To illustrate this, consider the following configuration:
with the file /usr/local/dacs/federations/certnamemap containing the two lines:
Given the configuration above, if the value of the SSL_CLIENT_S_DN_CN
environment variable is "Clark Kent", the username returned by the
module will be "superman".
As with any module, an expression can be used within an Auth clause to modify or
override the value returned by a module.
CERT_OPENSSL_PATH (Optional1)
VFS "[certmap]dacs-kwv-fs:/usr/local/dacs/federations/certnamemap" <Auth id="cert"> URL "https://example.com/cgi-bin/dacs/local_cert_authenticate" STYLE "cert" CONTROL "sufficient" CERT_CA_PATH "/usr/local/apache2/conf/ssl.crt" CERT_NAME_ATTR "SSL_CLIENT_S_DN_CN" </Auth>
Clark Kent:superman Bruce Wayne:batman
This is the absolute pathname of the openssl
program. If not provided, a build-time value is used (
OPENSSL_PATH).
This module works in concert with the dacsgrid(1)[94] utility to provide
users with one-time passwords. It is also an approximation of the
"something you have" factor of two-factor authentication.
The STYLE should be configured as password for this module.
Please refer to dacsgrid(1)[94] for a complete description.
In addition to the usual USERNAME argument, the module requires the
PASSWORD argument to be the user's response to the challenge and the
AUXILIARY argument to be the encoded challenge. The latter two
arguments must be produced by dacsgrid(1)[94].
The following OPTION directive values are understood:
AUTH_GRID_CHALLENGE_SECS (Optional1)
Tip
A built-in version of this module can be selected by using the URL
local_grid_authenticate or just grid.
The number of seconds between when a challenge is created
and when it expires, overriding the default value. This value should be
relatively small, at most on the order of a few tens of seconds. If this
module runs on a host other than the one running dacs_authenticate, the
two system clocks must be suitably synchronized.
AUTH_GRID_LIFETIME_SECS (Optional1)
The length of time, in seconds, for which a grid is
valid. After this period, all authentication against a grid will fail.
This module authenticates by invoking a given (non-interactive) web service with
specified arguments. If the web service reports success by returning HTTP
status code 200 (see RFC 2616[95], Section 10), then the module
succeeds, otherwise it fails. Any output, including cookies, returned by the
web service is discarded. No session is established with the web service and
no additional requests are made to it; the web service is used solely to
determine whether a username/password is correct.
This module can be used to authenticate against any existing web service that
follows the expected protocol, or can provide a way to add a new, custom
authentication method to DACS.
The STYLE should be configured as password for this module.
The following OPTION directive values are understood:
AUTH_URL (Required1)
This web service returns an HTTP status code of 200 if the correct
username and password are given (i.e., login succeeded), and 403 if
login fails. If ClientLogin fails and requests a CAPTCHA challenge the
request will not be passed back to the user.
Note
One of the reasons for inclusion of this module is to support reuse of accounts
widely used by the public. Googleprovides exactly the right interface needed
by systems such as DACS. Accounts provided by eBay[98]and
Yahoo![99], for instance, do not appear to be directly usable in this
way. In some cases, dacs_auth_transfer(8)[8] may be a better approach
than this module.
Tip
A built-in version of this module can be selected by using the URL
local_http_authenticate or just http.
The URL to invoke, which may use either the http or https
scheme.
AUTH_METHOD (Optional1)
The HTTP method to use to invoke AUTH_URL. The default is
POST. Keep in mind that if query arguments are present (or if the GET method
is used) they may appear in log files.
USERNAME_PARAMETER (Required1)
The name of the argument by which USERNAME is
passed. The default is USERNAME.
PASSWORD_PARAMETER (Required1)
The name of the argument by which PASSWORD is
passed. The default is PASSWORD.
Any other OPTION directive values are simply passed to the web service.
Duplicate argument names will be passed.
For Google[96]account authentication[97], for instance, the
following configuration might be used:
<Auth id="google"> URL "local_http_authenticate" STYLE "password" CONTROL "required" OPTION 'AUTH_URL="https://www.google.com/accounts/ClientLogin"' OPTION 'USERNAME_PARAMETER=Email' OPTION 'PASSWORD_PARAMETER=Passwd' OPTION 'service=xapi' OPTION "source=DSS-DACS-1.4" </Auth>
The local_infocard_authenticate module performs DACS
authentication using an Information Card[57] (InfoCard) previously
registered at the jurisdiction. Self-issued InfoCards are registered using
dacs_infocard(8)[59] or dacsinfocard(1)[58]. Managed InfoCards
are also supported, provided they have been registered using
dacs_managed_infocard(8)[60] and include a dacs_identity claim in the
DACS namespace. DACS aims to conform to Identity Selector
Interoperability Profile (ISIP) 1.5[100].
A DACSrole descriptor string[101] can be associated with a managed
InfoCard through the dacs_roles claim name in the DACS namespace (see
dacs_infocard(8)[102]. These roles can be associated with new
credentials via the add_roles[63] and set_roles[64] modifiers.
Security
At present, to be valid for authentication, the dacs_identity claim value must
specify a user at the current jurisdiction; that is, it cannot specify an
identity at a jurisdiction other than the one where authentication is being
performed.
The authentication style infocard causes the module to accept either type of
InfoCard - the type of InfoCard actually used will be available in the
resulting credentials. The styles managed_infocard and selfissued_infocard
tell the module to limit authentication to managed InfoCards or self-issued
InfoCards, respectively. When invoked as a web service,
local_infocard_authenticate understands an optional argument,
TYPE, that may have the value "selfissued" or
"managed" to restrict authentication to the corresponding InfoCard
type; the default behaviour accepts either type of InfoCard.
Tip
The expression-based authentication style[103], which does not employ
this module, provides an alternative way to support InfoCard-based
authentication. It is somewhat more complicated to use, however, and may
require a small amount of programming.
For additional information about InfoCards, please refer to:
Tip
A built-in version of this module can be selected by using the URL
local_infocard_authenticate or just infocard.
•dacs_managed_infocard(8)[104],
dacs.conf(5)[105] (the INFOCARD_ prefixed directives),
dacs_mex(8)[106], and dacs_sts(8)[107].
•Using InfoCards With DACS[108],
Distributed Systems Software (July, 2009).
•Identity Selector Interoperability
Profile specification and companion guides[109] (August, 2008).
•Introducing Windows CardSpace[110]
(April, 2006).
The local_ldap_authenticate module performs DACS authentication
using the Lightweight Directory Access Protocol, also known as LDAP, (see
RFC 2251[111], RFC 2252[112], RFC 2253[113], RFC
3377[114], and many others). This form of authentication can be used with
Microsoft's Active Directory (ADS)[115]. OpenLDAP[116] is used
to supply LDAP client support.
The STYLE should be configured as password for this module.
In general, authentication using LDAP is challenging because an LDAP name (a
distinguished name, or DN) is typically long and often has a site-specific
structure. For this reason, this module often requires more local expertise
for configuring and testing than other DACS authentication modules. At
least a basic familiarity with LDAP will be required to configure this module.
The module implements two different approaches to authentication:
Tip
Before using LDAP authentication with DACS, you should first make sure
that your LDAP server is functioning as you expect and that the host that will
run the local_ldap_authenticate module can communicate with the LDAP
server.
One way to do this is to use the ldapsearch(1)[121] command (found in the
clients/tools directory of the OpenLDAP distribution) to bind to the directory
and perform some searches. You should run this command on the same machine
that will be running DACS's LDAP authentication module (
local_ldap_authenticate). Some of the information that you obtain from
this exercise may be helpful when you configure DACS to use this form
of authentication.
Here are some examples to try - you must adapt the names for your environment:
In these examples, the LDAP server runs on a host named win2k.example.com (so
change win2k.example.com, example, and com), and it expects a user named
"Auggie Doggie" to exist and have the account name
"auggie" (again, change to names that exist in your LDAP directory).
You should be prompted for the LDAP password (in Windows, that will be the
login password) for either Administrator or a user named "Auggie
Doggie", depending on the argument that follows the -D flag.
The following configuration illustrates authentication using this module:
Here, the LDAP authentication module will construct a DN by plugging the
user-provided USERNAME argument into the template and binding to that
DN with the PASSWORD argument. If successful, the DACS username
will be the value of the user's entry's sAMAccountName attribute, and roles
will extracted from the entry's memberOf attribute values, as described above.
Note
In Windows, the SAM-Account-Name Active Directory attribute value
(sAMAccountName) need not be the same as the entry's Common Name; for
instance, the former might be "doggie" and the latter
"CN=Auggie Doggie". The sAMAccountName must not exceed 20 characters
in length and must be unique within the domain. It is composed of printable
characters other than the following:
The userPrincipalName attribute value is a user account name (or "user
login name") that is unique within its domain and a domain name
identifying the domain in which the user account is located. The format is the
same as a domain-name based email address; e.g., doggie@example.com.
1.In the direct method, which is the simpler and more
efficient approach, the USERNAME argument is directly mapped to the
corresponding DN. The module binds to that DN using the given PASSWORD.
If the bind operation succeeds, the user has been authenticated.
2.When the simpler method is not possible, the indirect
method can be used to bind to the directory as an LDAP administrator (or an
identity with the ability to search the appropriate portion of the directory
tree) and perform an LDAP search operation for a directory entry having an
attribute that matches the USERNAME argument. If the search returns
exactly one entry, it binds to that entry's DN using the PASSWORD
argument; if the bind operation succeeds, the user has been
authenticated.
Regardless of the approach, after successful authentication it may be necessary
to map the USERNAME or the DN into a valid DACS username.
The following configuration directives are specific to this module:
LDAP_ADMIN_PASSWORD (Optional1)
This is the password for the LDAP administrator account
that corresponds to LDAP_ADMIN_URL.
LDAP_ADMIN_URL (Required1-C)
If the indirect method is used, this directive is
required. This value is a URI like LDAP_USERNAME_URL except that it identifies
the LDAP directory's administrator. Example:
LDAP_BIND_METHOD (Required1-C)
LDAP_ADMIN_URL "ldap://example.com/cn=Administrator, cn=Users, dc=example, dc=com"
This directive tells the module to use the direct method,
indirect method, or both methods (case insensitive). When both are used, the
indirect method is attempted only if the direct method fails.
LDAP_ROLES_SELECTOR* (Optional)
Since LDAP directory operations are usually relatively
expensive, this module can return role information for the authenticated user,
avoiding a second LDAP operation during Roles clause processing. Roles are
typically extracted from information in the user's directory entry. Each
occurrence of this directive specifies an expression that is evaluated by
iterating through each attribute of the entry and making the attribute name (
${LDAP::attrname}) and its value (${LDAP::attrvalue}) available.
All of the entry's attribute names and values are made available within the
LDAP namespace. If the result of the expression is a valid role string (which
excludes the empty string, ""), it is added to the list of roles.
An example:
For each instance of the entry's memberOf attribute, this expression selects the
least significant (left-most) component of the attribute value (a DN) using
ldap()[117] and converts spaces to underscores. If the user's entry
contains:
the resulting roles would be Domain_Guests and Guests.
Note
These roles are discarded unless the STYLE[89] directive for this module
allows the roles to be incorporated into the user's credentials.
LDAP_SEARCH_FILTER (Required1-C)
LDAP_ROLES_SELECTOR* '"${LDAP::attrname}" eq "memberOf" \ ? strtr(ldap(rdn_attrvalue, \ ldap(dn_index, "${LDAP::attrvalue}", 1)), " ", "_") \ : ""'
memberOf: CN=Domain Guests,CN=Users,DC=example,DC=com memberOf: CN=Guests,CN=Builtin,DC=example,DC=com
If the indirect method is used, either this directive or
LDAP_SEARCH_FILTER* (but not both) must be configured. This search filter is
used to select the unique directory entry that corresponds to this user.
LDAP_SEARCH_FILTER* (Required1-C)
If the indirect method is used, either this directive or
LDAP_SEARCH_FILTER (but not both) must be configured. This search filter is
used to select the unique directory entry that corresponds to this user. This
directive is exactly like LDAP_SEARCH_FILTER except that it is evaluated just
before it is used, allowing various elements of the execution context to
appear in the string. Example:
LDAP_SEARCH_ROOT_DN (Required1-C)
LDAP_SEARCH_FILTER* '"(sAMAccountName=${Args::USERNAME})"'
This is the root DN at which the indirect method should
begin searching for user entries.
LDAP_TIMEOUT_SECS (Optional1)
This is a maximum time limit, in seconds, for any
individual LDAP read or search operation performed by the module. If not
specified, there will not be an application-specified time limit.
LDAP_USERNAME_EXPR* (Optional1)
If authentication succeeds, this directive is evaluated
to yield the DACS username returned to dacs_authenticate. All of
the entry's attribute names and values are made available within the LDAP
namespace. If unspecified, the value of the USERNAME parameter is
returned. Example:
LDAP_USERNAME_URL (Optional1)
LDAP_USERNAME_EXPR* '"${LDAP::sAMAccountName}"'
If the direct method is used, either this directive or
LDAP_USERNAME_URL*[118] (but not both) must be configured. This
directive identifies both the LDAP server to use and the user being
authenticated. The value of this directive is a URI (see RFC 2396[119]
and RFC 3986[120]) that gives the name of the LDAP server to contact to
authenticate the user (as the scheme and authority part of the URI) and the DN
for the user (as the path part of the URI). The scheme must be either ldap or
ldaps (case insensitive). If no port number is specified, 389 is used with the
former scheme and 636 with the latter.
Security
The ldaps scheme is not implemented. Communication between this module and the
LDAP server should use a secure channel or at least not be snoopable.
LDAP_USERNAME_URL* (Optional1)
LDAP_USERNAME_URL '"ldap://example.com/cn=Auggie%20Doggie, cn=Users, dc=example, dc=com"'
If the direct method is used, either this directive or
LDAP_USERNAME_URL (but not both) must be configured. This directive is exactly
like LDAP_USERNAME_URL except that it is evaluated just before it is used,
allowing various elements of the execution context to appear in the string.
Example:
LDAP_USERNAME_URL* '"ldap://example.com/cn=${Args::USERNAME}, cn=Users, dc=example, dc=com"'
% ./ldapsearch -h win2k.example.com -x -b "dc=example,dc=com" \ -D "CN=Administrator,CN=Users,DC=example,DC=com" -W -LLL % ./ldapsearch -h win2k.example.com -x -b "dc=example,dc=com" \ -D "CN=Auggie Doggie,CN=Users,DC=example,DC=com" -W -LLL % ./ldapsearch -h win2k.example.com -x -b "dc=example,dc=com" \ -D "CN=Administrator,CN=Users,DC=example,DC=com" -W -LLL \ "(cn=Administrator)" memberOf % ./ldapsearch -h win2k.example.com -x -b "dc=example,dc=com" \ -D "CN=Administrator,CN=Users,DC=example,DC=com" -W -LLL \ "(sAMAccountName=auggie)"
<Auth id="ldap"> URL "https://example.com/cgi-bin/dacs/local_ldap_authenticate" STYLE "password,add_roles" CONTROL "required" LDAP_BIND_METHOD "direct" LDAP_USERNAME_URL* '"ldap://windows.example.com/cn=" \ . encode(url, ${Args::USERNAME}) . ",cn=Users,dc=example,dc=com"' LDAP_USERNAME_EXPR* '"${LDAP::sAMAccountName}"' LDAP_ROLES_SELECTOR* '"${LDAP::attrname}" eq "memberOf" \ ? strtr(ldap(rdn_attrvalue, \ ldap(dn_index, "${LDAP::attrvalue}", 1)), " ", "_") \ : 0' </Auth>
\ / [ ] : ; | = , + * ? < > @ "
The local_native_authenticate module transfers a user's current,
context-dependent web server identity to a DACS identity. The web
server will most likely have used RFC 2617[55] Basic or Digest
authentication. The user, having already been authenticated by the web server
at a particular jurisdiction, will automatically be given DACS
credentials associated with that jurisdiction and typically having the same
username.
The STYLE should be configured as native for this module.
This method of authentication also depends on a CGI helper program (
autologin(8)[122]) and appropriate configuration of Apache
authentication. The general idea is that the helper program must be executable
only by users that have been properly authenticated by the web server (by any
Apache method and using any Apache authentication module). The
helper program then invokes dacs_authenticate with appropriate
arguments; if this module has been enabled and accepts its arguments, the user
will be given DACS credentials.
There are no directives or options specific to this module.
The local_ntlm_authenticate module authenticates users through Windows NT
LAN Manager using the NTLM protocol [ 1[123], 2[124]]. This
module, which makes use of Samba[125] libraries, provides Windows
NTLM authentication[126] based on a username and password. The module
does not need to be (and will not usually be) executed on the host running
Windows.
The STYLE should be configured as password for this module.
The following OPTION directive values are understood:
SAMBA_SERVER (Required1)
Here, dacs_authenticate will invoke the NTLM authentication module at the
given URL. That module will try to authenticate the username and password
given to it by asking the NTLM service at port 139 on the Windows system at
10.0.0.213.
There are no directives specific to this module.
Security
Attacks against some versions of NTLM have been identified[127].
Communication between this module and the NTLM service should use a secure
channel or at least not be snoopable.
Tip
The domain name or numeric IP address of the Windows
system providing NTLM authentication.
SAMBA_PORT (Optional1)
The port number to use on SAMBA_SERVER. The default is 0,
which tells Samba to use a sequence of default ports until one works.
SAMBA_DOMAIN (Optional1)
The domain name to use on SAMBA_SERVER. The default is
"".
The module-specific option SAMBA_SERVER must be given to provide the domain name
of the host providing the NTLM authentication. The module-specific options
SAMBA_DOMAIN and SAMBA_PORT, which are optional, can be used to override the
default port(s) used by Samba to contact SAMBA_SERVER.
The following illustrates how this module might be configured:
<Auth id="ntlm"> URL "https://example.com/cgi-bin/dacs/local_ntlm_authenticate" STYLE "pass" CONTROL "sufficient" OPTION 'SAMBA_SERVER="10.0.0.123"' OPTION 'SAMBA_PORT="139"' </Auth>
•A built-in version of this module can be selected
by using the URL local_ntlm_authenticate or just ntlm.
•Before attempting to use this module, it may save
a lot of time and aggravation if you first check that it is possible to
authenticate against NTLM, from the machine on which you intend to run this
module, using a username/password combination that you know is correct. If
you are not able to successfully authenticate in this way, obviously you will
not have any luck with the DACS module.
To test whether it is possible to authenticate using a particular username and
password, you may be able to use smbclient(1)[128]. For example, if
C:\Shared is a network shared folder or HPLaserJ-PS is a shared printer on the
Windows machine on which you want to perform authentication, to authenticate
as the Administrator try something like:
or to authenticate as the user bob, try:
Replace mywinhost with the name of your Windows machine. You should be
prompted for the account's password. If smbclient successfully connects
and establishes a session using the username and password you provide, then
this module should also be able to authenticate that user, otherwise you
should see an error message.
Before you have configured DACS, you can test NTLM authentication from
the command line using dacsauth(1)[6]. For example, try something like:
Change "bob" to the username you want to authenticate and
"windows.example.com" to the domain name of the Windows machine
where the user's account is. You may also need to specify SAMBA_PORT if
a non-standard port is being used. You will be prompted for the password for
the user's account The program's exit status indicates success ("ok"
is exit status 0) or failure (exit status 1). Repeat this with an invalid
password to make sure that it fails.
After you have configured DACS, there is another method of testing
local_ntlm_authenticate from the command line. Set the environment
variable QUERY_STRING (using your preferred shell's syntax) to
something like this:
Change "bob" to the username you want to authenticate,
"test" to the password for that username, "Test" to the
name of the DACS jurisdiction that will perform the authentication, and
"windows.example.com" to the domain name of the Windows machine
where the user's account is. You may also need to specify SAMBA_PORT.
Then from the distribution's src directory:
Use the -u, -uj, or -us flag to specify a jurisdiction that
you have configured (see dacs(1)[129]). The output, an XML document,
indicates success ("ok", exit status 0) or failure
("failed", exit status 1). Repeat this with an invalid password to
make sure that it fails. When you are done, remember to delete the
QUERY_STRING environment variable.
% smbclient //mywinhost/shared -U Administrator
% smbclient //mywinhost/HPLaserJ-PS -U bob
% dacsauth -m ntlm passwd suff -OSAMBA_SERVER="windows.example.com" -prompt -u bob
% export QUERY_STRING="USERNAME=bob&PASSWORD=test&DACS_JURISDICTION=Test\ &SAMBA_SERVER=windows.example.com"
% ./local_ntlm_auth -uj Test
This module makes a local or remote Pluggable Authentication Modules (PAM)
infrastructure available for authentication. PAM authenticates a user that is
known to the PAM-capable operating system (i.e., a user with an existing
account) through one or more PAM authentication service modules that have been
configured by the system administrator. Other PAM operations, such as password
management, are currently unsupported by DACS. Please refer to
X/Open Single Sign-On Service (XSSO) -- Pluggable Authentication[48]
for additional information about PAM.
Note
By default, the pamd server uses "dacs" as the name of the PAM
policy (see pam_start(3)[130]). Some systems may revert to a default
policy (such as "other") if no "dacs" policy is defined. A
policy name can be specified as a pamd argument.
There is a huge selection of open source and vendor-supplied PAM authentication
modules for a wide variety of platforms, including some that provide
functionality similar to that of DACS authentication modules [
GNU/Linux[131], FreeBSD[132], Solaris[133]]. For example,
pam_unix(8)[134] performs essentially the same authentication function
as local_unix_authenticate[135], except that the latter is not
interactive (it does not prompt).
The STYLE should be configured as prompted for this module.
Note
While this authentication module has been tested with only a few PAM
authentication service modules, in theory it should work with any conformant
PAM authentication module. If this module is used, the current implementation
does not allow any other authentication modules to be configured for the
jurisdiction; this can be partially ameliorated by configuring PAM to try
multiple PAM modules.
Important
The local_pam_authenticate module depends on functionality provided by
pamd(8)[136] running on a PAM-capable system, which does not need to be
the same host where local_pam_authenticate is run. The
local_pam_authenticate module establishes connections with pamd,
which interacts with the pam(3)[47] library. Unlike the other
DACS authentication styles, authentication using the prompted style may
involve more than one request to dacs_authenticate, each of which
supplies additional authentication material.
The prompted authentication style implements a session between the user
and the PAM library that consists of a sequence of operations that comprise a
PAM transaction. For each operation, dacs_authenticate (via
local_pam_authenticate and pamd) supplies the PAM library with
authentication material (either initial data or data requested by the PAM
library from the previous operation), determines if authentication has
succeeded or failed, or whether the user must be prompted for additional data.
If the PAM library requires additional data, the user is prompted for it, and
the response is submitted to dacs_authenticate in the transaction's
next operation.
If PAM requires information from the user, local_pam_authenticate can be
configured to prompt for it using one of three methods. The first method is
used if the Auth clause has an OPTION directive that configures
PAM_HANDLER_URL; the user will be redirected to this URL. The other
possibilities are selected by the FORMAT argument (see
dacs.services(8)[75]). If any XML type is specified, the reply from
dacs_authenticate will conform to the DTD
dacs_auth_reply.dtd[76]. If HTML is specified and PAM authentication
requires additional information from the user, dacs_authenticate will
return a rudimentary HTML form that must be completed and submitted by the
user. For example, if pam_unix is configured, dacs_authenticate
may emit a web page that prompts for a username (if none was provided with the
initial invocation of dacs_authenticate), and after that form has been
submitted by the user emit a web page that prompts for a password.
If PAM_HANDLER_URL is configured, the handler to which the administrator
redirects users has complete control over user prompting. In most
implementations, the handler will emit a web page that includes a form
element, with appropriate inputs and hidden variables, which is submitted to
the web service named in the service argument (see below). The handler
is required to obtain values for a set of requested variables and submit them
to a given URL ( dacs_authenticate). Each variable has a type, an
optional descriptive text label, and a name. The value of PAM_HANDLER_URL may
either be an absolute URL or a web service name, beginning with a '/', that is
interpreted relative to the current jurisdiction (i.e., the
dacs_url[137] is prepended). Query arguments may be included, provided
none of the argument names used by dacs_authenticate, described below,
are duplicated.
The pamd server requires the handler to respond within 60 seconds
(configured at compile time). The local_pam_authenticate module
requires pamd to respond to the initial request with the first prompt
within 20 seconds (configured at compile time). Should the handler
encounter a serious error, it can simply terminate; this will cause
pamd to eventually time out, which will abort the PAM transaction.
Security
The handler does not have to be DACS-wrapped, but ideally it should be.
If it is, don't forget to add an access control rule to grant access to any
user that might authenticate through local_pam_authenticate.
This "prompter" service might be configured as follows:
This will be expanded into a URL that looks something like
https://example.com/cgi-bin/dacs/dacs_pam_handler. When a user is redirected
to this handler, dacs_authenticate adds the following query arguments:
Note
For testing purposes, it may be helpful to set PAM_HANDLER_URL to
dacs_prenv, which will display the arguments passed to the handler and
other context. The DACS distribution includes an example handler,
html/handlers/dacs_pam_handler.
If an HTML form is emitted, its appearance can be customized somewhat through
the default stylesheet local_pam_authenticate.css[138]. The content of
the generated web page can be customized through the local_pam_authenticate
VFS item type. The following items relative to that item type are emitted if
they exist:
Here, pam_auth is the directory ${Conf::DACS_HOME}/pam_auth. If files named
header and trailer exist in that directory, they are expected to contain the
initial and final HTML content, respectively. These files consist of text and
HTML markup but are not complete HTML documents.
Customization of the HTML form is possible using configuration variables:
Tip
A built-in version of this module can be selected by using the URL
local_pam_authenticate or just pam.
OPTION "PAM_HANDLER_URL=/dacs_pam_handler"
•service: This is the URL of the
dacs_authenticate service to which the handler must submit the
requested values. This URL will not include any query arguments. Because
private information, such as a password, may be present, it will typically use
the https scheme. The handler should use the POST method to invoke
service.
•CSS_PATH: This is the path configured for
HTML stylesheets.
•AUTH_TRANSID: This is the unique
transaction identifier for this PAM interaction. As part of a single
authentication transaction, the handler may be called several times with the
same AUTH_TRANSID. The handler is not required to retain state between
these calls, but it may do so. The handler must pass this argument when
calling service. Although the lifetime of this identifier is relatively
brief, it should be kept private by the handler.
•auth_prompt_var_prefix: Each requested
value will be identified by an argument to service having this prefix,
with a positive integer ( int, which is assigned consecutive integers
starting with 1) appended. For instance, if
auth_prompt_var_prefix is "AUTH_PROMPT_VAR", then the handler
must submit the requested values as AUTH_PROMPT_VAR1,
AUTH_PROMPT_VAR2, and so on. The first absent int value signals
the end of the variable argument list.
•TYPEint: This is the type
("text", "password", or "error") of the variable
numbered int. The password type indicates the value should not be
displayed during user input.
•LABELint: This argument,
which is optional, indicates a label that might be displayed beside the user
prompt (e.g., "Username?") for variable int.
•NAMEint: If this argument is
not present for a given int, then no value is required for this
variable - presumably LABELint is informational. If
NAME int is present, it gives the name of the variable to
use when the handler submits the value. For example, suppose the handler is
called with arguments TYPE2 as "text", LABEL2 as
"Login:", and NAME2 as "AUTH_PROMPT_VAR2". This
asks the handler to prompt for text input labeled "Login:". If the
user submits the value "Auggie", then included with the arguments to
service there should be a variable named AUTH_PROMPT_VAR2 with
the value "Auggie".
Any other arguments to the handler should be forwarded to service
verbatim. Such arguments include DACS_VERSION,
DACS_JURISDICTION, DACS_BROWSER, and
ENABLE_AUTH_HANDLERS.
•header: Initial HTML to emit instead of the
default.
•prologue: HTML to emit immediately after the
header.
•instructions: HTML to emit immediately after the
prologue and before the form.
•form: Additional HTML to emit within the
form.
•epilogue: HTML to emit immediately after the
form.
•trailer: Final HTML to emit instead of the
default.
For example, consider the configuration directive:
VFS "[local_pam_authenticate]dacs-fs:${Conf::DACS_HOME}/pam_auth"
•prompt_submit_label: the text label to put
in the form's submit button.
For example, the submit button's text can be specified using the directive:
EVAL ${Conf::prompt_submit_label} = " Continue "
The local_passwd_authenticate module provides support for DACS
identities, strictly private to DACS, through password-protected
accounts (similar to what Apache's mod_auth[80] and
mod_auth_dbm[82] modules do, along with the
htpasswd(1)[83] utility). A secure hash of a password is stored rather
than the plaintext password itself. Several hashing methods are available (see
PASSWORD_DIGEST[139]).
The local_passwd_authenticate module performs authentication by
consulting the USERNAME and PASSWORD parameters and comparing
them to the information previously stored by the administrator.
Security
This module always requires the PASSWORD argument and will not accept the
empty string as a password value (even if that actually is the password). Use
local_simple_authenticate[62] for password-less accounts.
The STYLE should be configured as password for this module.
The dacspasswd(1)[140] utility is used to manage these accounts. The item
type is "passwds".
The following example configuration, which reflects typical usage, maintains
user and password information in a plain text file named
/usr/local/dacs/federations/passwd.
There are no directives or options specific to this module.
Note
The name "local_passwd_authenticate" may be a little confusing because
there are other modules that implement some form of password-based
authentication. This module might more appropriately be called
"local_dacspasswd_authenticate".
Tip
A built-in version of this module can be selected by using the URL
local_passwd_authenticate or just passwd.
VFS "[passwds]dacs-kwv-fs:/usr/local/dacs/federations/passwd"
The local_simple_authenticate module supports DACS identities,
strictly private to DACS, through accounts that are not
password-protected. The local_simple_authenticate module performs
authentication by looking up an account named by the USERNAME argument.
In typical use, the username will be an email address, account or membership
number, or random character string.
Security
This form of authentication is inherently insecure because no password is
provided. It is only appropriate when the consequences of a valid account name
being guessed or misappropriated are of little concern. Administrators should
not assume that using difficult-to-guess account names with this module offers
much security. Keep in mind that depending on the larger context of how these
identities are used, these usernames may be publicly visible.
The STYLE should be configured as simple for this module.
The dacspasswd(1)[140] utility is used to manage these accounts. The item
type is "simple".
The following example configuration, which reflects typical usage, maintains
user account information in a plain text file named
/usr/local/dacs/federations/simple_accounts.
Note
Although it is possible to combine password-protected accounts and password-less
accounts in the same VFS object (i.e., with the item types passwds and simple
pointing to the same file or database), putting them in separate objects is
recommended.
There are no directives or options specific to this module.
Tip
A built-in version of this module can be selected by using the URL
local_simple_authenticate or just simple.
VFS "[simple]dacs-kwv-fs:/usr/local/dacs/federations/simple_accounts"
This module works in concert with the dacstoken(1)[141] utility to
support one-time passwords. Two-factor authentication, a strong authentication
method, is supported by combining hardware token-based one-time passwords
("something you have") with a PIN (a password, "something you
know"). Software-based clients may also be used. The implementation
follows RFC 4226[142], which has been adopted by OATH[143], and
other standards. Please refer to dacstoken(1)[141] for complete
details.
The STYLE should be configured as password for this module.
In addition to the usual USERNAME argument, the module requires the
PASSWORD argument to be the next one-time password (e.g., the value
produced by the user's hardware token). If the user's DACS account has
a PIN associated with it, the PIN must be passed as the AUXILIARY
argument. The PIN referred to here is the one managed by dacstoken, not
a PIN that may be entered into the token device to unlock it.
One-time password generation depends on a secret that is shared between the
client and DACS, and a non-repeating value that may be based on
synchronized counters or clocks. The client's token can become unsynchronized
with the server's state. This can happen for many reasons, such as if a
password is generated by the device but not used, if a password or PIN is
typed incorrectly, or because of a configuration error. The method can
tolerate a configurable deviation of the client's token from the server's
state; that is, provided the client's password falls within a window of
N from the one expected by DACS, DACS will accept the
client's token. For counter-based tokens, only the "forward" side of
the window is examined, so DACS can "catch up" to the client.
If the user's password does not fall within the window, it is deemed to have
become unsynchronized with local_token_authenticate and authentication
will fail. The user can attempt to resynchronize by entering a sequence of
passwords as PASSWORD, using a comma to separate them. Three
consecutive, valid passwords are required (this number can be configured at
build time). If the account has a PIN, it must be provided to enable
synchronization. If synchronization succeeds, the user's account information
is corrected and the module also reports successful authentication. If
synchronization fails, the module also fails and a DACS administrator
must be contacted to resynchronize the token.
Note
The token value must be entered exactly as it is displayed on the token. Leading
zeroes must be typed, for example, and no spaces or punctuation are allowed.
Whenever authentication fails, the user must obtain a new password from the
token.
The following OPTION directive value is understood:
ACCEPT_WINDOW (Optional1)
Tip
A built-in version of this module can be selected by using the URL
local_token_authenticate or just token.
The (non-negative) size of the acceptance window for
one-time passwords, overriding the default. If the size is zero, DACS
will only consider a match with the expected password and will not try to
match the user's password against "nearby" passwords. With some
modes of operation, only forward matches are allowed.
The local_unix_authenticate module implements native Unix
username/password authentication, allowing a user having a pre-existing Unix
account to be authenticated by DACS using the username and password for
that account. The getpwnam(3)[144] library function is passed the
USERNAME and PASSWORD parameters given to
dacs_authenticate. It can be configured for systems with or without
shadow passwords. On some Unix systems, when the yp(8)[145] password
database is enabled, the getpwnam(3)[144] function will use the YP map
"passwd.byname" if the requested password entry is not found in the
local database.
The STYLE should be configured as password for this module.
Tip
A built-in version of this module can be selected by using the URL
local_unix_authenticate or just unix. If the module is used,
dacs_authenticate must be setuid root since it must be able to read the
shadow password file.
Roles¶
Each user authenticated by DACS may be associated with one or more roles. The syntax of roles and role descriptors[14] is described elsewhere. Role-based group membership is discussed in dacs.groups(5)[146]. Configuration of a Roles clause is optional and if none are specified, an empty role descriptor string will be used. If more than one Roles clause is configured, their role strings are concatenated (duplicates are not removed). If a roles service fails, it is treated as if it returned no roles and processing continues normally. Like authentication, a modular mechanism is used to find the roles with which a user is associated. A roles module, analogous to an authentication module, can be called by dacs_authenticate to return roles. A roles service returns a roles_reply element (see roles_reply.dtd[147]). Each Roles element must have 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 id attribute values must be unique (case-sensitively) within the clause's Jurisdiction section.Roles Clause Directives¶
The roles directives are largely analogous to the authentication directives. When evaluation of the Roles clauses begins, several variables are available in the Auth namespace to reflect the outcome of authentication. These variables may be useful when determining the user's roles: DACS_USERNAME, DACS_IDENTITY, DACS_JURISDICTION, and DACS_VERSION. Roles Clause Directives Index: 1.EXIT* (Optional1)
2.EXPR (Optional1)
3.INIT* (Optional1)
4.OPTION (Optional)
5.OPTION* (Optional)
6.PREDICATE (Optional1)
7.URL (Optional1)
8.URL* (Optional1)
URL (Optional1)
Exactly one of these two directives must be specified,
unless EXPR is specified, in which case neither URL nor URL* may be specified.
These directives specify the URL to be used to invoke the roles module (or is
the name of a built-in module). The difference between the two directives is
that the value of URL* is an expression that is evaluated to determine the URL
to be used; this evaluation occurs immediately before the module is
invoked.
INIT* (Optional1)
An expression can be specified that is to be evaluated
immediately prior to the URL* and EXPR expressions, all of which are evaluated
before a module is invoked.
EXIT* (Optional1)
If authentication is successful, this expression is
evaluated immediately after the module is executed or EXPR evaluated.
EXPR (Optional1)
This directive gives an expression that is evaluated to
obtain roles instead of invoking a roles module. Please refer to Advanced
Techniques.
OPTION (Optional)
Similar to the Auth clause's OPTION[45] directive,
this is used to pass an argument to the roles module. A given name may
not be specified more than once within a particular Roles clause. The Options
namespace is initialized with DACS_USERNAME, DACS_JURISDICTION,
and DACS_VERSION variables. If these are specified by an OPTION, the
argument ordinarily used will be overridden.
For example:
causes PASSWORD=bobo to be passed as a POST method parameter.
OPTION* (Optional)
OPTION "PASSWORD=bobo"
The given expression is evaluated before the module is
called, and after all OPTION directives and all OPTION* directives that appear
earlier. The value of the expression must be a name=value pair,
as with the OPTION directive, and overrides any name in the Options
namespace.
PREDICATE (Optional1)
If provided, this expression is evaluated before any
other roles module processing is done. If there is an evaluation error or it
returns False (zero or the empty string), processing of the clause
terminates and the next Roles clause, if any, is processed. Otherwise,
processing of the clause continues normally.
Roles Clause Control Flow¶
If authentication succeeds, Roles clauses are processed in which they appear, but only if set_roles[64] has not been specified for some authentication module's STYLE. A Roles clause is processed in a sequence of steps, and with various hooks to provide fine-grained control. Before the first clause is examined, the variables ${Auth::CURRENT_ROLES} and ${Auth::LAST_ROLES} are initialized to the role string, if any, obtained during authentication module processing. Processing of each Roles clause proceeds as follows: 1.If the clause has a PREDICATE directive, it is
evaluated in the current context. If the value is not True the clause
is not evaluated further. No variables are updated. If the expression was
invalid, processing of roles is terminated.
2.If the clause has an INIT* directive, it is evaluated;
if an error occurs, processing of roles is terminated.
3.If the clause has a URL* directive, it is evaluated to
obtain the URL of the DACS roles service to be invoked; if an error
occurs, processing of roles is terminated. If the clause has an EXPR*
directive, it is evaluated to obtain the role string; if an error occurs
during evaluation it is treated as if the expression returned the empty
string.
4.If a roles service has been specified, it is invoked.
If an error occurs, roles processing continues as if the module returned
the empty string for the role string.
5.The variable ${Auth::LAST_ROLES} is set to the
roles string returned by the module or expression.
6.If the clause has an EXIT* directive, it is evaluated;
if an error occurs, processing of roles is terminated. The value of
${Auth::LAST_ROLES} becomes the role string returned by the
clause.
7.The role string returned by the clause is appended to
the variable ${Auth::CURRENT_ROLES}.
The value of ${Auth::CURRENT_ROLES} when the last module has been
processed is the roles string that will be used in the generated credentials.
Roles Modules¶
If and only if authentication succeeds, DACS can request the user's role descriptor from the jurisdiction. Roles modules are always invoked using the POST method and are passed the following arguments: DACS_USERNAMEThe username component of the user's DACS
identity.
DACS_JURISDICTION
The name of the jurisdiction that authenticated
DACS_USERNAME.
DACS_VERSION
The DACS_VERSION_NUMBER for this version of
dacs_authenticate.
OPTION directives
For each OPTION directive[149] or OPTION*
directive[150] in the Roles section being processed, the variable name and
its value are passed.
Any of the standard web service arguments will also be accepted; anything else
will be ignored.
Roles modules return an roles_reply.dtd[147] document to
dacs_authenticate.
1.local_roles: Private DACS roles
2.local_ldap_roles: Roles imported from an LDAP/ADS
directory
3.local_unix_roles: Roles imported from Unix group
membership
This roles service consults a private list to obtain a username-to-roles mapping
using DACS virtual storage (the item type is "roles"). The
following example configuration, which reflects typical usage, maintains
mappings in a plain text file named /usr/local/dacs/federations/roles.
The file /usr/local/dacs/federations/roles might look something like this:
Here, user auggie is associated with the roles staff and users.
Tip
A built-in version of this module can be selected by using the URL local_roles
or just roles.
VFS "[roles]dacs-kwv-fs:/usr/local/dacs/federations/roles"
admin:dacs,admin rick:metalogic,guests bobo:staff,users auggie:staff,users
This roles service returns roles derived from the attributes of a user's
LDAP/ADS directory entry. This module is based on
local_ldap_authenticate[44]; please consult the description and
examples presented with that authentication module for additional information.
Note
The user need not have been authenticated by LDAP/ADS for this module to be
used. For example, the user can be authenticated on a Unix system but his
roles can come from LDAP/ADS.
The following configuration directives are recognized by this module. They
function identically to the directives of the same name used by
local_ldap_authenticate[44], so for the most part their descriptions
will not be repeated here.
Note
These module directives must be passed using either the OPTION[149] or
OPTION*[150] directive. Ensure that the option value is properly
quoted.
LDAP_BIND_METHOD (Required1-C)
LDAP_USERNAME_URL* (Optional1)
LDAP_SEARCH_FILTER* (Required1-C)
For example, the resulting role string might look like:
This tells the module how to find the user's entry.
LDAP_USERNAME_URL (Optional1)
With the direct method, one of these options is used to
name the user's entry as a URI.
LDAP_ADMIN_URL (Required1-C)
If the indirect method is used, this option is required.
This value is a URI like LDAP_USERNAME_URL except that it identifies the LDAP
directory's administrator.
LDAP_ADMIN_PASSWORD (Optional1)
This is the password for the LDAP administrator account
that corresponds to LDAP_ADMIN_URL.
LDAP_SEARCH_ROOT_DN (Required1-C)
This is the root DN at which the indirect method should
begin searching for user entries.
LDAP_SEARCH_FILTER (Required1-C)
If the indirect method is used, either this option or
LDAP_SEARCH_FILTER* (but not both) must be configured. This search filter is
used to select the unique directory entry that corresponds to this user. The
LDAP_SEARCH_FILTER* option is exactly like LDAP_SEARCH_FILTER except that it
is evaluated just before it is used, allowing various elements of the
execution context to appear in the string. The DACS username obtained
from the preceding authentication phase can be referenced as
${Args::DACS_USERNAME}.
LDAP_USERNAME_EXPR* (Optional1)
This option is evaluated to yield a username that can be
referenced by the LDAP_ROLES_SELECTOR* option as
${LDAP::USERNAME}.
LDAP_ROLES_SELECTOR* (Optional)
Each occurrence of this directive specifies an expression
that is evaluated by iterating through each attribute of the entry and making
the attribute name ( ${LDAP::attrname}) and its value
(${LDAP::attrvalue}) available. All of the entry's attribute names and
values are made available within the LDAP namespace. If the result of the
expression is a valid role string (which excludes the empty string,
""), it is added to the list of roles.
LDAP_TIMEOUT_SECS (Optional1)
This is a maximum time limit, in seconds, for any
individual LDAP read or search operation performed by the module. If not
specified, there will not be an application-specified time limit.
Here is an example that binds to the directory on x.example.com as the
administrator, searches for the entry for the account of the authenticated
user, and assigns the user a role from the attribute value of each memberOf
attribute in the entry:
<Roles id="ldap_roles"> URL "http://example.com/cgi-bin/dacs/local_ldap_roles" OPTION "LDAP_BIND_METHOD=indirect" OPTION \ 'LDAP_ADMIN_URL="ldap://x.example.com/CN=Administrator,CN=Users,DC=example,DC=com"' OPTION 'LDAP_ADMIN_PASSWORD="secretpassword"' OPTION 'LDAP_SEARCH_ROOT_DN="cn=Users,dc=example,dc=com"' OPTION 'LDAP_SEARCH_FILTER*=\'"(sAMAccountName=${Args::DACS_USERNAME})"\'' OPTION 'LDAP_ROLES_SELECTOR*=\'"${LDAP::attrname}" eq "memberOf" \ ? strtr(ldap(rdn_attrvalue, \ ldap(dn_index, "${LDAP::attrvalue}", 1)), " ", "_") \ : ""\'' </Roles>
DnsAdmins,Print_Operators,Domain_Admins,Administrators
This roles service returns the Unix group membership associated with an
authenticated username; that it, the resulting list of roles is the same as
would be obtained if the user ran the Unix groups(1)[151].
Note
The user need not have been authenticated as this username on the Unix system
where this service is run.
Tip
A built-in version of this module can be selected by using the URL
local_unix_roles or just unix.
Related Services¶
The dacs_current_credentials(8)[33] web service displays elements of each set of credentials sent with the request. The dacs_signout(8)[152] service is typically called from a browser to cause one or more cookies (each representing a DACS identity) to be deleted. Cookies are automatically deleted when a browser terminates, but it is sometimes useful to explicitly logoff.DIAGNOSTICS¶
The program exits 0 if everything was fine, 1 if an error occurred.NOTES¶
A separate but similar mechanism called "affiliated DACS federations" supports cross-federation single sign-on; see dacs_auth_transfer(8)[8]. dacs_authenticate could be modified to temporarily disable an account after some number of unsuccessful login attempts over a certain time period. The flip side of such a feature is that it could be used in a denial of service attack. Rather than disabling an account, a designated administrator might receive an email notification or a console message might be logged. It might be worthwhile to include a rule-based mechanism, called after the user has been identified but before credentials are returned, to decide whether authentication should be permitted. This might be used, for example, to restrict a particular user to login from a specified IP address or range of addresses, or limit the time of day at which login is allowed.BUGS¶
It would be nice to provide assistance to programs that generate login pages. Composing modules should be easier, to make multi-factor authentication more accessible.SEE ALSO¶
dacsauth(1)[6], dacscred(1)[153], dacscookie(1)[9], dacs.exprs(5)[3], dacs_autologin_ssl(8)[154], autologin(8)[122], dacs_auth_agent(8)[7], dacs_auth_transfer(8)[8], dacs_current_credentials(8)[33], dacs_select_credentials(8)[41], dacs_signout(8)[152], pamd(8)[136]AUTHOR¶
Distributed Systems Software ( www.dss.ca[155])COPYING¶
Copyright2003-2013 Distributed Systems Software. See the LICENSE[156] file that accompanies the distribution for licensing information.NOTES¶
- 1.
- dacsoptions
- 2.
- dacs.conf(5)
- 4.
- html/examples
- 5.
- HTTP Authentication
- 6.
- dacsauth(1)
- 10.
- Auth clause
- 11.
- CONTROL
- 12.
- username
- 13.
- dacs.acls(5)
- 14.
- dacs(1)
- 15.
- credentials.dtd
- 16.
- VERIFY_IP
- 17.
- natd(8)
- 18.
- VERIFY_UA
- 19.
- AUTH_CREDENTIALS_DEFAULT_LIFETIME_SECS
- 20.
- Advanced Encryption Standard
- 21.
- Federal Information Processing Standard
- 22.
- FIPS 198
- 23.
- RFC 2104
- 24.
- RFC 4635
- 25.
- RFC 4868
- 26.
- NIST
- 27.
- FIPS 180-1
- 28.
- RFC 4634
- 29.
- FIPS 180-3
- 30.
- MD5 algorithm
- 31.
- Netscape HTTP Cookies Specification
- 32.
- COOKIE_SYNTAX
- 34.
- COOKIE_PATH
- 35.
- SECURE_MODE
- 36.
- standard CGI arguments
- 37.
- local_pam_authenticate
- 38.
- RFC 2109
- 39.
- RFC 2965
- 40.
- dacs_acs(8)
- 42.
- strtr()
- 43.
- LDAP_USERNAME_URL
- 44.
- local_ldap_authenticate
- 45.
- OPTION
- 46.
- dacs.conf(5)
- 47.
- pam(3)
- 48.
- X/Open Single Sign-On Service (XSSO) preliminary specification
- 49.
- dacs.conf(5)
- 50.
- Authenticating Using an Expression
- 51.
- PASSWORD_CONSTRAINTS
- 52.
- LOG_FILTER
- 53.
- local_cas_authenticate
- 54.
- Central Authentication Service (CAS)
- 55.
- RFC 2617
- 56.
- local_apache_authenticate
- 57.
- Information Card
- 58.
- dacsinfocard(1)
- 59.
- dacs_infocard(8)
- 61.
- local_infocard_authenticate
- 62.
- local_simple_authenticate
- 63.
- add_roles
- 64.
- set_roles
- 65.
- dacs.exprs(5)
- 66.
- AUTH_SUCCESS
- 67.
- AUTH_SUCCESS_HANDLER
- 68.
- AUTH_ERROR_HANDLER
- 69.
- AUTH_FAIL_DELAY_SECS
- 70.
- DACS_AUTH_SUCCESS_HANDLER
- 71.
- ENABLE_AUTH_HANDLERS
- 72.
- dacs_prenv(8)
- 73.
- Environment variables
- 74.
- mod_ssl
- 75.
- dacs.services(8)
- 76.
- dacs_auth_reply.dtd
- 77.
- dacs_current_credentials.dtd
- 78.
- auth_reply.dtd
- 79.
- dacs.install(7)
- 80.
- mod_auth
- 81.
- mod_auth_digest
- 82.
- mod_auth_dbm
- 83.
- htpasswd(1)
- 84.
- htdigest(1)
- 85.
- htdbm(1)
- 86.
- local_native_authenticate
- 87.
- CAS 2.0 Protocol
- 88.
- OpenID
- 89.
- STYLE
- 90.
- SSLVerifyClient
- 91.
- SSLRequire
- 92.
- OpenSSL
- 93.
- SSLOptions
- 94.
- dacsgrid(1)
- 95.
- RFC 2616
- 96.
- 97.
- account authentication
- 98.
- eBay
- 99.
- Yahoo!
- 00.
- Identity Selector Interoperability Profile (ISIP) 1.5
- 01.
- role descriptor string
- 02.
- dacs_infocard(8)
- 03.
- expression-based authentication style
- 05.
- dacs.conf(5)
- 06.
- dacs_mex(8)
- 07.
- dacs_sts(8)
- 08.
- Using InfoCards With DACS
- 09.
- Identity Selector Interoperability Profile specification and companion guides
- 10.
- Introducing Windows CardSpace
- 11.
- RFC 2251
- 12.
- RFC 2252
- 13.
- RFC 2253
- 14.
- RFC 3377
- 15.
- Active Directory (ADS)
- 16.
- OpenLDAP
- 17.
- ldap()
- 18.
- LDAP_USERNAME_URL*
- 19.
- RFC 2396
- 20.
- RFC 3986
- 21.
- ldapsearch(1)
- 22.
- autologin(8)
- 23.
- 1
- 24.
- 2
- 25.
- Samba
- 26.
- NTLM authentication
- 27.
- have been identified
- 28.
- smbclient(1)
- 29.
- dacs(1)
- 30.
- pam_start(3)
- 31.
- GNU/Linux
- 32.
- FreeBSD
- 33.
- Solaris
- 34.
- pam_unix(8)
- 35.
- local_unix_authenticate
- 36.
- pamd(8)
- 37.
- dacs_url
- 38.
- local_pam_authenticate.css
- 39.
- PASSWORD_DIGEST
- 40.
- dacspasswd(1)
- 41.
- dacstoken(1)
- 42.
- RFC 4226
- 43.
- OATH
- 44.
- getpwnam(3)
- 45.
- yp(8)
- 46.
- dacs.groups(5)
- 47.
- roles_reply.dtd
- 48.
- ROLE_STRING_MAX_LENGTH
- 49.
- OPTION directive
- 50.
- OPTION* directive
- 51.
- groups(1)
- 52.
- dacs_signout(8)
- 53.
- dacscred(1)
- 55.
- www.dss.ca
- 56.
- LICENSE
07/17/2013 | DACS 1.4.28b |