From c80b109d36b9d9de2a45f5211d2f412511a2a361 Mon Sep 17 00:00:00 2001 From: Shiv Kaushal Date: Mon, 23 May 2005 11:51:23 +0000 Subject: [PATCH] added files for XACML functions and example source code. --- org.gridsite.core/src/Makefile | 19 +- org.gridsite.core/src/grst_xacml.c | 556 +++++++++++++++++++++++++++++++++++ org.gridsite.core/src/xacmlexample.c | 148 ++++++++++ 3 files changed, 718 insertions(+), 5 deletions(-) create mode 100644 org.gridsite.core/src/grst_xacml.c create mode 100644 org.gridsite.core/src/xacmlexample.c diff --git a/org.gridsite.core/src/Makefile b/org.gridsite.core/src/Makefile index 0acfe92..e7e48ac 100644 --- a/org.gridsite.core/src/Makefile +++ b/org.gridsite.core/src/Makefile @@ -64,12 +64,12 @@ build: libgridsite_globus.so.$(VERSION) libgridsite_globus.a # First, normal versions using system OpenSSL rather than Globus OpenSSL -libgridsite.so.$(VERSION): grst_x509.o grst_gacl.o grst_http.o grst_asn1.o +libgridsite.so.$(VERSION): grst_x509.o grst_gacl.o grst_xacml.o grst_http.o grst_asn1.o gcc -shared -Wl,-soname,libgridsite.so.$(MINOR_VERSION) \ - -o libgridsite.so.$(PATCH_VERSION) grst_x509.o grst_gacl.o grst_http.o grst_asn1.o + -o libgridsite.so.$(PATCH_VERSION) grst_x509.o grst_gacl.o grst_xacml.o grst_http.o grst_asn1.o -libgridsite.a: grst_x509.o grst_gacl.o grst_http.o grst_asn1.o - ar src libgridsite.a grst_x509.o grst_gacl.o grst_http.o grst_asn1.o +libgridsite.a: grst_x509.o grst_gacl.o grst_xacml.o grst_http.o grst_asn1.o + ar src libgridsite.a grst_x509.o grst_gacl.o grst_xacml.o grst_http.o grst_asn1.o grst_x509.o: grst_x509.c ../interface/gridsite.h gcc $(MYCFLAGS) \ @@ -79,6 +79,10 @@ grst_gacl.o: grst_gacl.c ../interface/gridsite.h gcc $(MYCFLAGS) \ -I/usr/kerberos/include `xml2-config --cflags` -c grst_gacl.c +grst_xacml.o: grst_xacml.c ../interface/gridsite.h + gcc $(MYCFLAGS) \ + -I/usr/kerberos/include `xml2-config --cflags` -c grst_xacml.c + grst_http.o: grst_http.c ../interface/gridsite.h gcc $(MYCFLAGS) \ -I/usr/kerberos/include -c grst_http.c @@ -176,7 +180,12 @@ apidoc: gaclexample: gaclexample.c libgridsite.a gcc -o gaclexample gaclexample.c -I. -L. \ -I/usr/kerberos/include -lgridsite \ - -lssl -lcrypto -lxml2 -lz -lm + -lssl -lcrypto -lxml2 -lz -lm + +xacmlexample: xacmlexample.c libgridsite.a + gcc -o xacmlexample xacmlexample.c -I. -L. \ + -I/usr/kerberos/include -lgridsite \ + -lssl -lcrypto -lxml2 -lz -lm # # Delegation machinery, including SOAP delegation portType. To build this diff --git a/org.gridsite.core/src/grst_xacml.c b/org.gridsite.core/src/grst_xacml.c new file mode 100644 index 0000000..6beff98 --- /dev/null +++ b/org.gridsite.core/src/grst_xacml.c @@ -0,0 +1,556 @@ +/* + Andrew McNab and Shiv Kaushal, University of Manchester. + Copyright (c) 2002-3. All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, are permitted provided that the following + conditions are met: + + o Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + o Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ +/*------------------------------------------------------------------------* + * For more information about GridSite: http://www.gridpp.ac.uk/gridsite/ * + *------------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include + +#include +#include +#include + +#include "gridsite.h" + +//#define XACML_DEBUG + +#ifdef XACML_DEBUG + #define XACML_DEBUG_FILE "/tmp/grstxacmldebug.out" +#endif + + +/* * + * Global variables, shared by all GACL functions by private to libgacl * + * */ + +extern char *grst_perm_syms[]; +extern GRSTgaclPerm grst_perm_vals[]; + + +FILE* debugfile; + + +/* * + * Functions to read in XACML 1.1 compliant format ACL * + * Functions based on method for opening GACL format * + * */ + +// need to check these for libxml memory leaks? - what needs to be freed? + + +static GRSTgaclCred *GRSTxacmlCredParse(xmlNodePtr cur) +/* + GRSTxacmlCredParse - parse a credential stored in the libxml structure cur, + returning it as a pointer or NULL on error. +*/ +{ + xmlNodePtr attr_val; + xmlNodePtr attr_des; + GRSTgaclCred *cred; + + // cur points to or , loop done outside this function. + + if ( (xmlStrcmp(cur->name, (const xmlChar *) "AnySubject") == 0)) cred = GRSTgaclCredNew("any-user"); + + else{ + + attr_val=cur->xmlChildrenNode->xmlChildrenNode; + attr_des=attr_val->next; + + cred = GRSTgaclCredNew((char *) xmlNodeGetContent(attr_des->properties->children)); + + cred->firstname = NULL; + cred->next = NULL; + + //Assumed that there is only one name/value pair per credential + GRSTgaclCredAddValue(cred, (char *) xmlNodeGetContent(attr_des->properties->next->children), + (char *) xmlNodeGetContent(attr_val)); + } + + return cred; +} + +static GRSTgaclEntry *GRSTxacmlEntryParse(xmlNodePtr cur) +/* + GRSTxacmlEntryParse - parse an entry stored in the libxml structure cur, + returning it as a pointer or NULL on error. Also checks to see if the following + tag refers to the same by checking the of both +*/ +{ + int i, check=0; + xmlDocPtr doc=cur->doc; + xmlNodePtr cur2; + xmlNodePtr rule_root=cur; + GRSTgaclEntry *entry; + GRSTgaclCred *cred; + GRSTgaclPerm perm; + + + // Next line not needed as function only called if tag found + // if (xmlStrcmp(cur->name, (const xmlChar *) "Rule") != 0) return NULL; + // cur and rule_root point to the tag + + cur = cur->xmlChildrenNode->xmlChildrenNode; + // cur should now be pointing at tag +#ifdef XACML_DEBUG + fprintf (debugfile, "Starting to Parse Entry\n"); +#endif + entry = GRSTgaclEntryNew(); + + while (cur!=NULL){ + + if (xmlStrcmp(cur->name, (const xmlChar *) "Subjects") == 0){ +#ifdef XACML_DEBUG + fprintf (debugfile, "Starting to Parse Credentials\n"); +#endif + if (check==0){ + // cur still pointing at tag make cur2 point to and loop over them. + cur2=cur->xmlChildrenNode; + while (cur2!=NULL){ + if ( ((cred = GRSTxacmlCredParse(cur2)) != NULL) && (!GRSTgaclEntryAddCred(entry, cred))){ + GRSTgaclCredFree(cred); + GRSTgaclEntryFree(entry); + return NULL; + } + cur2=cur2->next; + } + } + } + + else if (xmlStrcmp(cur->name, (const xmlChar *) "Actions") == 0){ +#ifdef XACML_DEBUG + fprintf (debugfile, "Starting to Parse Permissions\n"); +#endif + if (xmlStrcmp(xmlNodeGetContent(rule_root->properties->next->children), (const xmlChar *) "Permit") == 0 ){ +#ifdef XACML_DEBUG + fprintf (debugfile, "\tPermit-ed actions: "); +#endif + for (cur2 = cur->xmlChildrenNode; cur2 != NULL; cur2=cur2->next) //cur2-> + for (i=0; grst_perm_syms[i] != NULL; ++i) + if (xmlStrcmp(xmlNodeGetContent(cur2->xmlChildrenNode->xmlChildrenNode), (const xmlChar *) grst_perm_syms[i]) == 0) + { +#ifdef XACML_DEBUG + fprintf (debugfile, "%s ", grst_perm_syms[i]); +#endif + GRSTgaclEntryAllowPerm(entry, grst_perm_vals[i]); + } + } + + if (xmlStrcmp(xmlNodeGetContent(rule_root->properties->next->children), (const xmlChar *) "Deny") == 0 ) { +#ifdef XACML_DEBUG + fprintf (debugfile, "\tDeny-ed actions: "); +#endif + for (cur2 = cur->xmlChildrenNode; cur2 != NULL; cur2=cur2->next) //cur2-> + for (i=0; grst_perm_syms[i] != NULL; ++i) + if (xmlStrcmp(xmlNodeGetContent(cur2->xmlChildrenNode->xmlChildrenNode), (const xmlChar *) grst_perm_syms[i]) == 0) + { + +#ifdef XACML_DEBUG + fprintf (debugfile, "%s ", grst_perm_syms[i]); +#endif + GRSTgaclEntryDenyPerm(entry, grst_perm_vals[i]); + } + } + + } + else{ // I cannot parse this - give up rather than get it wrong +#ifdef XACML_DEBUG + fprintf (debugfile, "OOOPSIE\n"); +#endif + GRSTgaclEntryFree(entry); + return NULL; + } + + cur=cur->next; + + // Check if next Rule should be included when end of current rule reached + // If RuleId are from the same entry (eg Entry1A and Entry1D) + // make cur point to the next Rule's tag + if (cur==NULL) + if (check==0) + if (rule_root->next!=NULL) + if ( strncmp(xmlNodeGetContent(rule_root->properties->children), // RuleId of this Rule + xmlNodeGetContent(rule_root->next->properties->children), // RuleId of next Rule + 6) == 0){ +#ifdef XACML_DEBUG + fprintf (debugfile, "End of perms and creds, next is %s \n", xmlNodeGetContent(rule_root->next->properties->children)); +#endif + rule_root=rule_root->next; + cur=rule_root->xmlChildrenNode->xmlChildrenNode; +#ifdef XACML_DEBUG + fprintf (debugfile, "skipped to <%s> tag of next Rule\n", cur->name); +#endif + check++; + } + } + + return entry; +} + +GRSTgaclAcl *GRSTxacmlAclLoadFile(char *filename) +{ + xmlDocPtr doc; + xmlNodePtr cur; + GRSTgaclAcl *acl; + GRSTgaclEntry *entry; +#ifdef XACML_DEBUG + debugfile=fopen(XACML_DEBUG_FILE, "w"); + fprintf (debugfile, "Loading acl..\n"); +#endif + doc = xmlParseFile(filename); + if (doc == NULL) return NULL; + + cur = xmlDocGetRootElement(doc); + if (cur == NULL) return NULL; + + if (xmlStrcmp(cur->name, (const xmlChar *) "Policy")) + { + free(doc); + free(cur); + return NULL; + } +#ifdef XACML_DEBUG + fprintf (debugfile, "Error Checks done, load acl\n"); +#endif + // Have an XACML policy file. + // Skip tag and set cur to first tag + cur = cur->xmlChildrenNode->next; + + acl = GRSTgaclAclNew(); + + while (cur != NULL){ + + + if ( xmlStrcmp(cur->name, (const xmlChar *)"Rule") == 0 ){ // IF statement not needed? +#ifdef XACML_DEBUG + fprintf (debugfile, "Rule %s found\n", xmlNodeGetContent(cur->properties->children) ); + fprintf (debugfile, "Parsing Entry for this rule\n"); +#endif + entry = GRSTxacmlEntryParse(cur); + + if (entry == NULL){ + GRSTgaclAclFree(acl); + xmlFreeDoc(doc); + return NULL; + } + else GRSTgaclAclAddEntry(acl, entry); +#ifdef XACML_DEBUG + fprintf (debugfile, "Entry read in\n\n"); +#endif + } + // If the current and next Rules are part of the same entry then advance two Rules + // If not then advance 1 + if (cur->next != NULL) + if ( strncmp(xmlNodeGetContent(cur->properties->children), // RuleId of this Rule + xmlNodeGetContent(cur->next->properties->children), // RuleId of next Rule + 6) == 0) { +#ifdef XACML_DEBUG + fprintf (debugfile, "skipping next rule %s, should have been caught previously\n\n", xmlNodeGetContent(cur->next->properties->children) ); +#endif + cur=cur->next; + } // Check first 6 characters i.e. Entry1**/ + cur=cur->next; + + } +#ifdef XACML_DEBUG + fprintf (debugfile, "Finished loading ACL - Fanfare!\n"); + fclose(debugfile); +#endif + xmlFreeDoc(doc); + return acl; +} + +int GRSTxacmlFileIsAcl(char *pathandfile) +/* Return 1 if filename in *pathandfile starts GRST_ACL_FILE + Return 0 otherwise. */ +{ + char *filename; + + filename = rindex(pathandfile, '/'); + if (filename == NULL) filename = pathandfile; + else filename++; + + return (strncmp(filename, GRST_ACL_FILE, sizeof(GRST_ACL_FILE) - 1) == 0); +} + +char *GRSTxacmlFileFindAclname(char *pathandfile) +/* Return malloc()ed ACL filename that governs the given file or directory + (for directories, the ACL file is in the directory itself), or NULL if none + can be found. */ +{ + char *path, *p; + struct stat statbuf; + + path = malloc(strlen(pathandfile) + sizeof(GRST_ACL_FILE) + 1); + strcpy(path, pathandfile); + + if (stat(path, &statbuf) == 0) + { + if (!S_ISDIR(statbuf.st_mode)) /* can strip this / off straightaway */ + { + p = rindex(path, '/'); + if (p != NULL) *p = '\0'; + } + } + + while (path[0] != '\0') + { + strcat(path, "/"); + strcat(path, GRST_ACL_FILE); + + if (stat(path, &statbuf) == 0) return path; + + p = rindex(path, '/'); + *p = '\0'; /* strip off the / we added for ACL */ + + p = rindex(path, '/'); + if (p == NULL) break; /* must start without / and we there now ??? */ + + *p = '\0'; /* strip off another layer of / */ + } + + free(path); + return NULL; +} + +GRSTgaclAcl *GRSTxacmlAclLoadforFile(char *pathandfile) +/* Return ACL that governs the given file or directory (for directories, + the ACL file is in the directory itself.) */ +{ + char *path; + GRSTgaclAcl *acl; + + path = GRSTxacmlFileFindAclname(pathandfile); + + if (path != NULL) + { + acl = GRSTxacmlAclLoadFile(path); + free(path); + return acl; + } + + return NULL; +} + + + +/* * + * Functions to save ACL in XACML 1.1 compliant format * + * Functions based on method for saving to GACL format * + * */ + + +int GRSTxacmlCredPrint(GRSTgaclCred *cred, FILE *fp) +/* + GRSTxacmlCredPrint - print a credential and any name-value pairs is contains in XACML form +*/ +{ + char *q; + GRSTgaclNamevalue *p; + + if (cred->firstname != NULL) + { + + p = cred->firstname; + + do { + + fputs("\t\t\t\t\n", fp); + fputs("\t\t\t\t\t\n", fp); + fputs("\t\t\t\t\t\t", fp); + for (q=p->value; *q != '\0'; ++q) + if (*q == '<') fputs("<", fp); + else if (*q == '>') fputs(">", fp); + else if (*q == '&') fputs("&" , fp); + else if (*q == '\'') fputs("'", fp); + else if (*q == '"') fputs(""", fp); + else fputc(*q, fp); + + + fputs("\n", fp); + + fputs("\t\t\t\t\t\ttype); + fputs("\t\t\t\t\t\t\tDataType=", fp); + fprintf(fp, "\"%s\"/>\n", p->name); + fputs("\t\t\t\t\t\n", fp); + fputs("\t\t\t\t\n", fp); + p = (GRSTgaclNamevalue *) p->next; + } while (p != NULL); + + } + else fputs("\t\t\t\t\n", fp); + + return 1; +} + + +int GRSTxacmlEntryPrint(GRSTgaclEntry *entry, FILE *fp, int rule_number) +{ + GRSTgaclCred *cred; + GRSTgaclPerm i; + + if (entry->allowed){ + + fprintf(fp, "\t\n", rule_number); + fputs("\t\t\n", fp); + fputs("\t\t\t\n", fp); + + for (cred = entry->firstcred; cred != NULL; cred = cred->next) + GRSTxacmlCredPrint(cred, fp); + + fputs("\t\t\t\n", fp); + fputs("\t\t\t\n", fp); + + for (i=GRST_PERM_READ; i <= GRST_PERM_ADMIN; ++i) + if ((entry->allowed) & i) GRSTxacmlPermPrint(i, fp); + + fputs("\t\t\t\n", fp); + fputs("\t\t\n", fp); + fputs("\t\n", fp); + } + + if (entry->denied){ + + fprintf(fp, "\t\n", rule_number); + fputs("\t\t\n", fp); + fputs("\t\t\t\n", fp); + + for (cred = entry->firstcred; cred != NULL; cred = cred->next) + GRSTxacmlCredPrint(cred, fp); + + fputs("\t\t\t\n", fp); + fputs("\t\t\t\n", fp); + + for (i=GRST_PERM_READ; i <= GRST_PERM_ADMIN; ++i) + if (entry->denied & i) GRSTxacmlPermPrint(i, fp); + + fputs("\t\t\t\n", fp); + fputs("\t\t\n", fp); + fputs("\t\n", fp); + } + return 1; +} + + +int GRSTxacmlPermPrint(GRSTgaclPerm perm, FILE *fp) +{ + GRSTgaclPerm i; + + for (i=GRST_PERM_READ; grst_perm_syms[i] != NULL; ++i) + if (perm == grst_perm_vals[i]) + { + + fputs("\t\t\t\t\n", fp); + fputs("\t\t\t\t\t\n", fp); + fputs("\t\t\t\t\t\t", fp); + fprintf(fp, "%s", grst_perm_syms[i]); + fputs("\n", fp); + fputs("\t\t\t\t\t\t\n", fp); + fputs("\t\t\t\t\t\n", fp); + fputs("\t\t\t\t\n",fp); + + return 1; + } + + return 0; +} + +int GRSTxacmlAclPrint(GRSTgaclAcl *acl, FILE *fp, char* dir_uri) +{ + GRSTgaclEntry *entry; + int rule_number=1; + + fputs("\n\n", fp); + + fputs("\t\n\t\t\n\t\t\t\n", fp); + fputs("\t\t\t\t\n", fp); + fputs("\t\t\t\t\t", fp); + fprintf(fp, "%s", dir_uri); + fputs("\n", fp); + fputs("\t\t\t\t\t\n", fp); + + fputs("\t\t\t\t\n\t\t\t\n\t\t\n\t\t\n\t\t\t\n\t\t", fp); + fputs("\n\t\t\n\t\t\t\n\t\t\n\t\n\n", fp); + + for (entry = acl->firstentry; entry != NULL; entry = entry->next){ + + GRSTxacmlEntryPrint(entry, fp, rule_number); + rule_number++; + } + + fputs("\n", fp); + + return 1; +} + +int GRSTxacmlAclSave(GRSTgaclAcl *acl, char *filename, char* dir_uri) +{ + int ret; + FILE *fp; + + fp = fopen(filename, "w"); + if (fp == NULL) return 0; + + fprintf(fp,"\n"); + + ret = GRSTxacmlAclPrint(acl, fp, dir_uri); + + fclose(fp); + + return ret; +} + + + + diff --git a/org.gridsite.core/src/xacmlexample.c b/org.gridsite.core/src/xacmlexample.c new file mode 100644 index 0000000..07baafa --- /dev/null +++ b/org.gridsite.core/src/xacmlexample.c @@ -0,0 +1,148 @@ +/* + Copyright (c) 2002-3, Andrew McNab, University of Manchester + All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, are permitted provided that the following + conditions are met: + + o Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + o Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +/*---------------------------------------------------------------* + * For more about GridSite: http://www.gridsite.org/ * + *---------------------------------------------------------------*/ + +/* + Example program using XACML + + Build with: + + gcc -o xacmlexample xacmlexample.c -L. -I. -lgridsite -lxml2 -lz -lm +*/ + +#include +#include +#include +#include + +int main() +{ + GRSTgaclCred *cred, *usercred; + GRSTgaclEntry *entry; + GRSTgaclAcl *acl1, *acl2; + GRSTgaclUser *user; + GRSTgaclPerm perm0, perm1, perm2; + FILE *fp; + + /* must initialise GACL before using XACML functions */ + + GRSTgaclInit(); + + /* build up an ACL, starting with a credential */ + + cred = GRSTgaclCredNew("person"); + + GRSTgaclCredAddValue(cred, "dn", "/O=Grid/CN=Mr Grid Person"); + + /* create an entry to put it in */ + + entry = GRSTgaclEntryNew(); + + /* add the credential to it */ + + GRSTgaclEntryAddCred(entry, cred); + + /* add another credential */ + + cred = GRSTgaclCredNew("dn-list"); + GRSTgaclCredAddValue(cred, "url", "example-dn-list"); + GRSTgaclEntryAddCred(entry, cred); + + fp = fopen("example-dn-list", "w"); + fputs("/O=Grid/CN=Mr Grid Person\n", fp); + fclose(fp); + + /* associate some permissions and denials to the credential */ + + GRSTgaclEntryAllowPerm( entry, GRST_PERM_READ); + GRSTgaclEntryAllowPerm( entry, GRST_PERM_WRITE); + GRSTgaclEntryAllowPerm( entry, GRST_PERM_ADMIN); + GRSTgaclEntryDenyPerm( entry, GRST_PERM_ADMIN); + GRSTgaclEntryDenyPerm( entry, GRST_PERM_LIST); + + perm0 = GRST_PERM_READ | GRST_PERM_WRITE; + + printf("test perm should be %d\n", perm0); + + /* create a new ACL and add the entry to it */ + + acl1 = GRSTgaclAclNew(); + + GRSTgaclAclAddEntry(acl1, entry); + + /* create a GRSTgaclUser to compare with the ACL */ + + usercred = GRSTgaclCredNew("person"); + + GRSTgaclCredAddValue(usercred, "dn", "/O=Grid/CN=Mr Grid Person"); + + user = GRSTgaclUserNew(usercred); + + GRSTgaclUserSetDNlists(user, getcwd(NULL, 0)); + printf("DN Lists dir %s\n", getcwd(NULL, 0)); + +// putenv("GRST_DN_LISTS=."); + + perm1 = GRSTgaclAclTestUser(acl1, user); + + printf("test /O=Grid/CN=Mr Grid Person in acl = %d\n", perm1); + + /* print and save the whole ACL */ + + GRSTgaclAclPrint(acl1, stdout); + + GRSTxacmlAclSave(acl1, "example.gacl"); + + puts("gridacl.out saved"); + + puts(""); + + /* load the ACL back off the disk, print and test it */ + + acl2 = GRSTxacmlAclLoadFile("example.gacl"); + + puts("gridacl.out loaded"); + + if (acl2 != NULL) GRSTgaclAclPrint(acl2, stdout); else puts("acl2 is NULL"); + + perm2 = GRSTgaclAclTestUser(acl2, user); + + printf("test /O=Grid/CN=Mr Grid Person in acl = %d\n", perm2); + + if (perm1 != perm0) return 1; + if (perm2 != perm0) return 2; + + return 0; +} + -- 1.8.2.3