roundcube & mailserver: fix oauth: mailserver is an OAuth secret donor
Both of them use the same client ID and client secret, but Roundcube depends on mailserver generally, so mailserver is the one to share OAuth client id and secret.
This commit is contained in:
@@ -7,5 +7,7 @@
|
|||||||
[ "passthru", "selfprivacy", "auth", "oauth2-systemd-service" ],
|
[ "passthru", "selfprivacy", "auth", "oauth2-systemd-service" ],
|
||||||
[ "selfprivacy", "domain" ],
|
[ "selfprivacy", "domain" ],
|
||||||
[ "selfprivacy", "modules", "auth" ],
|
[ "selfprivacy", "modules", "auth" ],
|
||||||
[ "selfprivacy", "modules", "roundcube" ]
|
[ "selfprivacy", "modules", "roundcube" ],
|
||||||
|
[ "selfprivacy", "passthru", "mailserver", "oauth-client-id" ],
|
||||||
|
[ "selfprivacy", "passthru", "mailserver", "oauth-client-secret-fp" ]
|
||||||
]
|
]
|
||||||
|
@@ -5,24 +5,21 @@ let
|
|||||||
is-auth-enabled = config.selfprivacy.modules.auth.enable or false;
|
is-auth-enabled = config.selfprivacy.modules.auth.enable or false;
|
||||||
auth-passthru = config.passthru.selfprivacy.auth;
|
auth-passthru = config.passthru.selfprivacy.auth;
|
||||||
auth-fqdn = auth-passthru.auth-fqdn;
|
auth-fqdn = auth-passthru.auth-fqdn;
|
||||||
oauth-client-id = "roundcube";
|
sp-module-name = "roundcube";
|
||||||
roundcube-user = "roundcube";
|
user = "roundcube";
|
||||||
roundcube-group = "roundcube";
|
group = "roundcube";
|
||||||
kanidmExecStartPreScriptRoot = pkgs.writeShellScript
|
oauth-donor = config.selfprivacy.passthru.mailserver;
|
||||||
"${oauth-client-id}-kanidm-ExecStartPre-root-script.sh"
|
|
||||||
''
|
|
||||||
# set-group-ID bit allows for kanidm user to create files,
|
|
||||||
mkdir -p -v --mode=u+rwx,g+rs,g-w,o-rwx /run/keys/${oauth-client-id}
|
|
||||||
chown kanidm:${roundcube-group} /run/keys/${oauth-client-id}
|
|
||||||
'';
|
|
||||||
kanidm-oauth-client-secret-fp =
|
kanidm-oauth-client-secret-fp =
|
||||||
"/run/keys/${oauth-client-id}/kanidm-oauth-client-secret";
|
"/run/keys/${group}/kanidm-oauth-client-secret";
|
||||||
kanidmExecStartPreScript = pkgs.writeShellScript
|
kanidmExecStartPreScriptRoot = pkgs.writeShellScript
|
||||||
"${oauth-client-id}-kanidm-ExecStartPre-script.sh" ''
|
"${sp-module-name}-kanidm-ExecStartPre-root-script.sh"
|
||||||
set -o xtrace
|
''
|
||||||
[ -f "${kanidm-oauth-client-secret-fp}" ] || \
|
# set-group-ID bit allows for kanidm user to create files inheriting group
|
||||||
"${lib.getExe pkgs.openssl}" rand -base64 -out "${kanidm-oauth-client-secret-fp}" 32
|
mkdir -p -v --mode=u+rwx,g+rs,g-w,o-rwx /run/keys/${group}
|
||||||
'';
|
chown kanidm:${group} /run/keys/${group}
|
||||||
|
|
||||||
|
install -v -m640 -o kanidm -g ${group} ${oauth-donor.oauth-client-secret-fp} ${kanidm-oauth-client-secret-fp}
|
||||||
|
'';
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.selfprivacy.modules.roundcube = {
|
options.selfprivacy.modules.roundcube = {
|
||||||
@@ -72,21 +69,23 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
systemd.slices.roundcube.description = "Roundcube service slice";
|
systemd.slices.roundcube.description = "Roundcube service slice";
|
||||||
|
# Roundcube depends on Dovecot and its OAuth2 client secret.
|
||||||
|
systemd.services.roundcube.after = [ "dovecot2.service" ];
|
||||||
}
|
}
|
||||||
# the following part is active only when "auth" module is enabled
|
# the following part is active only when "auth" module is enabled
|
||||||
(lib.attrsets.optionalAttrs
|
(lib.attrsets.optionalAttrs
|
||||||
(options.selfprivacy.modules ? "auth")
|
(options.selfprivacy.modules ? "auth")
|
||||||
(lib.mkIf is-auth-enabled {
|
(lib.mkIf is-auth-enabled {
|
||||||
# for phpfpm-roundcube to have access to get through /run/keys directory
|
# for phpfpm-roundcube to have access to get through /run/keys directory
|
||||||
users.groups.keys.members = [ roundcube-user ];
|
users.groups.keys.members = [ user ];
|
||||||
services.roundcube.extraConfig = lib.mkAfter ''
|
services.roundcube.extraConfig = lib.mkAfter ''
|
||||||
$config['oauth_provider'] = 'generic';
|
$config['oauth_provider'] = 'generic';
|
||||||
$config['oauth_provider_name'] = '${auth-passthru.oauth2-provider-name}';
|
$config['oauth_provider_name'] = '${auth-passthru.oauth2-provider-name}';
|
||||||
$config['oauth_client_id'] = '${oauth-client-id}';
|
$config['oauth_client_id'] = '${oauth-donor.oauth-client-id}';
|
||||||
$config['oauth_client_secret'] = file_get_contents('${kanidm-oauth-client-secret-fp}');
|
$config['oauth_client_secret'] = file_get_contents('${kanidm-oauth-client-secret-fp}');
|
||||||
$config['oauth_auth_uri'] = 'https://${auth-fqdn}/ui/oauth2';
|
$config['oauth_auth_uri'] = 'https://${auth-fqdn}/ui/oauth2';
|
||||||
$config['oauth_token_uri'] = 'https://${auth-fqdn}/oauth2/token';
|
$config['oauth_token_uri'] = 'https://${auth-fqdn}/oauth2/token';
|
||||||
$config['oauth_identity_uri'] = 'https://${auth-fqdn}/oauth2/openid/${oauth-client-id}/userinfo';
|
$config['oauth_identity_uri'] = 'https://${auth-fqdn}/oauth2/openid/${oauth-donor.oauth-client-id}/userinfo';
|
||||||
$config['oauth_scope'] = 'email profile openid'; # FIXME
|
$config['oauth_scope'] = 'email profile openid'; # FIXME
|
||||||
$config['oauth_auth_parameters'] = [];
|
$config['oauth_auth_parameters'] = [];
|
||||||
$config['oauth_identity_fields'] = ['email'];
|
$config['oauth_identity_fields'] = ['email'];
|
||||||
@@ -96,11 +95,9 @@ in
|
|||||||
# $config['oauth_pkce'] = 'S256'; # FIXME
|
# $config['oauth_pkce'] = 'S256'; # FIXME
|
||||||
'';
|
'';
|
||||||
systemd.services.kanidm = {
|
systemd.services.kanidm = {
|
||||||
serviceConfig.ExecStartPre = lib.mkAfter [
|
serviceConfig.ExecStartPre = lib.mkBefore [
|
||||||
("-+" + kanidmExecStartPreScriptRoot)
|
("-+" + kanidmExecStartPreScriptRoot)
|
||||||
("-" + kanidmExecStartPreScript)
|
|
||||||
];
|
];
|
||||||
requires = [ auth-passthru.oauth2-systemd-service ];
|
|
||||||
};
|
};
|
||||||
services.kanidm.provision = {
|
services.kanidm.provision = {
|
||||||
groups = {
|
groups = {
|
||||||
@@ -108,7 +105,7 @@ in
|
|||||||
"sp.roundcube.users".members =
|
"sp.roundcube.users".members =
|
||||||
[ "sp.roundcube.admins" auth-passthru.full-users-group ];
|
[ "sp.roundcube.admins" auth-passthru.full-users-group ];
|
||||||
};
|
};
|
||||||
systems.oauth2.roundcube = {
|
systems.oauth2.${oauth-donor.oauth-client-id} = {
|
||||||
displayName = "Roundcube";
|
displayName = "Roundcube";
|
||||||
originUrl = "https://${cfg.subdomain}.${domain}/index.php/login/oauth";
|
originUrl = "https://${cfg.subdomain}.${domain}/index.php/login/oauth";
|
||||||
originLanding = "https://${cfg.subdomain}.${domain}/";
|
originLanding = "https://${cfg.subdomain}.${domain}/";
|
||||||
|
@@ -1,14 +1,15 @@
|
|||||||
{ config, lib, pkgs, ... }@nixos-args:
|
{ config, lib, pkgs, ... }@nixos-args:
|
||||||
let
|
let
|
||||||
inherit (import ./common.nix nixos-args)
|
inherit (import ./common.nix nixos-args)
|
||||||
appendLdapBindPwd
|
appendSetting
|
||||||
auth-passthru
|
auth-passthru
|
||||||
cfg
|
cfg
|
||||||
domain
|
domain
|
||||||
|
group
|
||||||
is-auth-enabled
|
is-auth-enabled
|
||||||
;
|
;
|
||||||
|
|
||||||
runtime-directory = "dovecot2";
|
runtime-directory = group;
|
||||||
|
|
||||||
ldapConfFile = "/run/${runtime-directory}/dovecot-ldap.conf.ext";
|
ldapConfFile = "/run/${runtime-directory}/dovecot-ldap.conf.ext";
|
||||||
mkLdapSearchScope = scope: (
|
mkLdapSearchScope = scope: (
|
||||||
@@ -37,7 +38,7 @@ let
|
|||||||
user_filter = ${config.mailserver.ldap.dovecot.userFilter}
|
user_filter = ${config.mailserver.ldap.dovecot.userFilter}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
setPwdInLdapConfFile = appendLdapBindPwd {
|
setPwdInLdapConfFile = appendSetting {
|
||||||
name = "ldap-conf-file";
|
name = "ldap-conf-file";
|
||||||
file = dovecot-ldap-config;
|
file = dovecot-ldap-config;
|
||||||
prefix = ''dnpass = "'';
|
prefix = ''dnpass = "'';
|
||||||
@@ -45,24 +46,39 @@ let
|
|||||||
passwordFile = config.mailserver.ldap.bind.passwordFile;
|
passwordFile = config.mailserver.ldap.bind.passwordFile;
|
||||||
destination = ldapConfFile;
|
destination = ldapConfFile;
|
||||||
};
|
};
|
||||||
dovecot-oauth2-conf-file = pkgs.writeTextFile {
|
oauth-client-id = "mailserver";
|
||||||
name = "dovecot-oauth2.conf.ext";
|
oauth-client-secret-fp =
|
||||||
text = ''
|
"/run/keys/${group}/kanidm-oauth-client-secret";
|
||||||
|
oauth-secret-ExecStartPreScript = pkgs.writeShellScript
|
||||||
|
"${oauth-client-id}-kanidm-ExecStartPre-script.sh" ''
|
||||||
|
set -o xtrace
|
||||||
|
[ -f "${oauth-client-secret-fp}" ] || \
|
||||||
|
"${lib.getExe pkgs.openssl}" rand -base64 32 | tr -d "\n" > "${oauth-client-secret-fp}"
|
||||||
|
'';
|
||||||
|
dovecot-oauth2-conf-fp = "/run/${runtime-directory}/dovecot-oauth2.conf.ext";
|
||||||
|
write-dovecot-oauth2-conf = appendSetting {
|
||||||
|
name = "oauth2-conf-file";
|
||||||
|
file = builtins.toFile "dovecot-oauth2.conf.ext.template" ''
|
||||||
introspection_mode = post
|
introspection_mode = post
|
||||||
introspection_url = ${auth-passthru.oauth2-introspection-url "roundcube" "VERYSTRONGSECRETFORROUNDCUBE"}
|
|
||||||
client_id = roundcube
|
|
||||||
client_secret = VERYSTRONGSECRETFORROUNDCUBE # FIXME
|
|
||||||
username_attribute = username
|
username_attribute = username
|
||||||
scope = email profile openid
|
scope = email profile openid
|
||||||
tls_ca_cert_file = /etc/ssl/certs/ca-certificates.crt
|
tls_ca_cert_file = /etc/ssl/certs/ca-certificates.crt
|
||||||
active_attribute = active
|
active_attribute = active
|
||||||
active_value = true
|
active_value = true
|
||||||
openid_configuration_url = ${auth-passthru.oauth2-discovery-url "roundcube"}
|
openid_configuration_url = ${auth-passthru.oauth2-discovery-url oauth-client-id}
|
||||||
debug = "no"
|
debug = "no"
|
||||||
'';
|
'';
|
||||||
|
prefix = ''introspection_url = "'' +
|
||||||
|
(auth-passthru.oauth2-introspection-url-prefix oauth-client-id);
|
||||||
|
suffix = auth-passthru.oauth2-introspection-url-postfix + ''"'';
|
||||||
|
passwordFile = oauth-client-secret-fp;
|
||||||
|
destination = dovecot-oauth2-conf-fp;
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
# for dovecot2 to have access to get through /run/keys directory
|
||||||
|
users.groups.keys.members = [ group ];
|
||||||
|
|
||||||
mailserver.ldap = {
|
mailserver.ldap = {
|
||||||
# note: in `ldapsearch` first comes filter, then attributes
|
# note: in `ldapsearch` first comes filter, then attributes
|
||||||
dovecot.userAttrs = "+"; # all operational attributes
|
dovecot.userAttrs = "+"; # all operational attributes
|
||||||
@@ -76,7 +92,7 @@ in
|
|||||||
passdb {
|
passdb {
|
||||||
driver = oauth2
|
driver = oauth2
|
||||||
mechanisms = xoauth2 oauthbearer
|
mechanisms = xoauth2 oauthbearer
|
||||||
args = ${dovecot-oauth2-conf-file}
|
args = ${dovecot-oauth2-conf-fp}
|
||||||
}
|
}
|
||||||
|
|
||||||
userdb {
|
userdb {
|
||||||
@@ -114,13 +130,22 @@ in
|
|||||||
services.dovecot2.enablePAM = false;
|
services.dovecot2.enablePAM = false;
|
||||||
systemd.services.dovecot2 = {
|
systemd.services.dovecot2 = {
|
||||||
# TODO does it merge with existing preStart?
|
# TODO does it merge with existing preStart?
|
||||||
preStart = setPwdInLdapConfFile + "\n";
|
preStart = setPwdInLdapConfFile + "\n" + write-dovecot-oauth2-conf + "\n";
|
||||||
# FIXME pass dependant services to auth module option instead?
|
# FIXME pass dependant services to auth module option instead?
|
||||||
wants = [ auth-passthru.oauth2-systemd-service ];
|
wants = [ auth-passthru.oauth2-systemd-service ];
|
||||||
after = [ auth-passthru.oauth2-systemd-service ];
|
after = [ auth-passthru.oauth2-systemd-service ];
|
||||||
serviceConfig.RuntimeDirectory = lib.mkForce [ runtime-directory ];
|
serviceConfig.RuntimeDirectory = lib.mkForce [ runtime-directory ];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
systemd.services.kanidm.serviceConfig.ExecStartPre = lib.mkAfter [
|
||||||
|
("-" + oauth-secret-ExecStartPreScript)
|
||||||
|
];
|
||||||
# does it merge with existing restartTriggers?
|
# does it merge with existing restartTriggers?
|
||||||
systemd.services.postfix.restartTriggers = [ setPwdInLdapConfFile ];
|
systemd.services.postfix.restartTriggers = [
|
||||||
|
setPwdInLdapConfFile
|
||||||
|
write-dovecot-oauth2-conf
|
||||||
|
];
|
||||||
|
selfprivacy.passthru.mailserver = {
|
||||||
|
inherit oauth-client-id oauth-client-secret-fp;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
{ config, lib, pkgs, ... }@nixos-args:
|
{ config, lib, pkgs, ... }@nixos-args:
|
||||||
let
|
let
|
||||||
inherit (import ./common.nix nixos-args)
|
inherit (import ./common.nix nixos-args)
|
||||||
appendLdapBindPwd
|
appendSetting
|
||||||
auth-passthru
|
auth-passthru
|
||||||
is-auth-enabled
|
is-auth-enabled
|
||||||
;
|
;
|
||||||
@@ -29,7 +29,7 @@ let
|
|||||||
query_filter = ${cfg.ldap.postfix.filter}
|
query_filter = ${cfg.ldap.postfix.filter}
|
||||||
result_attribute = ${cfg.ldap.postfix.mailAttribute}
|
result_attribute = ${cfg.ldap.postfix.mailAttribute}
|
||||||
'';
|
'';
|
||||||
appendPwdInSenderLoginMap = appendLdapBindPwd {
|
appendPwdInSenderLoginMap = appendSetting {
|
||||||
name = "ldap-sender-login-map";
|
name = "ldap-sender-login-map";
|
||||||
file = ldapSenderLoginMap;
|
file = ldapSenderLoginMap;
|
||||||
prefix = "bind_pw = ";
|
prefix = "bind_pw = ";
|
||||||
@@ -43,7 +43,7 @@ let
|
|||||||
result_attribute = ${cfg.ldap.postfix.uidAttribute}
|
result_attribute = ${cfg.ldap.postfix.uidAttribute}
|
||||||
'';
|
'';
|
||||||
ldapVirtualMailboxMapFile = "/run/postfix/ldap-virtual-mailbox-map.cf";
|
ldapVirtualMailboxMapFile = "/run/postfix/ldap-virtual-mailbox-map.cf";
|
||||||
appendPwdInVirtualMailboxMap = appendLdapBindPwd {
|
appendPwdInVirtualMailboxMap = appendSetting {
|
||||||
name = "ldap-virtual-mailbox-map";
|
name = "ldap-virtual-mailbox-map";
|
||||||
file = ldapVirtualMailboxMap;
|
file = ldapVirtualMailboxMap;
|
||||||
prefix = "bind_pw = ";
|
prefix = "bind_pw = ";
|
||||||
|
@@ -3,8 +3,9 @@ rec {
|
|||||||
auth-passthru = config.passthru.selfprivacy.auth;
|
auth-passthru = config.passthru.selfprivacy.auth;
|
||||||
domain = config.selfprivacy.domain;
|
domain = config.selfprivacy.domain;
|
||||||
is-auth-enabled = config.selfprivacy.modules.auth.enable or false;
|
is-auth-enabled = config.selfprivacy.modules.auth.enable or false;
|
||||||
|
group = "dovecot2";
|
||||||
|
|
||||||
appendLdapBindPwd =
|
appendSetting =
|
||||||
{ name, file, prefix, suffix ? "", passwordFile, destination }:
|
{ name, file, prefix, suffix ? "", passwordFile, destination }:
|
||||||
pkgs.writeScript "append-ldap-bind-pwd-in-${name}" ''
|
pkgs.writeScript "append-ldap-bind-pwd-in-${name}" ''
|
||||||
#!${pkgs.stdenv.shell}
|
#!${pkgs.stdenv.shell}
|
||||||
|
@@ -1,10 +1,15 @@
|
|||||||
[
|
[
|
||||||
[ "mailserver" ],
|
[ "mailserver" ],
|
||||||
|
[ "passthru", "selfprivacy", "auth", "admins-group" ],
|
||||||
|
[ "passthru", "selfprivacy", "auth", "full-users-group" ],
|
||||||
[ "passthru", "selfprivacy", "auth", "ldap-base-dn" ],
|
[ "passthru", "selfprivacy", "auth", "ldap-base-dn" ],
|
||||||
[ "passthru", "selfprivacy", "auth", "ldap-port" ],
|
[ "passthru", "selfprivacy", "auth", "ldap-port" ],
|
||||||
[ "passthru", "selfprivacy", "auth", "oauth2-discovery-url" ],
|
[ "passthru", "selfprivacy", "auth", "oauth2-discovery-url" ],
|
||||||
[ "passthru", "selfprivacy", "auth", "oauth2-introspection-url" ],
|
[ "passthru", "selfprivacy", "auth", "oauth2-introspection-url-postfix" ],
|
||||||
|
[ "passthru", "selfprivacy", "auth", "oauth2-introspection-url-prefix" ],
|
||||||
[ "passthru", "selfprivacy", "auth", "oauth2-systemd-service" ],
|
[ "passthru", "selfprivacy", "auth", "oauth2-systemd-service" ],
|
||||||
|
[ "passthru", "selfprivacy", "roundcube", "oauth-client-id" ],
|
||||||
|
[ "passthru", "selfprivacy", "roundcube", "oauth-client-secret-fp" ],
|
||||||
[ "security", "acme", "certs" ],
|
[ "security", "acme", "certs" ],
|
||||||
[ "selfprivacy", "domain" ],
|
[ "selfprivacy", "domain" ],
|
||||||
[ "selfprivacy", "hashedMasterPassword" ],
|
[ "selfprivacy", "hashedMasterPassword" ],
|
||||||
|
@@ -5,20 +5,22 @@ let
|
|||||||
inherit (import ./common.nix { inherit config pkgs; })
|
inherit (import ./common.nix { inherit config pkgs; })
|
||||||
auth-passthru
|
auth-passthru
|
||||||
domain
|
domain
|
||||||
|
group
|
||||||
is-auth-enabled
|
is-auth-enabled
|
||||||
;
|
;
|
||||||
|
|
||||||
mailserver-service-account-name = "sp.mailserver.service-account";
|
mailserver-service-account-name = "sp.mailserver.service-account";
|
||||||
mailserver-service-account-token-name = "mailserver-service-account-token";
|
mailserver-service-account-token-name = "mailserver-service-account-token";
|
||||||
mailserver-service-account-token-fp =
|
mailserver-service-account-token-fp =
|
||||||
"/run/keys/mailserver/kanidm-service-account-token"; # FIXME sync with auth module
|
"/run/keys/${group}/kanidm-service-account-token"; # FIXME sync with auth module
|
||||||
kanidmExecStartPostScriptRoot = pkgs.writeShellScript
|
kanidmExecStartPreScriptRoot = pkgs.writeShellScript
|
||||||
"mailserver-kanidm-ExecStartPost-root-script.sh"
|
"mailserver-kanidm-ExecStartPre-root-script.sh"
|
||||||
''
|
''
|
||||||
# set-group-ID bit allows for kanidm user to create files,
|
# set-group-ID bit allows for kanidm user to create files inheriting group
|
||||||
mkdir -p -v --mode=u+rwx,g+rs,g-w,o-rwx /run/keys/mailserver
|
mkdir -p -v --mode=u+rwx,g+rs,g-w,o-rwx /run/keys/${group}
|
||||||
chown kanidm:kanidm /run/keys/mailserver
|
chown kanidm:${group} /run/keys/${group}
|
||||||
'';
|
'';
|
||||||
|
# create service account token, needed for LDAP
|
||||||
kanidmExecStartPostScript = pkgs.writeShellScript
|
kanidmExecStartPostScript = pkgs.writeShellScript
|
||||||
"mailserver-kanidm-ExecStartPost-script.sh"
|
"mailserver-kanidm-ExecStartPost-script.sh"
|
||||||
''
|
''
|
||||||
@@ -173,7 +175,7 @@ lib.mkIf sp.modules.simple-nixos-mailserver.enable (lib.mkMerge [
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
# the following part is active only when "auth" module is enabled
|
# the following parts are active only when "auth" module is enabled
|
||||||
(lib.attrsets.optionalAttrs
|
(lib.attrsets.optionalAttrs
|
||||||
(options.selfprivacy.modules ? "auth")
|
(options.selfprivacy.modules ? "auth")
|
||||||
(lib.mkIf is-auth-enabled {
|
(lib.mkIf is-auth-enabled {
|
||||||
@@ -199,9 +201,11 @@ lib.mkIf sp.modules.simple-nixos-mailserver.enable (lib.mkMerge [
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
# FIXME set auth module option instead
|
# FIXME set auth module option instead
|
||||||
|
systemd.services.kanidm.serviceConfig.ExecStartPre = lib.mkBefore [
|
||||||
|
("-+" + kanidmExecStartPreScriptRoot)
|
||||||
|
];
|
||||||
systemd.services.kanidm.serviceConfig.ExecStartPost = lib.mkAfter [
|
systemd.services.kanidm.serviceConfig.ExecStartPost = lib.mkAfter [
|
||||||
("+" + kanidmExecStartPostScriptRoot)
|
("-" + kanidmExecStartPostScript)
|
||||||
kanidmExecStartPostScript
|
|
||||||
];
|
];
|
||||||
}))
|
}))
|
||||||
(lib.attrsets.optionalAttrs
|
(lib.attrsets.optionalAttrs
|
||||||
|
Reference in New Issue
Block a user