mirror of
https://github.com/tailscale/tailscale.git
synced 2024-12-01 22:15:51 +00:00
6b5081ab31
ProgramData has a permissive ACL. For us to safely store machine-wide state information, we must set a more restrictive ACL on our state directory. We set the ACL so that only talescaled's user (ie, LocalSystem) and the Administrators group may access our directory. We must include Administrators to ensure that logs continue to be easily accessible; omitting that group would force users to use special tools to log in interactively as LocalSystem, which is not ideal. (Note that the ACL we apply matches the ACL that was used for LocalSystem's AppData\Local). There are two cases where we need to reset perms: One is during migration from the old location to the new. The second case is for clean installations where we are creating the file store for the first time. Updates #2856 Signed-off-by: Aaron Klotz <aaron@tailscale.com>
60 lines
1.7 KiB
Go
60 lines
1.7 KiB
Go
// Copyright (c) 2021 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.
|
|
|
|
package paths
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"tailscale.com/types/logger"
|
|
)
|
|
|
|
// TryConfigFileMigration carefully copies the contents of oldFile to
|
|
// newFile, returning the path which should be used to read the config.
|
|
// - if newFile already exists, don't modify it just return its path
|
|
// - if neither oldFile nor newFile exist, return newFile for a fresh
|
|
// default config to be written to.
|
|
// - if oldFile exists but copying to newFile fails, return oldFile so
|
|
// there will at least be some config to work with.
|
|
func TryConfigFileMigration(logf logger.Logf, oldFile, newFile string) string {
|
|
_, err := os.Stat(newFile)
|
|
if err == nil {
|
|
// Common case for a system which has already been migrated.
|
|
return newFile
|
|
}
|
|
if !os.IsNotExist(err) {
|
|
logf("TryConfigFileMigration failed; new file: %v", err)
|
|
return newFile
|
|
}
|
|
|
|
contents, err := os.ReadFile(oldFile)
|
|
if err != nil {
|
|
// Common case for a new user.
|
|
return newFile
|
|
}
|
|
|
|
if err = MkStateDir(filepath.Dir(newFile)); err != nil {
|
|
logf("TryConfigFileMigration failed; MkStateDir: %v", err)
|
|
return oldFile
|
|
}
|
|
|
|
err = os.WriteFile(newFile, contents, 0600)
|
|
if err != nil {
|
|
removeErr := os.Remove(newFile)
|
|
if removeErr != nil {
|
|
logf("TryConfigFileMigration failed; write newFile no cleanup: %v, remove err: %v",
|
|
err, removeErr)
|
|
return oldFile
|
|
}
|
|
logf("TryConfigFileMigration failed; write newFile: %v", err)
|
|
return oldFile
|
|
}
|
|
|
|
logf("TryConfigFileMigration: successfully migrated: from %v to %v",
|
|
oldFile, newFile)
|
|
|
|
return newFile
|
|
}
|