diff --git a/go.mod b/go.mod index 3c660088fba..23f226aba11 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.16.1-0.20240502205943-2f32059d43e6 - github.com/k3s-io/k3s v1.30.0-rc2.0.20240506181825-14549535f13c // master + github.com/k3s-io/k3s v1.30.1-0.20240516214027-1d22b6971fbf // 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 74c4bf2f76c..df9076aafe3 100644 --- a/go.sum +++ b/go.sum @@ -1151,8 +1151,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.16.1-0.20240502205943-2f32059d43e6 h1:2VcBFT2iPskZqNEVY5636Fk8NHiM/x4zQ9/h+f3WMSA= github.com/k3s-io/helm-controller v0.16.1-0.20240502205943-2f32059d43e6/go.mod h1:AcSxEhOIUgeVvBTnJOAwcezBZXtYew/RhKwO5xp3RlM= -github.com/k3s-io/k3s v1.30.0-rc2.0.20240506181825-14549535f13c h1:kTPmVDmVzBQVNY4REgkGHSb5LhGz7GL0K4lHssl6KQo= -github.com/k3s-io/k3s v1.30.0-rc2.0.20240506181825-14549535f13c/go.mod h1:LSHH7csUMTAoVfCtwtyyvBskZn31epLQMIv6AT+JqLQ= +github.com/k3s-io/k3s v1.30.1-0.20240516214027-1d22b6971fbf h1:UVNo8xt9qtRvN28aDfeauWUYTaY15sfmonQEFcS4nuk= +github.com/k3s-io/k3s v1.30.1-0.20240516214027-1d22b6971fbf/go.mod h1:LSHH7csUMTAoVfCtwtyyvBskZn31epLQMIv6AT+JqLQ= github.com/k3s-io/kine v0.11.8-0.20240430184817-f9ce6f8da97b h1:t3gQARoXVPqHkRXwYObNokrL+KU7/plVIjhXaNH6MUw= github.com/k3s-io/kine v0.11.8-0.20240430184817-f9ce6f8da97b/go.mod h1:TcTDRPVgcPQXL9E+lLXA1KVpHUxceN7xBICJUI2abPU= 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 1db87c2ec98..8b55d23abb8 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 00000000000..41f7aa15ff0 --- /dev/null +++ b/pkg/cli/defaults/defaults_linux.go @@ -0,0 +1,17 @@ +//go:build linux +// +build linux + +package defaults + +import ( + "os" + + "github.com/pkg/errors" +) + +func createDataDir(dataDir string, perm os.FileMode) error { + 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 00000000000..4834d13b065 --- /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 772de9f3f10..fa4ab349acd 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 +}