diff --git a/ipn/ipnlocal/local.go b/ipn/ipnlocal/local.go index c01eff80e..c4ed545a7 100644 --- a/ipn/ipnlocal/local.go +++ b/ipn/ipnlocal/local.go @@ -2760,11 +2760,17 @@ func (b *LocalBackend) CheckPrefs(p *ipn.Prefs) error { return b.checkPrefsLocked(p) } +// isConfigLocked_Locked reports whether the parsed config file is locked. +// b.mu must be held. +func (b *LocalBackend) isConfigLocked_Locked() bool { + // TODO(bradfitz,maisem): make this more fine-grained, permit changing + // some things if they're not explicitly set in the config. But for now + // (2023-10-16), just blanket disable everything. + return b.conf != nil && !b.conf.Parsed.Locked.EqualBool(false) +} + func (b *LocalBackend) checkPrefsLocked(p *ipn.Prefs) error { - if b.conf != nil && !b.conf.Parsed.Locked.EqualBool(false) { - // TODO(bradfitz,maisem): make this more fine-grained, permit changing - // some things if they're not explicitly set in the config. But for now - // (2023-10-16), just blanket disable everything. + if b.isConfigLocked_Locked() { return errors.New("can't reconfigure tailscaled when using a config file; config file is locked") } var errs []error diff --git a/ipn/ipnlocal/serve.go b/ipn/ipnlocal/serve.go index 9b218a71f..60dbaeff4 100644 --- a/ipn/ipnlocal/serve.go +++ b/ipn/ipnlocal/serve.go @@ -245,6 +245,9 @@ func (b *LocalBackend) setServeConfigLocked(config *ipn.ServeConfig, etag string if config.IsFunnelOn() && prefs.ShieldsUp() { return errors.New("Unable to turn on Funnel while shields-up is enabled") } + if b.isConfigLocked_Locked() { + return errors.New("can't reconfigure tailscaled when using a config file; config file is locked") + } nm := b.netMap if nm == nil {