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
 The default is
 .IR /etc/disorder/config .
 .TP
+.B \-\-no\-setuid
+Do not change UID.
+.TP
 .B \-\-debug\fR
 Enable debugging.
 .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.
 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
 .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()) {
     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)
       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"
 
  */
 #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' },
 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' },
   { "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 }
 };
 
   { 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"
          "  --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);
          "  --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 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();
   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");
     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 '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");
     }
   }
     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) {
     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");
     /* 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) {
     do_undump(fp, path, remove_pathless);
     xfclose(fp);
   } else if(recompute) {