mirror of
https://github.com/gensokyo-zone/infrastructure.git
synced 2026-02-09 20:39:18 -08:00
chore: ipa and sssd modules
This commit is contained in:
parent
0a48d9cf5d
commit
95e903697a
14 changed files with 983 additions and 65 deletions
5
modules/extern/misc/args.nix
vendored
5
modules/extern/misc/args.nix
vendored
|
|
@ -4,10 +4,7 @@
|
|||
...
|
||||
}: let
|
||||
hasConfigLib = options ? lib;
|
||||
gensokyo-zone = {
|
||||
inherit inputs;
|
||||
inherit (inputs.self.lib) tree meta lib;
|
||||
};
|
||||
gensokyo-zone = inputs.self.lib.gensokyo-zone // {};
|
||||
in {
|
||||
config = {
|
||||
${
|
||||
|
|
|
|||
5
modules/nixos/args.nix
Normal file
5
modules/nixos/args.nix
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{ gensokyo-zone, ... }: {
|
||||
config.lib = {
|
||||
inherit gensokyo-zone;
|
||||
};
|
||||
}
|
||||
142
modules/nixos/ipa.nix
Normal file
142
modules/nixos/ipa.nix
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
gensokyo-zone,
|
||||
modulesPath,
|
||||
...
|
||||
}: let
|
||||
inherit (gensokyo-zone.lib) mkAlmostOptionDefault mkAlmostForce mapOptionDefaults;
|
||||
inherit (lib.options) mkOption mkPackageOption;
|
||||
inherit (lib.modules) mkIf mkMerge mkOptionDefault mkForce;
|
||||
inherit (lib.attrsets) mapAttrsToList;
|
||||
inherit (lib.strings) toLower;
|
||||
cfg = config.security.ipa;
|
||||
in {
|
||||
options.security.ipa = with lib.types; {
|
||||
package = mkPackageOption pkgs "freeipa" { };
|
||||
overrideConfigs = {
|
||||
krb5 = mkOption {
|
||||
type = bool;
|
||||
default = true;
|
||||
description = "allow the ipa module to override krb5.conf";
|
||||
};
|
||||
sssd = mkOption {
|
||||
type = bool;
|
||||
default = true;
|
||||
description = "allow the ipa module to override the sssd configuration";
|
||||
};
|
||||
ntp = mkOption {
|
||||
type = bool;
|
||||
default = false;
|
||||
description = "allow the ipa module to override the ntp configuration";
|
||||
};
|
||||
};
|
||||
};
|
||||
config.services.sssd = let
|
||||
inherit (config.services) sssd;
|
||||
ipaDebugLevel = 65510;
|
||||
in mkIf cfg.enable {
|
||||
debugLevel = mkAlmostOptionDefault ipaDebugLevel;
|
||||
domains = {
|
||||
${cfg.domain} = {
|
||||
ldap.extraAttrs.user = {
|
||||
mail = "mail";
|
||||
sn = "sn";
|
||||
givenname = "givenname";
|
||||
telephoneNumber = "telephoneNumber";
|
||||
lock = "nsaccountlock";
|
||||
};
|
||||
settings = mapOptionDefaults {
|
||||
id_provider = "ipa";
|
||||
auth_provider = "ipa";
|
||||
access_provider = "ipa";
|
||||
chpass_provider = "ipa";
|
||||
ipa_domain = cfg.domain;
|
||||
|
||||
ipa_server = [ "_srv_" cfg.server ];
|
||||
|
||||
ipa_hostname = "${config.networking.hostName}.${cfg.domain}";
|
||||
|
||||
cache_credentials = cfg.cacheCredentials;
|
||||
|
||||
krb5_store_password_if_offline = cfg.offlinePasswords;
|
||||
|
||||
dyndns_update = cfg.dyndns.enable;
|
||||
|
||||
dyndns_iface = cfg.dyndns.interface;
|
||||
|
||||
ldap_tls_cacert = "/etc/ipa/ca.crt";
|
||||
} // {
|
||||
krb5_realm = mkIf (toLower cfg.domain != toLower cfg.realm) (mkOptionDefault cfg.realm);
|
||||
};
|
||||
};
|
||||
};
|
||||
services = {
|
||||
nss.settings = mapOptionDefaults {
|
||||
homedir_substring = "/home";
|
||||
};
|
||||
pam.settings = mapOptionDefaults {
|
||||
pam_pwd_expiration_warning = 3;
|
||||
pam_verbosity = 3;
|
||||
};
|
||||
sudo = {
|
||||
enable = mkAlmostOptionDefault true;
|
||||
settings = mapOptionDefaults {
|
||||
debug_level = ipaDebugLevel;
|
||||
};
|
||||
};
|
||||
ssh.enable = mkAlmostOptionDefault true;
|
||||
ifp = {
|
||||
enable = mkAlmostOptionDefault true;
|
||||
settings = mapOptionDefaults {
|
||||
allowed_uids = cfg.ifpAllowedUids;
|
||||
};
|
||||
};
|
||||
};
|
||||
configText = mkIf (cfg.overrideConfigs.sssd) (mkAlmostOptionDefault null);
|
||||
config = mkIf (sssd.configText != null) (mkAlmostForce sssd.configText);
|
||||
};
|
||||
config.security.krb5 = mkIf cfg.enable {
|
||||
package = mkAlmostOptionDefault pkgs.krb5Full;
|
||||
settings = {
|
||||
libdefaults = mapOptionDefaults {
|
||||
default_realm = cfg.realm;
|
||||
dns_lookup_realm = false;
|
||||
dns_lookup_kdc = true;
|
||||
rdns = false;
|
||||
ticket_lifetime = "24h";
|
||||
forwardable = true;
|
||||
udp_preference_limit = 0;
|
||||
};
|
||||
realms.${cfg.realm} = mapOptionDefaults {
|
||||
kdc = "${cfg.server}:88";
|
||||
master_kdc = "${cfg.server}:88";
|
||||
admin_server = "${cfg.server}:749";
|
||||
default_domain = cfg.domain;
|
||||
pkinit_anchors = "/etc/ipa/ca.crt";
|
||||
};
|
||||
domain_realm = mkMerge [
|
||||
(mapOptionDefaults {
|
||||
".${cfg.domain}" = cfg.realm;
|
||||
${cfg.domain} = cfg.realm;
|
||||
})
|
||||
(mapOptionDefaults {
|
||||
${cfg.server} = cfg.realm;
|
||||
})
|
||||
];
|
||||
dbmodules.${cfg.realm} = {
|
||||
db_library = "${cfg.package}/lib/krb5/plugins/kdb/ipadb.so";
|
||||
};
|
||||
};
|
||||
};
|
||||
config.services.ntp = mkIf (cfg.enable && !cfg.overrideConfigs.ntp) {
|
||||
servers = mkForce config.networking.timeServers;
|
||||
};
|
||||
config.environment.etc."krb5.conf" = let
|
||||
inherit (config.security) krb5;
|
||||
format = import (modulesPath + "/security/krb5/krb5-conf-format.nix") { inherit pkgs lib; } { };
|
||||
in mkIf (cfg.enable && !cfg.overrideConfigs.krb5) {
|
||||
text = mkForce (format.generate "krb5.conf" krb5.settings).text;
|
||||
};
|
||||
}
|
||||
136
modules/nixos/krb5/genso.nix
Normal file
136
modules/nixos/krb5/genso.nix
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
{ gensokyo-zone, pkgs, config, lib, ... }: let
|
||||
inherit (gensokyo-zone.lib) mkBaseDn mapDefaults mkAlmostOptionDefault mapOptionDefaults domain;
|
||||
inherit (lib.options) mkOption mkEnableOption;
|
||||
inherit (lib.modules) mkIf mkDefault mkOptionDefault mkForce;
|
||||
inherit (lib.attrsets) mapAttrsToList;
|
||||
inherit (lib.strings) toUpper concatStringsSep concatStrings;
|
||||
inherit (config.security) krb5 ipa;
|
||||
cfg = krb5.gensokyo-zone;
|
||||
enabled = krb5.enable || ipa.enable;
|
||||
subsection = attrs: "{\n" + concatStrings (mapAttrsToList (key: value: " ${key} = ${value}\n") attrs) + "}";
|
||||
in {
|
||||
options.security.krb5.gensokyo-zone = with lib.types; {
|
||||
enable = mkEnableOption "realm";
|
||||
host = mkOption {
|
||||
type = str;
|
||||
default = cfg.canonHost;
|
||||
};
|
||||
canonHost = mkOption {
|
||||
type = str;
|
||||
default = "idp.${cfg.domain}";
|
||||
};
|
||||
domain = mkOption {
|
||||
type = str;
|
||||
default = domain;
|
||||
};
|
||||
realm = mkOption {
|
||||
type = str;
|
||||
default = toUpper cfg.domain;
|
||||
};
|
||||
ca.cert = mkOption {
|
||||
type = path;
|
||||
};
|
||||
ldap = {
|
||||
baseDn = mkOption {
|
||||
type = str;
|
||||
default = mkBaseDn cfg.domain;
|
||||
};
|
||||
bind = {
|
||||
dn = mkOption {
|
||||
type = str;
|
||||
default = "uid=peep,cn=sysaccounts,cn=etc,${cfg.ldap.base}";
|
||||
};
|
||||
passwordFile = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
};
|
||||
};
|
||||
urls = mkOption {
|
||||
type = listOf str;
|
||||
};
|
||||
};
|
||||
db.backend = mkOption {
|
||||
type = enum [ "kldap" "ipa" ];
|
||||
default = "kldap";
|
||||
};
|
||||
authToLocalNames = mkOption {
|
||||
type = attrsOf str;
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
config = {
|
||||
security.krb5 = {
|
||||
package = let
|
||||
krb5-ldap = pkgs.krb5.override {
|
||||
withLdap = true;
|
||||
};
|
||||
in mkIf (cfg.enable && cfg.db.backend == "kldap") (mkDefault pkgs.krb5-ldap or krb5-ldap);
|
||||
settings = mkIf cfg.enable {
|
||||
dbmodules = {
|
||||
genso-kldap = mkIf (cfg.db.backend == "kldap") (mapDefaults {
|
||||
db_library = "kldap";
|
||||
ldap_servers = concatStringsSep " " cfg.ldap.urls;
|
||||
ldap_kdc_dn = cfg.ldap.bind.dn;
|
||||
ldap_kerberos_container_dn = cfg.ldap.baseDn;
|
||||
} // {
|
||||
ldap_service_password_file = mkIf (cfg.ldap.bind.passwordFile != null) (mkDefault cfg.ldap.bind.passwordFile);
|
||||
});
|
||||
genso-ipa = mkIf (cfg.db.backend == "ipa") (mapDefaults {
|
||||
db_library = "${ipa.package}/lib/krb5/plugins/kdb/ipadb.so";
|
||||
});
|
||||
${cfg.realm} = mkIf ipa.enable (mkForce { });
|
||||
};
|
||||
realms.${cfg.realm} = mapDefaults {
|
||||
kdc = "${cfg.host}:88";
|
||||
master_kdc = "${cfg.host}:88";
|
||||
admin_server = "${cfg.host}:749";
|
||||
default_domain = cfg.domain;
|
||||
pkinit_anchors = [ "FILE:${cfg.ca.cert}" ];
|
||||
} // {
|
||||
database_module = mkOptionDefault "genso-${cfg.db.backend}";
|
||||
auth_to_local_names = mkIf (cfg.authToLocalNames != { }) (mkDefault (subsection cfg.authToLocalNames));
|
||||
};
|
||||
domain_realm = mapOptionDefaults {
|
||||
${cfg.domain} = cfg.realm;
|
||||
".${cfg.domain}" = cfg.realm;
|
||||
};
|
||||
libdefaults = mapOptionDefaults {
|
||||
default_realm = cfg.realm;
|
||||
dns_lookup_realm = false;
|
||||
dns_lookup_kdc = true;
|
||||
rdns = false;
|
||||
ticket_lifetime = "24h";
|
||||
forwardable = true;
|
||||
udp_preference_limit = 0;
|
||||
ignore_acceptor_hostname = true;
|
||||
};
|
||||
};
|
||||
gensokyo-zone = {
|
||||
ca.cert = let
|
||||
caPem = pkgs.fetchurl {
|
||||
name = "${cfg.canonHost}.ca.pem";
|
||||
url = "https://freeipa.${cfg.domain}/ipa/config/ca.crt";
|
||||
sha256 = "sha256-PKjnjn1jIq9x4BX8+WGkZfj4HQtmnHqmFSALqggo91o=";
|
||||
};
|
||||
in mkOptionDefault caPem;
|
||||
db.backend = mkIf ipa.enable (mkAlmostOptionDefault "ipa");
|
||||
ldap.urls = mkOptionDefault [
|
||||
"ldaps://ldap.${cfg.domain}"
|
||||
"ldaps://${cfg.canonHost}"
|
||||
];
|
||||
};
|
||||
};
|
||||
networking.timeServers = mkIf (cfg.enable && enabled) [ "2.fedora.pool.ntp.org" ];
|
||||
security.ipa = mkIf cfg.enable {
|
||||
certificate = mkDefault cfg.ca.cert;
|
||||
basedn = mkDefault cfg.ldap.baseDn;
|
||||
domain = mkDefault cfg.domain;
|
||||
realm = mkDefault cfg.realm;
|
||||
server = mkDefault cfg.canonHost;
|
||||
ifpAllowedUids = [
|
||||
"root"
|
||||
] ++ config.users.groups.wheel.members;
|
||||
dyndns.enable = mkDefault false;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -73,7 +73,6 @@ in {
|
|||
netgroup = mkMerge [
|
||||
(mkBefore [ "files" ])
|
||||
(mkAfter [ "nis" ])
|
||||
(mkIf config.services.sssd.enable [ "sss" ])
|
||||
];
|
||||
};
|
||||
environment.etc."nsswitch.conf".text = mkIf (nssDatabases.netgroup != [ ]) (mkAfter ''
|
||||
|
|
|
|||
194
modules/nixos/sssd/genso.nix
Normal file
194
modules/nixos/sssd/genso.nix
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
{ gensokyo-zone, pkgs, config, lib, ... }: let
|
||||
inherit (gensokyo-zone.lib) mkAlmostOptionDefault mapOptionDefaults mapAlmostOptionDefaults;
|
||||
inherit (lib.options) mkOption mkEnableOption;
|
||||
inherit (lib.modules) mkIf mkMerge mkAfter mkDefault mkOptionDefault;
|
||||
inherit (config.security) krb5 ipa;
|
||||
inherit (config.services) sssd;
|
||||
genso = krb5.gensokyo-zone;
|
||||
cfg = sssd.gensokyo-zone;
|
||||
serverModule = { config, ... }: {
|
||||
options = with lib.types; {
|
||||
servers = mkOption {
|
||||
type = nullOr (listOf str);
|
||||
default = null;
|
||||
};
|
||||
backups = mkOption {
|
||||
type = listOf str;
|
||||
default = [ ];
|
||||
};
|
||||
serverName = mkOption {
|
||||
type = str;
|
||||
internal = true;
|
||||
};
|
||||
serverKind = mkOption {
|
||||
type = enum [ "server" "uri" ];
|
||||
default = "server";
|
||||
internal = true;
|
||||
};
|
||||
settings = mkOption {
|
||||
type = attrsOf (listOf str);
|
||||
};
|
||||
};
|
||||
config = let
|
||||
key = "${config.serverName}_${config.serverKind}";
|
||||
keyBackups = "${config.serverName}_backup_${config.serverKind}";
|
||||
in {
|
||||
settings = {
|
||||
${key} = mkIf (config.servers != null) (mkOptionDefault config.servers);
|
||||
${keyBackups} = mkIf (config.backups != [ ]) (mkOptionDefault config.backups);
|
||||
};
|
||||
};
|
||||
};
|
||||
mkServerType = { modules }: lib.types.submoduleWith {
|
||||
modules = [ serverModule ] ++ modules;
|
||||
specialArgs = {
|
||||
inherit gensokyo-zone pkgs;
|
||||
nixosConfig = config;
|
||||
};
|
||||
};
|
||||
mkServerOption = { name, kind ? "server" }: let
|
||||
serverInfoModule = { ... }: {
|
||||
config = {
|
||||
serverName = mkOptionDefault name;
|
||||
serverKind = mkAlmostOptionDefault kind;
|
||||
};
|
||||
};
|
||||
in mkOption {
|
||||
type = mkServerType {
|
||||
modules = [ serverInfoModule ];
|
||||
};
|
||||
default = { };
|
||||
};
|
||||
in {
|
||||
options.services.sssd.gensokyo-zone = with lib.types; {
|
||||
enable = mkEnableOption "realm" // {
|
||||
default = genso.enable;
|
||||
};
|
||||
ldap = {
|
||||
bind = {
|
||||
passwordFile = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
};
|
||||
};
|
||||
uris = mkServerOption { name = "ldap"; kind = "uri"; };
|
||||
};
|
||||
krb5 = {
|
||||
servers = mkServerOption { name = "krb5"; };
|
||||
};
|
||||
ipa = {
|
||||
servers = mkServerOption { name = "ipa"; } // {
|
||||
default = {
|
||||
inherit (cfg.krb5.servers) servers backups;
|
||||
};
|
||||
};
|
||||
hostName = mkOption {
|
||||
type = str;
|
||||
default = config.networking.fqdn;
|
||||
};
|
||||
};
|
||||
backend = mkOption {
|
||||
type = enum [ "ldap" "ipa" ];
|
||||
default = "ipa";
|
||||
};
|
||||
};
|
||||
config = {
|
||||
services.sssd = let
|
||||
# or "ipaNTSecurityIdentifier" which isn't set for most groups, maybe check netgroups..?
|
||||
objectsid = "sambaSID";
|
||||
backendDomainSettings = {
|
||||
ldap = mapAlmostOptionDefaults {
|
||||
id_provider = mkDefault "ldap";
|
||||
auth_provider = mkDefault "krb5";
|
||||
access_provider = "ldap";
|
||||
ldap_tls_cacert = "/etc/ssl/certs/ca-bundle.crt";
|
||||
} // mapOptionDefaults {
|
||||
ldap_access_order = [ "host" ];
|
||||
ldap_schema = "IPA";
|
||||
ldap_default_bind_dn = genso.ldap.bind.dn;
|
||||
ldap_search_base = genso.ldap.baseDn;
|
||||
ldap_user_search_base = "cn=users,cn=accounts,${genso.ldap.baseDn}";
|
||||
ldap_group_search_base = "cn=groups,cn=accounts,${config.ldap.baseDn}";
|
||||
ldap_user_uuid = "ipaUniqueID";
|
||||
ldap_user_ssh_public_key = "ipaSshPubKey";
|
||||
ldap_user_objectsid = objectsid;
|
||||
ldap_group_uuid = "ipaUniqueID";
|
||||
ldap_group_objectsid = objectsid;
|
||||
};
|
||||
ipa = mapOptionDefaults {
|
||||
id_provider = "ipa";
|
||||
auth_provider = "ipa";
|
||||
access_provider = "ipa";
|
||||
chpass_provider = "ipa";
|
||||
dyndns_update = ipa.dyndns.enable;
|
||||
dyndns_iface = ipa.dyndns.interface;
|
||||
};
|
||||
};
|
||||
domainSettings = mapAlmostOptionDefaults {
|
||||
ipa_hostname = cfg.ipa.hostName;
|
||||
} // mapOptionDefaults {
|
||||
enumerate = true;
|
||||
ipa_domain = genso.domain;
|
||||
krb5_realm = genso.realm;
|
||||
cache_credentials = ipa.cacheCredentials;
|
||||
krb5_store_password_if_offline = ipa.offlinePasswords;
|
||||
#min_id = 8000;
|
||||
#max_id = 8999;
|
||||
};
|
||||
in {
|
||||
gensokyo-zone = {
|
||||
krb5.servers.servers = mkMerge [
|
||||
[ genso.host ]
|
||||
(mkAfter [ "_srv" genso.canonHost ])
|
||||
];
|
||||
ldap.uris = {
|
||||
servers = mkMerge [
|
||||
(mkAfter [ "_srv" ])
|
||||
genso.ldap.urls
|
||||
];
|
||||
};
|
||||
};
|
||||
domains = mkIf cfg.enable {
|
||||
${genso.domain} = {
|
||||
ldap = {
|
||||
authtok = mkIf (cfg.backend == "ldap") {
|
||||
passwordFile = mkIf (cfg.ldap.bind.passwordFile != null) (mkAlmostOptionDefault cfg.ldap.bind.passwordFile);
|
||||
};
|
||||
extraAttrs.user = {
|
||||
mail = "mail";
|
||||
sn = "sn";
|
||||
givenname = "givenname";
|
||||
telephoneNumber = "telephoneNumber";
|
||||
lock = "nsaccountlock";
|
||||
};
|
||||
};
|
||||
settings = mkMerge [
|
||||
domainSettings
|
||||
backendDomainSettings.${cfg.backend}
|
||||
(mapAlmostOptionDefaults cfg.ldap.uris.settings)
|
||||
(mapAlmostOptionDefaults cfg.krb5.servers.settings)
|
||||
(mkIf (cfg.backend == "ipa") (mapAlmostOptionDefaults cfg.ipa.servers.settings))
|
||||
];
|
||||
};
|
||||
};
|
||||
services = mkIf cfg.enable {
|
||||
nss.settings = mapOptionDefaults {
|
||||
homedir_substring = "/home";
|
||||
};
|
||||
pam.settings = mapOptionDefaults {
|
||||
pam_pwd_expiration_warning = 3;
|
||||
pam_verbosity = 3;
|
||||
};
|
||||
sudo.enable = mkIf (!sssd.services.pam.enable) (mkDefault false);
|
||||
ssh.enable = mkIf (!sssd.services.pam.enable) (mkDefault false);
|
||||
ifp = {
|
||||
enable = mkAlmostOptionDefault true;
|
||||
settings = mapOptionDefaults {
|
||||
allowed_uids = ipa.ifpAllowedUids;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
210
modules/nixos/sssd/sssd.nix
Normal file
210
modules/nixos/sssd/sssd.nix
Normal file
|
|
@ -0,0 +1,210 @@
|
|||
{
|
||||
config,
|
||||
options,
|
||||
lib,
|
||||
gensokyo-zone,
|
||||
...
|
||||
}: let
|
||||
inherit (gensokyo-zone.lib) mkAlmostOptionDefault mapOptionDefaults;
|
||||
inherit (lib.options) mkOption mkEnableOption;
|
||||
inherit (lib.modules) mkIf mkMerge mkOptionDefault mkForce;
|
||||
inherit (lib.attrsets) mapAttrs filterAttrs attrNames attrValues listToAttrs mapAttrsToList nameValuePair;
|
||||
inherit (lib.lists) filter isList concatMap;
|
||||
inherit (lib.strings) toUpper concatMapStringsSep replaceStrings;
|
||||
inherit (lib.trivial) flip;
|
||||
inherit (lib) generators;
|
||||
cfg = config.services.sssd;
|
||||
mkValuePrimitive = value:
|
||||
if value == true then "True"
|
||||
else if value == false then "False"
|
||||
else toString value;
|
||||
toINI = generators.toINI {
|
||||
mkKeyValue = generators.mkKeyValueDefault {
|
||||
mkValueString = value:
|
||||
if isList value then concatMapStringsSep ", " mkValuePrimitive value
|
||||
else mkValuePrimitive value;
|
||||
} " = ";
|
||||
};
|
||||
primitiveType = with lib.types; oneOf [ str int bool ];
|
||||
valueType = with lib.types; oneOf [ primitiveType (listOf primitiveType) ];
|
||||
settingsType = lib.types.attrsOf valueType;
|
||||
serviceModule = { name, ... }: {
|
||||
options = with lib.types; {
|
||||
enable = mkEnableOption "${name} service";
|
||||
name = mkOption {
|
||||
type = str;
|
||||
default = name;
|
||||
readOnly = true;
|
||||
};
|
||||
settings = mkOption {
|
||||
type = settingsType;
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
nssModule = { nixosConfig, ... }: {
|
||||
options = {
|
||||
# TODO: passwd.enable = mkEnableOption "passwd" // { default = true; };
|
||||
shadow.enable = mkEnableOption "shadow" // { default = nixosConfig.services.sssd.services.pam.enable; };
|
||||
netgroup.enable = mkEnableOption "netgroup" // { default = true; };
|
||||
};
|
||||
};
|
||||
domainModule = { name, ... }: {
|
||||
options = with lib.types; {
|
||||
enable = mkEnableOption "domain" // {
|
||||
default = true;
|
||||
};
|
||||
domain = mkOption {
|
||||
type = str;
|
||||
default = name;
|
||||
};
|
||||
settings = mkOption {
|
||||
type = settingsType;
|
||||
};
|
||||
};
|
||||
};
|
||||
domainLdapModule = { config, ... }: let
|
||||
cfg = config.ldap;
|
||||
in {
|
||||
options.ldap = with lib.types; {
|
||||
extraAttrs.user = mkOption {
|
||||
type = attrsOf str;
|
||||
default = { };
|
||||
};
|
||||
authtok = {
|
||||
type = mkOption {
|
||||
type = enum [ "password" "obfuscated_password" ];
|
||||
default = "password";
|
||||
};
|
||||
password = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
};
|
||||
passwordFile = mkOption {
|
||||
type = nullOr path;
|
||||
default = null;
|
||||
};
|
||||
passwordVar = mkOption {
|
||||
type = str;
|
||||
internal = true;
|
||||
default = "SSSD_AUTHTOK_" + replaceStrings [ "-" "." ] [ "_" "_" ] (toUpper config.domain);
|
||||
};
|
||||
};
|
||||
};
|
||||
config = let
|
||||
authtokConfig = mkIf (cfg.authtok.password != null || cfg.authtok.passwordFile != null) {
|
||||
ldap_default_authtok_type = mkOptionDefault cfg.authtok.type;
|
||||
ldap_default_authtok = mkOptionDefault (
|
||||
if cfg.authtok.passwordFile != null then "\$${cfg.authtok.passwordVar}"
|
||||
else cfg.authtok.password
|
||||
);
|
||||
};
|
||||
extraAttrsConfig = mkIf (cfg.extraAttrs.user != { }) {
|
||||
ldap_user_extra_attrs = let
|
||||
mkAttr = name: attr: "${name}:${attr}";
|
||||
in mapAttrsToList mkAttr cfg.extraAttrs.user;
|
||||
};
|
||||
in {
|
||||
settings = mkMerge [
|
||||
authtokConfig
|
||||
extraAttrsConfig
|
||||
];
|
||||
};
|
||||
};
|
||||
in {
|
||||
options.services.sssd = with lib.types; {
|
||||
debugLevel = mkOption {
|
||||
type = ints.between 16 65520;
|
||||
default = 16;
|
||||
};
|
||||
domains = mkOption {
|
||||
type = attrsOf (submoduleWith {
|
||||
modules = [ domainModule domainLdapModule ];
|
||||
specialArgs = {
|
||||
nixosConfig = config;
|
||||
};
|
||||
});
|
||||
default = {
|
||||
shadowutils.settings = mapOptionDefaults {
|
||||
id_provider = "proxy";
|
||||
proxy_lib_name = "files";
|
||||
auth_provider = "proxy";
|
||||
proxy_pam_target = "sssd-shadowutils";
|
||||
proxy_fast_alias = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
services = let
|
||||
mkServiceOption = name: { modules ? [ ] }: mkOption {
|
||||
type = submoduleWith {
|
||||
modules = [ serviceModule ] ++ modules;
|
||||
specialArgs = {
|
||||
inherit name;
|
||||
nixosConfig = config;
|
||||
};
|
||||
};
|
||||
};
|
||||
services = {
|
||||
nss = { modules = [ nssModule ]; };
|
||||
pam = { };
|
||||
ifp = { };
|
||||
sudo = { };
|
||||
autofs = { };
|
||||
ssh = { };
|
||||
pac = { };
|
||||
};
|
||||
in mapAttrs mkServiceOption services;
|
||||
settings = mkOption {
|
||||
type = attrsOf settingsType;
|
||||
};
|
||||
configText = mkOption {
|
||||
type = nullOr lines;
|
||||
};
|
||||
};
|
||||
config.services.sssd = let
|
||||
enabledDomains = filter (domain: domain.enable) (attrValues cfg.domains);
|
||||
enabledServices = filterAttrs (_: service: service.enable) cfg.services;
|
||||
in {
|
||||
settings = let
|
||||
serviceSettings = mapAttrs (name: service: mapOptionDefaults service.settings) enabledServices;
|
||||
defaultSettings = {
|
||||
sssd = mapOptionDefaults {
|
||||
config_file_version = 2;
|
||||
debug_level = cfg.debugLevel;
|
||||
services = mapAttrsToList (_: service: service.name) enabledServices;
|
||||
domains = map (domain: domain.domain) enabledDomains;
|
||||
};
|
||||
};
|
||||
domainSettings = map (domain: {
|
||||
"domain/${domain.domain}" = mapAttrs (_: mkOptionDefault) domain.settings;
|
||||
}) enabledDomains;
|
||||
settings = [ defaultSettings serviceSettings ] ++ domainSettings;
|
||||
in mkMerge settings;
|
||||
services = {
|
||||
nss.enable = mkAlmostOptionDefault true;
|
||||
pam.enable = mkAlmostOptionDefault true;
|
||||
ifp.settings = let
|
||||
extraUserAttrs = listToAttrs (concatMap (domain: map (flip nameValuePair {}) (attrNames domain.ldap.extraAttrs.user)) enabledDomains);
|
||||
mkExtraAttr = name: _: "+${name}";
|
||||
in {
|
||||
user_attributes = mkIf (extraUserAttrs != { }) (mkOptionDefault (
|
||||
mapAttrsToList mkExtraAttr extraUserAttrs
|
||||
));
|
||||
};
|
||||
sudo = { };
|
||||
autofs = { };
|
||||
ssh = { };
|
||||
pac = { };
|
||||
};
|
||||
configText = mkOptionDefault (toINI cfg.settings);
|
||||
config = mkIf (cfg.configText != null) (mkAlmostOptionDefault cfg.configText);
|
||||
};
|
||||
config.system.nssDatabases = let
|
||||
inherit (cfg.services) nss;
|
||||
in mkIf cfg.enable {
|
||||
${if options ? system.nssDatabases.netgroup then "netgroup" else null} = mkIf (nss.enable && nss.netgroup.enable) [ "sss" ];
|
||||
shadow = mkIf (!nss.enable || !nss.shadow.enable) (
|
||||
mkForce [ "files" ]
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
@ -100,6 +100,7 @@ in {
|
|||
}) config.builder);
|
||||
specialArgs = {
|
||||
inherit name inputs std meta;
|
||||
inherit (inputs.self.lib) gensokyo-zone;
|
||||
systemType = config.folder;
|
||||
system = config;
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue