DACSCHECK(1)                 DACS Commands Manual                 DACSCHECK(1)



[1mNAME[0m
       dacscheck - authorization check

[1mSYNOPSIS[0m
       [1mdacscheck [22m[[1m-admin[22m] [[1m-app [4m[22mappname[24m] [[1m-context [4m[22mfile[24m] [[1m-D[4m[22mname=value[24m]
                 [[1m-F [4m[22mfield_sep[24m] [[1m-fd [4m[22mdomain[24m] [[1m-fh [4m[22mhostname[24m] [[1m-fj [4m[22mjurname[24m]
                 [[1m-fn [4m[22mfedname[24m]
                 [[1m-dump[22m] [[1m-groups [4m[22mgroup_vfs[24m] [[1m-h[22m] [[1m-i [4m[22mident[24m] [[1m-il [4m[22mident[24m]
                 [[1m-ilg [4m[22mident[24m] [[1m-ieuid[22m] [[1m-ieuidg[22m] [[1m-iuid[22m] [[1m-iuidg[22m] [[1m-lg[22m]
                 [[1m-ll [4m[22mlog_level[24m] [[1m-q[22m]
                 [[1m-redirect[22m] [[1m-roles [4m[22mroles_vfs[24m] [[1m-rules [4m[22mrule_vfs[24m] [[1m-v[22m]
                 [[1m-var [4m[22mname=value[24m]
                 [[1m-vfs [4m[22mvfs_uri[24m] [[1m--[22m] [4mobject[0m

[1mDESCRIPTION[0m
       This program is part of the [1mDACS [22msuite. It is a stand-alone program
       that neither accepts the usual [1mDACS [22mcommand line options ([4mdacsoptions[24m)
       nor accesses any [1mDACS [22mconfiguration files.

       Put simply, [1mdacscheck [22mlooks 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 [4m-q[24m flag is
       given, a line is printed to stdout that indicates the result. It
       provides simplified, general-purpose access to [1mDACS[22m'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, [1mdacscheck [22mchecks if a request for object should be
       granted according to specified access control rules and a given
       evaluation context. To do its job, [1mdacscheck [22mneeds to know only a few
       things:

        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
           which 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 the
       identity for which an access control decision is required. 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 [34m[1mPerl[0m[1m[22m[1], [34m[1mPHP[0m[1m[22m[2].  [34m[1mPython[0m[1m[22m[3], [34m[1mRuby[0m[1m[22m[4], and [34m[1mTcl/Tk[0m[1m[22m[5].

       Some simple examples will illustrate how [1mdacscheck [22mcan be used.

           [1mNote[0m
           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 [1mdacscheck [22mprogram and the
           rules that it requires must have file permissions set
           appropriately.

       The first example shows how a shell script might call [1mdacscheck [22mto 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, [1mdacscheck [22mobtains the identity
       through a system call, but a script might choose to pass the value of
       the [1mLOGNAME [22mor [1mUSER [22menvironment variable.

       The shell script simply asks [1mdacscheck [22mif the effective uid (see
       [34m[1mgeteuid(2)[0m[1m[22m[6]) is permitted to access /myapp. The exit status of
       [1mdacscheck [22m([4m$?[24m) 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
           st="$?"
           if test "${st}" != 0
           then
             echo "Access is denied"
             exit "${st}"
           fi

           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">
             <services>
              <service url_pattern="/myapp"/>
             </services>

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

       Access control rules are described in [34m[1mdacs.acls(5)[0m[1m[22m[7].

       A CGI program can obtain the identity of the user invoking it from the
       [1mREMOTE_USER [22menvironment variable and call [1mdacscheck[22m, as demonstrated in
       the following shell script, which uses the same rule as above:

           #! /bin/sh

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

           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

           st="$?"
           if test "${st}" = 0
           then
             echo "Access is granted"
           else
             echo "Access is denied"
           fi

           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"];
           putenv("REMOTE_USER=$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
             exit($st);
           }

           // Access is granted, proceed


           [1mNote[0m
           Some may question the point of having a program call [1mdacscheck [22mto
           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 [1mdacscheck [22min 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
           [34m[1mgetfacl(1)[0m[1m[22m[8] and [34m[1msetfacl(1)[0m[1m[22m[9] commands, and the [34m[1macl(3)[0m[1m[22m[10] ACL
           security API).

           [1mdacscheck [22mprovides similar functionality but for [4marbitrary[24m [4mnames[24m,
           not only for objects in the file system, and with respect to
           [4marbitrary[24m [4midentities[24m, not only for those known to the operating
           system. For example, a CGI script can call [1mdacscheck [22mto test access
           on behalf of a user known to the web server (e.g., via an account
           created using [34m[1mhtpasswd(1)[0m[1m[22m[11]) but not having an account on the
           underlying system. Therefore, besides being portable across
           platforms and available on systems without ACL-type file
           permissions, [1mdacscheck [22mis a much more general solution than what
           most operating systems provide. In contrast to a system-provided
           ACL-based mechanism, however, [1mdacscheck [22mis [4mnot[24m 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:

           +o    [34m[1mUsing FreeBSD's ACLs[0m[1m[22m[12], Dru Lavigne, [34m[1mONLamp.com[0m[1m[22m[13],
               22-Sep-05.

           +o    [34m[1mPOSIX ACLs in Linux[0m[1m[22m[14], Mike Peters, [34m[1mlinux.com[0m[1m[22m[15], 2-Aug-04.

           +o   For Solaris, [34m[1mSolaris 10 acl(2)[0m[1m[22m[16], [34m[1mSun Microsystems[0m[1m[22m[17] and
               [34m[1mUsing Solaris ACLs[0m[1m[22m[18] by the [34m[1mDept. of Computer Science, Duke[0m
               [1m[34mUniversity[0m[1m[22m[19].


       Because the authorization checking performed by [1mdacscheck [22mis completely
       separate from that performed by the operating system for system calls,
       a [1mUnix [22midentity such as root has no special rights or capabilities as
       far as [1mdacscheck [22mis concerned unless rules have been written to grant
       them. The same applies to the application of [1mUnix [22mgroups.

       The next example demonstrates how some typical [1mPerl [22mcode can be
       improved by [1mdacscheck[22m. 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 [4m$username[24m, 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 ([4m$username[24m) 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">
             <services>
              <service url_pattern="/myapp/admin"/>
             </services>

             <rule order="allow,deny">
              <allow>
                user("%:admin")
              </allow>
            </rule>
           </acl_rule>

       This rule grants access if and only if [4m$username[24m is a member of the
       [1mDACS [22mgroup named admin or is associated with that [1mDACS [22mrole. Membership
       in that group can be changed dynamically, and can even be reduced to
       zero.

       The important observation is that [4mthe[24m [4mconditions[24m [4mthat[24m [4mdetermine[24m [4mwhether[0m
       [4mthe[24m [4muser[24m [4mrunning[24m [4mthis[24m [4mPerl[24m [4mcode[24m [4mhas[24m [4madministrative[24m [4mprivileges[24m [4mare[0m
       [4mdefined[24m [4moutside[24m [4mof[24m [4mthe[24m [4mprogram[24m [4mand[24m [4mcan[24m [4mbe[24m [4mchanged[24m [4mwithout[24m [4mmodifying[24m [4mthe[0m
       [4mcode[24m [4mand[24m [4moften[24m [4mwithout[24m [4meven[24m [4mmodifying[24m [4maccess[24m [4mcontrol[24m [4mrules[24m.

       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 [34m[1mdacs.exprs(5)[0m[1m[22m[20]. Naming in [1mDACS [22mis
       discussed in [34m[1mdacs(1)[0m[1m[22m[21], and [1mDACS [22mgroups and roles are covered in
       [34m[1mdacs.groups(5)[0m[1m[22m[22].

           [1mSecurity[0m
           Clearly [1mdacscheck[22m, its caller, and the resources in question must
           be "isolated" from the user on whose behalf [1mdacscheck [22mis being run,
           otherwise the user could access the resources directly or subvert
           access control tests. Therefore, [1mdacscheck [22mand 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 [1mdacscheck [22mand its caller should be run in isolation
           from users (as on a remote server) or as an effective user ID
           different from the user's.

   [1mAdvantages[0m
       Programs that perform authorization tests typically contain code like:

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

       +o   "If the current user is the administrator, do the following", or

       +o   "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. A change to a security
       policy may involve changes 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, [1mdacscheck [22mhas many advantages:

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

           +o   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.

           +o   Bug fixes and improvements to rules are automatically available
               to programs that use [1mdacscheck[22m; no recompilation of
               applications is necessary.

           +o   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 error.

           +o   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


               +o   Applications are simplified and programming time and effort
                   are reduced because existing access control code (i.e.,
                   [1mdacscheck[22m) is reused.

               +o   Sophisticated rules can be constructed without having to
                   write any code.  [1mDACS [22mfeatures 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.

               Portability
                   Rules are platform independent, can be stored remotely from
                   the applications that use them, and can potentially be
                   evaluated remotely.  [1mdacscheck [22mis available for a variety
                   of platforms.

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

               Flexibility


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

                   +o   With respect to [1mDACS[22m, it can be used in circumstances
                       where the [34m[1mmod_auth_dacs[0m[1m[22m[23] module cannot be used with
                       [1mApache[22m, or where [1mApache [22mcannot be used at all.

                   +o   Because it is implemented as an ordinary command,
                       [1mdacscheck [22mcan be used from the command line or invoked
                       from almost any script or program.

                   +o   For CGI-based programs, [1mdacscheck [22mcan 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
                       [1mdacscheck [22mneither performs authentication nor relies on
                       any particular authentication method, so the
                       authentication method can be changed without affecting
                       the application's use of [1mdacscheck[22m. Any supported means
                       of authentication can be used, not only the typical
                       password-based method.

                   While the performance of [1mdacscheck [22mought 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 [1mdacscheck[0m
                   functionality into compiled programs and extensible
                   languages, such as [1mPerl[22m, [1mPython[22m, [1mTcl/Tk[22m, and [1mPHP[22m.

   [1mIdentities[0m
       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 [1mDACS's [22minternal 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:

       +o   a login name that [1mdacscheck [22mmaps to from the real or effective uid
           of the program (i.e., the user who is running the program);

       +o   a [1mDACS [22muser identity (e.g., :carol, DSS:bob, or
           EXAMPLE-COM::DEMO:alice, see [34m[1mdacs(1)[0m[1m[22m[24]);

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

       +o   a name expressed in the [34m[1mconcise syntax[0m[1m[22m[25], which gives a username
           and, optionally, roles and attributes for the identity. Any
           identity that has expired is not used.


           [1mNotes[0m
           +o   [1mdacscheck [22mvalidates 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
               terminates.

               Regardless of how it is specified, each identity must satisfy
               the syntactic requirements of a [1mDACS [22muser identity after this
               conversion and expansion (see [34m[1mdacs(1)[0m[1m[22m[24]). If a login name is
               specified as an identity, for example, it must be valid as a
               component of a [1mDACS [22muser identity; therefore, it cannot contain
               any invalid characters.

           +o   If no IP address is provided for an identity, it is obtained
               from the [1mREMOTE_ADDR [22menvironment variable when available,
               otherwise a default of 127.0.0.1 is used. The IP address
               associated with credentials is tested using the [1muser()[0m
               predicate.

           +o   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 [1mdacscheck [22mwhich federation
               name to compare against using the [1m-fn [22mflag.

       Here are some examples of identities that may follow the [1m-i [22mflag:

           bob
           :bob
           DSS:bob
           {u = bob}
           {u="bob"}
           {u="alice",g="admin"}
           {u="DSS:bob",g="guest"}
           {u="bob",a="a", g="guest"}


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

               [1m-i [22m'{u="bob"}'

       [1mApache [22mand other web servers set the environment variable [1mREMOTE_USER[0m
       to the authenticated identity that invoked a web service. Provided its
       syntax is suitable, this identity can be passed to [1mdacscheck[22m. For
       [1mDACS[22m-wrapped web services, [1mDACS [22midentities are available in this
       variable.

       By default, the federation, jurisdiction, and hostnames associated with
       the rules are derived from the system's hostname as returned by
       [34m[1mgethostname(3)[0m[1m[22m[26]. 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
       [34m[1mgethostbyname(3)[0m[1m[22m[27]) 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:

       +o   [4m${Conf::FEDERATION_NAME}[24m and [4m${DACS::FEDERATION}[24m are both set to
           EXAMPLE-COM (dots are mapped to dashes to form a valid name)

       +o   [4m${Conf::FEDERATION_DOMAIN}[24m is set to EXAMPLE.COM

       +o   [4m${Conf::JURISDICTION_NAME}[24m and [4m${DACS::JURISDICTION}[24m are set to the
           jurisdiction name, DEMO

       +o   [4m${DACS::HTTP_HOST}[24m 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 [1mdacscheck [22mare 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 [34m[1mdacs(1)[0m[1m[22m[24]).

   [1mObjects[0m
       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.
       [1mdacscheck [22mworks with names - specifically, URIs - rather than objects
       [4mper[24m [4mse[24m.  [4mIt[24m [4mdoes[24m [4mnot[24m [4massociate[24m [4many[24m [4mparticular[24m [4mmeaning[24m [4mwith[24m [4mnames,[24m [4mit[0m
       [4mmerely[24m [4muses[24m [4mthem[24m [4mto[24m [4mlocate[24m [4man[24m [4mapplicable[24m [4maccess[24m [4mcontrol[24m [4mrule[24m.
       Therefore, provided the rule writer and applications that consult the
       rules agree on the naming scheme, the exact names that are chosen is
       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 [4mobject[24m 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 [4mpath[24m is mapped internally to a URI as file://[4mpath[24m; e.g.,
       /myapp is interpreted as file:///myapp (see [34m[1mRFC 1738[0m[1m[22m[28]).

       The various components of the URI that names the object are available
       as [1mDACS [22mvariables 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 [4mArgs[24m namespace, just as for [1mDACS[22m-wrapped
       web services.

           [1mNote[0m
           Only the [4mpath[24m component of the URI is considered when [1mDACS [22mmatches
           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 [34m[1mRFC 3986[0m[1m[22m[29]), as is usually done by a web server, so
           relative path components should be avoided.

   [1mRule Evaluation Context[0m
       Rules are evaluated within an execution context that may affect
       expression evaluation implicitly or may be examined explicitly through
       variables.

       Since [1mdacscheck [22mdoes not consult the [1mDACS [22mconfiguration files, the [4mConf[0m
       namespace is instantiated with few variables. At present, only the VFS
       directives are available in it.

       The [4mArgs[24m namespace is instantiated if an [4mobject[24m argument has a query
       string component.

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

       The [4mEnv[24m namespace is instantiated from the environment. Syntactically
       invalid variable names are silently ignored.

       Many variables normally set by a web server are instantiated by
       [1mdacscheck [22mbased on the object name. These variables are available in
       the [4mEnv[24m and [4mDACS[24m 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:

           ${Env::HTTPS}=on
           ${Env::SERVER_NAME}=example.com
           ${Env::SERVER_ADDR}=142.179.101.118
           ${Env::HTTP_HOST}=example.com:8443
           ${Env::SERVER_PORT}=8443
           ${Env::REQUEST_URI}=/myapp/edit-menu
           ${Env::DOCUMENT_ROOT}=/
           ${Env::REQUEST_METHOD}=GET
           ${Env::SERVER_SOFTWARE}=dacscheck-1.4.8b
           ${Env::QUERY_STRING}=entry=item1
           ${Env::ARG_COUNT}=1
           ${Env::CURRENT_URI}=/myapp/edit-menu?entry=item1
           ${Env::CURRENT_URI_NO_QUERY}=/myapp/edit-menu

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

   [1mAn Example Application[0m
       To illustrate how the pieces fit together, let's consider a
       hypothetical (yet realistic) calendar application named [1mcal [22mthat is
       written in [1mPerl [22mand 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:

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

       +o   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:

       /usr/local/cal/rules/{acl-rule.0,acl-rule.1,...}
           General rules for the application

       /usr/local/cal/users/[4musername[0m
           Root directory for calendars owned by [4musername[0m

       /usr/local/cal/users/[4musername[24m/cal-1/data/*
           Per-calendar data files

       /usr/local/cal/users/[4musername[24m/rules/{acl-cal1.0,acl-cal2.0,...}
           Per-calendar [1mDACS [22maccess control files

       /usr/local/cal/users/[4musername[24m/groups/*
           Per-user [1mDACS [22mgroup lists, one per file

       Given these naming conventions:

       +o   to test whether it should perform a particular operation, the
           application would call [1mdacscheck[22m, telling it to use the rules it
           finds in /usr/local/cal/rules.

       +o   the general rules for the application would delegate access control
           decisions for objects with names that match /users/[4musername[24m/* to
           access control rules found in the directory
           /usr/local/cal/users/[4musername[24m/rules. These rules would describe
           which users, if any, would be permitted to perform a given
           operation on the calendar.

       +o   the application would use object names of the form
           /users/[4musername[24m/cal-1?OP=[4moperation[24m as arguments to [1mdacscheck[22m. The
           ruleset for cal-1 would determine whether a given identity is
           allowed to perform the requested [4moperation[24m on the calendar. For
           example, alice (the owner) might be granted access regardless of
           the value of the [4mOP[24m 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 [34m[1mEXAMPLES[0m[1m[22m[30] 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-[4musername[24m.0/{acl-cal1.0,acl-cal2.0,...}, or put
       them closer to the calendar they are controlling, like
       /usr/local/cal/users/[4musername[24m/cal-1/acl-cal1.0.

       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.

   [1mComparing dacscheck with dacs_acs[0m
       [34m[1mdacs_acs(8)[0m[1m[22m[31] is the [1mDACS [22mcomponent that is called by [1mApache [22m(by the
       [1mDACS [34mmod_auth_dacs[0m[1m[22m[23] module, actually) to perform access control
       processing on web service requests. Its operation is normally invisible
       to web services; [1mdacs_acs [22mdoes all of its work before a web service is
       even executed or a web page is returned.

       [1mdacscheck [22mperforms a function similar to the [1m-check_only [22mmode of
       operation of [1mdacs_acs [22min that it simply returns an access control
       decision. There are important differences between the two programs,
       however.

       [1mdacscheck[22m:

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

       +o   does not require [34m[1mmod_auth_dacs[0m[1m[22m[23];

       +o   does not use any [1mDACS [22mconfiguration files;

       +o   does not directly interact with a web server or any other [1mDACS[0m
           programs; and

       +o   runs at the privilege level of the user invoking it rather than the
           privilege level of [1mApache[22m.


       While [1mdacscheck [22muses ordinary [1mDACS [22maccess control rules
       ([34m[1mdacs.acls(5)[0m[1m[22m[7]), unlike most [1mDACS [22mcommands it does not consult any
       [1mDACS [22mconfiguration files. The evaluation environment for access control
       rules is [4msimilar[24m 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 [1mdacscheck[22m.

       Use and configuration of [1mDACS [22mby [1mdacscheck [22mis 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 [1mDACS [22mcredentials are created. Federation and
       jurisdiction names are instantiated, but those who write rules will
       often not need to be aware of them.

[1mOPTIONS[0m
       The arguments are processed as they are examined (left-to-right) and
       their ordering can be significant; for example, values established by
       the [1m-fh [22mflag may affect options that follow it, such as those that use
       string interpolation. Exactly one [4mobject[24m argument is required.

       [1m-admin[0m
           All identities that follow on the command line are [1mDACS [22midentities
           that satisfy the [1mdacs_admin() [22mfunction. Refer to the ADMIN_IDENTITY
           configuration directive in [34m[1mdacs.conf(5)[0m[1m[22m[32] and the "a" attribute
           for identities.

       [1m-app [4m[22mappname[0m
           Specify an application name to be used to construct default paths
           (see the [1m-rules [22mand [1m-groups [22mflags).

       [1m-context [4m[22mfile[0m
           Variable definitions for the [4mDACS[24m namespace are read, one per line,
           in the format [4mname[24m=[4mvalue[24m (with optional quotes around the [4mvalue[24m).
           The [4mname[24m must be syntactically valid. If [4mfile[24m is [1m-[22m, the standard
           input is read. For example, if [4mfile[24m contains the two lines:

               FOO=one
               BAZ=two

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

       [1m-D[4m[22mname=value[0m
           This is equivalent to [1m-var [4m[22mname=value[24m.

       [1m-dump[0m
           Perform all initializations, display the evaluation context, and
           then exit.

       [1m-F [4m[22mfield_sep[0m
           When roles are looked up, use the character [4mfield_sep[24m as the field
           separator character instead of the default. For details, refer to
           the description of the VFS directive in [34m[1mdacs.conf(5)[0m[1m[22m[33].

               [1mNote[0m
               Note that only the first occurrence of the character (from left
               to right) is treated as the separator character.

       [1m-fd [4m[22mdomain[0m
           Use [4mdomain[24m as the domain name for the federation. It must be
           syntactically valid.

       [1m-fh [4m[22mhostname[0m
           Use [4mhostname[24m, a fully-qualified domain name, as the system's
           hostname and to derive the federation and jurisdiction names. It
           must be syntactically valid.

       [1m-fj [4m[22mjurname[0m
           Use [4mjurname[24m as the jurisdiction name. It must be syntactically
           valid.

       [1m-fn [4m[22mfedname[0m
           Use [4mfedname[24m as the federation name. It must be syntactically valid.

       [1m-groups [4m[22mgroup_vfs[0m
           By default, [1mdacscheck [22mexpects to find [1mDACS [22mgroup definitions rooted
           in the directory dacscheck/groups relative to DACS_HOME (e.g.,
           /usr/local/dacs/dacscheck/groups), or if [1m-app [4m[22mappname[24m is given,
           rooted in the directory dacscheck/[4mappname[24m/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 [34m[1mdacs.conf(5)[0m[1m[22m[34]) or a URI
           in the syntax of the [34m[1mVFS[0m[1m[22m[33] 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
           [1mDACS [22mgroup directory.

       [1m-h[0m
           Prints the usage blurb.

       [1m-i [4m[22mident[0m
           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 [4mident[24m is the empty string, however, the flag has
           no effect; this is convenient behaviour when the flag is used like
           [1m-i ${Env::REMOTE_USER:-""}[22m, for example, where [1mREMOTE_USER [22mmay not
           have been set.

       [1m-icgi[0m
           If the environment variable [1mREMOTE_USER [22mis set to a valid simple
           name or [1mDACS [22midentity, 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.

       [1m-icgig[0m
           Like the [1m-icgi [22mflag, except any roles associated with the username
           will be added.

       [1m-il [4m[22mident[0m
           The given identity is "local" and must correspond to an account on
           the system; if the [1m-groups [22mflag is in effect, the account's group
           membership will be added as roles to [4mident[24m.

       [1m-ilg [4m[22mident[0m
           Like the [1m-ilg [22mflag, except the account's group membership will be
           added as roles to [4mident[24m regardless of whether the [1m-groups [22mflag is
           in effect.

       [1m-ieuid[0m
           The effective uid of the program is added to the set of identities.
           If the [1m-groups [22mflag is in effect, the account's group membership
           will be added as roles to [4mident[24m.

       [1m-ieuidg[0m
           The effective uid of the program is added to the set of identities.
           The account's group membership will be added as roles to [4mident[0m
           regardless of whether the [1m-groups [22mflag is in effect.

       [1m-iuid[0m
           The real uid of the program is added to the set of identities. If
           the [1m-groups [22mflag is in effect, the account's group membership will
           be added as roles to [4mident[24m.

       [1m-iuidg[0m
           The real uid of the program is added to the set of identities. The
           account's group membership will be added as roles to [4mident[0m
           regardless of whether the [1m-groups [22mflag is in effect.

       [1m-lg[0m
           For each local identity that follows on the command line, use its
           Unix group membership to the identity's roles.

       [1m-ll [4m[22mlog_level[0m
           Set the debugging output level to [4mlog_level[24m (see [34m[1mdacs(1)[0m[1m[22m[21]). The
           default level is warn, and the [1m-v [22mflag bumps the level to debug or
           trace.

       [1m-q[0m
           Be quiet, except for error messages; the outcome will not be
           printed to stdout. The [1m-v [22mand [1m-ll [22mflags are independent of this.

       [1m-redirect[0m
           If access is denied and the applicable rule calls [34m[1mredirect()[0m[1m[22m[35]
           with the BY_SIMPLE_REDIRECT argument, then the specified URL is
           printed to stdout. This flag enables the [1m-q [22mflag.

       [1m-roles [4m[22mroles_vfs[0m
           Roles for each identity that follows on the command line will be
           looked up using [4mroles_vfs[24m. It can be an absolute pathname (which
           will be string interpolated - see [34m[1mdacs.conf(5)[0m[1m[22m[34]) or a URI in the
           syntax of the [34m[1mVFS[0m[1m[22m[33] 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:

               bobo:users
               auggie:admin,users
               harley:guest

           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"}.

       [1m-rules [4m[22mrule_vfs[0m
           By default, [1mdacscheck [22mexpects 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 [1m-app [4m[22mappname[24m is
           given, rooted in the directory dacscheck/[4mappname[24m/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 [34m[1mdacs.conf(5)[0m[1m[22m[34])
           or a URI in the syntax of the [34m[1mVFS[0m[1m[22m[33] configuration directive.
           Examples:

               -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.

       [1m-v[0m
           Increase the level of debugging output. The flag may be repeated.

       [1m-var [4m[22mname=value[0m
           Like the [1m-context [22mflag, this adds a variable definition to the [4mDACS[0m
           namespace. The variable [4mDACS::name[24m will be assigned the string
           [4mvalue[24m. The [4mname[24m must be syntactically valid. This flag may be
           repeated.

       [1m-vfs [4m[22mvfs_uri[0m
           Add [4mvfs_uri[24m as a [34m[1mVFS[0m[1m[22m[33] 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
           [34m[1mdacs.conf(5)[0m[1m[22m[32]).

       [1m--[0m
           This marks the end of the flag arguments.

[1mEXAMPLES[0m
       To illustrate how [1mdacscheck [22mmight 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">
                <services>
                 <delegate url_pattern="/users/alice/*"
                         rule_uri="/usr/local/cal/users/alice/rules/>
                 <delegate url_pattern="/users/bob/*"
                         rule_uri="/usr/local/cal/users/bob/rules/>
                 <service url_pattern="/usr/local/cal/bin/*"/>
                </services>

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

           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 [4mobject[0m

           which will return an exit status of 0 if [1mREMOTE_USER [22mis granted
           access to [4mobject[24m; otherwise an exit status of 1 will be returned. A
           better choice is to use the command:

               % dacscheck -icgi -rules /usr/local/cal/rules [4mobject[0m

           which will leave the user unauthenticated if [1mREMOTE_USER [22mis unset
           or invalid.

        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">
                <services>
                 <service url_pattern="/users/alice/cal-1/*"/>
                </services>

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

                <rule order="allow,deny">
                  <precondition>
                    <predicate> ${Args::OP} eq "read" </predicate>
                  </precondition>
                  <allow>
                    user(":bob")
                  </allow>
                </rule>

               </acl_rule>

           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.  [1mdacscheck [22mwould 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 [1mDACS [22mgroup 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">
                  <precondition>
                    <predicate> ${Args::OP} eq "read"
                            or ${Args::OP} eq "update"</predicate>
                  </precondition>
                  <allow>
                    user("%:alice-family")
                  </allow>
                </rule>

           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">
                <services>
                 <service url_pattern="/users/alice/groups/*"/>
                </services>

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

           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">
                <services>
                 <service url_pattern="/users/alice/groups/*"/>
                </services>

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

           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 [1mREMOTE_USER[22m, as exported by
           the web server), or based on the user's IP address (using
           [1mREMOTE_ADDR[22m). 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


               [1mTip[0m
               The [1mDACS [22mdistribution includes a Perl module
               (/usr/local/dacs/lib/perl/DACScheck.pm) to make [1mdacscheck [22ma
               little easier to use. The example above would be written as:

                   use DACScheck.pm;
                   dacscheck_rules("/usr/local/webstats/acls");

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

                   # dacscheck grants access, so continue

           A simple [1mDACS [22maccess control rule can be written to duplicate the
           program's security functionality (using the [1muser() [22mand [1mfrom()[0m
           predicates, see [34m[1mdacs.exprs(5)[0m[1m[22m[20]), but more sophisticated policies
           can be added easily, all without having to modify the Perl program
           again.

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

[1mBUGS[0m
       A lightweight method of defining [1mDACS [22mgroups 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 [1mperlxs(1)[22m, for
       example).

       The [34m[1mDACS_ACS argument[0m[1m[22m[36] is not recognized by [1mdacscheck[22m.

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

       Unlike [34m[1mdacs_acs(8)[0m[1m[22m[31], 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 [1mdacscheck [22mcan be called transparently, or
       nearly so.

[1mSEE ALSO[0m
       See [34m[1mdacs(1)[0m[1m[22m[21], [34m[1mdacs.acls(5)[0m[1m[22m[7], [34m[1mdacs.conf(5)[0m[1m[22m[32], [34m[1mdacs.exprs(5)[0m[1m[22m[20],
       [34m[1mdacs.groups(5)[0m[1m[22m[22], [34m[1mdacs.java(7)[0m[1m[22m[37].

       [34m[1mRule-based access control[0m[1m[22m[38]

       DACScheck.pm

[1mAUTHOR[0m
       Distributed Systems Software ([34m[1mwww.dss.ca[0m[1m[22m[39])

[1mCOPYING[0m
       Copyright (C) 2003-2012 Distributed Systems Software. See the
       [34m[1mLICENSE[0m[1m[22m[40] file that accompanies the distribution for licensing
       information.

[1mNOTES[0m
        1. Perl
           http://www.perl.org/

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

        3. Python
           http://www.python.org

        4. Ruby
           http://www.ruby-lang.org

        5. Tcl/Tk
           http://www.tcl.tk/software/

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

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

        8. getfacl(1)
           http://www.freebsd.org/cgi/man.cgi?query=getfacl&apropos=0&sektion=1&manpath=FreeBSD+9.0-RELEASE&format=html

        9. setfacl(1)
           http://www.freebsd.org/cgi/man.cgi?query=setfacl&apropos=0&sektion=1&manpath=FreeBSD+9.0-RELEASE&format=html

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

       11. htpasswd(1)
           http://httpd.apache.org/docs/2.2/programs/htpasswd.html

       12. Using FreeBSD's ACLs
           http://www.onlamp.com/pub/a/bsd/2005/09/22/FreeBSD_Basics.html

       13. ONLamp.com
           http://www.onlamp.com

       14. POSIX ACLs in Linux
           http://www.cs.unc.edu/cgi-bin/howto?howto=linux-posix-acls

       15. linux.com
           http://linux.com

       16. Solaris 10 acl(2)
           http://docs.sun.com/app/docs/doc/816-5167/6mbb2jaf2?a=view

       17. Sun Microsystems
           http://www.sun.com

       18. Using Solaris ACLs
           http://www.cs.duke.edu/csl/faqs/solaris-acls.php

       19. Dept. of Computer Science, Duke University
           http://www.cs.duke.edu

       20. dacs.exprs(5)
           http://dacs.dss.ca/man/dacs.exprs.5.html

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

       22. dacs.groups(5)
           http://dacs.dss.ca/man/dacs.groups.5.html

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

       24. dacs(1)
           http://dacs.dss.ca/man/dacs.1.html#naming

       25. concise syntax
           http://dacs.dss.ca/man/dacs.1.html#concise_user_syntax

       26. gethostname(3)
           http://www.freebsd.org/cgi/man.cgi?query=gethostname&apropos=0&sektion=3&manpath=FreeBSD+9.0-RELEASE&format=html

       27. gethostbyname(3)
           http://www.freebsd.org/cgi/man.cgi?query=gethostbyname&apropos=0&sektion=3&manpath=FreeBSD+9.0-RELEASE&format=html

       28. RFC 1738
           http://www.rfc-editor.org/rfc/rfc1738.txt

       29. RFC 3986
           http://www.rfc-editor.org/rfc/rfc3986.txt

       30. EXAMPLES
           http://dacs.dss.ca/man/#EXAMPLES

       31. dacs_acs(8)
           http://dacs.dss.ca/man/dacs_acs.8.html

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

       33. dacs.conf(5)
           http://dacs.dss.ca/man/dacs.conf.5.html#VFS

       34. dacs.conf(5)
           http://dacs.dss.ca/man/dacs.conf.5.html#interpolation

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

       36. DACS_ACS argument
           http://dacs.dss.ca/man/dacs_acs.8.html#dacs_acs_argument

       37. dacs.java(7)
           http://dacs.dss.ca/man/dacs.java.7.html

       38. Rule-based access control
           http://www-128.ibm.com/developerworks/webservices/library/ws-soa-access.html

       39. www.dss.ca
           http://www.dss.ca

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



DACS 1.4.27b                      03/19/2012                      DACSCHECK(1)
