diff --git a/go.mod b/go.mod index 1fa573169d..e18d00e6d3 100644 --- a/go.mod +++ b/go.mod @@ -93,7 +93,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.28.9-rc1.0.20240423023449-289a1a3edbc0 // release-1.28 + github.com/k3s-io/k3s v1.28.10-0.20240517003114-1c33ee685998 // release-1.28 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 efa8119cdd..03360183b6 100644 --- a/go.sum +++ b/go.sum @@ -1197,8 +1197,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.28.9-rc1.0.20240423023449-289a1a3edbc0 h1:kzQidevLQ4cwCUSJ1FJ77wU03zwC9JxOrBOQ8uuNflw= -github.com/k3s-io/k3s v1.28.9-rc1.0.20240423023449-289a1a3edbc0/go.mod h1:g9XHLJTbg/B/KGodvdE2OBCDyxJSMsl2loM7zVDtYMw= +github.com/k3s-io/k3s v1.28.10-0.20240517003114-1c33ee685998 h1:OQIJ2Y+bQxwsk/0pmeqIaNlZKcIKhVezdbUsMs6ObM4= +github.com/k3s-io/k3s v1.28.10-0.20240517003114-1c33ee685998/go.mod h1:g9XHLJTbg/B/KGodvdE2OBCDyxJSMsl2loM7zVDtYMw= 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 +}