diff --git a/server/service/integration_core_test.go b/server/service/integration_core_test.go index a54387c34b..9479e3c17d 100644 --- a/server/service/integration_core_test.go +++ b/server/service/integration_core_test.go @@ -10794,7 +10794,7 @@ func (s *integrationTestSuite) TestDirectIngestScheduledQueryStats() { App: config.AppConfig{ EnableScheduledQueryStats: true, }, - }, appConfig, &appConfig.Features, osquery_utils.Integrations{}) + }, appConfig, &appConfig.Features, osquery_utils.Integrations{}, nil) task := async.NewTask(s.ds, nil, clock.C, config.OsqueryConfig{}) err = detailQueries["scheduled_query_stats"].DirectTaskIngestFunc( context.Background(), @@ -10949,7 +10949,7 @@ func (s *integrationTestSuite) TestDirectIngestSoftwareWithLongFields() { "installed_path": "C:\\Program Files\\Wireshark", }, } - detailQueries := osquery_utils.GetDetailQueries(context.Background(), config.FleetConfig{}, appConfig, &appConfig.Features, osquery_utils.Integrations{}) + detailQueries := osquery_utils.GetDetailQueries(context.Background(), config.FleetConfig{}, appConfig, &appConfig.Features, osquery_utils.Integrations{}, nil) err = detailQueries["software_windows"].DirectIngestFunc( context.Background(), log.NewNopLogger(), @@ -11085,7 +11085,7 @@ func (s *integrationTestSuite) TestDirectIngestSoftwareWithInvalidFields() { } var w1 bytes.Buffer logger1 := log.NewJSONLogger(&w1) - detailQueries := osquery_utils.GetDetailQueries(context.Background(), config.FleetConfig{}, appConfig, &appConfig.Features, osquery_utils.Integrations{}) + detailQueries := osquery_utils.GetDetailQueries(context.Background(), config.FleetConfig{}, appConfig, &appConfig.Features, osquery_utils.Integrations{}, nil) err = detailQueries["software_windows"].DirectIngestFunc( context.Background(), logger1, @@ -11120,7 +11120,7 @@ func (s *integrationTestSuite) TestDirectIngestSoftwareWithInvalidFields() { "last_opened_at": "foobar", }, } - detailQueries = osquery_utils.GetDetailQueries(context.Background(), config.FleetConfig{}, appConfig, &appConfig.Features, osquery_utils.Integrations{}) + detailQueries = osquery_utils.GetDetailQueries(context.Background(), config.FleetConfig{}, appConfig, &appConfig.Features, osquery_utils.Integrations{}, nil) var w2 bytes.Buffer logger2 := log.NewJSONLogger(&w2) err = detailQueries["software_windows"].DirectIngestFunc( @@ -11160,7 +11160,7 @@ func (s *integrationTestSuite) TestDirectIngestSoftwareWithInvalidFields() { } var w3 bytes.Buffer logger3 := log.NewJSONLogger(&w3) - detailQueries = osquery_utils.GetDetailQueries(context.Background(), config.FleetConfig{}, appConfig, &appConfig.Features, osquery_utils.Integrations{}) + detailQueries = osquery_utils.GetDetailQueries(context.Background(), config.FleetConfig{}, appConfig, &appConfig.Features, osquery_utils.Integrations{}, nil) err = detailQueries["software_windows"].DirectIngestFunc( context.Background(), logger3, diff --git a/server/service/integration_mdm_test.go b/server/service/integration_mdm_test.go index 0fe992f330..c3917cf91c 100644 --- a/server/service/integration_mdm_test.go +++ b/server/service/integration_mdm_test.go @@ -5487,7 +5487,7 @@ func (s *integrationMDMTestSuite) TestSSO() { ac, err := s.ds.AppConfig(context.Background()) require.NoError(t, err) - detailQueries := osquery_utils.GetDetailQueries(context.Background(), config.FleetConfig{}, ac, &ac.Features, osquery_utils.Integrations{}) + detailQueries := osquery_utils.GetDetailQueries(context.Background(), config.FleetConfig{}, ac, &ac.Features, osquery_utils.Integrations{}, nil) // simulate osquery reporting mdm information rows := []map[string]string{ @@ -5831,7 +5831,7 @@ func (s *integrationMDMTestSuite) TestSSOWithSCIM() { ac, err := s.ds.AppConfig(context.Background()) require.NoError(t, err) - detailQueries := osquery_utils.GetDetailQueries(context.Background(), config.FleetConfig{}, ac, &ac.Features, osquery_utils.Integrations{}) + detailQueries := osquery_utils.GetDetailQueries(context.Background(), config.FleetConfig{}, ac, &ac.Features, osquery_utils.Integrations{}, nil) // simulate osquery reporting mdm information, doesn't change anything rows := []map[string]string{ diff --git a/server/service/osquery.go b/server/service/osquery.go index 25ac73ce52..bf1ac2a1bf 100644 --- a/server/service/osquery.go +++ b/server/service/osquery.go @@ -176,9 +176,15 @@ func (svc *Service) EnrollAgent(ctx context.Context, enrollSecret, hostIdentifie } // Save enrollment details if provided - detailQueries := osquery_utils.GetDetailQueries(ctx, svc.config, appConfig, features, osquery_utils.Integrations{ - ConditionalAccessMicrosoft: false, // here we are just using a few ingestion functions, so no need to set. - }) + detailQueries := osquery_utils.GetDetailQueries( + ctx, + svc.config, + appConfig, + features, + osquery_utils.Integrations{ + ConditionalAccessMicrosoft: false, // here we are just using a few ingestion functions, so no need to set. + }, nil, // Ok ... the following queries do not need the Team's MDM config + ) save := false if r, ok := hostDetails["os_version"]; ok { err := detailQueries["os_version"].IngestFunc(ctx, svc.logger, host, []map[string]string{r}) @@ -722,12 +728,25 @@ func (svc *Service) detailQueriesForHost(ctx context.Context, host *fleet.Host) return nil, nil, ctxerr.Wrap(ctx, err, "read host features") } + var mdmTeamConfig *fleet.TeamMDM + if appConfig != nil && appConfig.MDM.EnabledAndConfigured && host.TeamID != nil { + mdmTeamConfig, err = svc.ds.TeamMDMConfig(ctx, *host.TeamID) + if err != nil { + return nil, nil, ctxerr.Wrap(ctx, err, "reading MDM Team Config") + } + } + queries = make(map[string]string) discovery = make(map[string]string) - detailQueries := osquery_utils.GetDetailQueries(ctx, svc.config, appConfig, features, osquery_utils.Integrations{ - ConditionalAccessMicrosoft: svc.hostRequiresConditionalAccessMicrosoftIngestion(ctx, host), - }) + detailQueries := osquery_utils.GetDetailQueries( + ctx, + svc.config, + appConfig, + features, + osquery_utils.Integrations{ + ConditionalAccessMicrosoft: svc.hostRequiresConditionalAccessMicrosoftIngestion(ctx, host), + }, mdmTeamConfig) for name, query := range detailQueries { if criticalQueriesOnly && !criticalDetailQueries[name] { continue @@ -1589,9 +1608,24 @@ func (svc *Service) directIngestDetailQuery(ctx context.Context, host *fleet.Hos return false, newOsqueryError("ingest detail query: " + err.Error()) } - detailQueries := osquery_utils.GetDetailQueries(ctx, svc.config, appConfig, features, osquery_utils.Integrations{ - ConditionalAccessMicrosoft: svc.hostRequiresConditionalAccessMicrosoftIngestion(ctx, host), - }) + var mdmTeamConfig *fleet.TeamMDM + if appConfig != nil && appConfig.MDM.EnabledAndConfigured && host.TeamID != nil { + mdmTeamConfig, err = svc.ds.TeamMDMConfig(ctx, *host.TeamID) + if err != nil { + return false, newOsqueryError("ingest detail query: " + err.Error()) + } + } + + detailQueries := osquery_utils.GetDetailQueries( + ctx, + svc.config, + appConfig, + features, + osquery_utils.Integrations{ + ConditionalAccessMicrosoft: svc.hostRequiresConditionalAccessMicrosoftIngestion(ctx, host), + }, + mdmTeamConfig, + ) query, ok := detailQueries[name] if !ok { return false, newOsqueryError("unknown detail query " + name) @@ -1733,9 +1767,25 @@ func (svc *Service) ingestDetailQuery(ctx context.Context, host *fleet.Host, nam return newOsqueryError("ingest detail query: " + err.Error()) } - detailQueries := osquery_utils.GetDetailQueries(ctx, svc.config, appConfig, features, osquery_utils.Integrations{ - ConditionalAccessMicrosoft: svc.hostRequiresConditionalAccessMicrosoftIngestion(ctx, host), - }) + var mdmTeamConfig *fleet.TeamMDM + if appConfig != nil && appConfig.MDM.EnabledAndConfigured && host.TeamID != nil { + mdmTeamConfig, err = svc.ds.TeamMDMConfig(ctx, *host.TeamID) + if err != nil { + return newOsqueryError("ingest detail query: " + err.Error()) + } + } + + detailQueries := osquery_utils.GetDetailQueries( + ctx, + svc.config, + appConfig, + features, + osquery_utils.Integrations{ + ConditionalAccessMicrosoft: svc.hostRequiresConditionalAccessMicrosoftIngestion(ctx, host), + }, + mdmTeamConfig, + ) + query, ok := detailQueries[name] if !ok { return newOsqueryError("unknown detail query " + name) diff --git a/server/service/osquery_test.go b/server/service/osquery_test.go index b064145f53..e6d40dfd63 100644 --- a/server/service/osquery_test.go +++ b/server/service/osquery_test.go @@ -256,16 +256,10 @@ func TestAgentOptionsForHost(t *testing.T) { assert.JSONEq(t, `{"foo":"override2"}`, string(opt)) } -var allDetailQueries = osquery_utils.GetDetailQueries( - context.Background(), - config.FleetConfig{Vulnerabilities: config.VulnerabilitiesConfig{DisableWinOSVulnerabilities: true}}, - nil, - &fleet.Features{ - EnableHostUsers: true, - EnableSoftwareInventory: true, - }, - osquery_utils.Integrations{}, -) +var allDetailQueries = osquery_utils.GetDetailQueries(context.Background(), config.FleetConfig{Vulnerabilities: config.VulnerabilitiesConfig{DisableWinOSVulnerabilities: true}}, nil, &fleet.Features{ + EnableHostUsers: true, + EnableSoftwareInventory: true, +}, osquery_utils.Integrations{}, nil) func expectedDetailQueriesForPlatform(platform string) map[string]osquery_utils.DetailQuery { queries := make(map[string]osquery_utils.DetailQuery) diff --git a/server/service/osquery_utils/gen_queries_doc.go b/server/service/osquery_utils/gen_queries_doc.go index 5d18dcaa28..666828ea2b 100644 --- a/server/service/osquery_utils/gen_queries_doc.go +++ b/server/service/osquery_utils/gen_queries_doc.go @@ -16,24 +16,22 @@ import ( ) func main() { - detailQueriesMap := osquery_utils.GetDetailQueries(context.Background(), - config.FleetConfig{ - Vulnerabilities: config.VulnerabilitiesConfig{ - DisableWinOSVulnerabilities: false, - }, - App: config.AppConfig{ - EnableScheduledQueryStats: true, - }, + detailQueriesMap := osquery_utils.GetDetailQueries(context.Background(), config.FleetConfig{ + Vulnerabilities: config.VulnerabilitiesConfig{ + DisableWinOSVulnerabilities: false, }, - &fleet.AppConfig{MDM: fleet.MDM{EnabledAndConfigured: true, WindowsEnabledAndConfigured: true}}, - &fleet.Features{ - EnableSoftwareInventory: true, - EnableHostUsers: true, + App: config.AppConfig{ + EnableScheduledQueryStats: true, }, - osquery_utils.Integrations{ - ConditionalAccessMicrosoft: true, - }, - ) + }, &fleet.AppConfig{MDM: fleet.MDM{ + EnabledAndConfigured: true, + WindowsEnabledAndConfigured: true, + }}, &fleet.Features{ + EnableSoftwareInventory: true, + EnableHostUsers: true, + }, osquery_utils.Integrations{ + ConditionalAccessMicrosoft: true, + }, nil) var b strings.Builder b.WriteString(` diff --git a/server/service/osquery_utils/queries.go b/server/service/osquery_utils/queries.go index 8d77b2d416..a96d8325a4 100644 --- a/server/service/osquery_utils/queries.go +++ b/server/service/osquery_utils/queries.go @@ -2645,6 +2645,7 @@ func GetDetailQueries( appConfig *fleet.AppConfig, features *fleet.Features, integrations Integrations, + teamMDMConfig *fleet.TeamMDM, ) map[string]DetailQuery { generatedMap := make(map[string]DetailQuery) for key, query := range hostDetailQueries { @@ -2689,12 +2690,22 @@ func GetDetailQueries( generatedMap[key] = query } - if appConfig.MDM.WindowsEnabledAndConfigured && - appConfig.MDM.EnableDiskEncryption.Value && - appConfig.MDM.RequireBitLockerPIN.Value { + // Add TPM PIN Queries iff Win MDM is enabled and ready to go + if appConfig.MDM.WindowsEnabledAndConfigured { + enableDiskEncryption := appConfig.MDM.EnableDiskEncryption.Value + requireTPMPin := appConfig.MDM.RequireBitLockerPIN.Value - for key, query := range tpmPINQueries { - generatedMap[key] = query + // If the host is part of a team, we need to look at the related team config + // instead of the App config ... + if teamMDMConfig != nil { + enableDiskEncryption = teamMDMConfig.EnableDiskEncryption + requireTPMPin = teamMDMConfig.RequireBitLockerPIN + } + + if enableDiskEncryption && requireTPMPin { + for key, query := range tpmPINQueries { + generatedMap[key] = query + } } } } diff --git a/server/service/osquery_utils/queries_test.go b/server/service/osquery_utils/queries_test.go index 1cece4da5c..5e578b2c32 100644 --- a/server/service/osquery_utils/queries_test.go +++ b/server/service/osquery_utils/queries_test.go @@ -70,7 +70,7 @@ func TestDetailQueryNetworkInterfaces(t *testing.T) { var initialHost fleet.Host host := initialHost - ingest := GetDetailQueries(context.Background(), config.FleetConfig{}, nil, nil, Integrations{})["network_interface_unix"].IngestFunc + ingest := GetDetailQueries(context.Background(), config.FleetConfig{}, nil, nil, Integrations{}, nil)["network_interface_unix"].IngestFunc assert.NoError(t, ingest(context.Background(), log.NewNopLogger(), &host, nil)) assert.Equal(t, initialHost, host) @@ -116,7 +116,7 @@ func TestDetailQueryScheduledQueryStats(t *testing.T) { return nil } - ingest := GetDetailQueries(context.Background(), config.FleetConfig{App: config.AppConfig{EnableScheduledQueryStats: true}}, nil, nil, Integrations{})["scheduled_query_stats"].DirectTaskIngestFunc + ingest := GetDetailQueries(context.Background(), config.FleetConfig{App: config.AppConfig{EnableScheduledQueryStats: true}}, nil, nil, Integrations{}, nil)["scheduled_query_stats"].DirectTaskIngestFunc ctx := context.Background() assert.NoError(t, ingest(ctx, log.NewNopLogger(), &host, task, nil)) @@ -295,7 +295,7 @@ func sortedKeysCompare(t *testing.T, m map[string]DetailQuery, expectedKeys []st } func TestGetDetailQueries(t *testing.T) { - queriesNoConfig := GetDetailQueries(context.Background(), config.FleetConfig{}, nil, nil, Integrations{}) + queriesNoConfig := GetDetailQueries(context.Background(), config.FleetConfig{}, nil, nil, Integrations{}, nil) baseQueries := []string{ "network_interface_unix", @@ -330,16 +330,16 @@ func TestGetDetailQueries(t *testing.T) { require.Len(t, queriesNoConfig, len(baseQueries)) sortedKeysCompare(t, queriesNoConfig, baseQueries) - queriesWithoutWinOSVuln := GetDetailQueries(context.Background(), config.FleetConfig{Vulnerabilities: config.VulnerabilitiesConfig{DisableWinOSVulnerabilities: true}}, nil, nil, Integrations{}) + queriesWithoutWinOSVuln := GetDetailQueries(context.Background(), config.FleetConfig{Vulnerabilities: config.VulnerabilitiesConfig{DisableWinOSVulnerabilities: true}}, nil, nil, Integrations{}, nil) require.Len(t, queriesWithoutWinOSVuln, 26) - queriesWithUsers := GetDetailQueries(context.Background(), config.FleetConfig{App: config.AppConfig{EnableScheduledQueryStats: true}}, nil, &fleet.Features{EnableHostUsers: true}, Integrations{}) + queriesWithUsers := GetDetailQueries(context.Background(), config.FleetConfig{App: config.AppConfig{EnableScheduledQueryStats: true}}, nil, &fleet.Features{EnableHostUsers: true}, Integrations{}, nil) qs := baseQueries qs = append(qs, "users", "users_chrome", "scheduled_query_stats") require.Len(t, queriesWithUsers, len(qs)) sortedKeysCompare(t, queriesWithUsers, qs) - queriesWithUsersAndSoftware := GetDetailQueries(context.Background(), config.FleetConfig{App: config.AppConfig{EnableScheduledQueryStats: true}}, nil, &fleet.Features{EnableHostUsers: true, EnableSoftwareInventory: true}, Integrations{}) + queriesWithUsersAndSoftware := GetDetailQueries(context.Background(), config.FleetConfig{App: config.AppConfig{EnableScheduledQueryStats: true}}, nil, &fleet.Features{EnableHostUsers: true, EnableSoftwareInventory: true}, Integrations{}, nil) qs = baseQueries qs = append(qs, "users", "users_chrome", "software_macos", "software_linux", "software_windows", "software_vscode_extensions", "software_chrome", "software_python_packages", "software_python_packages_with_users_dir", "scheduled_query_stats", "software_macos_firefox", "software_macos_codesign", "software_windows_last_opened_at", "software_deb_last_opened_at", "software_rpm_last_opened_at") @@ -359,14 +359,14 @@ func TestGetDetailQueries(t *testing.T) { ac := fleet.AppConfig{} ac.MDM.EnabledAndConfigured = true // windows mdm is disabled by default, windows mdm queries should not be present - gotQueries := GetDetailQueries(context.Background(), config.FleetConfig{}, &ac, nil, Integrations{}) + gotQueries := GetDetailQueries(context.Background(), config.FleetConfig{}, &ac, nil, Integrations{}, nil) wantQueries := baseQueries wantQueries = append(wantQueries, mdmQueriesBase...) require.Len(t, gotQueries, len(wantQueries)) sortedKeysCompare(t, gotQueries, wantQueries) // enable windows mdm, windows mdm queries should be present ac.MDM.WindowsEnabledAndConfigured = true - gotQueries = GetDetailQueries(context.Background(), config.FleetConfig{}, &ac, nil, Integrations{}) + gotQueries = GetDetailQueries(context.Background(), config.FleetConfig{}, &ac, nil, Integrations{}, nil) wantQueries = append(wantQueries, mdmQueriesWindows...) require.Len(t, gotQueries, len(wantQueries)) sortedKeysCompare(t, gotQueries, wantQueries) @@ -414,7 +414,7 @@ func TestGetDetailQueries(t *testing.T) { for _, tt := range testCases { t.Run(tt.name, func(t *testing.T) { - got := GetDetailQueries(context.Background(), config.FleetConfig{}, &tt.ac, nil, Integrations{}) + got := GetDetailQueries(context.Background(), config.FleetConfig{}, &tt.ac, nil, Integrations{}, nil) for _, name := range tt.want { _, ok := got[name] require.True(t, ok) @@ -427,7 +427,7 @@ func TestDetailQueriesOSVersionUnixLike(t *testing.T) { var initialHost fleet.Host host := initialHost - ingest := GetDetailQueries(context.Background(), config.FleetConfig{}, nil, nil, Integrations{})["os_version"].IngestFunc + ingest := GetDetailQueries(context.Background(), config.FleetConfig{}, nil, nil, Integrations{}, nil)["os_version"].IngestFunc assert.NoError(t, ingest(context.Background(), log.NewNopLogger(), &host, nil)) assert.Equal(t, initialHost, host) @@ -501,7 +501,7 @@ func TestDetailQueriesOSVersionWindows(t *testing.T) { var initialHost fleet.Host host := initialHost - ingest := GetDetailQueries(context.Background(), config.FleetConfig{}, nil, nil, Integrations{})["os_version_windows"].IngestFunc + ingest := GetDetailQueries(context.Background(), config.FleetConfig{}, nil, nil, Integrations{}, nil)["os_version_windows"].IngestFunc assert.NoError(t, ingest(context.Background(), log.NewNopLogger(), &host, nil)) assert.Equal(t, initialHost, host) @@ -556,7 +556,7 @@ func TestDetailQueriesOSVersionChrome(t *testing.T) { var initialHost fleet.Host host := initialHost - ingest := GetDetailQueries(context.Background(), config.FleetConfig{}, nil, nil, Integrations{})["os_version"].IngestFunc + ingest := GetDetailQueries(context.Background(), config.FleetConfig{}, nil, nil, Integrations{}, nil)["os_version"].IngestFunc assert.NoError(t, ingest(context.Background(), log.NewNopLogger(), &host, nil)) assert.Equal(t, initialHost, host) @@ -1376,29 +1376,29 @@ func TestDirectIngestOSUnixLike(t *testing.T) { } func TestAppConfigReplaceQuery(t *testing.T) { - queries := GetDetailQueries(context.Background(), config.FleetConfig{}, nil, &fleet.Features{EnableHostUsers: true}, Integrations{}) + queries := GetDetailQueries(context.Background(), config.FleetConfig{}, nil, &fleet.Features{EnableHostUsers: true}, Integrations{}, nil) originalQuery := queries["users"].Query replacementMap := make(map[string]*string) replacementMap["users"] = ptr.String("select 1 from blah") - queries = GetDetailQueries(context.Background(), config.FleetConfig{}, nil, &fleet.Features{EnableHostUsers: true, DetailQueryOverrides: replacementMap}, Integrations{}) + queries = GetDetailQueries(context.Background(), config.FleetConfig{}, nil, &fleet.Features{EnableHostUsers: true, DetailQueryOverrides: replacementMap}, Integrations{}, nil) assert.NotEqual(t, originalQuery, queries["users"].Query) assert.Equal(t, "select 1 from blah", queries["users"].Query) replacementMap["users"] = nil - queries = GetDetailQueries(context.Background(), config.FleetConfig{}, nil, &fleet.Features{EnableHostUsers: true, DetailQueryOverrides: replacementMap}, Integrations{}) + queries = GetDetailQueries(context.Background(), config.FleetConfig{}, nil, &fleet.Features{EnableHostUsers: true, DetailQueryOverrides: replacementMap}, Integrations{}, nil) _, exists := queries["users"] assert.False(t, exists) // put the query back again replacementMap["users"] = ptr.String("select 1 from blah") - queries = GetDetailQueries(context.Background(), config.FleetConfig{}, nil, &fleet.Features{EnableHostUsers: true, DetailQueryOverrides: replacementMap}, Integrations{}) + queries = GetDetailQueries(context.Background(), config.FleetConfig{}, nil, &fleet.Features{EnableHostUsers: true, DetailQueryOverrides: replacementMap}, Integrations{}, nil) assert.NotEqual(t, originalQuery, queries["users"].Query) assert.Equal(t, "select 1 from blah", queries["users"].Query) // empty strings are also ignored replacementMap["users"] = ptr.String("") - queries = GetDetailQueries(context.Background(), config.FleetConfig{}, nil, &fleet.Features{EnableHostUsers: true, DetailQueryOverrides: replacementMap}, Integrations{}) + queries = GetDetailQueries(context.Background(), config.FleetConfig{}, nil, &fleet.Features{EnableHostUsers: true, DetailQueryOverrides: replacementMap}, Integrations{}, nil) _, exists = queries["users"] assert.False(t, exists) }