chiark / gitweb /
Get permissions right on restored databases (issue #56).
authorRichard Kettlewell <rjk@greenend.org.uk>
Sun, 13 Feb 2011 14:45:02 +0000 (14:45 +0000)
committerRichard Kettlewell <rjk@greenend.org.uk>
Sun, 13 Feb 2011 14:45:02 +0000 (14:45 +0000)
doc/disorder-dump.8.in
lib/user.c
server/dump.c

index 3f0b6f0c941fa655a627f322177211eb22d56021..d29562f94ad722011eeba46d341006011b75bfc3 100644 (file)
@@ -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
index 100da166ab62c93ff1641623d19bb208ea6b782f..d6b47aaaea450e86433f98a0cc54414f7d283be2 100644 (file)
@@ -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)
index fb0741503808e261ad532481ba32c08a23564017..74f1c466360a62fccfffc0310b4eb04e053ac313 100644 (file)
  */
 #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) {