mirror of
https://github.com/fleetdm/fleet
synced 2026-05-24 01:18:42 +00:00
Fix sending of "install Fleetd" commands repeatedly on Azure-enrolled Windows devices (#18453)
This commit is contained in:
parent
8eec8e5371
commit
26b83de925
5 changed files with 102 additions and 24 deletions
|
|
@ -0,0 +1 @@
|
|||
* Fixed an issue on Windows hosts enrolled in MDM via Azure AD where the command to install Fleetd on the device was sent repeatedly, even though `fleetd` had been properly installed.
|
||||
|
|
@ -2680,13 +2680,13 @@ func (ds *Datastore) HostByIdentifier(ctx context.Context, identifier string) (*
|
|||
COALESCE(hd.percent_disk_space_available, 0) as percent_disk_space_available,
|
||||
COALESCE(hd.gigs_total_disk_space, 0) as gigs_total_disk_space,
|
||||
COALESCE(hst.seen_time, h.created_at) AS seen_time,
|
||||
COALESCE(hu.software_updated_at, h.created_at) AS software_updated_at
|
||||
` + hostMDMSelect + `
|
||||
COALESCE(hu.software_updated_at, h.created_at) AS software_updated_at
|
||||
` + hostMDMSelect + `
|
||||
FROM hosts h
|
||||
LEFT JOIN host_seen_times hst ON (h.id = hst.host_id)
|
||||
LEFT JOIN host_updates hu ON (h.id = hu.host_id)
|
||||
LEFT JOIN host_updates hu ON (h.id = hu.host_id)
|
||||
LEFT JOIN host_disks hd ON hd.host_id = h.id
|
||||
` + hostMDMJoin + `
|
||||
` + hostMDMJoin + `
|
||||
WHERE ? IN (h.hostname, h.osquery_host_id, h.node_key, h.uuid, h.hardware_serial)
|
||||
LIMIT 1
|
||||
`
|
||||
|
|
@ -3715,9 +3715,11 @@ func (ds *Datastore) GetHostOrbitInfo(ctx context.Context, hostID uint) (*fleet.
|
|||
err := sqlx.GetContext(
|
||||
ctx, ds.reader(ctx), &orbit, `
|
||||
SELECT
|
||||
scripts_enabled
|
||||
version,
|
||||
desktop_version,
|
||||
scripts_enabled
|
||||
FROM
|
||||
host_orbit_info
|
||||
host_orbit_info
|
||||
WHERE host_id = ?`, hostID,
|
||||
)
|
||||
if err != nil {
|
||||
|
|
@ -5037,7 +5039,7 @@ func (ds *Datastore) loadHostLite(ctx context.Context, id *uint, identifier *str
|
|||
stmt := `
|
||||
SELECT
|
||||
h.id,
|
||||
h.team_id,
|
||||
h.team_id,
|
||||
h.osquery_host_id,
|
||||
h.node_key,
|
||||
h.hostname,
|
||||
|
|
@ -5048,7 +5050,7 @@ func (ds *Datastore) loadHostLite(ctx context.Context, id *uint, identifier *str
|
|||
COALESCE(hst.seen_time, h.created_at) AS seen_time
|
||||
FROM hosts h
|
||||
LEFT JOIN host_seen_times hst ON (h.id = hst.host_id)
|
||||
%s
|
||||
%s
|
||||
LIMIT 1
|
||||
`
|
||||
var (
|
||||
|
|
|
|||
|
|
@ -361,7 +361,9 @@ type Host struct {
|
|||
|
||||
// HostOrbitInfo maps to the host_orbit_info table in the database, which maps to the orbit_info agent table.
|
||||
type HostOrbitInfo struct {
|
||||
ScriptsEnabled *bool `json:"scripts_enabled" db:"scripts_enabled"`
|
||||
Version string `json:"version" db:"version"`
|
||||
DesktopVersion *string `json:"desktop_version" db:"desktop_version"`
|
||||
ScriptsEnabled *bool `json:"scripts_enabled" db:"scripts_enabled"`
|
||||
}
|
||||
|
||||
// HostHealth contains a subset of Host data that indicates how healthy a Host is. For fields with
|
||||
|
|
|
|||
|
|
@ -6069,22 +6069,79 @@ func (s *integrationMDMTestSuite) TestWindowsAutomaticEnrollmentCommands() {
|
|||
d := mdmtest.NewTestMDMClientWindowsAutomatic(s.server.URL, azureMail)
|
||||
require.NoError(t, d.Enroll())
|
||||
|
||||
cmds, err := d.StartManagementSession()
|
||||
checkinAndAck := func(expectFleetdCmds bool) {
|
||||
cmds, err := d.StartManagementSession()
|
||||
require.NoError(t, err)
|
||||
|
||||
if !expectFleetdCmds {
|
||||
// receives only the 2 status commands
|
||||
require.Len(t, cmds, 2)
|
||||
for _, c := range cmds {
|
||||
require.Equal(t, "Status", c.Verb, c)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 2 status + 2 commands to install fleetd
|
||||
require.Len(t, cmds, 4)
|
||||
var fleetdAddCmd, fleetdExecCmd fleet.ProtoCmdOperation
|
||||
for _, c := range cmds {
|
||||
switch c.Verb {
|
||||
case "Add":
|
||||
fleetdAddCmd = c
|
||||
case "Exec":
|
||||
fleetdExecCmd = c
|
||||
}
|
||||
}
|
||||
require.Equal(t, syncml.FleetdWindowsInstallerGUID, fleetdAddCmd.Cmd.GetTargetURI())
|
||||
require.Equal(t, syncml.FleetdWindowsInstallerGUID, fleetdExecCmd.Cmd.GetTargetURI())
|
||||
|
||||
// reply with success for both commands
|
||||
msgID, err := d.GetCurrentMsgID()
|
||||
require.NoError(t, err)
|
||||
|
||||
d.AppendResponse(fleet.SyncMLCmd{
|
||||
XMLName: xml.Name{Local: fleet.CmdStatus},
|
||||
MsgRef: &msgID,
|
||||
CmdRef: &fleetdAddCmd.Cmd.CmdID.Value,
|
||||
Cmd: &fleetdAddCmd.Verb,
|
||||
Data: ptr.String("200"),
|
||||
Items: nil,
|
||||
CmdID: fleet.CmdID{Value: uuid.NewString()},
|
||||
})
|
||||
d.AppendResponse(fleet.SyncMLCmd{
|
||||
XMLName: xml.Name{Local: fleet.CmdStatus},
|
||||
MsgRef: &msgID,
|
||||
CmdRef: &fleetdExecCmd.Cmd.CmdID.Value,
|
||||
Cmd: &fleetdExecCmd.Verb,
|
||||
Data: ptr.String("200"),
|
||||
Items: nil,
|
||||
CmdID: fleet.CmdID{Value: uuid.NewString()},
|
||||
})
|
||||
cmds, err = d.SendResponse()
|
||||
require.NoError(t, err)
|
||||
|
||||
// the ack of the message should be the only returned command
|
||||
require.Len(t, cmds, 1)
|
||||
}
|
||||
|
||||
// start a management session, will receive the install fleetd commands
|
||||
checkinAndAck(true)
|
||||
|
||||
// start a new management session again, Fleetd is not reported as installed
|
||||
// so it receives the commands again
|
||||
checkinAndAck(true)
|
||||
|
||||
// simulate fleetd installed and enrolled
|
||||
host := createOrbitEnrolledHost(t, "windows", "h1", s.ds)
|
||||
err = s.ds.UpdateMDMWindowsEnrollmentsHostUUID(ctx, host.UUID, d.DeviceID)
|
||||
require.NoError(t, err)
|
||||
err = s.ds.SetOrUpdateHostOrbitInfo(ctx, host.ID, "1.23", sql.NullString{}, sql.NullBool{})
|
||||
require.NoError(t, err)
|
||||
|
||||
// 2 status + 2 commands to install fleetd
|
||||
require.Len(t, cmds, 4)
|
||||
var fleetdAddCmd, fleetdExecCmd fleet.ProtoCmdOperation
|
||||
for _, c := range cmds {
|
||||
switch c.Verb {
|
||||
case "Add":
|
||||
fleetdAddCmd = c
|
||||
case "Exec":
|
||||
fleetdExecCmd = c
|
||||
}
|
||||
}
|
||||
require.Equal(t, syncml.FleetdWindowsInstallerGUID, fleetdAddCmd.Cmd.GetTargetURI())
|
||||
require.Equal(t, syncml.FleetdWindowsInstallerGUID, fleetdExecCmd.Cmd.GetTargetURI())
|
||||
// start a new management session again, Fleetd is reported as installed so
|
||||
// it does not receive the commands
|
||||
checkinAndAck(false)
|
||||
}
|
||||
|
||||
func (s *integrationMDMTestSuite) TestValidManagementUnenrollRequest() {
|
||||
|
|
|
|||
|
|
@ -1274,7 +1274,23 @@ func (svc *Service) isFleetdPresentOnDevice(ctx context.Context, deviceID string
|
|||
// If user identity is a MS-MDM UPN it means that the device was enrolled through user-driven flow
|
||||
// This means that fleetd might not be installed
|
||||
if isValidUPN(enrolledDevice.MDMEnrollUserID) {
|
||||
return false, nil
|
||||
var isPresent bool
|
||||
if enrolledDevice.HostUUID != "" {
|
||||
host, err := svc.ds.HostLiteByIdentifier(ctx, enrolledDevice.HostUUID)
|
||||
if err != nil && !fleet.IsNotFound(err) {
|
||||
return false, ctxerr.Wrap(ctx, err, "get host lite by identifier")
|
||||
}
|
||||
if host != nil {
|
||||
orbitInfo, err := svc.ds.GetHostOrbitInfo(ctx, host.ID)
|
||||
if err != nil && !fleet.IsNotFound(err) {
|
||||
return false, ctxerr.Wrap(ctx, err, "get host orbit info")
|
||||
}
|
||||
if orbitInfo != nil {
|
||||
isPresent = orbitInfo.Version != ""
|
||||
}
|
||||
}
|
||||
}
|
||||
return isPresent, nil
|
||||
}
|
||||
|
||||
// TODO: Add check here to determine if MDM DeviceID is connected with Smbios UUID present on
|
||||
|
|
|
|||
Loading…
Reference in a new issue