Skip to content

Commit

Permalink
nixos/sane: ensure saned can access usb scanners
Browse files Browse the repository at this point in the history
For a user to be able to scan with an USB scanner, it must have write access
to the corresponding file in /dev/bus/usb. Enabling the sane module
adds SANE's upstream hwdb file and udev rules to udev search path. The
hwdb file tags the scanner as `libsane_matched` and a builtin (from
systemd upstream) udev rule marks all `libsane_matched` devices as
uaccess. When a physical user logins, logind adds an acl allowing them
to write to the device.

Unfortunately, saned is a daemon. Therefore, uaccess has no effect for
it, and if no other udev rule changes the device to belong to the
scanner group or the lp group, (there are such rules, but they are not
complete enough, in that some scanners known by SANE rules are not known
by these rules), it will not be able to write to the scanner.

This solves this by adding a udev rule so that all libsane_matched
devices have an acl rules so that users in the scanner group can write.

A similar rule is present on Arch and Debian at least.

Note that we don't chgroup the file instead, because this posed problems
in the past: scanners are often also printers, and a device's group
cannot be simultaneously lp and scanner.

Fixes: #361981
  • Loading branch information
symphorien committed Dec 21, 2024
1 parent d3c42f1 commit 7d0c25d
Showing 1 changed file with 6 additions and 0 deletions.
6 changes: 6 additions & 0 deletions nixos/modules/services/hardware/sane.nix
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,12 @@ in
environment.etc."sane-config".source = config.hardware.sane.configDir;
environment.etc."sane-libs".source = "${saneConfig}/lib/sane";
services.udev.packages = backends;
# sane sets up udev rules that tag scanners with `uaccess`. This way, physically logged in users
# can access them without belonging to the `scanner` group. However, the `scanner` user used by saned
# does not have a real logind seat, so `uaccess` is not enough.
services.udev.extraRules = ''
ENV{DEVNAME}!="", ENV{libsane_matched}=="yes", RUN+="${pkgs.acl}/bin/setfacl -m g:scanner:rw $env{DEVNAME}"
'';

users.groups.scanner.gid = config.ids.gids.scanner;
networking.firewall.allowedUDPPorts = lib.mkIf config.hardware.sane.openFirewall [ 8612 ];
Expand Down

0 comments on commit 7d0c25d

Please sign in to comment.