summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--lib/types.nix4
-rw-r--r--nixos/lib/utils.nix6
-rw-r--r--nixos/modules/config/shells-environment.nix8
-rw-r--r--nixos/modules/config/users-groups.nix25
-rw-r--r--nixos/modules/programs/bash/bash.nix2
-rw-r--r--nixos/modules/programs/shadow.nix18
-rw-r--r--pkgs/os-specific/linux/shadow/default.nix3
-rw-r--r--pkgs/shells/dash/default.nix4
-rw-r--r--pkgs/shells/es/default.nix4
-rw-r--r--pkgs/shells/fish/default.nix4
-rw-r--r--pkgs/shells/mksh/default.nix4
-rw-r--r--pkgs/shells/pash/default.nix4
-rw-r--r--pkgs/shells/rush/default.nix4
-rw-r--r--pkgs/shells/tcsh/default.nix4
-rw-r--r--pkgs/shells/xonsh/default.nix4
-rw-r--r--pkgs/shells/zsh/default.nix4
-rw-r--r--pkgs/top-level/all-packages.nix3
17 files changed, 85 insertions, 20 deletions
diff --git a/lib/types.nix b/lib/types.nix
index 91b39f3a9cf8..83f624e6b448 100644
--- a/lib/types.nix
+++ b/lib/types.nix
@@ -100,6 +100,10 @@ rec {
         in if isDerivation res then res else toDerivation res;
     };
 
+    shellPackage = package // {
+      check = x: (package.check x) && (hasAttr "shellPath" x);
+    };
+
     path = mkOptionType {
       name = "path";
       # Hacky: there is no ‘isPath’ primop.
diff --git a/nixos/lib/utils.nix b/nixos/lib/utils.nix
index 7b8be2050c13..871fbb121d03 100644
--- a/nixos/lib/utils.nix
+++ b/nixos/lib/utils.nix
@@ -8,4 +8,10 @@ rec {
    replaceChars ["/" "-" " "] ["-" "\\x2d" "\\x20"]
     (if hasPrefix "/" s then substring 1 (stringLength s) s else s);
 
+  # Returns a system path for a given shell package
+  toShellPath = shell:
+    if types.shellPackage.check shell then
+      "/run/current-system/sw${shell.shellPath}"
+    else
+      shell;
 }
diff --git a/nixos/modules/config/shells-environment.nix b/nixos/modules/config/shells-environment.nix
index 9642981803bf..f458bc39adaa 100644
--- a/nixos/modules/config/shells-environment.nix
+++ b/nixos/modules/config/shells-environment.nix
@@ -1,7 +1,7 @@
 # This module defines a global environment configuration and
 # a common configuration for all shells.
 
-{ config, lib, pkgs, ... }:
+{ config, lib, utils, pkgs, ... }:
 
 with lib;
 
@@ -135,13 +135,13 @@ in
 
     environment.shells = mkOption {
       default = [];
-      example = [ "/run/current-system/sw/bin/zsh" ];
+      example = literalExample "[ pkgs.bashInteractive pkgs.zsh ]";
       description = ''
         A list of permissible login shells for user accounts.
         No need to mention <literal>/bin/sh</literal>
         here, it is placed into this list implicitly.
       '';
-      type = types.listOf types.path;
+      type = types.listOf (types.either types.shellPackage types.path);
     };
 
   };
@@ -158,7 +158,7 @@ in
 
     environment.etc."shells".text =
       ''
-        ${concatStringsSep "\n" cfg.shells}
+        ${concatStringsSep "\n" (map utils.toShellPath cfg.shells)}
         /bin/sh
       '';
 
diff --git a/nixos/modules/config/users-groups.nix b/nixos/modules/config/users-groups.nix
index 8231907d7999..277a4264137b 100644
--- a/nixos/modules/config/users-groups.nix
+++ b/nixos/modules/config/users-groups.nix
@@ -1,9 +1,8 @@
-{ config, lib, pkgs, ... }:
+{ config, lib, utils, pkgs, ... }:
 
 with lib;
 
 let
-
   ids = config.ids;
   cfg = config.users;
 
@@ -103,7 +102,7 @@ let
       };
 
       home = mkOption {
-        type = types.str;
+        type = types.path;
         default = "/var/empty";
         description = "The user's home directory.";
       };
@@ -118,8 +117,10 @@ let
       };
 
       shell = mkOption {
-        type = types.str;
-        default = "/run/current-system/sw/bin/nologin";
+        type = types.either types.shellPackage types.path;
+        default = pkgs.nologin;
+        defaultText = "pkgs.nologin";
+        example = literalExample "pkgs.bashInteractive";
         description = "The path to the user's shell.";
       };
 
