about summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
authorFlorian Klink <flokli@flokli.de>2019-03-28 14:30:14 +0100
committerGitHub <noreply@github.com>2019-03-28 14:30:14 +0100
commit6670b4c37d4acfd4c2149fd60356d2d88c3ae4ef (patch)
treec419a87554cc6426051c783703318dc9c0e93b85 /nixos
parentef6a1b7f460e627828f9dc4ce74c0adb661a4702 (diff)
parent8817bbefdbe9f54f7ee42e5cef00f386e227bf5d (diff)
downloadnixlib-6670b4c37d4acfd4c2149fd60356d2d88c3ae4ef.tar
nixlib-6670b4c37d4acfd4c2149fd60356d2d88c3ae4ef.tar.gz
nixlib-6670b4c37d4acfd4c2149fd60356d2d88c3ae4ef.tar.bz2
nixlib-6670b4c37d4acfd4c2149fd60356d2d88c3ae4ef.tar.lz
nixlib-6670b4c37d4acfd4c2149fd60356d2d88c3ae4ef.tar.xz
nixlib-6670b4c37d4acfd4c2149fd60356d2d88c3ae4ef.tar.zst
nixlib-6670b4c37d4acfd4c2149fd60356d2d88c3ae4ef.zip
Merge pull request #58419 from flokli/ldap-nslcd-startup
nixos/ldap: set proper User= and Group= for nslcd service
Diffstat (limited to 'nixos')
-rw-r--r--nixos/doc/manual/release-notes/rl-1903.xml7
-rw-r--r--nixos/modules/config/ldap.nix89
-rw-r--r--nixos/tests/ldap.nix9
3 files changed, 57 insertions, 48 deletions
diff --git a/nixos/doc/manual/release-notes/rl-1903.xml b/nixos/doc/manual/release-notes/rl-1903.xml
index 7d40637df931..bbd3cf2e9db5 100644
--- a/nixos/doc/manual/release-notes/rl-1903.xml
+++ b/nixos/doc/manual/release-notes/rl-1903.xml
@@ -516,6 +516,13 @@
      Graylog</link> for details.
     </para>
    </listitem>
+   <listitem>
+    <para>
+      The option <literal>users.ldap.bind.password</literal> was renamed to <literal>users.ldap.bind.passwordFile</literal>,
+      and needs to be readable by the <literal>nslcd</literal> user.
+      Same applies to the new <literal>users.ldap.daemon.rootpwmodpwFile</literal> option.
+    </para>
+   </listitem>
   </itemizedlist>
  </section>
 
diff --git a/nixos/modules/config/ldap.nix b/nixos/modules/config/ldap.nix
index f65a3fc50d54..e008497a2a6e 100644
--- a/nixos/modules/config/ldap.nix
+++ b/nixos/modules/config/ldap.nix
@@ -27,25 +27,29 @@ let
     '';
   };
 
-  nslcdConfig = {
-    target = "nslcd.conf";
-    source = writeText "nslcd.conf" ''
-      uid nslcd
-      gid nslcd
-      uri ${cfg.server}
-      base ${cfg.base}
-      timelimit ${toString cfg.timeLimit}
-      bind_timelimit ${toString cfg.bind.timeLimit}
-      ${optionalString (cfg.bind.distinguishedName != "")
-        "binddn ${cfg.bind.distinguishedName}" }
-      ${optionalString (cfg.daemon.rootpwmoddn != "")
-        "rootpwmoddn ${cfg.daemon.rootpwmoddn}" }
-      ${optionalString (cfg.daemon.extraConfig != "") cfg.daemon.extraConfig }
-    '';
-  };
-
-  insertLdapPassword = !config.users.ldap.daemon.enable &&
-    config.users.ldap.bind.distinguishedName != "";
+  nslcdConfig = writeText "nslcd.conf" ''
+    uid nslcd
+    gid nslcd
+    uri ${cfg.server}
+    base ${cfg.base}
+    timelimit ${toString cfg.timeLimit}
+    bind_timelimit ${toString cfg.bind.timeLimit}
+    ${optionalString (cfg.bind.distinguishedName != "")
+      "binddn ${cfg.bind.distinguishedName}" }
+    ${optionalString (cfg.daemon.rootpwmoddn != "")
+      "rootpwmoddn ${cfg.daemon.rootpwmoddn}" }
+    ${optionalString (cfg.daemon.extraConfig != "") cfg.daemon.extraConfig }
+  '';
+
+  # nslcd normally reads configuration from /etc/nslcd.conf.
+  # this file might contain secrets. We append those at runtime,
+  # so redirect its location to something more temporary.
+  nslcdWrapped = runCommandNoCC "nslcd-wrapped" { nativeBuildInputs = [ makeWrapper ]; } ''
+    mkdir -p $out/bin
+    makeWrapper ${nss_pam_ldapd}/sbin/nslcd $out/bin/nslcd \
+      --set LD_PRELOAD    "${pkgs.libredirect}/lib/libredirect.so" \
+      --set NIX_REDIRECTS "/etc/nslcd.conf=/run/nslcd/nslcd.conf"
+  '';
 
 in
 
@@ -139,13 +143,13 @@ in
           '';
         };
 
-        rootpwmodpw = mkOption {
+        rootpwmodpwFile = mkOption {
           default = "";
           example = "/run/keys/nslcd.rootpwmodpw";
           type = types.str;
           description = ''
-            The path to a file containing the credentials with which
-            to bind to the LDAP server if the root user tries to change a user's password
+            The path to a file containing the credentials with which to bind to
+            the LDAP server if the root user tries to change a user's password.
           '';
         };
       };
