改动 / #3406

#3406 [TUI] Fix the owner-only check for the built-in Administrator (SDDL alias LA)

open · @jackbapa · 0 评论 · 去 GitHub 看

SecurityWindowsLinux

说明

## Problem and result

On Windows the built-in Administrator (RID 500) cannot start the engine or finish an engine update. `runtime_dir()` raises `ProfileError: runtime directory must be owner-only (mode 0700)` even though the directory ACL is exactly what `restrict_to_current_user()` wrote. The same check gates the activity lease and the engine test start, so the application stops there.

`restrict_to_current_user()` writes `D:PAI(A;OICI;FA;;;<current SID>)`. When Windows renders that DACL back, it replaces the SID of RID 500 with the SDDL alias `LA`, so `is_private()` compares `"LA"` with `S-1-5-21-...-500` and returns False. `is_unshared()` has the same problem.

After the change the alias is resolved to its string SID before the comparison, `runtime_dir()` returns the directory, and an ACL that names another account is still rejected.

## Related discussion

https://github.com/Niko1221/Strata/issues/3302 - reported the same failure and suggested resolving the SDDL alias (or comparing with `EqualSid`). This PR follows that approach.

## Approach

A new `_as_sid()` helper runs `ConvertStringSidToSidW` + `ConvertSidToStringSidW` and returns the string SID, or the input unchanged when it is not a resolvable alias. `is_private()` and `is_unshared()` normalise the trustee field through it.

Alternatives considered: adding `LA` to `_PRIVILEGED` would accept the built-in Administrator on every machine, including ones where the current user is someone else - that relaxes `is_unshared()` instead of fixing the comparison, so it is not done here.

No change to how the ACL is written; the same DACL is now recognised. POSIX behaviour is untouched (`_as_sid` returns its input when `WINDOWS` is false).

Two existing tests compared the raw SDDL text with `current_user_sid()`; they now compare through the same normalisation, otherwise they fail on every RID 500 host. Two Windows-only tests cover the alias and check that it does not authorise a different account.

## Validation

**Passed:**

- `python -m unittest tests.terminal.test_private_files -v` on a Windows x86_64 host signed in as the built-in Administrator (renamed locally, SID `S-1-5-21-...-500`), Python 3.13.9, revision d67b749: 16 tests, `OK (skipped=1)` (the POSIX test). Without the source change the same suite failed on that host, including five assertion failures that compared the raw SDDL text.
- Manual, with a fresh `STRATA_RUNTIME_DIR`: `runtime.runtime_dir()` returns the directory, `dacl_sddl()` is `D:PAI(A;OICI;FA;;;LA)`, `is_private()` and `is_unshared()` are True, `current_user_sid()` is the RID 500 SID.

**Failed:**

none observed.

**Not run:**

- POSIX (Linux/macOS): no machine available; `_as_sid` is a no-op there and the POSIX branches are unchanged.
- Other Windows accounts: covered by the mocked test (`LA` entry, different current SID -> False) rather than a second real account.

## Limits

Only trustee fields are normalised. An account whose SDDL alias cannot be resolved by `ConvertStringSidToSidW` keeps the previous literal comparison.

本站相关内容

相关页面的快捷入口。