From 121802f5ca1cf79b09fee015181b8230c6ea4845 Mon Sep 17 00:00:00 2001 From: Harrison Affel Date: Thu, 16 May 2024 20:03:20 -0400 Subject: [PATCH] windows changes Signed-off-by: Harrison Affel --- go.mod | 2 +- go.sum | 4 +- pkg/cli/defaults/defaults.go | 4 ++ pkg/cli/defaults/defaults_linux.go | 21 +++++++++ pkg/cli/defaults/defaults_windows.go | 42 +++++++++++++++++ pkg/windows/utils.go | 70 ++++++++++++++++++++++++++++ 6 files changed, 140 insertions(+), 3 deletions(-) create mode 100644 pkg/cli/defaults/defaults_linux.go create mode 100644 pkg/cli/defaults/defaults_windows.go diff --git a/go.mod b/go.mod index 5cb6d6a1d7..27bbe310eb 100644 --- a/go.mod +++ b/go.mod @@ -79,7 +79,7 @@ require ( github.com/google/go-containerregistry v0.19.0 github.com/iamacarpet/go-win64api v0.0.0-20210311141720-fe38760bed28 github.com/k3s-io/helm-controller v0.15.9 - github.com/k3s-io/k3s v1.29.4-rc1.0.20240423023443-94e29e2ef5d7 // master + github.com/k3s-io/k3s v1.29.5-0.20240516215516-16898462993f // master github.com/libp2p/go-netroute v0.2.1 github.com/natefinch/lumberjack v2.0.0+incompatible github.com/onsi/ginkgo/v2 v2.15.0 diff --git a/go.sum b/go.sum index 01f4c6106d..6995d0e32e 100644 --- a/go.sum +++ b/go.sum @@ -1203,8 +1203,8 @@ github.com/k3s-io/etcd/server/v3 v3.5.9-k3s1 h1:B3039IkTPnwQEt4tIMjC6yd6b1Q3Z9ZZ github.com/k3s-io/etcd/server/v3 v3.5.9-k3s1/go.mod h1:GgI1fQClQCFIzuVjlvdbMxNbnISt90gdfYyqiAIt65g= github.com/k3s-io/helm-controller v0.15.9 h1:eBZq0KkZCDyWh4og+tyI43Nt9T5TNjc7QCFhAt1aR64= github.com/k3s-io/helm-controller v0.15.9/go.mod h1:AYitg40howLjKloL/zdjDDOPL1jg/K5R4af0tQcyPR8= -github.com/k3s-io/k3s v1.29.4-rc1.0.20240423023443-94e29e2ef5d7 h1:vAMspjOSY57eKemOzMfNFTQBFKIzu2HBLV13gq7Q+40= -github.com/k3s-io/k3s v1.29.4-rc1.0.20240423023443-94e29e2ef5d7/go.mod h1:JDIPiDgr1nCfYmlL0vN5cgv27J3BuzSVBrsqh2KM/hM= +github.com/k3s-io/k3s v1.29.5-0.20240516215516-16898462993f h1:EWl72GAWeYXr+hX4FNa04P/nbhlhOeTbU9QDqtXluKA= +github.com/k3s-io/k3s v1.29.5-0.20240516215516-16898462993f/go.mod h1:JDIPiDgr1nCfYmlL0vN5cgv27J3BuzSVBrsqh2KM/hM= github.com/k3s-io/kine v0.11.7 h1:+I4TrxozQv4cdmD8RULI35r4o5G+A7gOD3F75lfjDP0= github.com/k3s-io/kine v0.11.7/go.mod h1:4C/zNVwl3FU1EubA2ju1Hq36JIjp8gAZaM+Hfnuvqt4= github.com/k3s-io/klog v1.0.0-k3s2/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= diff --git a/pkg/cli/defaults/defaults.go b/pkg/cli/defaults/defaults.go index 1db87c2ec9..8b55d23abb 100644 --- a/pkg/cli/defaults/defaults.go +++ b/pkg/cli/defaults/defaults.go @@ -12,6 +12,10 @@ import ( ) func Set(_ *cli.Context, dataDir string) error { + if err := createDataDir(dataDir, 0755); err != nil { + return errors.Wrapf(err, "failed to create directory %s", dataDir) + } + logsDir := filepath.Join(dataDir, "agent", "logs") if err := os.MkdirAll(logsDir, 0755); err != nil { return errors.Wrapf(err, "failed to create directory %s", logsDir) diff --git a/pkg/cli/defaults/defaults_linux.go b/pkg/cli/defaults/defaults_linux.go new file mode 100644 index 0000000000..1a28e93b9b --- /dev/null +++ b/pkg/cli/defaults/defaults_linux.go @@ -0,0 +1,21 @@ +//go:build linux +// +build linux + +package defaults + +import ( + "os" + + "github.com/pkg/errors" +) + +func createDataDir(dataDir string, perm os.FileMode) error { + if dataDir == "" { + return nil + } + + if err := os.MkdirAll(dataDir, perm); err != nil { + return errors.Wrapf(err, "failed to create directory %s", dataDir) + } + return nil +} diff --git a/pkg/cli/defaults/defaults_windows.go b/pkg/cli/defaults/defaults_windows.go new file mode 100644 index 0000000000..4834d13b06 --- /dev/null +++ b/pkg/cli/defaults/defaults_windows.go @@ -0,0 +1,42 @@ +//go:build windows +// +build windows + +package defaults + +import ( + "fmt" + "os" + "path/filepath" + + k3swindows "github.com/k3s-io/k3s/pkg/agent/util/acl" + "github.com/pkg/errors" + rke2windows "github.com/rancher/rke2/pkg/windows" + "golang.org/x/sys/windows" +) + +func createDataDir(dataDir string, perm os.FileMode) error { + _, err := os.Stat(dataDir) + doesNotExist := errors.Is(err, os.ErrNotExist) + if err != nil && !doesNotExist { + return fmt.Errorf("failed to create data directory %s: %v", dataDir, err) + } + + if !doesNotExist { + return nil + } + + // only set restrictive ACLs the dataDir, not the full path + path, _ := filepath.Split(dataDir) + if os.MkdirAll(path, perm) != nil { + return fmt.Errorf("failed to create data directory %s: %v", dataDir, err) + } + + if err = rke2windows.Mkdir(dataDir, []windows.EXPLICIT_ACCESS{ + k3swindows.GrantSid(windows.GENERIC_ALL, k3swindows.LocalSystemSID()), + k3swindows.GrantSid(windows.GENERIC_ALL, k3swindows.BuiltinAdministratorsSID()), + }...); err != nil { + return fmt.Errorf("failed to create data directory %s: %v", dataDir, err) + } + + return nil +} diff --git a/pkg/windows/utils.go b/pkg/windows/utils.go index 772de9f3f1..fa4ab349ac 100644 --- a/pkg/windows/utils.go +++ b/pkg/windows/utils.go @@ -9,10 +9,12 @@ import ( "net" "net/http" "net/url" + "os" "regexp" "strings" "text/template" "time" + "unsafe" "github.com/Microsoft/hcsshim" wapi "github.com/iamacarpet/go-win64api" @@ -20,6 +22,7 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" opv1 "github.com/tigera/operator/api/v1" + "golang.org/x/sys/windows" "k8s.io/apimachinery/pkg/util/wait" ) @@ -344,3 +347,70 @@ func findInterface(ip string) (string, error) { return "", fmt.Errorf("no interface has the ip: %s", ip) } + +// TODO: Remove the below ACL logic in favor of the rancher/permissions repository once that has been created + +// Mkdir creates a directory using the given explicitAccess rules for a number of SIDs. If no windows.EXPLICIT_ACCESS +// rules are provided then the directory will inherit its ACL from the parent directory. If the specified +// directory already exists or another error is encountered, Mkdir will return false and the relevant error. +// Upon Successful creation of the directory, Mkdir will return 'true' and a nil error. +func Mkdir(name string, explicitAccess ...windows.EXPLICIT_ACCESS) error { + if name == "" { + return fmt.Errorf("must supply a directory name") + } + + // check if the file already exists + _, err := os.Stat(name) + if err == nil { + return nil + } + + sd, err := windows.NewSecurityDescriptor() + if err != nil { + return fmt.Errorf("failed to create security descriptor: %v", err) + } + + // if we haven't been provided DACL rules + // we should defer to the parent directory + inheritACL := explicitAccess == nil + if explicitAccess != nil && len(explicitAccess) != 0 { + acl, err := windows.ACLFromEntries(explicitAccess, nil) + if err != nil { + return fmt.Errorf("failed to create ACL from explicit access entries: %v", err) + } + + err = sd.SetDACL(acl, true, inheritACL) + if err != nil { + return fmt.Errorf("failed to configure DACL for security desctriptor: %v", 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) + if !inheritACL { + err = sd.SetControl(windows.SE_DACL_PROTECTED, windows.SE_DACL_PROTECTED) + if err != nil { + return fmt.Errorf("failed to configure protected DACL for security descriptor: %v", err) + } + } + + var securityAttribute windows.SecurityAttributes + securityAttribute.Length = uint32(unsafe.Sizeof(securityAttribute)) + inheritHandle := 1 + if !inheritACL { + inheritHandle = 0 + } + securityAttribute.InheritHandle = uint32(inheritHandle) + securityAttribute.SecurityDescriptor = sd + + namePntr, err := windows.UTF16PtrFromString(name) + if err != nil { + return err + } + + if err = windows.CreateDirectory(namePntr, &securityAttribute); err != nil { + return fmt.Errorf("failed to create directory with custom ACE: %v", err) + } + + return nil +}