diff --git a/ipn/store.go b/ipn/store.go index c4f0d2c6d..1bf8194de 100644 --- a/ipn/store.go +++ b/ipn/store.go @@ -170,6 +170,11 @@ func (s *FileStore) String() string { return fmt.Sprintf("FileStore(%q)", s.path // NewFileStore returns a new file store that persists to path. func NewFileStore(path string) (*FileStore, error) { + // We unconditionally call this to ensure that our perms are correct + if err := paths.MkStateDir(filepath.Dir(path)); err != nil { + return nil, fmt.Errorf("creating state directory: %w", err) + } + bs, err := ioutil.ReadFile(path) // Treat an empty file as a missing file. @@ -183,9 +188,6 @@ func NewFileStore(path string) (*FileStore, error) { if os.IsNotExist(err) { // Write out an initial file, to verify that we can write // to the path. - if err := paths.MkStateDir(filepath.Dir(path)); err != nil { - return nil, fmt.Errorf("creating state directory: %w", err) - } if err = atomicfile.WriteFile(path, []byte("{}"), 0600); err != nil { return nil, err } diff --git a/paths/paths_unix.go b/paths/paths_unix.go index 0bc413ad1..17662b0f8 100644 --- a/paths/paths_unix.go +++ b/paths/paths_unix.go @@ -63,9 +63,9 @@ func xdgDataHome() string { } func ensureStateDirPerms(dirPath string) error { - // Unfortunately there are currently numerous tests that set up state files - // right off of /tmp, on which Chmod will of course fail. We should fix our - // test harnesses to not do that, at which point we can return an error. - os.Chmod(dirPath, 0700) - return nil + if filepath.Base(dirPath) != "tailscale" { + return nil + } + + return os.Chmod(dirPath, 0700) } diff --git a/paths/paths_windows.go b/paths/paths_windows.go index 75d49100a..e00a8062a 100644 --- a/paths/paths_windows.go +++ b/paths/paths_windows.go @@ -6,6 +6,8 @@ package paths import ( "os" + "path/filepath" + "strings" "unsafe" "golang.org/x/sys/windows" @@ -86,6 +88,9 @@ func ensureStateDirPerms(dirPath string) error { if !fi.IsDir() { return os.ErrInvalid } + if strings.ToLower(filepath.Base(dirPath)) != "tailscale" { + return nil + } // We need the info for our current user as SIDs sids, err := getCurrentUserSids()