@@ -359,11 +360,12 @@ let
 
   spec = pkgs.writeText "users-groups.json" (builtins.toJSON {
     inherit (cfg) mutableUsers;
-    users = mapAttrsToList (n: u:
+    users = mapAttrsToList (_: u:
       { inherit (u)
-          name uid group description home shell createHome isSystemUser
+          name uid group description home createHome isSystemUser
           password passwordFile hashedPassword
           initialPassword initialHashedPassword;
+        shell = utils.toShellPath u.shell;
       }) cfg.users;
     groups = mapAttrsToList (n: g:
       { inherit (g) name gid;
@@ -373,6 +375,12 @@ let
       }) cfg.groups;
   });
 
+  systemShells =
+    let
+      shells = mapAttrsToList (_: u: u.shell) cfg.users;
+    in
+      filter types.shellPackage.check shells;
+
 in {
 
   ###### interface
@@ -477,6 +485,9 @@ in {
       };
     };
 
+    # Install all the user shells
+    environment.systemPackages = systemShells;
+
     users.groups = {
       root.gid = ids.gids.root;
       wheel.gid = ids.gids.wheel;
diff --git a/nixos/modules/programs/bash/bash.nix b/nixos/modules/programs/bash/bash.nix
index e4e264ec0036..c09bcfb70e24 100644
--- a/nixos/modules/programs/bash/bash.nix
+++ b/nixos/modules/programs/bash/bash.nix
@@ -200,7 +200,7 @@ in
     # Configuration for readline in bash.
     environment.etc."inputrc".source = ./inputrc;
 
-    users.defaultUserShell = mkDefault "/run/current-system/sw/bin/bash";
+    users.defaultUserShell = mkDefault pkgs.bashInteractive;
 
     environment.pathsToLink = optionals cfg.enableCompletion [
       "/etc/bash_completion.d"
diff --git a/nixos/modules/programs/shadow.nix b/nixos/modules/programs/shadow.nix
index 566398d839fd..6398509357a6 100644
--- a/nixos/modules/programs/shadow.nix
+++ b/nixos/modules/programs/shadow.nix
@@ -1,6 +1,6 @@
 # Configuration for the pwdutils suite of tools: passwd, useradd, etc.
 
-{ config, lib, pkgs, ... }:
+{ config, lib, utils, pkgs, ... }:
 
 with lib;
 
@@ -43,13 +43,13 @@ in
     users.defaultUserShell = lib.mkOption {
       description = ''
         This option defines the default shell assigned to user
-        accounts.  This must not be a store path, since the path is
+        accounts. This can be either a full system path or a shell package.
+
+        This must not be a store path, since the path is
         used outside the store (in particular in /etc/passwd).
-        Rather, it should be the path of a symlink that points to the
-        actual shell in the Nix store.
       '';
-      example = "/run/current-system/sw/bin/zsh";
-      type = types.path;
+      example = literalExample "pkgs.zsh";
+      type = types.either types.path types.shellPackage;
     };
 
   };
@@ -60,7 +60,9 @@ in
   config = {
 
     environment.systemPackages =
-      lib.optional config.users.mutableUsers pkgs.shadow;
+      lib.optional config.users.mutableUsers pkgs.shadow ++
+      lib.optional (types.shellPackage.check config.users.defaultUserShell)
+        config.users.defaultUserShell;
 
     environment.etc =
       [ { # /etc/login.defs: global configuration for pwdutils.  You
@@ -74,7 +76,7 @@ in
             ''
               GROUP=100
               HOME=/home
-              SHELL=${config.users.defaultUserShell}
+              SHELL=${utils.toShellPath config.users.defaultUserShell}
             '';
           target = "default/useradd";
         }
diff --git a/pkgs/os-specific/linux/shadow/default.nix b/pkgs/os-specific/linux/shadow/default.nix
index 321e94e3aaf4..7f0d40f6be1f 100644
--- a/pkgs/os-specific/linux/shadow/default.nix
+++ b/pkgs/os-specific/linux/shadow/default.nix
@@ -53,5 +53,8 @@ stdenv.mkDerivation rec {
   meta = {
     homepage = http://pkg-shadow.alioth.debian.org/;
     description = "Suite containing authentication-related tools such as passwd and su";
+    passthru = {
+      shellPath = "/bin/nologin";
+    };
   };
 }
diff --git a/pkgs/shells/dash/default.nix b/pkgs/shells/dash/default.nix
index d3104439e578..1a95b4f42e6f 100644
--- a/pkgs/shells/dash/default.nix
+++ b/pkgs/shells/dash/default.nix
@@ -13,4 +13,8 @@ stdenv.mkDerivation rec {
     description = "A POSIX-compliant implementation of /bin/sh that aims to be as small as possible";
     hydraPlatforms = stdenv.lib.platforms.linux;
   };
+
+  passthru = {
+    shellPath = "/bin/dash";
+  };
 }
diff --git a/pkgs/shells/es/default.nix b/pkgs/shells/es/default.nix
index ba9fe29c33e6..037d1e1ec995 100644
--- a/pkgs/shells/es/default.nix
+++ b/pkgs/shells/es/default.nix
@@ -43,4 +43,8 @@ stdenv.mkDerivation {
     maintainers = [ maintainers.sjmackenzie ];
     platforms = platforms.all;
   };
+
+  passthru = {
+    shellPath = "/bin/es";
+  };
 }
diff --git a/pkgs/shells/fish/default.nix b/pkgs/shells/fish/default.nix
index 0124f914866c..353647f15b30 100644
--- a/pkgs/shells/fish/default.nix
+++ b/pkgs/shells/fish/default.nix
@@ -87,4 +87,8 @@ stdenv.mkDerivation rec {
     platforms = platforms.unix;
     maintainers = with maintainers; [ ocharles ];
   };
+
+  passthru = {
+    shellPath = "/bin/fish";
+  };
 }
diff --git a/pkgs/shells/mksh/default.nix b/pkgs/shells/mksh/default.nix
index 696777c7f1ff..dde890a022db 100644
--- a/pkgs/shells/mksh/default.nix
+++ b/pkgs/shells/mksh/default.nix
@@ -43,4 +43,8 @@ stdenv.mkDerivation rec {
     maintainers = with maintainers; [ AndersonTorres nckx ];
     platforms = platforms.unix;
   };
+
+  passthru = {
+    shellPath = "/bin/mksh";
+  };
 }