@@ -161,7 +165,7 @@ in
           '';
         };
 
-        password = mkOption {
+        passwordFile = mkOption {
           default = "/etc/ldap/bind.password";
           type = types.str;
           description = ''
@@ -220,14 +224,14 @@ in
 
   config = mkIf cfg.enable {
 
-    environment.etc = if cfg.daemon.enable then [nslcdConfig] else [ldapConfig];
+    environment.etc = optional (!cfg.daemon.enable) ldapConfig;
 
-    system.activationScripts = mkIf insertLdapPassword {
+    system.activationScripts = mkIf (!cfg.daemon.enable) {
       ldap = stringAfter [ "etc" "groups" "users" ] ''
-        if test -f "${cfg.bind.password}" ; then
+        if test -f "${cfg.bind.passwordFile}" ; then
           umask 0077
           conf="$(mktemp)"
-          printf 'bindpw %s\n' "$(cat ${cfg.bind.password})" |
+          printf 'bindpw %s\n' "$(cat ${cfg.bind.passwordFile})" |
           cat ${ldapConfig.source} - >"$conf"
           mv -fT "$conf" /etc/ldap.conf
         fi
@@ -251,7 +255,6 @@ in
     };
 
     systemd.services = mkIf cfg.daemon.enable {
-
       nslcd = {
         wantedBy = [ "multi-user.target" ];
 
@@ -259,32 +262,32 @@ in
           umask 0077
           conf="$(mktemp)"
           {
-            cat ${nslcdConfig.source}
-            test -z '${cfg.bind.distinguishedName}' -o ! -f '${cfg.bind.password}' ||
-            printf 'bindpw %s\n' "$(cat '${cfg.bind.password}')"
-            test -z '${cfg.daemon.rootpwmoddn}' -o ! -f '${cfg.daemon.rootpwmodpw}' ||
-            printf 'rootpwmodpw %s\n' "$(cat '${cfg.daemon.rootpwmodpw}')"
+            cat ${nslcdConfig}
+            test -z '${cfg.bind.distinguishedName}' -o ! -f '${cfg.bind.passwordFile}' ||
+            printf 'bindpw %s\n' "$(cat '${cfg.bind.passwordFile}')"
+            test -z '${cfg.daemon.rootpwmoddn}' -o ! -f '${cfg.daemon.rootpwmodpwFile}' ||
+            printf 'rootpwmodpw %s\n' "$(cat '${cfg.daemon.rootpwmodpwFile}')"
           } >"$conf"
-          mv -fT "$conf" /etc/nslcd.conf
+          mv -fT "$conf" /run/nslcd/nslcd.conf
         '';
-
-        # NOTE: because one cannot pass a custom config path to `nslcd`
-        # (which is only able to use `/etc/nslcd.conf`)
-        # changes in `nslcdConfig` won't change `serviceConfig`,
-        # and thus won't restart `nslcd`.
-        # Therefore `restartTriggers` is used on `/etc/nslcd.conf`.
-        restartTriggers = [ nslcdConfig.source ];
+        restartTriggers = [ "/run/nslcd/nslcd.conf" ];
 
         serviceConfig = {
-          ExecStart = "${nss_pam_ldapd}/sbin/nslcd";
+          ExecStart = "${nslcdWrapped}/bin/nslcd";
           Type = "forking";
-          PIDFile = "/run/nslcd/nslcd.pid";
           Restart = "always";
+          User = "nslcd";
+          Group = "nslcd";
           RuntimeDirectory = [ "nslcd" ];
+          PIDFile = "/run/nslcd/nslcd.pid";
         };
       };
 
     };
 
   };
+
+  imports =
+    [ (mkRenamedOptionModule [ "users" "ldap" "bind" "password"] [ "users" "ldap" "bind" "passwordFile"])
+    ];
 }
diff --git a/nixos/tests/ldap.nix b/nixos/tests/ldap.nix
index b3fd42e75886..fe859876ed25 100644
--- a/nixos/tests/ldap.nix
+++ b/nixos/tests/ldap.nix
@@ -28,20 +28,19 @@ let
       users.ldap.daemon = {
         enable = useDaemon;
         rootpwmoddn = "cn=admin,${dbSuffix}";
-        rootpwmodpw = "/etc/nslcd.rootpwmodpw";
+        rootpwmodpwFile = "/etc/nslcd.rootpwmodpw";
       };
-      # NOTE: password stored in clear in Nix's store, but this is a test.
-      environment.etc."nslcd.rootpwmodpw".source = pkgs.writeText "rootpwmodpw" dbAdminPwd;
       users.ldap.loginPam = true;
       users.ldap.nsswitch = true;
       users.ldap.server = "ldap://server";
       users.ldap.base = "ou=posix,${dbSuffix}";
       users.ldap.bind = {
         distinguishedName = "cn=admin,${dbSuffix}";
-        password = "/etc/ldap/bind.password";
+        passwordFile = "/etc/ldap/bind.password";
       };
-      # NOTE: password stored in clear in Nix's store, but this is a test.
+      # NOTE: passwords stored in clear in Nix's store, but this is a test.
       environment.etc."ldap/bind.password".source = pkgs.writeText "password" dbAdminPwd;
+      environment.etc."nslcd.rootpwmodpw".source = pkgs.writeText "rootpwmodpw" dbAdminPwd;
     };
 in