I am using Ferret for a Rails app in which Rails runs as one user but I have 
other processes that run as a different user that modify the ferret index.  
This is done in large part to mitigate the damage if a major exploit is found 
in Rails again.

The problem is Ferret creates all its index files with rw for the user only.  
I have included a small patch that changes Ferret to create these files with 
the rw permissions for the group based on the parent directory permissions.

Could this patch or similar find its way into the official releases?

A read only file store mode would also be usefull but not essential.

Thanks,
Quinn

diff -puN ext-orig/store.h ext/store.h
--- ext-orig/store.h    2006-09-23 22:11:22.000000000 -0600
+++ ext/store.h 2006-10-21 14:36:50.000000000 -0600
@@ -176,6 +176,8 @@ struct Store
         CompoundStore *cmpd;    /* for compound_store only */
     } dir;

+    mode_t file_mode;
+
     HashSet *locks;

     /**
diff -puN ext-orig/fs_store.c ext/fs_store.c
--- ext-orig/fs_store.c 2006-09-23 22:11:22.000000000 -0600
+++ ext/fs_store.c      2006-10-21 15:06:47.000000000 -0600
@@ -51,7 +51,7 @@ static void fs_touch(Store *store, char
     int f;
     char path[MAX_FILE_PATH];
     join_path(path, store->dir.path, filename);
-    if ((f = creat(path, S_IRUSR | S_IWUSR)) == 0) {
+    if ((f = creat(path, store->file_mode)) == 0) {
         RAISE(IO_ERROR, "couldn't create file %s: <%s>", path,
               strerror(errno));
     }
@@ -252,7 +252,7 @@ static OutStream *fs_new_output(Store *s
 {
     char path[MAX_FILE_PATH];
     int fd = open(join_path(path, store->dir.path, filename),
-                  O_WRONLY | O_CREAT | O_BINARY, S_IRUSR | S_IWUSR);
+                  O_WRONLY | O_CREAT | O_BINARY, store->file_mode);
     OutStream *os;
     if (fd < 0) {
         RAISE(IO_ERROR, "couldn't create OutStream %s: <%s>",
@@ -431,9 +431,19 @@ static void fs_close_i(Store *store)

 static Store *fs_store_new(const char *pathname)
 {
+  struct stat stt;
     Store *new_store = store_new();

     new_store->dir.path      = estrdup(pathname);
+
+    new_store->file_mode = S_IRUSR | S_IWUSR;
+    if (!stat(new_store->dir.path, &stt) &&
+       stt.st_gid == getgid()) {
+      if (stt.st_mode & S_IWGRP)
+       umask(S_IWOTH);
+      new_store->file_mode |= stt.st_mode & (S_IRGRP | S_IWGRP);
+    }
+
     new_store->touch         = &fs_touch;
     new_store->exists        = &fs_exists;
     new_store->remove        = &fs_remove;
_______________________________________________
Ferret-talk mailing list
Ferret-talk@rubyforge.org
http://rubyforge.org/mailman/listinfo/ferret-talk

Reply via email to