summary refs log tree commit diff
diff options
context:
space:
mode:
authorGuillaume Girol <symphorien@users.noreply.github.com>2021-09-18 15:28:49 +0000
committerGitHub <noreply@github.com>2021-09-18 15:28:49 +0000
commitceb2e6667b064ce5130f751d7b6625a81e191dec (patch)
tree25580706229710dd815d1d228474488331eb6b6e
parenta92dd171bae2db6eeff74a3d31fa99e47e793359 (diff)
parent27b0c53d237b6c0411dc5798376b0ba6fbad0df0 (diff)
downloadnixpkgs-ceb2e6667b064ce5130f751d7b6625a81e191dec.tar
nixpkgs-ceb2e6667b064ce5130f751d7b6625a81e191dec.tar.gz
nixpkgs-ceb2e6667b064ce5130f751d7b6625a81e191dec.tar.bz2
nixpkgs-ceb2e6667b064ce5130f751d7b6625a81e191dec.tar.lz
nixpkgs-ceb2e6667b064ce5130f751d7b6625a81e191dec.tar.xz
nixpkgs-ceb2e6667b064ce5130f751d7b6625a81e191dec.tar.zst
nixpkgs-ceb2e6667b064ce5130f751d7b6625a81e191dec.zip
Merge pull request #126289 from rnhmjoj/wrappers
nixos/security/wrappers: make well-typed
-rw-r--r--nixos/doc/manual/from_md/release-notes/rl-2111.section.xml10
-rw-r--r--nixos/doc/manual/release-notes/rl-2111.section.md2
-rw-r--r--nixos/modules/programs/bandwhich.nix4
-rw-r--r--nixos/modules/programs/captive-browser.nix4
-rw-r--r--nixos/modules/programs/ccache.nix2
-rw-r--r--nixos/modules/programs/firejail.nix7
-rw-r--r--nixos/modules/programs/gamemode.nix2
-rw-r--r--nixos/modules/programs/iftop.nix4
-rw-r--r--nixos/modules/programs/iotop.nix4
-rw-r--r--nixos/modules/programs/kbdlight.nix7
-rw-r--r--nixos/modules/programs/liboping.nix4
-rw-r--r--nixos/modules/programs/msmtp.nix2
-rw-r--r--nixos/modules/programs/mtr.nix4
-rw-r--r--nixos/modules/programs/noisetorch.nix4
-rw-r--r--nixos/modules/programs/shadow.nix21
-rw-r--r--nixos/modules/programs/singularity.nix7
-rw-r--r--nixos/modules/programs/slock.nix7
-rw-r--r--nixos/modules/programs/ssmtp.nix2
-rw-r--r--nixos/modules/programs/traceroute.nix4
-rw-r--r--nixos/modules/programs/udevil.nix7
-rw-r--r--nixos/modules/programs/wavemon.nix4
-rw-r--r--nixos/modules/programs/wshowkeys.nix7
-rw-r--r--nixos/modules/security/chromium-suid-sandbox.nix7
-rw-r--r--nixos/modules/security/doas.nix9
-rw-r--r--nixos/modules/security/duosec.nix7
-rw-r--r--nixos/modules/security/pam.nix5
-rw-r--r--nixos/modules/security/pam_usb.nix14
-rw-r--r--nixos/modules/security/polkit.nix14
-rw-r--r--nixos/modules/security/wrappers/default.nix282
-rw-r--r--nixos/modules/services/desktops/gnome/gnome-keyring.nix4
-rw-r--r--nixos/modules/services/mail/exim.nix7
-rw-r--r--nixos/modules/services/mail/mail.nix3
-rw-r--r--nixos/modules/services/mail/opensmtpd.nix5
-rw-r--r--nixos/modules/services/mail/postfix.nix4
-rw-r--r--nixos/modules/services/misc/mame.nix4
-rw-r--r--nixos/modules/services/misc/weechat.nix7
-rw-r--r--nixos/modules/services/monitoring/incron.nix7
-rw-r--r--nixos/modules/services/monitoring/zabbix-proxy.nix7
-rw-r--r--nixos/modules/services/networking/smokeping.nix14
-rw-r--r--nixos/modules/services/networking/x2goserver.nix2
-rw-r--r--nixos/modules/services/scheduling/cron.nix7
-rw-r--r--nixos/modules/services/scheduling/fcron.nix3
-rw-r--r--nixos/modules/services/video/replay-sorcery.nix4
-rw-r--r--nixos/modules/services/x11/desktop-managers/cde.nix5
-rw-r--r--nixos/modules/services/x11/desktop-managers/enlightenment.nix21
-rw-r--r--nixos/modules/services/x11/desktop-managers/plasma5.nix24
-rw-r--r--nixos/modules/tasks/filesystems/ecryptfs.nix14
-rw-r--r--nixos/modules/tasks/network-interfaces.nix9
-rw-r--r--nixos/modules/virtualisation/libvirtd.nix3
-rw-r--r--nixos/modules/virtualisation/spice-usb-redirection.nix6
50 files changed, 462 insertions, 155 deletions
diff --git a/nixos/doc/manual/from_md/release-notes/rl-2111.section.xml b/nixos/doc/manual/from_md/release-notes/rl-2111.section.xml
index 165c83148e6..6b3c706bb9b 100644
--- a/nixos/doc/manual/from_md/release-notes/rl-2111.section.xml
+++ b/nixos/doc/manual/from_md/release-notes/rl-2111.section.xml
@@ -280,6 +280,16 @@
     <itemizedlist>
       <listitem>
         <para>
+          The <literal>security.wrappers</literal> option now requires
+          to always specify an owner, group and whether the
+          setuid/setgid bit should be set. This is motivated by the fact
+          that before NixOS 21.11, specifying either setuid or setgid
+          but not owner/group resulted in wrappers owned by
+          nobody/nogroup, which is unsafe.
+        </para>
+      </listitem>
+      <listitem>
+        <para>
           The <literal>paperless</literal> module and package have been
           removed. All users should migrate to the successor
           <literal>paperless-ng</literal> instead. The Paperless project
