Merge pull request #8951 from omacom/cups-browsed-temporarily-removed

Temporarily remove automatic printer discovery
This commit is contained in:
Ryan Hughes
2026-08-29 15:38:23 -04:00
committed by GitHub
9 changed files with 166 additions and 84 deletions
+51
View File
@@ -0,0 +1,51 @@
#!/bin/bash
set -euo pipefail
source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh"
for package in cups cups-filters system-config-printer cups-pk-helper; do
pacman -Q "$package" >/dev/null 2>&1 || fail "printing packages are installed" "$package is missing"
done
pass "printing packages are installed"
! pacman -Q cups-pdf >/dev/null 2>&1 || fail "the root CUPS-PDF backend is absent"
pass "the root CUPS-PDF backend is absent"
! pacman -Q cups-browsed >/dev/null 2>&1 || fail "automatic printer discovery is absent"
! systemctl is-enabled --quiet cups-browsed.service 2>/dev/null ||
fail "automatic printer discovery is not enabled"
! systemctl is-active --quiet cups-browsed.service 2>/dev/null ||
fail "automatic printer discovery is not running"
! pgrep -x cups-browsed >/dev/null 2>&1 || fail "no cups-browsed process exists"
pass "automatic printer discovery is not installed or running"
for path in \
/etc/cups/cups-browsed.conf \
/etc/cups/cups-browsed.conf.pacsave \
/etc/cups/cups-browsed.conf.pacnew \
/usr/bin/cups-browsed \
/usr/lib/cups/backend/implicitclass \
/usr/lib/systemd/system/cups-browsed.service \
/etc/systemd/system/multi-user.target.wants/cups-browsed.service; do
[[ ! -e $path && ! -L $path ]] ||
fail "automatic printer discovery leaves no package files" "$path still exists"
done
pass "automatic printer discovery leaves no package files"
systemctl is-enabled --quiet cups.service || fail "CUPS is enabled"
systemctl is-active --quiet cups.service || fail "CUPS is running"
timeout 10 lpstat -r >/dev/null 2>&1 || fail "the CUPS scheduler answers"
pass "CUPS is enabled, running, and answering"
policy_metadata=$(stat -c '%U:%G %a' /etc/cups/cups-files.conf)
[[ $policy_metadata == "root:cups 640" ]] ||
fail "the CUPS authorization policy is protected" "$policy_metadata"
pass "the CUPS authorization policy is protected"
if lpinfo_output=$(LC_ALL=C timeout 10 lpinfo -v </dev/null 2>&1); then
fail "the desktop user cannot administer CUPS without authentication"
elif [[ $lpinfo_output != *"Forbidden"* ]]; then
fail "CUPS explicitly denies unauthenticated desktop administration" "$lpinfo_output"
fi
pass "CUPS denies unauthenticated desktop administration"
+2 -68
View File
@@ -47,7 +47,7 @@ verify_services() {
local unit
for unit in \
avahi-daemon.service cups.service cups-browsed.service docker.socket \
avahi-daemon.service docker.socket \
NetworkManager.service power-profiles-daemon.service sddm.service \
systemd-resolved.service ufw.service; do
systemctl is-enabled --quiet "$unit" || fail "core system services are enabled" "$unit is not enabled"
@@ -64,72 +64,6 @@ verify_services() {
pass "user audio services are running"
}
verify_printing_security() {
local cups_browsed_pid lpinfo_output printer_name printer_process printer_tmp
! pacman -Q cups-pdf >/dev/null 2>&1 || fail "CUPS-PDF is absent"
pass "the root CUPS-PDF backend is not installed"
getent passwd cups-browsed >/dev/null || fail "the cups-browsed service account exists"
[[ $(systemctl show -P User cups-browsed.service) == "cups-browsed" ]] ||
fail "cups-browsed runs as its service account"
[[ $(systemctl show -P Group cups-browsed.service) == "cups-browsed" ]] ||
fail "cups-browsed runs as its service group"
systemctl is-active --quiet cups-browsed.service || fail "cups-browsed is running"
cups_browsed_pid=$(systemctl show -P MainPID cups-browsed.service)
[[ -r /proc/$cups_browsed_pid/status ]] || fail "cups-browsed has a readable process status"
[[ $(awk '/^Uid:/{print $2}' "/proc/$cups_browsed_pid/status") != 0 ]] ||
fail "cups-browsed does not run with root UID"
[[ $(awk '/^CapEff:/{print $2}' "/proc/$cups_browsed_pid/status") == "0000000000000000" ]] ||
fail "cups-browsed has no effective Linux capabilities"
[[ $(stat -c '%a %U:%G' /var/cache/cups-browsed) == "750 cups-browsed:cups-browsed" ]] ||
fail "cups-browsed has an isolated cache" "$(stat -c '%a %U:%G' /var/cache/cups-browsed)"
[[ " $(id -nG cups-browsed) " != *" cups "* ]] ||
fail "cups-browsed is separate from the print-filter group"
if lpinfo_output=$(LC_ALL=C timeout 10 lpinfo -v </dev/null 2>&1); then
fail "the desktop user cannot administer CUPS without authentication"
elif [[ $lpinfo_output != *"Forbidden"* ]]; then
fail "CUPS explicitly denies unauthenticated desktop administration" "$lpinfo_output"
fi
pass "CUPS discovery is isolated from root, filters, and passwordless desktop administration"
# A live driverless printer proves the non-root daemon can still discover and
# create queues without the CAP_NET_BIND_SERVICE Ubuntu carries downstream.
printer_name="OmarchyAcceptancePrinter"
printer_tmp=$(mktemp -d)
printf '#!/bin/bash\nexit 0\n' >"$printer_tmp/command"
chmod 0700 "$printer_tmp/command"
mkdir -m 0700 "$printer_tmp/spool"
ippeveprinter -p 18631 -d "$printer_tmp/spool" -c "$printer_tmp/command" "$printer_name" \
>"$printer_tmp/ippeveprinter.log" 2>&1 &
printer_process=$!
printing_test_cleanup() {
kill "$printer_process" >/dev/null 2>&1 || true
wait "$printer_process" >/dev/null 2>&1 || true
rm -rf "$printer_tmp"
}
trap printing_test_cleanup EXIT
for _ in {1..30}; do
lpstat -v "$printer_name" 2>/dev/null | grep -q "implicitclass://$printer_name/" && break
sleep 1
done
lpstat -v "$printer_name" 2>/dev/null | grep -q "implicitclass://$printer_name/" ||
fail "non-root cups-browsed discovers a driverless IPP printer" "$(<"$printer_tmp/ippeveprinter.log")"
printing_test_cleanup
trap - EXIT
pass "non-root cups-browsed still creates driverless IPP queues without capabilities"
}
verify_runtime_tools() {
# Docker access is intentionally NOT granted to the desktop user: the docker
# group is root-equivalent, so a rogue process running as the user could
@@ -173,7 +107,7 @@ verify_user_setup() {
pass "Omarchy user state and shell configuration exist"
}
for check in verify_core_packages verify_defaults verify_services verify_printing_security verify_runtime_tools verify_user_setup; do
for check in verify_core_packages verify_defaults verify_services verify_runtime_tools verify_user_setup; do
if ! ("$check"); then
status=1
fi
+27 -2
View File
@@ -10,11 +10,36 @@ cups_files_conf="$ROOT/etc/cups/cups-files.conf"
sysusers_conf="$ROOT/etc/sysusers.d/omarchy-cups-browsed.conf"
service_dropin="$ROOT/etc/systemd/system/cups-browsed.service.d/10-omarchy.conf"
grep -qxF cups-browsed "$packages" || fail "cups-browsed remains in the base package set"
# Only discovery goes. Everything else printing needs stays, or this stops
# being a removal of one daemon and becomes a removal of printing.
grep -qxF cups "$packages" || fail "CUPS itself remains in the base package set"
grep -qxF cups-filters "$packages" || fail "the CUPS filters remain in the base package set"
grep -qxF system-config-printer "$packages" || fail "Print Settings remains in the base package set"
grep -qxF cups-pk-helper "$packages" || fail "Polkit printer administration is installed"
! grep -qxF cups-pdf "$packages" || fail "the root CUPS-PDF backend is removed"
pass "the base install keeps discovery and replaces CUPS-PDF with Polkit administration"
# Automatic discovery is temporarily out of the default install while it is
# reworked. The hardened configuration below stays as the baseline discovery
# comes back onto.
! grep -qxF cups-browsed "$packages" || fail "automatic printer discovery is out of the base package set"
! grep -q 'cups-browsed' "$ROOT/install/config/enable-services.sh" ||
fail "a fresh install does not enable a discovery service it no longer installs"
! grep -q 'enable_system_service cups-browsed' "$ROOT/bin/omarchy-upgrade-to-quattro" ||
fail "the Quattro upgrade does not enable a discovery service it no longer installs"
pass "the base install keeps CUPS and Polkit administration, without automatic discovery"
# CUPS still ships /etc/cups/cups-files.conf, so its authorization override is
# applied after the ISO installs that package. cups-browsed is absent, so the
# installer must not write any of its package-owned configuration.
post_install_pacman="$ROOT/install/post-install/pacman.sh"
! grep -q 'cups-cups-browsed.conf' "$post_install_pacman" ||
fail "a fresh install does not write configuration for absent printer discovery"
grep -q 'cups-cups-files.conf && -f /etc/cups/cups-files.conf' "$post_install_pacman" ||
fail "the CUPS authorization override waits for the file it replaces"
pass "the fresh install applies CUPS hardening without writing discovery configuration"
grep -qxF 'CacheDir /var/cache/cups-browsed' "$cups_browsed_conf" ||
fail "cups-browsed keeps state outside the print-filter cache"