Recognize legacy sudo grants for any account name

The legacy command wrote the caller's unvalidated name into both the
sudoers filename and the rule. Cleanup applied the current lower-case
account pattern to that suffix, so an exact legacy grant for an account
such as Alice was classified as administrator policy, left active, and
the machine-wide migration marker was written anyway.

Match a legacy grant by its exact filename and rule relationship instead
of the account policy, and cover it in the lifecycle suite through both
the unit cleanup and the real migration runner.

The account pattern itself stays lower-case: sudoers reads an upper-case
word such as ALICE as a User_Alias reference, and ALL as every user, so
such names must never reach the generated rule. Pin that with a test.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Afonso OliveiraandClaude Fable 5.1 committed 2026-09-16 23:01:13 +01:00
1 parent c46f321680
commit 3eb3142313
4 files changed
+34 -18

No files matched your search

+5 -2
View File
@@ -9,7 +9,8 @@ source "$SHELL_TEST_DIR/fixtures/passwordless-sudo-test.sh"
for minutes in 1 15 1440 00015; do valid_minutes "$minutes" || exit 1; done
for minutes in 0 1441 -1 1m '' 18446744073709551617; do ! valid_minutes "$minutes" || exit 1; done
for name in audituser 'buildbot$'; do valid_account_name "$name" || exit 1; done
for name in 'a$b' '$' aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; do ! valid_account_name "$name" || exit 1; done
# Upper-case words are sudoers alias references, so ALICE must never publish.
for name in 'a$b' '$' 'a b' 'a#b' Alice ALICE ALL aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; do ! valid_account_name "$name" || exit 1; done
! valid_uid 18446744073709551617
)
pass "duration and account validation retains bounded inputs and trailing-dollar usernames"
@@ -159,5 +160,7 @@ cp "$ROOT/default/libalpm/hooks/05-omarchy-passwordless-revoke.hook" "$test_tmp/
/usr/sbin/visudo -cf "$(rule_file 1000)" >/dev/null
cleanup_uid_locked 1000
[[ ! -e $(rule_file 1000) ]]
TEST_ACCOUNT=ALICE assert_status 1 enable_locked 1000 15
[[ ! -e $(rule_file 1000) ]]
)
pass "trailing-dollar accounts publish and revoke valid native policy"
pass "trailing-dollar accounts publish valid native policy and alias-shaped names never publish"
@@ -8,14 +8,20 @@ source "$SHELL_TEST_DIR/fixtures/passwordless-sudo-test.sh"
source "$library"
printf 'deleteduser ALL=(ALL) NOPASSWD: ALL\n' >"$(rule_file 1000)"
printf 'buildbot$ ALL=(ALL) NOPASSWD: ALL\n' >"$test_tmp/etc/sudoers.d/99-omarchy-nopasswd-buildbot$"
# The legacy command never validated the account name, so a manual or NSS
# account outside the current policy still has its exact old grant removed.
printf 'Alice ALL=(ALL) NOPASSWD: ALL\n' >"$test_tmp/etc/sudoers.d/99-omarchy-nopasswd-Alice"
printf 'admin ALL=(ALL) NOPASSWD: /usr/bin/true\n' >"$test_tmp/etc/sudoers.d/99-omarchy-nopasswd-custom"
printf 'Alice ALL=(ALL) NOPASSWD: ALL\n' >"$test_tmp/etc/sudoers.d/99-omarchy-nopasswd-handwritten"
TEST_DELETE_FAIL=1 assert_status 1 cleanup_all_locked
[[ -e $(rule_file 1000) ]]
cleanup_all_locked
[[ ! -e $(rule_file 1000) && -e $test_tmp/etc/sudoers.d/99-omarchy-nopasswd-custom ]]
[[ ! -e $(rule_file 1000) && ! -e $test_tmp/etc/sudoers.d/99-omarchy-nopasswd-Alice ]]
[[ -e $test_tmp/etc/sudoers.d/99-omarchy-nopasswd-custom && -e $test_tmp/etc/sudoers.d/99-omarchy-nopasswd-handwritten ]]
! compgen -G "$test_tmp/etc/sudoers.d/99-omarchy-nopasswd-buildbot*"
rm "$test_tmp/etc/sudoers.d/99-omarchy-nopasswd-custom" "$test_tmp/etc/sudoers.d/99-omarchy-nopasswd-handwritten"
)
pass "legacy cleanup removes generated orphan rules and preserves custom policy"
pass "legacy cleanup removes generated orphan rules for any account and preserves custom policy"
# Run the actual migration queue for separate temporary homes. Sudo only calls
# the mapped helper and can be refused without requesting host authorization.
@@ -31,10 +37,12 @@ marker="$test_tmp/var/lib/omarchy/migrations/1788163635"
(
source "$library"
printf 'audituser ALL=(ALL) NOPASSWD: ALL\n' >"$(rule_file 1000)"
printf 'Alice ALL=(ALL) NOPASSWD: ALL\n' >"$test_tmp/etc/sudoers.d/99-omarchy-nopasswd-Alice"
TEST_DELETE_FAIL=1 assert_status 1 run_migrations first
[[ ! -e $marker && ! -e $test_tmp/first/1788163636.sh ]]
run_migrations first
[[ -f $marker && -f $test_tmp/first/1788163636.sh ]]
[[ ! -e $test_tmp/etc/sudoers.d/99-omarchy-nopasswd-Alice ]]
enable_locked 1000 15
cp "$(rule_file 1000)" "$test_tmp/renewed"
: >"$test_tmp/commands"