diff --git a/nixos/doc/manual/release-notes/rl-2111.section.md b/nixos/doc/manual/release-notes/rl-2111.section.md
index 8e7bdbb8744..71342e0c2c9 100644
--- a/nixos/doc/manual/release-notes/rl-2111.section.md
+++ b/nixos/doc/manual/release-notes/rl-2111.section.md
@@ -88,6 +88,8 @@ subsonic-compatible api. Available as [navidrome](#opt-services.navidrome.enable
 
 ## Backward Incompatibilities {#sec-release-21.11-incompatibilities}
 
+- The `security.wrappers` option now requires to always specify an owner, group and whether the setuid/setgid bit should be set.
+  This is motivated by the fact that before NixOS 21.11, specifying either setuid or setgid but not owner/group resulted in wrappers owned by nobody/nogroup, which is unsafe.
 
 - The `paperless` module and package have been removed. All users should migrate to the
   successor `paperless-ng` instead. The Paperless project [has been
diff --git a/nixos/modules/programs/bandwhich.nix b/nixos/modules/programs/bandwhich.nix
index 1cffb5fa276..610d602ad2c 100644
--- a/nixos/modules/programs/bandwhich.nix
+++ b/nixos/modules/programs/bandwhich.nix
@@ -22,8 +22,10 @@ in {
   config = mkIf cfg.enable {
     environment.systemPackages = with pkgs; [ bandwhich ];
     security.wrappers.bandwhich = {
-      source = "${pkgs.bandwhich}/bin/bandwhich";
+      owner = "root";
+      group = "root";
       capabilities = "cap_net_raw,cap_net_admin+ep";
+      source = "${pkgs.bandwhich}/bin/bandwhich";
     };
   };
 }
diff --git a/nixos/modules/programs/captive-browser.nix b/nixos/modules/programs/captive-browser.nix
index d7684d08c6c..4e8abdeecf0 100644
--- a/nixos/modules/programs/captive-browser.nix
+++ b/nixos/modules/programs/captive-browser.nix
@@ -105,11 +105,15 @@ in
       );
 
     security.wrappers.udhcpc = {
+      owner = "root";
+      group = "root";
       capabilities = "cap_net_raw+p";
       source = "${pkgs.busybox}/bin/udhcpc";
     };
 
     security.wrappers.captive-browser = {
+      owner = "root";
+      group = "root";
       capabilities = "cap_net_raw+p";
       source = pkgs.writeShellScript "captive-browser" ''
         export PREV_CONFIG_HOME="$XDG_CONFIG_HOME"
diff --git a/nixos/modules/programs/ccache.nix b/nixos/modules/programs/ccache.nix
index d672e1da017..35a4373f612 100644
--- a/nixos/modules/programs/ccache.nix
+++ b/nixos/modules/programs/ccache.nix
@@ -28,7 +28,9 @@ in {
 
       # "nix-ccache --show-stats" and "nix-ccache --clear"
       security.wrappers.nix-ccache = {
+        owner = "nobody";
         group = "nixbld";
+        setuid = false;
         setgid = true;
         source = pkgs.writeScript "nix-ccache.pl" ''
           #!${pkgs.perl}/bin/perl
diff --git a/nixos/modules/programs/firejail.nix b/nixos/modules/programs/firejail.nix
index ad4ef1a3945..9384b01b367 100644
--- a/nixos/modules/programs/firejail.nix
+++ b/nixos/modules/programs/firejail.nix
@@ -81,7 +81,12 @@ in {
   };
 
   config = mkIf cfg.enable {
-    security.wrappers.firejail.source = "${lib.getBin pkgs.firejail}/bin/firejail";
+    security.wrappers.firejail =
+      { setuid = true;
+        owner = "root";
+        group = "root";
+        source = "${lib.getBin pkgs.firejail}/bin/firejail";
+      };
 
     environment.systemPackages = [ pkgs.firejail ] ++ [ wrappedBins ];
   };
diff --git a/nixos/modules/programs/gamemode.nix b/nixos/modules/programs/gamemode.nix
index 03949bf98df..102788f5b01 100644
--- a/nixos/modules/programs/gamemode.nix
+++ b/nixos/modules/programs/gamemode.nix
@@ -56,6 +56,8 @@ in
       polkit.enable = true;
       wrappers = mkIf cfg.enableRenice {
         gamemoded = {
+          owner = "root";
+          group = "root";
           source = "${pkgs.gamemode}/bin/gamemoded";
           capabilities = "cap_sys_nice+ep";
         };
diff --git a/nixos/modules/programs/iftop.nix b/nixos/modules/programs/iftop.nix
index a98a9a8187d..c74714a9a6d 100644
--- a/nixos/modules/programs/iftop.nix
+++ b/nixos/modules/programs/iftop.nix
@@ -11,8 +11,10 @@ in {
   config = mkIf cfg.enable {
     environment.systemPackages = [ pkgs.iftop ];
     security.wrappers.iftop = {
-      source = "${pkgs.iftop}/bin/iftop";
+      owner = "root";
+      group = "root";
       capabilities = "cap_net_raw+p";
+      source = "${pkgs.iftop}/bin/iftop";
     };
   };
 }
diff --git a/nixos/modules/programs/iotop.nix b/nixos/modules/programs/iotop.nix
index 5512dbc62f7..b7c1c69f9dd 100644
--- a/nixos/modules/programs/iotop.nix
+++ b/nixos/modules/programs/iotop.nix
@@ -10,8 +10,10 @@ in {
   };
   config = mkIf cfg.enable {
     security.wrappers.iotop = {
-      source = "${pkgs.iotop}/bin/iotop";
+      owner = "root";
+      group = "root";
       capabilities = "cap_net_admin+p";
+      source = "${pkgs.iotop}/bin/iotop";
     };
   };
 }
diff --git a/nixos/modules/programs/kbdlight.nix b/nixos/modules/programs/kbdlight.nix
index 58e45872fac..8a2a0057cf2 100644
--- a/nixos/modules/programs/kbdlight.nix
+++ b/nixos/modules/programs/kbdlight.nix
@@ -11,6 +11,11 @@ in
 
   config = mkIf cfg.enable {
     environment.systemPackages = [ pkgs.kbdlight ];
-    security.wrappers.kbdlight.source = "${pkgs.kbdlight.out}/bin/kbdlight";
+    security.wrappers.kbdlight =
+      { setuid = true;
+        owner = "root";
+        group = "root";
+        source = "${pkgs.kbdlight.out}/bin/kbdlight";
+      };
   };
 }
diff --git a/nixos/modules/programs/liboping.nix b/nixos/modules/programs/liboping.nix
index 4e4c235ccde..4433f9767d6 100644
--- a/nixos/modules/programs/liboping.nix
+++ b/nixos/modules/programs/liboping.nix
@@ -13,8 +13,10 @@ in {
     security.wrappers = mkMerge (map (
       exec: {
         "${exec}" = {
-          source = "${pkgs.liboping}/bin/${exec}";
+          owner = "root";
+          group = "root";
           capabilities = "cap_net_raw+p";
+          source = "${pkgs.liboping}/bin/${exec}";
         };
       }
     ) [ "oping" "noping" ]);
diff --git a/nixos/modules/programs/msmtp.nix b/nixos/modules/programs/msmtp.nix
index 217060e6b3b..9c067bdc969 100644
--- a/nixos/modules/programs/msmtp.nix
+++ b/nixos/modules/programs/msmtp.nix
@@ -78,6 +78,8 @@ in {
       source = "${pkgs.msmtp}/bin/sendmail";
       setuid = false;
       setgid = false;
+      owner = "root";
+      group = "root";
     };
 
     environment.etc."msmtprc".text = let
diff --git a/nixos/modules/programs/mtr.nix b/nixos/modules/programs/mtr.nix
index 75b710c1584..63516c58440 100644
--- a/nixos/modules/programs/mtr.nix
+++ b/nixos/modules/programs/mtr.nix
@@ -31,8 +31,10 @@ in {
     environment.systemPackages = with pkgs; [ cfg.package ];
 
     security.wrappers.mtr-packet = {
-      source = "${cfg.package}/bin/mtr-packet";
+      owner = "root";
+      group = "root";
       capabilities = "cap_net_raw+p";
+      source = "${cfg.package}/bin/mtr-packet";
     };
   };
 }
diff --git a/nixos/modules/programs/noisetorch.nix b/nixos/modules/programs/noisetorch.nix
index 5f3b0c8f5d1..bca68b0064c 100644
--- a/nixos/modules/programs/noisetorch.nix
+++ b/nixos/modules/programs/noisetorch.nix
@@ -18,8 +18,10 @@ in {
 
   config = mkIf cfg.enable {
     security.wrappers.noisetorch = {
-      source = "${cfg.package}/bin/noisetorch";
+      owner = "root";
+      group = "root";
       capabilities = "cap_sys_resource=+ep";
+      source = "${cfg.package}/bin/noisetorch";
     };
   };
 }
diff --git a/nixos/modules/programs/shadow.nix b/nixos/modules/programs/shadow.nix
index 386ded9d98b..e021f184179 100644
--- a/nixos/modules/programs/shadow.nix
+++ b/nixos/modules/programs/shadow.nix
@@ -43,6 +43,13 @@ let
 
     '';
 
+  mkSetuidRoot = source:
+    { setuid = true;
+      owner = "root";
+      group = "root";
+      inherit source;
+    };
+
 in
 
 {
@@ -109,14 +116,14 @@ in
       };
 
     security.wrappers = {
-      su.source        = "${pkgs.shadow.su}/bin/su";
-      sg.source        = "${pkgs.shadow.out}/bin/sg";
-      newgrp.source    = "${pkgs.shadow.out}/bin/newgrp";
-      newuidmap.source = "${pkgs.shadow.out}/bin/newuidmap";
-      newgidmap.source = "${pkgs.shadow.out}/bin/newgidmap";
+      su        = mkSetuidRoot "${pkgs.shadow.su}/bin/su";
+      sg        = mkSetuidRoot "${pkgs.shadow.out}/bin/sg";
+      newgrp    = mkSetuidRoot "${pkgs.shadow.out}/bin/newgrp";
+      newuidmap = mkSetuidRoot "${pkgs.shadow.out}/bin/newuidmap";
+      newgidmap = mkSetuidRoot "${pkgs.shadow.out}/bin/newgidmap";
     } // lib.optionalAttrs config.users.mutableUsers {
-      chsh.source      = "${pkgs.shadow.out}/bin/chsh";
-      passwd.source    = "${pkgs.shadow.out}/bin/passwd";
+      chsh   = mkSetuidRoot "${pkgs.shadow.out}/bin/chsh";
+      passwd = mkSetuidRoot "${pkgs.shadow.out}/bin/passwd";
     };
   };
 }
