mirror of
https://github.com/tailscale/tailscale.git
synced 2026-09-16 07:52:22 -04:00
On Windows, I could run tailscaled in the terminal over SSH only when
built with ts_omit_syspolicy, but that's kinda a sad workaround. This
is the alternative.
syspolicy registers a Registry policy store for the current user
whenever tailscaled isn't running as LocalSystem, and the first read
of that store takes the Group Policy read lock via
EnterCriticalPolicySection(FALSE). That call fails with
ERROR_ACCESS_DENIED when the user has no interactive logon session,
which is the case for a tailscaled.exe started over SSH (or WinRM,
psexec, a non-interactive scheduled task). The store's Lock method
returned the error, the reader failed to load, and LocalBackend
treated that as fatal:
ipnlocal.NewLocalBackend: syspolicy: LocalBackend failed to register
policy change callback: failed to get a store reader: Access is denied.
The GP lock is only there to keep reads of several settings consistent
while Group Policy is being applied; the store already documents that
reading the Registry without it is safe, and already skips it when
gp.ErrLockRestricted is returned during service start. Treat
ERROR_ACCESS_DENIED the same way: log it and read unlocked. Other errors
from the lock still propagate.
The optionalPolicyLock wrapper now holds the lockableCloser interface
instead of *gp.PolicyLock so the test can inject a failing lock.
Tested on a Windows Server 2022 VM: the test passes from an SSH session,
and a foreground tailscaled started from that session now runs and logs in
instead of exiting at startup.
Updates #21290
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Change-Id: I395f356730092299cf020a6787c56ab3b9ed6fe5