Sync
authorAndrew McNab <andrew.mcnab@manchester.ac.uk>
Thu, 7 Dec 2006 13:46:59 +0000 (13:46 +0000)
committerAndrew McNab <andrew.mcnab@manchester.ac.uk>
Thu, 7 Dec 2006 13:46:59 +0000 (13:46 +0000)
org.gridsite.core/doc/htproxyput.1
org.gridsite.core/doc/mod_gridsite.8
org.gridsite.core/src/Makefile
org.gridsite.core/src/grst_admin_file.c
org.gridsite.core/src/grst_gacl.c
org.gridsite.core/src/grst_x509.c
org.gridsite.core/src/make-gridsite-spec
org.gridsite.core/src/mod_gridsite.c
org.gridsite.core/src/slashgrid.c

index 3d2bf04..a917054 100644 (file)
@@ -6,12 +6,19 @@
 .B htproxyput, htproxydestroy, htproxytime, htproxyunixtime, htproxyrenew
 [options] Service-URL
 
+.B htproxyinfo
+[options]
+
 .SH DESCRIPTION
 .B htproxyput
 is a client to perform GSI proxy delegations using the GridSite/gLite
 delegation Web Service portType. The gridsite-delegation(8) CGI program is
 the complementary server-side implementation. 
 
+.B htproxyinfo
+examines a local copy of a GSI proxy, and outputs a summary of its X.509 and 
+VOMS contents.
+
 .SH OPTIONS
 .IP "-v/--verbose"
 Turn on debugging information.
@@ -39,6 +46,11 @@ Delegate an updated version of an existing proxy. The Delegation ID
 be given when using this option. Calling the program as htproxyrenew has the
 same effect.
 
+.IP "--info"
+Examine a local proxy file, and output a summary of the X.509 certificates
+and VOMS attributes it contains. Calling the program as htproxyinfo has the
+same effect.
+
 .IP "--cert <X.509 cert path>  and  --key <X.509 key path>"
 Path to the PEM-encoded
 X.509 or GSI Proxy user certificate and key to use for HTTPS
index cfbea3f..4299e34 100644 (file)
@@ -182,6 +182,15 @@ HTTPS requests following a session restart.
 Format to use when writing .gacl files. (Both formats are automatically
 recognised when reading.) (Default: GACL)
 
+.IP "GridSiteACLPath path"
+Specify the absolute or relative (to ServerRoot) path of the ACL file
+governing this section of the server's URL space. This can be applied to
+virtual URL spaces provided by other modules, such as DAV or SVN, using
+the Apache <Location> container. If the path contains %0, it is replaced
+by this virtual server's hostname. If it contains %1, %2, ... it is replaced
+with the 1st, 2nd, ... component of the request's URI, separated by slashes
+and counting from immediately after the initial slash.
+
 .IP "GridSiteExecMethod nosetuid|suexec|X509DN|directory"
 Execution strategy for CGI scripts and executables. For options other
 than nosetuid, suexec (or gsexec renamed suexec) must installed. For