diff --git a/nixos/modules/programs/singularity.nix b/nixos/modules/programs/singularity.nix
index 6ac64a81fc2..db935abe4bb 100644
--- a/nixos/modules/programs/singularity.nix
+++ b/nixos/modules/programs/singularity.nix
@@ -16,7 +16,12 @@ in {
 
   config = mkIf cfg.enable {
       environment.systemPackages = [ singularity ];
-      security.wrappers.singularity-suid.source = "${singularity}/libexec/singularity/bin/starter-suid.orig";
+      security.wrappers.singularity-suid =
+      { setuid = true;
+        owner = "root";
+        group = "root";
+        source = "${singularity}/libexec/singularity/bin/starter-suid.orig";
+      };
       systemd.tmpfiles.rules = [
         "d /var/singularity/mnt/session 0770 root root -"
         "d /var/singularity/mnt/final 0770 root root -"
diff --git a/nixos/modules/programs/slock.nix b/nixos/modules/programs/slock.nix
index 0e1281e62cd..ce80fcc5d4a 100644
--- a/nixos/modules/programs/slock.nix
+++ b/nixos/modules/programs/slock.nix
@@ -21,6 +21,11 @@ in
 
   config = mkIf cfg.enable {
     environment.systemPackages = [ pkgs.slock ];
-    security.wrappers.slock.source = "${pkgs.slock.out}/bin/slock";
+    security.wrappers.slock =
+      { setuid = true;
+        owner = "root";
+        group = "root";
+        source = "${pkgs.slock.out}/bin/slock";
+      };
   };
 }
diff --git a/nixos/modules/programs/ssmtp.nix b/nixos/modules/programs/ssmtp.nix
index 8b500f0383f..e28a14538ec 100644
--- a/nixos/modules/programs/ssmtp.nix
+++ b/nixos/modules/programs/ssmtp.nix
@@ -181,6 +181,8 @@ in
       source = "${pkgs.ssmtp}/bin/sendmail";
       setuid = false;
       setgid = false;
+      owner = "root";
+      group = "root";
     };
 
   };
diff --git a/nixos/modules/programs/traceroute.nix b/nixos/modules/programs/traceroute.nix
index 4eb0be3f0e0..6e04057ac50 100644
--- a/nixos/modules/programs/traceroute.nix
+++ b/nixos/modules/programs/traceroute.nix
@@ -19,8 +19,10 @@ in {
 
   config = mkIf cfg.enable {
     security.wrappers.traceroute = {
-      source = "${pkgs.traceroute}/bin/traceroute";
+      owner = "root";
+      group = "root";
       capabilities = "cap_net_raw+p";
+      source = "${pkgs.traceroute}/bin/traceroute";
     };
   };
 }
diff --git a/nixos/modules/programs/udevil.nix b/nixos/modules/programs/udevil.nix
index ba5670f9dfe..0dc08c435df 100644
--- a/nixos/modules/programs/udevil.nix
+++ b/nixos/modules/programs/udevil.nix
@@ -9,6 +9,11 @@ in {
   options.programs.udevil.enable = mkEnableOption "udevil";
 
   config = mkIf cfg.enable {
-    security.wrappers.udevil.source = "${lib.getBin pkgs.udevil}/bin/udevil";
+    security.wrappers.udevil =
+      { setuid = true;
+        owner = "root";
+        group = "root";
+        source = "${lib.getBin pkgs.udevil}/bin/udevil";
+      };
   };
 }
diff --git a/nixos/modules/programs/wavemon.nix b/nixos/modules/programs/wavemon.nix
index ac665fe4a02..e5ccacba75d 100644
--- a/nixos/modules/programs/wavemon.nix
+++ b/nixos/modules/programs/wavemon.nix
@@ -21,8 +21,10 @@ in {
   config = mkIf cfg.enable {
     environment.systemPackages = with pkgs; [ wavemon ];
     security.wrappers.wavemon = {
-      source = "${pkgs.wavemon}/bin/wavemon";
+      owner = "root";
+      group = "root";
       capabilities = "cap_net_admin+ep";
+      source = "${pkgs.wavemon}/bin/wavemon";
     };
   };
 }
diff --git a/nixos/modules/programs/wshowkeys.nix b/nixos/modules/programs/wshowkeys.nix
index 09b008af1d5..f7b71d2bb0c 100644
--- a/nixos/modules/programs/wshowkeys.nix
+++ b/nixos/modules/programs/wshowkeys.nix
@@ -17,6 +17,11 @@ in {
   };
 
   config = mkIf cfg.enable {
-    security.wrappers.wshowkeys.source = "${pkgs.wshowkeys}/bin/wshowkeys";
+    security.wrappers.wshowkeys =
+      { setuid = true;
+        owner = "root";
+        group = "root";
+        source = "${pkgs.wshowkeys}/bin/wshowkeys";
+      };
   };
 }
diff --git a/nixos/modules/security/chromium-suid-sandbox.nix b/nixos/modules/security/chromium-suid-sandbox.nix
index b83dbc4202a..bb99c053f71 100644
--- a/nixos/modules/security/chromium-suid-sandbox.nix
+++ b/nixos/modules/security/chromium-suid-sandbox.nix
@@ -28,6 +28,11 @@ in
 
   config = mkIf cfg.enable {
     environment.systemPackages = [ sandbox ];
-    security.wrappers.${sandbox.passthru.sandboxExecutableName}.source = "${sandbox}/bin/${sandbox.passthru.sandboxExecutableName}";
+    security.wrappers.${sandbox.passthru.sandboxExecutableName} =
+      { setuid = true;
+        owner = "root";
+        group = "root";
+        source = "${sandbox}/bin/${sandbox.passthru.sandboxExecutableName}";
+      };
   };
 }
