chiark / gitweb /
automatically create the home directory on startup
authorRichard Kettlewell <rjk@greenend.org.uk>
Wed, 17 Oct 2007 19:31:37 +0000 (20:31 +0100)
committerRichard Kettlewell <rjk@greenend.org.uk>
Wed, 17 Oct 2007 19:31:37 +0000 (20:31 +0100)
README
doc/disorder_config.5.in
lib/configuration.c
lib/user.c
lib/user.h
server/disorderd.c

diff --git a/README b/README
index 5be87163166ca66028d7c1f85ea6feecf378a2ac..350d7a274a5accb57417eca6fb9a9a11994c09d6 100644 (file)
--- a/README
+++ b/README
@@ -146,16 +146,7 @@ NOTE: If you are upgrading from an earlier version, see README.upgrades.
    suitable; install it in /etc/init.d, adapting it as necessary, and make
    appropriate links from /etc/rc[0-6].d.
 
-7. Make sure the state directory (/var/disorder or /usr/local/var/disorder or
-   as determined by configure) exists and is writable by the jukebox user.
-
-     mkdir -m 755 /var/disorder
-     chown disorder:root /var/disorder
-
-   If you want to use some other directory you must put use the 'home' command
-   in the configuration file.
-
-8. Start the server.
+7. Start the server.
 
    On Linux systems with sysv-style init:
 
@@ -166,35 +157,35 @@ NOTE: If you are upgrading from an earlier version, see README.upgrades.
    start up correctly there should be an error message.  Correct the problem
    and try again.
 
-9. After a minute it should start to play something.  Try scratching it, as any
+8. After a minute it should start to play something.  Try scratching it, as any
    of the users you set up in step 5:
 
      disorder scratch
 
    The track should stop playing, and (if you set any up) a scratch sound play.
 
-10. Add any other users you want to config.private.  Each user's password
-    should be stored in a file in their home directory, ~/.disorder/passwd,
-    which should be readable only by them, and should take the form of a single
-    line:
+9. Add any other users you want to config.private.  Each user's password
+   should be stored in a file in their home directory, ~/.disorder/passwd,
+   which should be readable only by them, and should take the form of a single
+   line:
 
-      password MYPASSWORD
+     password MYPASSWORD
 
-    (root doesn't need this as the client can read it out of config.private
-    when running as root.)
+   (root doesn't need this as the client can read it out of config.private
+   when running as root.)
 
-    Note that the server must be reloaded (e.g. by 'disorder reconfigure')
-    when new users are added.
+   Note that the server must be reloaded (e.g. by 'disorder reconfigure')
+   when new users are added.
 
-    Alternatively the administrator can create /etc/disorder/config.USERNAME
-    containing the same thing as above.  It can either be owned by the user and
-    mode 400, or owned by root and the user's group (if you have per-user
-    groups) and mode 440.
+   Alternatively the administrator can create /etc/disorder/config.USERNAME
+   containing the same thing as above.  It can either be owned by the user and
+   mode 400, or owned by root and the user's group (if you have per-user
+   groups) and mode 440.
 
-    You can use 'disorder authorize' to automatically pick passwords and
-    create these files.
+   You can use 'disorder authorize' to automatically pick passwords and
+   create these files.
 
-11. Optionally source completion.bash from /etc/profile or similar, for
+10. Optionally source completion.bash from /etc/profile or similar, for
     example:
 
       . /usr/local/share/disorder/completion.bash
index 26b1efc5841eb48e150e374a775501c4c4a0f46b..aeaef98cd9fbf377490f6e0fb6eb8808daa1375f 100644 (file)
@@ -117,6 +117,7 @@ start up without a valid config file.)
 .B home \fIDIRECTORY\fR
 The home directory for state files.  Defaults to
 .IR pkgstatedir .
+The server will create this directory on startup if it does not exist.
 .TP
 .B plugin \fIPATH\fR
 Adds a directory to the plugin path.  (This is also used by the web
index a506ee948fe8439167324c928017c341aca36d93..35573c5c15dc6d03c26248315cc509132f21facb 100644 (file)
@@ -593,6 +593,19 @@ static const struct conftype
   }                                                            \
 } while(0)
 
