chiark / gitweb /
default_rights directive
authorRichard Kettlewell <rjk@greenend.org.uk>
Fri, 21 Dec 2007 16:23:27 +0000 (16:23 +0000)
committerRichard Kettlewell <rjk@greenend.org.uk>
Fri, 21 Dec 2007 16:23:27 +0000 (16:23 +0000)
README.upgrades
doc/disorder_config.5.in
lib/configuration.c
lib/configuration.h
lib/rights.c
lib/rights.h
lib/trackdb.c
server/server.c
tests/dtest.py
tests/dump.py
tests/user-upgrade.py

index 5bea1cdaf642f9cb191bee6577841ebb6ab00cab..b47022e5510c040d2f0797e4215a0d61b2d4450d 100644 (file)
@@ -21,9 +21,16 @@ all 1.1.x versions.
 Users are now stored in the database rather than in 'allow' directives in a
 private configuration file.  'allow' is still understood in this version, but
 is only used to populate the database on startup.  After the first (successful)
-run of the server the remaining 'allow' directives can be deleted.
+run of the server the remaining 'allow' directives should be deleted.
 
-'allow' will stop working entirely in a future version.
+'restrict' and 'trust' are replaced by a system of per-user rights.  The
+default user rights are based on the 'restrict' setting, and the rights of
+users created frow 'allow' directives preserve the meaning of 'trust', but
+after the first run you should remove these directives and (optionally) add a
+'default_rights' directive.
+
+'allow', 'restrict' and 'trust' will stop working entirely in a future version
+but for now they will generate harmless error messages.
 
 * 1.4/1.5 -> 2.0
 
index a90d029a737f8b98ea141d434aba89db2e62b837..25bc90471060c687adcb92a226cb478a2583f253 100644 (file)
@@ -300,6 +300,15 @@ Examples might be \fBiso-8859-1\fR or \fButf-8\fR.
 \fIROOT\fR is the root in the filesystem of the filenames and is
 passed to the plugin module.
 .TP
+.B default_rights \fIRIGHTS\fR
+Defines the set of rights given to new users.  The argument is a
+comma-separated list of rights.  For the possible values see
+.B "Users And Access Control"
+above.
+.IP
+The default is to allow everything except \fBadmin\fR and \fBregister\fR
+(modified in legacy configurations by the obsolete \fBrestrict\fR directive).
+.TP
 .B device \fINAME\fR
 ALSA device to play raw-format audio.  Default is \fBdefault\fR, i.e. to use
 the whatever the ALSA configured default is.
index 3ddfea16e0cd6b4b5d99988fd445314ad9d8fa42..0f1dc96c016b4ffb545a5b79a0d47e9ab2385f19 100644 (file)
@@ -39,6 +39,7 @@
 #include <pcre.h>
 #include <signal.h>
 
+#include "rights.h"
 #include "configuration.h"
 #include "mem.h"
 #include "log.h"
@@ -489,6 +490,25 @@ static int set_backend(const struct config_state *cs,
   return 0;
 }
 
+static int set_rights(const struct config_state *cs,
+                     const struct conf *whoami,
+                     int nvec, char **vec) {
+  rights_type r;
+
+  if(nvec != 1) {
+    error(0, "%s:%d: '%s' requires one argument",
+         cs->path, cs->line, whoami->name);
+    return -1;
+  }
+  if(parse_rights(vec[0], &r)) {
+    error(0, "%s:%d: invalid rights string '%s'",
+         cs->path, cs->line, vec[0]);
+    return -1;
+  }
+  *ADDRESS(cs->config, rights_type) = r;
+  return 0;
+}
+
 /* free functions */
 
 static void free_none(struct config attribute((unused)) *c,
@@ -587,6 +607,7 @@ static const struct conftype
   type_restrict = { set_restrict, free_none },
   type_namepart = { set_namepart, free_namepartlist },
   type_transform = { set_transform, free_transformlist },
+  type_rights = { set_rights, free_none },
   type_backend = { set_backend, free_none };
 
 /* specific validation routine */
@@ -902,6 +923,7 @@ static const struct conf conf[] = {
   { C(cookie_login_lifetime),  &type_integer,    validate_positive },
   { C(cookie_key_lifetime),  &type_integer,      validate_positive },
   { C(dbversion),        &type_integer,          validate_positive },
+  { C(default_rights),   &type_rights,           validate_any },
   { C(device),           &type_string,           validate_any },
   { C(gap),              &type_integer,          validate_non_negative },
   { C(history),          &type_integer,          validate_positive },
@@ -1167,7 +1189,26 @@ static void config_postdefaults(struct config *c,
     c->sample_format.bits = 16;
     c->sample_format.endian = ENDIAN_NATIVE;
     break; 
- }
+  }
+  if(!c->default_rights) {
+    rights_type r = RIGHTS__MASK & ~(RIGHT_ADMIN|RIGHT_REGISTER
+                                    |RIGHT_MOVE__MASK
+                                    |RIGHT_SCRATCH__MASK
+                                    |RIGHT_REMOVE__MASK);
+    /* The idea is to approximate the meaning of the old 'restrict' directive
+     * in the default rights if they are not overridden. */
+    if(c->restrictions & RESTRICT_SCRATCH)
+      r |= RIGHT_SCRATCH_MINE|RIGHT_SCRATCH_RANDOM;
+    else
+      r |= RIGHT_SCRATCH_ANY;
+    if(!(c->restrictions & RESTRICT_MOVE))
+      r |= RIGHT_MOVE_ANY;
+    if(c->restrictions & RESTRICT_REMOVE)
+      r |= RIGHT_REMOVE_MINE;
+    else
+      r |= RIGHT_REMOVE_ANY;
+    c->default_rights = r;
+  }
 }
 
 /** @brief (Re-)read the config file
@@ -1210,6 +1251,13 @@ int config_read(int server) {
   config_postdefaults(c, server);
   /* everything is good so we shall use the new config */
   config_free(config);
