diff --git a/comp/workloadselection/impl/workloadselection_windows.go b/comp/workloadselection/impl/workloadselection_windows.go index 44ccdfc7e311d7..b5ff79b81c5570 100644 --- a/comp/workloadselection/impl/workloadselection_windows.go +++ b/comp/workloadselection/impl/workloadselection_windows.go @@ -60,11 +60,14 @@ func setFileReadableByEveryone(path string) error { return fmt.Errorf("failed to get DACL: %w", err) } - // Only set the DACL, don't touch owner or group + // Set the explicit DACL and allow inheritance from the parent directory. + // Not using PROTECTED_DACL_SECURITY_INFORMATION so that the file inherits + // ACEs from the parent (SYSTEM:F, Admins:F, ddagentuser:F via CREATOR OWNER), + // ensuring the agent retains write access for subsequent config updates. return windows.SetNamedSecurityInfo( path, windows.SE_FILE_OBJECT, - windows.DACL_SECURITY_INFORMATION|windows.PROTECTED_DACL_SECURITY_INFORMATION, + windows.DACL_SECURITY_INFORMATION, nil, // owner - leave unchanged nil, // group - leave unchanged dacl, // DACL - set this diff --git a/comp/workloadselection/impl/workloadselection_windows_test.go b/comp/workloadselection/impl/workloadselection_windows_test.go new file mode 100644 index 00000000000000..789b841c338120 --- /dev/null +++ b/comp/workloadselection/impl/workloadselection_windows_test.go @@ -0,0 +1,37 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2025-present Datadog, Inc. + +//go:build windows + +package workloadselectionimpl + +import ( + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestSetFileReadableByEveryone_FileCanBeOverwritten(t *testing.T) { + dir := t.TempDir() + path := filepath.Join(dir, "test-policy.bin") + + // Create initial file + require.NoError(t, os.WriteFile(path, []byte("initial content"), 0644)) + + // Apply the ACL (this was previously making the file unwritable) + require.NoError(t, setFileReadableByEveryone(path)) + + // Verify the file can still be overwritten by the current user + err := os.WriteFile(path, []byte("updated content"), 0644) + assert.NoError(t, err, "file should be writable after setFileReadableByEveryone") + + // Verify the content was actually updated + content, err := os.ReadFile(path) + require.NoError(t, err) + assert.Equal(t, "updated content", string(content)) +} diff --git a/releasenotes/notes/wls-permissions-bugfix-107620b486590d65.yaml b/releasenotes/notes/wls-permissions-bugfix-107620b486590d65.yaml new file mode 100644 index 00000000000000..b7b42153cae44c --- /dev/null +++ b/releasenotes/notes/wls-permissions-bugfix-107620b486590d65.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - | + Fix a Windows file-permission issue that prevented workload selection + policy files from being updated after the initial write.