users.nix (2442B)
1 { lib, pkgs, config, ...}: 2 let 3 inherit (lib) 4 concatStrings concatStringsSep mapAttrsToList mkOption types; 5 inherit (builtins) toString; 6 inherit (pkgs.pseudofile) dir symlink; 7 passwd-file = 8 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" ) 9 config.users; 10 in concatStrings lines; 11 group-file = 12 let lines = mapAttrsToList 13 (name: {gid, usernames ? []}: 14 "${name}:x:${toString gid}:${concatStringsSep "," usernames}\n" ) 15 config.groups; 16 in concatStrings lines; 17 in { 18 options = { 19 users = mkOption { 20 type = types.attrsOf (types.submodule { 21 options = { 22 passwd = mkOption { 23 type = types.str; 24 default = "!!"; 25 }; 26 uid = mkOption { 27 type = types.int; 28 }; 29 gid = mkOption { 30 type = types.int; 31 }; 32 gecos = mkOption { 33 type = types.str; 34 default = ""; 35 example = "Jo Q User"; 36 }; 37 dir = mkOption { 38 type = types.str; 39 default = "/run"; 40 }; 41 shell = mkOption { 42 type = types.str; 43 default = "/bin/sh"; 44 }; 45 openssh.authorizedKeys.keys = mkOption { 46 type = types.listOf types.str; 47 default = []; 48 }; 49 }; 50 }); 51 }; 52 groups = mkOption { 53 type = types.attrsOf (types.submodule { 54 options = { 55 gid = mkOption { 56 type = types.int; 57 }; 58 usernames = mkOption { 59 type = types.listOf types.str; 60 default = []; 61 }; 62 }; 63 }); 64 }; 65 }; 66 config = 67 let authorized_key_files = 68 lib.attrsets.mapAttrs 69 (name: val: dir { 70 ".ssh" = dir { 71 authorized_keys = { 72 inherit (val) uid gid; 73 type = "f"; 74 mode = "0400"; 75 file = lib.concatStringsSep 76 "\n" val.openssh.authorizedKeys.keys; 77 }; 78 }; 79 }) 80 config.users; 81 in { 82 filesystem = dir { 83 etc = dir { 84 passwd = { file = passwd-file; }; 85 group = { file = group-file; }; 86 }; 87 home = dir authorized_key_files; 88 }; 89 }; 90 }