tailscale/paths/paths_unix.go
Aaron Klotz f3be05e6ea ipn, paths: unconditionally attempt to set state dir perms, but only if the state dir is ours
We unconditionally set appropriate perms on the statefile dir.

We look at the basename of the statefile dir, and if it is "tailscale", then
we set perms as appropriate.

Fixes #2925
Updates #2856

Signed-off-by: Aaron Klotz <aaron@tailscale.com>
2021-09-24 15:12:20 -07:00

72 lines
1.4 KiB
Go

// Copyright (c) 2020 Tailscale Inc & AUTHORS All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build !windows
// +build !windows
package paths
import (
"os"
"path/filepath"
"runtime"
"golang.org/x/sys/unix"
)
func init() {
stateFileFunc = stateFileUnix
}
func statePath() string {
switch runtime.GOOS {
case "linux":
return "/var/lib/tailscale/tailscaled.state"
case "freebsd", "openbsd":
return "/var/db/tailscale/tailscaled.state"
case "darwin":
return "/Library/Tailscale/tailscaled.state"
default:
return ""
}
}
func stateFileUnix() string {
path := statePath()
if path == "" {
return ""
}
try := path
for i := 0; i < 3; i++ { // check writability of the file, /var/lib/tailscale, and /var/lib
err := unix.Access(try, unix.O_RDWR)
if err == nil {
return path
}
try = filepath.Dir(try)
}
if os.Getuid() == 0 {
return ""
}
// For non-root users, fall back to $XDG_DATA_HOME/tailscale/*.
return filepath.Join(xdgDataHome(), "tailscale", "tailscaled.state")
}
func xdgDataHome() string {
if e := os.Getenv("XDG_DATA_HOME"); e != "" {
return e
}
return filepath.Join(os.Getenv("HOME"), ".local/share")
}
func ensureStateDirPerms(dirPath string) error {
if filepath.Base(dirPath) != "tailscale" {
return nil
}
return os.Chmod(dirPath, 0700)
}