ipn/ipnlocal: preserve b.loginFlags in auto-login cc.Login calls

LocalBackend stores loginFlags at construction so that per-instance
properties (e.g. LoginEphemeral set by tsnet.Server.Ephemeral) persist
for the session. StartLoginInteractiveAs already merges b.loginFlags
into its cc.Login call, but the two auto-login call sites pass bare
controlclient.LoginDefault, silently dropping any stored flags.

Merge b.loginFlags at both auto-login call sites to match the existing
StartLoginInteractiveAs pattern. LoginDefault is zero so this is a
no-op when loginFlags is empty, and restores the documented behavior
when it isn't.

Fixes #15852

Signed-off-by: Scott Graham <scott.github@h4ck3r.net>
This commit is contained in:
Scott Graham
2026-04-17 23:31:18 -05:00
committed by Nick Khyl
parent 618dfd4081
commit cb5a53c424
3 changed files with 61 additions and 2 deletions
+2 -2
View File
@@ -2767,7 +2767,7 @@ func (b *LocalBackend) startLocked(opts ipn.Options) error {
// Without this, the state machine transitions to "NeedsLogin" implying
// that user interaction is required, which is not the case and can
// regress tsnet.Server restarts.
cc.Login(controlclient.LoginDefault)
cc.Login(b.loginFlags)
}
b.stateMachineLocked()
@@ -4842,7 +4842,7 @@ func (b *LocalBackend) setPrefsLocked(newp *ipn.Prefs) ipn.PrefsView {
if !oldp.WantRunning() && newp.WantRunning && cc != nil {
b.logf("transitioning to running; doing Login...")
cc.Login(controlclient.LoginDefault)
cc.Login(b.loginFlags)
}
if oldp.WantRunning() != newp.WantRunning {