2021-02-23 12:58:29 -08:00
|
|
|
{ config, lib, pkgs, ... }:
|
|
|
|
|
|
|
|
with lib;
|
|
|
|
let
|
|
|
|
systemUserOpts = { username, ... }: {
|
|
|
|
options = {
|
|
|
|
username = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
description = "The system user's login name.";
|
|
|
|
default = username;
|
|
|
|
};
|
|
|
|
|
|
|
|
description = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
description = "Description of this system user's purpose or role";
|
|
|
|
};
|
|
|
|
|
|
|
|
ldap-hashed-password = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
description =
|
|
|
|
"LDAP-formatted hashed password for this user. Generate with slappasswd.";
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
userOpts = { username, ... }: {
|
|
|
|
options = {
|
|
|
|
username = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
description = "The user's login name.";
|
|
|
|
default = username;
|
|
|
|
};
|
|
|
|
|
2021-02-25 12:45:50 -08:00
|
|
|
uid = mkOption {
|
2021-02-23 12:58:29 -08:00
|
|
|
type = types.int;
|
|
|
|
description = "Unique UID number for the user.";
|
|
|
|
};
|
|
|
|
|
|
|
|
common-name = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
description = "The user's common or given name.";
|
|
|
|
};
|
|
|
|
|
|
|
|
primary-group = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
description = "Primary group to which the user belongs.";
|
|
|
|
};
|
|
|
|
|
|
|
|
login-shell = mkOption {
|
|
|
|
type = with types; nullOr shellPackage;
|
|
|
|
description = "The user's preferred shell.";
|
|
|
|
};
|
|
|
|
|
|
|
|
description = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
default = "Fudo Member";
|
|
|
|
description = "A description of this user's role.";
|
|
|
|
};
|
|
|
|
|
|
|
|
ldap-hashed-passwd = mkOption {
|
|
|
|
type = with types; nullOr str;
|
|
|
|
description =
|
|
|
|
"LDAP-formatted hashed password, used for email and other services. Use slappasswd to generate the properly-formatted password.";
|
|
|
|
default = null;
|
|
|
|
};
|
|
|
|
|
|
|
|
login-hashed-passwd = mkOption {
|
|
|
|
type = with types; nullOr str;
|
|
|
|
description =
|
|
|
|
"Hashed password for shell, used for shell access to hosts. Use mkpasswd to generate the properly-formatted password.";
|
|
|
|
default = null;
|
|
|
|
};
|
|
|
|
|
|
|
|
ssh-authorized-keys = mkOption {
|
|
|
|
type = with types; listOf str;
|
|
|
|
description = "SSH public keys this user can use to log in.";
|
|
|
|
default = [ ];
|
|
|
|
};
|
|
|
|
|
|
|
|
home-manager-config = mkOption {
|
|
|
|
type = with types; nullOr attrs;
|
|
|
|
description = "Home Manager configuration for the given user.";
|
|
|
|
default = null;
|
|
|
|
};
|
|
|
|
|
|
|
|
home-directory = mkOption {
|
2021-02-25 12:45:50 -08:00
|
|
|
type = with types; nullOr str;
|
2021-02-23 12:58:29 -08:00
|
|
|
description = "Default home directory for the given user.";
|
2021-02-25 12:45:50 -08:00
|
|
|
default = null;
|
2021-02-23 12:58:29 -08:00
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
groupOpts = { group-name, ... }: {
|
|
|
|
options = {
|
|
|
|
group-name = mkOption {
|
|
|
|
type = with types; nullOr str;
|
|
|
|
default = group-name;
|
|
|
|
description = "Group name.";
|
|
|
|
};
|
|
|
|
|
|
|
|
description = mkOption {
|
|
|
|
type = types.str;
|
|
|
|
description = "Description of the group or it's purpose.";
|
|
|
|
};
|
|
|
|
|
|
|
|
members = mkOption {
|
|
|
|
type = with types; listOf str;
|
|
|
|
default = [ ];
|
|
|
|
description = "A list of users who are members of the current group.";
|
|
|
|
};
|
|
|
|
|
2021-02-25 12:45:50 -08:00
|
|
|
gid = mkOption {
|
2021-02-23 12:58:29 -08:00
|
|
|
type = types.int;
|
|
|
|
description = "GID number of the group.";
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2021-02-25 12:45:50 -08:00
|
|
|
list-includes = list: el: isNull (findFirst (this: this == el) null list);
|
|
|
|
|
|
|
|
filterExistingUsers = users: group-members:
|
|
|
|
let user-list = attrNames users;
|
|
|
|
in filter (username: list-includes user-list username) group-members;
|
|
|
|
|
2021-02-23 12:58:29 -08:00
|
|
|
in {
|
|
|
|
options.fudo = {
|
|
|
|
users = mkOption {
|
|
|
|
type = with types; attrsOf (submodule userOpts);
|
|
|
|
description = "Users";
|
|
|
|
default = { };
|
|
|
|
};
|
|
|
|
|
|
|
|
groups = mkOption {
|
|
|
|
type = with types; attrsOf (submodule groupOpts);
|
|
|
|
description = "Groups";
|
|
|
|
default = { };
|
|
|
|
};
|
|
|
|
|
|
|
|
system-users = mkOption {
|
|
|
|
type = with types; attrsOf (submodule systemUserOpts);
|
|
|
|
description = "System users (probably not what you're looking for!)";
|
|
|
|
default = { };
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
config = let
|
2021-02-25 12:45:50 -08:00
|
|
|
local-host = config.instance.hostname;
|
|
|
|
local-domain = config.fudo.hosts.${local-host}.domain;
|
|
|
|
local-site = config.fudo.hosts.${local-host}.site;
|
2021-02-23 12:58:29 -08:00
|
|
|
|
2021-02-25 12:45:50 -08:00
|
|
|
host-user-list = config.fudo.hosts."${local-host}".local-users;
|
2021-02-23 12:58:29 -08:00
|
|
|
domain-user-list = config.fudo.domains."${local-domain}".local-users;
|
2021-02-25 12:45:50 -08:00
|
|
|
local-users = getAttrs (host-user-list ++ domain-user-list) config.fudo.users;
|
|
|
|
|
|
|
|
host-admin-list = config.fudo.hosts."${local-host}".local-admins;
|
|
|
|
domain-admin-list = config.fudo.domains."${local-domain}".local-admins;
|
|
|
|
site-admin-list = config.fudo.sites."${local-site}".local-admins;
|
|
|
|
local-admins = host-admin-list ++ domain-admin-list ++ site-admin-list;
|
2021-02-23 12:58:29 -08:00
|
|
|
|
2021-02-25 12:45:50 -08:00
|
|
|
host-group-list = config.fudo.hosts."${local-host}".local-groups;
|
2021-02-23 12:58:29 -08:00
|
|
|
domain-group-list = config.fudo.domains."${local-domain}".local-groups;
|
2021-02-25 12:45:50 -08:00
|
|
|
site-group-list = config.fudo.sites."${local-site}".local-groups;
|
|
|
|
local-groups = getAttrs (host-group-list ++ domain-group-list ++ site-group-list) config.fudo.groups;
|
2021-02-23 12:58:29 -08:00
|
|
|
|
|
|
|
in {
|
2021-02-25 12:45:50 -08:00
|
|
|
fudo.auth.ldap-server = let
|
2021-02-23 12:58:29 -08:00
|
|
|
ldapUsers = (filterAttrs
|
2021-02-25 12:45:50 -08:00
|
|
|
(username: userOpts: userOpts.ldap-hashed-password != null)) config.fudo.users;
|
2021-02-23 12:58:29 -08:00
|
|
|
|
|
|
|
in {
|
|
|
|
users = mapAttrs (username: userOpts: {
|
|
|
|
uid = userOpts.uid;
|
|
|
|
group = userOpts.primary-group;
|
|
|
|
common-name = userOpts.common-name;
|
|
|
|
hashed-password = userOpts.ldap-hashed-password;
|
|
|
|
}) ldapUsers;
|
|
|
|
|
|
|
|
groups = mapAttrs (groupname: groupOpts: {
|
|
|
|
gid = groupOpts.gid-number;
|
|
|
|
description = groupOpts.description;
|
|
|
|
members = filterExistingUsers ldapUsers groupOpts.members;
|
2021-02-25 12:45:50 -08:00
|
|
|
}) config.fudo.groups;
|
2021-02-23 12:58:29 -08:00
|
|
|
|
|
|
|
system-users = mapAttrs (username: userOpts: {
|
|
|
|
description = userOpts.description;
|
|
|
|
hashed-password = userOpts.ldap-hashed-passwd;
|
2021-02-25 12:45:50 -08:00
|
|
|
}) config.fudo.system-users;
|
2021-02-23 12:58:29 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
users = {
|
|
|
|
users = mapAttrs (username: userOpts: {
|
|
|
|
isNormalUser = true;
|
2021-02-25 12:45:50 -08:00
|
|
|
uid = userOpts.uid;
|
2021-02-23 12:58:29 -08:00
|
|
|
createHome = true;
|
|
|
|
description = userOpts.common-name;
|
|
|
|
group = userOpts.primary-group;
|
2021-02-25 12:45:50 -08:00
|
|
|
home = if (userOpts.home-directory != null) then userOpts.home-directory else "/home/${userOpts.primary-group}/${username}";
|
2021-02-23 12:58:29 -08:00
|
|
|
hashedPassword = userOpts.login-hashed-passwd;
|
|
|
|
openssh.authorizedKeys.keys = userOpts.ssh-authorized-keys;
|
|
|
|
}) local-users;
|
|
|
|
|
2021-02-25 12:45:50 -08:00
|
|
|
groups = (mapAttrs (groupname: groupOpts: {
|
|
|
|
gid = groupOpts.gid;
|
|
|
|
members = filterExistingUsers local-users groupOpts.members;
|
|
|
|
}) local-groups) //
|
|
|
|
{
|
|
|
|
wheel = {
|
|
|
|
members = local-admins;
|
|
|
|
};
|
|
|
|
};
|
2021-02-23 12:58:29 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
home-manager.users = let
|
|
|
|
home-manager-users =
|
|
|
|
filterAttrs (username: userOpts: userOpts.home-manager-config != null)
|
|
|
|
local-users;
|
|
|
|
|
|
|
|
in mapAttrs (username: userOpts: userOpts.home-manager-config)
|
|
|
|
home-manager-users;
|
|
|
|
};
|
|
|
|
}
|