summary refs log tree commit diff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/config/power-management.nix30
-rw-r--r--modules/misc/ids.nix44
-rw-r--r--modules/programs/ssh.nix9
-rw-r--r--modules/programs/virtualbox.nix2
-rw-r--r--modules/rename.nix2
-rw-r--r--modules/services/amqp/activemq/default.nix27
-rw-r--r--modules/services/amqp/rabbitmq.nix13
-rw-r--r--modules/services/backup/almir.nix3
-rw-r--r--modules/services/backup/bacula.nix3
-rw-r--r--modules/services/databases/mysql.nix11
-rw-r--r--modules/services/databases/mysql55.nix11
-rw-r--r--modules/services/databases/postgresql.nix7
-rw-r--r--modules/services/hardware/nvidia-optimus.nix25
-rw-r--r--modules/services/misc/nix-daemon.nix5
-rw-r--r--modules/services/monitoring/dd-agent.nix3
-rw-r--r--modules/services/network-filesystems/samba.nix15
-rw-r--r--modules/services/networking/amuled.nix7
-rw-r--r--modules/services/networking/freenet.nix3
-rw-r--r--modules/services/networking/gnunet.nix18
-rw-r--r--modules/services/networking/ircd-hybrid/default.nix5
-rw-r--r--modules/services/networking/minidlna.nix9
-rw-r--r--modules/services/networking/oidentd.nix11
-rw-r--r--modules/services/networking/quassel.nix6
-rw-r--r--modules/services/networking/ssh/sshd.nix64
-rw-r--r--modules/services/security/torify.nix4
-rw-r--r--modules/services/security/torsocks.nix2
-rw-r--r--modules/services/system/dbus.nix18
-rw-r--r--modules/services/torrent/deluge.nix3
-rw-r--r--modules/services/torrent/transmission.nix3
-rw-r--r--modules/services/web-servers/lighttpd/default.nix3
-rw-r--r--modules/services/web-servers/varnish/default.nix3
-rw-r--r--modules/services/x11/desktop-managers/kde4.nix5
-rw-r--r--modules/services/x11/display-managers/default.nix5
-rw-r--r--modules/services/x11/display-managers/lightdm.nix4
-rw-r--r--modules/virtualisation/virtualbox-guest.nix2
-rw-r--r--modules/virtualisation/virtualbox-image.nix2
36 files changed, 224 insertions, 163 deletions
diff --git a/modules/config/power-management.nix b/modules/config/power-management.nix
index 50c7482a3727..fec2c886818a 100644
--- a/modules/config/power-management.nix
+++ b/modules/config/power-management.nix
@@ -72,6 +72,14 @@ in
     powerManagement.cpuFreqGovernor = mkDefault "ondemand";
     powerManagement.scsiLinkPolicy = mkDefault "min_power";
 
+    systemd.targets.post-resume = {
+      description = "Post-Resume Actions";
+      requires = [ "post-resume.service" ];
+      after = [ "post-resume.service" ];
+      wantedBy = [ "sleep.target" ];
+      unitConfig.StopWhenUnneeded = true;
+    };
+
     # Service executed before suspending/hibernating.
     systemd.services."pre-sleep" =
       { description = "Pre-Sleep Actions";
@@ -84,25 +92,9 @@ in
         serviceConfig.Type = "oneshot";
       };
 
