Sync
authorAndrew McNab <andrew.mcnab@manchester.ac.uk>
Thu, 8 Nov 2007 15:29:51 +0000 (15:29 +0000)
committerAndrew McNab <andrew.mcnab@manchester.ac.uk>
Thu, 8 Nov 2007 15:29:51 +0000 (15:29 +0000)
org.gridsite.core/VERSION
org.gridsite.core/doc/httpd-fileserver.conf
org.gridsite.core/doc/httpd-storage.conf
org.gridsite.core/doc/mod_gridsite.8
org.gridsite.core/interface/gridsite.h
org.gridsite.core/src/Makefile
org.gridsite.core/src/grst_admin_file.c
org.gridsite.core/src/grst_admin_gacl.c
org.gridsite.core/src/grst_admin_main.c
org.gridsite.core/src/grst_http.c
org.gridsite.core/src/mod_gridsite.c

index 8311a23..90c025b 100644 (file)
@@ -2,3 +2,4 @@ MAJOR_VERSION=1
 MINOR_VERSION=1.5
 PATCH_VERSION=1.5.3
 VERSION=$(PATCH_VERSION)
+DEFVERSION=010503
index c71e337..539de86 100644 (file)
@@ -78,7 +78,7 @@ PidFile logs/httpd.pid
 Timeout                        300
 KeepAlive              On
 MaxKeepAliveRequests   100
-KeepAliveTimeout       15
+KeepAliveTimeout       300
 
 LoadModule log_config_module   /usr/lib/httpd/modules/mod_log_config.so
 LoadModule ssl_module          /usr/lib/httpd/modules/mod_ssl.so
index fd7ae52..b03357a 100644 (file)
@@ -79,7 +79,7 @@ PidFile logs/httpd.pid
 Timeout                        300
 KeepAlive              On
 MaxKeepAliveRequests   100
-KeepAliveTimeout       15
+KeepAliveTimeout       300
 
 LoadModule log_config_module   /usr/lib/httpd/modules/mod_log_config.so
 LoadModule ssl_module          /usr/lib/httpd/modules/mod_ssl.so
@@ -160,8 +160,14 @@ GridSiteCastAlias https://sitecast.domain:488/ /var/www/html/
  GridSiteIndexes       on
  GridSiteAuth          on
  GridSiteDNlists       /etc/grid-security/dn-lists/
+ GridSiteDNlistsURI     /dn-lists/
  GridSiteGSIProxyLimit 9
  GridSiteMethods       GET PUT DELETE MOVE
 </Directory>
+
+<Location "/dn-lists/">
+ GridSiteACLPath /var/www/html/.gacl
+</Location>
+
  
 </VirtualHost>
index fc8c3bb..be7e903 100644 (file)
@@ -53,8 +53,10 @@ elements. If header and footer files are found, they will be used too.
 
 .IP "GridSiteHeadFile file"
 .IP "GridSiteFootFile file"
-Set the filenames to be searched for as standard headers and footers
-for HTML pages. For each HTML page, the directory of that page is tried
+Set the filenames to be used for as standard headers and footers
+for HTML pages. If the file name begins with "/" then this is used
+as the absolute path to that file to be used. Otherwise,
+for each HTML page, the directory of that page is tried
 first, and then parent directories in ascending order until a header / 
 footer file is found. Header files are inserted in place of HTML
 <body[ ...]> tags; footer files in place of </body>. (These
index 30bb91f..eb28011 100644 (file)
  * For more about GridSite: http://www.gridsite.org/             *
  *---------------------------------------------------------------*/
 
+#ifndef GRST_VERSION
+#define GRST_VERSION 010500
+#endif
+
 #ifndef HEADER_SSL_H
 #include <openssl/ssl.h>
 #endif
@@ -391,6 +395,8 @@ void  GRSThttpPrintf(GRSThttpBody *, char *, ...);
 int   GRSThttpCopy(GRSThttpBody *, char *);
 void  GRSThttpWriteOut(GRSThttpBody *);
 int   GRSThttpPrintHeaderFooter(GRSThttpBody *, char *, char *);
+int   GRSThttpPrintHeader(GRSThttpBody *, char *);
+int   GRSThttpPrintFooter(GRSThttpBody *, char *);
 char *GRSThttpGetCGI(char *);
 
 time_t GRSTasn1TimeToTimeT(char *, size_t);
index 2a4e0d4..6c6ad6d 100644 (file)
@@ -349,7 +349,8 @@ install: apidoc install-lib
                  $(prefix)/share/man/man8 \
                  $(prefix)/lib/httpd/modules \
                  $(prefix)/share/doc/gridsite-$(MINOR_VERSION)
-       cp -f ../interface/gridsite.h $(prefix)/include
+       echo "#define GRST_VERSION $DEFVERSION" > $(prefix)/include/gridsite.h
+       cat ../interface/gridsite.h >>$(prefix)/include/gridsite.h
        cp -f ../interface/gridsite-gacl.h $(prefix)/include
        cp -f urlencode $(prefix)/bin
        cp -f findproxyfile $(prefix)/bin
index fbc00a2..a9071c2 100644 (file)
@@ -175,23 +175,23 @@ void uploadfile(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
           puts("Status: 403 Forbidden filename\nContent-Type: text/html");
                                                                                 
           GRSThttpBodyInit(&bp);
-                                                                   
+
           GRSThttpPrintf(&bp,"<title>Forbidden filename %s</title>\n", filename);
-          GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE);
-                                 
+          GRSThttpPrintHeader(&bp, dir_path);
+
           GRSThttpPrintf(&bp, "<h1 align=center>Forbidden filename %s</h1>\n",
                          filename);
-                                                                                
+
           GRSThttpPrintf(&bp,
                       "<p align=center>New file names cannot include slashes "
                       "or use the reserved ACL name, %s\n", GRST_ACL_FILE);
-                                                                                
+
           GRSThttpPrintf(&bp,"<p align=center>"
                      "<a href=\"%s%s?cmd=managedir\">Return to "
                      "directory listing</a>\n", dir_uri, admin_file);
-                                                                                
+
           adminfooter(&bp, dn, help_uri, dir_uri, admin_file);
-          GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE);
+          GRSThttpPrintFooter(&bp, dir_path);
                                                                                 
           GRSThttpWriteOut(&bp);
           return;
@@ -233,7 +233,7 @@ void uploadfile(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
 
   GRSThttpPrintf(&bp, "<title>Failed to upload</title>\n");
 
-  GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE);
+  GRSThttpPrintHeader(&bp, dir_path);
 
   GRSThttpPrintf(&bp, "<h1 align=center>Failed to upload</h1>\n");
   
@@ -247,7 +247,7 @@ void uploadfile(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
                      "directory listing</a>\n", dir_uri, admin_file);
   
   adminfooter(&bp, dn, help_uri, dir_uri, admin_file);
-  GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE);
+  GRSThttpPrintFooter(&bp, dir_path);
 
   GRSThttpWriteOut(&bp);
 }
@@ -341,7 +341,7 @@ void deletefileaction(char *dn, GRSTgaclPerm perm, char *help_uri,
 
   GRSThttpPrintf(&bp, "<title>Error deleting %s%s</title>\n", dir_uri, file);
 
-  GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE);
+  GRSThttpPrintHeader(&bp, dir_path);
 
   GRSThttpPrintf(&bp, "<h1 align=center>Error deleting %s%s</h1>\n", 
                       dir_uri, file);
@@ -357,7 +357,7 @@ void deletefileaction(char *dn, GRSTgaclPerm perm, char *help_uri,
                      "directory listing</a>\n", dir_uri, admin_file);
   
   adminfooter(&bp, dn, help_uri, dir_uri, admin_file);
-  GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE);
+  GRSThttpPrintFooter(&bp, dir_path);
 
   GRSThttpWriteOut(&bp);
 }                    
@@ -375,7 +375,7 @@ void deletefileform(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
 
   GRSThttpPrintf(&bp, "<title>Delete %s</title>\n", file);
 
-  GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE);
+  GRSThttpPrintHeader(&bp, dir_path);
 
   GRSThttpPrintf(&bp, "<h1 align=center>Delete %s</h1>\n", file);
   
@@ -391,7 +391,7 @@ void deletefileform(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
                      "directory listing</a>\n", dir_uri, admin_file);
   
   adminfooter(&bp, dn, help_uri, dir_uri, admin_file);
-  GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE);
+  GRSThttpPrintFooter(&bp, dir_path);
 
   GRSThttpWriteOut(&bp);
 }                    
@@ -409,7 +409,7 @@ void renameform(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
 
   GRSThttpPrintf(&bp, "<title>Rename %s</title>\n", file);
 
-  GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE);
+  GRSThttpPrintHeader(&bp, dir_path);
 
   GRSThttpPrintf(&bp, "<h1 align=center>Rename %s%s</h1>\n", dir_uri, file);
   
@@ -426,7 +426,7 @@ void renameform(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
                      "directory listing</a>\n", dir_uri, admin_file, dir_uri);
   
   adminfooter(&bp, dn, help_uri, dir_uri, admin_file);
-  GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE);
+  GRSThttpPrintFooter(&bp, dir_path);
 
   GRSThttpWriteOut(&bp);
 }                    
@@ -470,7 +470,7 @@ void editfileaction(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
       GRSThttpBodyInit(&bp);
 
       GRSThttpPrintf(&bp,"<title>Error writing %s%s</title>\n", dir_uri, file);
-      GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE);
+      GRSThttpPrintHeader(&bp, dir_path);
 
       GRSThttpPrintf(&bp, "<h1 align=center>Error writing %s%s</h1>\n", 
                       dir_uri, file);
@@ -486,7 +486,7 @@ void editfileaction(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
                      "directory listing</a>\n", dir_uri, admin_file);
   
       adminfooter(&bp, dn, help_uri, dir_uri, admin_file);
-      GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE);
+      GRSThttpPrintFooter(&bp, dir_path);
 
       GRSThttpWriteOut(&bp);
       return;
@@ -542,7 +542,7 @@ void create_acl(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
 
   GRSThttpPrintf(&bp,"<title>Error creating %s%s</title>\n", dir_uri, 
                                                              GRST_ACL_FILE);
-  GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE);
+  GRSThttpPrintHeader(&bp, dir_path);
 
   GRSThttpPrintf(&bp, "<h1 align=center>Error creating %s%s</h1>\n", 
                       dir_uri, GRST_ACL_FILE);
@@ -557,7 +557,7 @@ void create_acl(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
                      "directory listing</a>\n", dir_uri, admin_file);
   
   adminfooter(&bp, dn, help_uri, dir_uri, admin_file);
