feat(idp): more ldap objects

This commit is contained in:
arcnmx 2024-03-28 09:59:03 -07:00
parent 69508d43a3
commit 86ac38cf2c
11 changed files with 503 additions and 16 deletions

View file

@ -0,0 +1,26 @@
{
config,
lib,
...
}: let
inherit (lib.options) mkOption;
in {
options.users.ldap = with lib.types; {
domainDnSuffix = mkOption {
type = str;
default = "";
};
hostDnSuffix = mkOption {
type = str;
default = "";
};
serviceDnSuffix = mkOption {
type = str;
default = "";
};
sysAccountDnSuffix = mkOption {
type = str;
default = "";
};
};
}

View file

@ -118,7 +118,7 @@
ldapwhoami
ldapmodify -cf "$MAN_LDAP_ADD"
ldapmodify -cf "$MAN_LDAP_ADD" || true
ldapmodify -c -f "$MAN_LDAP_MODIFY" || true
@ -147,7 +147,7 @@ in {
LDAPBASE = ldap.base;
LDAPURI = "ldaps://ldap.int.${config.networking.domain}";
LDAPSASL_MECH = "GSSAPI";
LDAPSASL_AUTHCID = "dn:krbprincipalname=host/${config.networking.fqdn}@${config.security.ipa.realm},cn=services,cn=accounts,${ldap.base}";
LDAPSASL_AUTHCID = "dn:fqdn=${config.networking.fqdn},${ldap.hostDnSuffix}${ldap.base}";
# LDAPBINDDN?
SMB_SYNC_GROUPS = concatStringsSep "," (map (group: group.name) smbSyncGroups);
SMB_SYNC_USERS = concatStringsSep "," (map (user: user.uid) smbSyncUsers);

View file

@ -9,7 +9,7 @@
inherit (lib.modules) mkIf mkOptionDefault;
inherit (lib.attrsets) filterAttrs mapAttrsToList nameValuePair;
inherit (lib.lists) optional toList;
inherit (lib.strings) toLower removeSuffix concatMapStrings concatStringsSep optionalString;
inherit (lib.strings) hasSuffix removeSuffix concatMapStrings concatStringsSep concatStrings optionalString;
ldap'lib = {
specialArgs = {
nixosConfig = config;
@ -37,7 +37,7 @@
inherit (ldap'lib) specialArgs;
};
mapObjectSettingsToPair = settings: nameValuePair
(removeSuffix ",${config.users.ldap.base}" settings.dn)
(ldap'lib.withoutBaseDn settings.dn)
(unmerged.mergeAttrs settings.settings);
mapObjectSettingsToAttr = settings: let
pair = ldap'lib.mapObjectSettingsToPair settings;
@ -46,12 +46,12 @@
};
mkLdapModifyObjectSettingValues = let
mkLdapModifyValues = setting: concatMapStrings (value: ''
${setting.key}: ${toString value}
${setting.name}: ${toString value}
'') (toList setting.value);
in mkLdapModifyValues;
mkLdapModifyObjectSettings = let
mkLdapModifySetting = setting: ''
${setting.modifyType}: ${setting.key}
${setting.modifyType}: ${setting.name}
'' + ldap'lib.mkLdapModifyObjectSettingValues setting;
in settings: mapAttrsToList (_: mkLdapModifySetting) settings;
mkLdapAddObjectSettings = settings: mapAttrsToList (_: ldap'lib.mkLdapModifyObjectSettingValues) settings;
@ -76,7 +76,8 @@
add = object: let
enabledSettings = filterAttrs (_: setting: setting.enable) object.settings;
addSettings = ldap'lib.mkLdapAddObjectSettings enabledSettings;
in mkHeader "add" object + concatStringsSep "-\n" addSettings;
modifyAfter = "\n" + ldap'lib.mkLdapModifyObject.modify object;
in mkHeader "add" object + concatStrings addSettings + modifyAfter;
delete = object: mkHeader "delete" object;
modrdn = object: { newrdn, deleteoldrdn, newsuperior }: let
modifySettings = ''
@ -93,6 +94,11 @@
'';
in mkHeader "moddn" + modifySettings;
};
withBaseDn = dn:
if hasSuffix ",${config.users.ldap.base}" dn then dn
else if hasSuffix "," dn || dn == "" then "${dn}${config.users.ldap.base}"
else "${dn},${config.users.ldap.base}";
withoutBaseDn = removeSuffix ",${config.users.ldap.base}";
};
ldapPrimitiveType = with lib.types; oneOf [ str int ];
ldapValueType = with lib.types; oneOf [ ldapPrimitiveType (listOf ldapPrimitiveType) ];
@ -101,7 +107,7 @@
enable = mkEnableOption "setting" // {
default = true;
};
key = mkOption {
name = mkOption {
type = str;
default = name;
};
@ -110,7 +116,7 @@
};
modifyType = mkOption {
type = enum [ "replace" "add" "delete" ];
default = if toLower config.key == "objectclass" then "add" else "replace";
default = "replace";
};
};
};
@ -139,7 +145,7 @@
};
dn = mkOption {
type = str;
default = "${name},${ldap.base}";
default = ldap.lib.withBaseDn "${name}";
};
changeType = mkOption {
type = enum [ "modify" "add" "delete" "modrdn" "moddn" ];
@ -151,6 +157,7 @@
objectClasses = mkOption {
type = listOf str;
default = [ ];
description = "additional object classes";
};
settings = mkOption {
type = attrsOf ldap.lib.objectSettingType;
@ -159,7 +166,11 @@
};
config = {
settings = {
objectClass = mkIf (config.objectClasses != [ ]) (mkOptionDefault config.objectClasses);
objectClasses' = mkIf (config.objectClasses != [ ]) (mkOptionDefault {
name = "objectClass";
modifyType = "add";
value = config.objectClasses;
});
};
changeText = mkOptionDefault (ldap'lib.mkLdapModifyObject.${config.changeType} config);
};

