From a745dd436a29ef2ca2a1a83582e3cfd53b24dcc5 Mon Sep 17 00:00:00 2001 Message-Id: From: Mark Wooding Date: Tue, 18 Dec 2007 17:39:26 +0000 Subject: [PATCH] create users.db (but don't do anythin with it). tighter db permissions Organization: Straylight/Edgeware From: Richard Kettlewell --- server/disorderd.c | 2 +- server/dump.c | 47 +++++++++++++++++++++++++++++++++++++------- server/trackdb-int.h | 1 + server/trackdb.c | 47 +++++++++++++++++++++++++++++++++++++++++++- server/trackdb.h | 3 +++ 5 files changed, 91 insertions(+), 9 deletions(-) diff --git a/server/disorderd.c b/server/disorderd.c index 34d9e23..3d77d73 100644 --- a/server/disorderd.c +++ b/server/disorderd.c @@ -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); diff --git a/server/dump.c b/server/dump.c index 119875f..ec1fc4d 100644 --- a/server/dump.c +++ b/server/dump.c @@ -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 #include #include +#include #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) diff --git a/server/trackdb-int.h b/server/trackdb-int.h index 02b07b9..441a056 100644 --- a/server/trackdb-int.h +++ b/server/trackdb-int.h @@ -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 */ diff --git a/server/trackdb.c b/server/trackdb.c index d1878c0..4c00e28 100644 --- a/server/trackdb.c +++ b/server/trackdb.c @@ -37,6 +37,8 @@ #include #include #include +#include +#include #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")); diff --git a/server/trackdb.h b/server/trackdb.h index c6a5897..d9d7ceb 100644 --- a/server/trackdb.h +++ b/server/trackdb.h @@ -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 */ -- [mdw]