-  GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE);
+  GRSThttpPrintFooter(&bp, dir_path);
 
   GRSThttpWriteOut(&bp);
 
@@ -625,7 +625,7 @@ void renameaction(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
   GRSThttpBodyInit(&bp);
 
   GRSThttpPrintf(&bp,"<title>Error renaming %s%s</title>\n", dir_uri, file);
-  GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE);
+  GRSThttpPrintHeader(&bp, dir_path);
 
   GRSThttpPrintf(&bp, "<h1 align=center>Error renaming %s%s</h1>\n", 
                       dir_uri, file);
@@ -640,7 +640,7 @@ void renameaction(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
                      "directory listing</a>\n", dir_uri, admin_file);
   
   adminfooter(&bp, dn, help_uri, dir_uri, admin_file);
-  GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE);
+  GRSThttpPrintFooter(&bp, dir_path);
 
   GRSThttpWriteOut(&bp);
 }
@@ -678,7 +678,7 @@ void newdirectory(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
   GRSThttpBodyInit(&bp);
 
   GRSThttpPrintf(&bp,"<title>Error create %s%s</title>\n", dir_uri, file);
-  GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE);
+  GRSThttpPrintHeader(&bp, dir_path);
 
   GRSThttpPrintf(&bp, "<h1 align=center>Error creating directory %s%s</h1>\n",
                       dir_uri, file);
@@ -694,7 +694,7 @@ void newdirectory(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
                      "parent directory listing</a>\n", dir_uri, admin_file);
   
   adminfooter(&bp, dn, help_uri, dir_uri, admin_file);
-  GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE);
+  GRSThttpPrintFooter(&bp, dir_path);
 
   GRSThttpWriteOut(&bp);
 }
@@ -733,7 +733,7 @@ void editdnlistaction(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_pat
       GRSThttpBodyInit(&bp);
 
       GRSThttpPrintf(&bp,"<title>Error writing %s</title>\n", file);
-      GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE);
+      GRSThttpPrintHeader(&bp, dir_path);
 
       GRSThttpPrintf(&bp, "<h1 align=center>Error writing %s to %s</h1>\n", 
                      file, dir_uri);
@@ -747,7 +747,7 @@ void editdnlistaction(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_pat
                      "directory listing</a>\n", dir_uri, admin_file);
   
       adminfooter(&bp, dn, help_uri, dir_uri, admin_file);
-      GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE);
+      GRSThttpPrintFooter(&bp, dir_path);
 
       GRSThttpWriteOut(&bp);
       return;    
@@ -818,7 +818,7 @@ void editdnlistaction(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_pat
   GRSThttpBodyInit(&bp);
 
   GRSThttpPrintf(&bp,"<title>Error writing %s%s</title>\n", dir_uri, file);
-  GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE);
+  GRSThttpPrintHeader(&bp, dir_path);
 
   GRSThttpPrintf(&bp, "<h1 align=center>Error writing %s%s</h1>\n", 
                       dir_uri, file);
@@ -833,7 +833,7 @@ void editdnlistaction(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_pat
                      "directory listing</a>\n", dir_uri, admin_file);
   
   adminfooter(&bp, dn, help_uri, dir_uri, admin_file);
-  GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE);
+  GRSThttpPrintFooter(&bp, dir_path);
 
   GRSThttpWriteOut(&bp);
 
@@ -895,7 +895,7 @@ void filehistory(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
                                                                                 
   GRSThttpBodyInit(&bp);
   GRSThttpPrintf(&bp, "<title>History of %s%s</title>\n", dir_uri, file);
-  GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE);
+  GRSThttpPrintHeader(&bp, dir_path);
   GRSThttpPrintf(&bp,
    "<h1 align=center>History of <a href=\"%s%s\">%s%s</a></h1>\n",
    dir_uri, file, dir_uri, file);
@@ -984,7 +984,7 @@ void filehistory(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
        adminfooter(&bp, dn, help_uri, dir_uri, admin_file);
   else adminfooter(&bp, dn, help_uri, dir_uri, NULL);
                                                                                 
-  GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE);
+  GRSThttpPrintFooter(&bp, dir_path);
   GRSThttpWriteOut(&bp);
 }
 
@@ -1003,7 +1003,7 @@ void ziplist(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
                                                                                 
   GRSThttpBodyInit(&bp);
   GRSThttpPrintf(&bp, "<title>Contents of %s%s</title>\n", dir_uri, file);
-  GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE);
+  GRSThttpPrintHeader(&bp, dir_path);
   GRSThttpPrintf(&bp,
    "<h1 align=center>Contents of ZIP file <a href=\"%s%s\">%s%s</a></h1>\n",
    dir_uri, file, dir_uri, file);
@@ -1038,7 +1038,7 @@ void ziplist(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
        adminfooter(&bp, dn, help_uri, dir_uri, admin_file);
   else adminfooter(&bp, dn, help_uri, dir_uri, NULL);
                                                                                 
-  GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE);
+  GRSThttpPrintFooter(&bp, dir_path);
   GRSThttpWriteOut(&bp);
 }
 
@@ -1057,7 +1057,7 @@ void unzipfile(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
                                                                                 
   GRSThttpBodyInit(&bp);
   GRSThttpPrintf(&bp, "<title>Unzipping %s%s</title>\n", dir_uri, file);
-  GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE);
+  GRSThttpPrintHeader(&bp, dir_path);
   GRSThttpPrintf(&bp,
    "<h1 align=center>Unzipping <a href=\"%s%s\">%s%s</a></h1>\n",
    dir_uri, file, dir_uri, file);
@@ -1087,7 +1087,7 @@ void unzipfile(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
        adminfooter(&bp, dn, help_uri, dir_uri, admin_file);
   else adminfooter(&bp, dn, help_uri, dir_uri, NULL);
                                                                                 
-  GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE);
+  GRSThttpPrintFooter(&bp, dir_path);
   GRSThttpWriteOut(&bp);
 }
 
@@ -1126,7 +1126,7 @@ void editfileform(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
 
   GRSThttpPrintf(&bp, "<title>Edit file %s</title>\n", file);
 
-  GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE);
+  GRSThttpPrintHeader(&bp, dir_path);
 
   GRSThttpPrintf(&bp, "<h1>Edit file %s</h1>\n", file);
   
@@ -1176,7 +1176,7 @@ void editfileform(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
 
   adminfooter(&bp, dn, help_uri, dir_uri, admin_file);
   
-  GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE);
+  GRSThttpPrintFooter(&bp, dir_path);
   GRSThttpWriteOut(&bp);
 }
 
@@ -1223,7 +1223,7 @@ void editdnlistform(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
 
   GRSThttpPrintf(&bp, "<title>Edit DN List %s</title>\n", file);
 
-  GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE);
+  GRSThttpPrintHeader(&bp, dir_path);
 
   GRSThttpPrintf(&bp, "<h1>Edit DN List</h1>\n");
   