+static int validate_isabspath(const struct config_state *cs,
+                             int nvec, char **vec) {
+  int n;
+
+  for(n = 0; n < nvec; ++n)
+    if(vec[n][0] != '/') {
+      error(errno, "%s:%d: %s: not an absolute path", 
+           cs->path, cs->line, vec[n]);
+      return -1;
+    }
+  return 0;
+}
+
 static int validate_isdir(const struct config_state *cs,
                          int nvec, char **vec) {
   VALIDATE_FILE(S_ISDIR, "directory");
@@ -863,7 +876,7 @@ static const struct conf conf[] = {
   { C(device),           &type_string,           validate_any },
   { C(gap),              &type_integer,          validate_non_negative },
   { C(history),          &type_integer,          validate_positive },
-  { C(home),             &type_string,           validate_isdir },
+  { C(home),             &type_string,           validate_isabspath },
   { C(listen),           &type_stringlist,       validate_port },
   { C(lock),             &type_boolean,          validate_any },
   { C(mixer),            &type_string,           validate_ischr },
index 2616de3494f97b2ca6f0a3b50e7a69d02b4eb44a..ec01a339bc6a7259294b07d9b98d8d51ce426672 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * This file is part of DisOrder
- * Copyright (C) 2005 Richard Kettlewell
+ * Copyright (C) 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
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  * USA
  */
+/** @file lib/user.c
+ * @brief Jukebox user management
+ */
 
 #include <config.h>
 #include "types.h"
 
 #include <sys/types.h>
+#include <sys/stat.h>
 #include <errno.h>
 #include <pwd.h>
 #include <grp.h>
 #include "user.h"
 #include "log.h"
 #include "configuration.h"
+#include "mem.h"
 
+/** @brief Become the jukebox user
+ *
+ * If a jukebox user is configured then becomes that user.
+ */
 void become_mortal(void) {
   struct passwd *pw;
   
@@ -54,6 +63,41 @@ void become_mortal(void) {
   }
 }
 
+/** @brief Create the jukebox state directory
+ *
+ * If the home directory does not exist then creates it and assigns
+ * it suitable permissions.
+ */
+void make_home(void) {
+  struct stat sb;
+  struct passwd *pw;
+  char *home, *p;
+  
+  if(stat(config->home, &sb) < 0) {
+    /* create parent directories */
+    home = xstrdup(config->home);
+    p = home;
+    while(*p) {
+      if(*p == '/' && p > home) {
+        *p = 0;
+        mkdir(home, 0755);
+        *p = '/';
+      }
+      ++p;
+    }
+    /* create the directory itself */
+    if(mkdir(config->home, 02755) < 0)
+      fatal(errno, "error creating %s", config->home);
+    /* make sure it has the right ownership */
+    if(config->user) {
+      if(!(pw = getpwnam(config->user)))
+        fatal(0, "cannot find user %s", config->user);
+      if(chown(config->home, pw->pw_uid, pw->pw_gid) < 0)
+        fatal(errno, "error chowning %s", config->home);
+    }
+  }
+}
+
 /*
 Local Variables:
 c-basic-offset:2
index be28a5146cf4c2d45f77ad5edd05d987745beaa8..8996032e55065c1c63327f408743d5de5073711b 100644 (file)
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  * USA
  */
+/** @file lib/user.h
+ * @brief Jukebox user management
+ */
 
 #ifndef USER_H
 #define USER_H
 
 void become_mortal(void);
+void make_home(void);
 
 #endif /* USER_H */
 
index f4a1a627176bce3f219ecf65b40a8d49e799f2d2..fb31087ba94ef4f1f8f8ef46df078bbeaa1b0e5a 100644 (file)
@@ -246,6 +246,8 @@ int main(int argc, char **argv) {
   /* read config */
   if(config_read(1))
     fatal(0, "cannot read configuration");
+  /* make sure the home directory exists and has suitable permissions */
+  make_home();
   /* Start the speaker process (as root! - so it can choose its nice value) */
   speaker_setup(ev);
   /* set server nice value _after_ starting the speaker, so that they