From 9ae198093a36af1df1c906e1ab1eee82f6399fb9 Mon Sep 17 00:00:00 2001 From: Andrew McNab Date: Thu, 22 Jun 2006 10:12:26 +0000 Subject: [PATCH] Sync --- org.gridsite.core/interface/gridsite.h | 35 ++- org.gridsite.core/src/Makefile | 51 +++-- org.gridsite.core/src/grst_err.c | 43 ++++ org.gridsite.core/src/grst_gacl.c | 70 ++++-- org.gridsite.core/src/grst_x509.c | 5 +- org.gridsite.core/src/grst_xacml.c | 5 +- org.gridsite.core/src/mod_gridsite.c | 127 ++++++----- org.gridsite.core/src/slashgrid.c | 401 +++++++++++++++++++++++++++++++-- org.gridsite.core/src/slashgrid.init | 1 + 9 files changed, 606 insertions(+), 132 deletions(-) create mode 100644 org.gridsite.core/src/grst_err.c diff --git a/org.gridsite.core/interface/gridsite.h b/org.gridsite.core/interface/gridsite.h index caa3a14..0fa2640 100644 --- a/org.gridsite.core/interface/gridsite.h +++ b/org.gridsite.core/interface/gridsite.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2002-5, Andrew McNab, University of Manchester + Copyright (c) 2002-6, Andrew McNab, University of Manchester All rights reserved. Redistribution and use in source and binary forms, with or @@ -63,6 +63,24 @@ /// No such file or directory #define GRST_RET_NO_SUCH_FILE 1003 + +// #define GRSTerrorLog(GRSTerrorLevel, GRSTerrorFmt, ...) if (GRSTerrorLogFunc != NULL) (GRSTerrorLogFunc)(__FILE__, __LINE__, GRSTerrorLevel, GRSTerrorFmt, __VA_ARGS__) + +#define GRSTerrorLog(GRSTerrorLevel, ...) if (GRSTerrorLogFunc != NULL) (GRSTerrorLogFunc)(__FILE__, __LINE__, GRSTerrorLevel, __VA_ARGS__) + +void (*GRSTerrorLogFunc)(char *, int, int, char *, ...); + +/* these levels are the same as Unix syslog() and Apache ap_log_error() */ + +#define GRST_LOG_EMERG 0 +#define GRST_LOG_ALERT 1 +#define GRST_LOG_CRIT 2 +#define GRST_LOG_ERR 3 +#define GRST_LOG_WARNING 4 +#define GRST_LOG_NOTICE 5 +#define GRST_LOG_INFO 6 +#define GRST_LOG_DEBUG 7 + typedef struct { char *name; char *value; void *next; } GRSTgaclNamevalue; @@ -94,14 +112,14 @@ typedef struct { GRSTgaclCred *firstcred; #define GRST_PERM_ALL 31 /* DO NOT USE PermIsNone!! */ -#define GRSTgaclPermIsNone(perm) (perm == 0) +#define GRSTgaclPermIsNone(perm) ((perm) == 0) -#define GRSTgaclPermHasNone(perm) (perm == 0) -#define GRSTgaclPermHasRead(perm) ((perm & GRST_PERM_READ ) != 0) -#define GRSTgaclPermHasExec(perm) ((perm & GRST_PERM_EXEC ) != 0) -#define GRSTgaclPermHasList(perm) ((perm & GRST_PERM_LIST ) != 0) -#define GRSTgaclPermHasWrite(perm) ((perm & GRST_PERM_WRITE) != 0) -#define GRSTgaclPermHasAdmin(perm) ((perm & GRST_PERM_ADMIN) != 0) +#define GRSTgaclPermHasNone(perm) ((perm) == 0) +#define GRSTgaclPermHasRead(perm) (((perm) & GRST_PERM_READ ) != 0) +#define GRSTgaclPermHasExec(perm) (((perm) & GRST_PERM_EXEC ) != 0) +#define GRSTgaclPermHasList(perm) (((perm) & GRST_PERM_LIST ) != 0) +#define GRSTgaclPermHasWrite(perm) (((perm) & GRST_PERM_WRITE) != 0) +#define GRSTgaclPermHasAdmin(perm) (((perm) & GRST_PERM_ADMIN) != 0) #define GRST_ACTION_ALLOW 0 #define GRST_ACTION_DENY 1 @@ -127,6 +145,7 @@ struct GRSTasn1TagList { char treecoords[GRST_ASN1_MAXCOORDLEN+1]; #define GRST_HTTP_PORT 777 #define GRST_HTTPS_PORT 488 #define GRST_HTCP_PORT 777 +#define GRST_GSIFTP_PORT 2811 #define GRSThtcpNOPop 0 #define GRSThtcpTSTop 1 diff --git a/org.gridsite.core/src/Makefile b/org.gridsite.core/src/Makefile index 026b9f5..a847bdb 100644 --- a/org.gridsite.core/src/Makefile +++ b/org.gridsite.core/src/Makefile @@ -65,12 +65,21 @@ build-lib: libgridsite_globus.so.$(VERSION) libgridsite_globus.a \ # First, normal versions using system OpenSSL rather than Globus OpenSSL -libgridsite.so.$(VERSION): grst_x509.o grst_gacl.o grst_xacml.o grst_http.o grst_asn1.o grst_htcp.o +libgridsite.so.$(VERSION): grst_err.o grst_x509.o grst_gacl.o grst_xacml.o \ + grst_http.o grst_asn1.o grst_htcp.o gcc -shared -Wl,-soname,libgridsite.so.$(MINOR_VERSION) \ - -o libgridsite.so.$(PATCH_VERSION) grst_x509.o grst_gacl.o grst_xacml.o grst_http.o grst_asn1.o grst_htcp.o + -o libgridsite.so.$(PATCH_VERSION) -lcrypto `xml2-config --libs` \ + grst_err.o grst_x509.o grst_gacl.o grst_xacml.o grst_http.o \ + grst_asn1.o grst_htcp.o + ln -sf libgridsite.so.$(VERSION) libgridsite.so + ln -sf libgridsite.so.$(VERSION) libgridsite.so.$(MINOR_VERSION) -libgridsite.a: grst_x509.o grst_gacl.o grst_xacml.o grst_http.o grst_asn1.o grst_htcp.o - ar src libgridsite.a grst_x509.o grst_gacl.o grst_xacml.o grst_http.o grst_asn1.o grst_htcp.o +libgridsite.a: grst_err.o grst_x509.o grst_gacl.o grst_xacml.o grst_http.o grst_asn1.o grst_htcp.o + ar src libgridsite.a grst_err.o grst_x509.o grst_gacl.o grst_xacml.o grst_http.o grst_asn1.o grst_htcp.o + +grst_err.o: grst_err.c ../interface/gridsite.h + gcc -g $(MYCFLAGS) \ + -c grst_err.c grst_x509.o: grst_x509.c ../interface/gridsite.h gcc -g $(MYCFLAGS) \ @@ -100,16 +109,23 @@ grst_htcp.o: grst_htcp.c ../interface/gridsite.h ifdef OPENSSL_GLOBUS_LIBS -libgridsite_globus.so.$(VERSION): \ +libgridsite_globus.so.$(VERSION): grst_err_globus.o \ grst_x509_globus.o grst_gacl_globus.o grst_http_globus.o \ - grst_asn1_globus.o grst_xacml_globus.o grst_htcp_globus.o + grst_asn1_globus.o grst_xacml_globus.o grst_htcp_globus.o gcc -shared -Wl,-soname,libgridsite_globus.so.$(MINOR_VERSION) \ -o libgridsite_globus.so.$(PATCH_VERSION) \ - grst_x509_globus.o grst_gacl_globus.o grst_xacml_globus.o grst_http_globus.o grst_asn1_globus.o + grst_err.o grst_x509_globus.o grst_gacl_globus.o grst_xacml_globus.o \ + grst_http_globus.o grst_asn1_globus.o + ln -sf libgridsite_globus.so.$(VERSION) libgridsite_globus.so -libgridsite_globus.a: grst_x509_globus.o grst_gacl_globus.o grst_http_globus.o grst_asn1_globus.o +libgridsite_globus.a: grst_err_globus.o grst_x509_globus.o grst_gacl_globus.o grst_http_globus.o grst_asn1_globus.o ar src libgridsite_globus.a \ - grst_x509_globus.o grst_gacl_globus.o grst_http_globus.o grst_asn1_globus.o + grst_err_globus.o grst_x509_globus.o grst_gacl_globus.o grst_http_globus.o grst_asn1_globus.o + +grst_err_globus.o: grst_err.c ../interface/gridsite.h + gcc -g $(MYCFLAGS) $(OPENSSL_GLOBUS_FLAGS) \ + -c grst_err.c \ + -o grst_err_globus.o grst_x509_globus.o: grst_x509.c ../interface/gridsite.h gcc -g $(MYCFLAGS) $(OPENSSL_GLOBUS_FLAGS) \ @@ -158,19 +174,22 @@ gsexec: gsexec.c gsexec.h urlencode: urlencode.c libgridsite.a gcc -g -DVERSION=\"$(PATCH_VERSION)\" $(MYCFLAGS) \ -o urlencode urlencode.c -L. \ - -I/usr/kerberos/include -lgridsite + -I/usr/kerberos/include \ + -lgridsite htcp: htcp.c libgridsite.a gcc -g -DVERSION=\"$(PATCH_VERSION)\" $(MYCFLAGS) \ -o htcp htcp.c -L. \ -I/usr/kerberos/include \ - `curl-config --cflags` `curl-config --libs` -lgridsite + `curl-config --cflags` `curl-config --libs` \ + -lgridsite gridsite-copy.cgi: gridsite-copy.c libgridsite.a gcc -g -DVERSION=\"$(PATCH_VERSION)\" $(MYCFLAGS) \ -o gridsite-copy.cgi gridsite-copy.c -L. \ -I/usr/kerberos/include \ - `curl-config --cflags` `curl-config --libs` -lgridsite + `curl-config --cflags` `curl-config --libs` \ + -lgridsite mod_gridsite.so: mod_gridsite.c mod_ssl-private.h libgridsite.a gcc -g $(MYCFLAGS) -shared -Wl,-soname=gridsite_module \ @@ -200,13 +219,15 @@ showx509exts: showx509exts.c libgridsite.a -I/usr/kerberos/include \ -lgridsite \ -lssl -lcrypto -lxml2 -lz -lm + + -slashgrid: slashgrid.c +slashgrid: slashgrid.c libgridsite.so.$(VERSION) gcc -g -o slashgrid -lfuse -lpthread slashgrid.c \ + $(MYCFLAGS) $(MYLDFLAGS) `xml2-config --cflags` \ -D_FILE_OFFSET_BITS=64 -D_REENTRANT -DFUSE_USE_VERSION=22 \ - $(MYCFLAGS) $(MYLDFLAGS) \ -I/usr/kerberos/include `curl-config --cflags` \ - `curl-config --libs` -lgridsite -lxml2 + -L. `curl-config --libs` -lgridsite apidoc: date diff --git a/org.gridsite.core/src/grst_err.c b/org.gridsite.core/src/grst_err.c new file mode 100644 index 0000000..5c541b5 --- /dev/null +++ b/org.gridsite.core/src/grst_err.c @@ -0,0 +1,43 @@ +/* + Copyright (c) 2002-6, Andrew McNab, University of Manchester + All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, are permitted provided that the following + conditions are met: + + o Redistributions of source code must retain the above + copyright notice, this list of conditions and the following + disclaimer. + o Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + --------------------------------------------------------------- + For more information about GridSite: http://www.gridsite.org/ + --------------------------------------------------------------- +*/ + +#define _GNU_SOURCE + +#include "gridsite.h" + +/* Little piece of GRSTerror in GRSTgacl */ + +void (*GRSTerrorLogFunc)(char *, int, int, char *, ...) = NULL; + diff --git a/org.gridsite.core/src/grst_gacl.c b/org.gridsite.core/src/grst_gacl.c index 336c853..667d5d8 100644 --- a/org.gridsite.core/src/grst_gacl.c +++ b/org.gridsite.core/src/grst_gacl.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2002-3, Andrew McNab, University of Manchester + Copyright (c) 2002-6, Andrew McNab, University of Manchester All rights reserved. Redistribution and use in source and binary forms, with or @@ -53,7 +53,7 @@ #include "gridsite.h" /* * - * Global variables, shared by all GACL functions by private to libgacl * + * Global variables, shared by all GACL functions but private to libgacl * * */ char *grst_perm_syms[] = { "none", @@ -572,8 +572,9 @@ static GRSTgaclCred *GRSTgaclCredParse(xmlNodePtr cur) for (cur2 = cur->xmlChildrenNode; cur2 != NULL; cur2=cur2->next) { - GRSTgaclCredAddValue(cred, (char *) cur2->name, - (char *) xmlNodeGetContent(cur2)); + if (!xmlIsBlankNode(cur2)) + GRSTgaclCredAddValue(cred, (char *) cur2->name, + (char *) xmlNodeGetContent(cur2)); } return cred; @@ -599,21 +600,32 @@ static GRSTgaclEntry *GRSTgaclEntryParse(xmlNodePtr cur) while (cur != NULL) { - if (xmlStrcmp(cur->name, (const xmlChar *) "allow") == 0) + if (xmlIsBlankNode(cur)) + { + cur=cur->next; + continue; + } + else if (xmlStrcmp(cur->name, (const xmlChar *) "allow") == 0) { for (cur2 = cur->xmlChildrenNode; cur2 != NULL; cur2=cur2->next) - for (i=0; grst_perm_syms[i] != NULL; ++i) - if (xmlStrcmp(cur2->name, + if (!xmlIsBlankNode(cur2)) + { + for (i=0; grst_perm_syms[i] != NULL; ++i) + if (xmlStrcmp(cur2->name, (const xmlChar *) grst_perm_syms[i]) == 0) - GRSTgaclEntryAllowPerm(entry, grst_perm_vals[i]); + GRSTgaclEntryAllowPerm(entry, grst_perm_vals[i]); + } } else if (xmlStrcmp(cur->name, (const xmlChar *) "deny") == 0) { for (cur2 = cur->xmlChildrenNode; cur2 != NULL; cur2=cur2->next) - for (i=0; grst_perm_syms[i] != NULL; ++i) - if (xmlStrcmp(cur2->name, + if (!xmlIsBlankNode(cur2)) + { + for (i=0; grst_perm_syms[i] != NULL; ++i) + if (xmlStrcmp(cur2->name, (const xmlChar *) grst_perm_syms[i]) == 0) - GRSTgaclEntryDenyPerm(entry, grst_perm_vals[i]); + GRSTgaclEntryDenyPerm(entry, grst_perm_vals[i]); + } } else if ((cred = GRSTgaclCredParse(cur)) != NULL) { @@ -642,22 +654,37 @@ GRSTgaclAcl *GRSTgaclAclLoadFile(char *filename) xmlNodePtr cur; GRSTgaclAcl *acl; + GRSTerrorLog(GRST_LOG_DEBUG, "GRSTgaclAclLoadFile() starting"); + + if (filename == NULL) + { + GRSTerrorLog(GRST_LOG_DEBUG, "GRSTgaclAclLoadFile() cannot open a NULL filename"); + return NULL; + } + doc = xmlParseFile(filename); - if (doc == NULL) return NULL; + if (doc == NULL) + { + GRSTerrorLog(GRST_LOG_DEBUG, "GRSTgaclAclLoadFile failed to open ACL file %s", filename); + return NULL; + } cur = xmlDocGetRootElement(doc); if (cur == NULL) { - xmlFreeDoc(doc); + xmlFreeDoc(doc); + GRSTerrorLog(GRST_LOG_DEBUG, "GRSTgaclAclLoadFile failed to parse root of ACL file %s", filename); return NULL; } if (!xmlStrcmp(cur->name, (const xmlChar *) "Policy")) { + GRSTerrorLog(GRST_LOG_DEBUG, "GRSTgaclAclLoadFile parsing XACML"); acl=GRSTxacmlAclParse(doc, cur, acl); } else if (!xmlStrcmp(cur->name, (const xmlChar *) "gacl")) { + GRSTerrorLog(GRST_LOG_DEBUG, "GRSTgaclAclLoadFile parsing GACL"); acl=GRSTgaclAclParse(doc, cur, acl); } else /* ACL format not recognised */ @@ -680,15 +707,18 @@ GRSTgaclAcl *GRSTgaclAclParse(xmlDocPtr doc, xmlNodePtr cur, GRSTgaclAcl *acl) while (cur != NULL) { - entry = GRSTgaclEntryParse(cur); - if (entry == NULL) + if (!xmlIsBlankNode(cur)) { - GRSTgaclAclFree(acl); - xmlFreeDoc(doc); - return NULL; - } + entry = GRSTgaclEntryParse(cur); + if (entry == NULL) + { + GRSTgaclAclFree(acl); - GRSTgaclAclAddEntry(acl, entry); + return NULL; + } + + GRSTgaclAclAddEntry(acl, entry); + } cur=cur->next; } diff --git a/org.gridsite.core/src/grst_x509.c b/org.gridsite.core/src/grst_x509.c index af871ae..31a89c9 100644 --- a/org.gridsite.core/src/grst_x509.c +++ b/org.gridsite.core/src/grst_x509.c @@ -76,7 +76,8 @@ int GRSTx509NameCmp(char *a, char *b) * would ideally be done with OIDs/values. In particular, we equate * "/Email=" == "/emailAddress=" to deal with this important change * between OpenSSL 0.9.6 and 0.9.7. - * Other than that, it is currently the same as ordinary strcmp(3). + * Other than that, it is currently the same as ordinary strcasecmp(3) + * (for consistency with EDG/LCG/EGEE gridmapdir case insensitivity.) */ { int ret; @@ -96,7 +97,7 @@ int GRSTx509NameCmp(char *a, char *b) p[1] = 'E'; } - ret = strcmp(aa, bb); + ret = strcasecmp(aa, bb); free(aa); free(bb); diff --git a/org.gridsite.core/src/grst_xacml.c b/org.gridsite.core/src/grst_xacml.c index c38424f..c4c88ee 100644 --- a/org.gridsite.core/src/grst_xacml.c +++ b/org.gridsite.core/src/grst_xacml.c @@ -231,7 +231,7 @@ static GRSTgaclEntry *GRSTxacmlEntryParse(xmlNodePtr cur) GRSTgaclAcl *GRSTxacmlAclLoadFile(char *filename) { -xmlDocPtr doc; + xmlDocPtr doc; xmlNodePtr cur; GRSTgaclAcl *acl; @@ -245,7 +245,7 @@ xmlDocPtr doc; else if (!xmlStrcmp(cur->name, (const xmlChar *) "gacl")) {acl=GRSTgaclAclParse(doc, cur, acl);} else /* ACL format not recognised */ { - free(doc); + xmlFreeDoc(doc); free(cur); return NULL; } @@ -283,7 +283,6 @@ GRSTgaclAcl *GRSTxacmlAclParse(xmlDocPtr doc, xmlNodePtr cur, GRSTgaclAcl *acl) if (entry == NULL) { GRSTgaclAclFree(acl); - xmlFreeDoc(doc); return NULL; } else GRSTgaclAclAddEntry(acl, entry); diff --git a/org.gridsite.core/src/mod_gridsite.c b/org.gridsite.core/src/mod_gridsite.c index 1321eec..328c807 100644 --- a/org.gridsite.core/src/mod_gridsite.c +++ b/org.gridsite.core/src/mod_gridsite.c @@ -112,12 +112,13 @@ struct sitecast_group #define GRST_SITECAST_ALIASES 32 struct sitecast_alias - { const char *sitecast_url; const char *local_path; server_rec *server; }; + { const char *sitecast_url; const char *scheme; int port; + const char *local_path; server_rec *server; }; /* Globals, defined by main server directives in httpd.conf These are assigned default values in create_gridsite_srv_config() */ -int gridhttpport = 0; +int gridhttpport = 0; /* set by create_gridsite_srv_config, used as flag */ char *sessionsdir = NULL; char *sitecastdnlists = NULL; struct sitecast_group sitecastgroups[GRST_SITECAST_GROUPS+1]; @@ -1421,7 +1422,8 @@ static void *create_gridsite_srv_config(apr_pool_t *p, server_rec *s) { int i; - if (!(s->is_virtual)) + /* only run once (in base server) */ + if (!(s->is_virtual) && (gridhttpport == 0)) { gridhttpport = GRST_HTTP_PORT; @@ -1438,14 +1440,17 @@ static void *create_gridsite_srv_config(apr_pool_t *p, server_rec *s) /* GridSiteCastUniPort udp-port */ for (i=1; i <= GRST_SITECAST_GROUPS; ++i) - sitecastgroups[i].port = 0; - /* GridSiteCastGroup mcast-list */ + { + sitecastgroups[i].port = 0; /* GridSiteCastGroup mcast-list */ + } for (i=1; i <= GRST_SITECAST_ALIASES; ++i) { sitecastaliases[i].sitecast_url = NULL; + sitecastaliases[i].port = 0; + sitecastaliases[i].scheme = NULL; sitecastaliases[i].local_path = NULL; - sitecastaliases[i].server = NULL; + sitecastaliases[i].server = NULL; } /* GridSiteCastAlias url path */ } @@ -1824,7 +1829,8 @@ static const char *mod_gridsite_take1_cmds(cmd_parms *a, void *cfg, static const char *mod_gridsite_take2_cmds(cmd_parms *a, void *cfg, const char *parm1, const char *parm2) { - int i; + int i; + char *p, *q; if (strcasecmp(a->cmd->name, "GridSiteUserGroup") == 0) { @@ -1864,9 +1870,34 @@ static const char *mod_gridsite_take2_cmds(cmd_parms *a, void *cfg, { if (sitecastaliases[i].sitecast_url == NULL) { - sitecastaliases[i].sitecast_url = parm1; - sitecastaliases[i].local_path = parm2; - sitecastaliases[i].server = a->server; + sitecastaliases[i].scheme = apr_pstrdup(a->pool, parm1); + + if (((p = index(sitecastaliases[i].scheme, ':')) == NULL) + || (p[1] != '/') || (p[2] != '/')) + return "GridSiteCastAlias URL must begin with scheme (http/https/gsiftp/...) and ://"; + + *p = '\0'; + ++p; + while (*p == '/') ++p; + + if ((q = index(p, '/')) == NULL) + return "GridSiteCastAlias URL must be of form scheme://domain:port/dirs"; + + *q = '\0'; + + p = index(p, ':'); + if (p == NULL) + { + return "GridSiteCastAlias URL must include the port number"; + } + + if (sscanf(p, ":%d", &(sitecastaliases[i].port)) != 1) + return "Unable to parse numeric port number in GridSiteCastAlias"; + + sitecastaliases[i].sitecast_url = apr_pstrdup(a->pool, parm1); + sitecastaliases[i].local_path = apr_pstrdup(a->pool, parm2); + sitecastaliases[i].server = a->server; + break; } } @@ -2735,42 +2766,13 @@ void sitecast_handle_TST_GET(server_rec *main_server, GRSThtcpMessage *htcp_mesg, int igroup, struct sockaddr_in *client_addr_ptr) { - int i, outbuf_len, ialias, port; + int i, outbuf_len, ialias; char *filename, *outbuf, *location, *local_uri = NULL; struct stat statbuf; - SSLSrvConfigRec *ssl_srv; - /* check sanity of requested uri */ - - if (strncmp(htcp_mesg->uri->text, "http://", 7) == 0) - { - for (i=7; i < GRSThtcpCountstrLen(htcp_mesg->uri); ++i) - if (htcp_mesg->uri->text[i] == '/') - { - local_uri = &(htcp_mesg->uri->text[i]); - break; - } - } - else if (strncmp(htcp_mesg->uri->text, "https://", 8) == 0) - { - for (i=8; i < GRSThtcpCountstrLen(htcp_mesg->uri); ++i) - if (htcp_mesg->uri->text[i] == '/') - { - local_uri = &(htcp_mesg->uri->text[i]); - break; - } - } - - if (local_uri == NULL) - { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, main_server, - "SiteCast responder only handles http(s):// (%*s requested by %s:%d)", - GRSThtcpCountstrLen(htcp_mesg->uri), - htcp_mesg->uri->text, - inet_ntoa(client_addr_ptr->sin_addr), - ntohs(client_addr_ptr->sin_port)); - return; - } + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, main_server, + "SiteCast responder received TST GET with uri %s", + htcp_mesg->uri->text, GRSThtcpCountstrLen(htcp_mesg->uri)); /* find if any GridSiteCastAlias lines match */ @@ -2796,9 +2798,9 @@ void sitecast_handle_TST_GET(server_rec *main_server, return; /* no match */ } - + /* convert URL to filename, using alias mapping */ - + asprintf(&filename, "%s%*s", sitecastaliases[ialias].local_path, GRSThtcpCountstrLen(htcp_mesg->uri) @@ -2806,19 +2808,12 @@ void sitecast_handle_TST_GET(server_rec *main_server, &(htcp_mesg->uri->text[strlen(sitecastaliases[ialias].sitecast_url)]) ); if (stat(filename, &statbuf) == 0) /* found file */ - { - ssl_srv = (SSLSrvConfigRec *) - ap_get_module_config(sitecastaliases[ialias].server->module_config, - &ssl_module); - - port = sitecastaliases[ialias].server->addrs->host_port; - if (port == 0) port = ((ssl_srv != NULL) && (ssl_srv->enabled)) - ? GRST_HTTPS_PORT : GRST_HTTP_PORT; - - asprintf(&location, "Location: http%s://%s:%d%s\r\n", - ((ssl_srv != NULL) && (ssl_srv->enabled)) ? "s" : "", - sitecastaliases[ialias].server->server_hostname, port, - local_uri); + { + asprintf(&location, "Location: %s://%s:%d/%s\r\n", + sitecastaliases[ialias].scheme, + sitecastaliases[ialias].server->server_hostname, + sitecastaliases[ialias].port, + &(htcp_mesg->uri->text[strlen(sitecastaliases[ialias].sitecast_url)]) ); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, main_server, "SiteCast finds %*s at %s, redirects with %s", @@ -2954,6 +2949,9 @@ void sitecast_responder(server_rec *main_server) /* initialise multicast listener sockets next */ + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, main_server, + "SiteCast UDP Responder group [1].port %d", sitecastgroups[1].port); + for (i=1; (i <= GRST_SITECAST_GROUPS) && (sitecastgroups[i].port != 0); ++i) { @@ -2994,6 +2992,17 @@ void sitecast_responder(server_rec *main_server) sitecastgroups[i].quad3, sitecastgroups[i].quad4, sitecastgroups[i].port); } + for (i=0; i < GRST_SITECAST_ALIASES ; ++i) + { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, main_server, + "SiteCast alias for %s (%s,%d) to %s (%s)", + sitecastaliases[i].sitecast_url, + sitecastaliases[i].scheme, + sitecastaliases[i].port, + sitecastaliases[i].local_path, + sitecastaliases[i].server->server_hostname); + } + while (1) /* **** main listening loop **** */ { /* set up bitmasks for select */ @@ -3152,7 +3161,7 @@ static void mod_gridsite_child_init(apr_pool_t *pPool, server_rec *pServer) /* expire old ssl creds files */ - if (sc != NULL) // && sc->enabled) + if (sc != NULL) { cutoff_time = apr_time_now() - apr_time_from_sec(sc->session_cache_timeout); diff --git a/org.gridsite.core/src/slashgrid.c b/org.gridsite.core/src/slashgrid.c index 5e6518f..1a7cbc0 100644 --- a/org.gridsite.core/src/slashgrid.c +++ b/org.gridsite.core/src/slashgrid.c @@ -53,6 +53,9 @@ #include #include #include +#include +#include +#include #include @@ -136,7 +139,10 @@ struct grst_handle { pthread_mutex_t mutex; int debugmode = 0; int number_of_tries = 1, sitecast_domain_len = 0; -char *sitecast_domain = NULL, *sitecast_groups = NULL; +char *sitecast_domain = NULL, *sitecast_groups = NULL, *local_root = NULL, + *gridmapdir = NULL; +uid_t local_uid = 0; +gid_t local_gid = 0; size_t headers_callback(void *ptr, size_t size, size_t nmemb, void *p) /* Find the values of the return code, Content-Length, Last-Modified @@ -854,7 +860,7 @@ struct grst_dir_list *index_to_dir_list(char *text, char *source) (p[i] != '\t') && (p[i] != ')' ) && (p[i] != '>' ) ; ++i) ; } - if (i > namestart) + if (i > namestart) { s = malloc(1 + i - namestart); memcpy(s, &p[namestart], i - namestart); @@ -862,6 +868,14 @@ struct grst_dir_list *index_to_dir_list(char *text, char *source) list[used].filename = canonicalise(s, source); free(s); + + if ((list[used].filename != NULL) && + ((list[used].filename[0] == '\0') || + (strcmp(list[used].filename, "/") == 0))) + { + free(list[used].filename); + list[used].filename = NULL; + } } p = &p[i-1]; /* -1 since continue results in ++i */ @@ -945,6 +959,31 @@ static char *GRSThttpUrlMildencode(char *in) } #endif +GRSTgaclPerm get_gaclPerm(struct fuse_context *fuse_ctx, char *path) +{ + GRSTgaclPerm perm = GRST_PERM_NONE; + GRSTgaclCred *cred; + GRSTgaclUser *user; + GRSTgaclAcl *acl; + +// eventually want a UID cache here... + +// will check gridmapdir for DN and create user in future... + user = NULL; // but just anonymous user for now + + acl = GRSTgaclAclLoadforFile(path); + + perm = GRSTgaclAclTestUser(acl, user); + GRSTgaclAclFree(acl); + GRSTgaclUserFree(user); + +perm = 255; + + if (debugmode) syslog(LOG_DEBUG, "get_gaclPerm returns perm=%d", perm); + + return perm; +} + int read_headers_from_cache(struct fuse_context *fuse_ctx, char *filename, off_t *length, time_t *modified) { @@ -1100,10 +1139,10 @@ static int slashgrid_readdir(const char *path, void *buf, (void) offset; (void) fi; - int anyerror = 0, thiserror, i, ilast; + int anyerror = 0, thiserror, i, ilast, len, isdir; const char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; - char *s, *url, errorbuffer[CURL_ERROR_SIZE+1] = ""; + char *s, *url, errorbuffer[CURL_ERROR_SIZE+1] = "", *dirname, *p; struct grst_body_text rawindex; struct grst_dir_list *list; struct grst_request request_data; @@ -1111,12 +1150,78 @@ static int slashgrid_readdir(const char *path, void *buf, struct stat stat_tmp; time_t now; struct fuse_context fuse_ctx; + struct dirent **dirlist; + GRSTgaclPerm perm; memcpy(&fuse_ctx, fuse_get_context(), sizeof(struct fuse_context)); if (debugmode) syslog(LOG_DEBUG, "in slashgrid_readdir"); - if (strncmp(path, "/http/", 6) == 0) + if (strcmp(path, "/") == 0) + { + filler(buf, ".", NULL, 0); + filler(buf, "..", NULL, 0); + filler(buf, "http", NULL, 0); + filler(buf, "https", NULL, 0); + return 0; + } + + if ((strcmp(path, "/http") == 0) || (strcmp(path, "/https") == 0)) + { + filler(buf, ".", NULL, 0); + filler(buf, "..", NULL, 0); + + asprintf(&dirname, "%s/%d%s", GRST_SLASH_HEADERS, fuse_ctx.uid, path); + ilast = scandir(dirname, &dirlist, 0, alphasort) - 1; + + for (i=0; i <= ilast; ++i) + { + if (dirlist[i]->d_name[0] != '.') + filler(buf, dirlist[i]->d_name, NULL, 0); + free(dirlist[i]); + } + + free(dirlist); + free(dirname); + + return 0; + } + else if ((local_root != NULL) && + ((strcmp(path, "/local") == 0) || + (strncmp(path, "/local/", 7) == 0))) + { + asprintf(&dirname, "%s%s/", local_root, &path[6]); + + if (debugmode) syslog(LOG_DEBUG, "in slashgrid_readdir, dirname=%s", dirname); + + perm = get_gaclPerm(&fuse_ctx, dirname); + + if (!GRSTgaclPermHasList(perm)) + { + free(dirname); + return -EACCES; + } + + ilast = scandir(dirname, &dirlist, 0, alphasort) - 1; + free(dirname); + + if (ilast < 0) return -ENOENT; + + filler(buf, ".", NULL, 0); + filler(buf, "..", NULL, 0); + + for (i=0; i <= ilast; ++i) + { + if (dirlist[i]->d_name[0] != '.') + filler(buf, dirlist[i]->d_name, NULL, 0); + free(dirlist[i]); + } + + free(dirlist); + + return 0; + } + else if (strncmp(path, "/http/", 6) == 0) asprintf(&url, "http://%s/", &path[6]); else if (strncmp(path, "/https/", 7) == 0) asprintf(&url, "https://%s/", &path[7]); @@ -1163,13 +1268,32 @@ static int slashgrid_readdir(const char *path, void *buf, rawindex.text[rawindex.used] = '\0'; +// we need to get this out of headers cache instead iff still valid + list = index_to_dir_list(rawindex.text, url); ilast = -1; for (i=0; list[i].filename != NULL; ++i) { + if (debugmode) syslog(LOG_DEBUG, + "in slashgrid_readdir, list[%d].filename=%s", + i, list[i].filename); + if (strncmp(list[i].filename, "mailto:", 7) == 0) continue; + len = strlen(list[i].filename); + if (list[i].filename[len-1] == '/') + { + isdir = 1; + list[i].filename[len-1] = '\0'; + } + else + { + isdir = 0; + + if ((p = index(list[i].filename, '?')) != NULL) *p = '\0'; + } + /* skip over duplicates */ if ((ilast >= 0) && @@ -1177,34 +1301,45 @@ static int slashgrid_readdir(const char *path, void *buf, continue; ilast=i; /* last distinct entry */ + if (debugmode) syslog(LOG_DEBUG, + "in slashgrid_readdir, list[%d].filename=%s not dup", + i, list[i].filename); + asprintf(&s, "%s/%s", path, list[i].filename); write_headers_to_cache(&fuse_ctx, s, list[i].length, list[i].modified); free(s); bzero(&stat_tmp, sizeof(struct stat)); + stat_tmp.st_size = list[i].length; stat_tmp.st_mtime = list[i].modified; stat_tmp.st_ctime = list[i].modified; stat_tmp.st_atime = now; - stat_tmp.st_mode = 0666; - + stat_tmp.st_mode = isdir ? 0777 : 0666; filler(buf, list[i].filename, &stat_tmp, 0); + + if (debugmode) syslog(LOG_DEBUG, + "in slashgrid_readdir, filler list[%d].filename=%s %lu %lu", + i, list[i].filename, stat_tmp.st_size, stat_tmp.st_mtime); } } + if (debugmode) syslog(LOG_DEBUG, + "in slashgrid_readdir, return 0"); return 0; } static int slashgrid_getattr(const char *rawpath, struct stat *stbuf) { - int anyerror = 0, thiserror, i, ilast, len; - char *s, *url, *path, errorbuffer[CURL_ERROR_SIZE+1] = ""; + int anyerror = 0, thiserror, i, ilast, len, ret; + char *s, *url, *path, errorbuffer[CURL_ERROR_SIZE+1] = "", *p; struct grst_dir_list *list; struct grst_request request_data; struct tm modified_tm; struct stat stat_tmp; time_t now; + GRSTgaclPerm dirperm, perm; struct fuse_context fuse_ctx; @@ -1220,11 +1355,12 @@ static int slashgrid_getattr(const char *rawpath, struct stat *stbuf) if ((strcmp(rawpath, "/") == 0) || (strcmp(rawpath, "/http") == 0) || - (strcmp(rawpath, "/https") == 0)) + (strcmp(rawpath, "/https") == 0) || + ((local_root != NULL) && (strcmp(rawpath, "/local") == 0))) { stbuf->st_mode = S_IFDIR | 0755; - return 0; /* The empty top level directory: OK */ + return 0; /* Empty top level directories: OK */ } else if (strncmp(rawpath, "/http/", 6) == 0) { @@ -1256,6 +1392,75 @@ static int slashgrid_getattr(const char *rawpath, struct stat *stbuf) path = strdup(rawpath); } } + else if ((local_root != NULL) && (strncmp(rawpath, "/local/", 7) == 0)) + { + asprintf(&path, "%s/%s", local_root, &rawpath[7]); + + ret = lstat(path, &stat_tmp); + + if (debugmode) syslog(LOG_DEBUG, "path=%s ret=%d", path, ret); + + if ((ret == 0) && S_ISDIR(stat_tmp.st_mode)) + { + dirperm = get_gaclPerm(&fuse_ctx, path); + + p = rindex(path, '/'); + if (p != NULL) *p = '\0'; + /* strip off directory name itself if a directory, + so get the GACL of the parent directory */ + + perm = get_gaclPerm(&fuse_ctx, path); + } + else + { + perm = get_gaclPerm(&fuse_ctx, path); + dirperm = perm; + } + + if (!GRSTgaclPermHasRead(perm)) ret = -EACCES; + else if (ret == 0) + { + stbuf->st_nlink = 1; + stbuf->st_uid = fuse_ctx.uid; + stbuf->st_gid = fuse_ctx.gid; + stbuf->st_size = stat_tmp.st_size; + stbuf->st_blksize = stat_tmp.st_blksize; + stbuf->st_blocks = stat_tmp.st_blocks; + stbuf->st_atime = stat_tmp.st_atime; + stbuf->st_mtime = stat_tmp.st_mtime; + stbuf->st_ctime = stat_tmp.st_ctime; + + if (S_ISDIR(stat_tmp.st_mode)) + { + stbuf->st_mode = S_IFDIR; + + if (GRSTgaclPermHasWrite(dirperm)) + stbuf->st_mode |= S_IWUSR; + + if (GRSTgaclPermHasList(dirperm)) + stbuf->st_mode |= S_IRUSR | S_IXUSR; + } + else + { + stbuf->st_mode = S_IFREG; + + if (GRSTgaclPermHasWrite(perm)) + stbuf->st_mode |= S_IWUSR; + + if (GRSTgaclPermHasRead(perm)) + stbuf->st_mode |= S_IRUSR; + } + + + } + else ret = -ENOENT; + + free(path); + + if (debugmode) syslog(LOG_DEBUG, "slashgrid_getattr returns %d for %s", + ret, rawpath); + return ret; + } else return -ENOENT; time(&now); @@ -1370,7 +1575,6 @@ static int slashgrid_getattr(const char *rawpath, struct stat *stbuf) return 0; } - int write_block_to_cache(struct fuse_context *fuse_ctx, char *filename, off_t start, off_t finish) { @@ -1458,8 +1662,8 @@ int write_block_to_cache(struct fuse_context *fuse_ctx, char *filename, if (*p == '\0') break; } - asprintf(&new_filename, "%s/%d%s/%ld-%ld", - GRST_SLASH_BLOCKS, fuse_ctx->uid, encoded_filename, (long) start, (long) finish); + asprintf(&new_filename, "%s/%d%s/%ld-%ld", GRST_SLASH_BLOCKS, fuse_ctx->uid, + encoded_filename, (long) start, (long) finish); free(encoded_filename); @@ -1520,13 +1724,14 @@ static int slashgrid_read(const char *path, char *buf, (void) fi; int anyerror = 0, thiserror, i, ilast, fd; - char *s, *url, *disk_filename, *encoded_filename; + char *s, *url, *disk_filename, *encoded_filename, *localpath; off_t block_start, block_finish, block_i, len; struct grst_body_text rawbody; struct grst_request request_data; struct tm modified_tm; struct stat statbuf; time_t now; + GRSTgaclPerm perm; struct fuse_context fuse_ctx; memcpy(&fuse_ctx, fuse_get_context(), sizeof(struct fuse_context)); @@ -1534,6 +1739,28 @@ static int slashgrid_read(const char *path, char *buf, if (debugmode) syslog(LOG_DEBUG, "in slashgrid_read size=%ld offset=%ld", (long) size, (long) offset); + if ((local_root != NULL) && (strncmp(path, "/local/", 7) == 0)) + { + asprintf(&localpath, "%s/%s", local_root, &path[7]); + + perm = get_gaclPerm(&fuse_ctx, localpath); + + if (GRSTgaclPermHasRead(perm)) + { + fd = open(localpath, O_RDONLY); + + if (lseek(fd, offset, SEEK_SET) < 0) size = -1; + else size = read(fd, buf, size); + + close(fd); + } + else size = -1; + + free(localpath); + + return size; + } + if ((strncmp(path, "/http/", 6) != 0) && (strncmp(path, "/https/", 7) != 0)) return -ENOENT; @@ -1600,7 +1827,8 @@ static int slashgrid_write(const char *path, const char *buf, struct fuse_file_info *fi) { int anyerror = 0, thiserror, i, fd; - char *s, *url, *p, errorbuffer[CURL_ERROR_SIZE+1] = ""; + char *s, *url, *p, errorbuffer[CURL_ERROR_SIZE+1] = "", *localpath; + GRSTgaclPerm perm; struct grst_read_data read_data; struct grst_request request_data; @@ -1608,6 +1836,32 @@ static int slashgrid_write(const char *path, const char *buf, memcpy(&fuse_ctx, fuse_get_context(), sizeof(struct fuse_context)); + if (debugmode) syslog(LOG_DEBUG, "in slashgrid_write, path=%s, UID=%d\n", + path, fuse_ctx.uid); + + if ((local_root != NULL) && (strncmp(path, "/local/", 7) == 0)) + { + asprintf(&localpath, "%s/%s", local_root, &path[7]); + + perm = get_gaclPerm(&fuse_ctx, localpath); + + if (GRSTgaclPermHasWrite(perm)) + { + fd = open(localpath, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); + + if (lseek(fd, offset, SEEK_SET) < 0) size = -1; + else size = write(fd, buf, size); + + fchown(fd, local_uid, local_gid); + close(fd); + } + else size = -1; + + free(localpath); + + return size; + } + if (strncmp(path, "/http/", 6) == 0) asprintf(&url, "http://%s", &path[6]); else if (strncmp(path, "/https/", 7) == 0) @@ -1794,6 +2048,8 @@ int slashgrid_rmdir(const char *path) int slashgrid_mknod(const char *path, mode_t mode, dev_t dev) { int ret; + + if (debugmode) syslog(LOG_DEBUG, "slashgrid_mknod called for %s", path); ret = slashgrid_write(path, "", 0, 0, NULL); @@ -1826,8 +2082,9 @@ int slashgrid_chmod(const char *path, mode_t mode) int slashgrid_truncate(const char *path, off_t offset) { - int anyerror = 0, thiserror, i, fd; - char *s, *url, *p, errorbuffer[CURL_ERROR_SIZE+1] = ""; + int anyerror = 0, thiserror, i, fd, ret; + char *s, *url, *p, errorbuffer[CURL_ERROR_SIZE+1] = "", *localpath; + GRSTgaclPerm perm; struct grst_read_data read_data; struct fuse_context fuse_ctx; @@ -1835,10 +2092,30 @@ int slashgrid_truncate(const char *path, off_t offset) memcpy(&fuse_ctx, fuse_get_context(), sizeof(struct fuse_context)); + if (debugmode) syslog(LOG_DEBUG, "slashgrid_truncate, for %s (%d)", + path, offset); + if (strncmp(path, "/http/", 6) == 0) asprintf(&url, "http://%s", &path[6]); else if (strncmp(path, "/https/", 7) == 0) asprintf(&url, "https://%s", &path[7]); + else if ((local_root != NULL) && (strncmp(path, "/local/", 7) == 0)) + { + asprintf(&localpath, "%s/%s", local_root, &path[7]); + + perm = get_gaclPerm(&fuse_ctx, localpath); + + if (GRSTgaclPermHasWrite(perm)) + { + ret = truncate(localpath, offset); + free(localpath); + + return (ret == 0) ? 0 : -ENOENT; + } + + free(localpath); + return -EACCES; + } else return -ENOENT; read_data.buf = ""; @@ -1882,7 +2159,12 @@ int slashgrid_truncate(const char *path, off_t offset) int slashgrid_statfs(const char *path, struct statfs *fs) { - return statfs(GRST_SLASH_BLOCKS, fs); + /* statfs() on /local not used in practice, since not mounted separately */ + + if ((strncmp(path, "/local/", 7) == 0) || + (strcmp(path, "/local") == 0)) + return statfs(local_root, fs); + else return statfs(GRST_SLASH_BLOCKS, fs); } void *slashgrid_init(void) @@ -1921,15 +2203,39 @@ static struct fuse_operations slashgrid_oper = { .destroy = slashgrid_destroy }; +void slashgrid_logfunc(char *file, int line, int level, char *fmt, ...) +{ + char *mesg; + va_list ap; + + va_start(ap, fmt); + vasprintf(&mesg, fmt, ap); + va_end(ap); + + syslog(level, "%s(%d) %s", file, line, mesg); + + free(mesg); +} + int main(int argc, char *argv[]) { -#define FUSE_ARGC 4 - char *fuse_argv[FUSE_ARGC] = { "slashgrid", "/grid", "-o", "allow_other" }; - int i, ret; + char *fuse_argv[] = { "slashgrid", "/grid", "-o", "allow_other", + "-s", "-d" }; + int i, ret, fuse_argc = 4; /* by default, ignore the final 2 args */ + struct passwd *pw; + struct rlimit unlimited = { RLIM_INFINITY, RLIM_INFINITY }; for (i=1; i < argc; ++i) { - if (strcmp(argv[i], "--debug") == 0) debugmode = 1; + if (strcmp(argv[i], "--debug") == 0) + { + debugmode = 1; + } + else if (strcmp(argv[i], "--foreground") == 0) + { + debugmode = 1; + fuse_argc = 6; + } else if ((strcmp(argv[i], "--domain") == 0) && (i + 1 < argc)) { sitecast_domain = argv[i+1]; @@ -1941,7 +2247,42 @@ int main(int argc, char *argv[]) sitecast_groups = argv[i+1]; ++i; } - } + else if ((strcmp(argv[i], "--local-root") == 0) && (i + 1 < argc)) + { + local_root = argv[i+1]; + ++i; + } + else if ((strcmp(argv[i], "--local-user") == 0) && (i + 1 < argc)) + { + if ((pw = getpwnam(argv[i+1])) == NULL) + { + fprintf(stderr, "unable to find user %s\n", argv[i+1]); + return 1; + } + + local_uid = pw->pw_uid; + local_gid = pw->pw_gid; + ++i; + } + else if ((strcmp(argv[i], "--gridmapdir") == 0) && (i + 1 < argc)) + { + gridmapdir = argv[i+1]; + ++i; + } + else + { + fprintf(stderr, "argument %s not recognised\n", argv[i]); + return 1; + } + } + + if ((local_root != NULL) && + ((local_uid == 0) || (local_gid == 0))) + { + fprintf(stderr, "if --local-root is given, " + "--local-user must be given too and not be the root user\n"); + return 1; + } openlog("slashgrid", 0, LOG_DAEMON); @@ -1955,7 +2296,17 @@ int main(int argc, char *argv[]) handles[i].last_used = 0; } - ret = fuse_main(FUSE_ARGC, fuse_argv, &slashgrid_oper); + if (debugmode) + { + chdir("/var/tmp"); + setrlimit(RLIMIT_CORE, &unlimited); + } + +// GRSTerrorLogFunc = slashgrid_logfunc; + + GRSTgaclInit(); + + ret = fuse_main(fuse_argc, fuse_argv, &slashgrid_oper); return ret; } diff --git a/org.gridsite.core/src/slashgrid.init b/org.gridsite.core/src/slashgrid.init index 44a12ad..f83b43e 100755 --- a/org.gridsite.core/src/slashgrid.init +++ b/org.gridsite.core/src/slashgrid.init @@ -30,6 +30,7 @@ RETVAL=0 start() { echo -n $"Starting $prog: " modprobe fuse + sleep 1 daemon $slashgrid $OPTIONS RETVAL=$? echo -- 1.8.2.3