.\" Copyright (c) 2003-2012 .\" Distributed Systems Software. All rights reserved. .\" See the file LICENSE for redistribution information. .\" $Id: copyright-nr 2564 2012-03-02 00:17:08Z brachman $ '\" t .\" Title: dacscheck .\" Author: [see the "AUTHOR" section] .\" Generator: DocBook XSL Stylesheets vsnapshot .\" Date: 08/23/2020 .\" Manual: DACS Commands Manual .\" Source: DACS 1.4.40 .\" Language: English .\" .TH "DACSCHECK" "1" "08/23/2020" "DACS 1.4.40" "DACS Commands Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" dacscheck \- authorization check .SH "SYNOPSIS" .HP \w'\fBdacscheck\fR\ 'u \fBdacscheck\fR [\fB\-admin\fR] [\fB\-app\ \fR\fB\fIappname\fR\fR] [\fB\-context\ \fR\fB\fIfile\fR\fR] [\fB\-D\fR\fB\fIname=value\fR\fR] .br [\fB\-F\ \fR\fB\fIfield_sep\fR\fR] [\fB\-fd\ \fR\fB\fIdomain\fR\fR] [\fB\-fh\ \fR\fB\fIhostname\fR\fR] [\fB\-fj\ \fR\fB\fIjurname\fR\fR] [\fB\-fn\ \fR\fB\fIfedname\fR\fR] .br [\fB\-dump\fR] [\fB\-groups\ \fR\fB\fIgroup_vfs\fR\fR] [\fB\-h\fR] [\fB\-i\ \fR\fB\fIident\fR\fR] [\fB\-il\ \fR\fB\fIident\fR\fR] .br [\fB\-ilg\ \fR\fB\fIident\fR\fR] [\fB\-ieuid\fR] [\fB\-ieuidg\fR] [\fB\-iuid\fR] [\fB\-iuidg\fR] [\fB\-lg\fR] [\fB\-ll\ \fR\fB\fIlog_level\fR\fR] [\fB\-name_compare\ \fR\fB\fImethod\fR\fR] [\fB\-q\fR] .br [\fB\-redirect\fR] [\fB\-roles\ \fR\fB\fIroles_vfs\fR\fR] [\fB\-rules\ \fR\fB\fIrule_vfs\fR\fR] [\fB\-v\fR] [\fB\-var\ \fR\fB\fIname=value\fR\fR] .br [\fB\-vfs\ \fR\fB\fIvfs_uri\fR\fR] [\fB\-\-\fR] \fIobject\fR .HP \w'\fBdacscheck\fR\ 'u \fBdacscheck\fR \fB\-\-version\fR .SH "DESCRIPTION" .PP This program is part of the \fBDACS\fR suite\&. It is a stand\-alone program that neither accepts the usual \fBDACS\fR command line options (\fIdacsoptions\fR) nor accesses any \fBDACS\fR configuration files\&. .PP \fBdacscheck\fR looks at access control rules to test if a given user is authorized to do something or access something\&. The command\*(Aqs exit status gives the result of the test, and unless the \fI\-q\fR flag is given, a line is printed to stdout that indicates the result\&. It provides simplified, general\-purpose access to \fBDACS\fR\*(Aqs access control rule evaluation engine, even for programs other than web services, and it lends itself to fine\-grained access control decisions\&. .PP More specifically, \fBdacscheck\fR determines if a request for object should be granted according to specified access control rules and a given evaluation context\&. To do its job, \fBdacscheck\fR needs to know only a few things: .sp .RS 4 .ie n \{\ \h'-04' 1.\h'+01'\c .\} .el \{\ .sp -1 .IP " 1." 4.2 .\} where to find the access control rules to apply; .RE .sp .RS 4 .ie n \{\ \h'-04' 2.\h'+01'\c .\} .el \{\ .sp -1 .IP " 2." 4.2 .\} the name of the object being accessed; and .RE .sp .RS 4 .ie n \{\ \h'-04' 3.\h'+01'\c .\} .el \{\ .sp -1 .IP " 3." 4.2 .\} optionally, an evaluation context that specifies an identity for whom access is being tested and variables that can be referenced by rules\&. .RE .PP 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 \m[blue]\fBPerl\fR\m[]\&\s-2\u[1]\d\s+2, \m[blue]\fBPHP\fR\m[]\&\s-2\u[2]\d\s+2\&. \m[blue]\fBPython\fR\m[]\&\s-2\u[3]\d\s+2, \m[blue]\fBRuby\fR\m[]\&\s-2\u[4]\d\s+2, or \m[blue]\fBTcl/Tk\fR\m[]\&\s-2\u[5]\d\s+2\&. .PP Some simple examples will illustrate how \fBdacscheck\fR can be used\&. .if n \{\ .sp .\} .RS 4 .it 1 an-trap .nr an-no-space-flag 1 .nr an-break-flag 1 .br .ps +1 \fBNote\fR .ps -1 .br .PP 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 \fBdacscheck\fR program and the rules that it requires must have file permissions set appropriately\&. .sp .5v .RE .PP The first example shows how a shell script might call \fBdacscheck\fR to test whether the user running it is allowed to do so\&. It obtains the user\*(Aqs 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, \fBdacscheck\fR obtains the identity through a system call, but a script might choose to pass the value of the \fBLOGNAME\fR or \fBUSER\fR environment variable\&. .PP The shell script simply asks \fBdacscheck\fR if the effective uid (see \m[blue]\fBgeteuid(2)\fR\m[]\&\s-2\u[6]\d\s+2) is permitted to access /myapp\&. The exit status of \fBdacscheck\fR (e\&.g\&., \fI$?\fR or \fI$status\fR) 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\*(Aqs filename, but it need not be\&. .sp .if n \{\ .RS 4 .\} .nf #! /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 .fi .if n \{\ .RE .\} .sp The directory /usr/local/myapp/rules might include a file named acl\-app\&.0 that grants access only to bob and alice: .sp .if n \{\ .RS 4 .\} .nf user(":bob") or user(":alice") .fi .if n \{\ .RE .\} .sp .if n \{\ .sp .\} .RS 4 .it 1 an-trap .nr an-no-space-flag 1 .nr an-break-flag 1 .br .ps +1 \fBNote\fR .ps -1 .br .PP Access control rules are described in \m[blue]\fBdacs\&.acls(5)\fR\m[]\&\s-2\u[7]\d\s+2\&. As with \m[blue]\fBdacs_acs(8)\fR\m[]\&\s-2\u[8]\d\s+2, these rules must be indexed by \m[blue]\fBdacsacl(1)\fR\m[]\&\s-2\u[9]\d\s+2\&. For example, in a common use case where a \fBDACS\fR configuration file is not being used, the ruleset consulted by \fBdacscheck\fR might be indexed using a command like: .sp .if n \{\ .RS 4 .\} .nf % dacsacl \-un \-vfs "[acls]file:///users/bobo/my\-rules" \-vfs "[dacsacls]file:///dev/null" .fi .if n \{\ .RE .\} .sp If \fBdacsacl\fR 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\&. .sp .5v .RE .PP A CGI program can obtain the identity of the user invoking it from the \fBREMOTE_USER\fR environment variable and call \fBdacscheck\fR, as demonstrated in the following shell script, which uses the same rule as above: .sp .if n \{\ .RS 4 .\} .nf #! /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 .fi .if n \{\ .RE .\} .PP 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: .sp .if n \{\ .RS 4 .\} .nf $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 .fi .if n \{\ .RE .\} .sp .if n \{\ .sp .\} .RS 4 .it 1 an-trap .nr an-no-space-flag 1 .nr an-break-flag 1 .br .ps +1 \fBNote\fR .ps -1 .br .PP Some may question the point of having a program call \fBdacscheck\fR 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 \fBdacscheck\fR in the examples would be unnecessary\&. It turns out that there is more to it than that\&. .PP 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)\&. .PP 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 \m[blue]\fBgetfacl(1)\fR\m[]\&\s-2\u[10]\d\s+2 and \m[blue]\fBsetfacl(1)\fR\m[]\&\s-2\u[11]\d\s+2 commands, and the \m[blue]\fBacl(3)\fR\m[]\&\s-2\u[12]\d\s+2 ACL security API)\&. .PP \fBdacscheck\fR provides similar functionality but for \fIarbitrary names\fR, not only for objects in the file system, and with respect to \fIarbitrary identities\fR, not only for those known to the operating system\&. For example, a CGI script can call \fBdacscheck\fR to test access on behalf of a user known to the web server (e\&.g\&., via an account created using \m[blue]\fBhtpasswd(1)\fR\m[]\&\s-2\u[13]\d\s+2) but not having an account on the underlying system\&. Therefore, besides being portable across platforms and available on systems without ACL\-type file permissions, \fBdacscheck\fR is a much more general solution than what most operating systems provide\&. In contrast to a system\-provided ACL\-based mechanism, however, \fBdacscheck\fR is \fInot\fR 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\&. .PP For additional information: .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} \m[blue]\fBUsing FreeBSD\*(Aqs ACLs\fR\m[]\&\s-2\u[14]\d\s+2, Dru Lavigne, \m[blue]\fBONLamp\&.com\fR\m[]\&\s-2\u[15]\d\s+2, 22\-Sep\-05\&. .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} \m[blue]\fBPOSIX ACLs in Linux\fR\m[]\&\s-2\u[16]\d\s+2, Mike Peters, \m[blue]\fBlinux\&.com\fR\m[]\&\s-2\u[17]\d\s+2, 2\-Aug\-04\&. .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} For Solaris, \m[blue]\fBSolaris acl(2) and facl(2)\fR\m[]\&\s-2\u[18]\d\s+2, \m[blue]\fBSun Microsystems\fR\m[]\&\s-2\u[19]\d\s+2 and \m[blue]\fBUsing Solaris ACLs\fR\m[]\&\s-2\u[20]\d\s+2 by the \m[blue]\fBDept\&. of Computer Science, Duke University\fR\m[]\&\s-2\u[21]\d\s+2\&. .RE .sp .5v .RE .PP Because the authorization checking performed by \fBdacscheck\fR is completely separate from that performed by the operating system for system calls, a \fBUnix\fR identity such as root has no special rights or capabilities as far as \fBdacscheck\fR is concerned unless rules have been written to grant them\&. The same applies to the application of \fBUnix\fR groups\&. .PP The next example demonstrates how some typical \fBPerl\fR code can be improved by \fBdacscheck\fR\&. The code fragment: .sp .if n \{\ .RS 4 .\} .nf if ($logged_in_as_root || $logged_in_as_current_admin) { # Do something privileged\&.\&.\&. } .fi .if n \{\ .RE .\} .sp which depends on the two variables being properly initialized depending on the value of \fI$username\fR, can be replaced by this: .sp .if n \{\ .RS 4 .\} .nf # 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\&.\&.\&. } .fi .if n \{\ .RE .\} .sp The new authorization test depends on the identity that is running the program (\fI$username\fR) 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: .sp .if n \{\ .RS 4 .\} .nf user("%:admin") .fi .if n \{\ .RE .\} .sp This rule grants access if and only if \fI$username\fR is a member of the \fBDACS\fR group named admin or is associated with that \fBDACS\fR role\&. Membership in that group can be changed dynamically, and can even be reduced to zero\&. .PP The important observation is that \fIthe 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\fR\&. .PP 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 \m[blue]\fBdacs\&.exprs(5)\fR\m[]\&\s-2\u[22]\d\s+2\&. Naming in \fBDACS\fR is discussed in \m[blue]\fBdacs(1)\fR\m[]\&\s-2\u[23]\d\s+2, and \fBDACS\fR groups and roles are covered in \m[blue]\fBdacs\&.groups(5)\fR\m[]\&\s-2\u[24]\d\s+2\&. .if n \{\ .sp .\} .RS 4 .it 1 an-trap .nr an-no-space-flag 1 .nr an-break-flag 1 .br .ps +1 \fBSecurity\fR .ps -1 .br .PP Clearly \fBdacscheck\fR, its caller, and the resources in question must be "isolated" from the user on whose behalf \fBdacscheck\fR is being run, otherwise the user could access the resources directly or subvert access control tests\&. Therefore, \fBdacscheck\fR 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 \fBdacscheck\fR and its caller should be run in isolation from users (as on a remote server) or as an effective user ID different from the user\*(Aqs\&. .sp .5v .RE .SS "Advantages" .PP Programs that perform authorization tests typically contain code like: .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} "If the current user has provided a suitable password, then execute the following code, otherwise do not", or .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} "If the current user is the administrator, do the following", or .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} "If the current user is allowed to perform an update operation, then show these menu items, otherwise do not show them" .RE .sp 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\&. .PP Compared to custom\-coded solutions, \fBdacscheck\fR has many advantages: .PP Data\-driven policies .RS 4 As opposed to specially\-written access control logic, data\-driven (rule\-based) functionality is superior because: .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} 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\&. .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} Bug fixes and improvements to rules are automatically available to programs that use \fBdacscheck\fR; no recompilation of applications is necessary\&. .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} The person who administers the rules does not have to be the application\*(Aqs 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\&. .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} 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\&. .RE .sp .RE .PP Programming Efficiency .RS 4 .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} Applications are simplified and programming time and effort are reduced because existing access control code (i\&.e\&., \fBdacscheck\fR) is reused\&. .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} Sophisticated rules can be constructed without having to write any code\&. \fBDACS\fR 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\&. .RE .sp .RE .PP Portability .RS 4 Rules are platform independent, can be stored remotely from the applications that use them, and can potentially be evaluated remotely\&. \fBdacscheck\fR is available for a variety of platforms\&. .RE .PP Increased Sharing .RS 4 Rules can be shared and used in different situations and by different programs\&. .RE .PP Flexibility .RS 4 .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} Because it does not rely on a web server, it can be used by virtually any CGI\-based program\&. .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} With respect to \fBDACS\fR, it can be used in circumstances where the \m[blue]\fBmod_auth_dacs\fR\m[]\&\s-2\u[25]\d\s+2 module cannot be used with \fBApache\fR, or where \fBApache\fR cannot be used at all\&. .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} Because it is implemented as an ordinary command, \fBdacscheck\fR can be used from the command line or invoked from almost any script or program\&. .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} For CGI\-based programs, \fBdacscheck\fR 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\&. .RE .sp .RE .PP Increased Security .RS 4 \fBdacscheck\fR neither performs authentication nor relies on any particular authentication method, so the authentication method can be changed without affecting the application\*(Aqs use of \fBdacscheck\fR\&. Any supported means of authentication can be used, not only the typical password\-based method\&. .RE .PP While the performance of \fBdacscheck\fR 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 \fBdacscheck\fR functionality into compiled programs and extensible languages, such as \fBPerl\fR, \fBPython\fR, \fBTcl/Tk\fR, and \fBPHP\fR\&. .SS "Identities" .PP 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 \fBDACS\*(Aqs\fR internal representation\&. .PP 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\&. .PP If no identity is given, the check is made on behalf of an unauthenticated user\&. .PP An identity can be: .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} a login name that \fBdacscheck\fR maps to from the real or effective uid of the program (i\&.e\&., the user who is running the program); .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} a \fBDACS\fR user identity (e\&.g\&., :carol, DSS:bob, or EXAMPLE\-COM::DEMO:alice, see \m[blue]\fBdacs(1)\fR\m[]\&\s-2\u[26]\d\s+2); .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} a simple name (bob is equivalent to :bob); or .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} a name expressed in the \m[blue]\fBconcise syntax\fR\m[]\&\s-2\u[27]\d\s+2, which gives a username and, optionally, roles and attributes for the identity\&. Any identity that has expired is not used\&. .RE .sp .if n \{\ .sp .\} .RS 4 .it 1 an-trap .nr an-no-space-flag 1 .nr an-break-flag 1 .br .ps +1 \fBNotes\fR .ps -1 .br .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} \fBdacscheck\fR 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 terminates\&. .sp Regardless of how it is specified, each identity must satisfy the syntactic requirements of a \fBDACS\fR user identity after this conversion and expansion (see \m[blue]\fBdacs(1)\fR\m[]\&\s-2\u[26]\d\s+2)\&. If a login name is specified as an identity, for example, it must be valid as a component of a \fBDACS\fR user identity; therefore, it cannot contain any invalid characters\&. .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} If no IP address is provided for an identity, it is obtained from the \fBREMOTE_ADDR\fR environment variable when available, otherwise a default of 127\&.0\&.0\&.1 is used\&. The IP address associated with credentials is tested using the \fBuser()\fR predicate\&. .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} 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 \fBdacscheck\fR which federation name to compare against using the \fB\-fn\fR flag\&. .RE .sp .5v .RE .PP Here are some examples of identities that may follow the \fB\-i\fR flag: .sp .if n \{\ .RS 4 .\} .nf bob :bob DSS:bob {u = bob} {u="bob"} {u="alice",g="admin"} {u="DSS:bob",g="guest"} {u="bob",a="a", g="guest"} .fi .if n \{\ .RE .\} .sp .if n \{\ .sp .\} .RS 4 .it 1 an-trap .nr an-no-space-flag 1 .nr an-break-flag 1 .br .ps +1 \fBNote\fR .ps -1 .br .PP This string may need to be quoted appropriately on the command line because the brace characters are significant to some shells; e\&.g\&., .sp .if n \{\ .RS 4 .\} .nf \fB\-i\fR \*(Aq{u="bob"}\*(Aq .fi .if n \{\ .RE .\} .sp .5v .RE .PP \fBApache\fR and other web servers set the environment variable \fBREMOTE_USER\fR to the authenticated identity that invoked a web service\&. Provided its syntax is suitable, this identity can be passed to \fBdacscheck\fR\&. For \fBDACS\fR\-wrapped web services, \fBDACS\fR identities are available in this variable\&. .PP By default, the federation, jurisdiction, and hostnames associated with the rules are derived from the system\*(Aqs hostname as returned by \m[blue]\fBgethostname(3)\fR\m[]\&\s-2\u[28]\d\s+2\&. 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 \m[blue]\fBgethostbyname(3)\fR\m[]\&\s-2\u[29]\d\s+2) 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\*(Aqs 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)\&. .PP If the system\*(Aqs 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: .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} \fI${Conf::FEDERATION_NAME}\fR and \fI${DACS::FEDERATION}\fR are both set to EXAMPLE\-COM (dots are mapped to dashes to form a valid name) .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} \fI${Conf::FEDERATION_DOMAIN}\fR is set to EXAMPLE\&.COM .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} \fI${Conf::JURISDICTION_NAME}\fR and \fI${DACS::JURISDICTION}\fR are set to the jurisdiction name, DEMO .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} \fI${DACS::HTTP_HOST}\fR is set to demo\&.example\&.com:80 .RE .PP 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 \fBdacscheck\fR 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\&. .PP Regardless of their origins, federation and jurisdiction names must always be syntactically valid (see \m[blue]\fBdacs(1)\fR\m[]\&\s-2\u[26]\d\s+2)\&. .SS "Objects" .PP 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\&. \fBdacscheck\fR works with names \- in the form of URIs \- rather than objects \fIper se\fR\&. \fIIt does not associate any particular meaning with names, it merely uses them to locate an applicable access control rule\fR\&. Therefore, provided the rule writer and applications that consult the rules agree on the naming scheme, the names that are chosen are largely irrelevant\&. .PP 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\*(Aqs run\-time file and directory organization depends on the particular package\&. .PP The \fIobject\fR 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 \fIpath\fR is mapped internally to a URI as file://\fIpath\fR; e\&.g\&., /myapp is interpreted as file:///myapp (see \m[blue]\fBRFC 1738\fR\m[]\&\s-2\u[30]\d\s+2)\&. .PP The various components of the URI that names the object are available as \fBDACS\fR 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 \fIArgs\fR namespace, just as for \fBDACS\fR\-wrapped web services\&. .if n \{\ .sp .\} .RS 4 .it 1 an-trap .nr an-no-space-flag 1 .nr an-break-flag 1 .br .ps +1 \fBNote\fR .ps -1 .br .PP Only the \fIpath\fR component of the URI is considered when \fBDACS\fR matches an object\*(Aqs name against the url_pattern of an access control rule\&. At present, the object name is not automatically canonicalized or resolved (see \m[blue]\fBRFC 3986\fR\m[]\&\s-2\u[31]\d\s+2), as is usually done by a web server, so relative path components such as "\&." and "\&.\&." should be avoided\&. .sp .5v .RE .SS "Rule Evaluation Context" .PP Rules are evaluated within an execution context that may affect expression evaluation implicitly or may be examined explicitly through variables\&. .PP Since \fBdacscheck\fR does not consult the \fBDACS\fR configuration files, the \fIConf\fR namespace is instantiated with few variables\&. At present, only the VFS directives are available in it\&. .PP The \fIArgs\fR namespace is instantiated if an \fIobject\fR argument has a query string component\&. .PP The \fIDACS\fR namespace is instantiated with a few standard variables (such as \fI${DACS::JURISDICTION}\fR) but can also be instantiated in various ways from the command line and from files\&. .PP The \fIEnv\fR namespace is instantiated from the environment\&. Syntactically invalid variable names are silently ignored\&. .PP Many variables normally set by a web server are instantiated by \fBdacscheck\fR based on the object name\&. These variables are available in the \fIEnv\fR and \fIDACS\fR 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: .sp .if n \{\ .RS 4 .\} .nf ${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 .fi .if n \{\ .RE .\} .sp Variables of the same name will also be set in the \fIDACS\fR namespace and exported as environment variables\&. The value of \fI${Args::entry}\fR will be item1\&. The request method defaults to GET\&. The variable \fI${Env::REMOTE_USER}\fR (and therefore \fI${DACS::REMOTE_USER}\fR and the environment variable \fBREMOTE_USER\fR) will be set based on the first identity specified on the command line; if no identity has been specified, this variable will be undefined\&. .SS "An Example Application" .PP To illustrate how the pieces fit together, let\*(Aqs consider a hypothetical (yet realistic) calendar application named \fBcal\fR that is written in \fBPerl\fR and invoked as a CGI program\&. We\*(Aqll 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\&. .PP This authorization policy can be specified fairly easily\&. One approach is to use: .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} A main rule that delegates responsibility for specifying a security policy for each user\*(Aqs calendars to that user\&. .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} Per\-user, per\-calendar rules that say which users can access a calendar and in what way or ways\&. .RE .PP The program\*(Aqs 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: .PP /usr/local/cal/rules/{acl\-rule\&.0,acl\-rule\&.1,\&.\&.\&.} .RS 4 General rules for the application .RE .PP /usr/local/cal/users/\fIusername\fR .RS 4 Root directory for calendars owned by \fIusername\fR .RE .PP /usr/local/cal/users/\fIusername\fR/cal\-1/data/* .RS 4 Per\-calendar data files .RE .PP /usr/local/cal/users/\fIusername\fR/rules/{acl\-cal1\&.0,acl\-cal2\&.0,\&.\&.\&.} .RS 4 Per\-calendar \fBDACS\fR access control files .RE .PP /usr/local/cal/users/\fIusername\fR/groups/* .RS 4 Per\-user \fBDACS\fR group lists, one per file .RE .PP Given these naming conventions: .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} to test whether it should perform a particular operation, the application would call \fBdacscheck\fR, telling it to use the rules it finds in /usr/local/cal/rules\&. .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} the general rules for the application would delegate access control decisions for objects with names that match /users/\fIusername\fR/* to access control rules found in the directory /usr/local/cal/users/\fIusername\fR/rules\&. These rules would describe which users, if any, would be permitted to perform a given operation on the calendar\&. .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} the application would use object names of the form /users/\fIusername\fR/cal\-1?OP=\fIoperation\fR as arguments to \fBdacscheck\fR\&. The ruleset for cal\-1 would determine whether a given identity is allowed to perform the requested \fIoperation\fR on the calendar\&. For example, alice (the owner) might be granted access regardless of the value of the \fIOP\fR 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\&. .RE .PP Users\*(Aq 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\&. .PP See the \m[blue]\fBEXAMPLES\fR\m[]\&\s-2\u[32]\d\s+2 section for example rules\&. .PP This is by no means the only way to organize the calendars, and a delegation\-based approach isn\*(Aqt required\&. The administrator might instead put all of the rules under a common directory, like /usr/local/cal/rules/acl\-\fIusername\fR\&.0/{acl\-cal1\&.0,acl\-cal2\&.0,\&.\&.\&.}, or put them closer to the calendar they are controlling, like /usr/local/cal/users/\fIusername\fR/cal\-1/acl\-cal1\&.0\&. .PP 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\*(Aqs output line will include the constraint string within quotes\&. .SS "Comparing dacscheck with dacs_acs" .PP \m[blue]\fBdacs_acs(8)\fR\m[]\&\s-2\u[8]\d\s+2 is the \fBDACS\fR component that is called by \fBApache\fR (by the \fBDACS\fR \m[blue]\fBmod_auth_dacs\fR\m[]\&\s-2\u[25]\d\s+2 module, actually) to perform access control processing on web service requests\&. Its operation is normally invisible to web services; \fBdacs_acs\fR does all of its work before a web service is even executed or a web page is returned\&. .PP \fBdacscheck\fR performs a function similar to the \fB\-check_only\fR mode of operation of \fBdacs_acs\fR in that it simply returns an access control decision\&. There are important differences between the two programs, however\&. .PP \fBdacscheck\fR: .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} is not a CGI program (though it can be called from one); .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} does not require \m[blue]\fBmod_auth_dacs\fR\m[]\&\s-2\u[25]\d\s+2; .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} does not use any \fBDACS\fR configuration files; .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} does not directly interact with a web server or any other \fBDACS\fR programs; and .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} runs at the privilege level of the user invoking it rather than the privilege level of \fBApache\fR\&. .RE .PP While \fBdacscheck\fR uses ordinary \fBDACS\fR access control rules (\m[blue]\fBdacs\&.acls(5)\fR\m[]\&\s-2\u[7]\d\s+2), unlike most \fBDACS\fR commands it does not consult any \fBDACS\fR configuration files\&. The evaluation environment for access control rules is \fIsimilar\fR 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 \fBdacscheck\fR\&. .PP Use and configuration of \fBDACS\fR by \fBdacscheck\fR 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 \fBDACS\fR credentials are created\&. Federation and jurisdiction names are instantiated, but those who write rules will often not need to be aware of them\&. .SH "OPTIONS" .PP The arguments are processed as they are examined (left\-to\-right) and their ordering can be significant; for example, values established by the \fB\-fh\fR flag may affect options that follow it, such as those that use string interpolation\&. Exactly one \fIobject\fR argument is required\&. .PP \fB\-admin\fR .RS 4 All identities that follow on the command line are \fBDACS\fR identities that satisfy the \fBdacs_admin()\fR function\&. Refer to the ADMIN_IDENTITY configuration directive in \m[blue]\fBdacs\&.conf(5)\fR\m[]\&\s-2\u[33]\d\s+2 and the "a" attribute for identities\&. .RE .PP \fB\-app \fR\fB\fIappname\fR\fR .RS 4 Specify an application name to be used to construct default paths (see the \fB\-rules\fR and \fB\-groups\fR flags)\&. .RE .PP \fB\-context\fR \fIfile\fR .RS 4 Variable definitions for the \fIDACS\fR namespace are read, one per line, in the format \fIname\fR=\fIvalue\fR (with optional quotes around the \fIvalue\fR)\&. The \fIname\fR must be syntactically valid\&. If \fIfile\fR is \fB\-\fR, the standard input is read\&. For example, if \fIfile\fR contains the two lines: .sp .if n \{\ .RS 4 .\} .nf FOO=one BAZ=two .fi .if n \{\ .RE .\} .sp then within access control rules \fI${DACS::FOO}\fR will have the value "one" and \fI${DACS::BAZ}\fR will have the value "two"\&. This flag may be repeated, although the standard input can be read only once\&. .RE .PP \fB\-D\fR\fIname=value\fR .RS 4 This is equivalent to \fB\-var\fR \fIname=value\fR\&. .RE .PP \fB\-dump\fR .RS 4 Perform all initializations, display the evaluation context, and then exit\&. .RE .PP \fB\-F\fR \fIfield_sep\fR .RS 4 When roles are looked up, use the character \fIfield_sep\fR as the field separator character instead of the default\&. For details, refer to the description of the VFS directive in \m[blue]\fBdacs\&.conf(5)\fR\m[]\&\s-2\u[34]\d\s+2\&. .if n \{\ .sp .\} .RS 4 .it 1 an-trap .nr an-no-space-flag 1 .nr an-break-flag 1 .br .ps +1 \fBNote\fR .ps -1 .br Note that only the first occurrence of the character (from left to right) is treated as the separator character\&. .sp .5v .RE .RE .PP \fB\-fd\fR \fIdomain\fR .RS 4 Use \fIdomain\fR as the domain name for the federation\&. It must be syntactically valid\&. .RE .PP \fB\-fh\fR \fIhostname\fR .RS 4 Use \fIhostname\fR, a fully\-qualified domain name, as the system\*(Aqs hostname and to derive the federation and jurisdiction names\&. It must be syntactically valid\&. .RE .PP \fB\-fj\fR \fIjurname\fR .RS 4 Use \fIjurname\fR as the jurisdiction name\&. It must be syntactically valid\&. .RE .PP \fB\-fn\fR \fIfedname\fR .RS 4 Use \fIfedname\fR as the federation name\&. It must be syntactically valid\&. .RE .PP \fB\-groups\fR \fIgroup_vfs\fR .RS 4 By default, \fBdacscheck\fR expects to find \fBDACS\fR group definitions rooted in the directory dacscheck/groups relative to DACS_HOME (e\&.g\&., /usr/local/dacs/dacscheck/groups), or if \fB\-app \fR\fB\fIappname\fR\fR is given, rooted in the directory dacscheck/\fIappname\fR/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 \m[blue]\fBdacs\&.conf(5)\fR\m[]\&\s-2\u[35]\d\s+2) or a URI in the syntax of the \m[blue]\fBVFS\fR\m[]\&\s-2\u[34]\d\s+2 configuration directive\&. Examples: .sp .if n \{\ .RS 4 .\} .nf \-groups "[groups]dacs\-fs:/local/groups" \-groups /home/bob/mygroups .fi .if n \{\ .RE .\} .sp 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 \fBDACS\fR group directory\&. .RE .PP \fB\-h\fR .RS 4 Prints the usage blurb\&. .RE .PP \fB\-i\fR \fIident\fR .RS 4 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 \fIident\fR is the empty string, however, the flag has no effect; this is convenient behaviour when the flag is used like \fB\-i ${Env::REMOTE_USER:\-""}\fR, for example, where \fBREMOTE_USER\fR may not have been set\&. .RE .PP \fB\-icgi\fR .RS 4 If the environment variable \fBREMOTE_USER\fR is set to a valid simple name or \fBDACS\fR 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\&. .RE .PP \fB\-icgig\fR .RS 4 Like the \fB\-icgi\fR flag, except any roles associated with the username will be added\&. .RE .PP \fB\-il\fR \fIident\fR .RS 4 The given identity is "local" and must correspond to an account on the system; if the \fB\-groups\fR flag is in effect, the account\*(Aqs group membership will be added as roles to \fIident\fR\&. .RE .PP \fB\-ilg\fR \fIident\fR .RS 4 Like the \fB\-ilg\fR flag, except the account\*(Aqs group membership will be added as roles to \fIident\fR regardless of whether the \fB\-groups\fR flag is in effect\&. .RE .PP \fB\-ieuid\fR .RS 4 The effective uid of the program is added to the set of identities\&. If the \fB\-groups\fR flag is in effect, the account\*(Aqs group membership will be added as roles to \fIident\fR\&. .RE .PP \fB\-ieuidg\fR .RS 4 The effective uid of the program is added to the set of identities\&. The account\*(Aqs group membership will be added as roles to \fIident\fR regardless of whether the \fB\-groups\fR flag is in effect\&. .RE .PP \fB\-iuid\fR .RS 4 The real uid of the program is added to the set of identities\&. If the \fB\-groups\fR flag is in effect, the account\*(Aqs group membership will be added as roles to \fIident\fR\&. .RE .PP \fB\-iuidg\fR .RS 4 The real uid of the program is added to the set of identities\&. The account\*(Aqs group membership will be added as roles to \fIident\fR regardless of whether the \fB\-groups\fR flag is in effect\&. .RE .PP \fB\-lg\fR .RS 4 For each local identity that follows on the command line, use its Unix group membership to the identity\*(Aqs roles\&. .RE .PP \fB\-ll\fR \fIlog_level\fR .RS 4 Set the debugging output level to \fIlog_level\fR (see \m[blue]\fBdacs(1)\fR\m[]\&\s-2\u[23]\d\s+2)\&. The default level is warn, and the \fB\-v\fR flag bumps the level to debug or trace\&. .RE .PP \fB\-name_compare\fR \fImethod\fR .RS 4 Exactly like the \m[blue]\fBNAME_COMPARE\fR\m[]\&\s-2\u[36]\d\s+2 directive, set the default method used to compare DACS names in various contexts to \fImethod\fR, which may be (case\-insensitively) case, nocase, or default\&. .RE .PP \fB\-q\fR .RS 4 Be quiet, except for error messages; the outcome will not be printed to stdout\&. The \fB\-v\fR and \fB\-ll\fR flags are independent of this\&. .RE .PP \fB\-redirect\fR .RS 4 If access is denied and the applicable rule calls \m[blue]\fBredirect()\fR\m[]\&\s-2\u[37]\d\s+2 with the BY_SIMPLE_REDIRECT argument, then the specified URL is printed to stdout\&. This flag enables the \fB\-q\fR flag\&. .RE .PP \fB\-roles\fR \fIroles_vfs\fR .RS 4 Roles for each identity that follows on the command line will be looked up using \fIroles_vfs\fR\&. It can be an absolute pathname (which will be string interpolated \- see \m[blue]\fBdacs\&.conf(5)\fR\m[]\&\s-2\u[35]\d\s+2) or a URI in the syntax of the \m[blue]\fBVFS\fR\m[]\&\s-2\u[34]\d\s+2 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: .sp .if n \{\ .RS 4 .\} .nf bobo:users auggie:admin,users harley:guest .fi .if n \{\ .RE .\} .sp then the command line: .sp .if n \{\ .RS 4 .\} .nf % dacscheck \-roles /usr/local/myapp/roles \-i auggie /myapp/admin .fi .if n \{\ .RE .\} .sp will test access for the identity {u="auggie",g="admin,users"}\&. .RE .PP \fB\-rules\fR \fIrule_vfs\fR .RS 4 By default, \fBdacscheck\fR 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 \fB\-app \fR\fB\fIappname\fR\fR is given, rooted in the directory dacscheck/\fIappname\fR/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 \m[blue]\fBdacs\&.conf(5)\fR\m[]\&\s-2\u[35]\d\s+2) or a URI in the syntax of the \m[blue]\fBVFS\fR\m[]\&\s-2\u[34]\d\s+2 configuration directive\&. Examples: .sp .if n \{\ .RS 4 .\} .nf \-rules "[acls1]dacs\-fs:/local/acls" \-rules /usr/local/myrules .fi .if n \{\ .RE .\} .sp This flag may be repeated; rulesets will examined in the order in which they are specified on the command line\&. .RE .PP \fB\-v\fR .RS 4 Increase the level of debugging output\&. The flag may be repeated\&. .RE .PP \fB\-var\fR \fIname=value\fR .RS 4 Like the \fB\-context\fR flag, this adds a variable definition to the \fIDACS\fR namespace\&. The variable \fIDACS::\fR\fI\fIname\fR\fR will be assigned the string \fIvalue\fR\&. The \fIname\fR must be syntactically valid\&. This flag may be repeated\&. .RE .PP \fB\-\-version\fR .RS 4 Display the program\*(Aqs version information and then exit\&. .RE .PP \fB\-vfs\fR \fIvfs_uri\fR .RS 4 Add \fIvfs_uri\fR as a \m[blue]\fBVFS\fR\m[]\&\s-2\u[34]\d\s+2 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 \m[blue]\fBdacs\&.conf(5)\fR\m[]\&\s-2\u[33]\d\s+2)\&. .RE .PP \fB\-\-\fR .RS 4 This marks the end of the flag arguments\&. .RE .SH "EXAMPLES" .PP To illustrate how \fBdacscheck\fR might be used with real applications, here are some examples\&. The first few continue with the hypothetical calendar application described earlier\&. .sp .RS 4 .ie n \{\ \h'-04' 1.\h'+01'\c .\} .el \{\ .sp -1 .IP " 1." 4.2 .\} The file /usr/local/cal/rules/acl\-rule\&.0 might look like: .sp .if n \{\ .RS 4 .\} .nf user("auth") .fi .if n \{\ .RE .\} .sp This rule redirects requests for a particular user\*(Aqs calendar to that user\*(Aqs access control rules\&. It also says that access to the application\*(Aqs binaries is restricted to authenticated users\&. The application might issue a command such as: .sp .if n \{\ .RS 4 .\} .nf % dacscheck \-i $REMOTE_USER \-rules /usr/local/cal/rules \fIobject\fR .fi .if n \{\ .RE .\} .sp which will return an exit status of 0 if \fBREMOTE_USER\fR is granted access to \fIobject\fR; otherwise an exit status of 1 will be returned\&. A better choice is to use the command: .sp .if n \{\ .RS 4 .\} .nf % dacscheck \-icgi \-rules /usr/local/cal/rules \fIobject\fR .fi .if n \{\ .RE .\} .sp which will leave the user unauthenticated if \fBREMOTE_USER\fR is unset or invalid\&. .RE .sp .RS 4 .ie n \{\ \h'-04' 2.\h'+01'\c .\} .el \{\ .sp -1 .IP " 2." 4.2 .\} The file /usr/local/cal/users/alice/rules/acl\-cal1\&.0 contains the rule for user alice\*(Aqs "Calendar 1" and might look like: .sp .if n \{\ .RS 4 .\} .nf user(":alice") return(1) ${Args::OP} eq "read" user(":bob") .fi .if n \{\ .RE .\} .sp 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\&. \fBdacscheck\fR 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\&. .RE .sp .RS 4 .ie n \{\ \h'-04' 3.\h'+01'\c .\} .el \{\ .sp -1 .IP " 3." 4.2 .\} If alice defines a \fBDACS\fR 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: .sp .if n \{\ .RS 4 .\} .nf ${Args::OP} eq "read" or ${Args::OP} eq "update" user("%:alice\-family") .fi .if n \{\ .RE .\} .sp This rule says that any member of the group alice\-family is allowed read and update access to this calendar\&. The command: .sp .if n \{\ .RS 4 .\} .nf % dacscheck \-i julia /users/alice/cal\-1?OP=update .fi .if n \{\ .RE .\} .sp would report that access is granted\&. .RE .sp .RS 4 .ie n \{\ \h'-04' 4.\h'+01'\c .\} .el \{\ .sp -1 .IP " 4." 4.2 .\} The membership of alice\*(Aqs group called alice\-family might be specified in the file /usr/local/cal/users/alice/groups/family .sp .if n \{\ .RS 4 .\} .nf user(":alice") return(1) .fi .if n \{\ .RE .\} .sp 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\&. .RE .sp .RS 4 .ie n \{\ \h'-04' 5.\h'+01'\c .\} .el \{\ .sp -1 .IP " 5." 4.2 .\} As a final example for this application, alice\*(Aqs rules might also be under access control: .sp .if n \{\ .RS 4 .\} .nf user(":alice") return(1) .fi .if n \{\ .RE .\} .sp 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\&. .RE .sp .RS 4 .ie n \{\ \h'-04' 6.\h'+01'\c .\} .el \{\ .sp -1 .IP " 6." 4.2 .\} 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 \fBREMOTE_USER\fR, as exported by the web server), or based on the user\*(Aqs IP address (using \fBREMOTE_ADDR\fR)\&. 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: .sp .if n \{\ .RS 4 .\} .nf 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 \e"$remote_user\e"\en"; if ($exit_value != 0) { # dacscheck denies access; print message and exit exit 1; } # dacscheck grants access, so continue .fi .if n \{\ .RE .\} .sp .if n \{\ .sp .\} .RS 4 .it 1 an-trap .nr an-no-space-flag 1 .nr an-break-flag 1 .br .ps +1 \fBTip\fR .ps -1 .br The \fBDACS\fR distribution includes a Perl module (/usr/local/dacs/lib/perl/DACScheck\&.pm) to make \fBdacscheck\fR a little easier to use\&. The example above would be written as: .sp .if n \{\ .RS 4 .\} .nf 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 .fi .if n \{\ .RE .\} .sp .5v .RE A simple \fBDACS\fR access control rule can be written to duplicate the program\*(Aqs security functionality (using the \fBuser()\fR and \fBfrom()\fR predicates, see \m[blue]\fBdacs\&.exprs(5)\fR\m[]\&\s-2\u[22]\d\s+2), but more sophisticated policies can be added easily, all without having to modify the Perl program again\&. .RE .SH "DIAGNOSTICS" .PP The program exits 0 if access is granted and 1 if access is denied\&. Any other exit status indicates an error occurred\&. .SH "BUGS" .PP A light\-weight method of defining \fBDACS\fR groups is needed\&. Once the internal are stable, this program\*(Aqs functionality will be made available through a C/C++ API, which will permit direct, efficient use by other applications and extensible languages (through \fBperlxs(1)\fR, for example)\&. .PP The \m[blue]\fBDACS_ACS argument\fR\m[]\&\s-2\u[38]\d\s+2 is not recognized by \fBdacscheck\fR\&. .PP Identities are not considered when roles are looked up; only the username is matched\&. .PP Unlike \m[blue]\fBdacs_acs(8)\fR\m[]\&\s-2\u[8]\d\s+2, there is no support for automatically setting variables by parsing a message body (a MIME document)\&. .PP It might be possible to create a layer between an application and the underlying system so that \fBdacscheck\fR can be called transparently, or nearly so\&. .SH "SEE ALSO" .PP See \m[blue]\fBdacs(1)\fR\m[]\&\s-2\u[23]\d\s+2, \m[blue]\fBdacsacl(1)\fR\m[]\&\s-2\u[9]\d\s+2, \m[blue]\fBdacs\&.acls(5)\fR\m[]\&\s-2\u[7]\d\s+2, \m[blue]\fBdacs\&.conf(5)\fR\m[]\&\s-2\u[33]\d\s+2, \m[blue]\fBdacs\&.exprs(5)\fR\m[]\&\s-2\u[22]\d\s+2, \m[blue]\fBdacs\&.groups(5)\fR\m[]\&\s-2\u[24]\d\s+2, \m[blue]\fBdacs\&.java(7)\fR\m[]\&\s-2\u[39]\d\s+2\&. .PP \m[blue]\fBRule\-based access control\fR\m[]\&\s-2\u[40]\d\s+2 .PP DACScheck\&.pm .SH "AUTHOR" .PP Distributed Systems Software (\m[blue]\fBwww\&.dss\&.ca\fR\m[]\&\s-2\u[41]\d\s+2) .SH "COPYING" .PP Copyright \(co 2003\-2018 Distributed Systems Software\&. See the \m[blue]\fBLICENSE\fR\m[]\&\s-2\u[42]\d\s+2 file that accompanies the distribution for licensing information\&. .SH "NOTES" .IP " 1." 4 Perl .RS 4 \%http://www.perl.org/ .RE .IP " 2." 4 PHP .RS 4 \%http://www.php.net/ .RE .IP " 3." 4 Python .RS 4 \%http://www.python.org .RE .IP " 4." 4 Ruby .RS 4 \%http://www.ruby-lang.org .RE .IP " 5." 4 Tcl/Tk .RS 4 \%http://www.tcl.tk/software/ .RE .IP " 6." 4 geteuid(2) .RS 4 \%https://www.freebsd.org/cgi/man.cgi?query=geteuid&apropos=0&sektion=2&manpath=FreeBSD+10.3-RELEASE&format=html .RE .IP " 7." 4 dacs.acls(5) .RS 4 \%http://dacs.dss.ca/man/dacs.acls.5.html .RE .IP " 8." 4 dacs_acs(8) .RS 4 \%http://dacs.dss.ca/man/dacs_acs.8.html .RE .IP " 9." 4 dacsacl(1) .RS 4 \%http://dacs.dss.ca/man/dacsacl.1.html .RE .IP "10." 4 getfacl(1) .RS 4 \%https://www.freebsd.org/cgi/man.cgi?query=getfacl&apropos=0&sektion=1&manpath=FreeBSD+10.3-RELEASE&format=html .RE .IP "11." 4 setfacl(1) .RS 4 \%https://www.freebsd.org/cgi/man.cgi?query=setfacl&apropos=0&sektion=1&manpath=FreeBSD+10.3-RELEASE&format=html .RE .IP "12." 4 acl(3) .RS 4 \%https://www.freebsd.org/cgi/man.cgi?query=acl&apropos=0&sektion=3&manpath=FreeBSD+10.3-RELEASE&format=html .RE .IP "13." 4 htpasswd(1) .RS 4 \%http://httpd.apache.org/docs/2.4/programs/htpasswd.html .RE .IP "14." 4 Using FreeBSD's ACLs .RS 4 \%http://www.onlamp.com/pub/a/bsd/2005/09/22/FreeBSD_Basics.html .RE .IP "15." 4 ONLamp.com .RS 4 \%http://www.onlamp.com .RE .IP "16." 4 POSIX ACLs in Linux .RS 4 \%http://www.cs.unc.edu/cms/help/help-articles/posix-acls-in-linux .RE .IP "17." 4 linux.com .RS 4 \%http://linux.com .RE .IP "18." 4 Solaris acl(2) and facl(2) .RS 4 \%http://docs.oracle.com/cd/E18752_01/html/816-5167/facl-2.html .RE .IP "19." 4 Sun Microsystems .RS 4 \%http://www.sun.com .RE .IP "20." 4 Using Solaris ACLs .RS 4 \%http://www.cs.duke.edu/csl/faqs/solaris-acls.php .RE .IP "21." 4 Dept. of Computer Science, Duke University .RS 4 \%http://www.cs.duke.edu .RE .IP "22." 4 dacs.exprs(5) .RS 4 \%http://dacs.dss.ca/man/dacs.exprs.5.html .RE .IP "23." 4 dacs(1) .RS 4 \%http://dacs.dss.ca/man/dacs.1.html .RE .IP "24." 4 dacs.groups(5) .RS 4 \%http://dacs.dss.ca/man/dacs.groups.5.html .RE .IP "25." 4 mod_auth_dacs .RS 4 \%http://dacs.dss.ca/man/mod_auth_dacs.html .RE .IP "26." 4 dacs(1) .RS 4 \%http://dacs.dss.ca/man/dacs.1.html#naming .RE .IP "27." 4 concise syntax .RS 4 \%http://dacs.dss.ca/man/dacs.1.html#concise_user_syntax .RE .IP "28." 4 gethostname(3) .RS 4 \%https://www.freebsd.org/cgi/man.cgi?query=gethostname&apropos=0&sektion=3&manpath=FreeBSD+10.3-RELEASE&format=html .RE .IP "29." 4 gethostbyname(3) .RS 4 \%https://www.freebsd.org/cgi/man.cgi?query=gethostbyname&apropos=0&sektion=3&manpath=FreeBSD+10.3-RELEASE&format=html .RE .IP "30." 4 RFC 1738 .RS 4 \%http://www.rfc-editor.org/rfc/rfc1738.txt .RE .IP "31." 4 RFC 3986 .RS 4 \%http://www.rfc-editor.org/rfc/rfc3986.txt .RE .IP "32." 4 EXAMPLES .RS 4 \%http://dacs.dss.ca/man/#EXAMPLES .RE .IP "33." 4 dacs.conf(5) .RS 4 \%http://dacs.dss.ca/man/dacs.conf.5.html .RE .IP "34." 4 dacs.conf(5) .RS 4 \%http://dacs.dss.ca/man/dacs.conf.5.html#VFS .RE .IP "35." 4 dacs.conf(5) .RS 4 \%http://dacs.dss.ca/man/dacs.conf.5.html#interpolation .RE .IP "36." 4 NAME_COMPARE .RS 4 \%http://dacs.dss.ca/man/dacs.conf.5.html#NAME_COMPARE .RE .IP "37." 4 redirect() .RS 4 \%http://dacs.dss.ca/man/dacs.exprs.5.html#redirect .RE .IP "38." 4 DACS_ACS argument .RS 4 \%http://dacs.dss.ca/man/dacs_acs.8.html#dacs_acs_argument .RE .IP "39." 4 dacs.java(7) .RS 4 \%http://dacs.dss.ca/man/dacs.java.7.html .RE .IP "40." 4 Rule-based access control .RS 4 \%http://www-128.ibm.com/developerworks/webservices/library/ws-soa-access.html .RE .IP "41." 4 www.dss.ca .RS 4 \%http://www.dss.ca .RE .IP "42." 4 LICENSE .RS 4 \%http://dacs.dss.ca/man/../misc/LICENSE .RE