@@ -1265,17 +1265,16 @@ void editdnlistform(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
 
   adminfooter(&bp, dn, help_uri, dir_uri, admin_file);
   
-  GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE);
+  GRSThttpPrintFooter(&bp, dir_path);
   GRSThttpWriteOut(&bp);
 }
 
 void managedir(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
                char *dir_uri, char *admin_file)
 {
-  int         n, is_dnlists_dir = 0, enclen, numfiles, encprefixlen;
+  int         n, numfiles;
   char       *d_namepath, modified[99], *absaclpath, *editable, *p, *unzip,
-             *dnlistsuri, *d_name, *server_name, *fulluri, *encfulluri,
-             *encprefix, *dnlistsprefix;
+             *d_name;
   GRSThttpBody    bp;
   struct tm       mtime_tm;
   struct stat     statbuf;
@@ -1293,30 +1292,13 @@ void managedir(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
   unzip = getenv("GRST_UNZIP");
   if (unzip == NULL) unzip = getenv("REDIRECT_GRST_UNZIP");
   
-  dnlistsuri = getenv("GRST_DN_LISTS_URI");
-  if (dnlistsuri == NULL) dnlistsuri = getenv("REDIRECT_GRST_DN_LISTS_URI");
-
-  if (dnlistsuri && (strncmp(dnlistsuri, dir_uri, strlen(dnlistsuri)) == 0))
-    {
-      is_dnlists_dir = 1;
-      server_name = getenv("SERVER_NAME");
-
-      asprintf(&fulluri, "https://%s%s", server_name, dir_uri);
-      encfulluri = GRSThttpUrlEncode(fulluri);
-      enclen = strlen(encfulluri);
-
-      asprintf(&dnlistsprefix, "https://%s%s", server_name, dnlistsuri);
-      encprefix = GRSThttpUrlEncode(dnlistsprefix);
-      encprefixlen = strlen(encprefix);
-    }
-  
   printf("Status: 200 OK\nContent-Type: text/html\n");
 
   GRSThttpBodyInit(&bp);
 
   GRSThttpPrintf(&bp,"<title>Manage directory %s</title>\n", dir_uri);
 
-  GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE);
+  GRSThttpPrintHeader(&bp, dir_path);
     
   GRSThttpPrintf(&bp, "<h1>Manage directory %s</h1>\n<table>\n", dir_uri);
   
@@ -1339,25 +1321,17 @@ void managedir(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
            "<td align=right>%R</td><td align=right>%e&nbsp;%b&nbsp;%y</td>",
                         &mtime_tm);    
 
-          if (!is_dnlists_dir)
-            {
-              GRSThttpPrintf(&bp,
+          GRSThttpPrintf(&bp,
                       "<tr><td><a href=\"%s\">%s</a></td>"
                       "<td align=right>%ld</td>%s\n",
                       GRST_ACL_FILE,
                       GRST_ACL_FILE,
                       statbuf.st_size, modified);
 
-              GRSThttpPrintf(&bp,
+          GRSThttpPrintf(&bp,
                    "<td><a href=\"%s%s?cmd=history&amp;file=%s\">"
-                      "History</a></td>",
-                      dir_uri, admin_file, GRST_ACL_FILE);
-            }
-          else GRSThttpPrintf(&bp,
-                      "<tr><td>%s</td>"
-                      "<td align=right>%ld</td>%s\n",
-                      GRST_ACL_FILE,
-                      statbuf.st_size, modified);
+                   "History</a></td>",
+                   dir_uri, admin_file, GRST_ACL_FILE);
 
           if (GRSTgaclPermHasAdmin(perm)) 
                GRSThttpPrintf(&bp,
@@ -1438,41 +1412,7 @@ void managedir(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
                       
                    GRSThttpPrintf(&bp, "<td>&nbsp;</td></tr>\n");
                  }
-               else if (is_dnlists_dir) 
-                 {        
-                   if ((strlen(namelist[n]->d_name) <= encprefixlen) ||
-                       (strncmp(namelist[n]->d_name, encprefix, 
-                                              encprefixlen) != 0)) continue;
-
-                   d_name = GRSThttpUrlDecode(namelist[n]->d_name);
-
-                   GRSThttpPrintf(&bp, "<tr><td><a href=\"%s\">%s</a></td>"
-                                       "<td align=right>%ld</td>%s"
-                                       "<td>&nbsp;</td>",
-                                       d_name, d_name,
-                                       statbuf.st_size, modified);
-
-                   if (GRSTgaclPermHasWrite(perm))
-                     GRSThttpPrintf(&bp, "<form action=\"%s%s\" method=post>"
-                        "<td><input type=submit value=Edit></td>"
-                        "<input type=hidden name=cmd value=editdnlist>"
-                        "<input type=hidden name=file value=\"%s\">"
-                        "</form>\n",
-                        dir_uri, admin_file, d_name);
-                   else GRSThttpPrintf(&bp, "<td>&nbsp;</td>\n");
-                   
-                   if (GRSTgaclPermHasWrite(perm))
-                     GRSThttpPrintf(&bp, "<form action=\"%s%s\" method=post>"
-                        "<td><input type=submit value=Delete></td>"
-                        "<input type=hidden name=cmd value=delete>"
-                        "<input type=hidden name=file value=\"%s\">"
-                        "</form>\n",
-                        dir_uri, admin_file, d_name);
-                   else GRSThttpPrintf(&bp, "<td>&nbsp;</td>\n");
-
-                   GRSThttpPrintf(&bp, "<td>&nbsp;</td></tr>");
-                 }
-               else /* regular directory, not DN Lists */
+               else /* regular file */
                  {        
                    d_name = namelist[n]->d_name;
 
@@ -1531,26 +1471,7 @@ void managedir(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
 
   if (GRSTgaclPermHasWrite(perm))
     {
-      if (is_dnlists_dir)
-        {
-          GRSThttpPrintf(&bp, "<form method=post action=\"%s%s\">\n"
-        "<tr><td colspan=4>New list name: "
-        "<input type=text name=file value=\"%sNEW_LIST\" size=%d>\n"
-        "<input type=hidden name=cmd value=editdnlist></td>"
-        "<td colspan=2 align=center><input type=submit value=Create></td>\n"
-        "</tr></form>\n",
-        dir_uri, admin_file, fulluri, strlen(fulluri)+8);
-
-          GRSThttpPrintf(&bp, "<form method=post action=\"%s%s\">\n"
-        "<tr><td colspan=4>New directory: "
-        "<input type=text name=file>\n"
-        "<td colspan=2 align=center><input type=submit name=button value=\"Create\"></td>\n"
-        "<input type=hidden name=cmd value=edit></td></tr></form>\n",
-        dir_uri, admin_file);      
-        }
-      else
-        {
-          GRSThttpPrintf(&bp, "<form method=post action=\"%s%s\">\n"
+      GRSThttpPrintf(&bp, "<form method=post action=\"%s%s\">\n"
         "<tr><td colspan=8><hr width=\"75%\"></td></tr>\n"
         "<tr><td>New name:</td>"
         "<td colspan=3><input type=text name=file size=25>\n"
@@ -1559,7 +1480,7 @@ void managedir(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
         "<input type=hidden name=cmd value=edit></td></tr></form>\n",
         dir_uri, admin_file);
       
-          GRSThttpPrintf(&bp,
+      GRSThttpPrintf(&bp,
         "<form method=post action=\"%s%s\" enctype=\"multipart/form-data\">\n"
         "<tr><td colspan=8><hr width=\"75%\"></td></tr>\n"
         "<tr><td rowspan=2>Upload file:</td>"
@@ -1569,14 +1490,164 @@ void managedir(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
         "<tr><td colspan=2>Local name:</td>"
         "<td colspan=6><input type=file name=uploadfile size=25></td></tr>\n"
         "</form>\n", dir_uri, admin_file);
-        }
     }
 
   GRSThttpPrintf(&bp, "</table>\n");
 
-  if (!is_dnlists_dir) adminfooter(&bp, dn, help_uri, dir_uri, NULL);
+  adminfooter(&bp, dn, help_uri, dir_uri, NULL);
+
+  GRSThttpPrintFooter(&bp, dir_path);
+  GRSThttpWriteOut(&bp);
+}
+
+int userisgroupadmin(GRSTgaclUser *user, char *adminrole, char *uri)
+{
+  char *uri_workspace, *p;
+  
+  if (uri[strlen(uri) - 1] == '/') 
+       asprintf(&uri_workspace, "%sRole=%s",  uri, adminrole);
+  else asprintf(&uri_workspace, "%s/Role=%s", uri, adminrole);
+  
+  while (1)
+       {
+         if (GRSTgaclUserHasAURI(user, uri_workspace))
+           {
+             free(uri_workspace);
+             return 1;
+           }
+
+         p = rindex(uri_workspace, '/');
+         if (p == NULL) 
+           {
+             free(uri_workspace);
+             return 0;
+           }
+
+         *p = '\0';
+         strcat(uri_workspace, "/Role=");
+         strcat(uri_workspace, adminrole);
+       }
+}
+
+void managednlists(GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, 
+                   char *help_uri, char *dir_path,
+                   char *dir_uri, char *admin_file)
+{
+  int         n, enclen, numfiles, encprefixlen, has_any_admin = 0;
+  char       *d_namepath, modified[99], *p, *adminrole, *dnlists_path,
+             *dnlistsuri, *d_name, *server_name, *fulluri, *encfulluri,
+             *encprefix, *dnlistsprefix, *unencuri;
+  GRSThttpBody    bp;
+  struct tm       mtime_tm;
+  struct stat     statbuf;
+  struct dirent **namelist, *subdirfile_ent;
+  DIR            *subDIR;
+
+  /* need to have got GACL list permission from somewhere, 
+     but we dont use GACL permissions apart from this */
+
+  if (!GRSTgaclPermHasList(perm)) GRSThttpError("403 Forbidden");
+
+  p = getenv("REDIRECT_GRST_DN_LISTS");
+
+  if (p == NULL) p = getenv("GRST_DN_LISTS");
+  
+  if (p == NULL) p = GRST_DN_LISTS;
+
+  dnlists_path = strdup(p);
+          
+  p = index(dnlists_path, ':');
+  if (p != NULL) *p = '\0';
+
+  dnlistsuri = getenv("REDIRECT_GRST_DN_LISTS_URI");
+  if (dnlistsuri == NULL) dnlistsuri = getenv("GRST_DN_LISTS_URI");
+
+  adminrole = getenv("REDIRECT_GRST_DN_LISTS_ADMIN_ROLE");
+  if (adminrole == NULL) adminrole = getenv("GRST_DN_LISTS_ADMIN_ROLE");
+
+  server_name = getenv("SERVER_NAME");
+  asprintf(&dnlistsprefix, "https://%s%s", server_name, dnlistsuri);
+  encprefix = GRSThttpUrlEncode(dnlistsprefix);
+  encprefixlen = strlen(encprefix);
+  
+//  asprintf(&fulluri, "https://%s%s", server_name, dir_uri);
+//  encfulluri = GRSThttpUrlEncode(fulluri);
+//  enclen = strlen(encfulluri);
+
+  printf("Status: 200 OK\nContent-Type: text/html\n");
+
+  GRSThttpBodyInit(&bp);
+
+  GRSThttpPrintf(&bp,"<title>Manage DN lists</title>\n");
+
+  GRSThttpPrintHeader(&bp, dir_path);
+    
+  GRSThttpPrintf(&bp, "<h1>Manage DN lists</h1>\n<table>\n");
+
+  n = scandir(dnlists_path, &namelist, 0, alphasort);
+  while (n--)
+       {       
+         if (namelist[n]->d_name[0] == '.') continue;
+         
+         if (strncmp(namelist[n]->d_name, encprefix, encprefixlen) != 0) continue;
+
+         unencuri = GRSThttpUrlDecode(namelist[n]->d_name);
+
+         if (userisgroupadmin(user, adminrole, unencuri))
+           {
+             has_any_admin = 1;
+           
+             localtime_r(&(statbuf.st_mtime), &mtime_tm);
+             strftime(modified, sizeof(modified), 
+               "<td align=right>%R</td><td align=right>%e&nbsp;%b&nbsp;%y</td>",
+                        &mtime_tm);    
+                              
+             GRSThttpPrintf(&bp, "<tr><td><a href=\"%s\">%s</a></td>"
+                                 "<td align=right>%ld</td>%s"
+                                 "<td>&nbsp;</td>",
+                                 unencuri, unencuri,
+                                 statbuf.st_size, modified);
+
+             GRSThttpPrintf(&bp, 
+                        "<form action=\"./%s\" method=post>"
+                        "<td><input type=submit value=Edit></td>"
+                        "<input type=hidden name=cmd value=editdnlist>"
+                        "<input type=hidden name=file value=\"%s\">"
+                        "</form>\n",
+                        admin_file, unencuri);
+                   
+             GRSThttpPrintf(&bp, 
+                        "<form action=\"./%s\" method=post>"
+                        "<td><input type=submit value=Delete></td>"
+                        "<input type=hidden name=cmd value=delete>"
+                        "<input type=hidden name=file value=\"%s\">"
+                        "</form>\n",
+                        admin_file, unencuri);
+
+             GRSThttpPrintf(&bp, "<td>&nbsp;</td></tr>");             
+           }
+           
+         free(unencuri);
+         free(namelist[n]);
+       }
+                    
+  free(namelist);
+
+  if (has_any_admin)
+    {
+      GRSThttpPrintf(&bp, "<form method=post action=\"./%s\">\n"
+        "<tr><td colspan=4>New DN list name: "
+        "<input type=text name=file value=\"%s\" size=%d>\n"
+        "<input type=hidden name=cmd value=editdnlist></td>"
+        "<td colspan=2 align=center><input type=submit value=Create></td>\n"
+        "</tr></form>\n",
+        admin_file, dnlistsprefix, strlen(dnlistsprefix)+8);
+    }
+
+  GRSThttpPrintf(&bp, "</table>\n");
 
-  GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE);
+// change everywhere else too!
+  GRSThttpPrintFooter(&bp, dir_path);
   GRSThttpWriteOut(&bp);
 }
 
index 580060e..37aabc2 100644 (file)
@@ -128,7 +128,7 @@ void show_acl(int admin, GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *
   if (acl==NULL){
     GRSThttpPrintf ( &bp,"The ACL was found but could not be loaded - it could be incorrectly formatted<br>\n");
     adminfooter(&bp, dn, help_uri, dir_uri, NULL);
-    GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); 
+    GRSThttpPrintFooter(&bp, dir_path); 
     GRSThttpWriteOut(&bp);
     return;
   }
@@ -176,7 +176,7 @@ void show_acl(int admin, GRSTgaclUser *user, char *dn, GRSTgaclPerm perm, char *
   }
 
   adminfooter(&bp, dn, help_uri, dir_uri, NULL);
-  GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE); GRSThttpWriteOut(&bp); return;
+  GRSThttpPrintFooter(&bp, dir_path); GRSThttpWriteOut(&bp); return;
 }
 
 
@@ -551,7 +551,7 @@ void admin_continue(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
   // Should ALWAYS be the end of a page
   GRSThttpPrintf (bp, "\n<br><a href=\"%s%s?diruri=%s&cmd=admin_acl&timestamp=%d\">Click&nbsp;Here</a> to return to the editor", dir_uri,admin_file,dir_uri, time(NULL));
   adminfooter(bp, dn, help_uri, dir_uri, NULL);
-  GRSThttpPrintHeaderFooter(bp, dir_path, GRST_FOOTFILE);
+  GRSThttpPrintFooter(bp, dir_path);
   GRSThttpWriteOut(bp);
   return;
 }
@@ -767,7 +767,7 @@ void StartHTML(GRSThttpBody *bp, char *dir_uri, char* dir_path){
   printf("Status: 200 OK\nContent-Type: text/html\n");
   GRSThttpBodyInit(bp);
   GRSThttpPrintf(bp, "<title>Access Control List for %s</title>\n", dir_uri);
-  GRSThttpPrintHeaderFooter(bp, dir_path, GRST_HEADFILE);
+  GRSThttpPrintHeader(bp, dir_path);
   return;
 }
 void StartForm(GRSThttpBody *bp, char* dir_uri, char* dir_path, char* admin_file, int timestamp, char* target_function){
index 45e819b..eb81fed 100644 (file)
@@ -170,7 +170,7 @@ void justheader(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
    
   GRSThttpBodyInit(&bp);
  
-  GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_HEADFILE);
+  GRSThttpPrintHeader(&bp, dir_path);
 
   GRSThttpWriteOut(&bp);
 }
@@ -188,7 +188,7 @@ void justfooter(char *dn, GRSTgaclPerm perm, char *help_uri, char *dir_path,
                                 || GRSTgaclPermHasAdmin(perm))
                adminfooter(&bp, dn, help_uri, dir_uri, admin_file);
 
-  GRSThttpPrintHeaderFooter(&bp, dir_path, GRST_FOOTFILE);
+  GRSThttpPrintFooter(&bp, dir_path);
                                                                                 
   GRSThttpWriteOut(&bp);
 }
@@ -316,6 +316,8 @@ int main()
       printfile(dn, perm, help_uri, dir_path, file, dir_uri, admin_file);
   else if (strcmp(cmd, "history") == 0) 
       filehistory(dn, perm, help_uri, dir_path, file, dir_uri, admin_file);
+  else if (strcmp(cmd, "managednlists") == 0) 
+      managednlists(user, dn, perm, help_uri, dir_path, dir_uri, admin_file);
   else if (strcmp(cmd, "editdnlist") == 0) 
       editdnlistform(dn, perm, help_uri, dir_path, file, dir_uri, admin_file);
   else if (strcmp(cmd, "edit") == 0)
index c933ca0..3bb44b9 100644 (file)
@@ -201,6 +201,38 @@ int GRSThttpPrintHeaderFooter(GRSThttpBody *bp, char *file, char *headfootname)
   return found;
 }
 
+int GRSThttpPrintHeader(GRSThttpBody *bp, char *file)
+{
+  char *headname;
+  
+  headname = getenv("REDIRECT_GRST_HEAD_FILE");
+  if (headname == NULL) headname = getenv("GRST_HEAD_FILE");
+  if (headname == NULL) headname = GRST_HEADFILE;
+
+  if (headname[0] == '/') /* absolute location */
+    {
+      return GRSThttpCopy(bp, headname);
+    }
+    
+  return GRSThttpPrintHeaderFooter(bp, file, headname);
+}
+
+int GRSThttpPrintFooter(GRSThttpBody *bp, char *file)
+{
+  char *footname;
+  
+  footname = getenv("REDIRECT_GRST_FOOT_FILE");
+  if (footname == NULL) footname = getenv("GRST_FOOT_FILE");
+  if (footname == NULL) footname = GRST_FOOTFILE;
+
+  if (footname[0] == '/') /* absolute location */
+    {
+      return GRSThttpCopy(bp, footname);
+    }
+    
+  return GRSThttpPrintHeaderFooter(bp, file, footname);
+}
+
 char *GRSThttpGetCGI(char *name)
 /* 
    Return a malloc()ed copy of CGI form parameter identified by name[],
index 8ddd0be..6fa3d52 100644 (file)
@@ -129,6 +129,8 @@ struct sitecast_alias       sitecastaliases[GRST_SITECAST_ALIASES];
 typedef struct
 {
    int                 auth;
+   int                  autopasscode;
+   int                 zoneslashes;
    int                 envs;
    int                 format;
    int                 indexes;
@@ -219,7 +221,7 @@ char *html_escape(apr_pool_t *pool, char *s)
       if ((*p == '<') || (*p == '>') || (*p == '&') || (*p == '"')) 
           ++htmlspecials;
 
-    escaped = apr_palloc(pool, strlen(s) + htmlspecials * 6);
+    escaped = apr_palloc(pool, strlen(s) + htmlspecials * 6 + 1);
         
     for (i=0,p=s; *p != '\0'; ++p)
        {
@@ -442,24 +444,32 @@ int html_format(request_rec *r, mod_gridsite_dir_cfg *conf)
 
     /* **** try to find a header file in this or parent directories **** */
 
-    /* first make a buffer big enough to hold path names we want to try */
     fd = -1;
-    s = apr_palloc(r->pool, 
+
+    if (conf->headfile[0] == '/') /* try absolute */
+      {
+        fd = open(conf->headfile, O_RDONLY);
+      }
+    else /* try relative */
+      {
+        /* first make a buffer big enough to hold path names we want to try */
+        s = apr_palloc(r->pool, 
                        strlen(r->filename) + strlen(conf->headfile) + 1);
-    strcpy(s, r->filename);
+        strcpy(s, r->filename);
 
-    for (;;)
-       {
-         p = rindex(s, '/');
-         if (p == NULL) break; /* failed to find one */
-         p[1] = '\0';
-         strcat(p, conf->headfile);
+        for (;;)
+           {
+             p = rindex(s, '/');
+             if (p == NULL) break; /* failed to find one */
+             p[1] = '\0';
+             strcat(p, conf->headfile);
 
-         fd = open(s, O_RDONLY);
-         if (fd != -1) break; /* found one */
+             fd = open(s, O_RDONLY);
+             if (fd != -1) break; /* found one */
 
-         *p = '\0';
-       }
+             *p = '\0';
+           }
+      }
 
     if (fd == -1) /* not found, so set up not to output one */
       {
@@ -519,24 +529,32 @@ int html_format(request_rec *r, mod_gridsite_dir_cfg *conf)
 
     /* **** try to find a footer file in this or parent directories **** */
 
-    /* first make a buffer big enough to hold path names we want to try */
     fd = -1;
-    s = apr_palloc(r->pool, 
+
+    if (conf->footfile[0] == '/') /* try absolute */
+      {
+        fd = open(conf->footfile, O_RDONLY);
+      }
+    else /* try relative */
+      {
+        /* first make a buffer big enough to hold path names we want to try */
+        s = apr_palloc(r->pool, 
                        strlen(r->filename) + strlen(conf->footfile) + 1);
-    strcpy(s, r->filename);
+        strcpy(s, r->filename);
 
-    for (;;)
-       {
-         p = rindex(s, '/');
-         if (p == NULL) break; /* failed to find one */
+        for (;;)
+           {
+             p = rindex(s, '/');
+             if (p == NULL) break; /* failed to find one */
 
-         p[1] = '\0';
-         strcat(p, conf->footfile);
+             p[1] = '\0';
+             strcat(p, conf->footfile);
 
-         fd = open(s, O_RDONLY);
-         if (fd != -1) break; /* found one */
+             fd = open(s, O_RDONLY);
+             if (fd != -1) break; /* found one */
 
-         *p = '\0';
+             *p = '\0';
+           }
        }
 
     if (fd == -1) /* failed to find a footer, so set up empty default */
@@ -581,7 +599,7 @@ int html_dir_list(request_rec *r, mod_gridsite_dir_cfg *conf)
     int    i, fd, n, nn;
     char  *buf, *p, *s, *head_formatted, *header_formatted,
           *body_formatted, *admin_formatted, *footer_formatted, *temp,
-           modified[99], *d_namepath, *indexheaderpath, *indexheadertext,
+           modified[999], *d_namepath, *indexheaderpath, *indexheadertext,
            *encoded, *escaped;
     size_t length;
     struct stat statbuf;
@@ -779,25 +797,21 @@ int html_dir_list(request_rec *r, mod_gridsite_dir_cfg *conf)
     return OK;
 }
 
-int http_gridhttp(request_rec *r, mod_gridsite_dir_cfg *conf)
-{ 
-    int          i;
-    char        *httpurl, *filetemplate, *cookievalue, *envname_i, 
-                *grst_cred_i, expires_str[APR_RFC822_DATE_LEN];
-    apr_uint64_t gridauthcookie;
-    apr_table_t *env;
-    apr_time_t   expires_time;
-    apr_file_t  *fp;
+char *make_passcode_file(request_rec *r, mod_gridsite_dir_cfg *conf, 
+                         char *path, apr_time_t expires_time)
+{
+    int           i;
+    char         *filetemplate, *notename_i, *grst_cred_i, *cookievalue=NULL;
+    apr_uint64_t  gridauthcookie;
+    apr_table_t  *env;
+    apr_file_t   *fp;
 
-    /* create random cookie and gridauthcookie file */
+    /* create random for use in GRIDHTTP_PASSCODE cookies and file name */
 
     if (apr_generate_random_bytes((char *) &gridauthcookie, 
                                   sizeof(gridauthcookie))
-         != APR_SUCCESS) return HTTP_INTERNAL_SERVER_ERROR;
+         != APR_SUCCESS) return NULL;
     
-    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
-               "Generated GridHTTP passcode %016llx", gridauthcookie);
-
     filetemplate = apr_psprintf(r->pool, "%s/passcode-%016llxXXXXXX", 
      ap_server_root_relative(r->pool,
      sessionsdir),
@@ -807,35 +821,31 @@ int http_gridhttp(request_rec *r, mod_gridsite_dir_cfg *conf)
                         filetemplate, 
                         APR_CREATE | APR_WRITE | APR_EXCL,
                         r->pool)
-                      != APR_SUCCESS) return HTTP_INTERNAL_SERVER_ERROR;
+                      != APR_SUCCESS) return NULL;
                       
     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                "Created passcode file %s", filetemplate);
 
-    expires_time = apr_time_now() + apr_time_from_sec(300);
-    /* passcode cookies are valid for only 5 mins! */
+    if (expires_time > 0) apr_file_printf(fp, "expires=%lu\n",
+                                      (time_t) apr_time_sec(expires_time));
 
-    apr_file_printf(fp,
-              "expires=%lu\ndomain=%s\npath=%s\nonetime=yes\nmethod=%s\n",
-              (time_t) apr_time_sec(expires_time),
-              r->hostname, r->uri, r->method);
-    /* above variables are evaluated in order and method= MUST be last! */
+    apr_file_printf(fp, "domain=%s\npath=%s\n", r->hostname, path);
 
     for (i=0; ; ++i)
        {
-         envname_i = apr_psprintf(r->pool, "GRST_CRED_AURI_%d", i);
+         notename_i = apr_psprintf(r->pool, "GRST_CRED_AURI_%d", i);
          if (grst_cred_i = (char *)
-                           apr_table_get(r->connection->notes, envname_i))
+                           apr_table_get(r->connection->notes, notename_i))
            {
-             apr_file_printf(fp, "%s=%s\n", envname_i, grst_cred_i);
+             apr_file_printf(fp, "%s=%s\n", notename_i, grst_cred_i);
            }
          else break; /* GRST_CRED_AURI_i are numbered consecutively */
 
-         envname_i = apr_psprintf(r->pool, "GRST_CRED_VALID_%d", i);
+         notename_i = apr_psprintf(r->pool, "GRST_CRED_VALID_%d", i);
          if (grst_cred_i = (char *)
-                           apr_table_get(r->connection->notes, envname_i))
+                           apr_table_get(r->connection->notes, notename_i))
            {
-             apr_file_printf(fp, "%s=%s\n", envname_i, grst_cred_i);
+             apr_file_printf(fp, "%s=%s\n", notename_i, grst_cred_i);
            }
          else break; /* GRST_CRED_VALID_i are numbered consecutively */
        }
@@ -843,20 +853,38 @@ int http_gridhttp(request_rec *r, mod_gridsite_dir_cfg *conf)
     if (apr_file_close(fp) != APR_SUCCESS) 
       {
         apr_file_remove(filetemplate, r->pool); /* try to clean up */
-        return HTTP_INTERNAL_SERVER_ERROR;
+        return NULL;
+      }
+      
+    cookievalue = rindex(filetemplate, '-');
+    if (cookievalue != NULL) 
+      {
+        ++cookievalue;
+        return cookievalue;
       }
+    else return NULL;
+}
+
+int http_gridhttp(request_rec *r, mod_gridsite_dir_cfg *conf)
+{ 
+    char        *httpurl, *cookievalue, expires_str[APR_RFC822_DATE_LEN];
+    apr_time_t   expires_time;
+
+    /* passcode cookies are valid for only 5 mins! */
+    expires_time = apr_time_now() + apr_time_from_sec(300);
+
+    /* try to generate passcode and make passcode file */
+    cookievalue = make_passcode_file(r, conf, r->uri, expires_time);
+    
+    if (cookievalue == NULL) return HTTP_INTERNAL_SERVER_ERROR;
     
     /* send redirection header back to client */
        
-    cookievalue = rindex(filetemplate, '-');
-    if (cookievalue != NULL) ++cookievalue;
-    else cookievalue = filetemplate;
-       
     apr_rfc822_date(expires_str, expires_time);
 
     apr_table_add(r->headers_out, 
-                  apr_pstrdup(r->pool, "Set-Cookie"), 
-                  apr_psprintf(r->pool, 
+                  apr_pstrdup(r->pool, "Set-Cookie"),
+                  apr_psprintf(r->pool,
                   "GRIDHTTP_PASSCODE=%s; "
                   "expires=%s; "
                   "domain=%s; "
@@ -1168,7 +1196,7 @@ static int mod_gridsite_nondir_handler(request_rec *r, mod_gridsite_dir_cfg *con
 static void recurse4dirlist(char *dirname, time_t *dirs_time,
                              char *fulluri, int fullurilen,
                              char *encfulluri, int enclen,
-                             apr_pool_t *pool, char **body,
+                             request_rec *r, char **body,
                              int recurse_level)
 /* try to find DN Lists in dir[] and its subdirs that match the fulluri[]
    prefix. add blobs of HTML to body as they are found. */
@@ -1191,13 +1219,17 @@ static void recurse4dirlist(char *dirname, time_t *dirs_time,
         {
           if (onedirent->d_name[0] == '.') continue;
         
-          d_namepath = apr_psprintf(pool, "%s/%s", dirname, onedirent->d_name);
+          d_namepath = apr_psprintf(r->pool, "%s/%s", dirname, onedirent->d_name);
+
           if (stat(d_namepath, &statbuf) != 0) continue;
 
-          if (S_ISDIR(statbuf.st_mode) && (recurse_level < GRST_RECURS_LIMIT)) 
+          if (S_ISDIR(statbuf.st_mode))
+            {
+              if (recurse_level < GRST_RECURS_LIMIT)
                  recurse4dirlist(d_namepath, dirs_time, fulluri,
                                  fullurilen, encfulluri, enclen, 
-                                 pool, body, recurse_level + 1);
+                                 r, body, recurse_level + 1);
+            }
           else if ((strncmp(onedirent->d_name, encfulluri, enclen) == 0) &&
                    (onedirent->d_name[strlen(onedirent->d_name) - 1] != '~'))
             {
@@ -1205,7 +1237,6 @@ static void recurse4dirlist(char *dirname, time_t *dirs_time,
                     
               if (strncmp(unencname, fulluri, fullurilen) == 0)
                 {
-
                   if (statbuf.st_mtime > *dirs_time) 
                                                 *dirs_time = statbuf.st_mtime;
 
@@ -1216,7 +1247,7 @@ static void recurse4dirlist(char *dirname, time_t *dirs_time,
                   
                   mildencoded = GRSThttpUrlMildencode(&unencname[fullurilen]);
                  
-                  oneline = apr_psprintf(pool,
+                  oneline = apr_psprintf(r->pool,
                                      "<tr><td><a href=\"%s\" "
                                      "content-length=\"%ld\" "
                                      "last-modified=\"%ld\">"
@@ -1224,15 +1255,15 @@ static void recurse4dirlist(char *dirname, time_t *dirs_time,
                                      "<td align=right>%ld</td>%s</tr>\n", 
                                      mildencoded, statbuf.st_size, 
                                      statbuf.st_mtime, 
-                                     html_escape(pool, unencname), 
+                                     html_escape(r->pool, unencname), 
                                      statbuf.st_size, modified);
 
                   free(mildencoded);
 
-                  *body = apr_pstrcat(pool, *body, oneline, NULL);
+                  *body = apr_pstrcat(r->pool, *body, oneline, NULL);
                 }      
                       
-              free(unencname); /* libgridsite doesnt use pools */    
+              free(unencname); /* libgridsite doesnt use pools */
             }
         }
         
@@ -1264,7 +1295,7 @@ static int mod_gridsite_dnlistsuri_dir_handler(request_rec *r,
     if (permstr != NULL) sscanf(permstr, "%d", &perm);
 
     fulluri = apr_psprintf(r->pool, "https://%s%s",
-                                    ap_get_server_name(r), conf->dnlistsuri);
+                                    r->hostname, conf->dnlistsuri);
     fullurilen = strlen(fulluri);
 
     encfulluri = GRSThttpUrlEncode(fulluri);
@@ -1283,26 +1314,34 @@ static int mod_gridsite_dnlistsuri_dir_handler(request_rec *r,
       {
         /* **** try to find a header file in this or parent directories **** */
 
-        /* first make a buffer big enough to hold path names we want to try */
         fd = -1;
-        s = malloc(strlen(r->filename) + strlen(conf->headfile) + 1);
-        strcpy(s, r->filename);
+
+        if (conf->headfile[0] == '/') /* try absolute */
+          {
+            fd = open(conf->headfile, O_RDONLY);
+          }
+        else /* try relative */
+          {
+            /* first make a buffer big enough to hold path names we want to try */
+            s = malloc(strlen(r->filename) + strlen(conf->headfile) + 1);
+            strcpy(s, r->filename);
     
-        for (;;)
-           {
-             p = rindex(s, '/');
-             if (p == NULL) break; /* failed to find one */
-             p[1] = '\0';
-             strcat(p, conf->headfile);
+            for (;;)
+               {
+                 p = rindex(s, '/');
+                 if (p == NULL) break; /* failed to find one */
+                 p[1] = '\0';
+                 strcat(p, conf->headfile);
     
-             fd = open(s, O_RDONLY);
-             if (fd != -1) break; /* found one */
+                 fd = open(s, O_RDONLY);
+                 if (fd != -1) break; /* found one */
 
-             *p = '\0';
-           }
+                 *p = '\0';
+               }
             
-        free(s);
-
+             free(s);
+           }
+           
         if (fd == -1) /* not found, so set up to output sensible default */
           {
             header_formatted = apr_pstrdup(r->pool, "<body bgcolor=white>");
@@ -1328,21 +1367,20 @@ static int mod_gridsite_dnlistsuri_dir_handler(request_rec *r,
 
     while ((dirname = strsep(&dn_list_ptr, ":")) != NULL)
         recurse4dirlist(dirname, &dirs_time, fulluri, fullurilen,
-                                 encfulluri, enclen, r->pool, &body, 0);
+                                 encfulluri, enclen, r, &body, 0);
 
-    if ((stat(r->filename, &statbuf) == 0) &&
-        S_ISDIR(statbuf.st_mode) && 
-        GRSTgaclPermHasWrite(perm))
+    p = (char *) apr_table_get(r->subprocess_env, "HTTPS");
+    if ((p != NULL) && (strcmp(p, "on") == 0))
       {
         oneline = apr_psprintf(r->pool,
            "<form action=\"%s%s\" method=post>\n"
-           "<input type=hidden name=cmd value=managedir>"
+           "<input type=hidden name=cmd value=managednlists>"
            "<tr><td colspan=4 align=center><small><input type=submit "
-           "value=\"Manage directory\"></small></td></tr></form>\n",
+           "value=\"Manage DN lists\"></small></td></tr></form>\n",
            r->uri, conf->adminfile);
           
         body = apr_pstrcat(r->pool, body, oneline, NULL);
-      } 
+      }
 
     body = apr_pstrcat(r->pool, body, "</table>\n", NULL);
 
@@ -1352,26 +1390,34 @@ static int mod_gridsite_dnlistsuri_dir_handler(request_rec *r,
       {
         /* **** try to find a footer file in this or parent directories **** */
 
-        /* first make a buffer big enough to hold path names we want to try */
         fd = -1;
-        s  = malloc(strlen(r->filename) + strlen(conf->footfile));
-        strcpy(s, r->filename);
-    
-        for (;;)
-           {
-             p = rindex(s, '/');
-             if (p == NULL) break; /* failed to find one */
+
+        if (conf->headfile[0] == '/') /* try absolute */
+          {
+            fd = open(conf->headfile, O_RDONLY);
+          }
+        else /* try relative */
+          {
+            /* first make a buffer big enough to hold path names we want to try */
+            s  = malloc(strlen(r->filename) + strlen(conf->footfile));
+            strcpy(s, r->filename);
     
-             p[1] = '\0';
-             strcat(p, conf->footfile);
+            for (;;)
+               {
+                 p = rindex(s, '/');
+                 if (p == NULL) break; /* failed to find one */
+
+                 p[1] = '\0';
+                 strcat(p, conf->footfile);
     
-             fd = open(s, O_RDONLY);
-             if (fd != -1) break; /* found one */
+                 fd = open(s, O_RDONLY);
+                 if (fd != -1) break; /* found one */
 
-             *p = '\0';
-           }
+                 *p = '\0';
+               }
             
-        free(s);
+            free(s);
+          }
 
         if (fd == -1) /* failed to find a footer, so use standard default */
           {
@@ -1475,9 +1521,18 @@ static int mod_gridsite_dnlistsuri_handler(request_rec *r,
         ap_internal_redirect(conf->adminuri, r);
         return OK;
       }
+      
+    if (r->uri[strlen(r->uri) - 1] == '/') 
+      {
+        apr_table_setn(r->headers_out, apr_pstrdup(r->pool, "Location"), 
+                                       apr_pstrdup(r->pool, conf->dnlistsuri));
+
+        r->status = HTTP_MOVED_TEMPORARILY;
+        return OK;                   
+      }
 
     fulluri = apr_psprintf(r->pool, "https://%s%s", 
-                                    ap_get_server_name(r), r->uri);
+                                    r->hostname, r->uri);
 
     encfulluri = GRSThttpUrlEncode(fulluri);
     
@@ -1563,6 +1618,8 @@ static void *create_gridsite_dir_config(apr_pool_t *p, char *path)
     if (path == NULL) /* set up document root defaults */
       {
         conf->auth          = 0;     /* GridSiteAuth          on/off       */
+        conf->autopasscode  = 1;     /* GridSiteAutoPasscode  on/off       */
+        conf->zoneslashes   = 1;     /* GridSiteZoneSlashes   number       */
         conf->envs          = 1;     /* GridSiteEnvs          on/off       */
         conf->format        = 0;     /* GridSiteHtmlFormat    on/off       */
         conf->indexes       = 0;     /* GridSiteIndexes       on/off       */
@@ -1607,6 +1664,8 @@ static void *create_gridsite_dir_config(apr_pool_t *p, char *path)
     else
       {
         conf->auth          = UNSET; /* GridSiteAuth          on/off       */
+        conf->autopasscode  = UNSET; /* GridSiteAutoPasscode  on/off       */
+        conf->zoneslashes   = UNSET; /* GridSiteZoneSlashes   number       */
         conf->envs          = UNSET; /* GridSiteEnvs          on/off       */
         conf->format        = UNSET; /* GridSiteHtmlFormat    on/off       */
         conf->indexes       = UNSET; /* GridSiteIndexes       on/off       */
@@ -1651,6 +1710,12 @@ static void *merge_gridsite_dir_config(apr_pool_t *p, void *vserver,
     if (direct->auth != UNSET) conf->auth = direct->auth;
     else                       conf->auth = server->auth;
 
+    if (direct->autopasscode != UNSET) conf->autopasscode = direct->autopasscode;
+    else                               conf->autopasscode = server->autopasscode;
+
+    if (direct->zoneslashes != UNSET) conf->zoneslashes = direct->zoneslashes;
+    else                              conf->zoneslashes = server->zoneslashes;
+
     if (direct->envs != UNSET) conf->envs = direct->envs;
     else                       conf->envs = server->envs;
         
@@ -1754,6 +1819,13 @@ static const char *mod_gridsite_take1_cmds(cmd_parms *a, void *cfg,
     
       sessionsdir = apr_pstrdup(a->pool, parm);
     }
+    else if (strcasecmp(a->cmd->name, "GridSiteZoneSlashes") == 0)
+    {
+      ((mod_gridsite_dir_cfg *) cfg)->zoneslashes = atoi(parm);
+      
+      if (((mod_gridsite_dir_cfg *) cfg)->zoneslashes < 1)
+       return "GridSiteZoneSlashes must be greater than 0";
+    }
     else if (strcasecmp(a->cmd->name, "GridSiteGridHTTPport") == 0)
     {
       gridhttpport = atoi(parm);
@@ -2038,6 +2110,10 @@ static const char *mod_gridsite_flag_cmds(cmd_parms *a, void *cfg,
     {
       ((mod_gridsite_dir_cfg *) cfg)->auth = flag;
     }
+    else if (strcasecmp(a->cmd->name, "GridSiteAutoPasscode") == 0)
+    {
+      ((mod_gridsite_dir_cfg *) cfg)->autopasscode = flag;
+    }
     else if (strcasecmp(a->cmd->name, "GridSiteEnvs") == 0)
     {
       ((mod_gridsite_dir_cfg *) cfg)->envs = flag;
@@ -2070,6 +2146,8 @@ static const command_rec mod_gridsite_cmds[] =
 
     AP_INIT_FLAG("GridSiteAuth", mod_gridsite_flag_cmds, 
                  NULL, OR_FILEINFO, "on or off"),
+    AP_INIT_FLAG("GridSiteAutoPasscode", mod_gridsite_flag_cmds,
+                 NULL, OR_FILEINFO, "on or off"),
     AP_INIT_FLAG("GridSiteEnvs", mod_gridsite_flag_cmds, 
                  NULL, OR_FILEINFO, "on or off"),
     AP_INIT_FLAG("GridSiteHtmlFormat", mod_gridsite_flag_cmds, 
@@ -2118,6 +2196,8 @@ static const command_rec mod_gridsite_cmds[] =
 /* GridSiteOnetimesDir is deprecated in favour of GridSiteSessionsDir */
     AP_INIT_TAKE1("GridSiteOnetimesDir", mod_gridsite_take1_cmds,
                  NULL, RSRC_CONF, "directory with GridHTTP passcodes"),
+    AP_INIT_TAKE1("GridSiteZoneSlashes", mod_gridsite_take1_cmds,
+                 NULL, OR_FILEINFO, "number of slashes in passcode cookie paths"),
 
     AP_INIT_TAKE1("GridSiteCastDNlists", mod_gridsite_take1_cmds,
                  NULL, RSRC_CONF, "DN Lists directories search path for SiteCast"),
@@ -2211,7 +2291,7 @@ int GRST_get_session_id(SSL *ssl, char *session_id, size_t len)
 
 int GRST_load_ssl_creds(SSL *ssl, conn_rec *conn)
 {
-   char session_id[(SSL_MAX_SSL_SESSION_ID_LENGTH+1)*2], *sessionfile = NULL,
+   char session_id[(SSL_MAX_SSL_SESSION_ID_LENGTH+1)*2+1], *sessionfile = NULL,
         line[512], *p;
    apr_file_t  *fp = NULL;
    int i;
@@ -2285,7 +2365,7 @@ void GRST_save_ssl_creds(conn_rec *conn, GRSTx509Chain *grst_chain)
    if ((grst_chain != NULL) && (conn->notes != NULL) &&
        (apr_table_get(conn->notes, "GRST_save_ssl_creds") != NULL)) return;
 
-   /* we at least need to say we've been run */
+   /* we at least need to say we've been run - even if creds not save-able*/
 
    apr_table_set(conn->notes, "GRST_save_ssl_creds", "yes");
    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, conn->base_server,
@@ -2519,16 +2599,17 @@ static int mod_gridsite_perm_handler(request_rec *r)
     We also publish environment variables here if requested by GridSiteEnv.
 */
 {
-    int          retcode = DECLINED, i, n, file_is_acl = 0, cc_delegation,
-                 destination_is_acl = 0, ishttps = 0, nist_loa, delegation;
-    char        *dn, *p, envname1[30], envname2[30], 
-                *grst_cred_auri_0 = NULL, *dir_path, 
+    int          retcode = DECLINED, i, j, n, file_is_acl = 0, cc_delegation,
+                 destination_is_acl = 0, ishttps = 0, nist_loa, delegation,
+                 from_cookie = 0;
+    char        *dn, *p, *q, envname1[30], envname2[30], 
+                *grst_cred_auri_0 = NULL, *dir_path,
                 *remotehost, s[99], *grst_cred_auri_i, *cookies, *file, *https,
-                *gridauthpasscode = NULL, *cookiefile, oneline[1025], *key_i,
+                *cookiefile, oneline[1025], *key_i,
                 *destination = NULL, *destination_uri = NULL, *querytmp, 
                 *destination_prefix = NULL, *destination_translated = NULL,
-                *aclpath = NULL, *grst_cred_valid_0 = NULL, *grst_cred_valid_i;
-    char        *vomsAttribute = NULL, *loa;
+                *aclpath = NULL, *grst_cred_valid_0 = NULL, *grst_cred_valid_i,
+                *gridauthpasscode = NULL;
     const char  *content_type;
     time_t       now, notbefore, notafter;
     apr_table_t *env;
@@ -2549,83 +2630,212 @@ static int mod_gridsite_perm_handler(request_rec *r)
 
     if (cfg == NULL) return DECLINED;
 
-    if ((cfg->auth == 0) &&
-        (cfg->envs == 0))
+    if ((cfg->auth == 0) && (cfg->envs == 0))
                return DECLINED; /* if not turned on, look invisible */
 
     env = r->subprocess_env;
-    
-    /* Get the user's attributes from Shibboleth and set up user credential
-       based on the attributes if authentication has been carried out using
-       a Shibboleth Identity Provider.*/
 
-    /* Get DN from a Shibboleth attribute */
+    p = (char *) apr_table_get(env, "HTTPS");
+    if ((p != NULL) && (strcmp(p, "on") == 0)) ishttps = 1;
 
-    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
+    delegation = ((mod_gridsite_dir_cfg *) cfg)->gsiproxylimit + 1;
 
-    if ((dn != NULL) && (*dn == '\0')) dn = NULL;
-    
-    if (dn != NULL) ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "DN: %s", dn);
+    /* reload per-connection (SSL) cred variables? (TO CONNECTION) */
 
-    /* Get the NIST LoA attribute */
-    loa = (char *) apr_table_get(r->headers_in, "nist-loa");
+    sslconn = (SSLConnRec *) ap_get_module_config(r->connection->conn_config, 
+                                                  &ssl_module);
+    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)
+            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+                         "Restored SSL session data from session cache file");
+      }
 
-    if ((loa == NULL) || (*loa == '\0'))
-     loa = (char *) apr_table_get(r->headers_in, "loa");
-    
-    if ((loa != NULL) && (*loa == '\0')) loa = NULL;
+    /* look for GRIDHTTP_PASSCODE in QUERY_STRING ie after ? */
+      
+    if ((r->parsed_uri.query != NULL) && (r->parsed_uri.query[0] != '\0'))
+      {
+        querytmp = apr_pstrcat(r->pool,"&",r->parsed_uri.query,"&",NULL);
+            
+        gridauthpasscode = strstr(querytmp, "&GRIDHTTP_PASSCODE=");
+        if (gridauthpasscode != NULL)
+          {
+            gridauthpasscode = &gridauthpasscode[19];
 
-    if (loa != NULL) ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "nist-loa: %s", loa);
+            for (p = gridauthpasscode; (*p != '\0') && (*p != '&'); ++p)
+                                                if (!isalnum(*p)) *p = '\0';
+          }
+      }
 
-    /* Set up user credential based on the DN and LoA attributes */
-                                  
-    if (dn != NULL)
+    /* then look for GRIDHTTP_PASSCODE cookie */
+      
+    if ((gridauthpasscode == NULL) &&
+        ((q = (char *) apr_table_get(r->headers_in, "Cookie")) != NULL))
       {
-        cred = GRSTgaclCredCreate("dn:", dn);
+        cookies = apr_pstrcat(r->pool, " ", q, NULL);
+        gridauthpasscode = strstr(cookies, " GRIDHTTP_PASSCODE=");
 
-        if (loa != NULL) GRSTgaclCredSetNistLoa(cred, atoi(loa));
-        else GRSTgaclCredSetNistLoa(cred, 2);
+        if (gridauthpasscode != NULL)
+          {
+            gridauthpasscode = &gridauthpasscode[19];
+          
+            for (p = gridauthpasscode; 
+                 (*p != '\0') && (*p != ';'); ++p)
+                                      if (!isalnum(*p)) *p = '\0';
 
-        user = GRSTgaclUserNew(cred);
+            if (gridauthpasscode[0] != '\0') from_cookie = 1;
+          }
       }
-            
-    /* Set up user credential based on VOMS Attribute from Shibboleth? */
 
-    vomsAttribute = (char *) apr_table_get(r->headers_in, "VOMS-Attribute");
-    if (vomsAttribute != NULL)
+    /* try to load user structure from passcode file */
+
+    if ((user == NULL) && 
+        (gridauthpasscode != NULL) &&
+        (gridauthpasscode[0] != '\0'))
       {
-        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, 
-                 "VOMS-Attribute: %s", vomsAttribute);
+        cookiefile = apr_psprintf(r->pool, "%s/passcode-%s",
+                 ap_server_root_relative(r->pool,
+                 sessionsdir),
+                 gridauthpasscode);
+                                      
+        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+                             "Opening GridHTTP passcode file %s", cookiefile);
+              
+        if ((apr_stat(&cookiefile_info, cookiefile, 
+                          APR_FINFO_TYPE, r->pool) == APR_SUCCESS) &&
+            (cookiefile_info.filetype == APR_REG) &&
+            (apr_file_open(&fp, cookiefile, APR_READ, 0, r->pool)
+                                                         == APR_SUCCESS))
+              {
+                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+                             "Reading GridHTTP passcode file %s", cookiefile);
+               
+                i = -1;
+                cred = NULL;
+              
+                while (apr_file_gets(oneline, 
+                                     sizeof(oneline), fp) == APR_SUCCESS)
+                     {
+                       p = index(oneline, '\n');
+                       if (p != NULL) *p = '\0';
+                       
+                       ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
+                                    "%s: %s", cookiefile, oneline);
 
-        cred = GRSTgaclCredCreate("fqan:", vomsAttribute);
-        if (user == NULL) user = GRSTgaclUserNew(cred);
-        else GRSTgaclUserAddCred(user, cred);
-      }
+                       if ((strncmp(oneline, "expires=", 8) == 0) &&
+                           (apr_time_from_sec(atoll(&oneline[8])) < 
+                                                       apr_time_now()))
+                         {
+                           if (user != NULL) 
+                             {
+                               ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, 
+                                            r->server, "Bad expires");
+                               GRSTgaclUserFree(user);
+                               user = NULL;
+                             }
+                           break;
+                         }
+                       else if ((strncmp(oneline, "domain=", 7) == 0) &&
+                                (strcmp(&oneline[7], r->hostname) != 0))
+                         {
+                           if (user != NULL) 
+                             {
+                               ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, 
+                                            r->server, "Bad domain/host");
+                               GRSTgaclUserFree(user);
+                               user = NULL;
+                             }
+                           break;
+                         }
+                       else if (strncmp(oneline, "path=", 5) == 0)
+                         {
+                           /* count number of slashes in Request URI */
+                           
+                           for (n=0,p=r->uri; *p != '\0'; ++p)
+                                                     if (*p == '/') ++n;
+
+                           /* if too few slashes or path mismatch, then stop */
+                              
+                           if ((n < ((mod_gridsite_dir_cfg *) cfg)->zoneslashes) ||
+                               (strncmp(&oneline[5], r->uri, strlen(&oneline[5])) != 0))
+                             {
+                               if (user != NULL)
+                                 {
+                                   ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, 
+                                            r->server, "Bad path");
+                                   GRSTgaclUserFree(user);
+                                   user = NULL;
+                                 }
+
+                               break;
+                             }
+                         }
+                       else if ((sscanf(oneline,"GRST_CRED_AURI_%d=",&j) == 1)
+                                && (j == i+1)
+                                && ((p = index(oneline, '=')) != NULL))
+                         {
+                           cred = GRSTgaclCredCreate(&p[1], NULL);
+                           
+                           if (cred != NULL) ++i;
+                           
+                           if (user == NULL) user = GRSTgaclUserNew(cred);
+                           else GRSTgaclUserAddCred(user, cred);                           
+                         }
+                       else if ((sscanf(oneline,"GRST_CRED_VALID_%d=",&j) == 1)
+                                && (j == i)
+                                && ((p = index(oneline, '=')) != NULL)
+                                && (sscanf(&p[1], 
+                       "notbefore=%ld notafter=%ld delegation=%d nist-loa=%d", 
+                                  &notbefore, &notafter, &delegation, 
+                                  &nist_loa) == 4))
+                         {
+                           if ((i == 0) && 
+             (delegation > ((mod_gridsite_dir_cfg *) cfg)->gsiproxylimit))
+                             {
+                               ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, 
+                                            r->server, "Bad delegation");
+                               if (user != NULL) GRSTgaclUserFree(user);
+                               user = NULL;
+                               break;
+                             }
+                         
+                           GRSTgaclCredSetNotBefore( cred, notbefore);
+                           GRSTgaclCredSetNotAfter(  cred, notafter);
+                           GRSTgaclCredSetDelegation(cred, delegation);
+                           if (delegation == 0) GRSTgaclCredSetNistLoa(cred, 3);
+                           else                 GRSTgaclCredSetNistLoa(cred, 2);
+                         }
+                     }
 
-    p = (char *) apr_table_get(r->subprocess_env, "HTTPS");
-    if ((p != NULL) && (strcmp(p, "on") == 0)) ishttps = 1;
+                apr_file_close(fp);
 
-    /* reload per-connection (SSL) cred variables? */
+                /* delete passcode file if used over HTTP not HTTPS */
+                if (!ishttps) remove(cookiefile);
 
-    sslconn = (SSLConnRec *) ap_get_module_config(r->connection->conn_config, 
-                                                  &ssl_module);
-    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)
-            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
-                         "Restored SSL session data from session cache file");
+                /* if successful and we got passcode from a cookie, then
+                   we put cookie value into environment variables, so
+                   can be used for double-submit cookie CSRF protection */
+
+                if ((user != NULL) && 
+                    from_cookie && 
+                    ((mod_gridsite_dir_cfg *) cfg)->envs)
+                        apr_table_setn(env, "GRST_PASSCODE_COOKIE",
+                                            gridauthpasscode);
+              }
       }
 
-    delegation = ((mod_gridsite_dir_cfg *) cfg)->gsiproxylimit + 1;
+    /* 
+        if not succeeded from passcode file, try from connection notes
+        if a GSI Proxy or have  GridSiteAutoPasscode on  (the default)
+        (if  GridSiteAutoPasscode off  then interactive websites must use
+        a login script to make passcode and file instead.)
+    */
     
     if ((user == NULL) && 
         (r->connection->notes != NULL) &&
@@ -2637,7 +2847,8 @@ static int mod_gridsite_perm_handler(request_rec *r)
         (sscanf(grst_cred_valid_0, 
                 "notbefore=%ld notafter=%ld delegation=%d nist-loa=%d", 
                 &notbefore, &notafter, &delegation, &nist_loa) == 4) &&
-        (delegation <= ((mod_gridsite_dir_cfg *) cfg)->gsiproxylimit))
+        (delegation <= ((mod_gridsite_dir_cfg *) cfg)->gsiproxylimit) &&
+        ((delegation > 0) || ((mod_gridsite_dir_cfg *) cfg)->autopasscode))
       {
         cred_0 = GRSTgaclCredCreate(grst_cred_auri_0, NULL);
         if (cred_0 != NULL)
@@ -2689,12 +2900,64 @@ static int mod_gridsite_perm_handler(request_rec *r)
                  else break; /* GRST_CRED_AURI_i are numbered consecutively */
                }
           }
+
+         /* if passcode absent but SSL ok and not a GSI Proxy, we must 
+            have  GridSiteAutoPasscode on  so we create passcode and file
+            automatically, and return cookie to client. 
+            (if  GridSiteAutoPasscode off  then the site must use
+            a login script to make passcode and file instead.) */
+
+         if ((user != NULL) &&
+             (GRSTgaclCredGetDelegation(cred_0) == 0))
+           {
+             n = 0; /* number of slashes seen */
+
+             for (i=0; r->uri[i] != '\0'; ++i)
+                {
+                  if (n >= ((mod_gridsite_dir_cfg *) cfg)->zoneslashes) break;
+
+                  if (r->uri[i] == '/') ++n;
+                }
+             if ((n >= ((mod_gridsite_dir_cfg *) cfg)->zoneslashes)
+                 && (i > 0))
+               {
+                 p = apr_pstrdup(r->pool, r->uri);
+                 p[i] = '\0';
+               
+                 /* try to generate passcode and make passcode file */
+                 gridauthpasscode = make_passcode_file(r, cfg, p, 0);
+
+                 if (gridauthpasscode != NULL)
+                   {
+                     apr_table_add(r->headers_out,
+                        apr_pstrdup(r->pool, "Set-Cookie"),
+                        apr_psprintf(r->pool,
+                        "GRIDHTTP_PASSCODE=%s; "
+                        "domain=%s; "
+                        "path=%s; "
+                        "secure; httponly", gridauthpasscode, r->hostname, p));
+                   }
+               }
+           }
       }
 
+    /* 
+       GridSite passcode files don't include groups, IP or DNS so we add
+       them last so they're not written to passcode files by GridSite.
+
+       (site-supplied login scripts might create passcode files with 
+       optional or additional AURIs. for example, valid roles selected by
+       the user on the login page.)
+       
+    */
+      
+    /* first add groups from DN lists - ie non-optional attributes */
+
     if ((user != NULL) && ((mod_gridsite_dir_cfg *) cfg)->dnlists)
           GRSTgaclUserLoadDNlists(user, ((mod_gridsite_dir_cfg *) cfg)->dnlists);
 
-    /* add DNS credential */
+    /* then add DNS credential */
     
     remotehost = (char *) ap_get_remote_host(r->connection,
                                   r->per_dir_config, REMOTE_DOUBLE_REV, NULL);
@@ -2707,7 +2970,7 @@ static int mod_gridsite_perm_handler(request_rec *r)
         else              GRSTgaclUserAddCred(user, cred);
       }
 
-    /* add IP credential */
+    /* finally add IP credential */
     
     remotehost = (char *) ap_get_remote_host(r->connection,
                                   r->per_dir_config, REMOTE_DOUBLE_REV, NULL);
@@ -2858,7 +3121,14 @@ static int mod_gridsite_perm_handler(request_rec *r)
                         "Failed to make ACL file from ACL path %s, URI %s)",
                         ((mod_gridsite_dir_cfg *) cfg)->aclpath, r->uri);
           }
