DACSCHECK(1)                  DACS Commands Manual                  DACSCHECK(1)

       dacscheck - authorization check

       dacscheck [-admin] [-app appname] [-context file] [-Dname=value]
                 [-F field_sep] [-fd domain] [-fh hostname] [-fj jurname]
                 [-fn fedname]
                 [-dump] [-groups group_vfs] [-h] [-i ident] [-il ident]
                 [-ilg ident] [-ieuid] [-ieuidg] [-iuid] [-iuidg] [-lg]
                 [-ll log_level] [-name_compare method] [-q]
                 [-redirect] [-roles roles_vfs] [-rules rule_vfs] [-v]
                 [-var name=value]
                 [-vfs vfs_uri] [--] object

       dacscheck --version

       This program is part of the DACS suite. It is a stand-alone program that
       neither accepts the usual DACS command line options (dacsoptions) nor
       accesses any DACS configuration files.

       dacscheck looks at access control rules to test if a given user is
       authorized to do something or access something. The command's exit status
       gives the result of the test, and unless the -q flag is given, a line is
       printed to stdout that indicates the result. It provides simplified,
       general-purpose access to DACS's access control rule evaluation engine,
       even for programs other than web services, and it lends itself to
       fine-grained access control decisions.

       More specifically, dacscheck determines if a request for object should be
       granted according to specified access control rules and a given
       evaluation context. To do its job, dacscheck needs to know only a few

        1. where to find the access control rules to apply;

        2. the name of the object being accessed; and

        3. optionally, an evaluation context that specifies an identity for whom
           access is being tested and variables that can be referenced by rules.

       The command does not perform any authentication. It assumes that the
       caller (or the execution environment) has already established an identity
       or the identity is inconsequential. It may be used like any other
       command: run from the command line or a shell script, executed by a
       compiled program, or called from a scripting language such as Perl[1],
       PHP[2].  Python[3], Ruby[4], or Tcl/Tk[5].

       Some simple examples will illustrate how dacscheck can be used.

           The examples in this document have been simplified for readability;
           in real use, absolute pathnames should appear, error checking should
           be performed, and so on. Also, the dacscheck program and the rules
           that it requires must have file permissions set appropriately.

       The first example shows how a shell script might call dacscheck to test
       whether the user running it is allowed to do so. It obtains the user's
       identity from the operating system; it assumes that the user has invoked
       the script from the command line and has therefore already signed in to
       the system. In the example, dacscheck obtains the identity through a
       system call, but a script might choose to pass the value of the LOGNAME
       or USER environment variable.

       The shell script simply asks dacscheck if the effective uid (see
       geteuid(2)[6]) is permitted to access /myapp. The exit status of
       dacscheck (e.g., $?  or $status) gives the result. The pathname /myapp is
       essentially a label that is used to find the access control rule to
       apply; in this example it simply represents the name of the program. It
       could be the program's filename, but it need not be.

           #! /bin/sh

           dacscheck -q -ieuid -rules /usr/local/myapp/rules /myapp
           if test "${st}" != 0
             echo "Access is denied"
             exit "${st}"

           echo "Access is granted"

           # Do some stuff

           exit 0

       The directory /usr/local/myapp/rules might include a file named acl-app.0
       that grants access only to bob and alice:

           <acl_rule status="enabled">
              <service url_pattern="/myapp"/>

             <rule order="allow,deny">
                user(":bob") or user(":alice")

           Access control rules are described in dacs.acls(5)[7]. As with
           dacs_acs(8)[8], these rules must be indexed by dacsacl(1)[9]. For
           example, in a common use case where a DACS configuration file is not
           being used, the ruleset consulted by dacscheck might be indexed using
           a command like:

               % dacsacl -un -vfs "[acls]file:///users/bobo/my-rules" -vfs "[dacsacls]file:///dev/null"

           If dacsacl is successful in the example above, a file named INDEX
           will be created or updated in the /users/bobo/my-rules directory,
           where the files containing the rules are also found. Warning messages
           can usually be ignored provided INDEX looks correct.

       A CGI program can obtain the identity of the user invoking it from the
       REMOTE_USER environment variable and call dacscheck, as demonstrated in
       the following shell script, which uses the same rule as above:

           #! /bin/sh

           if test "${REMOTE_USER}x" = "x"
             idarg="-i ${REMOTE_USER}"

           echo "Context-Type: text/plain"
           echo ""

           # Note: append 2>&1 to the end of the next line to capture error messages
           dacscheck -q ${idarg} -rules /usr/local/myapp/rules /myapp

           if test "${st}" = 0
             echo "Access is granted"
             echo "Access is denied"

           exit 0

       This example can easily be translated into any scripting language that
       allows an external program to be called and its exit status examined.
       Here is a similar example in PHP:

           $user = $_SERVER["REMOTE_USER"];
           system("/usr/local/dacs/bin/dacscheck -q -fn DEMO -icgi
                -rules /usr/local/myapp/rules /myapp", $st);
           if ($st != 0) {
           // Access is denied, bail out

           // Access is granted, proceed

           Some may question the point of having a program call dacscheck to
           test if the user invoking it is allowed to merely run the program. At
           first glance it might appear that one could achieve the same result
           by simply setting file permissions such that only bob and alice can
           run the program. If that could be done, the coarse-grained testing
           done by dacscheck in the examples would be unnecessary. It turns out
           that there is more to it than that.

           Setting file permissions to achieve this on a traditional Unix-type
           system requires creating a new group in /etc/group, something that
           generally can only be done by a system administrator. Ordinary users
           must therefore either bother the system administrator each time such
           a group must be created or modified, or find some other way to
           achieve the same result (e.g., by encryption, using a special setuid
           or setgid command that provides password-protected access, or some
           other clumsy and possibly insecure solution).

           To address this limitation and others, many Unix-type operating
           systems now include file systems that extend the traditional Unix
           file permissions with an ACL-based mechanism (e.g., providing the
           getfacl(1)[10] and setfacl(1)[11] commands, and the acl(3)[12] ACL
           security API).

           dacscheck provides similar functionality but for arbitrary names, not
           only for objects in the file system, and with respect to arbitrary
           identities, not only for those known to the operating system. For
           example, a CGI script can call dacscheck to test access on behalf of
           a user known to the web server (e.g., via an account created using
           htpasswd(1)[13]) but not having an account on the underlying system.
           Therefore, besides being portable across platforms and available on
           systems without ACL-type file permissions, dacscheck is a much more
           general solution than what most operating systems provide. In
           contrast to a system-provided ACL-based mechanism, however, dacscheck
           is not invoked transparently (i.e., it is not called automatically by
           the operating system when a resource such as a file is accessed).
           Also, with respect to testing whether a user is allowed to run a
           program, that program will typically perform the test itself and must
           therefore begin execution.

           For additional information:

           •   Using FreeBSD's ACLs[14], Dru Lavigne, ONLamp.com[15], 22-Sep-05.

           •   POSIX ACLs in Linux[16], Mike Peters, linux.com[17], 2-Aug-04.

           •   For Solaris, Solaris acl(2) and facl(2)[18], Sun Microsystems[19]
               and Using Solaris ACLs[20] by the Dept. of Computer Science, Duke

       Because the authorization checking performed by dacscheck is completely
       separate from that performed by the operating system for system calls, a
       Unix identity such as root has no special rights or capabilities as far
       as dacscheck is concerned unless rules have been written to grant them.
       The same applies to the application of Unix groups.

       The next example demonstrates how some typical Perl code can be improved
       by dacscheck. The code fragment:

           if ($logged_in_as_root || $logged_in_as_current_admin) {
             # Do something privileged...

       which depends on the two variables being properly initialized depending
       on the value of $username, can be replaced by this:

           # Determine if $username has admin privileges
           $output = `dacscheck -q -i $username -app myapp /myapp/admin`;
           $is_admin = ($? >> 8) == 0;

           if ($is_admin) {
             # Do something privileged...

           # Later...
           if ($is_admin) {
             # Do something else privileged...

       The new authorization test depends on the identity that is running the
       program ($username) and the separate ruleset that determines whether that
       identity should be granted access to /myapp/admin, which is simply a
       label for a rule that might look like this:

           <acl_rule status="enabled">
              <service url_pattern="/myapp/admin"/>

             <rule order="allow,deny">

       This rule grants access if and only if $username is a member of the DACS
       group named admin or is associated with that DACS role. Membership in
       that group can be changed dynamically, and can even be reduced to zero.

       The important observation is that the conditions that determine whether
       the user running this Perl code has administrative privileges are defined
       outside of the program and can be changed without modifying the code and
       often without even modifying access control rules.

       A few concepts that are used in this document are described elsewhere.
       Variables, variable namespaces, and expressions that are used in access
       control rules are discussed in dacs.exprs(5)[22]. Naming in DACS is
       discussed in dacs(1)[23], and DACS groups and roles are covered in

           Clearly dacscheck, its caller, and the resources in question must be
           "isolated" from the user on whose behalf dacscheck is being run,
           otherwise the user could access the resources directly or subvert
           access control tests. Therefore, dacscheck and its caller must either
           be more privileged than the user on whose behalf it is being run or
           both programs must run in a secure context. This generally means that
           both dacscheck and its caller should be run in isolation from users
           (as on a remote server) or as an effective user ID different from the

       Programs that perform authorization tests typically contain code like:

       •   "If the current user has provided a suitable password, then execute
           the following code, otherwise do not", or

       •   "If the current user is the administrator, do the following", or

       •   "If the current user is allowed to perform an update operation, then
           show these menu items, otherwise do not show them"

       Complicated applications can be littered with these kinds of tests,
       making them prone to bugs and security problems. Changes to security
       policies may involve modifications throughout an application or suite of
       applications. Also, password handling is often incorporated into such
       programs; because password management can require a significant
       implementation effort and is difficult to do securely, it seems wise to
       try to leverage existing implementations.

       Compared to custom-coded solutions, dacscheck has many advantages:

       Data-driven policies
           As opposed to specially-written access control logic, data-driven
           (rule-based) functionality is superior because:

           •   Access control rules are separate from code, so changes to a set
               of rules automatically applies to all uses of those rules
               throughout an application or set of applications; code does not
               need to be modified if the policy is changed.

           •   Bug fixes and improvements to rules are automatically available
               to programs that use dacscheck; no recompilation of applications
               is necessary.

           •   The person who administers the rules does not have to be the
               application's programmer (or even someone who understands the
               code), so delegating responsibility is much easier. This reduces
               the amount of programming required when changes are required,
               reduces code maintenance effort, and decreases the chance of

           •   It is usually easier to understand (and express) a set of rules
               that describes an access control policy; code that implements the
               same policy will be more complex and difficult to understand,
               increasing the chance of error.

       Programming Efficiency

           •   Applications are simplified and programming time and effort are
               reduced because existing access control code (i.e., dacscheck) is

           •   Sophisticated rules can be constructed without having to write
               any code.  DACS features are available, such as roles and groups,
               and can be used to construct simpler and more expressive
               authorization policies than are likely to be hand-coded.

           Rules are platform independent, can be stored remotely from the
           applications that use them, and can potentially be evaluated
           remotely.  dacscheck is available for a variety of platforms.

       Increased Sharing
           Rules can be shared and used in different situations and by different


           •   Because it does not rely on a web server, it can be used by
               virtually any CGI-based program.

           •   With respect to DACS, it can be used in circumstances where the
               mod_auth_dacs[25] module cannot be used with Apache, or where
               Apache cannot be used at all.

           •   Because it is implemented as an ordinary command, dacscheck can
               be used from the command line or invoked from almost any script
               or program.

           •   For CGI-based programs, dacscheck can be used without any
               assistance from a system administrator; e.g., it does not require
               a web server to be configured to provide authorization for a CGI
               program because all access control functionality is performed
               within the program.

       Increased Security
           dacscheck neither performs authentication nor relies on any
           particular authentication method, so the authentication method can be
           changed without affecting the application's use of dacscheck. Any
           supported means of authentication can be used, not only the typical
           password-based method.

       While the performance of dacscheck ought not to be a factor for many
       applications, the C/C++ API can be used where it is an issue. This API
       can be used to incorporate dacscheck functionality into compiled programs
       and extensible languages, such as Perl, Python, Tcl/Tk, and PHP.

       The identity for which access is to be tested is given to the program or
       obtained by the program from its execution environment. This identity is
       converted into DACS's internal representation.

       More than one identity can be specified; the check is made on behalf of
       the union of all the identities. If the identities bob and alice are
       specified, for instance, a rule that is satisfied by either identity may
       grant access.

       If no identity is given, the check is made on behalf of an
       unauthenticated user.

       An identity can be:

       •   a login name that dacscheck maps to from the real or effective uid of
           the program (i.e., the user who is running the program);

       •   a DACS user identity (e.g., :carol, DSS:bob, or
           EXAMPLE-COM::DEMO:alice, see dacs(1)[26]);

       •   a simple name (bob is equivalent to :bob); or

       •   a name expressed in the concise syntax[27], which gives a username
           and, optionally, roles and attributes for the identity. Any identity
           that has expired is not used.

           Notesdacscheck validates the syntax of an identity it is given,
               converts and expands it to the concise syntax if necessary, and
               then converts it into its internal representation for
               credentials. These credentials are destroyed when the program

               Regardless of how it is specified, each identity must satisfy the
               syntactic requirements of a DACS user identity after this
               conversion and expansion (see dacs(1)[26]). If a login name is
               specified as an identity, for example, it must be valid as a
               component of a DACS user identity; therefore, it cannot contain
               any invalid characters.

           •   If no IP address is provided for an identity, it is obtained from
               the REMOTE_ADDR environment variable when available, otherwise a
               default of is used. The IP address associated with
               credentials is tested using the user() predicate.

           •   If an identity that is being tested includes a federation name,
               since the default federation name is unlikely to be correct, it
               will probably be necessary to tell dacscheck which federation
               name to compare against using the -fn flag.

       Here are some examples of identities that may follow the -i flag:

           {u = bob}
           {u="bob",a="a", g="guest"}

           This string may need to be quoted appropriately on the command line
           because the brace characters are significant to some shells; e.g.,

               -i '{u="bob"}'

       Apache and other web servers set the environment variable REMOTE_USER to
       the authenticated identity that invoked a web service. Provided its
       syntax is suitable, this identity can be passed to dacscheck. For
       DACS-wrapped web services, DACS identities are available in this

       By default, the federation, jurisdiction, and hostnames associated with
       the rules are derived from the system's hostname as returned by
       gethostname(3)[28]. If that name is unsuitable because it is not a FQDN
       (i.e., it is not a fully-qualified domain name because it does not
       contain a period), each of the alias names is examined (using
       gethostbyname(3)[29]) until a FQDN is found. The jurisdiction name comes
       from the left-most component of the selected FQDN and the federation
       domain and name come from the remaining components. If no FQDN is found,
       the system's hostname will be selected as the jurisdiction name and
       defaults will be used as the federation domain and name (EXAMPLE.COM and
       EXAMPLE-COM, respectively).

       If the system's hostname is found to be (or explicitly given as)
       demo.example.com, for instance, the following variables will be set as
       indicated during rule evaluation:

       •   ${Conf::FEDERATION_NAME} and ${DACS::FEDERATION} are both set to
           EXAMPLE-COM (dots are mapped to dashes to form a valid name)

       •   ${Conf::FEDERATION_DOMAIN} is set to EXAMPLE.COM

       •   ${Conf::JURISDICTION_NAME} and ${DACS::JURISDICTION} are set to the
           jurisdiction name, DEMO

       •   ${DACS::HTTP_HOST} is set to demo.example.com:80

       Often, rules and identities can be expressed such that the names chosen
       for the federation and jurisdiction are unimportant. When this is not the
       case, however, and the defaults chosen by dacscheck are incorrect, they
       can be set on the command line. In some circumstances it might be
       appropriate for the jurisdiction name to be the name of the application,
       for example.

       Regardless of their origins, federation and jurisdiction names must
       always be syntactically valid (see dacs(1)[26]).

       While an object will often be an actual thing, such as a file, menu, or
       variable, it can also be an abstraction, such as an operation.  dacscheck
       works with names - in the form of URIs - rather than objects per se.  It
       does not associate any particular meaning with names, it merely uses them
       to locate an applicable access control rule. Therefore, provided the rule
       writer and applications that consult the rules agree on the naming
       scheme, the names that are chosen are largely irrelevant.

       An application assigns names to every object or class of objects that
       need to be referenced by access control rules. At its simplest, only one
       name is required (the name of the application, for example). In more
       complex situations, a wide variety of objects need to be named. The
       choice of names and the details of the naming hierarchy are up to the
       particular application, much like the organization of a software
       package's run-time file and directory organization depends on the
       particular package.

       The object argument is the name that is matched against the services
       specified in access control rules. It can be either a URI or an absolute
       pathname (one that begins with a slash character), and either can have an
       optional query string component attached. An absolute pathname path is
       mapped internally to a URI as file://path; e.g., /myapp is interpreted as
       file:///myapp (see RFC 1738[30]).

       The various components of the URI that names the object are available as
       DACS variables and environment variables (see below). If a query string
       is given, it is parsed and the individual arguments are made available to
       rules through the Args namespace, just as for DACS-wrapped web services.

           Only the path component of the URI is considered when DACS matches an
           object's name against the url_pattern of an access control rule. At
           present, the object name is not automatically canonicalized or
           resolved (see RFC 3986[31]), as is usually done by a web server, so
           relative path components such as "." and ".." should be avoided.

   Rule Evaluation Context
       Rules are evaluated within an execution context that may affect
       expression evaluation implicitly or may be examined explicitly through

       Since dacscheck does not consult the DACS configuration files, the Conf
       namespace is instantiated with few variables. At present, only the VFS
       directives are available in it.

       The Args namespace is instantiated if an object argument has a query
       string component.

       The DACS namespace is instantiated with a few standard variables (such as
       ${DACS::JURISDICTION}) but can also be instantiated in various ways from
       the command line and from files.

       The Env namespace is instantiated from the environment. Syntactically
       invalid variable names are silently ignored.

       Many variables normally set by a web server are instantiated by dacscheck
       based on the object name. These variables are available in the Env and
       DACS namespaces. For example, if the object name is
       https://example.com:8443/myapp/edit-menu?entry=item1, the following
       variables will be set as indicated:


       Variables of the same name will also be set in the DACS namespace and
       exported as environment variables. The value of ${Args::entry} will be
       item1. The request method defaults to GET. The variable
       ${Env::REMOTE_USER} (and therefore ${DACS::REMOTE_USER} and the
       environment variable REMOTE_USER) will be set based on the first identity
       specified on the command line; if no identity has been specified, this
       variable will be undefined.

   An Example Application
       To illustrate how the pieces fit together, let's consider a hypothetical
       (yet realistic) calendar application named cal that is written in Perl
       and invoked as a CGI program. We'll allow a user that has been
       authenticated by the web server to read, create, or update only her own
       calendars, unless the owner of a calendar gives her permission to perform
       a read or update operation on the calendar. Each owner can specify which
       users have access to her own calendar and the type(s) of access allowed.

       This authorization policy can be specified fairly easily. One approach is
       to use:

       •   A main rule that delegates responsibility for specifying a security
           policy for each user's calendars to that user.

       •   Per-user, per-calendar rules that say which users can access a
           calendar and in what way or ways.

       The program's administrator might collect all of the run-time files for
       the application in the directory /usr/local/cal and its subdirectories,
       and organize it as follows:

           General rules for the application

           Root directory for calendars owned by username

           Per-calendar data files

           Per-calendar DACS access control files

           Per-user DACS group lists, one per file

       Given these naming conventions:

       •   to test whether it should perform a particular operation, the
           application would call dacscheck, telling it to use the rules it
           finds in /usr/local/cal/rules.

       •   the general rules for the application would delegate access control
           decisions for objects with names that match /users/username/* to
           access control rules found in the directory
           /usr/local/cal/users/username/rules. These rules would describe which
           users, if any, would be permitted to perform a given operation on the

       •   the application would use object names of the form
           /users/username/cal-1?OP=operation as arguments to dacscheck. The
           ruleset for cal-1 would determine whether a given identity is allowed
           to perform the requested operation on the calendar. For example,
           alice (the owner) might be granted access regardless of the value of
           the OP argument, while bob might be granted access only if OP=read,
           and all others might be denied access. Later, alice might define a
           set of users that she names family and change the rule to allow any
           member of that group read and update access.

       Users' access control rules could themselves be under access control. A
       command line, GUI, or web interface would give the administrator and
       users the ability to manage rules.

       See the EXAMPLES[32] section for example rules.

       This is by no means the only way to organize the calendars, and a
       delegation-based approach isn't required. The administrator might instead
       put all of the rules under a common directory, like
       /usr/local/cal/rules/acl-username.0/{acl-cal1.0,acl-cal2.0,...}, or put
       them closer to the calendar they are controlling, like

       Instead of testing whether an operation is permitted, rules can be
       written to return a constraint string that tells the caller what kind (or
       kinds) of access are permitted. The program's output line will include
       the constraint string within quotes.

   Comparing dacscheck with dacs_acs
       dacs_acs(8)[8] is the DACS component that is called by Apache (by the
       DACS mod_auth_dacs[25] module, actually) to perform access control
       processing on web service requests. Its operation is normally invisible
       to web services; dacs_acs does all of its work before a web service is
       even executed or a web page is returned.

       dacscheck performs a function similar to the -check_only mode of
       operation of dacs_acs in that it simply returns an access control
       decision. There are important differences between the two programs,


       •   is not a CGI program (though it can be called from one);

       •   does not require mod_auth_dacs[25];

       •   does not use any DACS configuration files;

       •   does not directly interact with a web server or any other DACS
           programs; and

       •   runs at the privilege level of the user invoking it rather than the
           privilege level of Apache.

       While dacscheck uses ordinary DACS access control rules
       (dacs.acls(5)[7]), unlike most DACS commands it does not consult any DACS
       configuration files. The evaluation environment for access control rules
       is similar to that of web service testing, but it is not identical since
       there need not be a web server in the picture. Other than the attributes
       related to constraints, attributes such as pass_credentials have no
       meaning to dacscheck.

       Use and configuration of DACS by dacscheck is greatly simplified because
       no real federation or jurisdictions are defined; a completely
       self-contained environment is created so that a single program or set of
       related programs can perform both course-grained and fine-grained access
       control tests. No federation or jurisdiction cryptographic keys are used,
       and no real DACS credentials are created. Federation and jurisdiction
       names are instantiated, but those who write rules will often not need to
       be aware of them.

       The arguments are processed as they are examined (left-to-right) and
       their ordering can be significant; for example, values established by the
       -fh flag may affect options that follow it, such as those that use string
       interpolation. Exactly one object argument is required.

           All identities that follow on the command line are DACS identities
           that satisfy the dacs_admin() function. Refer to the ADMIN_IDENTITY
           configuration directive in dacs.conf(5)[33] and the "a" attribute for

       -app appname
           Specify an application name to be used to construct default paths
           (see the -rules and -groups flags).

       -context file
           Variable definitions for the DACS namespace are read, one per line,
           in the format name=value (with optional quotes around the value). The
           name must be syntactically valid. If file is -, the standard input is
           read. For example, if file contains the two lines:


           then within access control rules ${DACS::FOO} will have the value
           "one" and ${DACS::BAZ} will have the value "two". This flag may be
           repeated, although the standard input can be read only once.

           This is equivalent to -var name=value.

           Perform all initializations, display the evaluation context, and then

       -F field_sep
           When roles are looked up, use the character field_sep as the field
           separator character instead of the default. For details, refer to the
           description of the VFS directive in dacs.conf(5)[34].

               Note that only the first occurrence of the character (from left
               to right) is treated as the separator character.

       -fd domain
           Use domain as the domain name for the federation. It must be
           syntactically valid.

       -fh hostname
           Use hostname, a fully-qualified domain name, as the system's hostname
           and to derive the federation and jurisdiction names. It must be
           syntactically valid.

       -fj jurname
           Use jurname as the jurisdiction name. It must be syntactically valid.

       -fn fedname
           Use fedname as the federation name. It must be syntactically valid.

       -groups group_vfs
           By default, dacscheck expects to find DACS group definitions rooted
           in the directory dacscheck/groups relative to DACS_HOME (e.g.,
           /usr/local/dacs/dacscheck/groups), or if -app appname is given,
           rooted in the directory dacscheck/appname/groups relative to
           DACS_HOME (e.g., /usr/local/dacs/dacscheck/myapp/groups) This flag
           specifies a different location. It can be an absolute pathname (which
           will be string interpolated - see dacs.conf(5)[35]) or a URI in the
           syntax of the VFS[34] configuration directive. Examples:

               -groups "[groups]dacs-fs:/local/groups"
               -groups /home/bob/mygroups

           By default, a reference to the group %FOO:people will be mapped to a
           file named people.grp within the directory FOO relative to the DACS
           group directory.

           Prints the usage blurb.

       -i ident
           The given identity is added to the set of identities in effect during
           checking. This identity does not necessarily have an account on the
           system. If ident is the empty string, however, the flag has no
           effect; this is convenient behaviour when the flag is used like -i
           ${Env::REMOTE_USER:-""}, for example, where REMOTE_USER may not have
           been set.

           If the environment variable REMOTE_USER is set to a valid simple name
           or DACS identity, it is added to the set of identities in effect
           during checking. If the variable is not set or is invalid, this flag
           has no effect.

           Like the -icgi flag, except any roles associated with the username
           will be added.

       -il ident
           The given identity is "local" and must correspond to an account on
           the system; if the -groups flag is in effect, the account's group
           membership will be added as roles to ident.

       -ilg ident
           Like the -ilg flag, except the account's group membership will be
           added as roles to ident regardless of whether the -groups flag is in

           The effective uid of the program is added to the set of identities.
           If the -groups flag is in effect, the account's group membership will
           be added as roles to ident.

           The effective uid of the program is added to the set of identities.
           The account's group membership will be added as roles to ident
           regardless of whether the -groups flag is in effect.

           The real uid of the program is added to the set of identities. If the
           -groups flag is in effect, the account's group membership will be
           added as roles to ident.

           The real uid of the program is added to the set of identities. The
           account's group membership will be added as roles to ident regardless
           of whether the -groups flag is in effect.

           For each local identity that follows on the command line, use its
           Unix group membership to the identity's roles.

       -ll log_level
           Set the debugging output level to log_level (see dacs(1)[23]). The
           default level is warn, and the -v flag bumps the level to debug or

       -name_compare method
           Exactly like the NAME_COMPARE[36] directive, set the default method
           used to compare DACS names in various contexts to method, which may
           be (case-insensitively) case, nocase, or default.

           Be quiet, except for error messages; the outcome will not be printed
           to stdout. The -v and -ll flags are independent of this.

           If access is denied and the applicable rule calls redirect()[37] with
           the BY_SIMPLE_REDIRECT argument, then the specified URL is printed to
           stdout. This flag enables the -q flag.

       -roles roles_vfs
           Roles for each identity that follows on the command line will be
           looked up using roles_vfs. It can be an absolute pathname (which will
           be string interpolated - see dacs.conf(5)[35]) or a URI in the syntax
           of the VFS[34] configuration directive. If any roles are found, they
           will be added to any other roles specified for the user (whether
           explicitly listed or obtained from Unix group membership). For
           example, if /usr/local/myapp/roles contains:


           then the command line:

               % dacscheck -roles /usr/local/myapp/roles -i auggie /myapp/admin

           will test access for the identity {u="auggie",g="admin,users"}.

       -rules rule_vfs
           By default, dacscheck expects to use a ruleset rooted in the
           directory dacscheck/acls relative to DACS_HOME (e.g.,
           /usr/local/dacs/dacscheck/acls), or if the flag -app appname is
           given, rooted in the directory dacscheck/appname/acls relative to
           DACS_HOME (e.g., /usr/local/dacs/dacscheck/myapp/acls). This flag
           specifies a different ruleset to be used. It can be an absolute
           pathname (which will be string interpolated - see dacs.conf(5)[35])
           or a URI in the syntax of the VFS[34] configuration directive.

               -rules "[acls1]dacs-fs:/local/acls"
               -rules /usr/local/myrules

           This flag may be repeated; rulesets will examined in the order in
           which they are specified on the command line.

           Increase the level of debugging output. The flag may be repeated.

       -var name=value
           Like the -context flag, this adds a variable definition to the DACS
           namespace. The variable DACS::name will be assigned the string value.
           The name must be syntactically valid. This flag may be repeated.

           Display the program's version information and then exit.

       -vfs vfs_uri
           Add vfs_uri as a VFS[34] configuration directive. This flag may be
           repeated, with later occurrences having a higher "priority" than
           earlier ones (just as if they appeared later in dacs.conf; see

           This marks the end of the flag arguments.

       To illustrate how dacscheck might be used with real applications, here
       are some examples. The first few continue with the hypothetical calendar
       application described earlier.

        1. The file /usr/local/cal/rules/acl-rule.0 might look like:

               <acl_rule status="enabled">
                 <delegate url_pattern="/users/alice/*"
                 <delegate url_pattern="/users/bob/*"
                 <service url_pattern="/usr/local/cal/bin/*"/>

                <rule order="allow,deny">

           This rule redirects requests for a particular user's calendar to that
           user's access control rules. It also says that access to the
           application's binaries is restricted to authenticated users. The
           application might issue a command such as:

               % dacscheck -i $REMOTE_USER -rules /usr/local/cal/rules object

           which will return an exit status of 0 if REMOTE_USER is granted
           access to object; otherwise an exit status of 1 will be returned. A
           better choice is to use the command:

               % dacscheck -icgi -rules /usr/local/cal/rules object

           which will leave the user unauthenticated if REMOTE_USER is unset or

        2. The file /usr/local/cal/users/alice/rules/acl-cal1.0 contains the
           rule for user alice's "Calendar 1" and might look like:

               <acl_rule status="enabled">
                 <service url_pattern="/users/alice/cal-1/*"/>

                <rule order="allow,deny">
                    <predicate> user(":alice") </predicate>

                <rule order="allow,deny">
                    <predicate> ${Args::OP} eq "read" </predicate>


           This rule says that alice is allowed full access to the calendar
           (there is no restriction on the operation), but bob only has read
           access.  dacscheck would be called with /users/alice/cal-1?OP=create,
           /users/alice/cal-1?OP=update, or /users/alice/cal-1?OP=read to test
           for authorization to perform a create, update, or read operation on
           the calendar, respectively.

        3. If alice defines a DACS group that she calls family and adds the
           names julia and auggie to that group, she might modify the rule above
           by adding the following:

               <rule order="allow,deny">
                    <predicate> ${Args::OP} eq "read"
                            or ${Args::OP} eq "update"</predicate>

           This rule says that any member of the group alice-family is allowed
           read and update access to this calendar. The command:

               % dacscheck -i julia /users/alice/cal-1?OP=update

           would report that access is granted.

        4. The membership of alice's group called alice-family might be
           specified in the file /usr/local/cal/users/alice/groups/family

               <acl_rule status="enabled">
                 <service url_pattern="/users/alice/groups/*"/>

                <rule order="allow,deny">
                    <predicate> user(":alice") </predicate>

           This rule allows only alice to manage the membership of this group,
           but she is free modify the rule to allow others to manage her groups.

        5. As a final example for this application, alice's rules might also be
           under access control:

               <acl_rule status="enabled">
                 <service url_pattern="/users/alice/groups/*"/>

                <rule order="allow,deny">
                    <predicate> user(":alice") </predicate>

           This rule allows only alice to manage the membership of this group,
           but she is free modify the rule to allow others to manage her groups.

        6. A popular open source web log analyzer program, written in Perl, can
           be invoked as a CGI program. The program includes security provisions
           whereby it can restrict access to any user authenticated by the web
           server, by username (using REMOTE_USER, as exported by the web
           server), or based on the user's IP address (using REMOTE_ADDR). The
           approximately 40 lines of code (plus assorted initializations) that
           implements this security policy can essentially be replaced by just a
           few lines of code:

               my $exit_value = 0;
               system "/usr/local/dacs/bin/dacscheck", "-q", "-icgi", "-rules",
                  "/usr/local/webstats/acls", "/webstats";
               $exit_value  = $? >> 8;
               # print "dacscheck returned $exit_value for user \"$remote_user\"\n";
               if ($exit_value != 0) {
                 # dacscheck denies access; print message and exit
                 exit 1;

               # dacscheck grants access, so continue

               The DACS distribution includes a Perl module
               (/usr/local/dacs/lib/perl/DACScheck.pm) to make dacscheck a
               little easier to use. The example above would be written as:

                   use DACScheck.pm;

                   my $result = dacscheck_cgi("/webstats");
                   if ($result != 1) {
                     # dacscheck denies access; print message and exit
                     exit 1;

                   # dacscheck grants access, so continue

           A simple DACS access control rule can be written to duplicate the
           program's security functionality (using the user() and from()
           predicates, see dacs.exprs(5)[22]), but more sophisticated policies
           can be added easily, all without having to modify the Perl program

       The program exits 0 if access is granted and 1 if access is denied. Any
       other exit status indicates an error occurred.

       A light-weight method of defining DACS groups is needed. Once the
       internal are stable, this program's functionality will be made available
       through a C/C++ API, which will permit direct, efficient use by other
       applications and extensible languages (through perlxs(1), for example).

       The DACS_ACS argument[38] is not recognized by dacscheck.

       Identities are not considered when roles are looked up; only the username
       is matched.

       Unlike dacs_acs(8)[8], there is no support for automatically setting
       variables by parsing a message body (a MIME document).

       It might be possible to create a layer between an application and the
       underlying system so that dacscheck can be called transparently, or
       nearly so.

       See dacs(1)[23], dacsacl(1)[9], dacs.acls(5)[7], dacs.conf(5)[33],
       dacs.exprs(5)[22], dacs.groups(5)[24], dacs.java(7)[39].

       Rule-based access control[40]


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

       Copyright © 2003-2018 Distributed Systems Software. See the LICENSE[42]
       file that accompanies the distribution for licensing information.

        1. Perl

        2. PHP

        3. Python

        4. Ruby

        5. Tcl/Tk

        6. geteuid(2)

        7. dacs.acls(5)

        8. dacs_acs(8)

        9. dacsacl(1)

       10. getfacl(1)

       11. setfacl(1)

       12. acl(3)

       13. htpasswd(1)

       14. Using FreeBSD's ACLs

       15. ONLamp.com

       16. POSIX ACLs in Linux

       17. linux.com

       18. Solaris acl(2) and facl(2)

       19. Sun Microsystems

       20. Using Solaris ACLs

       21. Dept. of Computer Science, Duke University

       22. dacs.exprs(5)

       23. dacs(1)

       24. dacs.groups(5)

       25. mod_auth_dacs

       26. dacs(1)

       27. concise syntax

       28. gethostname(3)

       29. gethostbyname(3)

       30. RFC 1738

       31. RFC 3986

       32. EXAMPLES

       33. dacs.conf(5)

       34. dacs.conf(5)

       35. dacs.conf(5)

       36. NAME_COMPARE

       37. redirect()

       38. DACS_ACS argument

       39. dacs.java(7)

       40. Rule-based access control

       41. www.dss.ca

       42. LICENSE

DACS 1.4.40                        02/19/2019                       DACSCHECK(1)