index 95f2cbd..2d0e8bf 100644 (file)
@@ -297,9 +297,7 @@ htproxyput: htproxyput.c delegation.h DelegationService.wsdl libgridsite.so.$(VE
             -lgridsite -lcurl -lz -lssl -lcrypto -lxml2 -lm
         
 # This target is used by make-gridsite-spec to test for gSOAP include+libs
-gsoap-test: gridsite-delegation.cgi
-
-gsoap-test-xxx: gsoap-test.c 
+gsoap-test: gsoap-test.c 
        gcc -g $(MYCFLAGS) $(MYLDFLAGS) -o gsoap-test \
             gsoap-test.c \
             -I/usr/kerberos/include -I. \
@@ -310,6 +308,15 @@ gsoap-test-xxx: gsoap-test.c
             $(STDSOAP2) -L$(GRIDSITEDIR)/lib \
             -lgsoapssl -lz -lssl -lcrypto -lxml2 -lm
         
+gridsite-srm.cgi: gridsite-srm.c libgridsite.so.$(VERSION)
+       gcc -g $(MYCFLAGS) $(MYLDFLAGS) -o gridsite-srm.cgi \
+            gridsite-srm.c \
+            -I/usr/kerberos/include -I.\
+            -I$(GRIDSITEDIR)/include \
+            -DVERSION=\"$(VERSION)\" -L. \
+            -L$(GRIDSITEDIR)/lib \
+            -lgridsite -lcurl -lz -lssl -lcrypto -lxml2 -lm
+
 clean:
 
 #
@@ -379,6 +386,10 @@ install-lib:
 install-slashgrid: slashgrid
        cp -f slashgrid $(prefix)/sbin
        cp -f slashgrid.init $(RPM_BUILD_ROOT)/etc/rc.d/init.d/slashgrid
+       cp -f ../doc/slashgrid.8.html $(prefix)/share/doc/gridsite-$(MINOR_VERSION) ; \
+       cp -f ../doc/slashgrid.8 $(prefix)/share/doc/gridsite-$(MINOR_VERSION) ; \
+       cp -f ../doc/slashgrid.8 $(prefix)/share/man/man8
+       gzip -f $(prefix)/share/man/man8/slashgrid.8
        mkdir -p $(RPM_BUILD_ROOT)/var/spool/slashgrid/headers
        mkdir -p $(RPM_BUILD_ROOT)/var/spool/slashgrid/blocks
        mkdir -p $(RPM_BUILD_ROOT)/var/spool/slashgrid/tmp
@@ -393,7 +404,7 @@ install-ws: gridsite-delegation.cgi htproxyput
                  $(prefix)/share/doc/gridsite-$(MINOR_VERSION)
        cp -f ../doc/*.wsdl $(prefix)/share/doc/gridsite-$(MINOR_VERSION)
        for i in htproxyput.1 htproxytime.1 htproxyrenew.1 htproxydestroy.1 \
-        htproxyunixtime.1 ; do \
+        htproxyunixtime.1 htproxyinfo.1 ; do \
         cp -f ../doc/$$i.html $(prefix)/share/doc/gridsite-$(MINOR_VERSION) ; \
          cp -f ../doc/$$i $(prefix)/share/doc/gridsite-$(MINOR_VERSION) ; \
          cp -f ../doc/$$i $(prefix)/share/man/man1 ; \
@@ -408,6 +419,7 @@ install-ws: gridsite-delegation.cgi htproxyput
        ln -sf htproxyput $(prefix)/bin/htproxytime
        ln -sf htproxyput $(prefix)/bin/htproxyunixtime
        ln -sf htproxyput $(prefix)/bin/htproxyrenew
+       ln -sf htproxyput $(prefix)/bin/htproxyinfo
        cp -f gridsite-delegation.cgi $(prefix)/sbin
           
 #
index b4d47f5..cf85f5d 100644 (file)
@@ -836,8 +836,9 @@ void editdnlistaction(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_pat
 void printfile(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path, 
                   char *file, char *dir_uri, char *admin_file)
 {
-  int   fd;
+  int   c;
   char *dir_path_file;
+  FILE *fp;
   struct stat statbuf;
   
   if (!GRSTgaclPermHasRead(perm)) GRSThttpError("403 Forbidden");
@@ -849,19 +850,20 @@ void printfile(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
   strcpy(dir_path_file, dir_path);
   strcat(dir_path_file, "/");
   strcat(dir_path_file, file);
-  
-  fd = open(dir_path_file, O_RDONLY);  
-  if (fd == -1) GRSThttpError("500 Internal server error");
-
-  if ((fstat(fd, &statbuf) != 0) ||
+  if ((stat(dir_path_file, &statbuf) != 0) ||
         !S_ISREG(statbuf.st_mode)) GRSThttpError("403 Forbidden");
        
+  fp = fopen(dir_path_file, "r");
+  if (fp == NULL) GRSThttpError("500 Internal server error");
   printf("Status: 200 OK\nContent-Type: text/html\nContent-Length: %d\n\n",
          statbuf.st_size);
 
-  fflush(stdout);
+  while ((c = fgetc(fp)) != EOF) putchar(c);
 
-  sendfile(1, fd, 0, statbuf.st_size);  
+  fflush(stdout);
+  fclose(fp);
 }
 
 void filehistory(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
@@ -1463,7 +1465,7 @@ void managedir(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
                  }
                else /* regular directory, not DN Lists */
                  {        
-                   d_name   = namelist[n]->d_name;
+                   d_name = namelist[n]->d_name;
 
                    GRSThttpPrintf(&bp,
                           "<tr><td><a href=\"%s%s\">%s</a></td>"
@@ -1475,7 +1477,7 @@ void managedir(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
                    GRSThttpPrintf(&bp,
                      "<td><a href=\"%s%s?cmd=history&amp;file=%s\">"
                       "History</a></td>",
-                      dir_uri, admin_file, d_name);
+                      dir_uri, admin_file, GRSThttpUrlEncode(d_name));
 
                    p = rindex(namelist[n]->d_name, '.');
 
@@ -1486,27 +1488,27 @@ void managedir(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
                              GRSThttpPrintf(&bp,
                                "<td><a href=\"%s%s?cmd=ziplist&amp;file=%s\">"
                                "List</a></td>\n",
-                               dir_uri, admin_file, d_name);                   
+                               dir_uri, admin_file, GRSThttpUrlEncode(d_name));                   
                    else if ((p != NULL) && 
                        (strstr(editable, &p[1]) != NULL) &&
                        GRSTgaclPermHasWrite(perm))
                          GRSThttpPrintf(&bp,
                                "<td><a href=\"%s%s?cmd=edit&amp;file=%s\">"
                                "Edit</a></td>\n",
-                               dir_uri, admin_file, d_name);
+                               dir_uri, admin_file, GRSThttpUrlEncode(d_name));
                    else  GRSThttpPrintf(&bp, "<td>&nbsp;</td>");
 
                    if (GRSTgaclPermHasWrite(perm))
                     GRSThttpPrintf(&bp,
                      "<td><a href=\"%s%s?cmd=delete&amp;file=%s\">"
-                     "Delete</a></td>\n", dir_uri, admin_file, d_name);
+                     "Delete</a></td>\n", dir_uri, admin_file, GRSThttpUrlEncode(d_name));
                    else
                     GRSThttpPrintf(&bp, "<td>&nbsp;</td>\n");
 
                    if (GRSTgaclPermHasWrite(perm))
                     GRSThttpPrintf(&bp,
                      "<td><a href=\"%s%s?cmd=rename&amp;file=%s\">"
-                     "Rename</a></td></tr>\n", dir_uri, admin_file, d_name);
+                     "Rename</a></td></tr>\n", dir_uri, admin_file, GRSThttpUrlEncode(d_name));
                    else
                     GRSThttpPrintf(&bp, "<td>&nbsp;</td></tr>");
                  }
index db1dbdb..c2c4ecd 100644 (file)
@@ -928,6 +928,25 @@ int GRSTgaclUserHasCred(GRSTgaclUser *user, GRSTgaclCred *cred)
       return 0;    
     }
   