diff --git a/nixos/modules/security/doas.nix b/nixos/modules/security/doas.nix
index 27f6870aaf3..35f618b03e8 100644
--- a/nixos/modules/security/doas.nix
+++ b/nixos/modules/security/doas.nix
@@ -241,9 +241,12 @@ in
       }
     ];
 
-    security.wrappers = {
-      doas.source = "${doas}/bin/doas";
-    };
+    security.wrappers.doas =
+      { setuid = true;
+        owner = "root";
+        group = "root";
+        source = "${doas}/bin/doas";
+      };
 
     environment.systemPackages = [
       doas
diff --git a/nixos/modules/security/duosec.nix b/nixos/modules/security/duosec.nix
index c47be80b9dc..bbe246fe229 100644
--- a/nixos/modules/security/duosec.nix
+++ b/nixos/modules/security/duosec.nix
@@ -186,7 +186,12 @@ in
   config = mkIf (cfg.ssh.enable || cfg.pam.enable) {
     environment.systemPackages = [ pkgs.duo-unix ];
 
-    security.wrappers.login_duo.source = "${pkgs.duo-unix.out}/bin/login_duo";
+    security.wrappers.login_duo =
+      { setuid = true;
+        owner = "root";
+        group = "root";
+        source = "${pkgs.duo-unix.out}/bin/login_duo";
+      };
 
     system.activationScripts = {
       login_duo = mkIf cfg.ssh.enable ''
diff --git a/nixos/modules/security/pam.nix b/nixos/modules/security/pam.nix
index 163d75d7caf..8b1f653d4e2 100644
--- a/nixos/modules/security/pam.nix
+++ b/nixos/modules/security/pam.nix
@@ -869,9 +869,10 @@ in
 
     security.wrappers = {
       unix_chkpwd = {
-        source = "${pkgs.pam}/sbin/unix_chkpwd.orig";
-        owner = "root";
         setuid = true;
+        owner = "root";
+        group = "root";
+        source = "${pkgs.pam}/sbin/unix_chkpwd.orig";
       };
     };
 
diff --git a/nixos/modules/security/pam_usb.nix b/nixos/modules/security/pam_usb.nix
index c695ba075ca..51d81e823f8 100644
--- a/nixos/modules/security/pam_usb.nix
+++ b/nixos/modules/security/pam_usb.nix
@@ -32,8 +32,18 @@ in
 
     # Make sure pmount and pumount are setuid wrapped.
     security.wrappers = {
-      pmount.source = "${pkgs.pmount.out}/bin/pmount";
-      pumount.source = "${pkgs.pmount.out}/bin/pumount";
+      pmount =
+        { setuid = true;
+          owner = "root";
+          group = "root";
+          source = "${pkgs.pmount.out}/bin/pmount";
+        };
+      pumount =
+        { setuid = true;
+          owner = "root";
+          group = "root";
+          source = "${pkgs.pmount.out}/bin/pumount";
+        };
     };
 
     environment.systemPackages = [ pkgs.pmount ];
diff --git a/nixos/modules/security/polkit.nix b/nixos/modules/security/polkit.nix
index f556cca23cd..d9c58152f1f 100644
--- a/nixos/modules/security/polkit.nix
+++ b/nixos/modules/security/polkit.nix
@@ -83,8 +83,18 @@ in
     security.pam.services.polkit-1 = {};
 
     security.wrappers = {
-      pkexec.source = "${pkgs.polkit.bin}/bin/pkexec";
-      polkit-agent-helper-1.source = "${pkgs.polkit.out}/lib/polkit-1/polkit-agent-helper-1";
+      pkexec =
+        { setuid = true;
+          owner = "root";
+          group = "root";
+          source = "${pkgs.polkit.bin}/bin/pkexec";
+        };
+      polkit-agent-helper-1 =
+        { setuid = true;
+          owner = "root";
+          group = "root";
+          source = "${pkgs.polkit.out}/lib/polkit-1/polkit-agent-helper-1";
+        };
     };
 
     systemd.tmpfiles.rules = [
diff --git a/nixos/modules/security/wrappers/default.nix b/nixos/modules/security/wrappers/default.nix
index 1e65f451515..2697ab0bde8 100644
--- a/nixos/modules/security/wrappers/default.nix
+++ b/nixos/modules/security/wrappers/default.nix
@@ -5,85 +5,140 @@ let
 
   parentWrapperDir = dirOf wrapperDir;
 
-  programs =
-    (lib.mapAttrsToList
-      (n: v: (if v ? program then v else v // {program=n;}))
-      wrappers);
-
   securityWrapper = pkgs.callPackage ./wrapper.nix {
     inherit parentWrapperDir;
   };
 
+  fileModeType =
+    let
+      # taken from the chmod(1) man page
+      symbolic = "[ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=][0-7]+";
+      numeric = "[-+=]?[0-7]{0,4}";
+      mode = "((${symbolic})(,${symbolic})*)|(${numeric})";
+    in
+     lib.types.strMatching mode
+     // { description = "file mode string"; };
+
+  wrapperType = lib.types.submodule ({ name, config, ... }: {
+    options.source = lib.mkOption
+      { type = lib.types.path;
+        description = "The absolute path to the program to be wrapped.";
+      };
+    options.program = lib.mkOption
+      { type = with lib.types; nullOr str;
+        default = name;
+        description = ''
+          The name of the wrapper program. Defaults to the attribute name.
+        '';
+      };
+    options.owner = lib.mkOption
+      { type = lib.types.str;
+        description = "The owner of the wrapper program.";
+      };
+    options.group = lib.mkOption
+      { type = lib.types.str;
+        description = "The group of the wrapper program.";
+      };
+    options.permissions = lib.mkOption
+      { type = fileModeType;
+        default  = "u+rx,g+x,o+x";
+        example = "a+rx";
+        description = ''
+          The permissions of the wrapper program. The format is that of a
+          symbolic or numeric file mode understood by <command>chmod</command>.
+        '';
+      };
+    options.capabilities = lib.mkOption
+      { type = lib.types.commas;
+        default = "";
+        description = ''
+          A comma-separated list of capabilities to be given to the wrapper
+          program. For capabilities supported by the system check the
+          <citerefentry>
+            <refentrytitle>capabilities</refentrytitle>
+            <manvolnum>7</manvolnum>
+          </citerefentry>
+          manual page.
+
+          <note><para>
+            <literal>cap_setpcap</literal>, which is required for the wrapper
+            program to be able to raise caps into the Ambient set is NOT raised
+            to the Ambient set so that the real program cannot modify its own
+            capabilities!! This may be too restrictive for cases in which the
+            real program needs cap_setpcap but it at least leans on the side
+            security paranoid vs. too relaxed.
+          </para></note>
+        '';
+      };
+    options.setuid = lib.mkOption
+      { type = lib.types.bool;
+        default = false;
+        description = "Whether to add the setuid bit the wrapper program.";
+      };
+    options.setgid = lib.mkOption
+      { type = lib.types.bool;
+        default = false;
+        description = "Whether to add the setgid bit the wrapper program.";
+      };
+  });
+
   ###### Activation script for the setcap wrappers
   mkSetcapProgram =
     { program
     , capabilities
     , source
-    , owner  ? "nobody"
-    , group  ? "nogroup"
-    , permissions ? "u+rx,g+x,o+x"
+    , owner
+    , group
+    , permissions
     , ...
     }:
     assert (lib.versionAtLeast (lib.getVersion config.boot.kernelPackages.kernel) "4.3");
     ''
-      cp ${securityWrapper}/bin/security-wrapper $wrapperDir/${program}
-      echo -n "${source}" > $wrapperDir/${program}.real
+      cp ${securityWrapper}/bin/security-wrapper "$wrapperDir/${program}"
+      echo -n "${source}" > "$wrapperDir/${program}.real"
 
       # Prevent races
-      chmod 0000 $wrapperDir/${program}
-      chown ${owner}.${group} $wrapperDir/${program}
+      chmod 0000 "$wrapperDir/${program}"
+      chown ${owner}.${group} "$wrapperDir/${program}"
 
       # Set desired capabilities on the file plus cap_setpcap so
       # the wrapper program can elevate the capabilities set on
       # its file into the Ambient set.
-      ${pkgs.libcap.out}/bin/setcap "cap_setpcap,${capabilities}" $wrapperDir/${program}
+      ${pkgs.libcap.out}/bin/setcap "cap_setpcap,${capabilities}" "$wrapperDir/${program}"
 
       # Set the executable bit
-      chmod ${permissions} $wrapperDir/${program}
+      chmod ${permissions} "$wrapperDir/${program}"
     '';
 
   ###### Activation script for the setuid wrappers
   mkSetuidProgram =
     { program
     , source
-    , owner  ? "nobody"
-    , group  ? "nogroup"
-    , setuid ? false
-    , setgid ? false
-    , permissions ? "u+rx,g+x,o+x"
+    , owner
+    , group
+    , setuid
+    , setgid
+    , permissions
     , ...
     }:
     ''
-      cp ${securityWrapper}/bin/security-wrapper $wrapperDir/${program}
-      echo -n "${source}" > $wrapperDir/${program}.real
+      cp ${securityWrapper}/bin/security-wrapper "$wrapperDir/${program}"
+      echo -n "${source}" > "$wrapperDir/${program}.real"
 
       # Prevent races
-      chmod 0000 $wrapperDir/${program}
-      chown ${owner}.${group} $wrapperDir/${program}
+      chmod 0000 "$wrapperDir/${program}"
+      chown ${owner}.${group} "$wrapperDir/${program}"
 
-      chmod "u${if setuid then "+" else "-"}s,g${if setgid then "+" else "-"}s,${permissions}" $wrapperDir/${program}
+      chmod "u${if setuid then "+" else "-"}s,g${if setgid then "+" else "-"}s,${permissions}" "$wrapperDir/${program}"
     '';
 
   mkWrappedPrograms =
     builtins.map
-      (s: if (s ? capabilities)
-          then mkSetcapProgram
-                 ({ owner = "root";
-                    group = "root";
-                  } // s)
-          else if
-             (s ? setuid && s.setuid) ||
-             (s ? setgid && s.setgid) ||
-             (s ? permissions)
-          then mkSetuidProgram s
-          else mkSetuidProgram
-                 ({ owner  = "root";
-                    group  = "root";
-                    setuid = true;
-                    setgid = false;
-                    permissions = "u+rx,g+x,o+x";
-                  } // s)
-      ) programs;
+      (opts:
+        if opts.capabilities != ""
+        then mkSetcapProgram opts
+        else mkSetuidProgram opts
+      ) (lib.attrValues wrappers);
 in
 {
   imports = [
@@ -95,45 +150,42 @@ in
 
   options = {
     security.wrappers = lib.mkOption {
-      type = lib.types.attrs;
+      type = lib.types.attrsOf wrapperType;
       default = {};
       example = lib.literalExample
         ''
-          { sendmail.source = "/nix/store/.../bin/sendmail";
-            ping = {
-              source  = "${pkgs.iputils.out}/bin/ping";
-              owner   = "nobody";
-              group   = "nogroup";
-              capabilities = "cap_net_raw+ep";
-            };
+          {
+            # a setuid root program
+            doas =
+              { setuid = true;
+                owner = "root";
+                group = "root";
+                source = "''${pkgs.doas}/bin/doas";
+              };
+
+            # a setgid program
+            locate =
+              { setgid = true;
+                owner = "root";
+                group = "mlocate";
+                source = "''${pkgs.locate}/bin/locate";
+              };
+
+            # a program with the CAP_NET_RAW capability
+            ping =
+              { owner = "root";
+                group = "root";
+                capabilities = "cap_net_raw+ep";
+                source = "''${pkgs.iputils.out}/bin/ping";
+              };
           }
         '';
       description = ''
-        This option allows the ownership and permissions on the setuid
-        wrappers for specific programs to be overridden from the
-        default (setuid root, but not setgid root).
-
-        <note>
-          <para>The sub-attribute <literal>source</literal> is mandatory,
-          it must be the absolute path to the program to be wrapped.
-          </para>
-
-          <para>The sub-attribute <literal>program</literal> is optional and
-          can give the wrapper program a new name. The default name is the same
-          as the attribute name itself.</para>
-
-          <para>Additionally, this option can set capabilities on a
-          wrapper program that propagates those capabilities down to the
-          wrapped, real program.</para>
-
-          <para>NOTE: cap_setpcap, which is required for the wrapper
-          program to be able to raise caps into the Ambient set is NOT
-          raised to the Ambient set so that the real program cannot
-          modify its own capabilities!! This may be too restrictive for
-          cases in which the real program needs cap_setpcap but it at
-          least leans on the side security paranoid vs. too
-          relaxed.</para>
-        </note>
+        This option effectively allows adding setuid/setgid bits, capabilities,
+        changing file ownership and permissions of a program without directly
+        modifying it. This works by creating a wrapper program under the
+        <option>security.wrapperDir</option> directory, which is then added to
+        the shell <literal>PATH</literal>.
       '';
     };
 
@@ -151,13 +203,31 @@ in
   ###### implementation
   config = {
 
-    security.wrappers = {
-      # These are mount related wrappers that require the +s permission.
-      fusermount.source = "${pkgs.fuse}/bin/fusermount";
-      fusermount3.source = "${pkgs.fuse3}/bin/fusermount3";
-      mount.source = "${lib.getBin pkgs.util-linux}/bin/mount";
-      umount.source = "${lib.getBin pkgs.util-linux}/bin/umount";
-    };
+    assertions = lib.mapAttrsToList
+      (name: opts:
+        { assertion = opts.setuid || opts.setgid -> opts.capabilities == "";
+          message = ''
+            The security.wrappers.${name} wrapper is not valid:
+                setuid/setgid and capabilities are mutually exclusive.
+          '';
+        }
+      ) wrappers;
+
+    security.wrappers =
+      let
+        mkSetuidRoot = source:
+          { setuid = true;
+            owner = "root";
+            group = "root";
+            inherit source;
+          };
+      in
+      { # These are mount related wrappers that require the +s permission.
+        fusermount  = mkSetuidRoot "${pkgs.fuse}/bin/fusermount";
+        fusermount3 = mkSetuidRoot "${pkgs.fuse3}/bin/fusermount3";
+        mount  = mkSetuidRoot "${lib.getBin pkgs.util-linux}/bin/mount";
+        umount = mkSetuidRoot "${lib.getBin pkgs.util-linux}/bin/umount";
+      };
 
     boot.specialFileSystems.${parentWrapperDir} = {
       fsType = "tmpfs";
@@ -179,19 +249,15 @@ in
       ]}"
     '';
 
-    ###### setcap activation script
+    ###### wrappers activation script
     system.activationScripts.wrappers =
       lib.stringAfter [ "specialfs" "users" ]
         ''
-          # Look in the system path and in the default profile for
-          # programs to be wrapped.
-          WRAPPER_PATH=${config.system.path}/bin:${config.system.path}/sbin
-
           chmod 755 "${parentWrapperDir}"
 
           # We want to place the tmpdirs for the wrappers to the parent dir.
           wrapperDir=$(mktemp --directory --tmpdir="${parentWrapperDir}" wrappers.XXXXXXXXXX)
-          chmod a+rx $wrapperDir
+          chmod a+rx "$wrapperDir"
 
           ${lib.concatStringsSep "\n" mkWrappedPrograms}
 
@@ -199,16 +265,44 @@ in
             # Atomically replace the symlink
             # See https://axialcorps.com/2013/07/03/atomically-replacing-files-and-directories/
             old=$(readlink -f ${wrapperDir})
-            if [ -e ${wrapperDir}-tmp ]; then
-              rm --force --recursive ${wrapperDir}-tmp
+            if [ -e "${wrapperDir}-tmp" ]; then
+              rm --force --recursive "${wrapperDir}-tmp"
             fi
-            ln --symbolic --force --no-dereference $wrapperDir ${wrapperDir}-tmp
-            mv --no-target-directory ${wrapperDir}-tmp ${wrapperDir}
-            rm --force --recursive $old
+            ln --symbolic --force --no-dereference "$wrapperDir" "${wrapperDir}-tmp"
+            mv --no-target-directory "${wrapperDir}-tmp" "${wrapperDir}"
+            rm --force --recursive "$old"
           else
             # For initial setup
-            ln --symbolic $wrapperDir ${wrapperDir}
+            ln --symbolic "$wrapperDir" "${wrapperDir}"
           fi
         '';
+
+    ###### wrappers consistency checks
+    system.extraDependencies = lib.singleton (pkgs.runCommandLocal
+      "ensure-all-wrappers-paths-exist" { }
+      ''
+        # make sure we produce output
+        mkdir -p $out
+
+        echo -n "Checking that Nix store paths of all wrapped programs exist... "
+
+        declare -A wrappers
+        ${lib.concatStringsSep "\n" (lib.mapAttrsToList (n: v:
+          "wrappers['${n}']='${v.source}'") wrappers)}
+
+        for name in "''${!wrappers[@]}"; do
+          path="''${wrappers[$name]}"
+          if [[ "$path" =~ /nix/store ]] && [ ! -e "$path" ]; then
+            test -t 1 && echo -ne '\033[1;31m'
+            echo "FAIL"
+            echo "The path $path does not exist!"
+            echo 'Please, check the value of `security.wrappers."'$name'".source`.'
+            test -t 1 && echo -ne '\033[0m'
+            exit 1
+          fi
+        done
+
+        echo "OK"
+      '');
   };
 }
diff --git a/nixos/modules/services/desktops/gnome/gnome-keyring.nix b/nixos/modules/services/desktops/gnome/gnome-keyring.nix
index cda44bab8bf..d821da164be 100644
--- a/nixos/modules/services/desktops/gnome/gnome-keyring.nix
+++ b/nixos/modules/services/desktops/gnome/gnome-keyring.nix
@@ -52,8 +52,10 @@ with lib;
     security.pam.services.login.enableGnomeKeyring = true;
 
     security.wrappers.gnome-keyring-daemon = {
-      source = "${pkgs.gnome.gnome-keyring}/bin/gnome-keyring-daemon";
+      owner = "root";
+      group = "root";
       capabilities = "cap_ipc_lock=ep";
+      source = "${pkgs.gnome.gnome-keyring}/bin/gnome-keyring-daemon";
     };
 
   };
diff --git a/nixos/modules/services/mail/exim.nix b/nixos/modules/services/mail/exim.nix
index 8927d84b478..25b533578c9 100644
--- a/nixos/modules/services/mail/exim.nix
+++ b/nixos/modules/services/mail/exim.nix
@@ -104,7 +104,12 @@ in
       gid = config.ids.gids.exim;
     };
 
-    security.wrappers.exim.source = "${cfg.package}/bin/exim";
+    security.wrappers.exim =
+      { setuid = true;
+        owner = "root";
+        group = "root";
+        source = "${cfg.package}/bin/exim";
+      };
 
     systemd.services.exim = {
       description = "Exim Mail Daemon";
diff --git a/nixos/modules/services/mail/mail.nix b/nixos/modules/services/mail/mail.nix
index fed313e4738..fcc7ff6db91 100644
--- a/nixos/modules/services/mail/mail.nix
+++ b/nixos/modules/services/mail/mail.nix
@@ -1,4 +1,4 @@
-{ config, lib, ... }:
+{ config, options, lib, ... }:
 
 with lib;
 
@@ -11,6 +11,7 @@ with lib;
     services.mail = {
 
       sendmailSetuidWrapper = mkOption {
+        type = types.nullOr options.security.wrappers.type.nestedTypes.elemType;
         default = null;
         internal = true;
         description = ''
diff --git a/nixos/modules/services/mail/opensmtpd.nix b/nixos/modules/services/mail/opensmtpd.nix
index c838d3b949d..dc209e8add4 100644
--- a/nixos/modules/services/mail/opensmtpd.nix
+++ b/nixos/modules/services/mail/opensmtpd.nix
@@ -103,12 +103,15 @@ in {
     };
 
     security.wrappers.smtpctl = {
+      owner = "nobody";
       group = "smtpq";
+      setuid = false;
       setgid = true;
       source = "${cfg.package}/bin/smtpctl";
     };
 
-    services.mail.sendmailSetuidWrapper = mkIf cfg.setSendmail security.wrappers.smtpctl;
+    services.mail.sendmailSetuidWrapper = mkIf cfg.setSendmail
+      security.wrappers.smtpctl // { program = "sendmail"; };
 
     systemd.tmpfiles.rules = [
       "d /var/spool/smtpd 711 root - - -"
diff --git a/nixos/modules/services/mail/postfix.nix b/nixos/modules/services/mail/postfix.nix
index 9b0a5bba2fe..2b8edb9c51f 100644
--- a/nixos/modules/services/mail/postfix.nix
+++ b/nixos/modules/services/mail/postfix.nix
@@ -673,6 +673,7 @@ in
       services.mail.sendmailSetuidWrapper = mkIf config.services.postfix.setSendmail {
         program = "sendmail";
         source = "${pkgs.postfix}/bin/sendmail";
+        owner = "nobody";
         group = setgidGroup;
         setuid = false;
         setgid = true;
@@ -681,6 +682,7 @@ in
       security.wrappers.mailq = {
         program = "mailq";
         source = "${pkgs.postfix}/bin/mailq";
+        owner = "nobody";
         group = setgidGroup;
         setuid = false;
         setgid = true;
@@ -689,6 +691,7 @@ in
       security.wrappers.postqueue = {
         program = "postqueue";
         source = "${pkgs.postfix}/bin/postqueue";
+        owner = "nobody";
         group = setgidGroup;
         setuid = false;
         setgid = true;
@@ -697,6 +700,7 @@ in
       security.wrappers.postdrop = {
         program = "postdrop";
         source = "${pkgs.postfix}/bin/postdrop";
+        owner = "nobody";
         group = setgidGroup;
         setuid = false;
         setgid = true;
diff --git a/nixos/modules/services/misc/mame.nix b/nixos/modules/services/misc/mame.nix
index 4b9a04be7c2..dd6c5ef9aa0 100644
--- a/nixos/modules/services/misc/mame.nix
+++ b/nixos/modules/services/misc/mame.nix
@@ -45,8 +45,10 @@ in
     environment.systemPackages = [ pkgs.mame ];
 
     security.wrappers."${mame}" = {
-      source = "${pkgs.mame}/bin/${mame}";
+      owner = "root";
+      group = "root";
       capabilities = "cap_net_admin,cap_net_raw+eip";
+      source = "${pkgs.mame}/bin/${mame}";
     };
 
     systemd.services.mame = {
diff --git a/nixos/modules/services/misc/weechat.nix b/nixos/modules/services/misc/weechat.nix
index b71250f62e0..9ac2b0ea490 100644
--- a/nixos/modules/services/misc/weechat.nix
+++ b/nixos/modules/services/misc/weechat.nix
@@ -52,7 +52,12 @@ in
       wants = [ "network.target" ];
     };
 
-    security.wrappers.screen.source = "${pkgs.screen}/bin/screen";
+    security.wrappers.screen =
+      { setuid = true;
+        owner = "root";
+        group = "root";
+        source = "${pkgs.screen}/bin/screen";
+      };
   };
 
   meta.doc = ./weechat.xml;
diff --git a/nixos/modules/services/monitoring/incron.nix b/nixos/modules/services/monitoring/incron.nix
index dc97af58562..255e1d9e30b 100644
--- a/nixos/modules/services/monitoring/incron.nix
+++ b/nixos/modules/services/monitoring/incron.nix
@@ -71,7 +71,12 @@ in
 
     environment.systemPackages = [ pkgs.incron ];
 
-    security.wrappers.incrontab.source = "${pkgs.incron}/bin/incrontab";
+    security.wrappers.incrontab =
+    { setuid = true;
+      owner = "root";
+      group = "root";
+      source = "${pkgs.incron}/bin/incrontab";
+    };
 
     # incron won't read symlinks
     environment.etc."incron.d/system" = {
diff --git a/nixos/modules/services/monitoring/zabbix-proxy.nix b/nixos/modules/services/monitoring/zabbix-proxy.nix
index 2c8b8b92cb3..8c7a2970e9b 100644
--- a/nixos/modules/services/monitoring/zabbix-proxy.nix
+++ b/nixos/modules/services/monitoring/zabbix-proxy.nix
@@ -262,7 +262,12 @@ in
     };
 
     security.wrappers = {
-      fping.source = "${pkgs.fping}/bin/fping";
+      fping =
+        { setuid = true;
+          owner = "root";
+          group = "root";
+          source = "${pkgs.fping}/bin/fping";
+        };
     };
 
     systemd.services.zabbix-proxy = {
diff --git a/nixos/modules/services/networking/smokeping.nix b/nixos/modules/services/networking/smokeping.nix
index ef411767a94..12d7ffe8675 100644
--- a/nixos/modules/services/networking/smokeping.nix
+++ b/nixos/modules/services/networking/smokeping.nix
@@ -278,8 +278,18 @@ in
       }
     ];
     security.wrappers = {
-      fping.source = "${pkgs.fping}/bin/fping";
-      fping6.source = "${pkgs.fping}/bin/fping6";
+      fping =
+        { setuid = true;
+          owner = "root";
+          group = "root";
+          source = "${pkgs.fping}/bin/fping";
+        };
+      fping6 =
+        { setuid = true;
+          owner = "root";
+          group = "root";
+          source = "${pkgs.fping}/bin/fping6";
+        };
     };
     environment.systemPackages = [ pkgs.fping ];
     users.users.${cfg.user} = {
diff --git a/nixos/modules/services/networking/x2goserver.nix b/nixos/modules/services/networking/x2goserver.nix
index 48020fc1cec..554e51f9d4f 100644
--- a/nixos/modules/services/networking/x2goserver.nix
+++ b/nixos/modules/services/networking/x2goserver.nix
@@ -88,12 +88,14 @@ in {
       source = "${pkgs.x2goserver}/lib/x2go/libx2go-server-db-sqlite3-wrapper.pl";
       owner = "x2go";
       group = "x2go";
+      setuid = false;
       setgid = true;
     };
     security.wrappers.x2goprintWrapper = {
       source = "${pkgs.x2goserver}/bin/x2goprint";
       owner = "x2go";
       group = "x2go";
+      setuid = false;
       setgid = true;
     };
 
diff --git a/nixos/modules/services/scheduling/cron.nix b/nixos/modules/services/scheduling/cron.nix
index 3bc31832946..c28956b3bfe 100644
--- a/nixos/modules/services/scheduling/cron.nix
+++ b/nixos/modules/services/scheduling/cron.nix
@@ -93,7 +93,12 @@ in
 
     { services.cron.enable = mkDefault (allFiles != []); }
     (mkIf (config.services.cron.enable) {
-      security.wrappers.crontab.source = "${cronNixosPkg}/bin/crontab";
+      security.wrappers.crontab =
+        { setuid = true;
+          owner = "root";
+          group = "root";
+          source = "${cronNixosPkg}/bin/crontab";
+        };
       environment.systemPackages = [ cronNixosPkg ];
       environment.etc.crontab =
         { source = pkgs.runCommand "crontabs" { inherit allFiles; preferLocalBuild = true; }
diff --git a/nixos/modules/services/scheduling/fcron.nix b/nixos/modules/services/scheduling/fcron.nix
index 42bed21bf25..acaa995f739 100644
--- a/nixos/modules/services/scheduling/fcron.nix
+++ b/nixos/modules/services/scheduling/fcron.nix
@@ -136,10 +136,13 @@ in
         owner = "fcron";
         group = "fcron";
         setgid = true;
+        setuid = false;
       };
       fcronsighup = {
         source = "${pkgs.fcron}/bin/fcronsighup";
+        owner = "root";
         group = "fcron";
+        setuid = true;
       };
     };
     systemd.services.fcron = {
diff --git a/nixos/modules/services/video/replay-sorcery.nix b/nixos/modules/services/video/replay-sorcery.nix
index d78e782c796..7ce5be8a5a1 100644
--- a/nixos/modules/services/video/replay-sorcery.nix
+++ b/nixos/modules/services/video/replay-sorcery.nix
@@ -44,8 +44,10 @@ in
 
     security.wrappers = mkIf cfg.enableSysAdminCapability {
       replay-sorcery = {
-        source = "${pkgs.replay-sorcery}/bin/replay-sorcery";
+        owner = "root";
+        group = "root";
         capabilities = "cap_sys_admin+ep";
+        source = "${pkgs.replay-sorcery}/bin/replay-sorcery";
       };
     };
 
diff --git a/nixos/modules/services/x11/desktop-managers/cde.nix b/nixos/modules/services/x11/desktop-managers/cde.nix
index 3f1575a0ca6..24ca82fca79 100644
--- a/nixos/modules/services/x11/desktop-managers/cde.nix
+++ b/nixos/modules/services/x11/desktop-managers/cde.nix
@@ -49,9 +49,10 @@ in {
     users.groups.mail = {};
     security.wrappers = {
       dtmail = {
-        source = "${pkgs.cdesktopenv}/bin/dtmail";
-        group = "mail";
         setgid = true;
+        owner = "nobody";
+        group = "mail";
+        source = "${pkgs.cdesktopenv}/bin/dtmail";
       };
     };
 
diff --git a/nixos/modules/services/x11/desktop-managers/enlightenment.nix b/nixos/modules/services/x11/desktop-managers/enlightenment.nix
index 3a7ab64510b..e3d876e82fd 100644
--- a/nixos/modules/services/x11/desktop-managers/enlightenment.nix
+++ b/nixos/modules/services/x11/desktop-managers/enlightenment.nix
@@ -65,9 +65,24 @@ in
 
     # Wrappers for programs installed by enlightenment that should be setuid
     security.wrappers = {
-      enlightenment_ckpasswd.source = "${pkgs.enlightenment.enlightenment}/lib/enlightenment/utils/enlightenment_ckpasswd";
-      enlightenment_sys.source = "${pkgs.enlightenment.enlightenment}/lib/enlightenment/utils/enlightenment_sys";
-      enlightenment_system.source = "${pkgs.enlightenment.enlightenment}/lib/enlightenment/utils/enlightenment_system";
+      enlightenment_ckpasswd =
+        { setuid = true;
+          owner = "root";
+          group = "root";
+          source = "${pkgs.enlightenment.enlightenment}/lib/enlightenment/utils/enlightenment_ckpasswd";
+        };
+      enlightenment_sys =
+        { setuid = true;
+          owner = "root";
+          group = "root";
+          source = "${pkgs.enlightenment.enlightenment}/lib/enlightenment/utils/enlightenment_sys";
+        };
+      enlightenment_system =
+        { setuid = true;
+          owner = "root";
+          group = "root";
+          source = "${pkgs.enlightenment.enlightenment}/lib/enlightenment/utils/enlightenment_system";
+        };
     };
 
     environment.etc."X11/xkb".source = xcfg.xkbDir;
diff --git a/nixos/modules/services/x11/desktop-managers/plasma5.nix b/nixos/modules/services/x11/desktop-managers/plasma5.nix
index aac905fea43..d8dc2675f06 100644
--- a/nixos/modules/services/x11/desktop-managers/plasma5.nix
+++ b/nixos/modules/services/x11/desktop-managers/plasma5.nix
@@ -197,12 +197,24 @@ in
       };
 
       security.wrappers = {
-        kcheckpass.source = "${lib.getBin libsForQt5.kscreenlocker}/libexec/kcheckpass";
-        start_kdeinit.source = "${lib.getBin libsForQt5.kinit}/libexec/kf5/start_kdeinit";
-        kwin_wayland = {
-          source = "${lib.getBin plasma5.kwin}/bin/kwin_wayland";
-          capabilities = "cap_sys_nice+ep";
-        };
+        kcheckpass =
+          { setuid = true;
+            owner = "root";
+            group = "root";
+            source = "${lib.getBin libsForQt5.kscreenlocker}/libexec/kcheckpass";
+          };
+        start_kdeinit =
+          { setuid = true;
+            owner = "root";
+            group = "root";
+            source = "${lib.getBin libsForQt5.kinit}/libexec/kf5/start_kdeinit";
+          };
+        kwin_wayland =
+          { owner = "root";
+            group = "root";
+            capabilities = "cap_sys_nice+ep";
+            source = "${lib.getBin plasma5.kwin}/bin/kwin_wayland";
+          };
       };
 
       # DDC support
diff --git a/nixos/modules/tasks/filesystems/ecryptfs.nix b/nixos/modules/tasks/filesystems/ecryptfs.nix
index 12a407cabbf..8138e659161 100644
--- a/nixos/modules/tasks/filesystems/ecryptfs.nix
+++ b/nixos/modules/tasks/filesystems/ecryptfs.nix
@@ -7,8 +7,18 @@ with lib;
   config = mkIf (any (fs: fs == "ecryptfs") config.boot.supportedFilesystems) {
     system.fsPackages = [ pkgs.ecryptfs ];
     security.wrappers = {
-      "mount.ecryptfs_private".source = "${pkgs.ecryptfs.out}/bin/mount.ecryptfs_private";
-      "umount.ecryptfs_private".source = "${pkgs.ecryptfs.out}/bin/umount.ecryptfs_private";
+      "mount.ecryptfs_private" =
+        { setuid = true;
+          owner = "root";
+          group = "root";
+          source = "${pkgs.ecryptfs.out}/bin/mount.ecryptfs_private";
+        };
+      "umount.ecryptfs_private" =
+        { setuid = true;
+          owner = "root";
+          group = "root";
+          source = "${pkgs.ecryptfs.out}/bin/umount.ecryptfs_private";
+        };
     };
   };
 }
diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix
index 8f9c66b0157..d934e3cf022 100644
--- a/nixos/modules/tasks/network-interfaces.nix
+++ b/nixos/modules/tasks/network-interfaces.nix
@@ -1133,11 +1133,16 @@ in
     # kernel because we need the ambient capability
     security.wrappers = if (versionAtLeast (getVersion config.boot.kernelPackages.kernel) "4.3") then {
       ping = {
-        source  = "${pkgs.iputils.out}/bin/ping";
+        owner = "root";
+        group = "root";
         capabilities = "cap_net_raw+p";
+        source = "${pkgs.iputils.out}/bin/ping";
       };
     } else {
-      ping.source = "${pkgs.iputils.out}/bin/ping";
+      setuid = true;
+      owner = "root";
+      group = "root";
+      source = "${pkgs.iputils.out}/bin/ping";
     };
     security.apparmor.policies."bin.ping".profile = lib.mkIf config.security.apparmor.policies."bin.ping".enable (lib.mkAfter ''
       /run/wrappers/bin/ping {
diff --git a/nixos/modules/virtualisation/libvirtd.nix b/nixos/modules/virtualisation/libvirtd.nix
index f45f1802d91..3c291397a99 100644
--- a/nixos/modules/virtualisation/libvirtd.nix
+++ b/nixos/modules/virtualisation/libvirtd.nix
@@ -183,6 +183,9 @@ in {
     };
 
     security.wrappers.qemu-bridge-helper = {
+      setuid = true;
+      owner = "root";
+      group = "root";
       source = "/run/${dirName}/nix-helpers/qemu-bridge-helper";
     };
 
diff --git a/nixos/modules/virtualisation/spice-usb-redirection.nix b/nixos/modules/virtualisation/spice-usb-redirection.nix
index 4168cebe79b..255327f2622 100644
--- a/nixos/modules/virtualisation/spice-usb-redirection.nix
+++ b/nixos/modules/virtualisation/spice-usb-redirection.nix
@@ -14,9 +14,11 @@
 
   config = lib.mkIf config.virtualisation.spiceUSBRedirection.enable {
     environment.systemPackages = [ pkgs.spice-gtk ]; # For polkit actions
-    security.wrappers.spice-client-glib-usb-acl-helper ={
-      source = "${pkgs.spice-gtk}/bin/spice-client-glib-usb-acl-helper";
+    security.wrappers.spice-client-glib-usb-acl-helper = {
+      owner = "root";
+      group = "root";
       capabilities = "cap_fowner+ep";
+      source = "${pkgs.spice-gtk}/bin/spice-client-glib-usb-acl-helper";
     };
   };