mirror of
https://github.com/gensokyo-zone/infrastructure.git
synced 2026-02-09 04:19:19 -08:00
feat(idp): samba ldap attributes
This commit is contained in:
parent
4ad8e34fa4
commit
81bd1a1a15
12 changed files with 670 additions and 3 deletions
|
|
@ -123,7 +123,7 @@
|
|||
(mkWrapper rec {
|
||||
name = "ldapsearch";
|
||||
attr = "pkgs.openldap";
|
||||
exe = "${name} -H ${ldapHostArg} -b ${ldapBaseDn} -o ldif_wrap=no";
|
||||
exe = ''${name} -H ${ldapHostArg} -b "''${LDAPSEARCH_BASE_DN-${ldapBaseDn}}" -o ldif_wrap=no'';
|
||||
})
|
||||
(mkWrapper rec {
|
||||
name = "ldapadd";
|
||||
|
|
|
|||
164
modules/nixos/ldap/management.nix
Normal file
164
modules/nixos/ldap/management.nix
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
inputs,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
inherit (inputs.self.lib.lib) mapOptionDefaults;
|
||||
inherit (lib.options) mkEnableOption;
|
||||
inherit (lib.modules) mkIf mkOptionDefault;
|
||||
inherit (lib.attrsets) attrValues;
|
||||
inherit (lib.lists) filter;
|
||||
inherit (lib.strings) concatStringsSep concatMapStringsSep escapeShellArgs;
|
||||
inherit (config.users) ldap;
|
||||
cfg = config.users.ldap.management;
|
||||
enabledObjects = filter (object: object.enable) (attrValues cfg.objects);
|
||||
smbSyncUsers = filter (user: user.samba.sync.enable) (attrValues cfg.users);
|
||||
smbSyncGroups = filter (group: group.samba.sync.enable) (attrValues cfg.groups);
|
||||
modifyObjects = filter (object: object.changeType == "modify") enabledObjects;
|
||||
addObjects = filter (object: object.changeType == "add") enabledObjects;
|
||||
deleteObjects = filter (object: object.changeType == "delete") enabledObjects;
|
||||
additions = pkgs.writeText "ldap-management-add.ldap" (
|
||||
concatMapStringsSep "\n" (object: object.changeText) addObjects
|
||||
);
|
||||
# TODO: split up adds and replaces so this can be done without `ldapmodify -c`
|
||||
modifications = pkgs.writeText "ldap-management-modify.ldap" (
|
||||
concatMapStringsSep "\n" (object: object.changeText) modifyObjects
|
||||
);
|
||||
deletions = pkgs.writeText "ldap-management-delete.ldap" (
|
||||
concatMapStringsSep "\n" (object: object.changeText) deleteObjects
|
||||
);
|
||||
objectClassAttr = "objectClass";
|
||||
sidAttr = "ipaNTSecurityIdentifier";
|
||||
ntHashAttr = "ipaNTHash";
|
||||
authTypeAttr = "ipaUserAuthType";
|
||||
userSearchAttrs = [ objectClassAttr sidAttr authTypeAttr ntHashAttr ];
|
||||
groupSearchAttrs = [ objectClassAttr sidAttr ];
|
||||
managementScript = pkgs.writeShellScript "ldap-management.sh" ''
|
||||
set -eu
|
||||
|
||||
ldapsearch() {
|
||||
command ldapsearch -QLLL -o ldif_wrap=no "$@"
|
||||
}
|
||||
|
||||
ldapmodify() {
|
||||
command ldapmodify -Q "$@"
|
||||
}
|
||||
|
||||
ldap_parse() {
|
||||
local LDAP_ATTR=$1 LDAP_LIMIT LDAP_LINE LDAP_COUNT=0
|
||||
shift 1
|
||||
local LDAP_LIMIT=''${1-1}
|
||||
|
||||
while read -r LDAP_LINE; do
|
||||
if [[ $LDAP_LIMIT -eq 0 ]]; then
|
||||
break
|
||||
fi
|
||||
if [[ $LDAP_LINE = "$LDAP_ATTR:: "* ]]; then
|
||||
printf '%s\n' "$LDAP_LINE" | cut -d ' ' -f 2- | base64 -d
|
||||
elif [[ $LDAP_LINE = "$LDAP_ATTR: "* ]]; then
|
||||
printf '%s\n' "$LDAP_LINE" | cut -d ' ' -f 2-
|
||||
else
|
||||
continue
|
||||
fi
|
||||
LDAP_COUNT=$((LDAP_COUNT+1))
|
||||
LDAP_LIMIT=$((LDAP_LIMIT-1))
|
||||
done
|
||||
if [[ $LDAP_COUNT -eq 0 ]]; then
|
||||
echo "$LDAP_ATTR not found" >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
smbsync_group() {
|
||||
local LDAP_GROUP_CN=$1 SMB_GROUP_DATA SMB_GROUP_SID
|
||||
shift 1
|
||||
|
||||
echo "updating cn=''${LDAP_GROUP_CN},${ldap.groupDnSuffix} ..." >&2
|
||||
SMB_GROUP_DATA=$(ldapsearch -z1 \
|
||||
-b "${ldap.groupDnSuffix}${ldap.base}" \
|
||||
"(&(cn=$LDAP_GROUP_CN)(${objectClassAttr}=posixgroup))" \
|
||||
${escapeShellArgs groupSearchAttrs}
|
||||
)
|
||||
SMB_GROUP_SID=$(ldap_parse ${sidAttr} <<< "$SMB_GROUP_DATA")
|
||||
ldapmodify <<EOF
|
||||
dn: cn=$LDAP_GROUP_CN,${ldap.groupDnSuffix}${ldap.base}
|
||||
changetype: modify
|
||||
replace: sambaSID
|
||||
sambaSID: $SMB_GROUP_SID
|
||||
-
|
||||
EOF
|
||||
}
|
||||
|
||||
smbsync_user() {
|
||||
local LDAP_USER_UID=$1 SMB_USER_DATA SMB_USER_SID SMB_USER_NTPASS
|
||||
shift 1
|
||||
|
||||
echo "updating uid=''${LDAP_USER_UID},${ldap.userDnSuffix} ..." >&2
|
||||
SMB_USER_DATA=$(ldapsearch -z1 \
|
||||
-b "${ldap.userDnSuffix}${ldap.base}" \
|
||||
"(&(uid=$LDAP_USER_UID)(${objectClassAttr}=posixaccount))" \
|
||||
${escapeShellArgs userSearchAttrs}
|
||||
)
|
||||
SMB_USER_SID=$(ldap_parse ${sidAttr} <<< "$SMB_USER_DATA")
|
||||
SMB_USER_NTPASS=$(ldap_parse ${ntHashAttr} <<< "$SMB_USER_DATA" | xxd -p)
|
||||
SMB_USER_NTPASS=''${SMB_USER_NTPASS^^}
|
||||
ldapmodify <<EOF
|
||||
dn: uid=$LDAP_USER_UID,${ldap.userDnSuffix}${ldap.base}
|
||||
changetype: modify
|
||||
replace: sambaSID
|
||||
sambaSID: $SMB_USER_SID
|
||||
-
|
||||
replace: sambaNTPassword
|
||||
sambaNTPassword: $SMB_USER_NTPASS
|
||||
-
|
||||
EOF
|
||||
}
|
||||
|
||||
ldapwhoami
|
||||
|
||||
ldapmodify -cf "$MAN_LDAP_ADD"
|
||||
|
||||
ldapmodify -c -f "$MAN_LDAP_MODIFY" || true
|
||||
|
||||
ldapmodify -f "$MAN_LDAP_DELETE"
|
||||
|
||||
IFS=',' declare -a 'SMB_SYNC_GROUPS=($SMB_SYNC_GROUPS)'
|
||||
for SMB_GROUP_CN in "''${SMB_SYNC_GROUPS[@]}"; do
|
||||
smbsync_group "$SMB_GROUP_CN"
|
||||
done
|
||||
IFS=',' declare -a 'SMB_SYNC_USERS=($SMB_SYNC_USERS)'
|
||||
for SMB_USER_UID in "''${SMB_SYNC_USERS[@]}"; do
|
||||
smbsync_user "$SMB_USER_UID"
|
||||
done
|
||||
'';
|
||||
in {
|
||||
options.users.ldap.management = with lib.types; {
|
||||
enable = mkEnableOption "LDAP object management";
|
||||
};
|
||||
config = mkIf cfg.enable {
|
||||
systemd.services.ldap-management = rec {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
wants = [ "krb5-host.service" ];
|
||||
after = wants;
|
||||
path = [ config.services.openldap.package pkgs.coreutils pkgs.xxd ];
|
||||
environment = mapOptionDefaults {
|
||||
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}";
|
||||
# LDAPBINDDN?
|
||||
SMB_SYNC_GROUPS = concatStringsSep "," (map (group: group.name) smbSyncGroups);
|
||||
SMB_SYNC_USERS = concatStringsSep "," (map (user: user.uid) smbSyncUsers);
|
||||
MAN_LDAP_ADD = "${additions}";
|
||||
MAN_LDAP_MODIFY = "${modifications}";
|
||||
MAN_LDAP_DELETE = "${deletions}";
|
||||
};
|
||||
serviceConfig = {
|
||||
Type = mkOptionDefault "oneshot";
|
||||
ExecStart = [ "${managementScript}" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
175
modules/nixos/ldap/object.nix
Normal file
175
modules/nixos/ldap/object.nix
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
inputs,
|
||||
...
|
||||
}: let
|
||||
inherit (inputs.self.lib.lib) unmerged mkAlmostOptionDefault;
|
||||
inherit (lib.options) mkOption mkEnableOption;
|
||||
inherit (lib.modules) mkIf mkOptionDefault;
|
||||
inherit (lib.attrsets) filterAttrs mapAttrsToList nameValuePair;
|
||||
inherit (lib.lists) optional toList;
|
||||
inherit (lib.strings) toLower removeSuffix concatMapStrings concatStringsSep optionalString;
|
||||
ldap'lib = {
|
||||
specialArgs = {
|
||||
nixosConfig = config;
|
||||
ldap = config.users.ldap // {
|
||||
lib = config.lib.ldap;
|
||||
};
|
||||
};
|
||||
objectModule = ldapObjectModule;
|
||||
objectType = lib.types.submoduleWith {
|
||||
modules = [ ldapObjectModule ];
|
||||
inherit (ldap'lib) specialArgs;
|
||||
};
|
||||
objectSettingType' = lib.types.submoduleWith {
|
||||
modules = [ ldapObjectSettingModule ];
|
||||
inherit (ldap'lib) specialArgs;
|
||||
};
|
||||
objectSettingType = let
|
||||
mapToObjectSetting = value: {
|
||||
inherit value;
|
||||
};
|
||||
in lib.types.coercedTo ldapValueType mapToObjectSetting ldap'lib.objectSettingType';
|
||||
objectSettingsModule = ldapObjectSettingsModule;
|
||||
objectSettingsType = lib.types.submoduleWith {
|
||||
modules = [ ldapObjectSettingsModule ];
|
||||
inherit (ldap'lib) specialArgs;
|
||||
};
|
||||
mapObjectSettingsToPair = settings: nameValuePair
|
||||
(removeSuffix ",${config.users.ldap.base}" settings.dn)
|
||||
(unmerged.mergeAttrs settings.settings);
|
||||
mapObjectSettingsToAttr = settings: let
|
||||
pair = ldap'lib.mapObjectSettingsToPair settings;
|
||||
in {
|
||||
${pair.name} = pair.value;
|
||||
};
|
||||
mkLdapModifyObjectSettingValues = let
|
||||
mkLdapModifyValues = setting: concatMapStrings (value: ''
|
||||
${setting.key}: ${toString value}
|
||||
'') (toList setting.value);
|
||||
in mkLdapModifyValues;
|
||||
mkLdapModifyObjectSettings = let
|
||||
mkLdapModifySetting = setting: ''
|
||||
${setting.modifyType}: ${setting.key}
|
||||
'' + ldap'lib.mkLdapModifyObjectSettingValues setting;
|
||||
in settings: mapAttrsToList (_: mkLdapModifySetting) settings;
|
||||
mkLdapAddObjectSettings = settings: mapAttrsToList (_: ldap'lib.mkLdapModifyObjectSettingValues) settings;
|
||||
mkLdapModifyObject = let
|
||||
mkHeader = changeType: object: ''
|
||||
dn: ${object.dn}
|
||||
changetype: ${changeType}
|
||||
'';
|
||||
in {
|
||||
modify = object: let
|
||||
enabledSettings' = filterAttrs (_: setting: setting.enable) object.settings;
|
||||
enabledSettings = ldap'lib.mkLdapModifyObjectSettings enabledSettings';
|
||||
replaceSettings' = filterAttrs (_: setting: setting.modifyType == "replace") enabledSettings';
|
||||
replaceSettings = ldap'lib.mkLdapModifyObjectSettings replaceSettings';
|
||||
addSettings' = filterAttrs (_: setting: setting.modifyType == "add") enabledSettings';
|
||||
replaceText = mkHeader "modify" object + concatStringsSep "-\n" replaceSettings;
|
||||
text = mkHeader "modify" object + concatStringsSep "-\n" enabledSettings;
|
||||
in concatStringsSep "-\n\n" (
|
||||
[ text ]
|
||||
++ optional (addSettings' != { }) replaceText
|
||||
);
|
||||
add = object: let
|
||||
enabledSettings = filterAttrs (_: setting: setting.enable) object.settings;
|
||||
addSettings = ldap'lib.mkLdapAddObjectSettings enabledSettings;
|
||||
in mkHeader "add" object + concatStringsSep "-\n" addSettings;
|
||||
delete = object: mkHeader "delete" object;
|
||||
modrdn = object: { newrdn, deleteoldrdn, newsuperior }: let
|
||||
modifySettings = ''
|
||||
newrdn: ${newrdn}
|
||||
deleteoldrdn: ${if deleteoldrdn == true then "1" else if deleteoldrdn == "false" then "0" else toString deleteoldrdn}
|
||||
'' + optionalString (newsuperior != null) ''
|
||||
newsuperior: ${newsuperior}
|
||||
'';
|
||||
in mkHeader "modrdn" + modifySettings;
|
||||
moddn = object: { deleteoldrdn, newsuperior }: let
|
||||
modifySettings = ''
|
||||
deleteoldrdn: ${if deleteoldrdn == true then "1" else if deleteoldrdn == "false" then "0" else toString deleteoldrdn}
|
||||
newsuperior: ${newsuperior}
|
||||
'';
|
||||
in mkHeader "moddn" + modifySettings;
|
||||
};
|
||||
};
|
||||
ldapPrimitiveType = with lib.types; oneOf [ str int ];
|
||||
ldapValueType = with lib.types; oneOf [ ldapPrimitiveType (listOf ldapPrimitiveType) ];
|
||||
ldapObjectSettingModule = {config, name, ...}: {
|
||||
options = with lib.types; {
|
||||
enable = mkEnableOption "setting" // {
|
||||
default = true;
|
||||
};
|
||||
key = mkOption {
|
||||
type = str;
|
||||
default = name;
|
||||
};
|
||||
value = mkOption {
|
||||
type = ldapValueType;
|
||||
};
|
||||
modifyType = mkOption {
|
||||
type = enum [ "replace" "add" "delete" ];
|
||||
default = if toLower config.key == "objectclass" then "add" else "replace";
|
||||
};
|
||||
};
|
||||
};
|
||||
ldapObjectSettingsModule = {config, ...}: {
|
||||
options = with lib.types; {
|
||||
enable = mkEnableOption "object" // {
|
||||
default = true;
|
||||
};
|
||||
dn = mkOption {
|
||||
type = str;
|
||||
};
|
||||
settings = mkOption {
|
||||
type = unmerged.types.attrs;
|
||||
};
|
||||
};
|
||||
config = {
|
||||
settings = {
|
||||
dn = mkAlmostOptionDefault config.dn;
|
||||
};
|
||||
};
|
||||
};
|
||||
ldapObjectModule = {config, name, ldap, ...}: {
|
||||
options = with lib.types; {
|
||||
enable = mkEnableOption "object creation" // {
|
||||
default = true;
|
||||
};
|
||||
dn = mkOption {
|
||||
type = str;
|
||||
default = "${name},${ldap.base}";
|
||||
};
|
||||
changeType = mkOption {
|
||||
type = enum [ "modify" "add" "delete" "modrdn" "moddn" ];
|
||||
default = "modify";
|
||||
};
|
||||
changeText = mkOption {
|
||||
type = lines;
|
||||
};
|
||||
objectClasses = mkOption {
|
||||
type = listOf str;
|
||||
default = [ ];
|
||||
};
|
||||
settings = mkOption {
|
||||
type = attrsOf ldap.lib.objectSettingType;
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
config = {
|
||||
settings = {
|
||||
objectClass = mkIf (config.objectClasses != [ ]) (mkOptionDefault config.objectClasses);
|
||||
};
|
||||
changeText = mkOptionDefault (ldap'lib.mkLdapModifyObject.${config.changeType} config);
|
||||
};
|
||||
};
|
||||
in {
|
||||
options.users.ldap = with lib.types; {
|
||||
management.objects = mkOption {
|
||||
type = attrsOf ldap'lib.objectType;
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
config.lib.ldap = ldap'lib;
|
||||
}
|
||||
201
modules/nixos/ldap/users.nix
Normal file
201
modules/nixos/ldap/users.nix
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
inputs,
|
||||
...
|
||||
}: let
|
||||
inherit (inputs.self.lib.lib) mkAlmostOptionDefault mapListToAttrs;
|
||||
inherit (lib.options) mkOption mkEnableOption;
|
||||
inherit (lib.modules) mkIf mkDefault mkOptionDefault;
|
||||
inherit (lib.attrsets) mapAttrs mapAttrsToList;
|
||||
inherit (lib.lists) filter;
|
||||
inherit (lib.strings) concatStrings;
|
||||
cfg = config.users.ldap;
|
||||
ldap'lib = config.lib.ldap;
|
||||
userModule = {config, nixosConfig, name, ldap, ...}: let
|
||||
user = nixosConfig.users.users.${config.user.name};
|
||||
sambaAccountFlags = {
|
||||
normalUser = "U";
|
||||
disabled = "D";
|
||||
homeRequired = "H";
|
||||
temporaryDuplicate = "T";
|
||||
mnsLogon = "M";
|
||||
workstationTrust = "W";
|
||||
serverTrust = "S";
|
||||
domainTrust = "I";
|
||||
autoLock = "L";
|
||||
noPasswordExpiry = "X";
|
||||
noPasswordRequired = "N";
|
||||
};
|
||||
mkSambaAccountFlags = flags: let
|
||||
empty = " ";
|
||||
flagChar = char: flag: if flag then char else empty;
|
||||
flagChars = mapAttrsToList (name: flagChar sambaAccountFlags.${name}) flags;
|
||||
in "[${concatStrings flagChars}]";
|
||||
in {
|
||||
options = with lib.types; {
|
||||
user = {
|
||||
enable = mkEnableOption "system user";
|
||||
name = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
};
|
||||
uid = mkOption {
|
||||
type = nullOr int;
|
||||
default = null;
|
||||
};
|
||||
};
|
||||
uid = mkOption {
|
||||
type = str;
|
||||
default = name;
|
||||
};
|
||||
samba = {
|
||||
enable = mkEnableOption "SMB user";
|
||||
sync.enable = mkEnableOption "IPA data sync";
|
||||
sid = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
};
|
||||
accountFlags = mapAttrs (_: _: mkOption {
|
||||
type = bool;
|
||||
default = false;
|
||||
}) sambaAccountFlags;
|
||||
};
|
||||
object = mkOption {
|
||||
type = ldap.lib.objectSettingsType;
|
||||
};
|
||||
};
|
||||
config = {
|
||||
user = {
|
||||
name = mkIf config.user.enable (mkAlmostOptionDefault name);
|
||||
uid = mkIf (config.user.name != null) (mkAlmostOptionDefault user.uid);
|
||||
};
|
||||
samba = {
|
||||
sid = mkIf (ldap.samba.domainSID != null && config.user.uid != null) (
|
||||
mkAlmostOptionDefault "${ldap.samba.domainSID}-${toString (ldap.samba.sidUserOffset + config.user.uid)}"
|
||||
);
|
||||
accountFlags = {
|
||||
normalUser = mkIf (config.user.name != null) (mkAlmostOptionDefault user.isNormalUser);
|
||||
};
|
||||
};
|
||||
object = {
|
||||
enable = mkAlmostOptionDefault config.samba.enable;
|
||||
dn = mkOptionDefault "uid=${config.uid},${ldap.userDnSuffix}${ldap.base}";
|
||||
settings = {
|
||||
objectClasses = mkIf config.samba.enable [ "sambaSamAccount" ];
|
||||
settings = mkIf config.samba.enable {
|
||||
sambaSID = mkIf (config.samba.sid != null) (mkOptionDefault config.samba.sid);
|
||||
sambaAcctFlags = mkOptionDefault (mkSambaAccountFlags config.samba.accountFlags);
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
groupModule = {config, nixosConfig, name, ldap, ...}: let
|
||||
group = nixosConfig.users.groups.${config.group.name};
|
||||
in {
|
||||
options = with lib.types; {
|
||||
group = {
|
||||
enable = mkEnableOption "system group";
|
||||
name = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
};
|
||||
gid = mkOption {
|
||||
type = nullOr int;
|
||||
default = null;
|
||||
};
|
||||
};
|
||||
name = mkOption {
|
||||
type = str;
|
||||
default = name;
|
||||
};
|
||||
samba = {
|
||||
enable = mkEnableOption "SMB group";
|
||||
sync.enable = mkEnableOption "IPA data sync";
|
||||
sid = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
};
|
||||
groupType = mkOption {
|
||||
type = int;
|
||||
default = 2;
|
||||
description = "http://pig.made-it.com/samba-accounts.html#22762";
|
||||
};
|
||||
};
|
||||
object = mkOption {
|
||||
type = ldap.lib.objectSettingsType;
|
||||
};
|
||||
};
|
||||
config = {
|
||||
group = {
|
||||
name = mkIf config.group.enable (mkAlmostOptionDefault name);
|
||||
gid = mkIf (config.group.name != null) (mkAlmostOptionDefault group.gid);
|
||||
};
|
||||
samba = {
|
||||
sid = mkIf (ldap.samba.domainSID != null && config.group.gid != null) (
|
||||
mkAlmostOptionDefault "${ldap.samba.domainSID}-${toString (ldap.samba.sidGroupOffset + config.group.gid)}"
|
||||
);
|
||||
};
|
||||
object = {
|
||||
enable = mkAlmostOptionDefault config.samba.enable;
|
||||
dn = mkOptionDefault "cn=${config.name},${ldap.groupDnSuffix}${ldap.base}";
|
||||
settings = {
|
||||
objectClasses = mkIf config.samba.enable [ "sambaGroupMapping" ];
|
||||
settings = mkIf config.samba.enable {
|
||||
sambaSID = mkIf (config.samba.sid != null) (mkOptionDefault config.samba.sid);
|
||||
sambaGroupType = mkOptionDefault config.samba.groupType;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
in {
|
||||
options.users.ldap = with lib.types; {
|
||||
management = {
|
||||
users = mkOption {
|
||||
type = attrsOf (submoduleWith {
|
||||
modules = [ userModule ];
|
||||
inherit (config.lib.ldap) specialArgs;
|
||||
});
|
||||
default = { };
|
||||
};
|
||||
groups = mkOption {
|
||||
type = attrsOf (submoduleWith {
|
||||
modules = [ groupModule ];
|
||||
inherit (config.lib.ldap) specialArgs;
|
||||
});
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
samba = {
|
||||
domainSID = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
};
|
||||
sidUserOffset = mkOption {
|
||||
type = int;
|
||||
default = -7999;
|
||||
};
|
||||
sidGroupOffset = mkOption {
|
||||
type = int;
|
||||
default = 256 + 1;
|
||||
};
|
||||
};
|
||||
userDnSuffix = mkOption {
|
||||
type = str;
|
||||
default = "";
|
||||
};
|
||||
groupDnSuffix = mkOption {
|
||||
type = str;
|
||||
default = "";
|
||||
};
|
||||
};
|
||||
config.users.ldap = {
|
||||
management.objects = let
|
||||
userObjects = mapAttrsToList (_: user: user.object) cfg.management.users;
|
||||
groupObjects = mapAttrsToList (_: group: group.object) cfg.management.groups;
|
||||
enabledObjects = filter (object: object.enable) (userObjects ++ groupObjects);
|
||||
in mapListToAttrs ldap'lib.mapObjectSettingsToPair enabledObjects;
|
||||
};
|
||||
}
|
||||
|
|
@ -154,6 +154,7 @@ in {
|
|||
${virtualHosts.freeipa'ca.serverName} ${upstreams.freeipa};
|
||||
${nginx.access.ldap.domain} ${upstreams.ldap};
|
||||
${nginx.access.ldap.localDomain} ${upstreams.ldap};
|
||||
${nginx.access.ldap.intDomain} ${upstreams.ldap};
|
||||
${nginx.access.ldap.tailDomain} ${upstreams.ldap};
|
||||
default ${upstreams.nginx};
|
||||
}
|
||||
|
|
@ -244,6 +245,7 @@ in {
|
|||
};
|
||||
freeipa'ldap'local = {
|
||||
serverName = mkDefault ldap.localDomain;
|
||||
serverAliases = [ ldap.intDomain ];
|
||||
ssl.cert.copyFromVhost = "freeipa'ldap";
|
||||
globalRedirect = virtualHosts.freeipa'web'local.serverName;
|
||||
local.enable = true;
|
||||
|
|
|
|||
|
|
@ -35,6 +35,10 @@ in {
|
|||
type = str;
|
||||
default = "ldap.local.${config.networking.domain}";
|
||||
};
|
||||
intDomain = mkOption {
|
||||
type = str;
|
||||
default = "ldap.int.${config.networking.domain}";
|
||||
};
|
||||
tailDomain = mkOption {
|
||||
type = str;
|
||||
default = "ldap.tail.${config.networking.domain}";
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{ inputs, pkgs, config, lib, ... }: let
|
||||
inherit (inputs.self.lib.lib) mkBaseDn;
|
||||
inherit (lib.modules) mkIf mkBefore mkDefault;
|
||||
inherit (lib.modules) mkIf mkBefore mkDefault mkOptionDefault;
|
||||
inherit (lib.strings) toUpper;
|
||||
inherit (config.networking) domain;
|
||||
cfg = config.security.ipa;
|
||||
|
|
@ -19,6 +19,14 @@ in {
|
|||
# once the sops secret has been updated with keytab...
|
||||
# :; systemctl restart sssd
|
||||
config = {
|
||||
users.ldap = {
|
||||
base = mkDefault baseDn;
|
||||
server = mkDefault "ldaps://ldap.local.${domain}";
|
||||
samba.domainSID = mkDefault "S-1-5-21-1535650373-1457993706-2355445124";
|
||||
#samba.domainSID = mkDefault "S-1-5-21-208293719-3143191303-229982100"; # HAKUREI
|
||||
userDnSuffix = mkDefault "cn=users,cn=accounts,";
|
||||
groupDnSuffix = mkDefault "cn=groups,cn=accounts,";
|
||||
};
|
||||
security.ipa = {
|
||||
enable = mkDefault true;
|
||||
certificate = mkDefault caPem;
|
||||
|
|
@ -41,5 +49,18 @@ in {
|
|||
path = "/etc/krb5.keytab";
|
||||
};
|
||||
};
|
||||
systemd.services.krb5-host = let
|
||||
krb5-host = pkgs.writeShellScript "krb5-host" ''
|
||||
set -eu
|
||||
|
||||
kinit -k host/${config.networking.fqdn}
|
||||
'';
|
||||
in mkIf cfg.enable {
|
||||
path = [ config.security.krb5.package ];
|
||||
serviceConfig = {
|
||||
Type = mkOptionDefault "oneshot";
|
||||
ExecStart = [ "${krb5-host}" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ in {
|
|||
securityType = mkDefault "user";
|
||||
ldap = {
|
||||
enable = mkDefault true;
|
||||
url = mkDefault "ldaps://ldap.local.${domain}";
|
||||
url = mkDefault "ldaps://ldap.int.${domain}";
|
||||
baseDn = mkDefault (mkBaseDn domain);
|
||||
adminDn = mkDefault "uid=samba,cn=sysaccounts,cn=etc,${cfg.ldap.baseDn}";
|
||||
adminPasswordPath = mkIf cfg.ldap.enable (
|
||||
|
|
@ -56,6 +56,7 @@ in {
|
|||
"winbind scan trusted domains" = false;
|
||||
"winbind use default domain" = true;
|
||||
"domain master" = false;
|
||||
"domain logons" = true;
|
||||
"remote announce" = mkIf hasIpv4 [
|
||||
"10.1.1.255/${cfg.settings.workgroup}"
|
||||
];
|
||||
|
|
|
|||
95
nixos/users/ldap.nix
Normal file
95
nixos/users/ldap.nix
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
{config, lib, inputs, ...}: let
|
||||
inherit (inputs.self.lib.lib) userIs mkAlmostOptionDefault;
|
||||
inherit (lib.modules) mkMerge mkDefault;
|
||||
inherit (lib.attrsets) mapAttrs filterAttrs;
|
||||
ldapUsers = filterAttrs (_: userIs "peeps") config.users.users;
|
||||
ldapGroups = filterAttrs (_: group: group.gid != null && group.gid >= 8000 && group.gid < 8256) config.users.groups;
|
||||
management = {
|
||||
users = mapAttrs (name: user: {
|
||||
user.name = mkAlmostOptionDefault name;
|
||||
samba = {
|
||||
enable = mkDefault true;
|
||||
sync.enable = mkDefault true;
|
||||
accountFlags = {
|
||||
noPasswordExpiry = mkDefault true;
|
||||
};
|
||||
};
|
||||
}) ldapUsers;
|
||||
groups = mapAttrs (name: group: {
|
||||
group.name = mkAlmostOptionDefault name;
|
||||
samba.enable = mkDefault true;
|
||||
}) ldapGroups;
|
||||
};
|
||||
in {
|
||||
config.users.ldap = {
|
||||
management = mkMerge [ management {
|
||||
users = {
|
||||
guest.user.enable = true;
|
||||
admin = {
|
||||
user.enable = true;
|
||||
samba.enable = true;
|
||||
};
|
||||
opl = {
|
||||
user.enable = true;
|
||||
samba = {
|
||||
enable = true;
|
||||
#sync.enable = true;
|
||||
accountFlags = {
|
||||
noPasswordExpiry = mkDefault true;
|
||||
normalUser = true;
|
||||
};
|
||||
};
|
||||
object.settings.settings = {
|
||||
sambaNTPassword = "F7C2C5D78C24EACB73550B02BF5888E3";
|
||||
sambaLMPassword = "A5C96CDE7660B20BAAD3B435B51404EE";
|
||||
};
|
||||
};
|
||||
};
|
||||
groups = {
|
||||
nogroup = {
|
||||
group.enable = true;
|
||||
samba.enable = true;
|
||||
};
|
||||
guest = {
|
||||
samba = {
|
||||
enable = true;
|
||||
groupType = 4;
|
||||
sid = "S-1-5-32-546";
|
||||
};
|
||||
};
|
||||
admin = {
|
||||
group.enable = true;
|
||||
samba.enable = true;
|
||||
};
|
||||
kyuuto-peeps = {
|
||||
group.enable = true;
|
||||
samba.enable = true;
|
||||
};
|
||||
kyuuto = {
|
||||
group.enable = true;
|
||||
samba.enable = true;
|
||||
};
|
||||
peeps = {
|
||||
group.enable = true;
|
||||
samba.enable = true;
|
||||
};
|
||||
admins = {
|
||||
samba = {
|
||||
enable = true;
|
||||
#sync.enable = true;
|
||||
groupType = 4;
|
||||
sid = "S-1-5-32-544";
|
||||
};
|
||||
};
|
||||
smb = {
|
||||
name = "Default SMB Group";
|
||||
samba = {
|
||||
#sync.enable = true;
|
||||
groupType = 4;
|
||||
sid = "S-1-5-32-545";
|
||||
};
|
||||
};
|
||||
};
|
||||
} ];
|
||||
};
|
||||
}
|
||||
|
|
@ -52,6 +52,8 @@ in {
|
|||
./reisen-ssh.nix
|
||||
];
|
||||
|
||||
users.ldap.management.enable = true;
|
||||
|
||||
sops.secrets.cloudflared-tunnel-hakurei = {
|
||||
owner = config.services.cloudflared.user;
|
||||
};
|
||||
|
|
|
|||
2
tree.nix
2
tree.nix
|
|
@ -55,9 +55,11 @@
|
|||
];
|
||||
};
|
||||
};
|
||||
"modules/nixos/ldap".functor.enable = true;
|
||||
"modules/nixos/network".functor.enable = true;
|
||||
"modules/nixos/nginx".functor.enable = true;
|
||||
"modules/nixos/steam".functor.enable = true;
|
||||
"modules/nixos/users".functor.enable = true;
|
||||
"modules/meta".functor.enable = true;
|
||||
"modules/system".functor.enable = true;
|
||||
"modules/system/proxmox".functor.enable = true;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue