chiark / gitweb /
create users.db (but don't do anythin with it). tighter db permissions
authorRichard Kettlewell <rjk@greenend.org.uk>
Tue, 18 Dec 2007 17:39:26 +0000 (17:39 +0000)
committerRichard Kettlewell <rjk@greenend.org.uk>
Tue, 18 Dec 2007 17:39:26 +0000 (17:39 +0000)
server/disorderd.c
server/dump.c
server/trackdb-int.h
server/trackdb.c
server/trackdb.h

index 34d9e23fb2f33d79494323d1171bac22e76c1817..3d77d7329c5af528471eb7070bad6c68553886c8 100644 (file)
@@ -277,7 +277,7 @@ int main(int argc, char **argv) {
       fatal(errno, "error locking %s", lockfile);
   }
   /* initialize database environment */
-  trackdb_init(TRACKDB_NORMAL_RECOVER);
+  trackdb_init(TRACKDB_NORMAL_RECOVER|TRACKDB_MAY_CREATE);
   trackdb_master(ev);
   /* install new config */
   reconfigure(ev, 0);
index 119875f55fee3a8a19ac8eafb928cf0778257126..ec1fc4d29c9e26abeaa7760558b0274404382c7e 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * This file is part of DisOrder.
- * Copyright (C) 2004, 2005 Richard Kettlewell
+ * Copyright (C) 2004, 2005, 2007 Richard Kettlewell
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -29,6 +29,7 @@
 #include <pcre.h>
 #include <unistd.h>
 #include <db.h>
+#include <fcntl.h>
 
 #include "configuration.h"
 #include "syscalls.h"
@@ -140,6 +141,23 @@ static void do_dump(FILE *fp, const char *tag,
     if(trackdb_closecursor(cursor)) { cursor = 0; goto fail; }
     cursor = 0;
     
+    /* dump the users */
+    cursor = trackdb_opencursor(trackdb_usersdb, tid);
+    err = cursor->c_get(cursor, prepare_data(&k), prepare_data(&d),
+                        DB_FIRST);
+    while(err == 0) {
+      if(fputc('U', fp) < 0
+         || urlencode(s, k.data, k.size)
+         || fputc('\n', fp) < 0
+         || urlencode(s, d.data, d.size)
+         || fputc('\n', fp) < 0)
+        fatal(errno, "error writing to %s", tag);
+      err = cursor->c_get(cursor, prepare_data(&k), prepare_data(&d),
+                          DB_NEXT);
+    }
+    if(trackdb_closecursor(cursor)) { cursor = 0; goto fail; }
+    cursor = 0;
+    
     if(tracksdb) {
       cursor = trackdb_opencursor(trackdb_tracksdb, tid);
       err = cursor->c_get(cursor, prepare_data(&k), prepare_data(&d),
@@ -284,6 +302,7 @@ static int undump_from_fp(DB_TXN *tid, FILE *fp, const char *tag) {
   if((err = truncdb(tid, trackdb_globaldb))) return err;
   if((err = truncdb(tid, trackdb_searchdb))) return err;
   if((err = truncdb(tid, trackdb_tagsdb))) return err;
+  if((err = truncdb(tid, trackdb_usersdb))) return err;
   c = getc(fp);
   while(!ferror(fp) && !feof(fp)) {
     switch(c) {
@@ -296,12 +315,22 @@ static int undump_from_fp(DB_TXN *tid, FILE *fp, const char *tag) {
       return 0;
     case 'P':
     case 'G':
-      if(c == 'P') {
+    case 'U':
+      switch(c) {
+      case 'P':
        which_db = trackdb_prefsdb;
        which_name = "prefs.db";
-      } else {
+       break;
+      case 'G':
        which_db = trackdb_globaldb;
        which_name = "global.db";
+       break;
+      case 'U':
+       which_db = trackdb_usersdb;
+       which_name = "users.db";
+       break;
+      default:
+       abort();
       }
       if(undump_dbt(fp, tag, prepare_data(&k))
          || undump_dbt(fp, tag, prepare_data(&d)))
@@ -415,7 +444,7 @@ fail:
 
 int main(int argc, char **argv) {
   int n, dump = 0, undump = 0, recover = TRACKDB_NO_RECOVER, recompute = 0;
-  int tracksdb = 0, searchdb = 0, remove_pathless = 0;
+  int tracksdb = 0, searchdb = 0, remove_pathless = 0, fd;
   const char *path;
   char *tmp;
   FILE *fp;
@@ -454,12 +483,16 @@ int main(int argc, char **argv) {
     path = argv[optind];
   }
   if(config_read(0)) fatal(0, "cannot read configuration");
-  trackdb_init(recover);
+  trackdb_init(recover|TRACKDB_MAY_CREATE);
   trackdb_open(TRACKDB_NO_UPGRADE);
   if(dump) {
-    /* we write to a temporary file and rename into place */
+    /* We write to a temporary file and rename into place.  We make
+     * sure the permissions are tight from the start. */
     byte_xasprintf(&tmp, "%s.%lx.tmp", path, (unsigned long)getpid());
-    if(!(fp = fopen(tmp, "w"))) fatal(errno, "error opening %s", tmp);
+    if((fd = open(tmp, O_CREAT|O_TRUNC|O_WRONLY, 0600)) < 0)
+      fatal(errno, "error opening %s", tmp);
+    if(!(fp = fdopen(fd, "w")))
+      fatal(errno, "fdopen on %s", tmp);
     do_dump(fp, tmp, tracksdb, searchdb);
     if(fclose(fp) < 0) fatal(errno, "error closing %s", tmp);
     if(rename(tmp, path) < 0)
index 02b07b9a9e1ea86685fa927cb8a1b1e4d39f3f04..441a056f397da61cca98b9699c79cd94212fe423 100644 (file)
@@ -29,6 +29,7 @@ extern DB *trackdb_searchdb;
 extern DB *trackdb_tagsdb;
 extern DB *trackdb_noticeddb;
 extern DB *trackdb_globaldb;
+extern DB *trackdb_usersdb;
 
 DBC *trackdb_opencursor(DB *db, DB_TXN *tid);
 /* open a transaction */
index d1878c01fa4f0ac3b98330f255b71cf3176271ab..4c00e2826e582b988213bb1cc387f0f8536b8521 100644 (file)
@@ -37,6 +37,8 @@
 #include <time.h>
 #include <arpa/inet.h>
 #include <sys/wait.h>
+#include <dirent.h>
+#include <sys/stat.h>
 
 #include "event.h"
 #include "mem.h"
@@ -137,6 +139,14 @@ DB *trackdb_globaldb;                   /* global preferences */
  * - Data cannot be reconstructed (but isn't THAT important)
  */
 DB *trackdb_noticeddb;                   /* when track noticed */
+
+/** @brief The user database
+ * - Keys are usernames
+ * - Values are encoded key-value pairs
+ * - Data is user data and cannot be reconstructed
+ */
+DB *trackdb_usersdb;
+
 static pid_t db_deadlock_pid = -1;      /* deadlock manager PID */
 static pid_t rescan_pid = -1;           /* rescanner PID */
 static int initialized, opened;         /* state */
@@ -158,6 +168,7 @@ static int compare(DB attribute((unused)) *db_,
  * - @ref TRACKDB_NO_RECOVER
  * - @ref TRACKDB_NORMAL_RECOVER
  * - @ref TRACKDB_FATAL_RECOVER
+ * - @ref TRACKDB_MAY_CREATE
  */
 void trackdb_init(int flags) {
   int err;
@@ -173,6 +184,36 @@ void trackdb_init(int flags) {
     home = config->home;
   }
 
+  if(flags & TRACKDB_MAY_CREATE) {
+    DIR *dp;
+    struct dirent *de;
+    struct stat st;
+    char *p;
+
+    /* create home directory if it does not exist */
+    mkdir(config->home, 0755);
+    /* Remove world/group permissions on any regular files already in the
+     * database directory.  Actually we don't care about all of them but it's
+     * easier to just do the lot.  This can be revisited if it's a serious
+     * practical inconvenience for anyone.
+     *
+     * The socket, not being a regular file, is excepted.
+     */
+    if(!(dp = opendir(config->home)))
+      fatal(errno, "error reading %s", config->home);
+    while((de = readdir(dp))) {
+      byte_xasprintf(&p, "%s/%s", config->home, de->d_name);
+      if(lstat(p, &st) == 0
+         && S_ISREG(st.st_mode)
+         && (st.st_mode & 077)) {
+        if(chmod(p, st.st_mode & (~(mode_t)077) & 07777) < 0)
+          fatal(errno, "cannot chmod %s", p);
+      }
+      xfree(p);
+    }
+    closedir(dp);
+  }
+
   /* create environment */
   if((err = db_env_create(&trackdb_env, 0))) fatal(0, "db_env_create: %s",
                                                    db_strerror(err));
@@ -190,7 +231,7 @@ void trackdb_init(int flags) {
                               |DB_INIT_TXN
                               |DB_CREATE
                               |recover_type[recover],
-                              0666)))
+                              0600)))
     fatal(0, "trackdb_env->open %s: %s", config->home, db_strerror(err));
   trackdb_env->set_errpfx(trackdb_env, "DB");
   trackdb_env->set_errfile(trackdb_env, stderr);
@@ -383,6 +424,8 @@ void trackdb_open(int flags) {
   trackdb_globaldb = open_db("global.db", 0, DB_HASH, DB_CREATE, 0666);
   trackdb_noticeddb = open_db("noticed.db",
                              DB_DUPSORT, DB_BTREE, DB_CREATE, 0666);
+  trackdb_usersdb = open_db("users.db",
+                            0, DB_HASH, DB_CREATE, 0600);
   if(!trackdb_existing_database) {
     /* Stash the database version */
     char buf[32];
@@ -413,6 +456,8 @@ void trackdb_close(void) {
     fatal(0, "error closing global.db: %s", db_strerror(err));
   if((err = trackdb_noticeddb->close(trackdb_noticeddb, 0)))
     fatal(0, "error closing noticed.db: %s", db_strerror(err));
+  if((err = trackdb_usersdb->close(trackdb_usersdb, 0)))
+    fatal(0, "error closing users.db: %s", db_strerror(err));
   trackdb_tracksdb = trackdb_searchdb = trackdb_prefsdb = 0;
   trackdb_tagsdb = trackdb_globaldb = 0;
   D(("closed databases"));
index c6a5897577b2f59786001c66425d94e394dddb6f..d9d7ceb020aca517f5e46c784a39e929f1d57f45 100644 (file)
@@ -53,6 +53,9 @@ extern unsigned long cache_files_hits, cache_files_misses;
 /** @brief Mask of upgrade bits (trackdb_open()) */
 #define TRACKDB_UPGRADE_MASK 0x000C
 
+/** @brief May create database environment (trackdb_init()) */
+#define TRACKDB_MAY_CREATE 0x0010
+
 void trackdb_init(int flags);
 void trackdb_deinit(void);
 /* close/close environment */