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:
Roberto Dip 2023-12-04 11:03:05 -03:00 committed by GitHub
parent 6fd06d6486
commit a7be0be9e9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 85 additions and 47 deletions

View file

@ -0,0 +1 @@
* Improved the query used to get MDM details for Windows hosts to account for multiple registry entries.

View file

@ -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"]

View file

@ -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,