of the user's process, or a file of the form /tmp/x509up_uUID, where UID is
 their Unix user ID. If none is found, an authenticated HTTPS request is made.
 
+SlashGrid searches /etc/grid-security/certificates by default for CA root
+files when verifying the host certificate of remote servers. This can be
+overriden by users setting the variable X509_CERT_DIR in their environment.
+
 .SH "SITECAST DOMAINS"
 
 If the slashgrid daemon is started with the option --domain, then URLs 
 The SiteCast area of the virtual filesystem is read-only (to prevent
 corruption of replicas.)
 
+.TP
+--domain DOMAIN
+SiteCast domain to use.
+ 
+.TP
+--groups GROUPS
+SiteCast multicast groups to query.
+ 
 .SH "LOCAL FILESYSTEM"
 
 This filesystem is intended for use with GridSite/Apache webservers, which
 can interpret these files internally, and this allows other services, such
 as GridFTP running in chroot mode, to share access to a common file store.
 
-.SH "OPTIONS"
+.TP
+--local-root PATH
+Top level directory in the underlying filesystem, which will be mapped to
+/grid/local/
+ 
+.TP
+--local-user USER
+Local user who will own the files created in the underlying filesystem.
+ 
+.TP
+--gridmapdir PATH
+Private gridmapdir used for mapping of pool users back to X.509 DNs. For
+example, after configuring GridFTP to use this gridmapdir.
+ 
+.SH "OTHER OPTIONS"
  
 .TP
 --debug
 
 #define GRST_LOG_INFO    6
 #define GRST_LOG_DEBUG   7
 
