summary refs log tree commit diff
path: root/nixos/modules/services/x11/display-managers
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2013-10-10 13:28:20 +0200
committerEelco Dolstra <eelco.dolstra@logicblox.com>2013-10-10 13:28:20 +0200
commit5c1f8cbc70cd5e6867ef6a2a06d27a40daa07010 (patch)
treea6c0f605be6de3f372ae69905b331f9f75452da7 /nixos/modules/services/x11/display-managers
parent6070bc016bd2fd945b04347e25cfd3738622d2ac (diff)
downloadnixlib-5c1f8cbc70cd5e6867ef6a2a06d27a40daa07010.tar
nixlib-5c1f8cbc70cd5e6867ef6a2a06d27a40daa07010.tar.gz
nixlib-5c1f8cbc70cd5e6867ef6a2a06d27a40daa07010.tar.bz2
nixlib-5c1f8cbc70cd5e6867ef6a2a06d27a40daa07010.tar.lz
nixlib-5c1f8cbc70cd5e6867ef6a2a06d27a40daa07010.tar.xz
nixlib-5c1f8cbc70cd5e6867ef6a2a06d27a40daa07010.tar.zst
nixlib-5c1f8cbc70cd5e6867ef6a2a06d27a40daa07010.zip
Move all of NixOS to nixos/ in preparation of the repository merge
Diffstat (limited to 'nixos/modules/services/x11/display-managers')
-rw-r--r--nixos/modules/services/x11/display-managers/auto.nix52
-rw-r--r--nixos/modules/services/x11/display-managers/default.nix283
-rw-r--r--nixos/modules/services/x11/display-managers/kdm.nix151
-rw-r--r--nixos/modules/services/x11/display-managers/lightdm.nix119
-rw-r--r--nixos/modules/services/x11/display-managers/slim.nix113
5 files changed, 718 insertions, 0 deletions
diff --git a/nixos/modules/services/x11/display-managers/auto.nix b/nixos/modules/services/x11/display-managers/auto.nix
new file mode 100644
index 000000000000..33d97e0e07a9
--- /dev/null
+++ b/nixos/modules/services/x11/display-managers/auto.nix
@@ -0,0 +1,52 @@
+{ config, pkgs, ... }:
+
+with pkgs.lib;
+
+let
+
+  dmcfg = config.services.xserver.displayManager;
+  cfg = dmcfg.auto;
+
+in
+
+{
+
+  ###### interface
+
+  options = {
+
+    services.xserver.displayManager.auto = {
+
+      enable = mkOption {
+        default = false;
+        description = ''
+          Whether to enable the fake "auto" display manager, which
+          automatically logs in the user specified in the
+          <option>user</option> option.  This is mostly useful for
+          automated tests.
+        '';
+      };
+
+      user = mkOption {
+        default = "root";
+        description = "The user account to login automatically.";
+      };
+
+    };
+
+  };
+
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+
+    services.xserver.displayManager.slim = {
+      enable = true;
+      autoLogin = true;
+      defaultUser = cfg.user;
+    };
+
+  };
+
+}
diff --git a/nixos/modules/services/x11/display-managers/default.nix b/nixos/modules/services/x11/display-managers/default.nix
new file mode 100644
index 000000000000..c7599e245b05
--- /dev/null
+++ b/nixos/modules/services/x11/display-managers/default.nix
@@ -0,0 +1,283 @@
+# This module declares the options to define a *display manager*, the
+# program responsible for handling X logins (such as xdm, kdm, gdb, or
+# SLiM).  The display manager allows the user to select a *session
+# type*.  When the user logs in, the display manager starts the
+# *session script* ("xsession" below) to launch the selected session
+# type.  The session type defines two things: the *desktop manager*
+# (e.g., KDE, Gnome or a plain xterm), and optionally the *window
+# manager* (e.g. kwin or twm).
+
+{ config, pkgs, ... }:
+
+with pkgs.lib;
+
+let
+
+  cfg = config.services.xserver;
+  xorg = pkgs.xorg;
+
+  vaapiDrivers = pkgs.buildEnv {
+    name = "vaapi-drivers";
+    paths = cfg.vaapiDrivers;
+    # We only want /lib/dri, but with a single input path, we need "/" for it to work
+    pathsToLink = [ "/" ];
+  };
+
+  # file provided by services.xserver.displayManager.session.script
+  xsession = wm: dm: pkgs.writeScript "xsession"
+    ''
+      #! /bin/sh
+
+      . /etc/profile
+      cd "$HOME"
+
+      # The first argument of this script is the session type.
+      sessionType="$1"
+      if [ "$sessionType" = default ]; then sessionType=""; fi
+
+      ${optionalString (!cfg.displayManager.job.logsXsession) ''
+        exec > ~/.xsession-errors 2>&1
+      ''}
+
+      ${optionalString cfg.displayManager.desktopManagerHandlesLidAndPower ''
+        # Stop systemd from handling the power button and lid switch,
+        # since presumably the desktop environment will handle these.
+        if [ -z "$_INHIBITION_LOCK_TAKEN" ]; then
+          export _INHIBITION_LOCK_TAKEN=1
+          exec ${config.systemd.package}/bin/systemd-inhibit --what=handle-lid-switch:handle-power-key "$0" "$sessionType"
+        fi
+
+      ''}
+
+      ${optionalString cfg.startOpenSSHAgent ''
+        if test -z "$SSH_AUTH_SOCK"; then
+            # Restart this script as a child of the SSH agent.  (It is
+            # also possible to start the agent as a child that prints
+            # the required environment variabled on stdout, but in
+            # that mode ssh-agent is not terminated when we log out.)
+            export SSH_ASKPASS=${pkgs.x11_ssh_askpass}/libexec/x11-ssh-askpass
+            exec ${pkgs.openssh}/bin/ssh-agent "$0" "$sessionType"
+        fi
+      ''}
+
+      ${optionalString cfg.startGnuPGAgent ''
+        if test -z "$SSH_AUTH_SOCK"; then
+            # Restart this script as a child of the GnuPG agent.
+            exec "${pkgs.gnupg}/bin/gpg-agent"                         \
+              --enable-ssh-support --daemon                             \
+              --pinentry-program "${pkgs.pinentry}/bin/pinentry-gtk-2"  \
+              --write-env-file "$HOME/.gpg-agent-info"                  \
+              "$0" "$sessionType"
+        fi
+      ''}
+
+      # Handle being called by kdm.
+      if test "''${1:0:1}" = /; then eval exec "$1"; fi
+
+      # Start PulseAudio if enabled.
+      ${optionalString (config.hardware.pulseaudio.enable) ''
+        ${optionalString (!config.hardware.pulseaudio.systemWide)
+          "${pkgs.pulseaudio}/bin/pulseaudio --start"
+        }
+
+        # Publish access credentials in the root window.
+        ${pkgs.pulseaudio}/bin/pactl load-module module-x11-publish "display=$DISPLAY"
+
+        # Keep track of devices.  Mostly useful for Phonon/KDE.
+        ${pkgs.pulseaudio}/bin/pactl load-module module-device-manager "do_routing=1"
+      ''}
+
+      # Load X defaults.
+      if test -e ~/.Xdefaults; then
+          ${xorg.xrdb}/bin/xrdb -merge ~/.Xdefaults
+      fi
+
+      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 -rf $HOME/.compose-cache
+      mkdir $HOME/.compose-cache
+
+      ${cfg.displayManager.sessionCommands}
+
+      # Allow the user to setup a custom session type.
+      if test -x ~/.xsession; then
+          exec ~/.xsession
+      else
+          if test "$sessionType" = "custom"; then
+              sessionType="" # fall-thru if there is no ~/.xsession
+          fi
+      fi
+
+      # The session type is "<desktop-manager> + <window-manager>", so
+      # extract those.
+      windowManager="''${sessionType##* + }"
+      : ''${windowManager:=${cfg.windowManager.default}}
+      desktopManager="''${sessionType% + *}"
+      : ''${desktopManager:=${cfg.desktopManager.default}}
+
+      # Start the window manager.
+      case $windowManager in
+        ${concatMapStrings (s: ''
+          (${s.name})
+            ${s.start}
+            ;;
+        '') wm}
+        (*) echo "$0: Window manager '$windowManager' not found.";;
+      esac
+
+      # Start the desktop manager.
+      case $desktopManager in
+        ${concatMapStrings (s: ''
+          (${s.name})
+            ${s.start}
+            ;;
+        '') dm}
+        (*) echo "$0: Desktop manager '$desktopManager' not found.";;
+      esac
+
+      test -n "$waitPID" && wait "$waitPID"
+      exit 0
+    '';
+
+  mkDesktops = names: pkgs.runCommand "desktops" {}
+    ''
+      mkdir -p $out
+      ${concatMapStrings (n: ''
+        cat - > "$out/${n}.desktop" << EODESKTOP
+        [Desktop Entry]
+        Version=1.0
+        Type=XSession
+        TryExec=${cfg.displayManager.session.script}
+        Exec=${cfg.displayManager.session.script} '${n}'
+        Name=${n}
+        Comment=
+        EODESKTOP
+      '') names}
+    '';
+
+in
+
+{
+
+  options = {
+
+    services.xserver.displayManager = {
+
+      xauthBin = mkOption {
+        default = "${xorg.xauth}/bin/xauth";
+        description = "Path to the <command>xauth</command> program used by display managers.";
+      };
+
+      xserverBin = mkOption {
+        default = "${xorg.xorgserver}/bin/X";
+        description = "Path to the X server used by display managers.";
+      };
+
+      xserverArgs = mkOption {
+        default = [];
+        example = [ "-ac" "-logverbose" "-nolisten tcp" ];
+        description = "List of arguments for the X server.";
+        apply = toString;
+      };
+
+      sessionCommands = mkOption {
+        default = "";
+        example =
+          ''
+            xmessage "Hello World!" &
+          '';
+        type = types.string;
+        description = "Shell commands executed just before the window or desktop manager is started.";
+      };
+
+      desktopManagerHandlesLidAndPower = mkOption {
+        default = true;
+        description = ''
+          Whether the display manager should prevent systemd from handling
+          lid and power events. This is normally handled by the desktop
+          environment's power manager. Turn this off when using a minimal
+          X11 setup without a full power manager.
+        '';
+      };
+
+      session = mkOption {
+        default = [];
+        example = [
+          {
+            manage = "desktop";
+            name = "xterm";
+            start = "
+              ${pkgs.xterm}/bin/xterm -ls &
+              waitPID=$!
+            ";
+          }
+        ];
+        description = ''
+          List of sessions supported with the command used to start each
+          session.  Each session script can set the
+          <varname>waitPID</varname> shell variable to make this script
+          wait until the end of the user session.  Each script is used
+          to define either a windows manager or a desktop manager.  These
+          can be differentiated by setting the attribute
+          <varname>manage</varname> either to <literal>"window"</literal>
+          or <literal>"desktop"</literal>.
+
+          The list of desktop manager and window manager should appear
+          inside the display manager with the desktop manager name
+          followed by the window manager name.
+        '';
+        apply = list: rec {
+          wm = filter (s: s.manage == "window") list;
+          dm = filter (s: s.manage == "desktop") list;
+          names = flip concatMap dm
+            (d: map (w: d.name + optionalString (w.name != "none") (" + " + w.name))
+              (filter (w: d.name != "none" || w.name != "none") wm));
+          desktops = mkDesktops names;
+          script = xsession wm dm;
+        };
+      };
+
+      job = mkOption {
+        default = {};
+        type = types.uniq types.optionSet;
+        description = "This option defines how to start the display manager.";
+
+        options = {
+
+          preStart = mkOption {
+            default = "";
+            example = "rm -f /var/log/my-display-manager.log";
+            description = "Script executed before the display manager is started.";
+          };
+
+          execCmd = mkOption {
+            example = "${pkgs.slim}/bin/slim";
+            description = "Command to start the display manager.";
+          };
+
+          environment = mkOption {
+            default = {};
+            example = { SLIM_CFGFILE = /etc/slim.conf; };
+            description = "Additional environment variables needed by the display manager.";
+          };
+
+          logsXsession = mkOption {
+            default = false;
+            description = ''
+              Whether the display manager redirects the
+              output of the session script to
+              <filename>~/.xsession-errors</filename>.
+            '';
+          };
+
+        };
+
+      };
+
+    };
+
+  };
+
+}
diff --git a/nixos/modules/services/x11/display-managers/kdm.nix b/nixos/modules/services/x11/display-managers/kdm.nix
new file mode 100644
index 000000000000..229ab12c6e1b
--- /dev/null
+++ b/nixos/modules/services/x11/display-managers/kdm.nix
@@ -0,0 +1,151 @@
+{ config, pkgs, ... }:
+
+with pkgs.lib;
+
+let
+
+  dmcfg = config.services.xserver.displayManager;
+  cfg = dmcfg.kdm;
+
+  inherit (pkgs.kde4) kdebase_workspace;
+
+  defaultConfig =
+    ''
+      [Shutdown]
+      HaltCmd=${config.systemd.package}/sbin/shutdown -h now
+      RebootCmd=${config.systemd.package}/sbin/shutdown -r now
+      ${optionalString (config.system.boot.loader.id == "grub") ''
+        BootManager=${if config.boot.loader.grub.version == 2 then "Grub2" else "Grub"}
+      ''}
+
+      [X-*-Core]
+      Xrdb=${pkgs.xlibs.xrdb}/bin/xrdb
+      SessionsDirs=${dmcfg.session.desktops}
+      Session=${dmcfg.session.script}
+      FailsafeClient=${pkgs.xterm}/bin/xterm
+
+      [X-:*-Core]
+      ServerCmd=${dmcfg.xserverBin} ${dmcfg.xserverArgs}
+      # KDM calls `rm' somewhere to clean up some temporary directory.
+      SystemPath=${pkgs.coreutils}/bin
+      # The default timeout (15) is too short in a heavily loaded boot process.
+      ServerTimeout=60
+      # Needed to prevent the X server from dying on logout and not coming back:
+      TerminateServer=true
+      ${optionalString (cfg.setupScript != "")
+      ''
+        Setup=${cfg.setupScript}
+      ''} 
+
+      [X-*-Greeter]
+      HiddenUsers=root,nixbld1,nixbld2,nixbld3,nixbld4,nixbld5,nixbld6,nixbld7,nixbld8,nixbld9,nixbld10
+      PluginsLogin=${kdebase_workspace}/lib/kde4/kgreet_classic.so
+      ${optionalString (cfg.themeDirectory != "")
+      ''
+        UseTheme=true
+        Theme=${cfg.themeDirectory}
+      ''
+      }
+
+      ${optionalString (cfg.enableXDMCP)
+      ''
+        [Xdmcp]
+        Enable=true
+      ''}
+    '';
+
+  kdmrc = pkgs.stdenv.mkDerivation {
+    name = "kdmrc";
+    config = defaultConfig + cfg.extraConfig;
+    buildCommand =
+      ''
+        echo "$config" > $out
+
+        # The default kdmrc would add "-nolisten tcp", and we already
+        # have that managed by nixos. Hence the grep.
+        cat ${kdebase_workspace}/share/config/kdm/kdmrc | grep -v nolisten >> $out
+      '';
+  };
+
+in
+
+{
+
+  ###### interface
+
+  options = {
+
+    services.xserver.displayManager.kdm = {
+
+      enable = mkOption {
+        default = false;
+        description = ''
+          Whether to enable the KDE display manager.
+        '';
+      };
+
+      enableXDMCP = mkOption {
+        default = false;
+        description = ''
+          Whether to enable XDMCP, which allows remote logins.
+        '';
+      };
+
+      themeDirectory = mkOption {
+        default = "";
+        description = ''
+          The path to a KDM theme directory. This theme
+          will be used by the KDM greeter.
+        '';
+      };
+
+      setupScript = mkOption {
+        default = "";
+        description = ''
+          The path to a KDM setup script. This script is run as root just
+          before KDM starts. Can be used for setting up
+          monitors with xrandr, for example.
+        '';
+      };
+
+      extraConfig = mkOption {
+        default = "";
+        description = ''
+          Options appended to <filename>kdmrc</filename>, the
+          configuration file of KDM.
+        '';
+      };
+
+    };
+
+  };
+
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+
+    services.xserver.displayManager.slim.enable = false;
+
+    services.xserver.displayManager.job =
+      { execCmd =
+          ''
+            mkdir -m 0755 -p /var/lib/kdm
+            chown kdm /var/lib/kdm
+            ${(optionalString (config.system.boot.loader.id == "grub" && config.system.build.grub != null) "PATH=${config.system.build.grub}/sbin:$PATH ") +
+              "KDEDIRS=/run/current-system/sw exec ${kdebase_workspace}/bin/kdm -config ${kdmrc} -nodaemon"}
+          '';
+        logsXsession = true;
+      };
+
+    security.pam.services = [ { name = "kde"; allowNullPassword = true; startSession = true; } ];
+
+    users.extraUsers = singleton
+      { name = "kdm";
+        uid = config.ids.uids.kdm;
+        description = "KDM user";
+      };
+
+  };
+
+}
diff --git a/nixos/modules/services/x11/display-managers/lightdm.nix b/nixos/modules/services/x11/display-managers/lightdm.nix
new file mode 100644
index 000000000000..c2b90d239eaa
--- /dev/null
+++ b/nixos/modules/services/x11/display-managers/lightdm.nix
@@ -0,0 +1,119 @@
+{ config, pkgs, ... }:
+
+with pkgs.lib;
+
+let
+
+  dmcfg = config.services.xserver.displayManager;
+  xEnv = config.systemd.services."display-manager".environment;
+  cfg = dmcfg.lightdm;
+
+  inherit (pkgs) stdenv lightdm writeScript writeText;
+
+  # lightdm runs with clearenv(), but we need a few things in the enviornment for X to startup
+  xserverWrapper = writeScript "xserver-wrapper"
+    ''
+      #! /bin/sh
+      ${concatMapStrings (n: "export ${n}=\"${getAttr n xEnv}\"\n") (attrNames xEnv)}
+      exec ${dmcfg.xserverBin} ${dmcfg.xserverArgs}
+    '';
+
+  # The default greeter provided with this expression is the GTK greeter.
+  # Again, we need a few things in the environment for the greeter to run with
+  # fonts/icons.
+  wrappedGtkGreeter = stdenv.mkDerivation {
+    name = "lightdm-gtk-greeter";
+    buildInputs = [ pkgs.makeWrapper ];
+
+    buildCommand = ''
+      ensureDir $out/gtk-3.0/
+
+      # This wrapper ensures that we actually get fonts
+      makeWrapper ${pkgs.lightdm_gtk_greeter}/sbin/lightdm-gtk-greeter \
+        $out/greeter \
+        --set XDG_DATA_DIRS ${pkgs.gnome2.gnome_icon_theme}/share \
+        --set FONTCONFIG_FILE /etc/fonts/fonts.conf \
+        --set XDG_CONFIG_HOME $out/
+
+      # We need this to ensure that it actually tries to find icons from gnome-icon-theme
+      cat - > $out/gtk-3.0/settings.ini << EOF
+      [Settings]
+      gtk-icon-theme-name=gnome
+      EOF
+
+      cat - > $out/lightdm-gtk-greeter.desktop << EOF
+      [Desktop Entry]
+      Name=LightDM Greeter
+      Comment=This runs the LightDM Greeter
+      Exec=$out/greeter
+      Type=Application
+      EOF
+    '';
+  };
+
+  lightdmConf = writeText "lightdm.conf"
+    ''
+      [LightDM]
+      greeter-user = ${config.users.extraUsers.lightdm.name}
+      xgreeters-directory = ${cfg.greeter.package}
+      xsessions-directory = ${dmcfg.session.desktops}
+
+      [SeatDefaults]
+      xserver-command = ${xserverWrapper}
+      session-wrapper = ${dmcfg.session.script}
+      greeter-session = ${cfg.greeter.name}
+    '';
+
+in
+{
+  options = {
+    services.xserver.displayManager.lightdm = {
+      enable = mkOption {
+        default = false;
+        description = ''
+          Whether to enable lightdm as the display manager.
+        '';
+      };
+
+      greeter = mkOption {
+        description = ''
+          The LightDM greeter to login via. The package should be a directory
+          containing a .desktop file matching the name in the 'name' option.
+        '';
+        default = {
+          name = "lightdm-gtk-greeter";
+          package = wrappedGtkGreeter;
+        };
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+    services.xserver.displayManager.job = {
+      logsXsession = true;
+
+      # lightdm relaunches itself via just `lightdm`, so needs to be on the PATH
+      execCmd = ''
+        export PATH=${lightdm}/sbin:$PATH
+        ${lightdm}/sbin/lightdm --log-dir=/var/log --run-dir=/run --config=${lightdmConf}
+      '';
+    };
+
+    services.dbus.enable = true;
+    services.dbus.packages = [ lightdm ];
+
+    security.pam.services = [
+      { name = "lightdm"; allowNullPassword = true; startSession = true; }
+      { name = "lightdm-greeter"; allowNullPassword = true; startSession = true; }
+    ];
+
+    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/nixos/modules/services/x11/display-managers/slim.nix b/nixos/modules/services/x11/display-managers/slim.nix
new file mode 100644
index 000000000000..9e8b9391f45f
--- /dev/null
+++ b/nixos/modules/services/x11/display-managers/slim.nix
@@ -0,0 +1,113 @@
+{ config, pkgs, ... }:
+
+with pkgs.lib;
+
+let
+
+  dmcfg = config.services.xserver.displayManager;
+  cfg = dmcfg.slim;
+
+  slimConfig = pkgs.writeText "slim.cfg"
+    ''
+      xauth_path ${dmcfg.xauthBin}
+      default_xserver ${dmcfg.xserverBin}
+      xserver_arguments ${dmcfg.xserverArgs}
+      sessions ${pkgs.lib.concatStringsSep "," (dmcfg.session.names ++ ["custom"])}
+      login_cmd exec ${pkgs.stdenv.shell} ${dmcfg.session.script} "%session"
+      halt_cmd ${config.systemd.package}/sbin/shutdown -h now
+      reboot_cmd ${config.systemd.package}/sbin/shutdown -r now
+      ${optionalString (cfg.defaultUser != "") ("default_user " + cfg.defaultUser)}
+      ${optionalString cfg.autoLogin "auto_login yes"}
+    '';
+
+  # Unpack the SLiM theme, or use the default.
+  slimThemesDir =
+    let
+      unpackedTheme = pkgs.stdenv.mkDerivation {
+        name = "slim-theme";
+        buildCommand = ''
+          ensureDir $out
+          cd $out
+          unpackFile ${cfg.theme}
+          ln -s * default
+        '';
+      };
+    in if cfg.theme == null then "${pkgs.slim}/share/slim/themes" else unpackedTheme;
+
+in
+
+{
+
+  ###### interface
+
+  options = {
+
+    services.xserver.displayManager.slim = {
+
+      enable = mkOption {
+        default = true;
+        description = ''
+          Whether to enable SLiM as the display manager.
+        '';
+      };
+
+      theme = mkOption {
+        default = null;
+        example = pkgs.fetchurl {
+          url = http://download.berlios.de/slim/slim-wave.tar.gz;
+          sha256 = "0ndr419i5myzcylvxb89m9grl2xyq6fbnyc3lkd711mzlmnnfxdy";
+        };
+        description = ''
+          The theme for the SLiM login manager.  If not specified, SLiM's
+          default theme is used.  See <link
+          xlink:href='http://slim.berlios.de/themes01.php'/> for a
+          collection of themes.
+        '';
+      };
+
+      defaultUser = mkOption {
+        default = "";
+        example = "login";
+        description = ''
+          The default user to load. If you put a username here you
+          get it automatically loaded into the username field, and
+          the focus is placed on the password.
+        '';
+      };
+
+      autoLogin = mkOption {
+        default = false;
+        example = true;
+        description = ''
+          Automatically log in as the default user.
+        '';
+      };
+
+    };
+
+  };
+
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+
+    services.xserver.displayManager.job =
+      { preStart =
+          ''
+            rm -f /var/log/slim.log
+          '';
+        environment =
+          { SLIM_CFGFILE = slimConfig;
+            SLIM_THEMESDIR = slimThemesDir;
+          };
+        execCmd = "exec ${pkgs.slim}/bin/slim";
+      };
+
+    # Allow null passwords so that the user can login as root on the
+    # installation CD.
+    security.pam.services = [ { name = "slim"; allowNullPassword = true; startSession = true; } ];
+
+  };
+
+}