summaryrefslogtreecommitdiffstats
path: root/krebs/3modules/shadow.nix
diff options
context:
space:
mode:
authorjeschli <jeschli@gmail.com>2019-04-28 15:05:34 +0200
committerjeschli <jeschli@gmail.com>2019-04-28 15:05:34 +0200
commite45b3492b3961685936378a160adb225789e51d9 (patch)
treecc0480e485ab78d1f52f80ec36987b9a57e925f7 /krebs/3modules/shadow.nix
parent97d4f9a771a9bbb1b45085569028db2d7dfbd610 (diff)
parent915e4b843790d3e71bdccea124d4832ca042e456 (diff)
Merge branch 'master' of prism.r:stockholm
Diffstat (limited to 'krebs/3modules/shadow.nix')
-rw-r--r--krebs/3modules/shadow.nix79
1 files changed, 79 insertions, 0 deletions
diff --git a/krebs/3modules/shadow.nix b/krebs/3modules/shadow.nix
new file mode 100644
index 000000000..cff66492d
--- /dev/null
+++ b/krebs/3modules/shadow.nix
@@ -0,0 +1,79 @@
+with import <stockholm/lib>;
+{ config, pkgs, ... }: let
+
+ cfg = config.krebs.shadow;
+
+ mergeShadowsJq = pkgs.writeJq "merge-shadows.jq" ''
+ def fields_3_to_9: ["1", "", "", "", "", "", ""];
+
+ def read_value:
+ split(":") |
+ if length == 9 then
+ if .[2:] == fields_3_to_9 then
+ .
+ else
+ error("unrecognized field contents")
+ end
+ elif length == 2 then
+ if .[1] | test("^\\$6\\$") then
+ . + fields_3_to_9
+ else
+ error("unrecognized hashed password")
+ end
+ else
+ error("unexpected field count: expected 9 or 2, got \(length)")
+ end;
+
+ def write_value:
+ join(":");
+
+ split("\n") |
+ map(select(length > 0) | read_value) |
+
+ reverse |
+ unique_by(.[0]) |
+ map(write_value) |
+ sort |
+
+ join("\n")
+ '';
+
+in {
+
+ options.krebs.shadow = {
+ enable = mkEnableOption "krebs.shadow" // {
+ default = cfg.overridesFile != null;
+ };
+ overridesFile = mkOption {
+ apply = x: if typeOf x == "path" then toString x else x;
+ default = null;
+ description = ''
+ Path to a file containing additional shadow entries, used for adding
+ encrypted passwords which should not be placed into the Nix store.
+
+ The overrides file may contain either regular shadow(5) entries like:
+
+ <code>&lt;login-name&gt;:&lt;hashed-password&gt;:1::::::</code>
+
+ Or shortened entries only containing login name and password like:
+
+ <code>&lt;login-name&gt;:&lt;hashed-password&gt</code>
+ '';
+ type = types.nullOr (types.either types.path types.absolute-pathname);
+ };
+ };
+
+ config = let
+ in mkIf cfg.enable {
+ system.activationScripts.users-tv = stringAfter [ "users" ] /* sh */ ''
+ (
+ set -efu
+ umask 77
+ ${pkgs.jq}/bin/jq -Rrs -f ${mergeShadowsJq} \
+ /etc/shadow ${cfg.overridesFile} > /etc/shadow~
+ ${pkgs.coreutils}/bin/mv /etc/shadow /etc/shadow-
+ ${pkgs.coreutils}/bin/mv /etc/shadow~ /etc/shadow
+ )
+ '';
+ };
+}