From 7cbcb94720ca7fef851ad8951455991bc78497bd Mon Sep 17 00:00:00 2001 From: Martin Angers Date: Thu, 12 Oct 2023 08:31:10 -0400 Subject: [PATCH] Return os settings of host even if only Windows MDM is enabled (#14469) #14383 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Changes file added for user-visible changes in `changes/` or `orbit/changes/`. See [Changes files](https://fleetdm.com/docs/contributing/committing-changes#changes-files) for more information. - [x] Added/updated tests - [x] Manual QA for all new/changed functionality (tested the fix with my reproduction setup) --- ...383-return-host-ossettings-for-winonly-mdm | 1 + server/mock/datastore_mock.go | 12 ++--- server/service/hosts.go | 36 +++++++------- server/service/hosts_test.go | 49 ++++++++++++++++++- 4 files changed, 74 insertions(+), 24 deletions(-) create mode 100644 changes/issue-14383-return-host-ossettings-for-winonly-mdm diff --git a/changes/issue-14383-return-host-ossettings-for-winonly-mdm b/changes/issue-14383-return-host-ossettings-for-winonly-mdm new file mode 100644 index 0000000000..21a1f8b8fd --- /dev/null +++ b/changes/issue-14383-return-host-ossettings-for-winonly-mdm @@ -0,0 +1 @@ +* Fixed a bug where the OS settings information with disk encryption status of Windows hosts was not returned when only the Windows MDM was enabled (and not the macOS one). diff --git a/server/mock/datastore_mock.go b/server/mock/datastore_mock.go index 2c85a98eb4..f419c17d14 100644 --- a/server/mock/datastore_mock.go +++ b/server/mock/datastore_mock.go @@ -1716,9 +1716,9 @@ type DataStore struct { MDMWindowsGetEnrolledDeviceWithDeviceIDFunc MDMWindowsGetEnrolledDeviceWithDeviceIDFunc MDMWindowsGetEnrolledDeviceWithDeviceIDFuncInvoked bool - + MDMWindowsDeleteEnrolledDeviceWithDeviceIDFunc MDMWindowsDeleteEnrolledDeviceWithDeviceIDFunc - MDMWindowsDeleteEnrolledDeviceWithDeviceIDFuncInvoked bool + MDMWindowsDeleteEnrolledDeviceWithDeviceIDFuncInvoked bool GetMDMWindowsBitLockerSummaryFunc GetMDMWindowsBitLockerSummaryFunc GetMDMWindowsBitLockerSummaryFuncInvoked bool @@ -4072,11 +4072,11 @@ func (s *DataStore) WSTEPAssociateCertHash(ctx context.Context, deviceUUID strin return s.WSTEPAssociateCertHashFunc(ctx, deviceUUID, hash) } -func (s *DataStore) MDMWindowsGetEnrolledDevice(ctx context.Context, mdmDeviceHWID string) (*fleet.MDMWindowsEnrolledDevice, error) { +func (s *DataStore) MDMWindowsGetEnrolledDevice(ctx context.Context, mdmDeviceID string) (*fleet.MDMWindowsEnrolledDevice, error) { s.mu.Lock() s.MDMWindowsGetEnrolledDeviceFuncInvoked = true s.mu.Unlock() - return s.MDMWindowsGetEnrolledDeviceFunc(ctx, mdmDeviceHWID) + return s.MDMWindowsGetEnrolledDeviceFunc(ctx, mdmDeviceID) } func (s *DataStore) MDMWindowsInsertEnrolledDevice(ctx context.Context, device *fleet.MDMWindowsEnrolledDevice) error { @@ -4086,11 +4086,11 @@ func (s *DataStore) MDMWindowsInsertEnrolledDevice(ctx context.Context, device * return s.MDMWindowsInsertEnrolledDeviceFunc(ctx, device) } -func (s *DataStore) MDMWindowsDeleteEnrolledDevice(ctx context.Context, mdmDeviceHWID string) error { +func (s *DataStore) MDMWindowsDeleteEnrolledDevice(ctx context.Context, mdmDeviceID string) error { s.mu.Lock() s.MDMWindowsDeleteEnrolledDeviceFuncInvoked = true s.mu.Unlock() - return s.MDMWindowsDeleteEnrolledDeviceFunc(ctx, mdmDeviceHWID) + return s.MDMWindowsDeleteEnrolledDeviceFunc(ctx, mdmDeviceID) } func (s *DataStore) MDMWindowsGetEnrolledDeviceWithDeviceID(ctx context.Context, mdmDeviceID string) (*fleet.MDMWindowsEnrolledDevice, error) { diff --git a/server/service/hosts.go b/server/service/hosts.go index 0055aa66a4..4c4dda1dec 100644 --- a/server/service/hosts.go +++ b/server/service/hosts.go @@ -917,11 +917,11 @@ func (svc *Service) getHostDetails(ctx context.Context, host *fleet.Host, opts f } var profiles []fleet.HostMDMAppleProfile - if ac.MDM.EnabledAndConfigured { + if ac.MDM.EnabledAndConfigured || ac.MDM.WindowsEnabledAndConfigured { host.MDM.OSSettings = &fleet.HostMDMOSSettings{} switch host.Platform { case "windows": - if license.IsPremium(ctx) { + if ac.MDM.WindowsEnabledAndConfigured && license.IsPremium(ctx) { bls, err := svc.ds.GetMDMWindowsBitLockerStatus(ctx, host) if err != nil { return nil, ctxerr.Wrap(ctx, err, "get host mdm bitlocker status") @@ -929,22 +929,24 @@ func (svc *Service) getHostDetails(ctx context.Context, host *fleet.Host, opts f host.MDM.OSSettings.DiskEncryption.Status = bls } case "darwin": - profs, err := svc.ds.GetHostMDMProfiles(ctx, host.UUID) - if err != nil { - return nil, ctxerr.Wrap(ctx, err, "get host mdm profiles") - } - - // determine disk encryption and action required here based on profiles and - // raw decryptable key status. - host.MDM.DetermineMacOSDiskEncryptionStatus(profs, mobileconfig.FleetFileVaultPayloadIdentifier) - host.MDM.OSSettings.DiskEncryption.Status = host.MDM.MacOSSettings.DiskEncryption - - for _, p := range profs { - if p.Identifier == mobileconfig.FleetFileVaultPayloadIdentifier { - p.Status = host.MDM.ProfileStatusFromDiskEncryptionState(p.Status) + if ac.MDM.EnabledAndConfigured { + profs, err := svc.ds.GetHostMDMProfiles(ctx, host.UUID) + if err != nil { + return nil, ctxerr.Wrap(ctx, err, "get host mdm profiles") + } + + // determine disk encryption and action required here based on profiles and + // raw decryptable key status. + host.MDM.DetermineMacOSDiskEncryptionStatus(profs, mobileconfig.FleetFileVaultPayloadIdentifier) + host.MDM.OSSettings.DiskEncryption.Status = host.MDM.MacOSSettings.DiskEncryption + + for _, p := range profs { + if p.Identifier == mobileconfig.FleetFileVaultPayloadIdentifier { + p.Status = host.MDM.ProfileStatusFromDiskEncryptionState(p.Status) + } + p.Detail = fleet.HostMDMProfileDetail(p.Detail).Message() + profiles = append(profiles, p) } - p.Detail = fleet.HostMDMProfileDetail(p.Detail).Message() - profiles = append(profiles, p) } } } diff --git a/server/service/hosts_test.go b/server/service/hosts_test.go index cd7a5dc993..8cd1e30e5b 100644 --- a/server/service/hosts_test.go +++ b/server/service/hosts_test.go @@ -394,7 +394,7 @@ func TestHostDetailsOSSettings(t *testing.T) { ds.GetHostMDMProfilesFuncInvoked = false ds.AppConfigFunc = func(ctx context.Context) (*fleet.AppConfig, error) { - return &fleet.AppConfig{MDM: fleet.MDM{EnabledAndConfigured: true}}, nil + return &fleet.AppConfig{MDM: fleet.MDM{EnabledAndConfigured: true, WindowsEnabledAndConfigured: true}}, nil } ds.GetMDMWindowsBitLockerStatusFunc = func(ctx context.Context, host *fleet.Host) (*fleet.DiskEncryptionStatus, error) { if c.wantStatus == "" { @@ -444,6 +444,53 @@ func TestHostDetailsOSSettings(t *testing.T) { } } +func TestHostDetailsOSSettingsWindowsOnly(t *testing.T) { + ds := new(mock.Store) + svc := &Service{ds: ds} + + ds.ListLabelsForHostFunc = func(ctx context.Context, hid uint) ([]*fleet.Label, error) { + return nil, nil + } + ds.ListPacksForHostFunc = func(ctx context.Context, hid uint) ([]*fleet.Pack, error) { + return nil, nil + } + ds.LoadHostSoftwareFunc = func(ctx context.Context, host *fleet.Host, includeCVEScores bool) error { + return nil + } + ds.ListPoliciesForHostFunc = func(ctx context.Context, host *fleet.Host) ([]*fleet.HostPolicy, error) { + return nil, nil + } + ds.ListHostBatteriesFunc = func(ctx context.Context, hostID uint) ([]*fleet.HostBattery, error) { + return nil, nil + } + ds.GetHostMDMMacOSSetupFunc = func(ctx context.Context, hid uint) (*fleet.HostMDMMacOSSetup, error) { + return nil, nil + } + ds.AppConfigFunc = func(ctx context.Context) (*fleet.AppConfig, error) { + return &fleet.AppConfig{MDM: fleet.MDM{WindowsEnabledAndConfigured: true}}, nil + } + ds.GetMDMWindowsBitLockerStatusFunc = func(ctx context.Context, host *fleet.Host) (*fleet.DiskEncryptionStatus, error) { + verified := fleet.DiskEncryptionVerified + return &verified, nil + } + ds.GetHostMDMProfilesFunc = func(ctx context.Context, uuid string) ([]fleet.HostMDMAppleProfile, error) { + return nil, nil + } + + ctx := license.NewContext(context.Background(), &fleet.LicenseInfo{Tier: fleet.TierPremium}) + hostDetail, err := svc.getHostDetails(test.UserContext(ctx, test.UserAdmin), &fleet.Host{ID: 42, Platform: "windows"}, fleet.HostDetailOptions{ + IncludeCVEScores: false, + IncludePolicies: false, + }) + require.NoError(t, err) + require.NotNil(t, hostDetail) + require.True(t, ds.AppConfigFuncInvoked) + require.False(t, ds.GetHostMDMProfilesFuncInvoked) + require.True(t, ds.GetMDMWindowsBitLockerStatusFuncInvoked) + require.NotNil(t, hostDetail.MDM.OSSettings.DiskEncryption.Status) + require.Equal(t, fleet.DiskEncryptionVerified, *hostDetail.MDM.OSSettings.DiskEncryption.Status) +} + func TestHostAuth(t *testing.T) { ds := new(mock.Store) svc, ctx := newTestService(t, ds, nil, nil)