-    # Service executed before suspending/hibernating.  There doesn't
-    # seem to be a good way to hook in a service to be executed after
-    # both suspend *and* hibernate, so have a separate one for each.
-    systemd.services."post-suspend" =
-      { description = "Post-Suspend Actions";
-        wantedBy = [ "suspend.target" ];
-        after = [ "systemd-suspend.service" ];
-        script =
-          ''
-            ${cfg.resumeCommands}
-            ${cfg.powerUpCommands}
-          '';
-        serviceConfig.Type = "oneshot";
-      };
-
-    systemd.services."post-hibernate" =
-      { description = "Post-Hibernate Actions";
-        wantedBy = [ "hibernate.target" ];
-        after = [ "systemd-hibernate.service" ];
+    systemd.services."post-resume" =
+      { description = "Post-Resume Actions";
+        after = [ "suspend.target" "hibernate.target" "hybrid-sleep.target" ];
         script =
           ''
             ${cfg.resumeCommands}
diff --git a/modules/misc/ids.nix b/modules/misc/ids.nix
index 27af51d21e1a..6bb98c354dbc 100644
--- a/modules/misc/ids.nix
+++ b/modules/misc/ids.nix
@@ -82,7 +82,27 @@ in
     iodined = 66;
     graphite = 68;
     statsd = 69;
-    elasticsearch = 70;
+    transmission = 70;
+    postgres = 71;
+    smbguest = 74;
+    varnish = 75;
+    dd-agent = 76;
+    lighttpd = 77;
+    lightdm = 78;
+    freenet = 79;
+    ircd = 80;
+    bacula = 81;
+    almir = 82;
+    deluge = 83;
+    mysql = 84;
+    rabbitmq = 85;
+    activemq = 86;
+    gnunet = 87;
+    oidentd = 88;
+    quassel = 89;
+    amule = 90;
+    minidlna = 91;
+    elasticsearch = 92;
 
     # When adding a uid, make sure it doesn't match an existing gid.
 
@@ -148,6 +168,28 @@ in
     iodined = 66;
     libvirtd = 67;
     graphite = 68;
+    transmission = 70;
+    postgres = 71;
+    vboxusers = 72;
+    vboxsf = 73;
+    smbguest = 74;
+    varnish = 75;
+    dd-agent = 76;
+    lighttpd = 77;
+    lightdm = 78;
+    freenet = 79;
+    ircd = 80;
+    bacula = 81;
+    almir = 82;
+    deluge = 83;
+    mysql = 84;
+    rabbitmq = 85;
+    activemq = 86;
+    gnunet = 87;
+    oidentd = 88;
+    quassel = 89;
+    amule = 90;
+    minidlna = 91;
 
     # When adding a gid, make sure it doesn't match an existing uid.
 
diff --git a/modules/programs/ssh.nix b/modules/programs/ssh.nix
index f28de02bb4eb..5ec32376b60e 100644
--- a/modules/programs/ssh.nix
+++ b/modules/programs/ssh.nix
@@ -35,6 +35,14 @@ in
           Pulls in X11 dependency.
         '';
       };
+
+      extraConfig = mkOption {
+        default = "";
+        description = ''
+          Extra configuration text appended to <filename>ssh_config</filename>.
+          See the ssh_config(5) man page for help.
+        '';
+      };
     };
   };
 
@@ -51,6 +59,7 @@ in
               XAuthLocation ${pkgs.xorg.xauth}/bin/xauth
             ''}
             ForwardX11 ${if cfg.forwardX11 then "yes" else "no"}
+            ${cfg.extraConfig}
           '';
           target = "ssh/ssh_config";
         }
diff --git a/modules/programs/virtualbox.nix b/modules/programs/virtualbox.nix
index c2781edffb8a..2a2ca745e2f9 100644
--- a/modules/programs/virtualbox.nix
+++ b/modules/programs/virtualbox.nix
@@ -9,7 +9,7 @@ let virtualbox = config.boot.kernelPackages.virtualbox; in
   boot.extraModulePackages = [ virtualbox ];
   environment.systemPackages = [ virtualbox ];
 
-  users.extraGroups = singleton { name = "vboxusers"; };
+  users.extraGroups.vboxusers.gid = config.ids.gids.vboxusers;
 
   services.udev.extraRules =
     ''
diff --git a/modules/rename.nix b/modules/rename.nix
index bf6179cf369e..bc0ebf1f0919 100644
--- a/modules/rename.nix
+++ b/modules/rename.nix
@@ -26,7 +26,7 @@ let
 
 
   zipModules = list: with pkgs.lib;
