mirror of
				https://github.com/tailscale/tailscale.git
				synced 2025-11-04 10:11:18 +01:00 
			
		
		
		
	Updates #16524 Change-Id: I183428de8c65d7155d82979d2d33f031c22e3331 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
		
			
				
	
	
		
			92 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			92 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Copyright (c) Tailscale Inc & AUTHORS
 | 
						|
// SPDX-License-Identifier: BSD-3-Clause
 | 
						|
 | 
						|
//go:build !windows && !wasm && !plan9 && !tamago
 | 
						|
 | 
						|
package paths
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"os"
 | 
						|
	"path/filepath"
 | 
						|
	"runtime"
 | 
						|
 | 
						|
	"golang.org/x/sys/unix"
 | 
						|
	"tailscale.com/version/distro"
 | 
						|
)
 | 
						|
 | 
						|
func init() {
 | 
						|
	stateFileFunc = stateFileUnix
 | 
						|
	ensureStateDirPerms = ensureStateDirPermsUnix
 | 
						|
}
 | 
						|
 | 
						|
func statePath() string {
 | 
						|
	if runtime.GOOS == "linux" && distro.Get() == distro.JetKVM {
 | 
						|
		return "/userdata/tailscale/var/tailscaled.state"
 | 
						|
	}
 | 
						|
	switch runtime.GOOS {
 | 
						|
	case "linux", "illumos", "solaris":
 | 
						|
		return "/var/lib/tailscale/tailscaled.state"
 | 
						|
	case "freebsd", "openbsd":
 | 
						|
		return "/var/db/tailscale/tailscaled.state"
 | 
						|
	case "darwin":
 | 
						|
		return "/Library/Tailscale/tailscaled.state"
 | 
						|
	case "aix":
 | 
						|
		return "/var/tailscale/tailscaled.state"
 | 
						|
	default:
 | 
						|
		return ""
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func stateFileUnix() string {
 | 
						|
	if distro.Get() == distro.Gokrazy {
 | 
						|
		return "/perm/tailscaled/tailscaled.state"
 | 
						|
	}
 | 
						|
	path := statePath()
 | 
						|
	if path == "" {
 | 
						|
		return ""
 | 
						|
	}
 | 
						|
 | 
						|
	try := path
 | 
						|
	for range 3 { // 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 ensureStateDirPermsUnix(dir string) error {
 | 
						|
	if filepath.Base(dir) != "tailscale" {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
	fi, err := os.Stat(dir)
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
	if !fi.IsDir() {
 | 
						|
		return fmt.Errorf("expected %q to be a directory; is %v", dir, fi.Mode())
 | 
						|
	}
 | 
						|
	const perm = 0700
 | 
						|
	if fi.Mode().Perm() == perm {
 | 
						|
		// Already correct.
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
	return os.Chmod(dir, perm)
 | 
						|
}
 |