-        else acl = GRSTgaclAclLoadforFile(r->filename);
+        else if ((((mod_gridsite_dir_cfg *) cfg)->dnlistsuri == NULL) ||
+                 (strncmp(r->uri,
+                          ((mod_gridsite_dir_cfg *) cfg)->dnlistsuri,
+                          strlen(((mod_gridsite_dir_cfg *) cfg)->dnlistsuri)) != 0) ||
+                 (strlen(r->uri) <= strlen(((mod_gridsite_dir_cfg *) cfg)->dnlistsuri)))
+          {
+            acl = GRSTgaclAclLoadforFile(r->filename);
+          }
 
         if (acl != NULL) perm = GRSTgaclAclTestUser(acl, user);
         GRSTgaclAclFree(acl);
@@ -2877,95 +3147,6 @@ static int mod_gridsite_perm_handler(request_rec *r)
                               apr_psprintf(r->pool, "%d", destination_perm));
           }
       }
-      
-    /* first look for GRIDHTTP_PASSCODE cookie */
-      
-    if ((p = (char *) apr_table_get(r->headers_in, "Cookie")) != NULL)
-      {
-        cookies = apr_pstrcat(r->pool, " ", p, NULL);
-        gridauthpasscode = strstr(cookies, " GRIDHTTP_PASSCODE=");
-                
-        if (gridauthpasscode != NULL)
-          {
-            gridauthpasscode = &gridauthpasscode[19];
-          
-            for (p = gridauthpasscode; 
-                 (*p != '\0') && (*p != ';'); ++p)
-                                      if (!isalnum(*p)) *p = '\0';
-          }
-      }
-
-    /* then look for GRIDHTTP_PASSCODE in QUERY_STRING ie after ? */
-      
-    if (gridauthpasscode == NULL)
-      {
-        if ((r->parsed_uri.query != NULL) && (r->parsed_uri.query[0] != '\0'))
-          {
-            querytmp = apr_pstrcat(r->pool,"&",r->parsed_uri.query,"&",NULL);
-            
-            gridauthpasscode = strstr(querytmp, "&GRIDHTTP_PASSCODE=");
-            
-            if (gridauthpasscode != NULL)                         
-              {
-                gridauthpasscode = &gridauthpasscode[19];
-              
-                for (p = gridauthpasscode; 
-                     (*p != '\0') && (*p != '&'); ++p)
-                                          if (!isalnum(*p)) *p = '\0';
-              }            
-          }
-      }
-
-    if ((gridauthpasscode != NULL) && (gridauthpasscode[0] != '\0')) 
-      {
-        cookiefile = apr_psprintf(r->pool, "%s/passcode-%s",
-                 ap_server_root_relative(r->pool,
-                 sessionsdir),
-                 gridauthpasscode);
-                                      
-        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
-                             "Opening GridHTTP passcode file %s", cookiefile);
-              
-        if ((apr_stat(&cookiefile_info, cookiefile, 
-                          APR_FINFO_TYPE, r->pool) == APR_SUCCESS) &&
-            (cookiefile_info.filetype == APR_REG) &&
-            (apr_file_open(&fp, cookiefile, APR_READ, 0, r->pool)
-                                                         == APR_SUCCESS))
-              {
-                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
-                             "Reading GridHTTP passcode file %s", cookiefile);
-              
-                while (apr_file_gets(oneline, 
-                                     sizeof(oneline), fp) == APR_SUCCESS)
-                     {
-                       p = index(oneline, '\n');
-                       if (p != NULL) *p = '\0';
-                       
-                       ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
-                                    "%s: %s", cookiefile, oneline);
-
-                       if ((strncmp(oneline, "expires=", 8) == 0) &&
-                           (apr_time_from_sec(atoll(&oneline[8])) < 
-                                                       apr_time_now()))
-                                  break;                
-                       else if ((strncmp(oneline, "domain=", 7) == 0) &&
-                                (strcmp(&oneline[7], r->hostname) != 0))
-                                  break; /* exact needed in the version */
-                       else if ((strncmp(oneline, "path=", 5) == 0) &&
-                                (strcmp(&oneline[5], r->uri) != 0))
-                                  break;
-                       else if  ((strncmp(oneline, "onetime=yes", 11) == 0)
-                                 && !ishttps)
-                                  apr_file_remove(cookiefile, r->pool);
-                       else if  (strncmp(oneline, "method=PUT", 10) == 0)
-                                  perm |= GRST_PERM_WRITE;
-                       else if  (strncmp(oneline, "method=GET", 10) == 0)
-                                  perm |= GRST_PERM_READ;
-                     }
-
-                apr_file_close(fp);
-              }
-      }
     
     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                  "After GACL/Onetime evaluation, GRST_PERM=%d", perm);
