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
-1
View File
@@ -1364,7 +1364,6 @@ EOF
as_root systemctl disable docker.service >/dev/null 2>&1 || true
enable_system_service cups.service
enable_system_service cups-browsed.service
enable_system_service avahi-daemon.service
enable_system_service linux-modules-cleanup.service
enable_system_service docker.socket
+3 -5
View File
@@ -1,16 +1,14 @@
# Enable services only. Installs are followed by reboot, so don't start/reload
# daemons mid-install. UFW and hardware-gated services stay in their own scripts.
systemctl enable cups.service
systemctl enable cups-browsed.service
systemctl enable avahi-daemon.service
systemctl enable linux-modules-cleanup.service
systemctl enable docker.socket
systemctl enable systemd-resolved.service
systemctl enable NetworkManager.service
# Don't let network-online.target (pulled in by cups-browsed) hold up
# graphical.target waiting for DHCP/Wi-Fi association. Nothing in the session
# needs to block on the network. Mirrors the systemd-networkd-wait-online mask
# in install/hardware/network.sh.
# Don't let network-online.target hold up graphical.target waiting for
# DHCP/Wi-Fi association. Nothing in the session needs to block on the network.
# Mirrors the systemd-networkd-wait-online mask in install/hardware/network.sh.
systemctl mask NetworkManager-wait-online.service
systemctl enable power-profiles-daemon.service
systemctl enable sddm.service
-1
View File
@@ -17,7 +17,6 @@ chromium
clang
cliamp
cups
cups-browsed
cups-filters
cups-pk-helper
ddcutil
+4 -6
View File
@@ -3,13 +3,11 @@
cp -f "$OMARCHY_PATH/default/pacman/pacman-${OMARCHY_MIRROR:-stable}.conf" /etc/pacman.conf
cp -f "$OMARCHY_PATH/default/pacman/mirrorlist-${OMARCHY_MIRROR:-stable}" /etc/pacman.d/mirrorlist
# omarchy-settings skips these overrides until CUPS is actually present to
# avoid pacman creating .pacnew files during ISO package installation.
if [[ -f $OMARCHY_PATH/etc-overrides/cups-cups-browsed.conf && -f /etc/cups/cups-files.conf ]]; then
systemd-sysusers /etc/sysusers.d/omarchy-cups-browsed.conf
cp -f "$OMARCHY_PATH/etc-overrides/cups-cups-browsed.conf" /etc/cups/cups-browsed.conf
# Wait for CUPS to own the file, the way omarchy-settings does, so pacman does
# not turn the override into a .pacnew during ISO package installation.
if [[ -f $OMARCHY_PATH/etc-overrides/cups-cups-files.conf && -f /etc/cups/cups-files.conf ]]; then
install -m 0640 -o root -g cups "$OMARCHY_PATH/etc-overrides/cups-cups-files.conf" /etc/cups/cups-files.conf
rm -f /etc/cups/cups-browsed.conf.pacnew /etc/cups/cups-files.conf.pacnew
rm -f /etc/cups/cups-files.conf.pacnew
fi
source "$OMARCHY_INSTALL/hardware/pacman.sh"
+7 -1
View File
@@ -44,7 +44,13 @@ The plain open source Chromium build doesn't ship with the OAuth credentials tha
### How do I add a printer?
Printing is set up and running out of the box, so a printer on your network is usually already discovered. Launch _Print Settings_ from the app launcher (`Super + Space`) to see what's there, add one by hand, or set the default. Printing to a PDF file works without any printer at all.
Printing is set up and running out of the box, and you add each printer yourself from _Print Settings_ in the app launcher (`Super + Space`).
Choose _Add_, and give it a moment to look: a printer plugged in over USB, and most network printers, are found for you. If yours isn't in the list, pick _Network Printer > Internet Printing Protocol (ipp)_ and enter its address — the printer's own display or its web page will tell you what that is, usually something like `192.168.1.50` with a queue of `ipp/print`. _Forward_ then offers a driver, where a modern printer works best on the driverless _IPP Everywhere_ profile and an older one wants the model's own driver.
Right-click a printer and choose _Set as Default_ to pick which one your apps reach for first, and _Properties_ to set paper size, duplex and quality.
Automatic discovery, where printers on the network appear without being added, is temporarily switched off while it's reworked, which is why the first step above is yours rather than automatic. Printing to a PDF file works without any printer at all.
### How do I change where screenshots or screenrecordings are saved?
+72
View File
@@ -0,0 +1,72 @@
echo "Temporarily remove automatic printer discovery"
machine_marker="${OMARCHY_CUPS_BROWSED_REMOVAL_MARKER:-/var/lib/omarchy/migrations/1788009111}"
[[ ! -e $machine_marker ]] || exit 0
omarchy-pkg-present cups-browsed || exit 0
# Check the full removal transaction before changing the service or queues.
pacman -Rs --print cups-browsed >/dev/null
# Disable the unit while its package still owns the unit file so systemd can
# remove the enable symlink cleanly.
if systemctl is-enabled --quiet cups-browsed.service 2>/dev/null; then
sudo systemctl disable --now cups-browsed.service >/dev/null
elif systemctl is-active --quiet cups-browsed.service 2>/dev/null; then
sudo systemctl stop cups-browsed.service >/dev/null
fi
# cups-browsed leaves its implicitclass queues behind when stopped. Remove idle
# discovery queues before removing the backend they require, but leave queues
# with jobs for the user to resolve.
#
# A healthy CUPS server with no configured printers reports this condition on
# stderr and exits 1. Treat that as an empty queue list; every other failure
# keeps the migration pending so it can be retried.
if queue_report=$(LC_ALL=C lpstat -v 2>&1); then
:
elif [[ $queue_report == "lpstat: No destinations added." ]]; then
queue_report=""
else
printf '%s\n' "$queue_report" >&2
exit 1
fi
generated_queues=$(printf '%s\n' "$queue_report" |
sed -n 's|^device for \(.*\): implicitclass://.*|\1|p')
while IFS= read -r queue; do
[[ -n $queue ]] || continue
if ! reject_error=$(sudo cupsreject -r "Printer discovery has been removed from Omarchy" "$queue" 2>&1); then
if LC_ALL=C lpstat -p "$queue" >/dev/null 2>&1; then
printf '%s\n' "$reject_error" >&2
exit 1
else
continue
fi
fi
if job_report=$(LC_ALL=C lpstat -o "$queue" 2>&1); then
[[ -z $job_report ]] || continue
elif LC_ALL=C lpstat -p "$queue" >/dev/null 2>&1; then
printf '%s\n' "$job_report" >&2
exit 1
else
# The queue disappeared after the initial snapshot, which is already the
# desired state.
continue
fi
if ! delete_error=$(sudo lpadmin -x "$queue" 2>&1); then
# Treat a concurrent disappearance as success. A queue that still exists
# means CUPS did not complete the deletion, so retry the migration later.
if LC_ALL=C lpstat -p "$queue" >/dev/null 2>&1; then
printf '%s\n' "$delete_error" >&2
exit 1
fi
fi
done <<<"$generated_queues"
omarchy-pkg-drop cups-browsed >/dev/null
sudo install -Dm644 /dev/null "$machine_marker"
+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"