From: Richard Kettlewell Date: Sun, 13 Feb 2011 14:45:02 +0000 (+0000) Subject: Get permissions right on restored databases (issue #56). X-Git-Tag: branchpoint-5.1~58 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/disorder/commitdiff_plain/e5af9e8ddd1ec06cceee9bafeb164da081912c80 Get permissions right on restored databases (issue #56). --- diff --git a/doc/disorder-dump.8.in b/doc/disorder-dump.8.in index 3f0b6f0..d29562f 100644 --- a/doc/disorder-dump.8.in +++ b/doc/disorder-dump.8.in @@ -60,6 +60,9 @@ Set the configuration file. The default is .IR /etc/disorder/config . .TP +.B \-\-no\-setuid +Do not change UID. +.TP .B \-\-debug\fR Enable debugging. .TP @@ -99,7 +102,11 @@ No other process should be accessing the database at the time. DisOrder does not currently support catastrophic recovery. .PP This program requires write access to DisOrder's databases. -Ideally therefore it should be run as the same user as the server or as root. +Therefore it should be run as the same user as the server or as root. +.PP +If a restore is done as root then it will automatically change to the +server user, so that the new files end up with the right ownership. +This can be suppressed with the \fB\-\-no\-setuid\fR option. .SH FILES .TP .I pkgconfdir/config diff --git a/lib/user.c b/lib/user.c index 100da16..d6b47aa 100644 --- a/lib/user.c +++ b/lib/user.c @@ -44,6 +44,9 @@ void become_mortal(void) { if(!(pw = getpwnam(config->user))) disorder_fatal(0, "cannot find user %s", config->user); if(pw->pw_uid != getuid()) { + disorder_info("becoming user %u group %u", + (unsigned)pw->pw_uid, + (unsigned)pw->pw_gid); if(initgroups(config->user, pw->pw_gid)) disorder_fatal(errno, "error calling initgroups"); if(setgid(pw->pw_gid) < 0) diff --git a/server/dump.c b/server/dump.c index fb07415..74f1c46 100644 --- a/server/dump.c +++ b/server/dump.c @@ -20,6 +20,10 @@ */ #include "disorder-server.h" +enum { + NO_SETUID = UCHAR_MAX + 1, +}; + static const struct option options[] = { { "help", no_argument, 0, 'h' }, { "version", no_argument, 0, 'V' }, @@ -31,6 +35,7 @@ static const struct option options[] = { { "recover-fatal", no_argument, 0, 'R' }, { "recompute-aliases", no_argument, 0, 'a' }, { "remove-pathless", no_argument, 0, 'P' }, + { "no-setuid", no_argument, 0, NO_SETUID }, { 0, 0, 0, 0 } }; @@ -48,6 +53,7 @@ static void help(void) { " --recover, -r Run database recovery\n" " --recompute-aliases, -a Recompute aliases\n" " --remove-pathless, -P Remove pathless tracks\n" + " --no-setuid Do not become jukebox user\n" " --debug Debug mode\n"); xfclose(stdout); exit(0); @@ -365,12 +371,13 @@ fail: int main(int argc, char **argv) { int n, dump = 0, undump = 0, recover = TRACKDB_NO_RECOVER, recompute = 0; int remove_pathless = 0, fd; + int changeuid = !getuid(); const char *path; char *tmp; FILE *fp; mem_init(); - while((n = getopt_long(argc, argv, "hVc:dDurRaP", options, 0)) >= 0) { + while((n = getopt_long(argc, argv, "hVc:dDurRaPR", options, 0)) >= 0) { switch(n) { case 'h': help(); case 'V': version("disorder-dump"); @@ -382,6 +389,7 @@ int main(int argc, char **argv) { case 'R': recover = TRACKDB_FATAL_RECOVER; break; case 'a': recompute = 1; break; case 'P': remove_pathless = 1; break; + case NO_SETUID: changeuid = 0; break; default: disorder_fatal(0, "invalid option"); } } @@ -415,12 +423,15 @@ int main(int argc, char **argv) { if(rename(tmp, path) < 0) disorder_fatal(errno, "error renaming %s to %s", tmp, path); } else if(undump) { + /* Open the dump file before changing UID */ + if(!(fp = fopen(path, "r"))) + disorder_fatal(errno, "error opening %s", path); + if(changeuid) + become_mortal(); /* the databases or logfiles might end up with wrong permissions * if new ones are created */ if(getuid() == 0) disorder_info("you might need to chown database files"); - if(!(fp = fopen(path, "r"))) - disorder_fatal(errno, "error opening %s", path); do_undump(fp, path, remove_pathless); xfclose(fp); } else if(recompute) {