+  /* warn about obsolete directives */
+  if(c->restrictions)
+    error(0, "'restrict' will be removed in a future version");
+  if(c->allow.n)
+    error(0, "'allow' will be removed in a future version");
+  if(c->trust.n)
+    error(0, "'trust' will be removed in a future version");
   config = c;
   return 0;
 }
index eb028b05105c183694bb2ce0c5895a032111b106..f08b866e26fb46166a03ab374ebc84f7a10646ce 100644 (file)
@@ -25,6 +25,7 @@
 #define CONFIGURATION_H
 
 #include "speaker-protocol.h"
+#include "rights.h"
 
 struct real_pcre;
 
@@ -251,6 +252,9 @@ struct config {
 
   /** @brief Signing key lifetime in seconds */
   long cookie_key_lifetime;
+
+  /** @brief Default rights for a new user */
+  rights_type default_rights;
   
   /* derived values: */
   int nparts;                          /* number of distinct name parts */
index 5a9935bac1f102715305e77de4833073f650b633..d03eae10ba9dc3d6b2d838d470cd32b98c47edba 100644 (file)
@@ -75,28 +75,6 @@ char *rights_string(rights_type r) {
   return d->vec;
 }
 
-/** @brief Compute default rights for a new user
- * @return Default rights value
- */
-rights_type default_rights(void) {
-  /* TODO get rights from config */
-  rights_type r = RIGHTS__MASK & ~(RIGHT_ADMIN|RIGHT_REGISTER
-                                   |RIGHT_MOVE__MASK
-                                   |RIGHT_SCRATCH__MASK
-                                   |RIGHT_REMOVE__MASK);
-  if(config->restrictions & RESTRICT_SCRATCH)
-    r |= RIGHT_SCRATCH_MINE|RIGHT_SCRATCH_RANDOM;
-  else
-    r |= RIGHT_SCRATCH_ANY;
-  if(!(config->restrictions & RESTRICT_MOVE))
-    r |= RIGHT_MOVE_ANY;
-  if(config->restrictions & RESTRICT_REMOVE)
-    r |= RIGHT_REMOVE_MINE;
-  else
-    r |= RIGHT_REMOVE_ANY;
-  return r;
-}
-
 /** @brief Parse a rights list
  * @param s Rights list in string form
  * @param rp Where to store rights, or NULL to just validate
index 61927722fb502e4ba28e6d5d516d5fc523cb57ed..fb2d6254f4add7f3f8a6d200d1a45541e33b7c0e 100644 (file)
 /** @brief Unsigned type big enough for rights */
 typedef uint32_t rights_type;
 
-rights_type default_rights(void);
 char *rights_string(rights_type r);
 int parse_rights(const char *s, rights_type *rp);
 
index 2aed9a46c5ee8dd352f3a159146401a2f2588515..d4e7f3052ba82739a799fb399c40276176bf25a9 100644 (file)
@@ -2455,9 +2455,9 @@ static int one_old_user(const char *user, const char *password,
   if(!strcmp(user, "root"))
     rights = "all";
   else if(trusted(user))
-    rights = rights_string(default_rights()|RIGHT_ADMIN);
+    rights = rights_string(config->default_rights|RIGHT_ADMIN|RIGHT_RESCAN);
   else
-    rights = rights_string(default_rights());
+    rights = rights_string(config->default_rights);
   return create_user(user, password, rights, 0/*email*/, tid, DB_NOOVERWRITE);
 }
 
index 7c0d3b39cd6908f9e7320200ef363d2e080dc135..807a2766cd882f57d2efff6e0f96f1e5a6a65ded 100644 (file)
@@ -1077,7 +1077,7 @@ static int c_revoke(struct conn *c,
 static int c_adduser(struct conn *c,
                     char **vec,
                     int attribute((unused)) nvec) {
-  if(trackdb_adduser(vec[0], vec[1], default_rights(), 0))
+  if(trackdb_adduser(vec[0], vec[1], config->default_rights, 0))
     sink_writes(ev_writer_sink(c->w), "550 Cannot create user\n");
   else
     sink_writes(ev_writer_sink(c->w), "250 User created\n");
index d4e3472b54693613cfa505e13efb1286591c100f..8262a036f685be1ab483b01c1005290707192711 100644 (file)
@@ -180,7 +180,6 @@ stopword 21 22 23 24 25 26 27 28 29 30
 stopword the a an and to too in on of we i am as im for is
 username fred
 password fredpass
-trust fred root
 plugins
 plugins %s/plugins
 plugins %s/plugins/.libs
index 84018404802b493a6a672ad3aab40d13125c08d4..507199a10e33c4287807b91b4a7f08dc66ea8dda 100755 (executable)
@@ -55,7 +55,6 @@ def test():
                          "--dump", dump])
     print " changing track pref"
     c.set(track, "foo", "after dump");
-    print c.get(track, "foo")
     assert c.get(track, "foo") == "after dump", "checking track foo=after dump"
     print " changing global pref"
     c.setglobal("foo", "after dump");
index 61417148a345e36067d6684c215b53edfeb4979f..3bab5816aab1dd79c70a76e2788110819157c54c 100755 (executable)
@@ -25,6 +25,7 @@ def test():
     print " testing upgrade from old versions"
     open("%s/config" % dtest.testroot, "a").write(
       """allow fred fredpass
+trust fred
 """)
     dtest.start_daemon()
     print " checking can log in after upgrade"