GACL 0.1.6 Release Notes

GACL is a C library for manipulating Grid Access Control Lists, written in XML-based Access Control Languages. The aim of GACL is to insulate application authors from changes in ACL format and to provide easy access to ACL information (ie to remove the need for every application to know how to parse XML and evaluate ACL's.)

Getting GACL

The GACL homepage is at http://www.gridpp.ac.uk/authz/gacl/ and the current source code is available from the EDG CVS at http://datagrid.in2p3.fr/cgi-bin/cvsweb.cgi/gacl/

Installation

GACL requires libxml2 and libxml2-devel and has been validated with libxml2 version 2.4.22. Suitable versions of libxml2 RPM's for use on EDG RedHat 6.2 machines are available from http://datagrid.in2p3.fr/distribution/external/RPMS

To build GACL, unpack the source tar ball and in the gacl-VERSION directory, just do make, followed by make install as root. This will install the gacl.h in /usr/include and the static and shared libraries in /usr/lib

The current copy of these release notes is installed as /usr/share/doc/gacl-VERSION/notes.html and there is the source of a test program, gaclexample.c, which can be used to test the installation and demonstrate basic use of the library.

The source tarball also contains an RPM spec file, gacl.spec, which can be used to build RPM's in the normal way.

API

Features planned but not yet implemented are indicated by [...]

GACL types

GACLcred
A single credential required by an ACL, consisting of string giving the type of credential and zero or more name/value string pairs, depending on the type.
Credential types currently defined in GACL version 0.1.6 are ldap-group, cas-cred, voms-cred, any-user and auth-user.

GACLperm
An access perm.
Currently, GACL_PERM_NONE, GACL_PERM_READ, GACL_PERM_LIST, GACL_PERM_WRITE, and GACL_PERM_ADMIN (ie the ability to modify the ACL itself.)

GACLentry
A set of one or more credentials in an ACL, and associated allow and denys for specified access perms. If more than one credential is given, they must all be satisfied for the entry to apply to a given identity (ie AND is the operation within an entry.)

GACLacl
A set of one or more entries.
When evaluated, a user is tested against the entries in turn, resulting in an OR between entries. Allow and Denies are evaluated seperately and combined at the end of ACL processing in such a way that any Denies for a specific permission type override any Allows. In this way, the order of Entries in the ACL is not significant.

GACLuser
A set of credentials owned by a user.
Person DN and EDG VOMS credential types are supported in GACLuser (DN Lists, including EDG LDAP VO, in GACLacl matches against Person DN in GACLuser.)

Credential type mapping into GACL

The following list shows how the properties of different credential types are stored in GACL XML Access Control Lists.

Person "/O=Grid/OU=..."
<person>
<dn>/O=Grid/OU=...</dn>
</person>

DN List / EDG LDAP VO ldap://a.b.com:389/ou=d,dc=a,dc=b,dc=com
<dn-list>
<url>ldap://a.b.com:389/ou=d,dc=a,dc=b,dc=com</url>
</dn-list>

VOMS credential
<voms-cred>
<voms>DN of VOMS</voms> <vo>VO</vo> <group>Group</group> <group>Subgroup</group> <role>Role</role> <capability>Capability</capability>
</voms-cred>

GACL functions

Unless otherwise noted, functions returning int values, return 1 for success or 0 on failure. Functions returning pointers, return NULL on failure.

GACLcred *GACLnewCred(char *type)
Create and initialise a new credential of type *type.

int GACLaddToCred(GACLcred *cred, char *name, char *value)
Add a name/value pair to the end of this credential's list of name/value pairs.

int GACLfreeCred(GACLcred *cred)
Free the memory used by an existing credential.

int GACLaddCred(GACLentry *entry, GACLcred *cred)
Add a credential to an existing entry.

int GACLdelCred(GACLentry *entry, GACLcred *cred)
Remove a credential from an existing entry.

int GACLprintCred(GACLcred *cred, FILE *fp)
Print a credential to file fp as an XML fragment.

GACLentry *GACLnewEntry(void)
Create a new and empty entry.

int GACLfreeEntry(GACLentry *entry)
Free the memory used by an existing entry, and the memory used by all the credentials it contains.

int GACLaddEntry(GACLacl *acl, GACLentry *entry)
Add an entry to an existing ACL [inserting it in the correct place in the list of entries, according to a deterministic priority. This allows unique hashing for each equivalent ACL.]

int GACLprintEntry(GACLentry *entry, FILE *fp)
Print an entry to file fp as an XML fragment.

int GACLprintPerm(GACLperm perm, FILE *fp)
Print a perm to file fp as an XML tag (eg GACL_PERM_READ gives <read/>)

int GACLallowPerm(GACLentry *entry, GACLperm perm)
Set a perm to be explicitly allowed in an entry, ignoring the previous allow state of that perm.

int GACLunallowPerm(GACLentry *entry, GACLperm perm)
Prevent a perm being explicitly allowed by an entry, ignoring the previous allow state of that perm.

int GACLdenyPerm(GACLentry *entry, GACLperm perm)
Set a perm to be explicitly denied in an entry, ignoring the previous deny state of that perm.

int GACLundenyPerm(GACLentry *entry, GACLperm perm)
Prevent a perm being explicitly denied by an entry, ignoring the previous deny state of that perm.

char *GACLpermToChar(GACLperm perm)
Return a pointer to a static string containing the name of a given perm. (The string must not be freed after use.)

GACLperm GACLcharToPerm(char *s)
Return the perm associated with a given perm name.

GACLacl *GACLnewAcl(void)
Creating a new and empty ACL.

int GACLfreeAcl(GACLacl *acl)
Free the memory used by an existing ACL, and the memory used by any entries and credentials it may contain.

int GACLprintAcl(GACLacl *acl, FILE *fp)
Print a complete XML ACL to file fp, enclosed by <gacl>...</gacl> (You should prefix this with an XML version tag yourself if the file is to contain only an ACL.)

int GACLsaveAcl(char *filename, GACLacl *acl)
Write out a complete XML ACL to a file.

GACLacl *GACLloadAcl(char *filename)
Load an XML ACL from a file.

GACLacl *GACLloadAclForFile(char *filename)
Load the ACL which governs a given file. This is done by looking for file .gacl in the same directory as the file. If no such ACL exists, parent directories are searched in ascending order. [This will be extended to also search for per-file ACL's of the form .gacl-filename in a future release.]

char *GACLfindAclForFile(char *filename)
Return the ACL filename which governs a given file. This is done by looking for file .gacl in the same directory as the file. If no such ACL exists, parent directories are searched in ascending order. [This will be extended to also search for per-file ACL's of the form .gacl-filename in a future release.] The filename is a point to malloc'd memory which must be freed by the calling function.

int GACLisAclFile(char *filename)
Returns 1 if the full pathname filename is an ACL (ie is .gacl when the path is removed.) [Support for per-file ACL's will be added.]

int GACLtestDnList(char *listurl, GACLuser *user)
Test whether a given user is a member of a given DN List group, such as an EDG LDAP VO group.

GACLuser *GACLnewUser(GACLcred *cred)
Create a new user with a single credential.

int GACLfreeUser(GACLuser *user)
Free the storage used by *user.

int GACLuserAddCred(GACLuser *user, GACLcred *cred)
Add a credential to those a given user already has.

int GACLuserHasCred(GACLuser *user, GACLcred *cred)
Test if the user has the given credential.

GACLcred *GACLuserFindCredType(GACLuser *user, char *type)
Find the first credential of a given type for this user.

GACLperm GACLtestUserAcl(GACLacl *acl, GACLuser *user)
Find the access perm of a given user implied by an ACL. *user should be NULL if the user has no credentials.

GACLperm GACLtestExclAcl(GACLacl *acl, GACLuser *user)
Find the permissions which are exclusive to this user for the given ACL. That is, those permissions which no other user could obtain when presenting their credentials to this ACL. This is useful for testing whether files such as private keys are in fact world or group readable.

int GACLhasNone(GACLperm perm)
int GACLhasRead(GACLperm perm)
int GACLhasList(GACLperm perm)
int GACLhasWrite(GACLperm perm)
int GACLhasAdmin(GACLperm perm)
Macros to test whether perm gives the user a specific access permission.

char *GACLurlEncode(char *string)
URL-encode a string, converting all characters other than 0-9, A-Z, a-z, . = and - to %HH where HH is their ASCII value in hexadecimal. This can be used to produced filesystem-safe filenames from arbitrary strings.

char *GACLmildUrlEncode(char *string)
Partially URL-encode a string, converting all characters other than 0-9, A-Z, a-z, . = _ @ / and - to %HH where HH is their ASCII value in hexadecimal. This preserves more of the readability of the string than GACLurlEncode() and in particular, any directory-like structure, since / is passed through unmodified.

Other defined symbols

#define GACL_ACL_FILE ".gacl"
Used as the filename of per-directory ACL's, and as the prefix of per-file ACL's.

#define GACL_DN_LISTS "/etc/grid-security/dn-lists"
The default directory holding lists of DN's forming groups - can be overridden at runtime by the environment variable GACL_DN_LISTS

DN Lists

DN Lists, such as EDG VO LDAP groups, are stored by default in the directory /etc/grid-security/dn-lists (this location can be overridden at runtime by the environment variable GACL_DN_LISTS) Each list takes the form of a plain text file with one DN per line. The file name is the URL-encoded URL of the original location of the list (eg ldap://a.b.com:389/ou=d,dc=a,dc=b,dc=com for an EDG VO LDAP group.)

In the current release, the lists directory must be populated by an external program, rather than by GACL itself. (For EDG VO LDAP groups, a tool like mkgridmap can easily be used to do this periodically from cron.)

An example ACL

<gacl>
<entry>
<person>
<dn>/O=Grid/CN=Andrew</dn>
</person>
<allow><read/><write/><admin/></allow>
<deny><list/><admin/></deny>
</entry>
<entry>
<dn-list>
<url>ldap://a.b.com:389/ou=d,dc=a,dc=b,dc=com</url>
</dn-list>
<allow><read/></allow>
</entry>
</gacl>

Changes

For a full list of changes, see the CHANGELOG included in the source tarball or installed in /usr/share/doc/gacl-VERSION.

There is one very important API change since 0.1.1: GACLnewCred() now has only 1 parameter and does not initialise the name/value pairs associated with the cred. This is now done with GACLaddToCred(), allowing credentials of arbitrary complexity.

Also, the function GACLtestCredAcl() has been removed - you can achieve the same functionality with GACLtestUserAcl by creating a temporary GACLuser for the test.

More information

For information about GACL see http://www.gridpp.ac.uk/authz/gacl/

Andrew McNab <mcnab@hep.man.ac.uk> 24 January 2003