diff --git a/util/syspolicy/handler_windows.go b/util/syspolicy/handler_windows.go index c259bf96c..668fd3db2 100644 --- a/util/syspolicy/handler_windows.go +++ b/util/syspolicy/handler_windows.go @@ -5,21 +5,72 @@ import ( "errors" + "fmt" + "tailscale.com/util/clientmetric" "tailscale.com/util/winutil" ) +var ( + windowsErrors = clientmetric.NewCounter("windows_mdm_setting_errors") + windowsAny = clientmetric.NewGauge("windows_mdm_setting_any") +) + type windowsHandler struct{} func init() { RegisterHandler(NewCachingHandler(windowsHandler{})) + + keyList := []struct { + isSet func(Key) bool + keys []Key + }{ + { + isSet: func(k Key) bool { + _, err := handler.ReadString(string(k)) + return err == nil + }, + keys: stringKeys, + }, + { + isSet: func(k Key) bool { + _, err := handler.ReadBoolean(string(k)) + return err == nil + }, + keys: boolKeys, + }, + { + isSet: func(k Key) bool { + _, err := handler.ReadUInt64(string(k)) + return err == nil + }, + keys: uint64Keys, + }, + } + + var anySet bool + for _, l := range keyList { + for _, k := range l.keys { + if !l.isSet(k) { + continue + } + clientmetric.NewGauge(fmt.Sprintf("windows_mdm_setting_%s", k)).Set(1) + anySet = true + } + } + if anySet { + windowsAny.Set(1) + } } func (windowsHandler) ReadString(key string) (string, error) { s, err := winutil.GetPolicyString(key) if errors.Is(err, winutil.ErrNoValue) { err = ErrNoSuchKey + } else if err != nil { + windowsErrors.Add(1) } + return s, err } @@ -27,6 +78,8 @@ func (windowsHandler) ReadUInt64(key string) (uint64, error) { value, err := winutil.GetPolicyInteger(key) if errors.Is(err, winutil.ErrNoValue) { err = ErrNoSuchKey + } else if err != nil { + windowsErrors.Add(1) } return value, err } @@ -35,6 +88,8 @@ func (windowsHandler) ReadBoolean(key string) (bool, error) { value, err := winutil.GetPolicyInteger(key) if errors.Is(err, winutil.ErrNoValue) { err = ErrNoSuchKey + } else if err != nil { + windowsErrors.Add(1) } return value != 0, err } diff --git a/util/syspolicy/policy_keys.go b/util/syspolicy/policy_keys.go index c90f7b5cc..75393f9b2 100644 --- a/util/syspolicy/policy_keys.go +++ b/util/syspolicy/policy_keys.go @@ -50,3 +50,33 @@ // The default is "user-decides" unless otherwise stated. PostureChecking Key = "PostureChecking" ) + +var stringKeys = []Key{ + ControlURL, + LogTarget, + Tailnet, + ExitNodeID, + ExitNodeIP, + EnableIncomingConnections, + EnableServerMode, + ExitNodeAllowLANAccess, + EnableTailscaleDNS, + EnableTailscaleSubnets, + AdminConsoleVisibility, + NetworkDevicesVisibility, + TestMenuVisibility, + UpdateMenuVisibility, + RunExitNodeVisibility, + PreferencesMenuVisibility, + ExitNodeMenuVisibility, + AutoUpdateVisibility, + KeyExpirationNoticeTime, + PostureChecking, +} + +var boolKeys = []Key{ + LogSCMInteractions, + FlushDNSOnSessionUnlock, +} + +var uint64Keys = []Key{}