diff --git a/go.mod b/go.mod index 25e31b5884ac..05215694fadc 100644 --- a/go.mod +++ b/go.mod @@ -123,6 +123,7 @@ require ( github.com/prometheus/common v0.49.0 github.com/rancher/dynamiclistener v0.6.0-rc1 github.com/rancher/lasso v0.0.0-20240430201833-6f3def65ffc5 + github.com/rancher/permissions v0.0.0-20240523180510-4001d3d637f7 github.com/rancher/remotedialer v0.3.0 github.com/rancher/wharfie v0.6.4 github.com/rancher/wrangler/v3 v3.0.0-rc2 diff --git a/go.sum b/go.sum index 3cff4c893008..2fc837dca38e 100644 --- a/go.sum +++ b/go.sum @@ -252,8 +252,6 @@ github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2B github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= -github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/Microsoft/hcsshim v0.11.0 h1:7EFNIY4igHEXUdj1zXgAyU3fLc7QfOKHbkldRVTBdiM= github.com/Microsoft/hcsshim v0.11.0/go.mod h1:OEthFdQv/AD2RAdzR6Mm1N1KPCztGKDurW1Z8b8VGMM= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= @@ -1405,6 +1403,8 @@ github.com/rancher/dynamiclistener v0.6.0-rc1 h1:Emwf9o7PMLdQNv4lvFx7xJKxDuDa4Y6 github.com/rancher/dynamiclistener v0.6.0-rc1/go.mod h1:BIPgJ8xFSUyuTyGvRMVt++S1qjD3+7Ptvq1TXl6hcTM= github.com/rancher/lasso v0.0.0-20240430201833-6f3def65ffc5 h1:6K4RhfmCy7uxaw9OzCljNLfFcgD/q7SeF+/2gCQ3Tvw= github.com/rancher/lasso v0.0.0-20240430201833-6f3def65ffc5/go.mod h1:7WkdfPEvWAdnHVioMUkhpZkshJzjDY62ocHVhcbw89M= +github.com/rancher/permissions v0.0.0-20240523180510-4001d3d637f7 h1:0Kg2SGoMeU1ll4xPi4DE0+qNHLFO/U5MwtK0WrIdK+o= +github.com/rancher/permissions v0.0.0-20240523180510-4001d3d637f7/go.mod h1:fsbs0YOsGn1ofPD5p+BuI4qDhbMbSJtTegKt6Ucna+c= github.com/rancher/remotedialer v0.3.0 h1:y1EO8JCsgZo0RcqTUp6U8FXcBAv27R+TLnWRcpvX1sM= github.com/rancher/remotedialer v0.3.0/go.mod h1:BwwztuvViX2JrLLUwDlsYt5DiyUwHLlzynRwkZLAY0Q= github.com/rancher/wharfie v0.6.4 h1:JwYB+q661n8ut/ysgsjKe0P0z6bHCCFoC+29995ME90= diff --git a/pkg/agent/config/config.go b/pkg/agent/config/config.go index fc0e7241549b..7366a9924138 100644 --- a/pkg/agent/config/config.go +++ b/pkg/agent/config/config.go @@ -205,7 +205,7 @@ func ensureNodePassword(nodePasswordFile string) (string, error) { return nodePassword, err } - if err = configureACL(nodePassword); err != nil { + if err = configureACL(nodePasswordFile); err != nil { return nodePassword, err } diff --git a/pkg/agent/config/config_windows.go b/pkg/agent/config/config_windows.go index 2763ad769320..10f6973d4e3b 100644 --- a/pkg/agent/config/config_windows.go +++ b/pkg/agent/config/config_windows.go @@ -6,10 +6,12 @@ package config import ( "path/filepath" - "github.com/k3s-io/k3s/pkg/agent/util/acl" "github.com/k3s-io/k3s/pkg/cli/cmds" "github.com/k3s-io/k3s/pkg/daemons/config" "github.com/pkg/errors" + "github.com/rancher/permissions/pkg/access" + "github.com/rancher/permissions/pkg/acl" + "github.com/rancher/permissions/pkg/sid" "golang.org/x/sys/windows" ) @@ -33,8 +35,8 @@ func configureACL(file string) error { // as the owner and current user group as the allowed group // additionally, we define a DACL to permit access to the file to the local system and all administrators if err := acl.Apply(file, nil, nil, []windows.EXPLICIT_ACCESS{ - acl.GrantSid(windows.GENERIC_ALL, acl.LocalSystemSID()), - acl.GrantSid(windows.GENERIC_ALL, acl.BuiltinAdministratorsSID()), + access.GrantSid(windows.GENERIC_ALL, sid.LocalSystem()), + access.GrantSid(windows.GENERIC_ALL, sid.BuiltinAdministrators()), }...); err != nil { return errors.Wrapf(err, "failed to configure Access Control List For %s", file) } diff --git a/pkg/agent/util/acl/acl_windows.go b/pkg/agent/util/acl/acl_windows.go deleted file mode 100644 index 6d9bab8819bc..000000000000 --- a/pkg/agent/util/acl/acl_windows.go +++ /dev/null @@ -1,166 +0,0 @@ -//go:build windows -// +build windows - -package acl - -import ( - "fmt" - "golang.org/x/sys/windows" - "unsafe" -) - -// TODO: Remove in favor of the rancher/permissions repository once that is setup - -func BuiltinAdministratorsSID() *windows.SID { - return mustGetSid(windows.WinBuiltinAdministratorsSid) -} - -func LocalSystemSID() *windows.SID { - return mustGetSid(windows.WinLocalSystemSid) -} - -func mustGetSid(sidType windows.WELL_KNOWN_SID_TYPE) *windows.SID { - sid, err := windows.CreateWellKnownSid(sidType) - if err != nil { - panic(err) - } - return sid -} - -// GrantSid creates an EXPLICIT_ACCESS instance granting permissions to the provided SID. -func GrantSid(accessPermissions windows.ACCESS_MASK, sid *windows.SID) windows.EXPLICIT_ACCESS { - return windows.EXPLICIT_ACCESS{ - AccessPermissions: accessPermissions, - AccessMode: windows.GRANT_ACCESS, - Inheritance: windows.SUB_CONTAINERS_AND_OBJECTS_INHERIT, - Trustee: windows.TRUSTEE{ - TrusteeForm: windows.TRUSTEE_IS_SID, - TrusteeValue: windows.TrusteeValueFromSID(sid), - }, - } -} - -// Apply performs both Chmod and Chown at the same time, where the filemode's owner and group will correspond to -// the provided owner and group (or the current owner and group, if they are set to nil) -func Apply(path string, owner *windows.SID, group *windows.SID, access ...windows.EXPLICIT_ACCESS) error { - if path == "" { - return fmt.Errorf("path cannot be empty") - } - return apply(path, owner, group, access...) -} - -// apply performs a Chmod (if owner and group are provided) and sets a custom ACL based on the provided EXPLICIT_ACCESS rules -// To create EXPLICIT_ACCESS rules, see the helper functions in pkg/access -func apply(path string, owner *windows.SID, group *windows.SID, access ...windows.EXPLICIT_ACCESS) error { - // assemble arguments - args := securityArgs{ - path: path, - owner: owner, - group: group, - access: access, - } - - securityInfo := args.ToSecurityInfo() - if securityInfo == 0 { - // nothing to change - return nil - } - dacl, err := args.ToDACL() - if err != nil { - return err - } - return windows.SetNamedSecurityInfo( - path, - windows.SE_FILE_OBJECT, - securityInfo, - owner, - group, - dacl, - nil, - ) -} - -type securityArgs struct { - path string - - owner *windows.SID - group *windows.SID - - access []windows.EXPLICIT_ACCESS -} - -func (a *securityArgs) ToSecurityInfo() windows.SECURITY_INFORMATION { - var securityInfo windows.SECURITY_INFORMATION - - if a.owner != nil { - // override owner - securityInfo |= windows.OWNER_SECURITY_INFORMATION - } - - if a.group != nil { - // override group - securityInfo |= windows.GROUP_SECURITY_INFORMATION - } - - if len(a.access) != 0 { - // override DACL - securityInfo |= windows.DACL_SECURITY_INFORMATION - securityInfo |= windows.PROTECTED_DACL_SECURITY_INFORMATION - } - - return securityInfo -} - -func (a *securityArgs) ToSecurityAttributes() (*windows.SecurityAttributes, error) { - // define empty security descriptor - sd, err := windows.NewSecurityDescriptor() - if err != nil { - return nil, err - } - err = sd.SetOwner(a.owner, false) - if err != nil { - return nil, err - } - err = sd.SetGroup(a.group, false) - if err != nil { - return nil, err - } - - // define security attributes using descriptor - var sa windows.SecurityAttributes - sa.Length = uint32(unsafe.Sizeof(sa)) - sa.SecurityDescriptor = sd - - if len(a.access) == 0 { - // security attribute should simply inherit parent rules - sa.InheritHandle = 1 - return &sa, nil - } - - // apply provided access rules to the DACL - dacl, err := a.ToDACL() - if err != nil { - return nil, err - } - err = sd.SetDACL(dacl, true, false) - if err != nil { - return nil, err - } - - // set the protected DACL flag to prevent the DACL of the security descriptor from being modified by inheritable ACEs - // (i.e. prevent parent folders from modifying this ACL) - err = sd.SetControl(windows.SE_DACL_PROTECTED, windows.SE_DACL_PROTECTED) - if err != nil { - return nil, err - } - - return &sa, nil -} - -func (a *securityArgs) ToDACL() (*windows.ACL, error) { - if len(a.access) == 0 { - // No rules were specified - return nil, nil - } - return windows.ACLFromEntries(a.access, nil) -}