+  if (strcmp(cred->type, "level") == 0)
+    {
+      if ((user->firstcred == NULL) ||
+          ((user->firstcred)->firstname == NULL)) return 0;
+      
+      for (crediter=user->firstcred; 
+           crediter != NULL; 
+           crediter = crediter->next)
+        if (strcmp(crediter->type, "level") == 0) 
+          {
+            if (atoi(user->firstcred->firstname->value) 
+                        >= atoi(crediter->firstname->value)) return 1;
+
+            return 0;
+          } 
+                
+      return 0;    
+    }
+
   for (crediter=user->firstcred; crediter != NULL; crediter = crediter->next)
        {
          if (strcmp(crediter->type, cred->type) != 0) continue;
@@ -950,11 +969,13 @@ int GRSTgaclUserHasCred(GRSTgaclUser *user, GRSTgaclCred *cred)
                   if (GRSTx509NameCmp(usernamevalue->value, 
                                       crednamevalue->value) != 0) break;
                 }
+/*
               else if (strcmp(cred->type, "level") == 0)
                 {
                   if (atoi(usernamevalue->value) 
                         < atoi(crednamevalue->value)) break;
                 }              
+*/
               else if (strcmp(usernamevalue->value,
                               crednamevalue->value) != 0) break;
               
index 53a7500..3251813 100644 (file)
@@ -1,4 +1,4 @@
-/*5~
+/*
    Copyright (c) 2002-6, Andrew McNab, University of Manchester
    All rights reserved.
 
@@ -382,7 +382,6 @@ static int GRSTx509VerifyVomsSig(time_t *time1_time, time_t *time2_time,
 static int GRSTx509ChainVomsAdd(GRSTx509Cert **grst_cert, 
                          time_t time1_time, time_t time2_time,
                          X509_EXTENSION *ex, 
-                         int chain_errors,
                          char *ucuserdn, char *vomsdir)
 {
 #define MAXTAG 500
@@ -396,7 +395,7 @@ static int GRSTx509ChainVomsAdd(GRSTx509Cert **grst_cert,
                       dn_coords[200], fqan_coords[200], time1_coords[200],
                       time2_coords[200];
    long               asn1length;
-   int                lasttag=-1, itag, i, acnumber = 1;
+   int                lasttag=-1, itag, i, acnumber = 1, chain_errors = 0;
    struct GRSTasn1TagList taglist[MAXTAG+1];
    time_t             actime1 = 0, actime2 = 0, time_now;
    GRSTx509Cert      *new_grst_cert;
@@ -409,6 +408,8 @@ static int GRSTx509ChainVomsAdd(GRSTx509Cert **grst_cert,
 
    for (acnumber = 1; ; ++acnumber) /* go through ACs one by one */
       {
+        chain_errors = 0;
+      
         snprintf(dn_coords, sizeof(dn_coords), GRST_ASN1_COORDS_USER_DN, acnumber);
         if (GRSTasn1GetX509Name(acuserdn, sizeof(acuserdn), dn_coords,
                                 asn1string, taglist, lasttag) != GRST_RET_OK)
@@ -482,24 +483,13 @@ static int GRSTx509ChainVomsAdd(GRSTx509Cert **grst_cert,
    return GRST_RET_OK;
 }
 
-/// Load and check X.509 chain, include Proxy Certificates and VOMS Attributes
+/// Check certificate chain for GSI proxy acceptability.
 /**
- *  Returns GRST_RET_OK if valid; GRST_xxx errors otherwise.
+ *  Returns GRST_RET_OK if valid; OpenSSL X509 errors otherwise.
  *
- *  This function fills the GridSite linked list **chain with summaries
- *  of the X.509 certificates, and any VOMS attributes they contain
- * 
- *  o If the root CA cert is not present, it is added from the capath
- *    directory of hashed-DN.
- *  o The chain list starts from the CA end.
- *  o Certs are included even if they are invalid, but are flagged in their
- *    errors field (0 = OK)
- *  o If lastcert is not NULL, then it is included at the end of the chain.
- *  o If capath is not NULL, then it is used as a source of CA root
- *    certificates. (If capath is NULL, or a root cert in capath cannot
- *    be found, then all EEC/PC/AC certs are flagged with BAD CHAIN errors.)
- *  o If vomsdir is not NULL, it used as the top of a hierarchy of VOMS
- *    cert directories. (VOMS ACs are ignored if vomsdir is NULL.)
+ *  The GridSite version handles old and new style Globus proxies, and
+ *  proxies derived from user certificates issued with "X509v3 Basic
+ *  Constraints: CA:FALSE" (eg UK e-Science CA)
  *
  *  TODO: we do not yet check ProxyCertInfo and ProxyCertPolicy extensions
  *        (although via GRSTx509KnownCriticalExts() we can accept them.)
@@ -552,36 +542,30 @@ int GRSTx509ChainLoadCheck(GRSTx509Chain **chain,
        return GRST_RET_FAILED;
      }
 
-   if (capath != NULL)
-     {
-       cert = sk_X509_value(certstack, depth - 1);
-       subjecthash = X509_NAME_hash(X509_get_subject_name(cert));
-       issuerhash = X509_NAME_hash(X509_get_issuer_name(cert));
-       asprintf(&cacertpath, "%s/%.8x.0", capath, issuerhash);
+   cert = sk_X509_value(certstack, depth - 1);
+   subjecthash = X509_NAME_hash(X509_get_subject_name(cert));
+   issuerhash = X509_NAME_hash(X509_get_issuer_name(cert));
+   asprintf(&cacertpath, "%s/%.8x.0", capath, issuerhash);
    
-       GRSTerrorLog(GRST_LOG_DEBUG, "Look for CA root file %s", cacertpath);
+   GRSTerrorLog(GRST_LOG_DEBUG, "Look for CA root file %s", cacertpath);
 
-       fp = fopen(cacertpath, "r");
-       free(cacertpath);
+   fp = fopen(cacertpath, "r");
+   free(cacertpath);
 
-       if (fp == NULL) chain_errors |= GRST_CERT_BAD_CHAIN;
-       else
-         {
-           cacert = PEM_read_X509(fp, NULL, NULL, NULL);
-           fclose(fp);
-           if (cacert != NULL) 
-            GRSTerrorLog(GRST_LOG_DEBUG, " Loaded CA root cert from file");
-         }
+   if (fp == NULL) chain_errors |= GRST_CERT_BAD_CHAIN;
+   else
+     {
+       cacert = PEM_read_X509(fp, NULL, NULL, NULL);
+       fclose(fp);
+       if (cacert != NULL) 
+        GRSTerrorLog(GRST_LOG_DEBUG, " Loaded CA root cert from file");
      }
-   
-   if (cacert == NULL)
-         chain_errors |= GRST_CERT_BAD_CHAIN; /* never good without CA */
 
    *chain = malloc(sizeof(GRSTx509Chain));
    bzero(*chain, sizeof(GRSTx509Chain));
        
    /* Check the client chain */
-   for (i = depth - (((subjecthash == issuerhash) || (cacert == NULL)) ? 1 : 0);
+   for (i = depth - ((subjecthash == issuerhash) ? 1 : 0);
         i >= ((lastcert == NULL) ? 0 : -1); 
         --i) 
       /* loop through client-presented chain starting at CA end */
@@ -607,17 +591,13 @@ int GRSTx509ChainLoadCheck(GRSTx509Chain **chain,
         if (i < 0) cert = lastcert;
         else if (i == depth)
              cert = cacert; /* the self-signed CA from the store*/
-        else if ((i == depth - 1) && 
-                 (subjecthash == issuerhash) &&
-                 (cacert != NULL))
+        else if ((i == depth - 1) && (subjecthash == issuerhash))
              cert = cacert; /* ie claims to be a copy of a self-signed CA */
         else cert = sk_X509_value(certstack, i);
 
         if (cert != NULL)
           {
-            if ((i == depth - 1) && 
-                (subjecthash != issuerhash) && 
-                (cacert != NULL))
+            if ((i == depth - 1) && (subjecthash != issuerhash))
               {
                 /* if first cert does not claim to be a self-signed copy 
                    of a CA root cert in the store, we check the signature */
@@ -630,9 +610,7 @@ int GRSTx509ChainLoadCheck(GRSTx509Chain **chain,
                 if (ret != X509_V_OK) 
                              new_grst_cert->errors |= GRST_CERT_BAD_SIG;
               }
-            else if ((i == depth - 2) && 
-                     (subjecthash == issuerhash) && 
-                     (cacert != NULL))
+            else if ((i == depth - 2) && (subjecthash == issuerhash))
               {
                 /* first cert claimed to be a self-signed copy of a CA root
                 cert in the store, we check the signature of the second
@@ -753,26 +731,22 @@ int GRSTx509ChainLoadCheck(GRSTx509Chain **chain,
                 if (strncmp(proxy_part_DN, "/CN=limited proxy", 17) == 0)
                         prevIsLimited = 1; /* ready for next cert ... */
 
-                if (vomsdir != NULL)
-                  {
-                    for (j=0; j < X509_get_ext_count(cert); ++j)
-                       {
-                         ex = X509_get_ext(cert, j);
-                         OBJ_obj2txt(s, sizeof(s), 
-                                     X509_EXTENSION_get_object(ex), 1);
+                for (j=0; j < X509_get_ext_count(cert); ++j)
+                   {
+                     ex = X509_get_ext(cert, j);
+                     OBJ_obj2txt(s,sizeof(s),X509_EXTENSION_get_object(ex),1);
 
-                         if (strcmp(s, GRST_VOMS_OID) == 0) /* VOMS ext */
-                           {
-                             GRSTx509ChainVomsAdd(&grst_cert, 
+                     if (strcmp(s, GRST_VOMS_OID) == 0) /* a VOMS extension */
+                       {
+                         GRSTx509ChainVomsAdd(&grst_cert, 
                                               new_grst_cert->start,
                                               new_grst_cert->finish,                                              
                                               ex,
-                                              chain_errors,
                                               ucuserdn, 
                                               vomsdir);
-                           }
                        }
-                  } 
+                   }
+                        
               } 
           }
           
index 21bac26..3b81780 100755 (executable)
@@ -12,13 +12,13 @@ if [ $? = 0 ] ; then have_fuse=1 ; fi
 
 # test to see if gsoap-devel (or stdsoap2.h and libgsoapssl) is installed
 #
-cat <<EOF >gsoap-test-xxx.c
+cat <<EOF >gsoap-test.c
 #include <stdsoap2.h>
 #ifdef SOAP_BEGIN  
 main() { return; }
 #endif
 EOF
-make GSOAPDIR=$GSOAPDIR STDSOAP2=$STDSOAP2 gsoap-test
+make GSOAPDIR=$GSOAPDIR STDSOAP2=$STDSOAP2 gridsite-delegation.cgi
 if [ $? = 0 ] ; then have_gsoap=1 ; fi
 
 cat <<EOF >gridsite.spec
@@ -245,6 +245,7 @@ mkdir -p /grid
 %attr(0744, root, root) %{prefix}/sbin/slashgrid
 %attr(0744, root, root) /etc/rc.d/init.d/slashgrid
 %attr(0700, root, root) /var/spool/slashgrid
+%attr(-, root, root) %{prefix}/share/man/man8/slashgrid.8.gz
 EOF
 
 fi
@@ -281,16 +282,19 @@ See http://www.gridsite.org/ for details.
 %attr(-, root, root) %{prefix}/bin/htproxytime
 %attr(-, root, root) %{prefix}/bin/htproxyunixtime
 %attr(-, root, root) %{prefix}/bin/htproxyrenew
+%attr(-, root, root) %{prefix}/bin/htproxyinfo
 %attr(-, root, root) %{prefix}/share/man/man1/htproxyput.1.gz
 %attr(-, root, root) %{prefix}/share/man/man1/htproxydestroy.1.gz
 %attr(-, root, root) %{prefix}/share/man/man1/htproxytime.1.gz
 %attr(-, root, root) %{prefix}/share/man/man1/htproxyunixtime.1.gz
 %attr(-, root, root) %{prefix}/share/man/man1/htproxyrenew.1.gz
+%attr(-, root, root) %{prefix}/share/man/man1/htproxyinfo.1.gz
 %attr(-, root, root) %{prefix}/share/doc/gridsite-${MINOR_VERSION:-1.x}/htproxyput.1
 %attr(-, root, root) %{prefix}/share/doc/gridsite-${MINOR_VERSION:-1.x}/htproxydestroy.1
 %attr(-, root, root) %{prefix}/share/doc/gridsite-${MINOR_VERSION:-1.x}/htproxytime.1
 %attr(-, root, root) %{prefix}/share/doc/gridsite-${MINOR_VERSION:-1.x}/htproxyunixtime.1
 %attr(-, root, root) %{prefix}/share/doc/gridsite-${MINOR_VERSION:-1.x}/htproxyrenew.1
+%attr(-, root, root) %{prefix}/share/doc/gridsite-${MINOR_VERSION:-1.x}/htproxyinfo.1
 EOF
 
 fi
index 7d04a77..16febab 100644 (file)
@@ -147,6 +147,7 @@ typedef struct
    char                        *footfile;
    int                 gridhttp;
    char                        *aclformat;
+   char                        *aclpath;
    char                        *execmethod;
    char                        *delegationuri;
    ap_unix_identity_t  execugid;
@@ -1532,6 +1533,7 @@ static void *create_gridsite_dir_config(apr_pool_t *p, char *path)
         conf->gridhttp      = 0;     /* GridSiteGridHTTP      on/off       */
        conf->aclformat     = apr_pstrdup(p, "GACL");
                                      /* GridSiteACLFormat     gacl/xacml   */
+       conf->aclpath       = NULL;  /* GridSiteACLPath       acl-path     */
        conf->delegationuri = NULL;  /* GridSiteDelegationURI URI-value    */
        conf->execmethod    = NULL;
                /* GridSiteExecMethod  nosetuid/suexec/X509DN/directory */
@@ -1566,6 +1568,7 @@ static void *create_gridsite_dir_config(apr_pool_t *p, char *path)
         conf->footfile      = NULL;  /* GridSiteFootFile      file name    */
         conf->gridhttp      = UNSET; /* GridSiteGridHTTP      on/off       */
        conf->aclformat     = NULL;  /* GridSiteACLFormat     gacl/xacml   */
+       conf->aclpath       = NULL;  /* GridSiteACLPath       acl-path     */
        conf->delegationuri = NULL;  /* GridSiteDelegationURI URI-value    */
        conf->execmethod    = NULL;  /* GridSiteExecMethod */
         conf->execugid.uid     = UNSET;        /* GridSiteUserGroup User Group */
@@ -1648,6 +1651,9 @@ static void *merge_gridsite_dir_config(apr_pool_t *p, void *vserver,
     if (direct->aclformat != NULL) conf->aclformat = direct->aclformat;
     else                           conf->aclformat = server->aclformat;
 
+    if (direct->aclpath != NULL)   conf->aclpath = direct->aclpath;
+    else                           conf->aclpath = server->aclpath;
+
     if (direct->delegationuri != NULL) conf->delegationuri = direct->delegationuri;
     else                               conf->delegationuri = server->delegationuri;
 
@@ -1845,7 +1851,10 @@ static const char *mod_gridsite_take1_cmds(cmd_parms *a, void *cfg,
       
       ((mod_gridsite_dir_cfg *) cfg)->aclformat = apr_pstrdup(a->pool, parm);
     }
-
+    else if (strcasecmp(a->cmd->name, "GridSiteACLPath") == 0)
+    {
+      ((mod_gridsite_dir_cfg *) cfg)->aclpath = apr_pstrdup(a->pool, parm);
+    }
     else if (strcasecmp(a->cmd->name, "GridSiteDelegationURI") == 0)
     {
       if (*parm != '/') return "GridSiteDelegationURI must begin with /";
@@ -2054,6 +2063,8 @@ static const command_rec mod_gridsite_cmds[] =
 
     AP_INIT_TAKE1("GridSiteACLFormat", mod_gridsite_take1_cmds,
                  NULL, OR_FILEINFO, "format to save access control lists in"),
+    AP_INIT_TAKE1("GridSiteACLPath", mod_gridsite_take1_cmds,
+                 NULL, OR_FILEINFO, "explicit location of access control file"),
 
     AP_INIT_TAKE1("GridSiteDelegationURI", mod_gridsite_take1_cmds,
                  NULL, OR_FILEINFO, "URI of the delegation service CGI"),
@@ -2079,7 +2090,11 @@ static const command_rec mod_gridsite_cmds[] =
 static int mod_gridsite_check_user_id(request_rec *r)
 {
     apr_table_unset(r->headers_in, "User-Distinguished-Name");
+#if 0
+    apr_table_unset(r->headers_in, "User-Distinguished-Name-2");
+#endif
     apr_table_unset(r->headers_in, "Nist-LoA");
+    apr_table_unset(r->headers_in, "LoA");
     apr_table_unset(r->headers_in, "VOMS-Attribute");
 
     return DECLINED; /* ie carry on processing request */
@@ -2287,6 +2302,79 @@ void GRST_save_ssl_creds(conn_rec *conn,
      }
 }
 
+static char *get_aclpath_component(request_rec *r, int n)
+/*
+    Get the nth component of REQUEST_URI, or component 0
+    which is the server name.
+
+*/
+{
+    int ii, i, nn;
+
+    if (n == 0) return r->server->server_hostname;
+
+    if (r->uri == NULL) return NULL; /* some kind of internal error? */
+
+    i  = 1; /* start of first component */
+    nn = 1;
+    
+    for (ii=1; r->uri[ii] != '\0'; ++ii) /* look for this component */
+       {
+         if (r->uri[ii] == '/') /* end of a component */
+           {
+             if (nn == n) break;
+             
+             ++nn;
+             i = ii + 1;
+           }
+         else if ((r->uri[ii] == '.') && (r->uri[ii+1] == '.'))
+           {
+             return NULL; /* can this happen? dont allow anyway */
+           }         
+       }
+       
+    if (nn != n) return NULL; /* no component for this number */
+    
+    return apr_psprintf(r->pool, "%.*s", ii - i, &(r->uri[i]));
+}
+
+static char *make_aclpath(request_rec *r, char *format)
+{
+    int i, n;
+    char *formatted, *p;
+    
+    formatted = apr_pstrdup(r->pool, format);
+
+    while (1)
+         {
+           for (i=0; (formatted[i] != '\0') && (formatted[i] != '%'); ++i) ;
+    
+           if (formatted[i] == '\0') break;
+           
+           if ((formatted[i] == '%') && (formatted[i+1] == '%')) 
+             {
+               ++i;
+               continue;
+             }
+            
+           if (sscanf(&formatted[i+1], "%d", &n) != 1)
+             {
+               return NULL; /* not %% or %0,%1,... */
+             }
+           
+           formatted[i] = '\0';
+           
+           for (i++; isdigit(formatted[i]); ++i) ;
+           
+           if ((p = get_aclpath_component(r, n)) == NULL) return NULL;
+           
+           formatted = apr_pstrcat(r->pool, formatted, p, &formatted[i],NULL);                                   
+           i += strlen(p);
+         }
+            
+    return ap_server_root_relative(r->pool, formatted);
+}
+
 static int mod_gridsite_perm_handler(request_rec *r)
 /*
     Do authentication/authorization here rather than in the normal module
@@ -2301,7 +2389,8 @@ static int mod_gridsite_perm_handler(request_rec *r)
                 *remotehost, s[99], *grst_cred_i, *cookies, *file, *https,
                 *gridauthpasscode = NULL, *cookiefile, oneline[1025], *key_i,
                 *destination = NULL, *destination_uri = NULL, *querytmp, 
-                *destination_prefix = NULL, *destination_translated = NULL;
+                *destination_prefix = NULL, *destination_translated = NULL,
+                *aclpath = NULL;
     char        *vomsAttribute = NULL, *loa;
     const char  *content_type;
     time_t       now, notbefore, notafter;
@@ -2334,13 +2423,27 @@ static int mod_gridsite_perm_handler(request_rec *r)
        a Shibboleth Identity Provider.*/
 
     /* Get DN from a Shibboleth attribute */
+
     dn = (char *) apr_table_get(r->headers_in, "User-Distinguished-Name");
+#if 0
+    if ((dn == NULL) || (*dn == '\0'))
+     dn = (char *) apr_table_get(r->headers_in, "User-Distinguished-Name-2");
+#endif
+
+    if ((dn != NULL) && (*dn == '\0')) dn = NULL;
+    
     if (dn != NULL) ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "DN: %s", dn);
-#if 0                                                                    
+
     /* Get the NIST LoA attribute */
     loa = (char *) apr_table_get(r->headers_in, "nist-loa");
-    if (loa != NULL) ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Nist-LoA: %d", loa);
-#endif
+
+    if ((loa == NULL) || (*loa == '\0'))
+     loa = (char *) apr_table_get(r->headers_in, "loa");
+    
+    if ((loa != NULL) && (*loa == '\0')) loa = NULL;
+
+    if (loa != NULL) ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "nist-loa: %s", loa);
+
     /* Set up user credential based on the DN and LoA attributes */
                                   
     if (dn != NULL)
@@ -2349,20 +2452,21 @@ static int mod_gridsite_perm_handler(request_rec *r)
         GRSTgaclCredAddValue(cred, "dn", dn);
         user = GRSTgaclUserNew(cred);
         cred = GRSTgaclCredNew("level");
-#if 0
-        GRSTgaclCredAddValue(cred, "nist-loa", loa);
-#endif
-        GRSTgaclCredAddValue(cred, "nist-loa", "2"); /* hardcoded for now */
+
+        if (loa != NULL) GRSTgaclCredAddValue(cred, "nist-loa", loa);
+        else GRSTgaclCredAddValue(cred, "nist-loa", "2");
+
         GRSTgaclUserAddCred(user, cred);
       }
+            
+    /* Set up user credential based on VOMS Attribute from Shibboleth? */
 
     vomsAttribute = (char *) apr_table_get(r->headers_in, "VOMS-Attribute");
-    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, 
-                 "VOMS-Attribute: %s", vomsAttribute);
-            
-    /* Set up user credential based on VOMS Attribute */
     if (vomsAttribute != NULL)
       {
+        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, 
+                 "VOMS-Attribute: %s", vomsAttribute);
+
         cred = GRSTgaclCredNew("voms");
         GRSTgaclCredAddValue(cred, "fqan", vomsAttribute);
         if (user == NULL) user = GRSTgaclUserNew(cred);
@@ -2376,13 +2480,14 @@ static int mod_gridsite_perm_handler(request_rec *r)
 
     sslconn = (SSLConnRec *) ap_get_module_config(r->connection->conn_config, 
                                                   &ssl_module);
-    if ((sslconn != NULL) && 
+    if ((user == NULL) &&
+        (sslconn != NULL) && 
         (sslconn->ssl != NULL) &&
         (sslconn->ssl->session != NULL) &&
         (r->connection->notes != NULL) &&
         (apr_table_get(r->connection->notes, "GRST_save_ssl_creds") == NULL))
       {
-        if (GRST_load_ssl_creds(sslconn->ssl, r->connection) == GRST_RET_OK)        
+        if (GRST_load_ssl_creds(sslconn->ssl, r->connection) == GRST_RET_OK)
             ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                          "Restored SSL session data from session cache file");
       }
@@ -2453,6 +2558,9 @@ static int mod_gridsite_perm_handler(request_rec *r)
     if ((destination = (char *) apr_table_get(r->headers_in,
                                               "Destination")) != NULL)
       {
+        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+                     "Destination header found, value=%s", destination);
+
         destination_prefix = apr_psprintf(r->pool, "https://%s:%d/", 
                          r->server->server_hostname, (int) r->server->port);
 
@@ -2501,7 +2609,24 @@ static int mod_gridsite_perm_handler(request_rec *r)
       }
     else
       {
-        acl = GRSTgaclAclLoadforFile(r->filename);
+        if (((mod_gridsite_dir_cfg *) cfg)->aclpath != NULL)
+          {
+            aclpath = make_aclpath(r,((mod_gridsite_dir_cfg *) cfg)->aclpath);
+          
+            if (aclpath != NULL) 
+              {
+                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+                        "Examine ACL file %s (from ACL path %s)",
+                        aclpath, ((mod_gridsite_dir_cfg *) cfg)->aclpath);
+
+                acl = GRSTgaclAclLoadFile(aclpath);
+              }
+            else ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+                        "Failed to make ACL file from ACL path %s, URI %s)",
+                        ((mod_gridsite_dir_cfg *) cfg)->aclpath, r->uri);
+          }
+        else acl = GRSTgaclAclLoadforFile(r->filename);
+
         if (acl != NULL) perm = GRSTgaclAclTestUser(acl, user);
         GRSTgaclAclFree(acl);
         
@@ -2674,6 +2799,10 @@ static int mod_gridsite_perm_handler(request_rec *r)
                  apr_table_setn(env, "GRST_ACL_FORMAT",
                               ((mod_gridsite_dir_cfg *) cfg)->aclformat);
 
+        if (((mod_gridsite_dir_cfg *) cfg)->aclpath != NULL)
+                 apr_table_setn(env, "GRST_ACL_PATH",
+                              ((mod_gridsite_dir_cfg *) cfg)->aclpath);
+
        if (((mod_gridsite_dir_cfg *) cfg)->delegationuri != NULL)
                  apr_table_setn(env, "GRST_DELEGATION_URI",
                               ((mod_gridsite_dir_cfg *) cfg)->delegationuri);
@@ -2763,7 +2892,21 @@ static int mod_gridsite_perm_handler(request_rec *r)
 
             (((r->method_number == M_PUT) || 
               (r->method_number == M_DELETE)) &&
-             !GRSTgaclPermHasAdmin(perm) && file_is_acl) 
+             !GRSTgaclPermHasAdmin(perm) && file_is_acl) ||
+
+            /* for WebDAV/Subversion */
+             
+            (((r->method_number == M_PROPFIND) ||
+              (r->method_number == M_REPORT)) &&
+             !GRSTgaclPermHasRead(perm)) ||
+
+            (((r->method_number == M_CHECKOUT) ||
+              (r->method_number == M_MERGE) ||
+              (r->method_number == M_MKACTIVITY) ||
+              (r->method_number == M_MKCOL) ||
+              (r->method_number == M_LOCK) ||
+              (r->method_number == M_UNLOCK)) &&
+             !GRSTgaclPermHasWrite(perm))
              
              ) retcode = HTTP_FORBIDDEN;
       }
