From 68fc0cf6e6a12c7774b35b1874d0344a61ddabd9 Mon Sep 17 00:00:00 2001 From: omabot Date: Thu, 27 Aug 2026 19:55:36 +0200 Subject: [PATCH] Match the CUPS directives being rewritten the way cupsd reads them cupsd compares directive names with _cups_strcasecmp, so a hand-edited "systemgroup sys root wheel" is live configuration, but matching $1 against the canonical spelling skipped it and appended a second directive at the end of the file. parse_groups accumulates the groups of every SystemGroup directive it reads rather than replacing them, so both lines took effect and wheel kept the passwordless administration this is meant to remove, with the migration reporting success. Co-Authored-By: Claude Opus 5 (1M context) Co-Authored-By: Codex XHigh --- install/config/printing.sh | 6 +++--- test/shell.d/cups-hardening-test.sh | 28 ++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/install/config/printing.sh b/install/config/printing.sh index b99e03c3..31c969ea 100644 --- a/install/config/printing.sh +++ b/install/config/printing.sh @@ -16,7 +16,7 @@ elif [[ -f $cups_files_conf ]]; then if ! awk ' NR == FNR { - if ($1 == "SystemGroup") { + if (tolower($1) == "systemgroup") { for (i = 2; i <= NF; i++) { if (substr($i, 1, 1) == "#") break @@ -29,7 +29,7 @@ elif [[ -f $cups_files_conf ]]; then next } - $1 == "SystemGroup" { + tolower($1) == "systemgroup" { comment_start = index($0, "#") if (!wrote_system_group) { printf "SystemGroup" @@ -47,7 +47,7 @@ elif [[ -f $cups_files_conf ]]; then next } - $1 == "PeerCred" { + tolower($1) == "peercred" { comment_start = index($0, "#") if (!saw_peer_cred) { printf "PeerCred on" diff --git a/test/shell.d/cups-hardening-test.sh b/test/shell.d/cups-hardening-test.sh index f5c92e44..2f0bc96a 100644 --- a/test/shell.d/cups-hardening-test.sh +++ b/test/shell.d/cups-hardening-test.sh @@ -222,3 +222,31 @@ OMARCHY_CUPS_TEST_LOG="$masked_log" \ [[ -f $masked_marker ]] || fail "the migration completes with cups-browsed masked" pass "a masked or disabled cups-browsed is left alone and does not fail the migration" + +# cupsd compares directive names case-insensitively, so a hand-edited lowercase +# directive is live configuration. Matching it exactly would skip the line and +# append a second one, and cupsd accumulates the groups of every SystemGroup +# directive it reads -- leaving wheel with passwordless administration. +lowercase_conf="$test_tmp/etc/cups/lowercase.conf" +cat >"$lowercase_conf" <<'CONF' +systemgroup sys root wheel +peercred off +CONF + +PATH="$mock_bin:$PATH" \ + OMARCHY_CUPS_FILES_CONF="$lowercase_conf" \ + OMARCHY_CUPS_BROWSED_SYSUSERS_CONF="$sysusers_conf" \ + bash -euo pipefail "$ROOT/install/config/printing.sh" + +! grep -qiE '^[[:space:]]*systemgroup\b.*\bwheel\b' "$lowercase_conf" || + fail "printing setup removes wheel from a lowercase SystemGroup directive" "$(cat "$lowercase_conf")" +[[ $(grep -ciE '^[[:space:]]*systemgroup\b' "$lowercase_conf") == 1 ]] || + fail "printing setup leaves one SystemGroup directive whatever case it was written in" "$(cat "$lowercase_conf")" +grep -qxF 'SystemGroup sys root cups-browsed' "$lowercase_conf" || + fail "printing setup reserves administration for the service account" "$(cat "$lowercase_conf")" +[[ $(grep -ciE '^[[:space:]]*peercred\b' "$lowercase_conf") == 1 ]] || + fail "printing setup leaves one PeerCred directive" "$(cat "$lowercase_conf")" +grep -qxF 'PeerCred on' "$lowercase_conf" || + fail "printing setup enables peer credentials whatever case they were written in" "$(cat "$lowercase_conf")" + +pass "printing setup rewrites directives cupsd reads case-insensitively"