mirror of
https://github.com/tailscale/tailscale.git
synced 2025-04-23 09:21:41 +00:00

I added yet another one in 6d117d64a256234 but that new one is at the best place int he dependency graph and has the best name, so let's use that one for everything possible. types/lazy can't use it for circular dependency reasons, so unexport that copy at least. Updates #cleanup Change-Id: I25db6b6a0d81dbb8e89a0a9080c7f15cbf7aa770 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
93 lines
3.3 KiB
Go
93 lines
3.3 KiB
Go
// Copyright (c) Tailscale Inc & AUTHORS
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
package syspolicy
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"os/user"
|
|
|
|
"tailscale.com/util/syspolicy/internal"
|
|
"tailscale.com/util/syspolicy/rsop"
|
|
"tailscale.com/util/syspolicy/setting"
|
|
"tailscale.com/util/syspolicy/source"
|
|
"tailscale.com/util/testenv"
|
|
)
|
|
|
|
func init() {
|
|
// On Windows, we should automatically register the Registry-based policy
|
|
// store for the device. If we are running in a user's security context
|
|
// (e.g., we're the GUI), we should also register the Registry policy store for
|
|
// the user. In the future, we should register (and unregister) user policy
|
|
// stores whenever a user connects to (or disconnects from) the local backend.
|
|
// This ensures the backend is aware of the user's policy settings and can send
|
|
// them to the GUI/CLI/Web clients on demand or whenever they change.
|
|
//
|
|
// Other platforms, such as macOS, iOS and Android, should register their
|
|
// platform-specific policy stores via [RegisterStore]
|
|
// (or [RegisterHandler] until they implement the [source.Store] interface).
|
|
//
|
|
// External code, such as the ipnlocal package, may choose to register
|
|
// additional policy stores, such as config files and policies received from
|
|
// the control plane.
|
|
internal.Init.MustDefer(func() error {
|
|
// Do not register or use default policy stores during tests.
|
|
// Each test should set up its own necessary configurations.
|
|
if testenv.InTest() {
|
|
return nil
|
|
}
|
|
return configureSyspolicy(nil)
|
|
})
|
|
}
|
|
|
|
// configureSyspolicy configures syspolicy for use on Windows,
|
|
// either in test or regular builds depending on whether tb has a non-nil value.
|
|
func configureSyspolicy(tb testenv.TB) error {
|
|
const localSystemSID = "S-1-5-18"
|
|
// Always create and register a machine policy store that reads
|
|
// policy settings from the HKEY_LOCAL_MACHINE registry hive.
|
|
machineStore, err := source.NewMachinePlatformPolicyStore()
|
|
if err != nil {
|
|
return fmt.Errorf("failed to create the machine policy store: %v", err)
|
|
}
|
|
if tb == nil {
|
|
_, err = rsop.RegisterStore("Platform", setting.DeviceScope, machineStore)
|
|
} else {
|
|
_, err = rsop.RegisterStoreForTest(tb, "Platform", setting.DeviceScope, machineStore)
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
// Check whether the current process is running as Local System or not.
|
|
u, err := user.Current()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if u.Uid == localSystemSID {
|
|
return nil
|
|
}
|
|
// If it's not a Local System's process (e.g., it's the GUI rather than the tailscaled service),
|
|
// we should create and use a policy store for the current user that reads
|
|
// policy settings from that user's registry hive (HKEY_CURRENT_USER).
|
|
userStore, err := source.NewUserPlatformPolicyStore(0)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to create the current user's policy store: %v", err)
|
|
}
|
|
if tb == nil {
|
|
_, err = rsop.RegisterStore("Platform", setting.CurrentUserScope, userStore)
|
|
} else {
|
|
_, err = rsop.RegisterStoreForTest(tb, "Platform", setting.CurrentUserScope, userStore)
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
// And also set [setting.CurrentUserScope] as the [setting.DefaultScope], so [GetString],
|
|
// [GetVisibility] and similar functions would be returning a merged result
|
|
// of the machine's and user's policies.
|
|
if !setting.SetDefaultScope(setting.CurrentUserScope) {
|
|
return errors.New("current scope already set")
|
|
}
|
|
return nil
|
|
}
|