mirror of
https://github.com/fleetdm/fleet
synced 2026-05-23 08:58:41 +00:00
improve mdm_windows query to account for multiple registry entries (#15391)
for #15362, this adjusts the query we use to get MDM details for windows to account for hosts that might have more than one matching value in the registry for any of the items we query.
This commit is contained in:
parent
6fd06d6486
commit
a7be0be9e9
3 changed files with 85 additions and 47 deletions
1
changes/15362-windows-mdm-query
Normal file
1
changes/15362-windows-mdm-query
Normal file
|
|
@ -0,0 +1 @@
|
|||
* Improved the query used to get MDM details for Windows hosts to account for multiple registry entries.
|
||||
|
|
@ -438,31 +438,48 @@ var extraDetailQueries = map[string]DetailQuery{
|
|||
Discovery: discoveryTable("mdm"),
|
||||
},
|
||||
"mdm_windows": {
|
||||
// we get most of the MDM information for Windows from the
|
||||
// `HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Enrollments\%%`
|
||||
// registry keys. A computer might many different folders under
|
||||
// that path, for different enrollments, so we need to group by
|
||||
// enrollment (key in this case) and try to grab the most
|
||||
// likely candiate to be an MDM solution.
|
||||
//
|
||||
// The best way I have found, is to filter by groups of entries
|
||||
// with an UPN value, and pick the first one.
|
||||
//
|
||||
// An example of a host having more than one entry: when
|
||||
// the `mdm_bridge` table is used, the `mdmlocalmanagement.dll`
|
||||
// registers an MDM with ProviderID = `Local_Management`
|
||||
//
|
||||
// For more information, refer to issue #15362
|
||||
Query: `
|
||||
SELECT * FROM (
|
||||
SELECT "provider_id" AS "key", data as "value" FROM registry
|
||||
WHERE path LIKE 'HKEY_LOCAL_MACHINE\Software\Microsoft\Enrollments\%\ProviderID'
|
||||
LIMIT 1
|
||||
WITH registry_keys AS (
|
||||
SELECT *
|
||||
FROM registry
|
||||
WHERE path LIKE 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Enrollments\%%'
|
||||
),
|
||||
enrollment_info AS (
|
||||
SELECT
|
||||
MAX(CASE WHEN name = 'UPN' THEN data END) AS upn,
|
||||
MAX(CASE WHEN name = 'IsFederated' THEN data END) AS is_federated,
|
||||
MAX(CASE WHEN name = 'DiscoveryServiceFullURL' THEN data END) AS discovery_service_url,
|
||||
MAX(CASE WHEN name = 'ProviderID' THEN data END) AS provider_id
|
||||
FROM registry_keys
|
||||
GROUP BY key
|
||||
)
|
||||
UNION ALL
|
||||
SELECT * FROM (
|
||||
SELECT "discovery_service_url" AS "key", data as "value" FROM registry
|
||||
WHERE path LIKE 'HKEY_LOCAL_MACHINE\Software\Microsoft\Enrollments\%\DiscoveryServiceFullURL'
|
||||
LIMIT 1
|
||||
)
|
||||
UNION ALL
|
||||
SELECT * FROM (
|
||||
SELECT "is_federated" AS "key", data as "value" FROM registry
|
||||
WHERE path LIKE 'HKEY_LOCAL_MACHINE\Software\Microsoft\Enrollments\%\IsFederated'
|
||||
LIMIT 1
|
||||
)
|
||||
UNION ALL
|
||||
SELECT * FROM (
|
||||
SELECT "installation_type" AS "key", data as "value" FROM registry
|
||||
WHERE path = 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\InstallationType'
|
||||
LIMIT 1
|
||||
)
|
||||
;
|
||||
SELECT
|
||||
e.is_federated,
|
||||
e.discovery_service_url,
|
||||
e.provider_id,
|
||||
(
|
||||
SELECT data
|
||||
FROM registry
|
||||
WHERE path = 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\InstallationType'
|
||||
) AS installation_type
|
||||
FROM enrollment_info e
|
||||
WHERE e.upn IS NOT NULL
|
||||
LIMIT 1;
|
||||
`,
|
||||
DirectIngestFunc: directIngestMDMWindows,
|
||||
Platforms: []string{"windows"},
|
||||
|
|
@ -1458,10 +1475,19 @@ func deduceMDMNameWindows(data map[string]string) string {
|
|||
}
|
||||
|
||||
func directIngestMDMWindows(ctx context.Context, logger log.Logger, host *fleet.Host, ds fleet.Datastore, rows []map[string]string) error {
|
||||
data := make(map[string]string, len(rows))
|
||||
for _, r := range rows {
|
||||
data[r["key"]] = r["value"]
|
||||
if len(rows) != 1 {
|
||||
logger.Log("component", "service", "method", "directIngestMDMWindows", "warn",
|
||||
fmt.Sprintf("mdm expected single result got %d", len(rows)))
|
||||
// assume the extension is not there
|
||||
return nil
|
||||
}
|
||||
|
||||
if len(rows) > 1 {
|
||||
logger.Log("component", "service", "method", "directIngestMDMWindows", "warn",
|
||||
fmt.Sprintf("mdm expected single result got %d", len(rows)))
|
||||
}
|
||||
|
||||
data := rows[0]
|
||||
var enrolled bool
|
||||
var automatic bool
|
||||
serverURL := data["discovery_service_url"]
|
||||
|
|
|
|||
|
|
@ -588,10 +588,12 @@ func TestDirectIngestMDMWindows(t *testing.T) {
|
|||
{
|
||||
name: "off empty server URL",
|
||||
data: []map[string]string{
|
||||
{"key": "discovery_service_url", "value": ""},
|
||||
{"key": "is_federated", "value": "1"},
|
||||
{"key": "provider_id", "value": "Some_ID"},
|
||||
{"key": "installation_type", "value": "Client"},
|
||||
{
|
||||
"discovery_service_url": "",
|
||||
"is_federated": "1",
|
||||
"provider_id": "Some_ID",
|
||||
"installation_type": "Client",
|
||||
},
|
||||
},
|
||||
wantEnrolled: false,
|
||||
wantInstalledFromDep: false,
|
||||
|
|
@ -601,8 +603,10 @@ func TestDirectIngestMDMWindows(t *testing.T) {
|
|||
{
|
||||
name: "off missing is_federated and server url",
|
||||
data: []map[string]string{
|
||||
{"key": "provider_id", "value": "Some_ID"},
|
||||
{"key": "installation_type", "value": "Client"},
|
||||
{
|
||||
"provider_id": "Some_ID",
|
||||
"installation_type": "Client",
|
||||
},
|
||||
},
|
||||
wantEnrolled: false,
|
||||
wantInstalledFromDep: false,
|
||||
|
|
@ -612,10 +616,12 @@ func TestDirectIngestMDMWindows(t *testing.T) {
|
|||
{
|
||||
name: "on automatic",
|
||||
data: []map[string]string{
|
||||
{"key": "discovery_service_url", "value": "https://example.com"},
|
||||
{"key": "is_federated", "value": "1"},
|
||||
{"key": "provider_id", "value": "Some_ID"},
|
||||
{"key": "installation_type", "value": "Client"},
|
||||
{
|
||||
"discovery_service_url": "https://example.com",
|
||||
"is_federated": "1",
|
||||
"provider_id": "Some_ID",
|
||||
"installation_type": "Client",
|
||||
},
|
||||
},
|
||||
wantEnrolled: true,
|
||||
wantInstalledFromDep: true,
|
||||
|
|
@ -625,10 +631,12 @@ func TestDirectIngestMDMWindows(t *testing.T) {
|
|||
{
|
||||
name: "on manual",
|
||||
data: []map[string]string{
|
||||
{"key": "discovery_service_url", "value": "https://example.com"},
|
||||
{"key": "is_federated", "value": "0"},
|
||||
{"key": "provider_id", "value": "Local_Management"},
|
||||
{"key": "installation_type", "value": "Client"},
|
||||
{
|
||||
"discovery_service_url": "https://example.com",
|
||||
"is_federated": "0",
|
||||
"provider_id": "Local_Management",
|
||||
"installation_type": "Client",
|
||||
},
|
||||
},
|
||||
wantEnrolled: true,
|
||||
wantInstalledFromDep: false,
|
||||
|
|
@ -638,9 +646,11 @@ func TestDirectIngestMDMWindows(t *testing.T) {
|
|||
{
|
||||
name: "on manual missing is_federated",
|
||||
data: []map[string]string{
|
||||
{"key": "discovery_service_url", "value": "https://example.com"},
|
||||
{"key": "provider_id", "value": "Some_ID"},
|
||||
{"key": "installation_type", "value": "Client"},
|
||||
{
|
||||
"discovery_service_url": "https://example.com",
|
||||
"provider_id": "Some_ID",
|
||||
"installation_type": "Client",
|
||||
},
|
||||
},
|
||||
wantEnrolled: true,
|
||||
wantInstalledFromDep: false,
|
||||
|
|
@ -650,10 +660,11 @@ func TestDirectIngestMDMWindows(t *testing.T) {
|
|||
{
|
||||
name: "is_server",
|
||||
data: []map[string]string{
|
||||
{"key": "discovery_service_url", "value": "https://example.com"},
|
||||
{"key": "is_federated", "value": "1"},
|
||||
{"key": "provider_id", "value": "Some_ID"},
|
||||
{"key": "installation_type", "value": "Windows SeRvEr 99.9"},
|
||||
{
|
||||
"discovery_service_url": "https://example.com",
|
||||
"is_federated": "1",
|
||||
"provider_id": "Some_ID",
|
||||
"installation_type": "Windows SeRvEr 99.9"},
|
||||
},
|
||||
wantEnrolled: true,
|
||||
wantInstalledFromDep: true,
|
||||
|
|
|
|||
Loading…
Reference in a new issue