@@ -2976,6 +3157,29 @@ static int mod_gridsite_perm_handler(request_rec *r)
 
     if (((mod_gridsite_dir_cfg *) cfg)->envs)
       {
+        /* copy any credentials from (SSL) connection to environment */
+        
+        for (i=0; ; ++i) 
+           {
+             snprintf(envname1, sizeof(envname1), "GRST_CRED_AURI_%d",  i);
+             snprintf(envname2, sizeof(envname2), "GRST_CRED_VALID_%d", i);
+
+             if ((grst_cred_auri_i = (char *) 
+                         apr_table_get(r->connection->notes,envname1)) &&
+                 (grst_cred_valid_i = (char *) 
+                         apr_table_get(r->connection->notes,envname2)))
+               { 
+                 apr_table_setn(env,
+                                apr_psprintf(r->pool, "GRST_CONN_AURI_%d", i),
+                                apr_pstrdup(r->pool, grst_cred_auri_i));
+
+                 apr_table_setn(env,
+                                apr_psprintf(r->pool, "GRST_CONN_VALID_%d", i),
+                                apr_pstrdup(r->pool, grst_cred_valid_i));
+               }
+             else break;
+           }
+
         apr_table_setn(env, "GRST_PERM", apr_psprintf(r->pool, "%d", perm));
 
         if (((dir_path = apr_pstrdup(r->pool, r->filename)) != NULL) &&
@@ -3781,14 +3985,24 @@ static int mod_gridsite_handler(request_rec *r)
    conf = (mod_gridsite_dir_cfg *)
                     ap_get_module_config(r->per_dir_config, &gridsite_module);
 
-   if ((conf->dnlistsuri != NULL) &&
-       (strncmp(r->uri, conf->dnlistsuri, strlen(conf->dnlistsuri)) == 0))
+   if (conf->dnlistsuri != NULL)
      {
        if (strcmp(r->uri, conf->dnlistsuri) == 0)
               return mod_gridsite_dnlistsuri_dir_handler(r, conf);
 
-       return mod_gridsite_dnlistsuri_handler(r, conf);
-    }
+       if (strncmp(r->uri, conf->dnlistsuri, strlen(conf->dnlistsuri)) == 0)
+              return mod_gridsite_dnlistsuri_handler(r, conf);
+
+       if ((strncmp(r->uri, conf->dnlistsuri, strlen(r->uri)) == 0)
+           && (strlen(r->uri) == strlen(conf->dnlistsuri) - 1))
+         {
+           apr_table_setn(r->headers_out, apr_pstrdup(r->pool, "Location"), 
+                          apr_pstrcat(r->pool, r->uri, "/", NULL));
+
+           r->status = HTTP_MOVED_TEMPORARILY;  
+           return OK;           
+         }      
+     }
 
    if (strcmp(r->handler, DIR_MAGIC_TYPE) == 0)
                    return mod_gridsite_dir_handler(r, conf);