diff --git a/pkgs/shells/pash/default.nix b/pkgs/shells/pash/default.nix
index b9a8397e3ba1..0b424c897771 100644
--- a/pkgs/shells/pash/default.nix
+++ b/pkgs/shells/pash/default.nix
@@ -22,4 +22,8 @@ buildDotnetPackage rec {
     platforms = platforms.all;
     license = with licenses; [ bsd3 gpl3 ];
   };
+
+  passthru = {
+    shellPath = "/bin/pash";
+  };
 }
diff --git a/pkgs/shells/rush/default.nix b/pkgs/shells/rush/default.nix
index 3232caf5848b..bbad1f8cdf47 100644
--- a/pkgs/shells/rush/default.nix
+++ b/pkgs/shells/rush/default.nix
@@ -35,4 +35,8 @@ stdenv.mkDerivation rec {
     maintainers = [ stdenv.lib.maintainers.bjg ];
     platforms = stdenv.lib.platforms.all;
   };
+
+  passthru = {
+    shellPath = "/bin/rush";
+  };
 }
diff --git a/pkgs/shells/tcsh/default.nix b/pkgs/shells/tcsh/default.nix
index be182f87f1ee..764ea64f3cea 100644
--- a/pkgs/shells/tcsh/default.nix
+++ b/pkgs/shells/tcsh/default.nix
@@ -19,4 +19,8 @@ stdenv.mkDerivation rec {
     homepage = http://www.tcsh.org/;
     description = "An enhanced version of the Berkeley UNIX C shell (csh)";
   };
+
+  passthru = {
+    shellPath = "/bin/tcsh";
+  };
 }
diff --git a/pkgs/shells/xonsh/default.nix b/pkgs/shells/xonsh/default.nix
index 395132bc2d82..78edf83caf75 100644
--- a/pkgs/shells/xonsh/default.nix
+++ b/pkgs/shells/xonsh/default.nix
@@ -41,4 +41,8 @@ python3Packages.buildPythonApplication rec {
     maintainers = with maintainers; [ spwhitt garbas ];
     platforms = platforms.all;
   };
+
+  passthru = {
+    shellPath = "/bin/xonsh";
+  };
 }
diff --git a/pkgs/shells/zsh/default.nix b/pkgs/shells/zsh/default.nix
index fda3e77c61f4..261dbf12f8e5 100644
--- a/pkgs/shells/zsh/default.nix
+++ b/pkgs/shells/zsh/default.nix
@@ -80,4 +80,8 @@ EOF
     maintainers = with stdenv.lib.maintainers; [ chaoflow pSub ];
     platforms = stdenv.lib.platforms.unix;
   };
+
+  passthru = {
+    shellPath = "/bin/zsh";
+  };
 }
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index 7a5057e1c7be..b5fa553c2f9c 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -2250,6 +2250,9 @@ in
   else
     nodePackages_4_x;
 
+  # Can be used as a user shell
+  nologin = shadow;
+
   npm2nix = nodePackages.npm2nix;
 
   ldapvi = callPackage ../tools/misc/ldapvi { };