| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- // Copyright (c) Tailscale Inc & AUTHORS
- // SPDX-License-Identifier: BSD-3-Clause
- package paths
- import (
- "os"
- "path/filepath"
- "strings"
- "golang.org/x/sys/windows"
- "tailscale.com/util/winutil"
- )
- func init() {
- ensureStateDirPerms = ensureStateDirPermsWindows
- }
- // ensureStateDirPermsWindows 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 ensureStateDirPermsWindows(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)
- }
|