index de86328..8ae240c 100644 (file)
@@ -91,7 +91,7 @@
 #endif
  
 #ifndef CURLOPT_READDATA
-#define CURLOPT_READDATA CURLOPT_FILE
+#define CURLOPT_READDATA CURLOPT_INFILE
 #endif
 
 #ifndef CURLE_HTTP_RETURNED_ERROR
@@ -599,12 +599,18 @@ int perform_request(struct grst_request *request_data,
       curl_easy_setopt(handles[i].curl_handle, CURLOPT_SSL_VERIFYHOST, 2);
     }   
 
+  curl_easy_setopt(handles[i].curl_handle, CURLOPT_READFUNCTION, request_data->readfunction);
+  curl_easy_setopt(handles[i].curl_handle, CURLOPT_READDATA, request_data->readdata);
+  curl_easy_setopt(handles[i].curl_handle, CURLOPT_WRITEFUNCTION, request_data->writefunction);
+  curl_easy_setopt(handles[i].curl_handle, CURLOPT_WRITEDATA, request_data->writedata);
+
   if (request_data->method == GRST_SLASH_GET)
     {
       curl_easy_setopt(handles[i].curl_handle, CURLOPT_CUSTOMREQUEST, NULL);
       curl_easy_setopt(handles[i].curl_handle, CURLOPT_NOBODY,  0);
       curl_easy_setopt(handles[i].curl_handle, CURLOPT_HTTPGET, 1);
       curl_easy_setopt(handles[i].curl_handle, CURLOPT_UPLOAD,  0);
+      curl_easy_setopt(handles[i].curl_handle, CURLOPT_INFILESIZE, -1);
     }
   else if ((request_data->method == GRST_SLASH_PUT) || 
            (request_data->method == GRST_SLASH_TRUNC))
