You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tailscale/ipn/ipnlocal/profiles_notwindows.go

36 lines
877 B
Go

// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
//go:build !windows
package ipnlocal
import (
"fmt"
"runtime"
"tailscale.com/ipn"
"tailscale.com/version"
)
ipn/ipnlocal: refactor and cleanup profileManager In preparation for multi-user and unattended mode improvements, we are refactoring and cleaning up `ipn/ipnlocal.profileManager`. The concept of the "current user", which is only relevant on Windows, is being deprecated and will soon be removed to allow more than one Windows user to connect and utilize `LocalBackend` according to that user's access rights to the device and specific Tailscale profiles. We plan to pass the user's identity down to the `profileManager`, where it can be used to determine the user's access rights to a given `LoginProfile`. While the new permission model in `ipnauth` requires more work and is currently blocked pending PR reviews, we are updating the `profileManager` to reduce its reliance on the concept of a single OS user being connected to the backend at the same time. We extract the switching to the default Tailscale profile, which may also trigger legacy profile migration, from `profileManager.SetCurrentUserID`. This introduces `profileManager.DefaultUserProfileID`, which returns the default profile ID for the current user, and `profileManager.SwitchToDefaultProfile`, which is essentially a shorthand for `pm.SwitchProfile(pm.DefaultUserProfileID())`. Both methods will eventually be updated to accept the user's identity and utilize that user's default profile. We make access checks more explicit by introducing the `profileManager.checkProfileAccess` method. The current implementation continues to use `profileManager.currentUserID` and `LoginProfile.LocalUserID` to determine whether access to a given profile should be granted. This will be updated to utilize the `ipnauth` package and the new permissions model once it's ready. We also expand access checks to be used more widely in the `profileManager`, not just when switching or listing profiles. This includes access checks in methods like `SetPrefs` and, most notably, `DeleteProfile` and `DeleteAllProfiles`, preventing unprivileged Windows users from deleting Tailscale profiles owned by other users on the same device, including profiles owned by local admins. We extract `profileManager.ProfilePrefs` and `profileManager.SetProfilePrefs` methods that can be used to get and set preferences of a given `LoginProfile` if `profileManager.checkProfileAccess` permits access to it. We also update `profileManager.setUnattendedModeAsConfigured` to always enable unattended mode on Windows if `Prefs.ForceDaemon` is true in the current `LoginProfile`, even if `profileManager.currentUserID` is `""`. This facilitates enabling unattended mode via `tailscale up --unattended` even if `tailscale-ipn.exe` is not running, such as when a Group Policy or MDM-deployed script runs at boot time, or when Tailscale is used on a Server Code or otherwise headless Windows environments. See #12239, #2137, #3186 and https://github.com/tailscale/tailscale/pull/6255#issuecomment-2016623838 for details. Fixes #12239 Updates tailscale/corp#18342 Updates #3186 Updates #2137 Signed-off-by: Nick Khyl <nickk@tailscale.com>
3 months ago
func (pm *profileManager) loadLegacyPrefs(ipn.WindowsUserID) (string, ipn.PrefsView, error) {
k := ipn.LegacyGlobalDaemonStateKey
switch {
case runtime.GOOS == "ios", version.IsSandboxedMacOS():
k = "ipn-go-bridge"
case runtime.GOOS == "android":
k = "ipn-android"
}
prefs, err := pm.loadSavedPrefs(k)
if err != nil {
return "", ipn.PrefsView{}, fmt.Errorf("calling ReadState on state store: %w", err)
}
pm.logf("migrating %q profile to new format", k)
return "", prefs, nil
}
func (pm *profileManager) completeMigration(migrationSentinel string) {
// Do not delete the old state key, as we may be downgraded to an
// older version that still relies on it.
}