-    zip (n: v:
+    zipAttrsWith (n: v:
       if tail v != [] then
         if n == "_type" then (head v)
         else if n == "extraConfigs" then (concatLists v)
diff --git a/modules/services/amqp/activemq/default.nix b/modules/services/amqp/activemq/default.nix
index 44bf8be58781..915d179e6999 100644
--- a/modules/services/amqp/activemq/default.nix
+++ b/modules/services/amqp/activemq/default.nix
@@ -89,32 +89,17 @@ in {
           Java runtime when the broker service is started.
         '';
       };
-      user = {
-        create = mkOption {
-          type = types.bool;
-          default = true;
-          description = ''
-            If true, a system user with the specified name will be added
-            to the system configuration. If false, a user with the specified
-            name is expected to exist.
-          '';
-        };
-        name = mkOption {
-          type = types.string;
-          default = "activemq";
-          description = ''
-            The name of the user that should run the ActiveMQ process.
-          '';
-        };
-      };
     };
   };
 
   config = mkIf cfg.enable {
-    users.extraUsers = mkIf cfg.user.create (singleton {
-      inherit (cfg.user) name;
+    users.extraUsers.activemq = {
       description = "ActiveMQ server user";
-    });
+      group = "activemq";
+      uid = config.ids.uids.activemq;
+    };
+
+    users.extraGroups.activemq.gid = config.ids.gids.activemq;
 
     systemd.services.activemq_init = {
       wantedBy = [ "activemq.service" ];
diff --git a/modules/services/amqp/rabbitmq.nix b/modules/services/amqp/rabbitmq.nix
index 4afbafdd0856..696b5ad43797 100644
--- a/modules/services/amqp/rabbitmq.nix
+++ b/modules/services/amqp/rabbitmq.nix
@@ -51,11 +51,14 @@ in
 
     environment.systemPackages = [ pkgs.rabbitmq_server ];
 
-    users.extraUsers = singleton
-      { name = "rabbitmq";
-        description = "RabbitMQ server user";
-        home = "/var/empty";
-      };
+    users.extraUsers.rabbitmq = {
+      description = "RabbitMQ server user";
+      home = "/var/empty";
+      group = "rabbitmq";
+      uid = config.ids.uids.rabbitmq;
+    };
+
+    users.extraGroups.rabbitmq.gid = config.ids.gids.rabbitmq;
 
     jobs.rabbitmq = {
         description = "RabbitMQ server";
diff --git a/modules/services/backup/almir.nix b/modules/services/backup/almir.nix
index a4ebfff23892..d5bc932c6b96 100644
--- a/modules/services/backup/almir.nix
+++ b/modules/services/backup/almir.nix
@@ -161,10 +161,11 @@ in {
 
     users.extraUsers.almir = {
       group = "almir";
+      uid = config.ids.uids.almir;
       createHome = true;
       shell = "${pkgs.bash}/bin/bash";
     };
 
-    users.extraGroups.almir = {};
+    users.extraGroups.almir.gid = config.ids.gids.almir;
   };
 }
diff --git a/modules/services/backup/bacula.nix b/modules/services/backup/bacula.nix
index 525df3400484..272903c99e33 100644
--- a/modules/services/backup/bacula.nix
+++ b/modules/services/backup/bacula.nix
@@ -396,12 +396,13 @@ in {
 
     users.extraUsers.bacula = {
       group = "bacula";
+      uid = config.ids.uids.bacula;
       home = "${libDir}";
       createHome = true;
       description = "Bacula Daemons user";
       shell = "${pkgs.bash}/bin/bash";
     };
 
-    users.extraGroups.bacula = {};
+    users.extraGroups.bacula.gid = config.ids.gids.bacula;
   };
 }
diff --git a/modules/services/databases/mysql.nix b/modules/services/databases/mysql.nix
index ed9d03dc60f7..663c2cc4505a 100644
--- a/modules/services/databases/mysql.nix
+++ b/modules/services/databases/mysql.nix
@@ -146,10 +146,13 @@ in
 
   config = mkIf config.services.mysql.enable {
 
-    users.extraUsers = singleton
-      { name = "mysql";
-        description = "MySQL server user";
-      };
+    users.extraUsers.mysql = {
+      description = "MySQL server user";
+      group = "mysql";
+      uid = config.ids.uids.mysql;
+    };
+
+    users.extraGroups.mysql.gid = config.ids.gids.mysql;
 
     environment.systemPackages = [mysql];
 
diff --git a/modules/services/databases/mysql55.nix b/modules/services/databases/mysql55.nix
index 1da182a0e591..46148d68f4c6 100644
--- a/modules/services/databases/mysql55.nix
+++ b/modules/services/databases/mysql55.nix
@@ -139,10 +139,13 @@ in
 
   config = mkIf config.services.mysql55.enable {
 
-    users.extraUsers = singleton
-      { name = "mysql";
-        description = "MySQL server user";
-      };
+    users.extraUsers.mysql = {
+      description = "MySQL server user";
+      group = "mysql";
+      uid = config.ids.uids.mysql;
+    };
+
+    users.extraGroups.mysql.gid = config.ids.gids.mysql;
 
     environment.systemPackages = [mysql];
 
diff --git a/modules/services/databases/postgresql.nix b/modules/services/databases/postgresql.nix
index de03fe1e46ee..fc6b5b167b88 100644
--- a/modules/services/databases/postgresql.nix
+++ b/modules/services/databases/postgresql.nix
@@ -154,13 +154,14 @@ in
         host  all all ::1/128      md5
       '';
 
-    users.extraUsers = singleton
+    users.extraUsers.postgres =
       { name = "postgres";
+        uid = config.ids.uids.postgres;
+        group = "postgres";
         description = "PostgreSQL server user";
       };
 
-    users.extraGroups = singleton
-      { name = "postgres"; };
+    users.extraGroups.postgres.gid = config.ids.gids.postgres;
 
     environment.systemPackages = [postgresql];
 
diff --git a/modules/services/hardware/nvidia-optimus.nix b/modules/services/hardware/nvidia-optimus.nix
index fd58b3d5ad52..4c0ce794d4f7 100644
--- a/modules/services/hardware/nvidia-optimus.nix
+++ b/modules/services/hardware/nvidia-optimus.nix
@@ -1,7 +1,6 @@
-{pkgs, config, ...}:
+{ config, pkgs, ... }:
 
-let kernel = config.boot.kernelPackages;
-in
+let kernel = config.boot.kernelPackages; in
 
 {
 
@@ -13,7 +12,8 @@ in
       default = false;
       type = pkgs.lib.types.bool;
       description = ''
-        Completely disable the nvidia gfx chip (saves power / heat) and just use IGP
+        Completely disable the NVIDIA graphics card and use the
+        integrated graphics processor instead.
       '';
     };
 
@@ -27,13 +27,16 @@ in
     boot.kernelModules = [ "bbswitch" ];
     boot.extraModulePackages = [ kernel.bbswitch ];
 
-    jobs.bbswitch = {
-      name = "bbswitch";
-      description = "turn off nvidia card";
-      startOn = "stopped udevtrigger";
-      exec = "discrete_vga_poweroff";
-      path = [kernel.bbswitch];
-      task = true;
+    systemd.services.bbswitch = {
+      description = "Disable NVIDIA Card";
+      wantedBy = [ "multi-user.target" ];
+      serviceConfig = {
+        Type = "oneshot";
+        RemainAfterExit = true;
+        ExecStart = "${kernel.bbswitch}/bin/discrete_vga_poweroff";
+        ExecStop = "${kernel.bbswitch}/bin/discrete_vga_poweron";
+      };
+      path = [ kernel.bbswitch ];
     };
   };
 
diff --git a/modules/services/misc/nix-daemon.nix b/modules/services/misc/nix-daemon.nix
index e77a9dc2e4b4..58fb3322c201 100644
--- a/modules/services/misc/nix-daemon.nix
+++ b/modules/services/misc/nix-daemon.nix
@@ -34,8 +34,9 @@ let
       pkgs.runCommand "nix.conf" {extraOptions = cfg.extraOptions; } ''
         extraPaths=$(for i in $(cat ${binshDeps}); do if test -d $i; then echo $i; fi; done)
         cat > $out <<END
-        # WARNING: this file is generated from the nix.* entries in
-        # ${maybeEnv "NIXOS_CONFIG" "/etc/nixos/configuration.nix"}
+        # WARNING: this file is generated from the nix.* options in
+        # your NixOS configuration, typically
+        # /etc/nixos/configuration.nix.  Do not edit it!
         build-users-group = nixbld
         build-max-jobs = ${toString (cfg.maxJobs)}
         build-use-chroot = ${if cfg.useChroot then "true" else "false"}
diff --git a/modules/services/monitoring/dd-agent.nix b/modules/services/monitoring/dd-agent.nix
index 92e88c68d162..ef658523c1f3 100644
--- a/modules/services/monitoring/dd-agent.nix
+++ b/modules/services/monitoring/dd-agent.nix
@@ -46,12 +46,13 @@ in {
 
     users.extraUsers."dd-agent" = {
       description = "Datadog Agent User";
+      uid = config.ids.uids.dd-agent;
       group = "dd-agent";
       home = "/var/log/datadog/";
       createHome = true;
     };
 
-    users.extraGroups."dd-agent" = { };
+    users.extraGroups.dd-agent.gid = config.ids.gids.dd-agent;
 
     systemd.services.dd-agent = {
       description = "Datadog agent monitor";
diff --git a/modules/services/network-filesystems/samba.nix b/modules/services/network-filesystems/samba.nix
index 903e2c39ae9c..518142ba97b1 100644
--- a/modules/services/network-filesystems/samba.nix
+++ b/modules/services/network-filesystems/samba.nix
@@ -188,16 +188,13 @@ in
       }
 
       (mkIf config.services.samba.enable {
-        users.extraUsers = singleton
-          { name = user;
-            description = "Samba service user";
-            group = group;
-          };
-
-        users.extraGroups = singleton
-          { name = group;
-          };
+        users.extraUsers.smbguest = {
+          description = "Samba service user";
+          group = group;
+          uid = config.ids.uids.smbguest;
+        };
 
+        users.extraGroups.smbguest.gid = config.ids.uids.smbguest;
 
         systemd = {
           targets.samba = {
diff --git a/modules/services/networking/amuled.nix b/modules/services/networking/amuled.nix
index 658d16af006c..8652d0daf4c8 100644
--- a/modules/services/networking/amuled.nix
+++ b/modules/services/networking/amuled.nix
@@ -48,6 +48,13 @@ in
     users.extraUsers = mkIf (cfg.user == null) [
       { name = "amule";
         description = "AMule daemon";
+        group = "amule";
+        uid = config.ids.uids.amule;
+      } ];
+
+    users.extraGroups = mkIf (cfg.user == null) [
+      { name = "amule";
+        gid = config.ids.gids.amule;
       } ];
 
     jobs.amuled =
diff --git a/modules/services/networking/freenet.nix b/modules/services/networking/freenet.nix
index 314c690d7d42..a4bd2098986d 100644
--- a/modules/services/networking/freenet.nix
+++ b/modules/services/networking/freenet.nix
@@ -55,9 +55,10 @@ in
       description = "Freenet daemon user";
       home = varDir;
       createHome = true;
+      uid = config.ids.uids.freenet;
     };
 
-    users.extraGroups.freenet = {};
+    users.extraGroups.freenet.gid = config.ids.gids.freenet;
   };
 
 }
diff --git a/modules/services/networking/gnunet.nix b/modules/services/networking/gnunet.nix
index e0c41dcb1887..421c0d9bb697 100644
--- a/modules/services/networking/gnunet.nix
+++ b/modules/services/networking/gnunet.nix
@@ -118,17 +118,15 @@ in
 
   config = mkIf config.services.gnunet.enable {
 
-    users.extraUsers = singleton
-      { name = "gnunet";
-        group = "gnunet";
-        description = "GNUnet User";
-        home = homeDir;
-        createHome = true; 
-      };
+    users.extraUsers.gnunet = {
+      group = "gnunet";
+      description = "GNUnet User";
+      home = homeDir;
+      createHome = true; 
+      uid = config.ids.uids.gnunet;
+    };
 
-    users.extraGroups = singleton
-      { name = "gnunet";
-      };
+    users.extraGroups.gnunet.gid = config.ids.gids.gnunet;
 
     # The user tools that talk to `gnunetd' should come from the same source,
     # so install them globally.
diff --git a/modules/services/networking/ircd-hybrid/default.nix b/modules/services/networking/ircd-hybrid/default.nix
index 99fe02db5db8..cd82a41ef7af 100644
--- a/modules/services/networking/ircd-hybrid/default.nix
+++ b/modules/services/networking/ircd-hybrid/default.nix
@@ -115,10 +115,11 @@ in
     users.extraUsers = singleton
       { name = "ircd";
         description = "IRCD owner";
+        group = "ircd";
+        uid = config.ids.uids.ircd;
       };
 
-    users.extraGroups = singleton
-      { name = "ircd"; };
+    users.extraGroups.ircd.gid = config.ids.gids.ircd;
 
     jobs.ircd_hybrid =
       { name = "ircd-hybrid";
diff --git a/modules/services/networking/minidlna.nix b/modules/services/networking/minidlna.nix
index c240e87e0596..ea5bc8514f1c 100644
--- a/modules/services/networking/minidlna.nix
+++ b/modules/services/networking/minidlna.nix
@@ -72,12 +72,19 @@ in
         '') cfg.mediaDirs}
       '';
 
-    users.extraUsers.minidlna.description = "MiniDLNA daemon user";
+    users.extraUsers.minidlna = {
+      description = "MiniDLNA daemon user";
+      group = "minidlna";
+      uid = config.ids.uids.minidlna;
+    };
+
+    users.extraGroups.minidlna.gid = config.ids.gids.minidlna;
 
     systemd.services.minidlna =
       { description = "MiniDLNA Server";
 
         wantedBy = [ "multi-user.target" ];
+        after = [ "network.target" ];
 
         preStart =
           ''
diff --git a/modules/services/networking/oidentd.nix b/modules/services/networking/oidentd.nix
index d730e99af89a..a2a555a8ad1b 100644
--- a/modules/services/networking/oidentd.nix
+++ b/modules/services/networking/oidentd.nix
@@ -31,10 +31,13 @@ with pkgs.lib;
         exec = "${pkgs.oidentd}/sbin/oidentd -u oidentd -g nogroup";
       };
 
-    users.extraUsers = singleton
-      { name = "oidentd";
-        description = "Ident Protocol daemon user";
-      };
+    users.extraUsers.oidentd = {
+      description = "Ident Protocol daemon user";
+      group = "oidentd";
+      uid = config.ids.uids.oidentd;
+    };
+
+    users.extraGroups.oidentd.gid = config.ids.gids.oidentd;
 
   };
 
diff --git a/modules/services/networking/quassel.nix b/modules/services/networking/quassel.nix
index e8af4926f5ca..f3a4e457ec84 100644
--- a/modules/services/networking/quassel.nix
+++ b/modules/services/networking/quassel.nix
@@ -65,8 +65,14 @@ in
     users.extraUsers = mkIf (cfg.user == null) [
       { name = "quassel";
         description = "Quassel IRC client daemon";
+        group = "quassel";
+        uid = config.ids.uids.quassel;
       }];
 
+    users.extraGroups = mkIf (cfg.user == null) [
+      { name = "quassel";
+        gid = config.ids.gids.quassel;
+      }];
 
     jobs.quassel =
       { description = "Quassel IRC client daemon";
diff --git a/modules/services/networking/ssh/sshd.nix b/modules/services/networking/ssh/sshd.nix
index e9df8dd3cf6b..d57eef860d28 100644
--- a/modules/services/networking/ssh/sshd.nix
+++ b/modules/services/networking/ssh/sshd.nix
@@ -15,21 +15,6 @@ let
     v == "forced-commands-only" ||
     v == "no";
 
-  hostKeyTypeNames = {
-    dsa1024  = "dsa";
-    rsa1024  = "rsa";
-    ecdsa521 = "ecdsa";
-  };
-
-  hostKeyTypeBits = {
-    dsa1024  = 1024;
-    rsa1024  = 1024;
-    ecdsa521 = 521;
-  };
-
-  hktn = attrByPath [cfg.hostKeyType] (throw "unknown host key type `${cfg.hostKeyType}'") hostKeyTypeNames;
-  hktb = attrByPath [cfg.hostKeyType] (throw "unknown host key type `${cfg.hostKeyType}'") hostKeyTypeBits;
-
   knownHosts = map (h: getAttr h cfg.knownHosts) (attrNames cfg.knownHosts);
 
   knownHostsFile = pkgs.writeText "ssh_known_hosts" (
@@ -168,22 +153,23 @@ in
         '';
       };
 
-      hostKeyType = mkOption {
-        default = "dsa1024";
+      hostKeys = mkOption {
+        default =
+          [ { path = "/etc/ssh/ssh_host_dsa_key";
+              type = "dsa";
+              bits = 1024;
+            }
+            { path = "/etc/ssh/ssh_host_ecdsa_key";
+              type = "ecdsa";
+              bits = 521;
+            }
+          ];
         description = ''
-          Type of host key to generate (dsa1024/rsa1024/ecdsa521), if
-          the file specified by <literal>hostKeyPath</literal> does not
-          exist when the service starts.
-        '';
-      };
-
-      hostKeyPath = mkOption {
-        default = "/etc/ssh/ssh_host_${hktn}_key";
-        description = ''
-          Path to the server's private key. If there is no key file
-          on this path, it will be generated when the service is
-          started for the first time. Otherwise, the ssh daemon will
-          use the specified key directly in-place.
+          NixOS can automatically generate SSH host keys.  This option
+          specifies the path, type and size of each key.  See
+          <citerefentry><refentrytitle>ssh-keygen</refentrytitle>
+          <manvolnum>1</manvolnum></citerefentry> for supported types
+          and sizes.
         '';
       };
 
@@ -244,7 +230,7 @@ in
 
   ###### implementation
 
-  config = mkIf config.services.openssh.enable {
+  config = mkIf cfg.enable {
 
     users.extraUsers = singleton
       { name = "sshd";
@@ -269,7 +255,7 @@ in
 
         stopIfChanged = false;
 
-        path = [ pkgs.openssh ];
+        path = [ pkgs.openssh pkgs.gawk ];
 
         environment.LD_LIBRARY_PATH = nssModulesPath;
         environment.LOCALE_ARCHIVE = "/run/current-system/sw/lib/locale/locale-archive";
@@ -278,14 +264,16 @@ in
           ''
             mkdir -m 0755 -p /etc/ssh
 
-            if ! test -f ${cfg.hostKeyPath}; then
-                ssh-keygen -t ${hktn} -b ${toString hktb} -f ${cfg.hostKeyPath} -N ""
-            fi
+            ${flip concatMapStrings cfg.hostKeys (k: ''
+              if ! [ -f "${k.path}" ]; then
+                  ssh-keygen -t "${k.type}" -b "${toString k.bits}" -f "${k.path}" -N ""
+              fi
+            '')}
           '';
 
         serviceConfig =
           { ExecStart =
-              "${pkgs.openssh}/sbin/sshd -h ${cfg.hostKeyPath} " +
+              "${pkgs.openssh}/sbin/sshd " +
               "-f ${pkgs.writeText "sshd_config" cfg.extraConfig}";
             Restart = "always";
             Type = "forking";
@@ -336,6 +324,10 @@ in
         PrintMotd no # handled by pam_motd
 
         AuthorizedKeysFile ${toString cfg.authorizedKeysFiles}
+
+        ${flip concatMapStrings cfg.hostKeys (k: ''
+          HostKey ${k.path}
+        '')}
       '';
 
     assertions = [{ assertion = if cfg.forwardX11 then cfgc.setXAuthLocation else true;
diff --git a/modules/services/security/torify.nix b/modules/services/security/torify.nix
index b91d7d58505c..1c158906a911 100644
--- a/modules/services/security/torify.nix
+++ b/modules/services/security/torify.nix
@@ -8,7 +8,7 @@ let
     name = "torify";
     text = ''
         #!${pkgs.stdenv.shell}
-        TSOCKS_CONF_FILE=${pkgs.writeText "tsocks.conf" cfg.torify.config} LD_PRELOAD="${pkgs.tsocks}/lib/libtsocks.so $LD_PRELOAD" $@
+        TSOCKS_CONF_FILE=${pkgs.writeText "tsocks.conf" cfg.torify.config} LD_PRELOAD="${pkgs.tsocks}/lib/libtsocks.so $LD_PRELOAD" "$@"
     '';
     executable = true;
     destination = "/bin/torify";
@@ -66,4 +66,4 @@ in
     '';
   };
 
-}
\ No newline at end of file
+}
diff --git a/modules/services/security/torsocks.nix b/modules/services/security/torsocks.nix
index 8c2015e37c1e..d6974282a6b5 100644
--- a/modules/services/security/torsocks.nix
+++ b/modules/services/security/torsocks.nix
@@ -20,7 +20,7 @@ let
     name = name;
     text = ''
         #!${pkgs.stdenv.shell}
-        TORSOCKS_CONF_FILE=${pkgs.writeText "torsocks.conf" (makeConfig server)} LD_PRELOAD="${pkgs.torsocks}/lib/torsocks/libtorsocks.so $LD_PRELOAD" $@
+        TORSOCKS_CONF_FILE=${pkgs.writeText "torsocks.conf" (makeConfig server)} LD_PRELOAD="${pkgs.torsocks}/lib/torsocks/libtorsocks.so $LD_PRELOAD" "$@"
     '';
     executable = true;
     destination = "/bin/${name}";
diff --git a/modules/services/system/dbus.nix b/modules/services/system/dbus.nix
index 28647004ce4c..eab876be76d3 100644
--- a/modules/services/system/dbus.nix
+++ b/modules/services/system/dbus.nix
@@ -103,18 +103,14 @@ in
         target = "dbus-1";
       };
 
-    users.extraUsers = singleton
-      { name = "messagebus";
-        uid = config.ids.uids.messagebus;
-        description = "D-Bus system message bus daemon user";
-        home = homeDir;
-        group = "messagebus";
-      };
+    users.extraUsers.messagebus = {
+      uid = config.ids.uids.messagebus;
+      description = "D-Bus system message bus daemon user";
+      home = homeDir;
+      group = "messagebus";
+    };
 
-    users.extraGroups = singleton
-      { name = "messagebus";
-        gid = config.ids.gids.messagebus;
-      };
+    users.extraGroups.messagebus.gid = config.ids.gids.messagebus;
 
     # FIXME: these are copied verbatim from the dbus source tree.  We
     # should install and use the originals.
diff --git a/modules/services/torrent/deluge.nix b/modules/services/torrent/deluge.nix
index 12b61d39109b..e0c212e5661f 100644
--- a/modules/services/torrent/deluge.nix
+++ b/modules/services/torrent/deluge.nix
@@ -54,11 +54,12 @@ in {
 
     users.extraUsers.deluge = {
       group = "deluge";
+      uid = config.ids.uids.deluge;
       home = "/var/lib/deluge/";
       createHome = true;
       description = "Deluge Daemon user";
     };
 
-    users.extraGroups.deluge = {};
+    users.extraGroups.deluge.gid = config.ids.gids.deluge;
   };
 }
diff --git a/modules/services/torrent/transmission.nix b/modules/services/torrent/transmission.nix
index 4c989f09fea6..063332d48628 100644
--- a/modules/services/torrent/transmission.nix
+++ b/modules/services/torrent/transmission.nix
@@ -129,12 +129,13 @@ in
 
     users.extraUsers.transmission = {
       group = "transmission";
+      uid = config.ids.uids.transmission;
       description = "Transmission BitTorrent user";
       home = homeDir;
       createHome = true;
     };
 
-    users.extraGroups.transmission = {};
+    users.extraGroups.transmission.gid = config.ids.gids.transmission;
 
     # AppArmor profile
     security.apparmor.profiles = mkIf (config.security.apparmor.enable && cfg.apparmor) [
diff --git a/modules/services/web-servers/lighttpd/default.nix b/modules/services/web-servers/lighttpd/default.nix
index f1099ef599f4..f9e40fc4b541 100644
--- a/modules/services/web-servers/lighttpd/default.nix
+++ b/modules/services/web-servers/lighttpd/default.nix
@@ -170,8 +170,9 @@ in
     users.extraUsers.lighttpd = {
       group = "lighttpd";
       description = "lighttpd web server privilege separation user";
+      uid = config.ids.uids.lighttpd;
     };
 
-    users.extraGroups.lighttpd = {};
+    users.extraGroups.lighttpd.gid = config.ids.gids.lighttpd;
   };
 }
diff --git a/modules/services/web-servers/varnish/default.nix b/modules/services/web-servers/varnish/default.nix
index 66ec978bac8e..39de73213ce1 100644
--- a/modules/services/web-servers/varnish/default.nix
+++ b/modules/services/web-servers/varnish/default.nix
@@ -47,8 +47,9 @@ with pkgs.lib;
 
     users.extraUsers.varnish = {
       group = "varnish";
+      uid = config.ids.uids.varnish;
     };
 
-    users.extraGroups.varnish = {};
+    users.extraGroups.varnish.gid = config.ids.uids.varnish;
   };
 }
diff --git a/modules/services/x11/desktop-managers/kde4.nix b/modules/services/x11/desktop-managers/kde4.nix
index 6d804c13827d..cf86d2b86be5 100644
--- a/modules/services/x11/desktop-managers/kde4.nix
+++ b/modules/services/x11/desktop-managers/kde4.nix
@@ -97,11 +97,6 @@ in
             # See http://lists-archives.org/kde-devel/26175-what-when-will-icon-cache-refresh.html
             rm -fv $HOME/.kde/cache-*/icon-cache.kcache
 
-            # Speed up application start by 50-150ms according to
-            # http://kdemonkey.blogspot.nl/2008/04/magic-trick.html
-            rm -fv $HOME/.compose-cache
-            mkdir $HOME/.compose-cache
-
             # Qt writes a weird ‘libraryPath’ line to
             # ~/.config/Trolltech.conf that causes the KDE plugin
             # paths of previous KDE invocations to be searched.
diff --git a/modules/services/x11/display-managers/default.nix b/modules/services/x11/display-managers/default.nix
index 451355d4980d..b6f6f2ec32eb 100644
--- a/modules/services/x11/display-managers/default.nix
+++ b/modules/services/x11/display-managers/default.nix
@@ -94,6 +94,11 @@ let
 
       export LIBVA_DRIVERS_PATH=${vaapiDrivers}/lib/dri
 
+      # Speed up application start by 50-150ms according to
+      # http://kdemonkey.blogspot.nl/2008/04/magic-trick.html
+      rm -fv $HOME/.compose-cache
+      mkdir $HOME/.compose-cache
+
       ${cfg.displayManager.sessionCommands}
 
       # Allow the user to setup a custom session type.
diff --git a/modules/services/x11/display-managers/lightdm.nix b/modules/services/x11/display-managers/lightdm.nix
index 6659a2dec469..b4f026d81439 100644
--- a/modules/services/x11/display-managers/lightdm.nix
+++ b/modules/services/x11/display-managers/lightdm.nix
@@ -109,6 +109,10 @@ in
     users.extraUsers.lightdm = {
       createHome = true;
       home = "/var/lib/lightdm";
+      group = "lightdm";
+      uid = config.ids.uids.lightdm;
     };
+
+    users.extraGroups.lightdm.gid = config.ids.gids.lightdm;
   };
 }
diff --git a/modules/virtualisation/virtualbox-guest.nix b/modules/virtualisation/virtualbox-guest.nix
index 262afae2cf6e..75c5349e0c26 100644
--- a/modules/virtualisation/virtualbox-guest.nix
+++ b/modules/virtualisation/virtualbox-guest.nix
@@ -38,7 +38,7 @@ optionalAttrs (pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64) # ugly...
 
     boot.extraModulePackages = [ kernel.virtualboxGuestAdditions ];
 
-    users.extraGroups = singleton { name = "vboxsf"; };
+    users.extraGroups.vboxsf.gid = config.ids.gids.vboxsf;
 
     jobs.virtualbox =
       { description = "VirtualBox Guest Services";
diff --git a/modules/virtualisation/virtualbox-image.nix b/modules/virtualisation/virtualbox-image.nix
index 18f375644f29..21b2e114340b 100644
--- a/modules/virtualisation/virtualbox-image.nix
+++ b/modules/virtualisation/virtualbox-image.nix
@@ -6,7 +6,7 @@ with pkgs.lib;
   system.build.virtualBoxImage =
     pkgs.vmTools.runInLinuxVM (
       pkgs.runCommand "virtualbox-image"
-        { memSize = 2048;
+        { memSize = 2047;
           preVM =
             ''
               mkdir $out