mirror of
https://github.com/tailscale/tailscale.git
synced 2024-12-01 22:15:51 +00:00
b005b79236
AFAICT this isn't documented on MSDN, but based on the issue referenced below, NRPT rules are not working when a rule specifies > 50 domains. This patch modifies our NRPT rule generator to split the list of domains into chunks as necessary, and write a separate rule for each chunk. For compatibility reasons, we continue to use the hard-coded rule ID, but as additional rules are required, we generate new GUIDs. Those GUIDs are stored under the Tailscale registry path so that we know which rules are ours. I made some changes to winutils to add additional helper functions in support of both the code and its test: I added additional registry accessors, and also moved some token accessors from paths to util/winutil. Fixes https://github.com/tailscale/coral/issues/63 Signed-off-by: Aaron Klotz <aaron@tailscale.com>
101 lines
3.3 KiB
Go
101 lines
3.3 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"
|
|
"strings"
|
|
|
|
"golang.org/x/sys/windows"
|
|
"tailscale.com/util/winutil"
|
|
)
|
|
|
|
// ensureStateDirPerms applies a restrictive ACL to the directory specified by dirPath.
|
|
// It sets the following security attributes on the directory:
|
|
// Owner: The user for the current process;
|
|
// Primary Group: The primary group for the current process;
|
|
// DACL: Full control to the current user and to the Administrators group.
|
|
// (We include Administrators so that admin users may still access logs;
|
|
// granting access exclusively to LocalSystem would require admins to use
|
|
// special tools to access the Log directory)
|
|
// Inheritance: The directory does not inherit the ACL from its parent.
|
|
// However, any directories and/or files created within this
|
|
// directory *do* inherit the ACL that we are setting.
|
|
func ensureStateDirPerms(dirPath string) error {
|
|
fi, err := os.Stat(dirPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if !fi.IsDir() {
|
|
return os.ErrInvalid
|
|
}
|
|
if strings.ToLower(filepath.Base(dirPath)) != "tailscale" {
|
|
return nil
|
|
}
|
|
|
|
// We need the info for our current user as SIDs
|
|
sids, err := winutil.GetCurrentUserSIDs()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// We also need the SID for the Administrators group so that admins may
|
|
// easily access logs.
|
|
adminGroupSid, err := windows.CreateWellKnownSid(windows.WinBuiltinAdministratorsSid)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Munge the SIDs into the format required by EXPLICIT_ACCESS.
|
|
userTrustee := windows.TRUSTEE{nil, windows.NO_MULTIPLE_TRUSTEE,
|
|
windows.TRUSTEE_IS_SID, windows.TRUSTEE_IS_USER,
|
|
windows.TrusteeValueFromSID(sids.User)}
|
|
|
|
adminTrustee := windows.TRUSTEE{nil, windows.NO_MULTIPLE_TRUSTEE,
|
|
windows.TRUSTEE_IS_SID, windows.TRUSTEE_IS_WELL_KNOWN_GROUP,
|
|
windows.TrusteeValueFromSID(adminGroupSid)}
|
|
|
|
// We declare our access rights via this array of EXPLICIT_ACCESS structures.
|
|
// We set full access to our user and to Administrators.
|
|
// We configure the DACL such that any files or directories created within
|
|
// dirPath will also inherit this DACL.
|
|
explicitAccess := []windows.EXPLICIT_ACCESS{
|
|
{
|
|
windows.GENERIC_ALL,
|
|
windows.SET_ACCESS,
|
|
windows.SUB_CONTAINERS_AND_OBJECTS_INHERIT,
|
|
userTrustee,
|
|
},
|
|
{
|
|
windows.GENERIC_ALL,
|
|
windows.SET_ACCESS,
|
|
windows.SUB_CONTAINERS_AND_OBJECTS_INHERIT,
|
|
adminTrustee,
|
|
},
|
|
}
|
|
|
|
dacl, err := windows.ACLFromEntries(explicitAccess, nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// We now reset the file's owner, primary group, and DACL.
|
|
// We also must pass PROTECTED_DACL_SECURITY_INFORMATION so that our new ACL
|
|
// does not inherit any ACL entries from the parent directory.
|
|
const flags = windows.OWNER_SECURITY_INFORMATION |
|
|
windows.GROUP_SECURITY_INFORMATION |
|
|
windows.DACL_SECURITY_INFORMATION |
|
|
windows.PROTECTED_DACL_SECURITY_INFORMATION
|
|
return windows.SetNamedSecurityInfo(dirPath, windows.SE_FILE_OBJECT, flags,
|
|
sids.User, sids.PrimaryGroup, dacl, nil)
|
|
}
|
|
|
|
// LegacyStateFilePath returns the legacy path to the state file when it was stored under the
|
|
// current user's %LocalAppData%.
|
|
func LegacyStateFilePath() string {
|
|
return filepath.Join(os.Getenv("LocalAppData"), "Tailscale", "server-state.conf")
|
|
}
|