diff --git a/ee/server/service/teams.go b/ee/server/service/teams.go index 20a526197bf5..eded9b4788ac 100644 --- a/ee/server/service/teams.go +++ b/ee/server/service/teams.go @@ -1516,15 +1516,15 @@ func unmarshalWithGlobalDefaults(b *json.RawMessage) (fleet.Features, error) { } func (svc *Service) updateTeamMDMDiskEncryption(ctx context.Context, tm *fleet.Team, enable *bool) error { - var didUpdate, didUpdateMacOSDiskEncryption bool + var didUpdate bool if enable != nil { - if svc.config.Server.PrivateKey == "" { - return ctxerr.New(ctx, "Missing required private key. Learn how to configure the private key here: https://fleetdm.com/learn-more-about/fleet-server-private-key") - } if tm.Config.MDM.EnableDiskEncryption != *enable { + if *enable && svc.config.Server.PrivateKey == "" { + return ctxerr.New(ctx, "Missing required private key. Learn how to configure the private key here: https://fleetdm.com/learn-more-about/fleet-server-private-key") + } + tm.Config.MDM.EnableDiskEncryption = *enable didUpdate = true - didUpdateMacOSDiskEncryption = true } } @@ -1537,13 +1537,7 @@ func (svc *Service) updateTeamMDMDiskEncryption(ctx context.Context, tm *fleet.T if err != nil { return err } - - // macOS-specific stuff. For legacy reasons we check if apple is configured - // via `appCfg.MDM.EnabledAndConfigured` - // - // TODO: is there a missing bitlocker activity feed item? (see same TODO on - // other methods that deal with disk encryption) - if appCfg.MDM.EnabledAndConfigured && didUpdateMacOSDiskEncryption { + if appCfg.MDM.EnabledAndConfigured { var act fleet.ActivityDetails if tm.Config.MDM.EnableDiskEncryption { act = fleet.ActivityTypeEnabledMacosDiskEncryption{TeamID: &tm.ID, TeamName: &tm.Name} diff --git a/frontend/services/entities/mdm.ts b/frontend/services/entities/mdm.ts index ec7499390b40..aab412772ae7 100644 --- a/frontend/services/entities/mdm.ts +++ b/frontend/services/entities/mdm.ts @@ -168,7 +168,7 @@ const mdmService = { }, getProfilesStatusSummary: (teamId: number) => { - let { MDM_PROFILES_STATUS_SUMMARY: path } = endpoints; + let { PROFILES_STATUS_SUMMARY: path } = endpoints; if (teamId) { path = `${path}?${buildQueryStringFromParams({ team_id: teamId })}`; diff --git a/frontend/utilities/endpoints.ts b/frontend/utilities/endpoints.ts index 196345bf2bbe..a1acd94adee5 100644 --- a/frontend/utilities/endpoints.ts +++ b/frontend/utilities/endpoints.ts @@ -114,7 +114,7 @@ export default { MDM_PROFILE: (id: string) => `/${API_VERSION}/fleet/mdm/profiles/${id}`, MDM_UPDATE_APPLE_SETTINGS: `/${API_VERSION}/fleet/mdm/apple/settings`, - MDM_PROFILES_STATUS_SUMMARY: `/${API_VERSION}/fleet/mdm/profiles/summary`, + PROFILES_STATUS_SUMMARY: `/${API_VERSION}/fleet/configuration_profiles/summary`, MDM_DISK_ENCRYPTION_SUMMARY: `/${API_VERSION}/fleet/mdm/disk_encryption/summary`, MDM_APPLE_SSO: `/${API_VERSION}/fleet/mdm/sso`, MDM_APPLE_ENROLLMENT_PROFILE: (token: string, ref?: string) => { diff --git a/server/datastore/mysql/app_configs.go b/server/datastore/mysql/app_configs.go index 8f8d708eb908..5de25d4d0006 100644 --- a/server/datastore/mysql/app_configs.go +++ b/server/datastore/mysql/app_configs.go @@ -274,7 +274,7 @@ func (ds *Datastore) AggregateEnrollSecretPerTeam(ctx context.Context) ([]*fleet return secrets, nil } -func (ds *Datastore) getConfigEnableDiskEncryption(ctx context.Context, teamID *uint) (bool, error) { +func (ds *Datastore) GetConfigEnableDiskEncryption(ctx context.Context, teamID *uint) (bool, error) { if teamID != nil && *teamID > 0 { tc, err := ds.TeamMDMConfig(ctx, *teamID) if err != nil { diff --git a/server/datastore/mysql/app_configs_test.go b/server/datastore/mysql/app_configs_test.go index dc0d4b1c9d9d..46df41010be8 100644 --- a/server/datastore/mysql/app_configs_test.go +++ b/server/datastore/mysql/app_configs_test.go @@ -449,7 +449,7 @@ func testGetConfigEnableDiskEncryption(t *testing.T, ds *Datastore) { require.NoError(t, err) require.False(t, ac.MDM.EnableDiskEncryption.Value) - enabled, err := ds.getConfigEnableDiskEncryption(ctx, nil) + enabled, err := ds.GetConfigEnableDiskEncryption(ctx, nil) require.NoError(t, err) require.False(t, enabled) @@ -461,7 +461,7 @@ func testGetConfigEnableDiskEncryption(t *testing.T, ds *Datastore) { require.NoError(t, err) require.True(t, ac.MDM.EnableDiskEncryption.Value) - enabled, err = ds.getConfigEnableDiskEncryption(ctx, nil) + enabled, err = ds.GetConfigEnableDiskEncryption(ctx, nil) require.NoError(t, err) require.True(t, enabled) @@ -474,7 +474,7 @@ func testGetConfigEnableDiskEncryption(t *testing.T, ds *Datastore) { require.NotNil(t, tm) require.False(t, tm.Config.MDM.EnableDiskEncryption) - enabled, err = ds.getConfigEnableDiskEncryption(ctx, &team1.ID) + enabled, err = ds.GetConfigEnableDiskEncryption(ctx, &team1.ID) require.NoError(t, err) require.False(t, enabled) diff --git a/server/datastore/mysql/hosts.go b/server/datastore/mysql/hosts.go index b2f7f3a650ed..7bb7f11f7ca0 100644 --- a/server/datastore/mysql/hosts.go +++ b/server/datastore/mysql/hosts.go @@ -1218,7 +1218,7 @@ func (ds *Datastore) applyHostFilters( return "", nil, ctxerr.Wrap(ctx, err, "building query to filter macOS settings status") } sqlStmt, whereParams = filterHostsByMacOSDiskEncryptionStatus(sqlStmt, opt, whereParams) - if enableDiskEncryption, err := ds.getConfigEnableDiskEncryption(ctx, opt.TeamFilter); err != nil { + if enableDiskEncryption, err := ds.GetConfigEnableDiskEncryption(ctx, opt.TeamFilter); err != nil { if errors.Is(err, sql.ErrNoRows) { return "", nil, ctxerr.Wrap( ctx, &fleet.BadRequestError{ diff --git a/server/datastore/mysql/labels.go b/server/datastore/mysql/labels.go index 21c4e0eb9402..4111c81b6ee0 100644 --- a/server/datastore/mysql/labels.go +++ b/server/datastore/mysql/labels.go @@ -662,7 +662,7 @@ func (ds *Datastore) applyHostLabelFilters(ctx context.Context, filter fleet.Tea } query, whereParams = filterHostsByMacOSDiskEncryptionStatus(query, opt, whereParams) query, whereParams = filterHostsByMDMBootstrapPackageStatus(query, opt, whereParams) - if enableDiskEncryption, err := ds.getConfigEnableDiskEncryption(ctx, opt.TeamFilter); err != nil { + if enableDiskEncryption, err := ds.GetConfigEnableDiskEncryption(ctx, opt.TeamFilter); err != nil { return "", nil, err } else if opt.OSSettingsFilter.IsValid() { query, whereParams, err = ds.filterHostsByOSSettingsStatus(query, opt, whereParams, enableDiskEncryption) diff --git a/server/datastore/mysql/microsoft_mdm.go b/server/datastore/mysql/microsoft_mdm.go index 9e773afddb06..e846ef8af79e 100644 --- a/server/datastore/mysql/microsoft_mdm.go +++ b/server/datastore/mysql/microsoft_mdm.go @@ -585,7 +585,7 @@ AND ( } func (ds *Datastore) GetMDMWindowsBitLockerSummary(ctx context.Context, teamID *uint) (*fleet.MDMWindowsBitLockerSummary, error) { - enabled, err := ds.getConfigEnableDiskEncryption(ctx, teamID) + enabled, err := ds.GetConfigEnableDiskEncryption(ctx, teamID) if err != nil { return nil, err } @@ -655,7 +655,7 @@ func (ds *Datastore) GetMDMWindowsBitLockerStatus(ctx context.Context, host *fle return nil, nil } - enabled, err := ds.getConfigEnableDiskEncryption(ctx, host.TeamID) + enabled, err := ds.GetConfigEnableDiskEncryption(ctx, host.TeamID) if err != nil { return nil, err } @@ -887,7 +887,7 @@ func subqueryHostsMDMWindowsOSSettingsStatusVerified() (string, []interface{}, e } func (ds *Datastore) GetMDMWindowsProfilesSummary(ctx context.Context, teamID *uint) (*fleet.MDMProfilesSummary, error) { - includeBitLocker, err := ds.getConfigEnableDiskEncryption(ctx, teamID) + includeBitLocker, err := ds.GetConfigEnableDiskEncryption(ctx, teamID) if err != nil { return nil, err } diff --git a/server/fleet/datastore.go b/server/fleet/datastore.go index 6dfaae64b248..f0e2d99871c0 100644 --- a/server/fleet/datastore.go +++ b/server/fleet/datastore.go @@ -899,6 +899,7 @@ type Datastore interface { GetHostEmails(ctx context.Context, hostUUID string, source string) ([]string, error) SetOrUpdateHostDisksSpace(ctx context.Context, hostID uint, gigsAvailable, percentAvailable, gigsTotal float64) error + GetConfigEnableDiskEncryption(ctx context.Context, teamID *uint) (bool, error) SetOrUpdateHostDisksEncryption(ctx context.Context, hostID uint, encrypted bool) error // SetOrUpdateHostDiskEncryptionKey sets the base64, encrypted key for // a host diff --git a/server/fleet/mdm.go b/server/fleet/mdm.go index 55e28bc7b945..4d3e09f68ec8 100644 --- a/server/fleet/mdm.go +++ b/server/fleet/mdm.go @@ -310,8 +310,8 @@ type MDMDiskEncryptionSummary struct { RemovingEnforcement MDMPlatformsCounts `db:"removing_enforcement" json:"removing_enforcement"` } -// MDMProfilesSummary reports the number of hosts being managed with MDM configuration -// profiles. Each host may be counted in only one of four mutually-exclusive categories: +// MDMProfilesSummary reports the number of hosts being managed with configuration +// profiles and/or disk encryption. Each host may be counted in only one of four mutually-exclusive categories: // Failed, Pending, Verifying, or Verified. type MDMProfilesSummary struct { // Verified includes each host where Fleet has verified the installation of all of the diff --git a/server/fleet/service.go b/server/fleet/service.go index ad12547a1d5f..7e9f7c973cbb 100644 --- a/server/fleet/service.go +++ b/server/fleet/service.go @@ -1059,6 +1059,11 @@ type Service interface { // Returns empty status if the host is not a supported Linux host LinuxHostDiskEncryptionStatus(ctx context.Context, host Host) (HostMDMDiskEncryption, error) + // GetMDMLinuxProfilesSummary summarizes the current status of Linux disk encryption for + // the provided team (or hosts without a team if teamId is nil), or returns zeroes if disk + // encryption is not enforced on the selected team + GetMDMLinuxProfilesSummary(ctx context.Context, teamId *uint) (MDMProfilesSummary, error) + /////////////////////////////////////////////////////////////////////////////// // Common MDM diff --git a/server/mock/datastore_mock.go b/server/mock/datastore_mock.go index 6d8fbd885676..1dfb9436612b 100644 --- a/server/mock/datastore_mock.go +++ b/server/mock/datastore_mock.go @@ -635,6 +635,8 @@ type GetHostEmailsFunc func(ctx context.Context, hostUUID string, source string) type SetOrUpdateHostDisksSpaceFunc func(ctx context.Context, hostID uint, gigsAvailable float64, percentAvailable float64, gigsTotal float64) error +type GetConfigEnableDiskEncryptionFunc func(ctx context.Context, teamID *uint) (bool, error) + type SetOrUpdateHostDisksEncryptionFunc func(ctx context.Context, hostID uint, encrypted bool) error type SetOrUpdateHostDiskEncryptionKeyFunc func(ctx context.Context, hostID uint, encryptedBase64Key string, clientError string, decryptable *bool) error @@ -2087,6 +2089,9 @@ type DataStore struct { SetOrUpdateHostDisksSpaceFunc SetOrUpdateHostDisksSpaceFunc SetOrUpdateHostDisksSpaceFuncInvoked bool + GetConfigEnableDiskEncryptionFunc GetConfigEnableDiskEncryptionFunc + GetConfigEnableDiskEncryptionFuncInvoked bool + SetOrUpdateHostDisksEncryptionFunc SetOrUpdateHostDisksEncryptionFunc SetOrUpdateHostDisksEncryptionFuncInvoked bool @@ -5034,6 +5039,13 @@ func (s *DataStore) SetOrUpdateHostDisksSpace(ctx context.Context, hostID uint, return s.SetOrUpdateHostDisksSpaceFunc(ctx, hostID, gigsAvailable, percentAvailable, gigsTotal) } +func (s *DataStore) GetConfigEnableDiskEncryption(ctx context.Context, teamID *uint) (bool, error) { + s.mu.Lock() + s.GetConfigEnableDiskEncryptionFuncInvoked = true + s.mu.Unlock() + return s.GetConfigEnableDiskEncryptionFunc(ctx, teamID) +} + func (s *DataStore) SetOrUpdateHostDisksEncryption(ctx context.Context, hostID uint, encrypted bool) error { s.mu.Lock() s.SetOrUpdateHostDisksEncryptionFuncInvoked = true diff --git a/server/service/appconfig.go b/server/service/appconfig.go index ad8778b57035..030c2c650202 100644 --- a/server/service/appconfig.go +++ b/server/service/appconfig.go @@ -416,7 +416,7 @@ func (svc *Service) ModifyAppConfig(ctx context.Context, p []byte, applyOpts fle // 1. To get the JSON value from the database // 2. To update fields with the incoming values if newAppConfig.MDM.EnableDiskEncryption.Valid { - if svc.config.Server.PrivateKey == "" { + if newAppConfig.MDM.EnableDiskEncryption.Value && svc.config.Server.PrivateKey == "" { return nil, ctxerr.New(ctx, "Missing required private key. Learn how to configure the private key here: https://fleetdm.com/learn-more-about/fleet-server-private-key") } appConfig.MDM.EnableDiskEncryption = newAppConfig.MDM.EnableDiskEncryption diff --git a/server/service/apple_mdm.go b/server/service/apple_mdm.go index b314d6189920..04ea557deb08 100644 --- a/server/service/apple_mdm.go +++ b/server/service/apple_mdm.go @@ -2152,12 +2152,15 @@ func (svc *Service) updateAppConfigMDMDiskEncryption(ctx context.Context, enable return err } - var didUpdate, didUpdateMacOSDiskEncryption bool + var didUpdate bool if enabled != nil { if ac.MDM.EnableDiskEncryption.Value != *enabled { + if *enabled && svc.config.Server.PrivateKey == "" { + return ctxerr.New(ctx, "Missing required private key. Learn how to configure the private key here: https://fleetdm.com/learn-more-about/fleet-server-private-key") + } + ac.MDM.EnableDiskEncryption = optjson.SetBool(*enabled) didUpdate = true - didUpdateMacOSDiskEncryption = true } } @@ -2165,7 +2168,7 @@ func (svc *Service) updateAppConfigMDMDiskEncryption(ctx context.Context, enable if err := svc.ds.SaveAppConfig(ctx, ac); err != nil { return err } - if didUpdateMacOSDiskEncryption { + if ac.MDM.EnabledAndConfigured { // if macOS MDM is configured, set up FileVault escrow var act fleet.ActivityDetails if ac.MDM.EnableDiskEncryption.Value { act = fleet.ActivityTypeEnabledMacosDiskEncryption{} diff --git a/server/service/integration_core_test.go b/server/service/integration_core_test.go index 999b6bfb34d6..0dfab1f02f1c 100644 --- a/server/service/integration_core_test.go +++ b/server/service/integration_core_test.go @@ -8638,6 +8638,11 @@ func (s *integrationTestSuite) TestGetHostDiskEncryption() { require.Equal(t, hostLin.ID, getHostResp.Host.ID) require.True(t, *getHostResp.Host.DiskEncryptionEnabled) + // should succeed as we no longer require MDM to access this endpoint, as Linux encryption doesn't require MDM + var profiles getMDMProfilesSummaryResponse + s.DoJSON("GET", "/api/latest/fleet/configuration_profiles/summary", getMDMProfilesSummaryRequest{}, http.StatusOK, &profiles) + s.DoJSON("GET", "/api/latest/fleet/mdm/profiles/summary", getMDMProfilesSummaryRequest{}, http.StatusOK, &profiles) + // set unencrypted for all hosts require.NoError(t, s.ds.SetOrUpdateHostDisksEncryption(context.Background(), hostWin.ID, false)) require.NoError(t, s.ds.SetOrUpdateHostDisksEncryption(context.Background(), hostMac.ID, false)) @@ -8653,7 +8658,7 @@ func (s *integrationTestSuite) TestGetHostDiskEncryption() { require.Equal(t, hostMac.ID, getHostResp.Host.ID) require.False(t, *getHostResp.Host.DiskEncryptionEnabled) - // Linux does not return false, it omits the field when false + // Linux may omit the field when false getHostResp = getHostResponse{} s.DoJSON("GET", fmt.Sprintf("/api/latest/fleet/hosts/%d", hostLin.ID), nil, http.StatusOK, &getHostResp) require.Equal(t, hostLin.ID, getHostResp.Host.ID) diff --git a/server/service/integration_enterprise_test.go b/server/service/integration_enterprise_test.go index 649d0b5912d0..25b51c317a0d 100644 --- a/server/service/integration_enterprise_test.go +++ b/server/service/integration_enterprise_test.go @@ -2881,6 +2881,96 @@ func (s *integrationEnterpriseTestSuite) TestAppleOSUpdatesTeamConfig() { }, http.StatusUnprocessableEntity, &tmResp) } +func (s *integrationEnterpriseTestSuite) TestLinuxDiskEncryption() { + t := s.T() + + // create a Linux host + noTeamHost, err := s.ds.NewHost(context.Background(), &fleet.Host{ + DetailUpdatedAt: time.Now(), + LabelUpdatedAt: time.Now(), + PolicyUpdatedAt: time.Now(), + SeenTime: time.Now(), + NodeKey: ptr.String(strings.ReplaceAll(t.Name(), "/", "_") + "3"), + OsqueryHostID: ptr.String(strings.ReplaceAll(t.Name(), "/", "_") + "3"), + UUID: t.Name() + "3", + Hostname: t.Name() + "foo3.local", + PrimaryIP: "192.168.1.3", + PrimaryMac: "30-65-EC-6F-C4-60", + Platform: "ubuntu", + OSVersion: "Ubuntu 22.04", + }) + require.NoError(t, err) + team, err := s.ds.NewTeam(context.Background(), &fleet.Team{Name: "A team"}) + require.NoError(t, err) + teamID := ptr.Uint(team.ID) + teamHost, err := s.ds.NewHost(context.Background(), &fleet.Host{ + DetailUpdatedAt: time.Now(), + LabelUpdatedAt: time.Now(), + PolicyUpdatedAt: time.Now(), + SeenTime: time.Now(), + NodeKey: ptr.String(strings.ReplaceAll(t.Name(), "/", "_") + "2"), + OsqueryHostID: ptr.String(strings.ReplaceAll(t.Name(), "/", "_") + "2"), + UUID: t.Name() + "2", + Hostname: t.Name() + "foo2.local", + PrimaryIP: "192.168.1.2", + PrimaryMac: "30-65-EC-6F-C4-59", + Platform: "rhel", + OSVersion: "Fedora 38.0", + TeamID: teamID, + }) + require.NoError(t, err) + + // NO TEAM // + + // config profiles endpoint should work but show all zeroes + var profileSummary getMDMProfilesSummaryResponse + s.DoJSON("GET", "/api/latest/fleet/configuration_profiles/summary", getMDMProfilesSummaryRequest{}, http.StatusOK, &profileSummary) + require.Equal(t, fleet.MDMProfilesSummary{}, profileSummary.MDMProfilesSummary) + + // set encrypted for host + require.NoError(t, s.ds.SetOrUpdateHostDisksEncryption(context.Background(), noTeamHost.ID, true)) + + // should still show zeroes + s.DoJSON("GET", "/api/latest/fleet/configuration_profiles/summary", getMDMProfilesSummaryRequest{}, http.StatusOK, &profileSummary) + require.Equal(t, fleet.MDMProfilesSummary{}, profileSummary.MDMProfilesSummary) + + // turn on disk encryption enforcement + s.Do("POST", "/api/latest/fleet/disk_encryption", updateDiskEncryptionRequest{EnableDiskEncryption: true}, http.StatusNoContent) + + // should show the Linux host as pending + s.DoJSON("GET", "/api/latest/fleet/configuration_profiles/summary", getMDMProfilesSummaryRequest{}, http.StatusOK, &profileSummary) + require.Equal(t, fleet.MDMProfilesSummary{Pending: 1}, profileSummary.MDMProfilesSummary) + + // encryption summary should succeed (Linux encryption doesn't require MDM) + var summary getMDMDiskEncryptionSummaryResponse + s.DoJSON("GET", "/api/latest/fleet/mdm/disk_encryption/summary", getMDMDiskEncryptionSummaryRequest{}, http.StatusOK, &summary) + s.DoJSON("GET", "/api/latest/fleet/disk_encryption", getMDMDiskEncryptionSummaryRequest{}, http.StatusOK, &summary) + // disk is encrypted but key hasn't been escrowed yet + require.Equal(t, fleet.MDMDiskEncryptionSummary{ActionRequired: fleet.MDMPlatformsCounts{Linux: 1}}, *summary.MDMDiskEncryptionSummary) + + // TEAM // + s.DoJSON("GET", "/api/latest/fleet/configuration_profiles/summary", getMDMProfilesSummaryRequest{TeamID: teamID}, http.StatusOK, &profileSummary) + require.Equal(t, fleet.MDMProfilesSummary{}, profileSummary.MDMProfilesSummary) + + // set encrypted for host + require.NoError(t, s.ds.SetOrUpdateHostDisksEncryption(context.Background(), teamHost.ID, true)) + + // should still show zeroes + s.DoJSON("GET", "/api/latest/fleet/configuration_profiles/summary", getMDMProfilesSummaryRequest{TeamID: teamID}, http.StatusOK, &profileSummary) + require.Equal(t, fleet.MDMProfilesSummary{}, profileSummary.MDMProfilesSummary) + + // turn on disk encryption enforcement for team + s.Do("POST", "/api/latest/fleet/disk_encryption", updateDiskEncryptionRequest{TeamID: teamID, EnableDiskEncryption: true}, http.StatusNoContent) + + // should show the Linux host as pending + s.DoJSON("GET", "/api/latest/fleet/configuration_profiles/summary", getMDMProfilesSummaryRequest{TeamID: teamID}, http.StatusOK, &profileSummary) + require.Equal(t, fleet.MDMProfilesSummary{Pending: 1}, profileSummary.MDMProfilesSummary) + + // encryption summary should show host as action required + s.DoJSON("GET", "/api/latest/fleet/disk_encryption", getMDMDiskEncryptionSummaryRequest{TeamID: teamID}, http.StatusOK, &summary) + require.Equal(t, fleet.MDMDiskEncryptionSummary{ActionRequired: fleet.MDMPlatformsCounts{Linux: 1}}, *summary.MDMDiskEncryptionSummary) +} + func (s *integrationEnterpriseTestSuite) TestListDevicePolicies() { t := s.T() ctx := context.Background() diff --git a/server/service/linux_mdm.go b/server/service/linux_mdm.go index d4ae8da27e2a..815e2bf04d7f 100644 --- a/server/service/linux_mdm.go +++ b/server/service/linux_mdm.go @@ -3,6 +3,7 @@ package service import ( "context" + "github.com/fleetdm/fleet/v4/server/contexts/ctxerr" "github.com/fleetdm/fleet/v4/server/fleet" ) @@ -42,3 +43,28 @@ func (svc *Service) LinuxHostDiskEncryptionStatus(ctx context.Context, host flee Status: &verified, }, nil } + +func (svc *Service) GetMDMLinuxProfilesSummary(ctx context.Context, teamId *uint) (summary fleet.MDMProfilesSummary, err error) { + if err = svc.authz.Authorize(ctx, fleet.MDMConfigProfileAuthz{TeamID: teamId}, fleet.ActionRead); err != nil { + return summary, ctxerr.Wrap(ctx, err) + } + + // Linux doesn't have configuration profiles, so if we aren't enforcing disk encryption we have nothing to report + includeDiskEncryptionStats, err := svc.ds.GetConfigEnableDiskEncryption(ctx, teamId) + if err != nil { + return summary, ctxerr.Wrap(ctx, err) + } else if !includeDiskEncryptionStats { + return summary, nil + } + + counts, err := svc.ds.GetLinuxDiskEncryptionSummary(ctx, teamId) + if err != nil { + return summary, ctxerr.Wrap(ctx, err) + } + + return fleet.MDMProfilesSummary{ + Verified: counts.Verified, + Pending: counts.ActionRequired, + Failed: counts.Failed, + }, nil +} diff --git a/server/service/mdm.go b/server/service/mdm.go index 12876b95ddd7..8ee18146311c 100644 --- a/server/service/mdm.go +++ b/server/service/mdm.go @@ -907,7 +907,8 @@ func (svc *Service) GetMDMDiskEncryptionSummary(ctx context.Context, teamID *uin } //////////////////////////////////////////////////////////////////////////////// -// GET /mdm/profiles/summary +// GET /mdm/profiles/summary (deprecated) +// GET /configuration_profiles/summary //////////////////////////////////////////////////////////////////////////////// type getMDMProfilesSummaryRequest struct { @@ -935,10 +936,15 @@ func getMDMProfilesSummaryEndpoint(ctx context.Context, request interface{}, svc return &getMDMProfilesSummaryResponse{Err: err}, nil } - res.Verified = as.Verified + ws.Verified + ls, err := svc.GetMDMLinuxProfilesSummary(ctx, req.TeamID) + if err != nil { + return &getMDMProfilesSummaryResponse{Err: err}, nil + } + + res.Verified = as.Verified + ws.Verified + ls.Verified res.Verifying = as.Verifying + ws.Verifying - res.Failed = as.Failed + ws.Failed - res.Pending = as.Pending + ws.Pending + res.Failed = as.Failed + ws.Failed + ls.Failed + res.Pending = as.Pending + ws.Pending + ls.Pending return &res, nil } @@ -2607,6 +2613,7 @@ func (svc *Service) UploadMDMAppleAPNSCert(ctx context.Context, cert io.ReadSeek } appCfg.MDM.EnabledAndConfigured = true + // TODO for each team (or no-team) set up for disk encryption, enable FileVault return svc.ds.SaveAppConfig(ctx, appCfg) }