users.nix (3095B)
1 ## Users 2 ## ===== 3 ## 4 ## User- and group-related configuration. 5 ## 6 ## Changes made here are reflected in files such as :file:/etc/shadow, 7 ## :file:/etc/passwd, :file:/etc/group etc. If you are familiar with 8 ## user configuration in NixOS, please note that Liminix does not have 9 ## the concept of "mutable users" - files in /etc/ are symlinks to 10 ## the immutable store, so you can't e.g change a password with 11 ## :command:`passwd` 12 13 14 { lib, pkgs, config, ...}: 15 let 16 inherit (lib) 17 concatStrings concatStringsSep mapAttrsToList mkOption types; 18 inherit (builtins) toString; 19 inherit (pkgs.pseudofile) dir symlink; 20 passwd-file = 21 let lines = mapAttrsToList (name: u: "${name}:${if u ? passwd then u.passwd else "!!"}:${toString u.uid}:${toString u.gid}:${u.gecos}:${u.dir}:${u.shell}\n" ) 22 config.users; 23 in concatStrings lines; 24 group-file = 25 let lines = mapAttrsToList 26 (name: {gid, usernames ? []}: 27 "${name}:x:${toString gid}:${concatStringsSep "," usernames}\n" ) 28 config.groups; 29 in concatStrings lines; 30 in { 31 options = { 32 users = mkOption { 33 type = types.attrsOf (types.submodule { 34 options = { 35 passwd = mkOption { 36 type = types.str; 37 description = "encrypted password, as generated by mkpasswd -m sha512crypt"; 38 example = "$6$RIYL.EgWOrtoJ0/7$Z53a8sc0o6AU/kuFOGiLJKhwVavTG/deoM7JTs6luNczYSUsh4UYmhvT8sVzm.l8F/LZXhhhkC7IHQs5UGAIM/"; 39 default = "!!"; 40 }; 41 uid = mkOption { 42 type = types.int; 43 }; 44 gid = mkOption { 45 type = types.int; 46 }; 47 gecos = mkOption { 48 type = types.str; 49 default = ""; 50 example = "Jo Q User"; 51 }; 52 dir = mkOption { 53 type = types.str; 54 default = "/run"; 55 }; 56 shell = mkOption { 57 type = types.str; 58 default = "/bin/sh"; 59 }; 60 openssh.authorizedKeys.keys = mkOption { 61 type = types.listOf types.str; 62 default = []; 63 }; 64 }; 65 }); 66 }; 67 groups = mkOption { 68 type = types.attrsOf (types.submodule { 69 options = { 70 gid = mkOption { 71 type = types.int; 72 }; 73 usernames = mkOption { 74 type = types.listOf types.str; 75 default = []; 76 }; 77 }; 78 }); 79 }; 80 }; 81 config = 82 let authorized_key_files = 83 lib.attrsets.mapAttrs 84 (name: val: dir { 85 ".ssh" = dir { 86 authorized_keys = { 87 inherit (val) uid gid; 88 type = "f"; 89 mode = "0400"; 90 file = lib.concatStringsSep 91 "\n" val.openssh.authorizedKeys.keys; 92 }; 93 }; 94 }) 95 config.users; 96 in { 97 filesystem = dir { 98 etc = dir { 99 passwd = { file = passwd-file; }; 100 group = { file = group-file; }; 101 }; 102 home = dir authorized_key_files; 103 }; 104 }; 105 }