+#define GRST_MAX_TIME_T         INT32_MAX
+
 typedef struct { char                      *auri;
                  int                       delegation;
                  int                       nist_loa;
 
 export prefix=/usr/local
 endif
 
+ifndef libdir
+export libdir=lib
+endif
+
 ifndef MYCFLAGS
 export MYCFLAGS=-I. -I../interface $(HTTPD_FLAGS) -I/usr/include/httpd -I/usr/include/apr-0 -I/opt/glite/include -fPIC
 endif
 
 install: apidoc install-lib
        mkdir -p $(prefix)/include \
-                 $(prefix)/lib \
+                 $(prefix)/$(libdir) \
                  $(prefix)/bin \
                  $(prefix)/sbin \
                  $(prefix)/share/man/man1 \
        cp -f mod_gridsite.so $(prefix)/lib/httpd/modules
 
 install-lib:
-       mkdir -p $(prefix)/lib
-       cp -f  libgridsite.a $(prefix)/lib
-       cp -f  libgridsite.so.$(PATCH_VERSION) $(prefix)/lib
+       mkdir -p $(prefix)/$(libdir)
+       cp -f  libgridsite.a $(prefix)/$(libdir)
+       cp -f  libgridsite.so.$(PATCH_VERSION) $(prefix)/$(libdir)
        ln -sf libgridsite.so.$(PATCH_VERSION) \
-                                 $(prefix)/lib/libgridsite.so
+                                 $(prefix)/$(libdir)/libgridsite.so
        ln -sf libgridsite.so.$(PATCH_VERSION) \
-                                 $(prefix)/lib/libgridsite.so.$(MAJOR_VERSION)
+                                 $(prefix)/$(libdir)/libgridsite.so.$(MAJOR_VERSION)
        ln -sf libgridsite.so.$(PATCH_VERSION) \
-                                 $(prefix)/lib/libgridsite.so.$(MINOR_VERSION)
-       cp -f  libgridsite_globus.a $(prefix)/lib
-       cp -f  libgridsite_globus.so.$(PATCH_VERSION) $(prefix)/lib
+                                 $(prefix)/$(libdir)/libgridsite.so.$(MINOR_VERSION)
+       cp -f  libgridsite_globus.a $(prefix)/$(libdir)
+       cp -f  libgridsite_globus.so.$(PATCH_VERSION) $(prefix)/$(libdir)
        ln -sf libgridsite_globus.so.$(PATCH_VERSION) \
-                                 $(prefix)/lib/libgridsite_globus.so
+                                 $(prefix)/$(libdir)/libgridsite_globus.so
        ln -sf libgridsite_globus.so.$(PATCH_VERSION) \
-                                 $(prefix)/lib/libgridsite_globus.so.$(MAJOR_VERSION)
+                                 $(prefix)/$(libdir)/libgridsite_globus.so.$(MAJOR_VERSION)
        ln -sf libgridsite_globus.so.$(PATCH_VERSION) \
-                                 $(prefix)/lib/libgridsite_globus.so.$(MINOR_VERSION)
+                                 $(prefix)/$(libdir)/libgridsite_globus.so.$(MINOR_VERSION)
 
 install-slashgrid: slashgrid
        cp -f slashgrid $(prefix)/sbin
 
 install-ws: gridsite-delegation.cgi htproxyput
        mkdir -p $(prefix)/include \
-                 $(prefix)/lib \
                  $(prefix)/bin \
                  $(prefix)/sbin \
                  $(prefix)/share/man/man1 \
 
 
   if ((cred == NULL) || (cred->auri == NULL)) return 0;
 
-  if (strcmp(cred->auri, "any-user:") == 0) return 1;
+  if (strcmp(cred->auri, "gacl:any-user") == 0) return 1;
   
   if ((user == NULL) || (user->firstcred == NULL)) return 0;
   
      
        for (cred = entry->firstcred; cred != NULL; cred = cred->next)
              if (!GRSTgaclUserHasCred(user, cred)) flag = 0;
-             else if (strcmp(cred->auri, "any-user:") != 0) onlyanyuser = 0;
+             else if (strcmp(cred->auri, "gacl:any-user") != 0) onlyanyuser = 0;
 
        if (!flag) continue; /* flag false if a subtest failed */
 
 
 
 %install
 cd src
-make install prefix=\$RPM_BUILD_ROOT/%{prefix} \
+make install prefix=\$RPM_BUILD_ROOT/%{prefix} libdir=%{_lib} \
 GSOAPDIR=\$GSOAPDIR OPENSSL_FLAGS=\$OPENSSL_FLAGS \
 OPENSSL_LIBS=\$OPENSSL_LIBS FLAVOR_EXT=\$FLAVOR_EXT
 EOF
 fi
 
 %files shared
-%attr(-, root, root) %{prefix}/lib/libgridsite.so.%{version}
-%attr(-, root, root) %{prefix}/lib/libgridsite.so
-%attr(-, root, root) %{prefix}/lib/libgridsite_globus.so.%{version}
-%attr(-, root, root) %{prefix}/lib/libgridsite_globus.so
+%attr(-, root, root) %{prefix}/%{_lib}/libgridsite.so.%{version}
+%attr(-, root, root) %{prefix}/%{_lib}/libgridsite.so
+%attr(-, root, root) %{prefix}/%{_lib}/libgridsite_globus.so.%{version}
+%attr(-, root, root) %{prefix}/%{_lib}/libgridsite_globus.so
 %attr(-, root, root) %{prefix}/share/doc/gridsite-${MINOR_VERSION:-1.x}
 
 %files devel
 
                    apr_psprintf(conn->pool, 
                       "notbefore=%ld notafter=%ld delegation=%d nist-loa=%d", 
                       grst_cert->notbefore,
-                      grst_cert->notafter, 0, 0));
+                      grst_cert->notafter, 
+                      grst_cert->delegation, 0));
 
             if (fp != NULL) apr_file_printf(fp, 
   "GRST_CRED_VALID_%d=notbefore=%ld notafter=%ld delegation=%d nist-loa=%d\n",
                                             i, grst_cert->notbefore,
-                                               grst_cert->notafter, 0, 0);
+                                               grst_cert->notafter,
+                                               grst_cert->delegation, 0);
 
             ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, conn->base_server,
                       "store GRST_CRED_AURI_%d=fqan:%s", i, grst_cert->value);
                    apr_psprintf(conn->pool, 
                       "notbefore=%ld notafter=%ld delegation=%d nist-loa=%d", 
                       grst_cert->notbefore,
-                      grst_cert->notafter, 0, 0));
+                      grst_cert->notafter,
+                      grst_cert->delegation, 0));
 
             if (fp != NULL) apr_file_printf(fp, 
   "GRST_CRED_VALID_%d=notbefore=%ld notafter=%ld delegation=%d nist-loa=%d\n",
                                             i, grst_cert->notbefore,
-                                               grst_cert->notafter, 0, 0);
+                                               grst_cert->notafter, 
+                                               grst_cert->delegation, 0);
 
             ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, conn->base_server,
                       "store GRST_CRED_AURI_%d=dn:%s", i, grst_cert->dn);
     if ((remotehost != NULL) && (*remotehost != '\0'))
       {
         cred = GRSTgaclCredCreate("dns:", remotehost);
+        GRSTgaclCredSetNotAfter(cred, GRST_MAX_TIME_T);
 
         if (user == NULL) user = GRSTgaclUserNew(cred);
         else              GRSTgaclUserAddCred(user, cred);
     if ((remotehost != NULL) && (*remotehost != '\0'))
       {
         cred = GRSTgaclCredCreate("ip:", r->connection->remote_ip);
+        GRSTgaclCredSetNotAfter(cred, GRST_MAX_TIME_T);
 
         if (user == NULL) user = GRSTgaclUserNew(cred);
         else              GRSTgaclUserAddCred(user, cred);
                                   apr_psprintf(r->pool, "GRST_CRED_%d", i),
                                   apr_psprintf(r->pool, 
                                                "%s %ld %ld %d %s",
-                                               (i=0) ? "X509USER" : "GSIPROXY",
+                                               (i==0) ? "X509USER" : "GSIPROXY",
                                                cred->notbefore,
                                                cred->notafter,
                                                cc_delegation, 
 
                      CURL              *curl_handle;
                      uid_t             uid;
                      char              *proxyfile;
+                     char              *capath;
                      time_t            last_used;
                    }  handles[GRST_SLASH_MAX_HANDLES];
  
   return GRST_RET_FAILED;
 }
 
-char *check_x509_user_proxy(pid_t pid)
+static void check_user_environ(char **capath, char **proxyfile, pid_t pid)
 {
   int fd;
-  char file[80], *proxyfile = NULL, *pid_environ, *p;
-  struct stat statbuf1, statbuf2;
+  size_t allocated = 1024, ret = 0, count = 0;
+  char file[80], *pid_environ, *p;
+  struct stat statbuf;
+  
+  *proxyfile = NULL;
+  *capath    = NULL;
   
   snprintf(file, sizeof(file), "/proc/%d/environ", (int) pid);
   
-  if ((fd = open(file, O_RDONLY)) == -1) return NULL;
+  if ((fd = open(file, O_RDONLY)) == -1) return;
 
-  if (debugmode) syslog(LOG_DEBUG, "Opened for %d environ in %s", (int) pid, file);
-  
-  fstat(fd, &statbuf1);
-  
-  pid_environ = malloc(statbuf1.st_size + 1);
-  
-  read(fd, pid_environ, statbuf1.st_size);
+  if (debugmode) 
+        syslog(LOG_DEBUG, "Opened for %d environ in %s", (int) pid, file);
   
+  pid_environ = malloc(allocated + 1); /* always space for terminal NUL */
+
+  while ((ret = read(fd, &pid_environ[count], allocated - count)) > 0)
+       {
+         count += ret;
+         
+         if (count >= allocated) 
+           {
+             allocated = count + 1024;
+             pid_environ = realloc(pid_environ, allocated + 1);
+           }
+       }       
+       
   close(fd);
-  
-  pid_environ[statbuf1.st_size] = '\0';
+
+  if (ret < 0)
+    {
+      free(pid_environ);
+      syslog(LOG_ERR, "File error reading %s for %d", file, (int) pid);
+      return;
+    }
     
-  for (p = pid_environ; p < pid_environ + statbuf1.st_size; p += (strlen(p) + 1))
+  pid_environ[count] = '\0'; /* just in case */
+
+  for (p = pid_environ; p < pid_environ + count; p += (strlen(p) + 1))
      {
        if (debugmode) syslog(LOG_DEBUG, "Examine %s in environ", p);
   
        if (strncmp(p, "X509_USER_PROXY=", 16) == 0)
          {
-           if ((p[16] != '\0') &&
-               (stat(&p[16], &statbuf2) == 0)) proxyfile = strdup(&p[16]);
-           break;
+           if ((p[16] != '\0') && (stat(&p[16], &statbuf) == 0))
+             {
+               if (*proxyfile != NULL) free(*proxyfile);
+               *proxyfile = strdup(&p[16]);
+               if (debugmode) syslog(LOG_DEBUG, "Found proxyfile");
+             }
+         }
+       else if (strncmp(p, "X509_CERT_DIR=", 14) == 0)
+         {
+           if ((p[14] != '\0') && (stat(&p[14], &statbuf) == 0))
+             {
+               if (*capath != NULL) free(*capath);
+               *capath = strdup(&p[14]);
+               if (debugmode) syslog(LOG_DEBUG, "Found capath");
+             }
          }
      }
   
   free(pid_environ);
-
-  return proxyfile;    
 }
 
 char *mapdir_uid_to_dn(uid_t uid)
                     struct fuse_context *fuse_ctx)
 {
   int                ret, i, j, itry, ishttps = 0;
-  char              *proxyfile = NULL, *range_header = NULL, *url;
+  char              *proxyfile = NULL, *capath = NULL, *range_header = NULL,
+                    *url;
   struct stat        statbuf;
   struct curl_slist *headers_list = NULL;
 
   if (strncmp(request_data->url, "https://", 8) == 0) /* HTTPS options */
     {
-// check for X509_USER_PROXY in that PID's environ too
       ishttps = 1;
 
-      if ((proxyfile = check_x509_user_proxy(fuse_ctx->pid)) == NULL)
+      check_user_environ(&capath, &proxyfile, fuse_ctx->pid);
+
+      if (proxyfile == NULL)
         {
           asprintf(&proxyfile, "/tmp/x509up_u%d", fuse_ctx->uid);
           /* if proxyfile is used, it will be referenced by handles[].proxyfile
               proxyfile = NULL;
             }
         }
+        
+      if (capath == NULL) capath = strdup("/etc/grid-security/certificates");
     }
 
   if (debugmode && (proxyfile != NULL))
            (handles[i].uid == fuse_ctx->uid) &&
            (((handles[i].proxyfile == NULL) && (proxyfile == NULL)) ||
             ((handles[i].proxyfile != NULL) && (proxyfile != NULL) &&
-             (strcmp(handles[i].proxyfile, proxyfile) == 0))))
+             (strcmp(handles[i].proxyfile, proxyfile) == 0))) &&
+           (((handles[i].capath == NULL) && (capath == NULL)) ||
+            ((handles[i].capath != NULL) && (capath != NULL) &&
+             (strcmp(handles[i].capath, capath) == 0))))
          {
            break;
          }
       (handles[i].uid != fuse_ctx->uid) ||
       (((handles[i].proxyfile != NULL) || (proxyfile != NULL)) &&
        ((handles[i].proxyfile == NULL) || (proxyfile == NULL) ||
-        (strcmp(handles[i].proxyfile, proxyfile) != 0))))
+        (strcmp(handles[i].proxyfile, proxyfile) != 0))) ||
+      (((handles[i].capath != NULL) || (capath != NULL)) &&
+       ((handles[i].capath == NULL) || (capath == NULL) ||
+        (strcmp(handles[i].capath, capath) != 0))))
     {
       /* we do need to initialise this handle */
       
                               curl_easy_cleanup(handles[i].curl_handle);
       handles[i].curl_handle = curl_easy_init();
       
+      if (handles[i].capath != NULL) free(handles[i].capath);
+      handles[i].capath = capath; /* capath might be NULL itself */
+      
       if (handles[i].proxyfile != NULL) free(handles[i].proxyfile);
       handles[i].proxyfile = proxyfile; /* proxyfile might be NULL itself */
       
       curl_easy_setopt(handles[i].curl_handle, CURLOPT_FOLLOWLOCATION, 0);
       curl_easy_setopt(handles[i].curl_handle, CURLOPT_HEADERFUNCTION, headers_callback);
 
-      curl_easy_setopt(handles[i].curl_handle, CURLOPT_CAPATH, 
-                                        "/etc/grid-security/certificates");
+      curl_easy_setopt(handles[i].curl_handle, CURLOPT_CAPATH, handles[i].capath);
 
       curl_easy_setopt(handles[i].curl_handle, CURLOPT_SSL_VERIFYPEER, 2);
       curl_easy_setopt(handles[i].curl_handle, CURLOPT_SSL_VERIFYHOST, 2);
   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))
     {
        break;
      }
 
+  pthread_mutex_unlock(&(handles[i].mutex));
+  
   if (headers_list != NULL) curl_slist_free_all(headers_list);
   if (range_header != NULL) free(range_header);
 
-  pthread_mutex_unlock(&(handles[i].mutex));
-  
   return ret;
 }