View file

@ -0,0 +1,159 @@
{
config,
lib,
inputs,
...
}: let
inherit (inputs.self.lib.lib) mkAlmostOptionDefault mapOptionDefaults mapListToAttrs;
inherit (lib.options) mkOption;
inherit (lib.modules) mkIf mkMerge mkOptionDefault;
inherit (lib.attrsets) attrNames mapAttrs mapAttrsToList;
inherit (lib.lists) filter;
cfg = config.users.ldap;
ldap'lib = config.lib.ldap;
permissionModule = {config, name, ldap, ...}: let
targetConf = {
user = {
location = ldap.userDnSuffix;
targetFilter = "(objectclass=posixaccount)";
};
user-group = {
location = ldap.groupDnSuffix;
targetFilter = "(|(objectclass=ipausergroup)(objectclass=posixgroup))";
};
permission = {
location = ldap.permissionDnSuffix;
targetFilter = "(objectclass=ipapermission)";
};
privilege = {
location = ldap.privilegeDnSuffix;
targetFilter = "(objectclass=groupofnames)";
};
role = {
location = ldap.roleDnSuffix;
targetFilter = "(objectclass=groupofnames)";
};
samba-domain = {
location = "";
target = "sambaDomainName=*,${ldap.base}";
targetFilter = "(objectclass=sambadomain)";
};
domain = {
location = ldap.domainDnSuffix;
targetFilter = "(objectclass=ipantdomainattrs)";
#target = "cn=*";
};
host = {
location = ldap.hostDnSuffix;
# TODO: targetFilter
target = "fqdn=*";
};
service = {
location = ldap.serviceDnSuffix;
# TODO: targetFilter
target = "krbprincipalname=*";
};
sysaccount = {
location = ldap.sysAccountDnSuffix;
# TODO: targetFilter
target = "uid=*";
};
};
in {
options = with lib.types; {
cn = mkOption {
type = str;
default = name;
};
bindType = mkOption {
type = enum [ "anonymous" "permission" "all" ];
default = "permission";
};
rights = mkOption {
type = oneOf [
(listOf (enum [ "read" "search" "compare" "write" "add" "delete" ]))
(enum [ "all" ])
];
default = [ "read" "search" "compare" ];
};
targetType = mkOption {
type = nullOr (enum (attrNames targetConf));
default = null;
};
location = mkOption {
type = str;
};
target = mkOption {
type = nullOr str;
default = null;
};
targetFilter = mkOption {
type = nullOr str;
};
attrs = mkOption {
type = listOf str;
};
members = mkOption {
type = listOf str;
};
object = mkOption {
type = ldap.lib.objectSettingsType;
};
};
config = let
conf.members = mkIf (config.bindType != "permission") (mkOptionDefault [ ]);
conf.targetFilter = mkIf (config.target != null) (mkOptionDefault null);
conf.object = {
dn = mkOptionDefault (ldap.lib.withBaseDn "cn=${config.cn},${ldap.permissionDnSuffix}");
settings = {
changeType = mkAlmostOptionDefault "add";
settings = mapOptionDefaults {
cn = config.cn;
objectClass = [ "top" "groupofnames" "ipapermission" "ipapermissionv2" ];
ipaPermissionType = [ "SYSTEM" "V2" ];
ipaPermIncludedAttr = config.attrs;
ipaPermBindRuleType = config.bindType;
ipaPermRight = config.rights;
ipaPermLocation = ldap.lib.withBaseDn config.location;
} // {
member = mkIf (config.members != [ ]) (mkOptionDefault (map ldap.lib.withBaseDn config.members));
ipaPermTargetFilter = mkIf (config.targetFilter != null) (mkOptionDefault config.targetFilter);
ipaPermTarget = mkIf (config.target != null) (mkOptionDefault config.target);
};
};
};
target = {
location = mkIf (config.targetType != null) (mkAlmostOptionDefault targetConf.${config.targetType}.location);
targetFilter = mkIf (config.targetType != null) (mkAlmostOptionDefault targetConf.${config.targetType}.targetFilter or null);
target = mkIf (config.targetType != null) (mkAlmostOptionDefault targetConf.${config.targetType}.target or null);
};
in mkMerge [ conf target ];
};
in {
options.users.ldap = with lib.types; {
management = {
permissions = mkOption {
type = attrsOf (submoduleWith {
modules = [ permissionModule ];
inherit (config.lib.ldap) specialArgs;
});
default = { };
};
};
permissionDnSuffix = mkOption {
type = str;
};
privilegeDnSuffix = mkOption {
type = str;
};
roleDnSuffix = mkOption {
type = str;
};
};
config.users.ldap = {
management.objects = let
permissionObjects = mapAttrsToList (_: user: user.object) cfg.management.permissions;
enabledObjects = filter (object: object.enable) (permissionObjects);
in mapListToAttrs ldap'lib.mapObjectSettingsToPair enabledObjects;
};
}