@@ -622,6 +628,7 @@ int perform_request(struct grst_request *request_data,
       curl_easy_setopt(handles[i].curl_handle, CURLOPT_HTTPGET, 0);
       curl_easy_setopt(handles[i].curl_handle, CURLOPT_UPLOAD,  0);
       curl_easy_setopt(handles[i].curl_handle, CURLOPT_CUSTOMREQUEST, "DELETE");
+      curl_easy_setopt(handles[i].curl_handle, CURLOPT_INFILESIZE, -1);
     }
   else if (request_data->method == GRST_SLASH_MOVE)
     {
@@ -629,6 +636,7 @@ int perform_request(struct grst_request *request_data,
       curl_easy_setopt(handles[i].curl_handle, CURLOPT_HTTPGET, 0);
       curl_easy_setopt(handles[i].curl_handle, CURLOPT_UPLOAD,  0);
       curl_easy_setopt(handles[i].curl_handle, CURLOPT_CUSTOMREQUEST, "MOVE");
+      curl_easy_setopt(handles[i].curl_handle, CURLOPT_INFILESIZE, -1);
     }
   else /* default or GRST_SLASH_HEAD */
     {
@@ -636,6 +644,7 @@ int perform_request(struct grst_request *request_data,
       curl_easy_setopt(handles[i].curl_handle, CURLOPT_NOBODY,  1);
       curl_easy_setopt(handles[i].curl_handle, CURLOPT_HTTPGET, 0);
       curl_easy_setopt(handles[i].curl_handle, CURLOPT_UPLOAD,  0);
+      curl_easy_setopt(handles[i].curl_handle, CURLOPT_INFILESIZE, -1);
     }
 
   curl_easy_setopt(handles[i].curl_handle, CURLOPT_WRITEHEADER, request_data);
@@ -647,11 +656,12 @@ int perform_request(struct grst_request *request_data,
   if (debugmode)
         curl_easy_setopt(handles[i].curl_handle, CURLOPT_DEBUGDATA, &i);
 
+/* Move to higher up
   curl_easy_setopt(handles[i].curl_handle, CURLOPT_READFUNCTION, request_data->readfunction);
   curl_easy_setopt(handles[i].curl_handle, CURLOPT_READDATA, request_data->readdata);
   curl_easy_setopt(handles[i].curl_handle, CURLOPT_WRITEFUNCTION, request_data->writefunction);
   curl_easy_setopt(handles[i].curl_handle, CURLOPT_WRITEDATA, request_data->writedata);
-
+*/
   if ((request_data->start >= 0) && 
       (request_data->finish >= request_data->start))
     {
@@ -1433,7 +1443,7 @@ static int slashgrid_getattr(const char *rawpath, struct stat *stbuf)
   memcpy(&fuse_ctx, fuse_get_context(), sizeof(struct fuse_context));
 
   if (debugmode) syslog(LOG_DEBUG, 
-                         "in slashgrid_getattr, rawpath=%s, UID=%d\n",
+                         "in slashgrid_getattr, rawpath=%s UID=%d\n",
                          rawpath, fuse_ctx.uid);
 
   memset(stbuf, 0, sizeof(struct stat));
@@ -1566,10 +1576,14 @@ static int slashgrid_getattr(const char *rawpath, struct stat *stbuf)
       free(path);
       return 0;    
     }
+  
+  if (debugmode) syslog(LOG_DEBUG, "Get details for %s over network\n", url);
 
   bzero(&request_data, sizeof(struct grst_request));
   request_data.writefunction = null_callback;
   request_data.writedata     = NULL;
+  request_data.readfunction  = null_callback;
+  request_data.readdata      = NULL;
   request_data.errorbuffer   = errorbuffer;
   request_data.url           = url;
   request_data.method        = GRST_SLASH_HEAD;
@@ -1578,6 +1592,9 @@ static int slashgrid_getattr(const char *rawpath, struct stat *stbuf)
 
   thiserror = perform_request(&request_data, &fuse_ctx);
 
+  if (debugmode) syslog(LOG_DEBUG, "perform_request returns error=%d (%s)\n",
+                        thiserror, errorbuffer);
+
   if ((thiserror != 0) ||
            (request_data.retcode < 200) ||
            (request_data.retcode > 301))
@@ -2333,6 +2350,7 @@ int slashgrid_statfs(const char *path, struct statfs *fs)
 void *slashgrid_init(void)
 {
   FILE *fp;
+  struct rlimit unlimited = { RLIM_INFINITY, RLIM_INFINITY };
   
   if ((fp = fopen(GRST_SLASH_PIDFILE, "w")) != NULL)
     {
@@ -2340,6 +2358,12 @@ void *slashgrid_init(void)
       fclose(fp);
     }
 
+  if (debugmode)
+    {
+      chdir("/var/tmp"); /* fuse changes to / in demonize: undo this */
+      setrlimit(RLIMIT_CORE, &unlimited);
+    }
+
   return NULL;
 }
 
@@ -2386,7 +2410,6 @@ int main(int argc, char *argv[])
                         "-s", "-d" };
   int   i, ret, fuse_argc = 4; /* by default, ignore the final 2 args */
   struct passwd *pw;
-  struct rlimit unlimited = { RLIM_INFINITY, RLIM_INFINITY };
   
   for (i=1; i < argc; ++i)
      {
@@ -2449,7 +2472,7 @@ int main(int argc, char *argv[])
 
   openlog("slashgrid", 0, LOG_DAEMON);
     
-  umount("/grid"); /* in case of a crash, but will fail if still busy */
+  umount("/grid"); /* in case of previous crash - will fail if still busy */
 
   for (i=0; i < GRST_SLASH_MAX_HANDLES; ++i)
      {
@@ -2459,12 +2482,6 @@ int main(int argc, char *argv[])
        handles[i].last_used   = 0;
      }
 
-  if (debugmode) 
-    {
-      chdir("/var/tmp");
-      setrlimit(RLIMIT_CORE, &unlimited);
-    }
-
 //  GRSTerrorLogFunc = slashgrid_logfunc;
  
   GRSTgaclInit();