AdGuardHome/internal/permcheck/check_windows.go

61 lines
1.6 KiB
Go

//go:build windows
package permcheck
import (
"context"
"log/slog"
"github.com/AdguardTeam/golibs/logutil/slogutil"
"golang.org/x/sys/windows"
)
// check is the Windows-specific implementation of [Check].
//
// Note, that it only checks the owner and the ACEs of the working directory.
// This is due to the assumption that the working directory ACEs are inherited
// by the underlying files and directories, since at least [migrate] sets this
// inheritance mode.
func check(ctx context.Context, l *slog.Logger, workDir, _, _, _, _ string) {
l = l.With("type", typeDir, "path", workDir)
dacl, owner, err := getSecurityInfo(workDir)
if err != nil {
l.ErrorContext(ctx, "getting security info", slogutil.KeyError, err)
return
}
if !owner.IsWellKnown(windows.WinBuiltinAdministratorsSid) {
l.WarnContext(ctx, "owner is not in administrators group")
}
err = rangeACEs(dacl, func(
hdr windows.ACE_HEADER,
mask windows.ACCESS_MASK,
sid *windows.SID,
) (cont bool) {
l.DebugContext(ctx, "checking access control entry", "mask", mask, "sid", sid)
warn := false
switch {
case hdr.AceType != windows.ACCESS_ALLOWED_ACE_TYPE:
// Skip non-allowed ACEs.
case !sid.IsWellKnown(windows.WinBuiltinAdministratorsSid):
// Non-administrator ACEs should not have any access rights.
warn = mask > 0
default:
// Administrators should full control access rights.
warn = mask&fullControlMask != fullControlMask
}
if warn {
l.WarnContext(ctx, "unexpected access control entry", "mask", mask, "sid", sid)
}
return true
})
if err != nil {
l.ErrorContext(ctx, "checking access control entries", slogutil.KeyError, err)
}
}