View file

@ -6,7 +6,7 @@
}: let
inherit (inputs.self.lib.lib) mkAlmostOptionDefault mapListToAttrs;
inherit (lib.options) mkOption mkEnableOption;
inherit (lib.modules) mkIf mkDefault mkOptionDefault;
inherit (lib.modules) mkIf mkOptionDefault;
inherit (lib.attrsets) mapAttrs mapAttrsToList;
inherit (lib.lists) filter;
inherit (lib.strings) concatStrings;
@ -80,7 +80,7 @@
};
object = {
enable = mkAlmostOptionDefault config.samba.enable;
dn = mkOptionDefault "uid=${config.uid},${ldap.userDnSuffix}${ldap.base}";
dn = mkOptionDefault (ldap.lib.withBaseDn "uid=${config.uid},${ldap.userDnSuffix}");
settings = {
objectClasses = mkIf config.samba.enable [ "sambaSamAccount" ];
settings = mkIf config.samba.enable {
@ -139,7 +139,7 @@
};
object = {
enable = mkAlmostOptionDefault config.samba.enable;
dn = mkOptionDefault "cn=${config.name},${ldap.groupDnSuffix}${ldap.base}";
dn = mkOptionDefault (ldap.lib.withBaseDn "cn=${config.name},${ldap.groupDnSuffix}");
settings = {
objectClasses = mkIf config.samba.enable [ "sambaGroupMapping" ];
settings = mkIf config.samba.enable {