From 7dda2e9f84e348df0e64956bf7ddeef19f4f19df Mon Sep 17 00:00:00 2001 From: Sarah Gillespie <73313222+gillespi314@users.noreply.github.com> Date: Tue, 16 Jul 2024 11:44:48 -0500 Subject: [PATCH] Revert changes to DEP enrollment flow (#20506) Reverts #20162 and #20355 per [QA findings](https://github.com/fleetdm/fleet/issues/19185#issuecomment-2229544188) --- changes/19185-dep-deviceinfo-mdm-idp | 4 - cmd/fleet/serve.go | 2 - .../MDMAppleSSOCallbackPage.tsx | 11 +- .../pages/MDMAppleSSOPage/MDMAppleSSOPage.tsx | 14 +- frontend/services/entities/mdm.ts | 15 +- frontend/utilities/endpoints.ts | 13 +- server/datastore/mysql/apple_mdm.go | 55 +----- server/datastore/mysql/apple_mdm_test.go | 4 +- server/datastore/mysql/hosts.go | 77 +------- server/datastore/mysql/hosts_test.go | 1 - ...240709175341_AddColumnsToMdmIdpAccounts.go | 42 ----- ...9175341_AddColumnsToMdmIdpAccounts_test.go | 74 -------- ...10152744_AddIndexHostUuidMdmIdpAccounts.go | 25 --- server/datastore/mysql/schema.sql | 9 +- server/fleet/datastore.go | 40 +--- server/fleet/mdm.go | 12 -- server/fleet/service.go | 2 +- server/mdm/apple/AppleIncRootCertificate.cer | Bin 1215 -> 0 bytes server/mdm/apple/deviceinfo.go | 173 ------------------ server/mock/datastore_mock.go | 84 ++------- server/service/apple_mdm.go | 57 +----- server/service/apple_mdm_test.go | 2 +- server/service/handler.go | 39 ---- server/service/integration_mdm_test.go | 22 +-- server/service/osquery_utils/queries.go | 17 +- server/service/osquery_utils/queries_test.go | 25 +-- server/worker/apple_mdm.go | 31 +--- server/worker/apple_mdm_test.go | 164 +---------------- 28 files changed, 87 insertions(+), 927 deletions(-) delete mode 100644 changes/19185-dep-deviceinfo-mdm-idp delete mode 100644 server/datastore/mysql/migrations/tables/20240709175341_AddColumnsToMdmIdpAccounts.go delete mode 100644 server/datastore/mysql/migrations/tables/20240709175341_AddColumnsToMdmIdpAccounts_test.go delete mode 100644 server/datastore/mysql/migrations/tables/20240710152744_AddIndexHostUuidMdmIdpAccounts.go delete mode 100644 server/mdm/apple/AppleIncRootCertificate.cer delete mode 100644 server/mdm/apple/deviceinfo.go diff --git a/changes/19185-dep-deviceinfo-mdm-idp b/changes/19185-dep-deviceinfo-mdm-idp deleted file mode 100644 index 4c8406184d6e..000000000000 --- a/changes/19185-dep-deviceinfo-mdm-idp +++ /dev/null @@ -1,4 +0,0 @@ -- Fixed bug where MDM devices would fail to renew enrollment profiles if applicable end user authentication - settings changed after the device was enrolled. -- Improved device user account creation during MDM IdP enrollment flow by removing enrollment - reference from MDM server url in Fleet-generated enrollment profiles. diff --git a/cmd/fleet/serve.go b/cmd/fleet/serve.go index 27d5c52641f0..5c8a3db664f6 100644 --- a/cmd/fleet/serve.go +++ b/cmd/fleet/serve.go @@ -942,8 +942,6 @@ the way that the Fleet server works. "get_frontend", service.ServeFrontend(config.Server.URLPrefix, config.Server.SandboxEnabled, httpLogger), ) - frontendHandler = service.WithDEPWebviewRedirect(svc, logger, frontendHandler, config.Server.URLPrefix) - apiHandler = service.MakeHandler(svc, config, httpLogger, limiterStore) setupRequired, err := svc.SetupRequired(baseCtx) diff --git a/frontend/pages/MDMAppleSSOCallbackPage/MDMAppleSSOCallbackPage.tsx b/frontend/pages/MDMAppleSSOCallbackPage/MDMAppleSSOCallbackPage.tsx index 296ece9ff829..8aa14b207da9 100644 --- a/frontend/pages/MDMAppleSSOCallbackPage/MDMAppleSSOCallbackPage.tsx +++ b/frontend/pages/MDMAppleSSOCallbackPage/MDMAppleSSOCallbackPage.tsx @@ -29,8 +29,6 @@ const EnrollmentGate = ({ }: IEnrollmentGateProps) => { const [showEULA, setShowEULA] = useState(Boolean(eulaToken)); - const dep_device_info = localStorage.getItem("dep_device_info") || ""; - if (!profileToken || error) { return ; } @@ -57,11 +55,10 @@ const EnrollmentGate = ({ return ( ); }; diff --git a/frontend/pages/MDMAppleSSOPage/MDMAppleSSOPage.tsx b/frontend/pages/MDMAppleSSOPage/MDMAppleSSOPage.tsx index 5fbde4090e10..c0920bb6637d 100644 --- a/frontend/pages/MDMAppleSSOPage/MDMAppleSSOPage.tsx +++ b/frontend/pages/MDMAppleSSOPage/MDMAppleSSOPage.tsx @@ -1,9 +1,8 @@ import React from "react"; import { useQuery } from "react-query"; import { AxiosError } from "axios"; -import { WithRouterProps } from "react-router"; -import mdmAPI, { IMDMSSOParams } from "services/entities/mdm"; +import mdmAPI from "services/entities/mdm"; import SSOError from "components/MDM/SSOError"; import Spinner from "components/Spinner/Spinner"; @@ -11,15 +10,10 @@ import { IMdmSSOReponse } from "interfaces/mdm"; const baseClass = "mdm-apple-sso-page"; -const DEPSSOLoginPage = ({ - location: { query }, -}: WithRouterProps) => { - const { dep_device_info } = query; - localStorage.setItem("dep_device_info", dep_device_info || ""); - - const { error } = useQuery( +const DEPSSOLoginPage = () => { + const { error } = useQuery( ["dep_sso"], - () => mdmAPI.initiateMDMAppleSSO(query), + () => mdmAPI.initiateMDMAppleSSO(), { retry: false, refetchOnWindowFocus: false, diff --git a/frontend/services/entities/mdm.ts b/frontend/services/entities/mdm.ts index f1549c08a238..e9c288db0918 100644 --- a/frontend/services/entities/mdm.ts +++ b/frontend/services/entities/mdm.ts @@ -4,7 +4,6 @@ import { DiskEncryptionStatus, IHostMdmProfile, IMdmProfile, - IMdmSSOReponse, MdmProfileStatus, } from "interfaces/mdm"; import { API_NO_TEAM_ID } from "interfaces/team"; @@ -68,16 +67,6 @@ export interface IAppleSetupEnrollmentProfileResponse { enrollment_profile: Record; } -export interface IMDMSSOParams { - dep_device_info: string; -} - -export interface IMDMAppleEnrollmentProfileParams { - token: string; - ref?: string; - dep_device_info?: string; -} - const mdmService = { resetEncryptionKey: (token: string) => { const { DEVICE_USER_RESET_ENCRYPTION_KEY } = endpoints; @@ -192,9 +181,9 @@ const mdmService = { }); }, - initiateMDMAppleSSO: (params: IMDMSSOParams): Promise => { + initiateMDMAppleSSO: () => { const { MDM_APPLE_SSO } = endpoints; - return sendRequest("POST", MDM_APPLE_SSO, params); + return sendRequest("POST", MDM_APPLE_SSO, {}); }, getBootstrapPackageMetadata: (teamId: number) => { diff --git a/frontend/utilities/endpoints.ts b/frontend/utilities/endpoints.ts index 8d456b3e24b4..d096fd4a0a67 100644 --- a/frontend/utilities/endpoints.ts +++ b/frontend/utilities/endpoints.ts @@ -1,5 +1,3 @@ -import { IMDMAppleEnrollmentProfileParams } from "services/entities/mdm"; - const API_VERSION = "latest"; export default { @@ -95,14 +93,11 @@ export default { MDM_PROFILES_STATUS_SUMMARY: `/${API_VERSION}/fleet/mdm/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, - ref, - dep_device_info, - }: IMDMAppleEnrollmentProfileParams) => { + MDM_APPLE_ENROLLMENT_PROFILE: (token: string, ref?: string) => { const query = new URLSearchParams({ token }); - ref && query.append("enrollment_reference", ref); - dep_device_info && query.append("dep_device_info", dep_device_info); + if (ref) { + query.append("enrollment_reference", ref); + } return `/api/mdm/apple/enroll?${query}`; }, MDM_APPLE_SETUP_ENROLLMENT_PROFILE: `/${API_VERSION}/fleet/mdm/apple/enrollment_profile`, diff --git a/server/datastore/mysql/apple_mdm.go b/server/datastore/mysql/apple_mdm.go index 4ceff0dee2fb..266c7637fae6 100644 --- a/server/datastore/mysql/apple_mdm.go +++ b/server/datastore/mysql/apple_mdm.go @@ -2732,13 +2732,8 @@ func (ds *Datastore) InsertMDMIdPAccount(ctx context.Context, account *fleet.MDM return ctxerr.Wrap(ctx, err, "creating new MDM IdP account") } -func (ds *Datastore) AssociateMDMIdPAccount(ctx context.Context, accountUUID, hostUUID string) error { - _, err := ds.writer(ctx).ExecContext(ctx, `UPDATE mdm_idp_accounts SET host_uuid = ? WHERE uuid = ?`, hostUUID, accountUUID) - return ctxerr.Wrap(ctx, err, "associating MDM IdP account with device") -} - func (ds *Datastore) GetMDMIdPAccountByEmail(ctx context.Context, email string) (*fleet.MDMIdPAccount, error) { - stmt := `SELECT uuid, username, fullname, email, host_uuid, fleet_enroll_ref FROM mdm_idp_accounts WHERE email = ?` + stmt := `SELECT uuid, username, fullname, email FROM mdm_idp_accounts WHERE email = ?` var acct fleet.MDMIdPAccount err := sqlx.GetContext(ctx, ds.reader(ctx), &acct, stmt, email) if err != nil { @@ -2750,39 +2745,13 @@ func (ds *Datastore) GetMDMIdPAccountByEmail(ctx context.Context, email string) return &acct, nil } -func (ds *Datastore) GetMDMIdPAccountByAccountUUID(ctx context.Context, accountUUID string) (*fleet.MDMIdPAccount, error) { - stmt := `SELECT uuid, username, fullname, email, host_uuid, fleet_enroll_ref FROM mdm_idp_accounts WHERE uuid = ?` +func (ds *Datastore) GetMDMIdPAccountByUUID(ctx context.Context, uuid string) (*fleet.MDMIdPAccount, error) { + stmt := `SELECT uuid, username, fullname, email FROM mdm_idp_accounts WHERE uuid = ?` var acct fleet.MDMIdPAccount - err := sqlx.GetContext(ctx, ds.reader(ctx), &acct, stmt, accountUUID) + err := sqlx.GetContext(ctx, ds.reader(ctx), &acct, stmt, uuid) if err != nil { if err == sql.ErrNoRows { - return nil, ctxerr.Wrap(ctx, notFound("MDMIdPAccount").WithMessage(fmt.Sprintf("with uuid %s", accountUUID))) - } - return nil, ctxerr.Wrap(ctx, err, "select mdm_idp_accounts") - } - return &acct, nil -} - -func (ds *Datastore) GetMDMIdPAccountByHostUUID(ctx context.Context, hostUUID string) (*fleet.MDMIdPAccount, error) { - stmt := `SELECT uuid, username, fullname, email, host_uuid, fleet_enroll_ref FROM mdm_idp_accounts WHERE host_uuid = ?` - var acct fleet.MDMIdPAccount - err := sqlx.GetContext(ctx, ds.reader(ctx), &acct, stmt, hostUUID) - if err != nil { - if err == sql.ErrNoRows { - return nil, ctxerr.Wrap(ctx, notFound("MDMIdPAccount").WithMessage(fmt.Sprintf("with host uuid %s", hostUUID))) - } - return nil, ctxerr.Wrap(ctx, err, "select mdm_idp_accounts") - } - return &acct, nil -} - -func (ds *Datastore) GetMDMIdPAccountByLegacyEnrollRef(ctx context.Context, ref string) (*fleet.MDMIdPAccount, error) { - stmt := `SELECT uuid, username, fullname, email, host_uuid, fleet_enroll_ref FROM mdm_idp_accounts WHERE fleet_enroll_ref = ?` - var acct fleet.MDMIdPAccount - err := sqlx.GetContext(ctx, ds.reader(ctx), &acct, stmt, ref) - if err != nil { - if err == sql.ErrNoRows { - return nil, ctxerr.Wrap(ctx, notFound("MDMIdPAccount").WithMessage(fmt.Sprintf("with fleet_enroll_ref %s", ref))) + return nil, ctxerr.Wrap(ctx, notFound("MDMIdPAccount").WithMessage(fmt.Sprintf("with uuid %s", uuid))) } return nil, ctxerr.Wrap(ctx, err, "select mdm_idp_accounts") } @@ -3676,20 +3645,6 @@ func (ds *Datastore) MDMResetEnrollment(ctx context.Context, hostUUID string) er return ctxerr.Wrap(ctx, err, "resetting disk encryption key information for host") } - // Delete any stored host emails sourced from mdm_idp_accounts. Note that we aren't deleting - // the mdm_idp_accounts themselves, just the host_emails associated with the host. This - // ensures that hosts that reenroll without IdP will have their emails removed. Hosts - // that reenroll with IdP will have their emails re-added in the - // AppleMDMPostDEPEnrollmentTask. - // - // TODO: Should we be applying any platform check here or is this ok for macOS, iOS, and Windows? - _, err = tx.ExecContext(ctx, ` - DELETE FROM host_emails - WHERE host_id = ? AND source = ?`, host.ID, fleet.DeviceMappingMDMIdpAccounts) - if err != nil { - return ctxerr.Wrap(ctx, err, "resetting host_emails sourced from mdm_idp_accounts") - } - if host.Platform == "darwin" { // Deleting the matching entry on this table will cause // the aggregate report to show this host as 'pending' to diff --git a/server/datastore/mysql/apple_mdm_test.go b/server/datastore/mysql/apple_mdm_test.go index 60507ce1cb6c..573a30492713 100644 --- a/server/datastore/mysql/apple_mdm_test.go +++ b/server/datastore/mysql/apple_mdm_test.go @@ -2470,11 +2470,11 @@ func testMDMAppleIdPAccount(t *testing.T, ds *Datastore) { require.ErrorAs(t, err, &nfe) require.Nil(t, out) - out, err = ds.GetMDMIdPAccountByAccountUUID(ctx, acc.UUID) + out, err = ds.GetMDMIdPAccountByUUID(ctx, acc.UUID) require.NoError(t, err) require.Equal(t, acc, out) - out, err = ds.GetMDMIdPAccountByAccountUUID(ctx, "BAD-TOKEN") + out, err = ds.GetMDMIdPAccountByUUID(ctx, "BAD-TOKEN") require.ErrorAs(t, err, &nfe) require.Nil(t, out) } diff --git a/server/datastore/mysql/hosts.go b/server/datastore/mysql/hosts.go index 30afa94dd11f..8c671787a41f 100644 --- a/server/datastore/mysql/hosts.go +++ b/server/datastore/mysql/hosts.go @@ -3629,78 +3629,19 @@ func (ds *Datastore) SetOrUpdateMDMData( ) } -func (ds *Datastore) SetOrUpdateHostEmailsFromMDMIdPAccountsByLegacyEnrollRef( +func (ds *Datastore) SetOrUpdateHostEmailsFromMdmIdpAccounts( ctx context.Context, hostID uint, fleetEnrollmentRef string, ) error { - if fleetEnrollmentRef == "" { - return ctxerr.New(ctx, "missing fleet enroll ref to upsert host emails with mdm idp account") - } - var email *string - idp, err := ds.GetMDMIdPAccountByLegacyEnrollRef(ctx, fleetEnrollmentRef) - if err != nil { - return err - } - email = &idp.Email - - return ds.updateOrInsert( - ctx, - `UPDATE host_emails SET email = ? WHERE host_id = ? AND source = ?`, - `INSERT INTO host_emails (email, host_id, source) VALUES (?, ?, ?)`, - email, hostID, fleet.DeviceMappingMDMIdpAccounts, - ) -} - -func (ds *Datastore) SetOrUpdateHostEmailsFromMDMIdPAccountsByHostUUID( - ctx context.Context, - hostUUID string, -) error { - if hostUUID == "" { - return ctxerr.New(ctx, "missing host uuid to upsert host emails with mdm idp account") - } - - var hid uint - var email string - host, err := ds.HostLiteByIdentifier(ctx, hostUUID) - if err != nil { - return ctxerr.Wrap(ctx, err, "getting host by identifier to upsert host emails with mdm idp account") - } - hid = host.ID - - idp, err := ds.GetMDMIdPAccountByHostUUID(ctx, hostUUID) - if err != nil { - return ctxerr.Wrap(ctx, err, "getting idp account by host uuid to upsert host emails with mdm idp account") - } - email = idp.Email - - return ds.updateOrInsert( - ctx, - `UPDATE host_emails SET email = ? WHERE host_id = ? AND source = ?`, - `INSERT INTO host_emails (email, host_id, source) VALUES (?, ?, ?)`, - email, hid, fleet.DeviceMappingMDMIdpAccounts, - ) -} - -func (ds *Datastore) SetOrUpdateEmailsFromMDMIdPAccountsByHostID( - ctx context.Context, - hostID uint, - hostUUID string, -) error { - if hostID == 0 { - return ctxerr.New(ctx, "missing host id to upsert host emails with mdm idp account") - } - if hostUUID == "" { - return ctxerr.New(ctx, "missing host uuid to upsert host emails with mdm idp account") - } - - var email string - idp, err := ds.GetMDMIdPAccountByHostUUID(ctx, hostUUID) - if err != nil { - return ctxerr.Wrap(ctx, err, "getting idp account by host uuid to upsert host emails with mdm idp account") + if fleetEnrollmentRef != "" { + idp, err := ds.GetMDMIdPAccountByUUID(ctx, fleetEnrollmentRef) + if err != nil { + return err + } + email = &idp.Email } - email = idp.Email return ds.updateOrInsert( ctx, @@ -5194,8 +5135,8 @@ func (ds *Datastore) loadHostLite(ctx context.Context, id *uint, identifier *str SELECT h.id, h.team_id, - COALESCE(h.osquery_host_id, '') AS osquery_host_id, - COALESCE(h.node_key, '') AS node_key, + h.osquery_host_id, + h.node_key, h.hostname, h.uuid, h.hardware_serial, diff --git a/server/datastore/mysql/hosts_test.go b/server/datastore/mysql/hosts_test.go index c4b0fdf25706..9e36aba7674e 100644 --- a/server/datastore/mysql/hosts_test.go +++ b/server/datastore/mysql/hosts_test.go @@ -7623,7 +7623,6 @@ func testHostsLoadHostByOrbitNodeKey(t *testing.T, ds *Datastore) { // compare only the fields we care about h.CreatedAt = returned.CreatedAt h.UpdatedAt = returned.UpdatedAt - h.LastEnrolledAt = returned.LastEnrolledAt // FIXME: this seems to be flaky (off by one second) in CI so don't compare it h.DEPAssignedToFleet = ptr.Bool(false) assert.Equal(t, h, returned) } diff --git a/server/datastore/mysql/migrations/tables/20240709175341_AddColumnsToMdmIdpAccounts.go b/server/datastore/mysql/migrations/tables/20240709175341_AddColumnsToMdmIdpAccounts.go deleted file mode 100644 index 81241d57e09d..000000000000 --- a/server/datastore/mysql/migrations/tables/20240709175341_AddColumnsToMdmIdpAccounts.go +++ /dev/null @@ -1,42 +0,0 @@ -package tables - -import ( - "database/sql" - "fmt" -) - -func init() { - MigrationClient.AddMigration(Up_20240709175341, Down_20240709175341) -} - -func Up_20240709175341(tx *sql.Tx) error { - alterStmt := ` -ALTER TABLE mdm_idp_accounts ADD COLUMN ( - host_uuid varchar(63) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', - fleet_enroll_ref varchar(63) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' -)` - - if _, err := tx.Exec(alterStmt); err != nil { - return fmt.Errorf("failed to alter mdm_idp_accounts table: %w", err) - } - - updateStmt := ` -UPDATE - mdm_idp_accounts mia - LEFT JOIN host_mdm hmdm ON mia.uuid = hmdm.fleet_enroll_ref - LEFT JOIN hosts h ON hmdm.host_id = h.id -SET - mia.fleet_enroll_ref = mia.uuid, - mia.host_uuid = COALESCE(h.uuid, ''), - mia.updated_at = mia.updated_at` - - if _, err := tx.Exec(updateStmt); err != nil { - return fmt.Errorf("failed to update data in mdm_idp_accounts: %w", err) - } - - return nil -} - -func Down_20240709175341(tx *sql.Tx) error { - return nil -} diff --git a/server/datastore/mysql/migrations/tables/20240709175341_AddColumnsToMdmIdpAccounts_test.go b/server/datastore/mysql/migrations/tables/20240709175341_AddColumnsToMdmIdpAccounts_test.go deleted file mode 100644 index fc57ba417936..000000000000 --- a/server/datastore/mysql/migrations/tables/20240709175341_AddColumnsToMdmIdpAccounts_test.go +++ /dev/null @@ -1,74 +0,0 @@ -package tables - -import ( - "context" - "fmt" - "testing" - "time" - - "github.com/fleetdm/fleet/v4/server/fleet" - "github.com/jmoiron/sqlx" - "github.com/stretchr/testify/require" -) - -func TestUp_20240709175341(t *testing.T) { - db := applyUpToPrev(t) - then := time.Now().UTC().Add(-time.Hour).Round(time.Second) - - for i := 0; i < 4; i++ { - // create some hosts with uuids that will be used in migration to populate new columns in mdm_idp_accounts - id := execNoErrLastID(t, db, `INSERT INTO hosts (uuid) VALUES (?);`, - fmt.Sprintf("host_uuid%d", i), - ) - - // insert host_mdm records that will be used in migration to populate new columns in mdm_idp_accounts - execNoErr(t, db, `INSERT INTO host_mdm (host_id, fleet_enroll_ref) VALUES (?, ?);`, - id, fmt.Sprintf("uuid%d", i), - ) - - execNoErr(t, db, ` -INSERT INTO - mdm_idp_accounts (uuid, username, fullname, email, created_at, updated_at) -VALUES - (?,?,?,?,?,?) -`, fmt.Sprintf("uuid%d", i), fmt.Sprintf("username%d", i), fmt.Sprintf("fullname%d", i), fmt.Sprintf("email%d", i), then, then) - } - - // insert an orphaned mdm_idp_account - execNoErr(t, db, ` -INSERT INTO - mdm_idp_accounts (uuid, username, fullname, email, created_at, updated_at) -VALUES - (?,?,?,?,?,?)`, "uuid4", "username4", "fullname4", "email4", then, then) - - // Apply current migration. - applyNext(t, db) - - var dest []struct { - fleet.MDMIdPAccount - CreatedAt time.Time `db:"created_at"` - UpdatedAt time.Time `db:"updated_at"` - } - - require.NoError(t, sqlx.SelectContext(context.Background(), db, &dest, `SELECT * FROM mdm_idp_accounts ORDER BY uuid;`)) - require.Len(t, dest, 5) - - for i, got := range dest { - require.Equal(t, fmt.Sprintf("uuid%d", i), got.UUID) // no change - require.Equal(t, fmt.Sprintf("username%d", i), got.Username) // no change - require.Equal(t, fmt.Sprintf("fullname%d", i), got.Fullname) // no change - require.Equal(t, fmt.Sprintf("email%d", i), got.Email) // no change - require.Equal(t, then, got.CreatedAt) // no change - require.Equal(t, then, got.UpdatedAt) // no change - - if i == 4 { - // this is the orphaned mdm_idp_account - require.Equal(t, "uuid4", got.FleetEnrollRef) // new column fleet_enroll_ref is set to uuid in migration - require.Empty(t, got.HostUUID) // new column host_uuid is not set in migration because there is no matching host - } else { - require.Equal(t, fmt.Sprintf("host_uuid%d", i), got.HostUUID) // new column host_uuid is set to host uuid in migration - require.Equal(t, fmt.Sprintf("uuid%d", i), got.FleetEnrollRef) // new column fleet_enroll_ref is set to uuid in migration - } - - } -} diff --git a/server/datastore/mysql/migrations/tables/20240710152744_AddIndexHostUuidMdmIdpAccounts.go b/server/datastore/mysql/migrations/tables/20240710152744_AddIndexHostUuidMdmIdpAccounts.go deleted file mode 100644 index b16cc8c09364..000000000000 --- a/server/datastore/mysql/migrations/tables/20240710152744_AddIndexHostUuidMdmIdpAccounts.go +++ /dev/null @@ -1,25 +0,0 @@ -package tables - -import ( - "database/sql" - "fmt" -) - -func init() { - MigrationClient.AddMigration(Up_20240710152744, Down_20240710152744) -} - -func Up_20240710152744(tx *sql.Tx) error { - _, err := tx.Exec(` - ALTER TABLE mdm_idp_accounts - ADD INDEX idx_mdm_idp_accounts_host_uuid (host_uuid)`, - ) - if err != nil { - return fmt.Errorf("failed to add idx_mdm_idp_accounts_host_uuid: %w", err) - } - return nil -} - -func Down_20240710152744(tx *sql.Tx) error { - return nil -} diff --git a/server/datastore/mysql/schema.sql b/server/datastore/mysql/schema.sql index 409ff2924ae1..41dc6c8f84ca 100644 --- a/server/datastore/mysql/schema.sql +++ b/server/datastore/mysql/schema.sql @@ -890,11 +890,8 @@ CREATE TABLE `mdm_idp_accounts` ( `email` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - `host_uuid` varchar(63) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', - `fleet_enroll_ref` varchar(63) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', PRIMARY KEY (`uuid`), - UNIQUE KEY `unique_idp_email` (`email`), - KEY `idx_mdm_idp_accounts_host_uuid` (`host_uuid`) + UNIQUE KEY `unique_idp_email` (`email`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; /*!40101 SET @saved_cs_client = @@character_set_client */; @@ -950,9 +947,9 @@ CREATE TABLE `migration_status_tables` ( `tstamp` timestamp NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `id` (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=286 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +) ENGINE=InnoDB AUTO_INCREMENT=284 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -INSERT INTO `migration_status_tables` VALUES (1,0,1,'2020-01-01 01:01:01'),(2,20161118193812,1,'2020-01-01 01:01:01'),(3,20161118211713,1,'2020-01-01 01:01:01'),(4,20161118212436,1,'2020-01-01 01:01:01'),(5,20161118212515,1,'2020-01-01 01:01:01'),(6,20161118212528,1,'2020-01-01 01:01:01'),(7,20161118212538,1,'2020-01-01 01:01:01'),(8,20161118212549,1,'2020-01-01 01:01:01'),(9,20161118212557,1,'2020-01-01 01:01:01'),(10,20161118212604,1,'2020-01-01 01:01:01'),(11,20161118212613,1,'2020-01-01 01:01:01'),(12,20161118212621,1,'2020-01-01 01:01:01'),(13,20161118212630,1,'2020-01-01 01:01:01'),(14,20161118212641,1,'2020-01-01 01:01:01'),(15,20161118212649,1,'2020-01-01 01:01:01'),(16,20161118212656,1,'2020-01-01 01:01:01'),(17,20161118212758,1,'2020-01-01 01:01:01'),(18,20161128234849,1,'2020-01-01 01:01:01'),(19,20161230162221,1,'2020-01-01 01:01:01'),(20,20170104113816,1,'2020-01-01 01:01:01'),(21,20170105151732,1,'2020-01-01 01:01:01'),(22,20170108191242,1,'2020-01-01 01:01:01'),(23,20170109094020,1,'2020-01-01 01:01:01'),(24,20170109130438,1,'2020-01-01 01:01:01'),(25,20170110202752,1,'2020-01-01 01:01:01'),(26,20170111133013,1,'2020-01-01 01:01:01'),(27,20170117025759,1,'2020-01-01 01:01:01'),(28,20170118191001,1,'2020-01-01 01:01:01'),(29,20170119234632,1,'2020-01-01 01:01:01'),(30,20170124230432,1,'2020-01-01 01:01:01'),(31,20170127014618,1,'2020-01-01 01:01:01'),(32,20170131232841,1,'2020-01-01 01:01:01'),(33,20170223094154,1,'2020-01-01 01:01:01'),(34,20170306075207,1,'2020-01-01 01:01:01'),(35,20170309100733,1,'2020-01-01 01:01:01'),(36,20170331111922,1,'2020-01-01 01:01:01'),(37,20170502143928,1,'2020-01-01 01:01:01'),(38,20170504130602,1,'2020-01-01 01:01:01'),(39,20170509132100,1,'2020-01-01 01:01:01'),(40,20170519105647,1,'2020-01-01 01:01:01'),(41,20170519105648,1,'2020-01-01 01:01:01'),(42,20170831234300,1,'2020-01-01 01:01:01'),(43,20170831234301,1,'2020-01-01 01:01:01'),(44,20170831234303,1,'2020-01-01 01:01:01'),(45,20171116163618,1,'2020-01-01 01:01:01'),(46,20171219164727,1,'2020-01-01 01:01:01'),(47,20180620164811,1,'2020-01-01 01:01:01'),(48,20180620175054,1,'2020-01-01 01:01:01'),(49,20180620175055,1,'2020-01-01 01:01:01'),(50,20191010101639,1,'2020-01-01 01:01:01'),(51,20191010155147,1,'2020-01-01 01:01:01'),(52,20191220130734,1,'2020-01-01 01:01:01'),(53,20200311140000,1,'2020-01-01 01:01:01'),(54,20200405120000,1,'2020-01-01 01:01:01'),(55,20200407120000,1,'2020-01-01 01:01:01'),(56,20200420120000,1,'2020-01-01 01:01:01'),(57,20200504120000,1,'2020-01-01 01:01:01'),(58,20200512120000,1,'2020-01-01 01:01:01'),(59,20200707120000,1,'2020-01-01 01:01:01'),(60,20201011162341,1,'2020-01-01 01:01:01'),(61,20201021104586,1,'2020-01-01 01:01:01'),(62,20201102112520,1,'2020-01-01 01:01:01'),(63,20201208121729,1,'2020-01-01 01:01:01'),(64,20201215091637,1,'2020-01-01 01:01:01'),(65,20210119174155,1,'2020-01-01 01:01:01'),(66,20210326182902,1,'2020-01-01 01:01:01'),(67,20210421112652,1,'2020-01-01 01:01:01'),(68,20210506095025,1,'2020-01-01 01:01:01'),(69,20210513115729,1,'2020-01-01 01:01:01'),(70,20210526113559,1,'2020-01-01 01:01:01'),(71,20210601000001,1,'2020-01-01 01:01:01'),(72,20210601000002,1,'2020-01-01 01:01:01'),(73,20210601000003,1,'2020-01-01 01:01:01'),(74,20210601000004,1,'2020-01-01 01:01:01'),(75,20210601000005,1,'2020-01-01 01:01:01'),(76,20210601000006,1,'2020-01-01 01:01:01'),(77,20210601000007,1,'2020-01-01 01:01:01'),(78,20210601000008,1,'2020-01-01 01:01:01'),(79,20210606151329,1,'2020-01-01 01:01:01'),(80,20210616163757,1,'2020-01-01 01:01:01'),(81,20210617174723,1,'2020-01-01 01:01:01'),(82,20210622160235,1,'2020-01-01 01:01:01'),(83,20210623100031,1,'2020-01-01 01:01:01'),(84,20210623133615,1,'2020-01-01 01:01:01'),(85,20210708143152,1,'2020-01-01 01:01:01'),(86,20210709124443,1,'2020-01-01 01:01:01'),(87,20210712155608,1,'2020-01-01 01:01:01'),(88,20210714102108,1,'2020-01-01 01:01:01'),(89,20210719153709,1,'2020-01-01 01:01:01'),(90,20210721171531,1,'2020-01-01 01:01:01'),(91,20210723135713,1,'2020-01-01 01:01:01'),(92,20210802135933,1,'2020-01-01 01:01:01'),(93,20210806112844,1,'2020-01-01 01:01:01'),(94,20210810095603,1,'2020-01-01 01:01:01'),(95,20210811150223,1,'2020-01-01 01:01:01'),(96,20210818151827,1,'2020-01-01 01:01:01'),(97,20210818151828,1,'2020-01-01 01:01:01'),(98,20210818182258,1,'2020-01-01 01:01:01'),(99,20210819131107,1,'2020-01-01 01:01:01'),(100,20210819143446,1,'2020-01-01 01:01:01'),(101,20210903132338,1,'2020-01-01 01:01:01'),(102,20210915144307,1,'2020-01-01 01:01:01'),(103,20210920155130,1,'2020-01-01 01:01:01'),(104,20210927143115,1,'2020-01-01 01:01:01'),(105,20210927143116,1,'2020-01-01 01:01:01'),(106,20211013133706,1,'2020-01-01 01:01:01'),(107,20211013133707,1,'2020-01-01 01:01:01'),(108,20211102135149,1,'2020-01-01 01:01:01'),(109,20211109121546,1,'2020-01-01 01:01:01'),(110,20211110163320,1,'2020-01-01 01:01:01'),(111,20211116184029,1,'2020-01-01 01:01:01'),(112,20211116184030,1,'2020-01-01 01:01:01'),(113,20211202092042,1,'2020-01-01 01:01:01'),(114,20211202181033,1,'2020-01-01 01:01:01'),(115,20211207161856,1,'2020-01-01 01:01:01'),(116,20211216131203,1,'2020-01-01 01:01:01'),(117,20211221110132,1,'2020-01-01 01:01:01'),(118,20220107155700,1,'2020-01-01 01:01:01'),(119,20220125105650,1,'2020-01-01 01:01:01'),(120,20220201084510,1,'2020-01-01 01:01:01'),(121,20220208144830,1,'2020-01-01 01:01:01'),(122,20220208144831,1,'2020-01-01 01:01:01'),(123,20220215152203,1,'2020-01-01 01:01:01'),(124,20220223113157,1,'2020-01-01 01:01:01'),(125,20220307104655,1,'2020-01-01 01:01:01'),(126,20220309133956,1,'2020-01-01 01:01:01'),(127,20220316155700,1,'2020-01-01 01:01:01'),(128,20220323152301,1,'2020-01-01 01:01:01'),(129,20220330100659,1,'2020-01-01 01:01:01'),(130,20220404091216,1,'2020-01-01 01:01:01'),(131,20220419140750,1,'2020-01-01 01:01:01'),(132,20220428140039,1,'2020-01-01 01:01:01'),(133,20220503134048,1,'2020-01-01 01:01:01'),(134,20220524102918,1,'2020-01-01 01:01:01'),(135,20220526123327,1,'2020-01-01 01:01:01'),(136,20220526123328,1,'2020-01-01 01:01:01'),(137,20220526123329,1,'2020-01-01 01:01:01'),(138,20220608113128,1,'2020-01-01 01:01:01'),(139,20220627104817,1,'2020-01-01 01:01:01'),(140,20220704101843,1,'2020-01-01 01:01:01'),(141,20220708095046,1,'2020-01-01 01:01:01'),(142,20220713091130,1,'2020-01-01 01:01:01'),(143,20220802135510,1,'2020-01-01 01:01:01'),(144,20220818101352,1,'2020-01-01 01:01:01'),(145,20220822161445,1,'2020-01-01 01:01:01'),(146,20220831100036,1,'2020-01-01 01:01:01'),(147,20220831100151,1,'2020-01-01 01:01:01'),(148,20220908181826,1,'2020-01-01 01:01:01'),(149,20220914154915,1,'2020-01-01 01:01:01'),(150,20220915165115,1,'2020-01-01 01:01:01'),(151,20220915165116,1,'2020-01-01 01:01:01'),(152,20220928100158,1,'2020-01-01 01:01:01'),(153,20221014084130,1,'2020-01-01 01:01:01'),(154,20221027085019,1,'2020-01-01 01:01:01'),(155,20221101103952,1,'2020-01-01 01:01:01'),(156,20221104144401,1,'2020-01-01 01:01:01'),(157,20221109100749,1,'2020-01-01 01:01:01'),(158,20221115104546,1,'2020-01-01 01:01:01'),(159,20221130114928,1,'2020-01-01 01:01:01'),(160,20221205112142,1,'2020-01-01 01:01:01'),(161,20221216115820,1,'2020-01-01 01:01:01'),(162,20221220195934,1,'2020-01-01 01:01:01'),(163,20221220195935,1,'2020-01-01 01:01:01'),(164,20221223174807,1,'2020-01-01 01:01:01'),(165,20221227163855,1,'2020-01-01 01:01:01'),(166,20221227163856,1,'2020-01-01 01:01:01'),(167,20230202224725,1,'2020-01-01 01:01:01'),(168,20230206163608,1,'2020-01-01 01:01:01'),(169,20230214131519,1,'2020-01-01 01:01:01'),(170,20230303135738,1,'2020-01-01 01:01:01'),(171,20230313135301,1,'2020-01-01 01:01:01'),(172,20230313141819,1,'2020-01-01 01:01:01'),(173,20230315104937,1,'2020-01-01 01:01:01'),(174,20230317173844,1,'2020-01-01 01:01:01'),(175,20230320133602,1,'2020-01-01 01:01:01'),(176,20230330100011,1,'2020-01-01 01:01:01'),(177,20230330134823,1,'2020-01-01 01:01:01'),(178,20230405232025,1,'2020-01-01 01:01:01'),(179,20230408084104,1,'2020-01-01 01:01:01'),(180,20230411102858,1,'2020-01-01 01:01:01'),(181,20230421155932,1,'2020-01-01 01:01:01'),(182,20230425082126,1,'2020-01-01 01:01:01'),(183,20230425105727,1,'2020-01-01 01:01:01'),(184,20230501154913,1,'2020-01-01 01:01:01'),(185,20230503101418,1,'2020-01-01 01:01:01'),(186,20230515144206,1,'2020-01-01 01:01:01'),(187,20230517140952,1,'2020-01-01 01:01:01'),(188,20230517152807,1,'2020-01-01 01:01:01'),(189,20230518114155,1,'2020-01-01 01:01:01'),(190,20230520153236,1,'2020-01-01 01:01:01'),(191,20230525151159,1,'2020-01-01 01:01:01'),(192,20230530122103,1,'2020-01-01 01:01:01'),(193,20230602111827,1,'2020-01-01 01:01:01'),(194,20230608103123,1,'2020-01-01 01:01:01'),(195,20230629140529,1,'2020-01-01 01:01:01'),(196,20230629140530,1,'2020-01-01 01:01:01'),(197,20230711144622,1,'2020-01-01 01:01:01'),(198,20230721135421,1,'2020-01-01 01:01:01'),(199,20230721161508,1,'2020-01-01 01:01:01'),(200,20230726115701,1,'2020-01-01 01:01:01'),(201,20230807100822,1,'2020-01-01 01:01:01'),(202,20230814150442,1,'2020-01-01 01:01:01'),(203,20230823122728,1,'2020-01-01 01:01:01'),(204,20230906152143,1,'2020-01-01 01:01:01'),(205,20230911163618,1,'2020-01-01 01:01:01'),(206,20230912101759,1,'2020-01-01 01:01:01'),(207,20230915101341,1,'2020-01-01 01:01:01'),(208,20230918132351,1,'2020-01-01 01:01:01'),(209,20231004144339,1,'2020-01-01 01:01:01'),(210,20231009094541,1,'2020-01-01 01:01:01'),(211,20231009094542,1,'2020-01-01 01:01:01'),(212,20231009094543,1,'2020-01-01 01:01:01'),(213,20231009094544,1,'2020-01-01 01:01:01'),(214,20231016091915,1,'2020-01-01 01:01:01'),(215,20231024174135,1,'2020-01-01 01:01:01'),(216,20231025120016,1,'2020-01-01 01:01:01'),(217,20231025160156,1,'2020-01-01 01:01:01'),(218,20231031165350,1,'2020-01-01 01:01:01'),(219,20231106144110,1,'2020-01-01 01:01:01'),(220,20231107130934,1,'2020-01-01 01:01:01'),(221,20231109115838,1,'2020-01-01 01:01:01'),(222,20231121054530,1,'2020-01-01 01:01:01'),(223,20231122101320,1,'2020-01-01 01:01:01'),(224,20231130132828,1,'2020-01-01 01:01:01'),(225,20231130132931,1,'2020-01-01 01:01:01'),(226,20231204155427,1,'2020-01-01 01:01:01'),(227,20231206142340,1,'2020-01-01 01:01:01'),(228,20231207102320,1,'2020-01-01 01:01:01'),(229,20231207102321,1,'2020-01-01 01:01:01'),(230,20231207133731,1,'2020-01-01 01:01:01'),(231,20231212094238,1,'2020-01-01 01:01:01'),(232,20231212095734,1,'2020-01-01 01:01:01'),(233,20231212161121,1,'2020-01-01 01:01:01'),(234,20231215122713,1,'2020-01-01 01:01:01'),(235,20231219143041,1,'2020-01-01 01:01:01'),(236,20231224070653,1,'2020-01-01 01:01:01'),(237,20240110134315,1,'2020-01-01 01:01:01'),(238,20240119091637,1,'2020-01-01 01:01:01'),(239,20240126020642,1,'2020-01-01 01:01:01'),(240,20240126020643,1,'2020-01-01 01:01:01'),(241,20240129162819,1,'2020-01-01 01:01:01'),(242,20240130115133,1,'2020-01-01 01:01:01'),(243,20240131083822,1,'2020-01-01 01:01:01'),(244,20240205095928,1,'2020-01-01 01:01:01'),(245,20240205121956,1,'2020-01-01 01:01:01'),(246,20240209110212,1,'2020-01-01 01:01:01'),(247,20240212111533,1,'2020-01-01 01:01:01'),(248,20240221112844,1,'2020-01-01 01:01:01'),(249,20240222073518,1,'2020-01-01 01:01:01'),(250,20240222135115,1,'2020-01-01 01:01:01'),(251,20240226082255,1,'2020-01-01 01:01:01'),(252,20240228082706,1,'2020-01-01 01:01:01'),(253,20240301173035,1,'2020-01-01 01:01:01'),(254,20240302111134,1,'2020-01-01 01:01:01'),(255,20240312103753,1,'2020-01-01 01:01:01'),(256,20240313143416,1,'2020-01-01 01:01:01'),(257,20240314085226,1,'2020-01-01 01:01:01'),(258,20240314151747,1,'2020-01-01 01:01:01'),(259,20240320145650,1,'2020-01-01 01:01:01'),(260,20240327115530,1,'2020-01-01 01:01:01'),(261,20240327115617,1,'2020-01-01 01:01:01'),(262,20240408085837,1,'2020-01-01 01:01:01'),(263,20240415104633,1,'2020-01-01 01:01:01'),(264,20240430111727,1,'2020-01-01 01:01:01'),(265,20240515200020,1,'2020-01-01 01:01:01'),(266,20240521143023,1,'2020-01-01 01:01:01'),(267,20240521143024,1,'2020-01-01 01:01:01'),(268,20240601174138,1,'2020-01-01 01:01:01'),(269,20240607133721,1,'2020-01-01 01:01:01'),(270,20240612150059,1,'2020-01-01 01:01:01'),(271,20240613162201,1,'2020-01-01 01:01:01'),(272,20240613172616,1,'2020-01-01 01:01:01'),(273,20240618142419,1,'2020-01-01 01:01:01'),(274,20240625093543,1,'2020-01-01 01:01:01'),(275,20240626195531,1,'2020-01-01 01:01:01'),(276,20240702123921,1,'2020-01-01 01:01:01'),(277,20240703154849,1,'2020-01-01 01:01:01'),(278,20240707134035,1,'2020-01-01 01:01:01'),(279,20240707134036,1,'2020-01-01 01:01:01'),(280,20240709124958,1,'2020-01-01 01:01:01'),(281,20240709132642,1,'2020-01-01 01:01:01'),(282,20240709175341,1,'2020-01-01 01:01:01'),(283,20240709183940,1,'2020-01-01 01:01:01'),(284,20240710152744,1,'2020-01-01 01:01:01'),(285,20240710155623,1,'2020-01-01 01:01:01'); +INSERT INTO `migration_status_tables` VALUES (1,0,1,'2020-01-01 01:01:01'),(2,20161118193812,1,'2020-01-01 01:01:01'),(3,20161118211713,1,'2020-01-01 01:01:01'),(4,20161118212436,1,'2020-01-01 01:01:01'),(5,20161118212515,1,'2020-01-01 01:01:01'),(6,20161118212528,1,'2020-01-01 01:01:01'),(7,20161118212538,1,'2020-01-01 01:01:01'),(8,20161118212549,1,'2020-01-01 01:01:01'),(9,20161118212557,1,'2020-01-01 01:01:01'),(10,20161118212604,1,'2020-01-01 01:01:01'),(11,20161118212613,1,'2020-01-01 01:01:01'),(12,20161118212621,1,'2020-01-01 01:01:01'),(13,20161118212630,1,'2020-01-01 01:01:01'),(14,20161118212641,1,'2020-01-01 01:01:01'),(15,20161118212649,1,'2020-01-01 01:01:01'),(16,20161118212656,1,'2020-01-01 01:01:01'),(17,20161118212758,1,'2020-01-01 01:01:01'),(18,20161128234849,1,'2020-01-01 01:01:01'),(19,20161230162221,1,'2020-01-01 01:01:01'),(20,20170104113816,1,'2020-01-01 01:01:01'),(21,20170105151732,1,'2020-01-01 01:01:01'),(22,20170108191242,1,'2020-01-01 01:01:01'),(23,20170109094020,1,'2020-01-01 01:01:01'),(24,20170109130438,1,'2020-01-01 01:01:01'),(25,20170110202752,1,'2020-01-01 01:01:01'),(26,20170111133013,1,'2020-01-01 01:01:01'),(27,20170117025759,1,'2020-01-01 01:01:01'),(28,20170118191001,1,'2020-01-01 01:01:01'),(29,20170119234632,1,'2020-01-01 01:01:01'),(30,20170124230432,1,'2020-01-01 01:01:01'),(31,20170127014618,1,'2020-01-01 01:01:01'),(32,20170131232841,1,'2020-01-01 01:01:01'),(33,20170223094154,1,'2020-01-01 01:01:01'),(34,20170306075207,1,'2020-01-01 01:01:01'),(35,20170309100733,1,'2020-01-01 01:01:01'),(36,20170331111922,1,'2020-01-01 01:01:01'),(37,20170502143928,1,'2020-01-01 01:01:01'),(38,20170504130602,1,'2020-01-01 01:01:01'),(39,20170509132100,1,'2020-01-01 01:01:01'),(40,20170519105647,1,'2020-01-01 01:01:01'),(41,20170519105648,1,'2020-01-01 01:01:01'),(42,20170831234300,1,'2020-01-01 01:01:01'),(43,20170831234301,1,'2020-01-01 01:01:01'),(44,20170831234303,1,'2020-01-01 01:01:01'),(45,20171116163618,1,'2020-01-01 01:01:01'),(46,20171219164727,1,'2020-01-01 01:01:01'),(47,20180620164811,1,'2020-01-01 01:01:01'),(48,20180620175054,1,'2020-01-01 01:01:01'),(49,20180620175055,1,'2020-01-01 01:01:01'),(50,20191010101639,1,'2020-01-01 01:01:01'),(51,20191010155147,1,'2020-01-01 01:01:01'),(52,20191220130734,1,'2020-01-01 01:01:01'),(53,20200311140000,1,'2020-01-01 01:01:01'),(54,20200405120000,1,'2020-01-01 01:01:01'),(55,20200407120000,1,'2020-01-01 01:01:01'),(56,20200420120000,1,'2020-01-01 01:01:01'),(57,20200504120000,1,'2020-01-01 01:01:01'),(58,20200512120000,1,'2020-01-01 01:01:01'),(59,20200707120000,1,'2020-01-01 01:01:01'),(60,20201011162341,1,'2020-01-01 01:01:01'),(61,20201021104586,1,'2020-01-01 01:01:01'),(62,20201102112520,1,'2020-01-01 01:01:01'),(63,20201208121729,1,'2020-01-01 01:01:01'),(64,20201215091637,1,'2020-01-01 01:01:01'),(65,20210119174155,1,'2020-01-01 01:01:01'),(66,20210326182902,1,'2020-01-01 01:01:01'),(67,20210421112652,1,'2020-01-01 01:01:01'),(68,20210506095025,1,'2020-01-01 01:01:01'),(69,20210513115729,1,'2020-01-01 01:01:01'),(70,20210526113559,1,'2020-01-01 01:01:01'),(71,20210601000001,1,'2020-01-01 01:01:01'),(72,20210601000002,1,'2020-01-01 01:01:01'),(73,20210601000003,1,'2020-01-01 01:01:01'),(74,20210601000004,1,'2020-01-01 01:01:01'),(75,20210601000005,1,'2020-01-01 01:01:01'),(76,20210601000006,1,'2020-01-01 01:01:01'),(77,20210601000007,1,'2020-01-01 01:01:01'),(78,20210601000008,1,'2020-01-01 01:01:01'),(79,20210606151329,1,'2020-01-01 01:01:01'),(80,20210616163757,1,'2020-01-01 01:01:01'),(81,20210617174723,1,'2020-01-01 01:01:01'),(82,20210622160235,1,'2020-01-01 01:01:01'),(83,20210623100031,1,'2020-01-01 01:01:01'),(84,20210623133615,1,'2020-01-01 01:01:01'),(85,20210708143152,1,'2020-01-01 01:01:01'),(86,20210709124443,1,'2020-01-01 01:01:01'),(87,20210712155608,1,'2020-01-01 01:01:01'),(88,20210714102108,1,'2020-01-01 01:01:01'),(89,20210719153709,1,'2020-01-01 01:01:01'),(90,20210721171531,1,'2020-01-01 01:01:01'),(91,20210723135713,1,'2020-01-01 01:01:01'),(92,20210802135933,1,'2020-01-01 01:01:01'),(93,20210806112844,1,'2020-01-01 01:01:01'),(94,20210810095603,1,'2020-01-01 01:01:01'),(95,20210811150223,1,'2020-01-01 01:01:01'),(96,20210818151827,1,'2020-01-01 01:01:01'),(97,20210818151828,1,'2020-01-01 01:01:01'),(98,20210818182258,1,'2020-01-01 01:01:01'),(99,20210819131107,1,'2020-01-01 01:01:01'),(100,20210819143446,1,'2020-01-01 01:01:01'),(101,20210903132338,1,'2020-01-01 01:01:01'),(102,20210915144307,1,'2020-01-01 01:01:01'),(103,20210920155130,1,'2020-01-01 01:01:01'),(104,20210927143115,1,'2020-01-01 01:01:01'),(105,20210927143116,1,'2020-01-01 01:01:01'),(106,20211013133706,1,'2020-01-01 01:01:01'),(107,20211013133707,1,'2020-01-01 01:01:01'),(108,20211102135149,1,'2020-01-01 01:01:01'),(109,20211109121546,1,'2020-01-01 01:01:01'),(110,20211110163320,1,'2020-01-01 01:01:01'),(111,20211116184029,1,'2020-01-01 01:01:01'),(112,20211116184030,1,'2020-01-01 01:01:01'),(113,20211202092042,1,'2020-01-01 01:01:01'),(114,20211202181033,1,'2020-01-01 01:01:01'),(115,20211207161856,1,'2020-01-01 01:01:01'),(116,20211216131203,1,'2020-01-01 01:01:01'),(117,20211221110132,1,'2020-01-01 01:01:01'),(118,20220107155700,1,'2020-01-01 01:01:01'),(119,20220125105650,1,'2020-01-01 01:01:01'),(120,20220201084510,1,'2020-01-01 01:01:01'),(121,20220208144830,1,'2020-01-01 01:01:01'),(122,20220208144831,1,'2020-01-01 01:01:01'),(123,20220215152203,1,'2020-01-01 01:01:01'),(124,20220223113157,1,'2020-01-01 01:01:01'),(125,20220307104655,1,'2020-01-01 01:01:01'),(126,20220309133956,1,'2020-01-01 01:01:01'),(127,20220316155700,1,'2020-01-01 01:01:01'),(128,20220323152301,1,'2020-01-01 01:01:01'),(129,20220330100659,1,'2020-01-01 01:01:01'),(130,20220404091216,1,'2020-01-01 01:01:01'),(131,20220419140750,1,'2020-01-01 01:01:01'),(132,20220428140039,1,'2020-01-01 01:01:01'),(133,20220503134048,1,'2020-01-01 01:01:01'),(134,20220524102918,1,'2020-01-01 01:01:01'),(135,20220526123327,1,'2020-01-01 01:01:01'),(136,20220526123328,1,'2020-01-01 01:01:01'),(137,20220526123329,1,'2020-01-01 01:01:01'),(138,20220608113128,1,'2020-01-01 01:01:01'),(139,20220627104817,1,'2020-01-01 01:01:01'),(140,20220704101843,1,'2020-01-01 01:01:01'),(141,20220708095046,1,'2020-01-01 01:01:01'),(142,20220713091130,1,'2020-01-01 01:01:01'),(143,20220802135510,1,'2020-01-01 01:01:01'),(144,20220818101352,1,'2020-01-01 01:01:01'),(145,20220822161445,1,'2020-01-01 01:01:01'),(146,20220831100036,1,'2020-01-01 01:01:01'),(147,20220831100151,1,'2020-01-01 01:01:01'),(148,20220908181826,1,'2020-01-01 01:01:01'),(149,20220914154915,1,'2020-01-01 01:01:01'),(150,20220915165115,1,'2020-01-01 01:01:01'),(151,20220915165116,1,'2020-01-01 01:01:01'),(152,20220928100158,1,'2020-01-01 01:01:01'),(153,20221014084130,1,'2020-01-01 01:01:01'),(154,20221027085019,1,'2020-01-01 01:01:01'),(155,20221101103952,1,'2020-01-01 01:01:01'),(156,20221104144401,1,'2020-01-01 01:01:01'),(157,20221109100749,1,'2020-01-01 01:01:01'),(158,20221115104546,1,'2020-01-01 01:01:01'),(159,20221130114928,1,'2020-01-01 01:01:01'),(160,20221205112142,1,'2020-01-01 01:01:01'),(161,20221216115820,1,'2020-01-01 01:01:01'),(162,20221220195934,1,'2020-01-01 01:01:01'),(163,20221220195935,1,'2020-01-01 01:01:01'),(164,20221223174807,1,'2020-01-01 01:01:01'),(165,20221227163855,1,'2020-01-01 01:01:01'),(166,20221227163856,1,'2020-01-01 01:01:01'),(167,20230202224725,1,'2020-01-01 01:01:01'),(168,20230206163608,1,'2020-01-01 01:01:01'),(169,20230214131519,1,'2020-01-01 01:01:01'),(170,20230303135738,1,'2020-01-01 01:01:01'),(171,20230313135301,1,'2020-01-01 01:01:01'),(172,20230313141819,1,'2020-01-01 01:01:01'),(173,20230315104937,1,'2020-01-01 01:01:01'),(174,20230317173844,1,'2020-01-01 01:01:01'),(175,20230320133602,1,'2020-01-01 01:01:01'),(176,20230330100011,1,'2020-01-01 01:01:01'),(177,20230330134823,1,'2020-01-01 01:01:01'),(178,20230405232025,1,'2020-01-01 01:01:01'),(179,20230408084104,1,'2020-01-01 01:01:01'),(180,20230411102858,1,'2020-01-01 01:01:01'),(181,20230421155932,1,'2020-01-01 01:01:01'),(182,20230425082126,1,'2020-01-01 01:01:01'),(183,20230425105727,1,'2020-01-01 01:01:01'),(184,20230501154913,1,'2020-01-01 01:01:01'),(185,20230503101418,1,'2020-01-01 01:01:01'),(186,20230515144206,1,'2020-01-01 01:01:01'),(187,20230517140952,1,'2020-01-01 01:01:01'),(188,20230517152807,1,'2020-01-01 01:01:01'),(189,20230518114155,1,'2020-01-01 01:01:01'),(190,20230520153236,1,'2020-01-01 01:01:01'),(191,20230525151159,1,'2020-01-01 01:01:01'),(192,20230530122103,1,'2020-01-01 01:01:01'),(193,20230602111827,1,'2020-01-01 01:01:01'),(194,20230608103123,1,'2020-01-01 01:01:01'),(195,20230629140529,1,'2020-01-01 01:01:01'),(196,20230629140530,1,'2020-01-01 01:01:01'),(197,20230711144622,1,'2020-01-01 01:01:01'),(198,20230721135421,1,'2020-01-01 01:01:01'),(199,20230721161508,1,'2020-01-01 01:01:01'),(200,20230726115701,1,'2020-01-01 01:01:01'),(201,20230807100822,1,'2020-01-01 01:01:01'),(202,20230814150442,1,'2020-01-01 01:01:01'),(203,20230823122728,1,'2020-01-01 01:01:01'),(204,20230906152143,1,'2020-01-01 01:01:01'),(205,20230911163618,1,'2020-01-01 01:01:01'),(206,20230912101759,1,'2020-01-01 01:01:01'),(207,20230915101341,1,'2020-01-01 01:01:01'),(208,20230918132351,1,'2020-01-01 01:01:01'),(209,20231004144339,1,'2020-01-01 01:01:01'),(210,20231009094541,1,'2020-01-01 01:01:01'),(211,20231009094542,1,'2020-01-01 01:01:01'),(212,20231009094543,1,'2020-01-01 01:01:01'),(213,20231009094544,1,'2020-01-01 01:01:01'),(214,20231016091915,1,'2020-01-01 01:01:01'),(215,20231024174135,1,'2020-01-01 01:01:01'),(216,20231025120016,1,'2020-01-01 01:01:01'),(217,20231025160156,1,'2020-01-01 01:01:01'),(218,20231031165350,1,'2020-01-01 01:01:01'),(219,20231106144110,1,'2020-01-01 01:01:01'),(220,20231107130934,1,'2020-01-01 01:01:01'),(221,20231109115838,1,'2020-01-01 01:01:01'),(222,20231121054530,1,'2020-01-01 01:01:01'),(223,20231122101320,1,'2020-01-01 01:01:01'),(224,20231130132828,1,'2020-01-01 01:01:01'),(225,20231130132931,1,'2020-01-01 01:01:01'),(226,20231204155427,1,'2020-01-01 01:01:01'),(227,20231206142340,1,'2020-01-01 01:01:01'),(228,20231207102320,1,'2020-01-01 01:01:01'),(229,20231207102321,1,'2020-01-01 01:01:01'),(230,20231207133731,1,'2020-01-01 01:01:01'),(231,20231212094238,1,'2020-01-01 01:01:01'),(232,20231212095734,1,'2020-01-01 01:01:01'),(233,20231212161121,1,'2020-01-01 01:01:01'),(234,20231215122713,1,'2020-01-01 01:01:01'),(235,20231219143041,1,'2020-01-01 01:01:01'),(236,20231224070653,1,'2020-01-01 01:01:01'),(237,20240110134315,1,'2020-01-01 01:01:01'),(238,20240119091637,1,'2020-01-01 01:01:01'),(239,20240126020642,1,'2020-01-01 01:01:01'),(240,20240126020643,1,'2020-01-01 01:01:01'),(241,20240129162819,1,'2020-01-01 01:01:01'),(242,20240130115133,1,'2020-01-01 01:01:01'),(243,20240131083822,1,'2020-01-01 01:01:01'),(244,20240205095928,1,'2020-01-01 01:01:01'),(245,20240205121956,1,'2020-01-01 01:01:01'),(246,20240209110212,1,'2020-01-01 01:01:01'),(247,20240212111533,1,'2020-01-01 01:01:01'),(248,20240221112844,1,'2020-01-01 01:01:01'),(249,20240222073518,1,'2020-01-01 01:01:01'),(250,20240222135115,1,'2020-01-01 01:01:01'),(251,20240226082255,1,'2020-01-01 01:01:01'),(252,20240228082706,1,'2020-01-01 01:01:01'),(253,20240301173035,1,'2020-01-01 01:01:01'),(254,20240302111134,1,'2020-01-01 01:01:01'),(255,20240312103753,1,'2020-01-01 01:01:01'),(256,20240313143416,1,'2020-01-01 01:01:01'),(257,20240314085226,1,'2020-01-01 01:01:01'),(258,20240314151747,1,'2020-01-01 01:01:01'),(259,20240320145650,1,'2020-01-01 01:01:01'),(260,20240327115530,1,'2020-01-01 01:01:01'),(261,20240327115617,1,'2020-01-01 01:01:01'),(262,20240408085837,1,'2020-01-01 01:01:01'),(263,20240415104633,1,'2020-01-01 01:01:01'),(264,20240430111727,1,'2020-01-01 01:01:01'),(265,20240515200020,1,'2020-01-01 01:01:01'),(266,20240521143023,1,'2020-01-01 01:01:01'),(267,20240521143024,1,'2020-01-01 01:01:01'),(268,20240601174138,1,'2020-01-01 01:01:01'),(269,20240607133721,1,'2020-01-01 01:01:01'),(270,20240612150059,1,'2020-01-01 01:01:01'),(271,20240613162201,1,'2020-01-01 01:01:01'),(272,20240613172616,1,'2020-01-01 01:01:01'),(273,20240618142419,1,'2020-01-01 01:01:01'),(274,20240625093543,1,'2020-01-01 01:01:01'),(275,20240626195531,1,'2020-01-01 01:01:01'),(276,20240702123921,1,'2020-01-01 01:01:01'),(277,20240703154849,1,'2020-01-01 01:01:01'),(278,20240707134035,1,'2020-01-01 01:01:01'),(279,20240707134036,1,'2020-01-01 01:01:01'),(280,20240709124958,1,'2020-01-01 01:01:01'),(281,20240709132642,1,'2020-01-01 01:01:01'),(282,20240709183940,1,'2020-01-01 01:01:01'),(283,20240710155623,1,'2020-01-01 01:01:01'); /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; CREATE TABLE `mobile_device_management_solutions` ( diff --git a/server/fleet/datastore.go b/server/fleet/datastore.go index d8a2e34b34d8..cd9c904f3a59 100644 --- a/server/fleet/datastore.go +++ b/server/fleet/datastore.go @@ -861,26 +861,9 @@ type Datastore interface { SetOrUpdateMunkiInfo(ctx context.Context, hostID uint, version string, errors, warnings []string) error SetOrUpdateMDMData(ctx context.Context, hostID uint, isServer, enrolled bool, serverURL string, installedFromDep bool, name string, fleetEnrollRef string) error - // SetOrUpdateHostEmailsFromMDMIdPAccountsByLegacyEnrollRef sets or updates the host emails associated with the provided - // host based on the MDM IdP account information associated with the provided fleet enrollment - // reference. - // - // Deprecated: Use SetOrUpdateHostEmailsFromMdmIdpAccountsByHostUUID instead. - SetOrUpdateHostEmailsFromMDMIdPAccountsByLegacyEnrollRef(ctx context.Context, hostID uint, fleetEnrollmentRef string) error - // SetOrUpdateHostEmailsFromMDMIdPAccountsByHostUUID sets or updates the host emails associated - // with the provided host uuid based on the MDM IdP account information (if any) associated with the - // provided host uuid. - // - // Note: Use this method only if the host ID is not available to the caller, otherwise use - // SetOrUpdateHostEmailsFromMdmIdpAccountsByHostID. - SetOrUpdateHostEmailsFromMDMIdPAccountsByHostUUID(ctx context.Context, hostUUID string) error - // SetOrUpdateEmailsFromMDMIdPAccountsByHostID sets or updates the host emails associated with - // the provided host ID based on the MDM IdP account information (if any) associated with the - // provided host UUID. - // - // Note: Use this method when both the host ID and host UUID are known to the caller, otherwise - // use SetOrUpdateHostEmailsFromMdmIdpAccountsByHostUUID. - SetOrUpdateEmailsFromMDMIdPAccountsByHostID(ctx context.Context, hostID uint, hostUUID string) error + // SetOrUpdateHostEmailsFromMdmIdpAccounts sets or updates the host emails associated with the provided + // host based on the MDM IdP account information associated with the provided fleet enrollment reference. + SetOrUpdateHostEmailsFromMdmIdpAccounts(ctx context.Context, hostID uint, fleetEnrollmentRef string) error SetOrUpdateHostDisksSpace(ctx context.Context, hostID uint, gigsAvailable, percentAvailable, gigsTotal float64) error SetOrUpdateHostDisksEncryption(ctx context.Context, hostID uint, encrypted bool) error // SetOrUpdateHostDiskEncryptionKey sets the base64, encrypted key for @@ -1187,21 +1170,8 @@ type Datastore interface { // InsertMDMIdPAccount inserts a new MDM IdP account InsertMDMIdPAccount(ctx context.Context, account *MDMIdPAccount) error - // AssociateMDMIdPAccount adds device info to an existing MDM IdP account - AssociateMDMIdPAccount(ctx context.Context, accountUUID string, deviceUUID string) error - - // GetMDMIdPAccountByAccountUUID returns MDM IdP account that matches the given account uuid. - GetMDMIdPAccountByAccountUUID(ctx context.Context, accountUUID string) (*MDMIdPAccount, error) - - // GetMDMIdPAccountByHostUUID returns MDM IdP account that matches the given host uuid. - GetMDMIdPAccountByHostUUID(ctx context.Context, hostUUID string) (*MDMIdPAccount, error) - - // GetMDMIdPAccountByLegacyEnrollRef returns MDM IdP account that matches the given Fleet - // enrollment ref. - // - // Deprecated: This method is deprecated and only used for backwards compatibility. - // GetMDMIdPAccountByAccountUUID and GetMDMIdPAccountByDeviceUUID are the preferred methods. - GetMDMIdPAccountByLegacyEnrollRef(ctx context.Context, ref string) (*MDMIdPAccount, error) + // GetMDMIdPAccountByUUID returns MDM IdP account that matches the given token. + GetMDMIdPAccountByUUID(ctx context.Context, uuid string) (*MDMIdPAccount, error) // GetMDMIdPAccountByEmail returns MDM IdP account that matches the given email. GetMDMIdPAccountByEmail(ctx context.Context, email string) (*MDMIdPAccount, error) diff --git a/server/fleet/mdm.go b/server/fleet/mdm.go index 1efe872a42d0..55e0a30c351c 100644 --- a/server/fleet/mdm.go +++ b/server/fleet/mdm.go @@ -66,22 +66,10 @@ type AppConfigUpdater interface { // MDMIdPAccount contains account information of a third-party IdP that can be // later used for MDM operations like creating local accounts. type MDMIdPAccount struct { - // UUID is the unique identifier created when a new user email is ingested (e.g., from the IdP response - // payload during the DEP automatic enrollment flow). It is used to subsequently associate the - // IdP account info to the device UUID extracted from the DEP webview client request. UUID string Username string Fullname string Email string - // HostUUID is the unique device identifier associated with the MDM enrollment. For Apple - // devices, it corresponds to the UDID extracted from the `x-apple-aspen-deviceinfo` header of - // the DEP webview client request. - HostUUID string `db:"host_uuid"` - // FleetEnrollRef is a legacy reference that is preserved for devices that enrolled - // via a mobileconfig that included an enrollment reference query param in the service URL. It - // is preserved for backwards compatibility with existing enrollments because Apple requires - // server URLs to match exactly when re-enrolling (e.g., via `profiles renew -type enrollment`). - FleetEnrollRef string `db:"fleet_enroll_ref"` } type MDMAppleBootstrapPackage struct { diff --git a/server/fleet/service.go b/server/fleet/service.go index 3c7c196a6b27..27bfa5b18767 100644 --- a/server/fleet/service.go +++ b/server/fleet/service.go @@ -749,7 +749,7 @@ type Service interface { GetMDMAppleProfilesSummary(ctx context.Context, teamID *uint) (*MDMProfilesSummary, error) // GetMDMAppleEnrollmentProfileByToken returns the Apple enrollment from its secret token. - GetMDMAppleEnrollmentProfileByToken(ctx context.Context, enrollmentToken string, enrollmentRef string, deviceinfo string) (profile []byte, err error) + GetMDMAppleEnrollmentProfileByToken(ctx context.Context, enrollmentToken string, enrollmentRef string) (profile []byte, err error) // GetDeviceMDMAppleEnrollmentProfile loads the raw (PList-format) enrollment // profile for the currently authenticated device. diff --git a/server/mdm/apple/AppleIncRootCertificate.cer b/server/mdm/apple/AppleIncRootCertificate.cer deleted file mode 100644 index 8a9ff247419dd22a07c837ba7394aeabdd0f14e2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1215 zcmXqLV%crb#JqR`GZP~d5E<~YacZ@Bw0-AgWMpM!Fi0}wHsEAq4rO5zW(o~96gCh9 zakzxJ9199^QWZS&lJyML3{*gZ+`_UDLFd$>lFYQsBg2!4D>>yS-j;I@c+L7YuChh5U7`KHvAiEsOqE5wMI&W5Px=0B&b;#hyADPKr1x`dQTTp(jgCTo z!8UtFgP!fq=lSQ_e%AKXkUH`2+}53ZH{)ckownU-we|}?AHyW>jf!G=C0A{DZzqYZ zUR*fIJvj8>dVR;uKYl+hIQwj|k87R0Pjj_t->jT;Rj-bAq&^<-@B zm%W!-{69S|b&uzbviZg$sSC@eoYZAvW@KPo+{9P~43RPeK43h`@-s62XJG-R8#V)e z5MLO?XEk63QUIB4HrbfL%co zBPgB8DzG#$asX{)0b&Md!c0zKWi)8~WT3^yq0I(NqwGwKVsaTJB?ZM+`ugSN<$8&r zl&P1TpQ{gMB`4||G#-X4W-@5pCe^q(C^aWDF)uk)0hmHdGBS%5lHrLqRUxTTAu+E~ zp&+rS1js5bF3n9XR!B@vPAw>b=t%?WNd@6N1&|%Uq@D!K48=g%l*FPGg_6{wT%d-$ z6ouscyp&8(HYirePg5u@PSruNs30Gx7i1YwCER{crYR^&OfJa;IuB@ONosCtUP-YY za{2^jO7!e*{cX?eJDxY@8r; zW8atJ+3zl;@Sm>qH@UIM?q|jS>=W#7YAu_)gB31Y9ND;kmOoeaf9*e!%UL;V#2vx} zUUwk!R<>!CBEM2a=7;zgw~E zguTASugG_6SFxo3)|+Pa2irq$E}yy6$m#cutA+FG76xsX-aFYzMMzw9>OIdRD+ Xyc@&=R&`yy_2kb5PImJRrKO4hMS!&; diff --git a/server/mdm/apple/deviceinfo.go b/server/mdm/apple/deviceinfo.go deleted file mode 100644 index 4506e5d3939b..000000000000 --- a/server/mdm/apple/deviceinfo.go +++ /dev/null @@ -1,173 +0,0 @@ -// The contents of this file have been copied and modified pursuant to the following -// license from the original source: -// https://github.com/korylprince/dep-webview-oidc/blob/2dd846a54fed04c16dd227b8c6c31665b4d0ebd8/header/header.go -// -// MIT License -// -// Copyright (c) 2023 Kory Prince -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -package apple_mdm - -import ( - "bytes" - "crypto" - "crypto/rsa" - "crypto/sha1" // nolint:gosec // See comments regarding Apple's Root CA below - "crypto/x509" - _ "embed" - "encoding/base64" - "errors" - "fmt" - - "github.com/groob/plist" - "go.mozilla.org/pkcs7" -) - -const DeviceInfoHeader = "x-apple-aspen-deviceinfo" - -// appleRootCert is https://www.apple.com/appleca/AppleIncRootCertificate.cer -// -//go:embed AppleIncRootCertificate.cer -var appleRootCert []byte - -func newAppleRootCert() *x509.Certificate { - cert, err := x509.ParseCertificate(appleRootCert) - if err != nil { - panic(fmt.Errorf("could not parse cert: %w", err)) - } - return cert -} - -// appleRootCA is Apple's Root CA parsed to an *x509.Certificate -var appleRootCA = newAppleRootCert() - -// MachineInfo is a [device's information] sent as part of an MDM enrollment profile request -// -// [device's information]: https://developer.apple.com/documentation/devicemanagement/machineinfo -type MachineInfo struct { - IMEI string `plist:"IMEI,omitempty"` - Language string `plist:"LANGUAGE,omitempty"` - MEID string `plist:"MEID,omitempty"` - Product string `plist:"PRODUCT"` - Serial string `plist:"SERIAL"` - UDID string `plist:"UDID"` - Version string `plist:"VERSION"` -} - -// verifyPKCS7SHA1RSA performs a manual SHA1withRSA verification, since it's deprecated in Go 1.18. -// If verifyChain is true, the signer certificate and its chain of certificates is verified against Apple's Root CA. -// Also note that the certificate validity time window of the signing cert is not checked, since the cert is expired. -// This follows guidance from Apple on the expired certificate. -func verifyPKCS7SHA1RSA(p7 *pkcs7.PKCS7, verifyChain bool) error { - if len(p7.Signers) == 0 { - return errors.New("not signed") - } - - // get signing cert - issuer := p7.Signers[0].IssuerAndSerialNumber - var signer *x509.Certificate - for _, cert := range p7.Certificates { - if bytes.Equal(cert.RawIssuer, issuer.IssuerName.FullBytes) && cert.SerialNumber.Cmp(issuer.SerialNumber) == 0 { - signer = cert - } - } - - // get sha1 hash of content - hashed := sha1.Sum(p7.Content) // nolint:gosec - - // verify content signature - signature := p7.Signers[0].EncryptedDigest - if err := rsa.VerifyPKCS1v15(signer.PublicKey.(*rsa.PublicKey), crypto.SHA1, hashed[:], signature); err != nil { - return fmt.Errorf("signature could not be verified: %w", err) - } - - if !verifyChain { - return nil - } - - // verify chain from signer to root - cert := signer -outer: - for { - // check if cert is signed by root - if bytes.Equal(cert.RawIssuer, appleRootCA.RawSubject) { - hashed := sha1.Sum(cert.RawTBSCertificate) // nolint:gosec - // check signature - if err := rsa.VerifyPKCS1v15(appleRootCA.PublicKey.(*rsa.PublicKey), crypto.SHA1, hashed[:], cert.Signature); err != nil { - return fmt.Errorf("could not verify root CA signature: %w", err) - } - return nil - } - for _, c := range p7.Certificates { - if cert == c { - continue - } - // check if cert is signed by intermediate cert in chain - if bytes.Equal(cert.RawIssuer, c.RawSubject) { - // check signature - hashed := sha1.Sum(cert.RawTBSCertificate) // nolint:gosec - if err := rsa.VerifyPKCS1v15(c.PublicKey.(*rsa.PublicKey), crypto.SHA1, hashed[:], cert.Signature); err != nil { - return fmt.Errorf("could not verify chained certificate signature: %w", err) - } - cert = c - continue outer - } - } - return errors.New("certificate root not found") - } -} - -// ParseDeviceinfo attempts to parse the provided string, assuming it to be the base64-encoded value -// of an x-apple-aspen-deviceinfo header. If successful, it returns the parsed *MachineInfo. If the -// verify parameter is specified as true, the signature is also verified against Apple's Root CA and -// an error will be returned if the signature is invalid. -// -// Warning: The information in this header, despite being signed by Apple PKI, shouldn't be trusted -// for device attestation or other security purposes. See the related [documentation] and referenced -// [article] for more information. -// -// [documentation]: https://github.com/korylprince/dep-webview-oidc/blob/2dd846a54fed04c16dd227b8c6c31665b4d0ebd8/docs/Architecture.md#x-apple-aspen-deviceinfo-header -// [article]: https://duo.com/labs/research/mdm-me-maybe -func ParseDeviceinfo(b64 string, verify bool) (*MachineInfo, error) { - buf, err := base64.StdEncoding.DecodeString(b64) - if err != nil { - return nil, fmt.Errorf("could not decode base64: %w", err) - } - - p7, err := pkcs7.Parse(buf) - if err != nil { - return nil, fmt.Errorf("could not decode pkcs7: %w", err) - } - - // verify signature and certificate chain - if verify { - if err = verifyPKCS7SHA1RSA(p7, verify); err != nil { - return nil, fmt.Errorf("could not verify signature: %w", err) - } - } - - info := new(MachineInfo) - if err = plist.Unmarshal(p7.Content, info); err != nil { - return nil, fmt.Errorf("could not decode plist: %w", err) - } - - return info, nil -} diff --git a/server/mock/datastore_mock.go b/server/mock/datastore_mock.go index df5ee05b6c7e..a8fc105d9259 100644 --- a/server/mock/datastore_mock.go +++ b/server/mock/datastore_mock.go @@ -601,11 +601,7 @@ type SetOrUpdateMunkiInfoFunc func(ctx context.Context, hostID uint, version str type SetOrUpdateMDMDataFunc func(ctx context.Context, hostID uint, isServer bool, enrolled bool, serverURL string, installedFromDep bool, name string, fleetEnrollRef string) error -type SetOrUpdateHostEmailsFromMDMIdPAccountsByLegacyEnrollRefFunc func(ctx context.Context, hostID uint, fleetEnrollmentRef string) error - -type SetOrUpdateHostEmailsFromMDMIdPAccountsByHostUUIDFunc func(ctx context.Context, hostUUID string) error - -type SetOrUpdateEmailsFromMDMIdPAccountsByHostIDFunc func(ctx context.Context, hostID uint, hostUUID string) error +type SetOrUpdateHostEmailsFromMdmIdpAccountsFunc func(ctx context.Context, hostID uint, fleetEnrollmentRef string) error type SetOrUpdateHostDisksSpaceFunc func(ctx context.Context, hostID uint, gigsAvailable float64, percentAvailable float64, gigsTotal float64) error @@ -781,13 +777,7 @@ type GetMDMAppleProfilesSummaryFunc func(ctx context.Context, teamID *uint) (*fl type InsertMDMIdPAccountFunc func(ctx context.Context, account *fleet.MDMIdPAccount) error -type AssociateMDMIdPAccountFunc func(ctx context.Context, accountUUID string, deviceUUID string) error - -type GetMDMIdPAccountByAccountUUIDFunc func(ctx context.Context, accountUUID string) (*fleet.MDMIdPAccount, error) - -type GetMDMIdPAccountByHostUUIDFunc func(ctx context.Context, hostUUID string) (*fleet.MDMIdPAccount, error) - -type GetMDMIdPAccountByLegacyEnrollRefFunc func(ctx context.Context, ref string) (*fleet.MDMIdPAccount, error) +type GetMDMIdPAccountByUUIDFunc func(ctx context.Context, uuid string) (*fleet.MDMIdPAccount, error) type GetMDMIdPAccountByEmailFunc func(ctx context.Context, email string) (*fleet.MDMIdPAccount, error) @@ -1871,14 +1861,8 @@ type DataStore struct { SetOrUpdateMDMDataFunc SetOrUpdateMDMDataFunc SetOrUpdateMDMDataFuncInvoked bool - SetOrUpdateHostEmailsFromMDMIdPAccountsByLegacyEnrollRefFunc SetOrUpdateHostEmailsFromMDMIdPAccountsByLegacyEnrollRefFunc - SetOrUpdateHostEmailsFromMDMIdPAccountsByLegacyEnrollRefFuncInvoked bool - - SetOrUpdateHostEmailsFromMDMIdPAccountsByHostUUIDFunc SetOrUpdateHostEmailsFromMDMIdPAccountsByHostUUIDFunc - SetOrUpdateHostEmailsFromMDMIdPAccountsByHostUUIDFuncInvoked bool - - SetOrUpdateEmailsFromMDMIdPAccountsByHostIDFunc SetOrUpdateEmailsFromMDMIdPAccountsByHostIDFunc - SetOrUpdateEmailsFromMDMIdPAccountsByHostIDFuncInvoked bool + SetOrUpdateHostEmailsFromMdmIdpAccountsFunc SetOrUpdateHostEmailsFromMdmIdpAccountsFunc + SetOrUpdateHostEmailsFromMdmIdpAccountsFuncInvoked bool SetOrUpdateHostDisksSpaceFunc SetOrUpdateHostDisksSpaceFunc SetOrUpdateHostDisksSpaceFuncInvoked bool @@ -2141,17 +2125,8 @@ type DataStore struct { InsertMDMIdPAccountFunc InsertMDMIdPAccountFunc InsertMDMIdPAccountFuncInvoked bool - AssociateMDMIdPAccountFunc AssociateMDMIdPAccountFunc - AssociateMDMIdPAccountFuncInvoked bool - - GetMDMIdPAccountByAccountUUIDFunc GetMDMIdPAccountByAccountUUIDFunc - GetMDMIdPAccountByAccountUUIDFuncInvoked bool - - GetMDMIdPAccountByHostUUIDFunc GetMDMIdPAccountByHostUUIDFunc - GetMDMIdPAccountByHostUUIDFuncInvoked bool - - GetMDMIdPAccountByLegacyEnrollRefFunc GetMDMIdPAccountByLegacyEnrollRefFunc - GetMDMIdPAccountByLegacyEnrollRefFuncInvoked bool + GetMDMIdPAccountByUUIDFunc GetMDMIdPAccountByUUIDFunc + GetMDMIdPAccountByUUIDFuncInvoked bool GetMDMIdPAccountByEmailFunc GetMDMIdPAccountByEmailFunc GetMDMIdPAccountByEmailFuncInvoked bool @@ -4505,25 +4480,11 @@ func (s *DataStore) SetOrUpdateMDMData(ctx context.Context, hostID uint, isServe return s.SetOrUpdateMDMDataFunc(ctx, hostID, isServer, enrolled, serverURL, installedFromDep, name, fleetEnrollRef) } -func (s *DataStore) SetOrUpdateHostEmailsFromMDMIdPAccountsByLegacyEnrollRef(ctx context.Context, hostID uint, fleetEnrollmentRef string) error { - s.mu.Lock() - s.SetOrUpdateHostEmailsFromMDMIdPAccountsByLegacyEnrollRefFuncInvoked = true - s.mu.Unlock() - return s.SetOrUpdateHostEmailsFromMDMIdPAccountsByLegacyEnrollRefFunc(ctx, hostID, fleetEnrollmentRef) -} - -func (s *DataStore) SetOrUpdateHostEmailsFromMDMIdPAccountsByHostUUID(ctx context.Context, hostUUID string) error { - s.mu.Lock() - s.SetOrUpdateHostEmailsFromMDMIdPAccountsByHostUUIDFuncInvoked = true - s.mu.Unlock() - return s.SetOrUpdateHostEmailsFromMDMIdPAccountsByHostUUIDFunc(ctx, hostUUID) -} - -func (s *DataStore) SetOrUpdateEmailsFromMDMIdPAccountsByHostID(ctx context.Context, hostID uint, hostUUID string) error { +func (s *DataStore) SetOrUpdateHostEmailsFromMdmIdpAccounts(ctx context.Context, hostID uint, fleetEnrollmentRef string) error { s.mu.Lock() - s.SetOrUpdateEmailsFromMDMIdPAccountsByHostIDFuncInvoked = true + s.SetOrUpdateHostEmailsFromMdmIdpAccountsFuncInvoked = true s.mu.Unlock() - return s.SetOrUpdateEmailsFromMDMIdPAccountsByHostIDFunc(ctx, hostID, hostUUID) + return s.SetOrUpdateHostEmailsFromMdmIdpAccountsFunc(ctx, hostID, fleetEnrollmentRef) } func (s *DataStore) SetOrUpdateHostDisksSpace(ctx context.Context, hostID uint, gigsAvailable float64, percentAvailable float64, gigsTotal float64) error { @@ -5135,32 +5096,11 @@ func (s *DataStore) InsertMDMIdPAccount(ctx context.Context, account *fleet.MDMI return s.InsertMDMIdPAccountFunc(ctx, account) } -func (s *DataStore) AssociateMDMIdPAccount(ctx context.Context, accountUUID string, deviceUUID string) error { - s.mu.Lock() - s.AssociateMDMIdPAccountFuncInvoked = true - s.mu.Unlock() - return s.AssociateMDMIdPAccountFunc(ctx, accountUUID, deviceUUID) -} - -func (s *DataStore) GetMDMIdPAccountByAccountUUID(ctx context.Context, accountUUID string) (*fleet.MDMIdPAccount, error) { - s.mu.Lock() - s.GetMDMIdPAccountByAccountUUIDFuncInvoked = true - s.mu.Unlock() - return s.GetMDMIdPAccountByAccountUUIDFunc(ctx, accountUUID) -} - -func (s *DataStore) GetMDMIdPAccountByHostUUID(ctx context.Context, hostUUID string) (*fleet.MDMIdPAccount, error) { - s.mu.Lock() - s.GetMDMIdPAccountByHostUUIDFuncInvoked = true - s.mu.Unlock() - return s.GetMDMIdPAccountByHostUUIDFunc(ctx, hostUUID) -} - -func (s *DataStore) GetMDMIdPAccountByLegacyEnrollRef(ctx context.Context, ref string) (*fleet.MDMIdPAccount, error) { +func (s *DataStore) GetMDMIdPAccountByUUID(ctx context.Context, uuid string) (*fleet.MDMIdPAccount, error) { s.mu.Lock() - s.GetMDMIdPAccountByLegacyEnrollRefFuncInvoked = true + s.GetMDMIdPAccountByUUIDFuncInvoked = true s.mu.Unlock() - return s.GetMDMIdPAccountByLegacyEnrollRefFunc(ctx, ref) + return s.GetMDMIdPAccountByUUIDFunc(ctx, uuid) } func (s *DataStore) GetMDMIdPAccountByEmail(ctx context.Context, email string) (*fleet.MDMIdPAccount, error) { diff --git a/server/service/apple_mdm.go b/server/service/apple_mdm.go index 23ce77ed43c9..d34222fa17fc 100644 --- a/server/service/apple_mdm.go +++ b/server/service/apple_mdm.go @@ -24,7 +24,6 @@ import ( "github.com/fleetdm/fleet/v4/server" "github.com/fleetdm/fleet/v4/server/authz" "github.com/fleetdm/fleet/v4/server/config" - "github.com/fleetdm/fleet/v4/server/contexts/ctxdb" "github.com/fleetdm/fleet/v4/server/contexts/ctxerr" "github.com/fleetdm/fleet/v4/server/contexts/logging" "github.com/fleetdm/fleet/v4/server/contexts/viewer" @@ -1286,17 +1285,8 @@ func (svc *Service) EnqueueMDMAppleCommand( } type mdmAppleEnrollRequest struct { - // Token is expected to be a UUID string that identifies a template MDM Apple enrollment profile. - Token string `query:"token"` - // EnrollmentReference is expected to be a UUID string that identifies the MDM IdP account used - // to authenticate the end user as part of the MDM IdP flow. + Token string `query:"token"` EnrollmentReference string `query:"enrollment_reference,optional"` - // DEPDeviceInfo is expected to be a base64 encoded string containing DEP deviceinfo extracted - // from the x-apple-aspen-deviceinfo header of the original configuration web view request and - // persisted by the client in local storage for inclusion in a subsequent enrollment request as - // part of the MDM IdP flow. - // See https://developer.apple.com/documentation/devicemanagement/device_assignment/authenticating_through_web_views - DEPDeviceInfo string `query:"dep_device_info,optional"` } func (r mdmAppleEnrollResponse) error() error { return r.Err } @@ -1326,7 +1316,7 @@ func (r mdmAppleEnrollResponse) hijackRender(ctx context.Context, w http.Respons func mdmAppleEnrollEndpoint(ctx context.Context, request interface{}, svc fleet.Service) (errorer, error) { req := request.(*mdmAppleEnrollRequest) - profile, err := svc.GetMDMAppleEnrollmentProfileByToken(ctx, req.Token, req.EnrollmentReference, req.DEPDeviceInfo) + profile, err := svc.GetMDMAppleEnrollmentProfileByToken(ctx, req.Token, req.EnrollmentReference) if err != nil { return mdmAppleEnrollResponse{Err: err}, nil } @@ -1335,7 +1325,7 @@ func mdmAppleEnrollEndpoint(ctx context.Context, request interface{}, svc fleet. }, nil } -func (svc *Service) GetMDMAppleEnrollmentProfileByToken(ctx context.Context, token string, ref string, deviceinfo string) (profile []byte, err error) { +func (svc *Service) GetMDMAppleEnrollmentProfileByToken(ctx context.Context, token string, ref string) (profile []byte, err error) { // skipauth: The enroll profile endpoint is unauthenticated. svc.authz.SkipAuthorization(ctx) @@ -1352,44 +1342,9 @@ func (svc *Service) GetMDMAppleEnrollmentProfileByToken(ctx context.Context, tok return nil, ctxerr.Wrap(ctx, err) } - enrollURL := appConfig.ServerSettings.ServerURL - // check if there is a legacy enroll ref and preserve it for backwards compatibility - if ref != "" { - idpAcct, err := svc.ds.GetMDMIdPAccountByAccountUUID( - // use the primary db as the account might have been just inserted - ctxdb.RequirePrimary(ctx, true), - ref, - ) - if err != nil { - return nil, ctxerr.Wrap(ctx, err, "getting MDM IdP account") - } - if idpAcct.FleetEnrollRef != "" { - level.Debug(svc.logger).Log("msg", "using legacy enroll ref", "enroll_ref", idpAcct.FleetEnrollRef) - // we have a legacy enroll ref, add it to the enroll URL - enrollURL, err = apple_mdm.AddEnrollmentRefToFleetURL(appConfig.ServerSettings.ServerURL, idpAcct.FleetEnrollRef) - if err != nil { - return nil, ctxerr.Wrap(ctx, err, "adding reference to fleet URL") - } - } - } - - // if we have device info, we need to parse it and associate the device with an MDM IdP account - if deviceinfo != "" { - di, err := apple_mdm.ParseDeviceinfo(deviceinfo, true) - if err != nil { - return nil, ctxerr.Wrap(ctx, err, "parsing deviceinfo") - } - - // try to associate the device with an MDM IdP account - if ref == "" { - // this is unexpected, there should be a reference if we have device info - level.Debug(svc.logger).Log("msg", "associating mdm idp account, missing idp account uuid", "device_uuid", di.UDID) - } else { - // associate the device with the DEP account - if err := svc.ds.AssociateMDMIdPAccount(ctx, ref, di.UDID); err != nil { - return nil, ctxerr.Wrap(ctx, err, "associating MDM IdP account") - } - } + enrollURL, err := apple_mdm.AddEnrollmentRefToFleetURL(appConfig.ServerSettings.ServerURL, ref) + if err != nil { + return nil, ctxerr.Wrap(ctx, err, "adding reference to fleet URL") } topic, err := svc.mdmPushCertTopic(ctx) diff --git a/server/service/apple_mdm_test.go b/server/service/apple_mdm_test.go index b35540cb9d78..93c8606af585 100644 --- a/server/service/apple_mdm_test.go +++ b/server/service/apple_mdm_test.go @@ -274,7 +274,7 @@ func TestAppleMDMAuthorization(t *testing.T) { ctx = test.UserContext(ctx, test.UserNoRoles) _, err := svc.GetMDMAppleInstallerByToken(ctx, "foo") require.NoError(t, err) - _, err = svc.GetMDMAppleEnrollmentProfileByToken(ctx, "foo", "", "") + _, err = svc.GetMDMAppleEnrollmentProfileByToken(ctx, "foo", "") require.NoError(t, err) _, err = svc.GetMDMAppleInstallerDetailsByToken(ctx, "foo") require.NoError(t, err) diff --git a/server/service/handler.go b/server/service/handler.go index b6ec74b26287..66709d72f51d 100644 --- a/server/service/handler.go +++ b/server/service/handler.go @@ -5,7 +5,6 @@ import ( "errors" "fmt" "net/http" - "net/url" "regexp" "github.com/fleetdm/fleet/v4/server/config" @@ -1038,44 +1037,6 @@ func RedirectSetupToLogin(svc fleet.Service, logger kitlog.Logger, next http.Han } } -func WithDEPWebviewRedirect(svc fleet.Service, logger kitlog.Logger, next http.Handler, urlPrefix string) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - if r.URL.Path == "/mdm/sso" && r.URL.RawQuery == "" { - level.Debug(logger).Log("msg", "handling mdm sso", "url", r.URL.String()) - // Note: We'll apply this redirect only if query params are empty because want to - // redirect to the same URL with added query params after parsing the x-apple-aspen-deviceinfo - // header. Whenever we see a request with any query params already present, we'll - // skip this step and just continue to the next handler. - di := r.Header.Get("X-apple-aspen-deviceinfo") - if di != "" { - level.Debug(logger).Log("msg", "parsing X-apple-aspen-deviceinfo", "url", r.URL.String()) - // extract x-apple-aspen-deviceinfo custom header from request - _, err := apple_mdm.ParseDeviceinfo(di, true) - if err != nil { - level.Error(logger).Log("msg", "parsing X-apple-aspen-deviceinfo", "err", err) - http.Redirect(w, r, r.URL.String()+"?error=true", http.StatusSeeOther) - return - } - // redirect to the same URL with added deviceinfo query params - newURL := r.URL - q := url.Values{ - "dep_device_info": []string{di}, - } - newURL.RawQuery = q.Encode() - level.Debug(logger).Log("msg", "adding query params to redirect url", "query", newURL.RawQuery) - http.Redirect(w, r, newURL.String(), http.StatusTemporaryRedirect) - return - } - // TODO: consider whether we want always return an error here if the header is missing for this endpoint? - level.Info(logger).Log("msg", "missig x-apple-aspen-deviceinfo header, continuing to next") - - } - - next.ServeHTTP(w, r) - return - } -} - // RegisterAppleMDMProtocolServices registers the HTTP handlers that serve // the MDM services to Apple devices. func RegisterAppleMDMProtocolServices( diff --git a/server/service/integration_mdm_test.go b/server/service/integration_mdm_test.go index 88be09b79c0f..04876a5a2d79 100644 --- a/server/service/integration_mdm_test.go +++ b/server/service/integration_mdm_test.go @@ -327,6 +327,7 @@ func (s *integrationMDMTestSuite) SetupSuite() { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) require.NoError(s.T(), json.NewEncoder(w).Encode(s.mockedDownloadFleetdmMeta)) + } })) s.T().Setenv("FLEET_DEV_DOWNLOAD_FLEETDM_URL", downloadFleetdmSrv.URL) @@ -4593,7 +4594,7 @@ func (s *integrationMDMTestSuite) TestSSO() { require.Equal(t, lastSubmittedProfile.ConfigurationWebURL, lastSubmittedProfile.URL) checkStoredIdPInfo := func(uuid, username, fullname, email string) { - acc, err := s.ds.GetMDMIdPAccountByAccountUUID(context.Background(), uuid) + acc, err := s.ds.GetMDMIdPAccountByUUID(context.Background(), uuid) require.NoError(t, err) require.Equal(t, username, acc.Username) require.Equal(t, fullname, acc.Fullname) @@ -4722,11 +4723,6 @@ func (s *integrationMDMTestSuite) TestSSO() { // test runs. mdmDevice.EnrollInfo.MDMURL = strings.Replace(enrollURL, "https://localhost:8080", s.server.URL, 1) mdmDevice.EnrollInfo.SCEPURL = strings.Replace(scepURL, "https://localhost:8080", s.server.URL, 1) - - // associate the mdm idp account with the host uuid manually (we can't mock the Apple webview client - // deviceinfo header because it is signed with the Apple Root CA) - require.NoError(t, s.ds.AssociateMDMIdPAccount(context.Background(), user1EnrollRef, mdmDevice.UUID)) - err = mdmDevice.Enroll() require.NoError(t, err) @@ -4754,22 +4750,13 @@ func (s *integrationMDMTestSuite) TestSSO() { require.Equal(t, "SSO User 1", fullAccCmd.Command.AccountConfiguration.PrimaryAccountFullName) require.Equal(t, "sso_user", fullAccCmd.Command.AccountConfiguration.PrimaryAccountUserName) - // check that the host was created and get the host id and other details for the next steps + // report host details for the device var hostResp getHostResponse s.DoJSON("GET", "/api/v1/fleet/hosts/identifier/"+mdmDevice.UUID, nil, http.StatusOK, &hostResp) - // ensure that host_emails entry was created from mdm_idp_accounts - mysql.ExecAdhocSQL(t, s.ds, func(q sqlx.ExtContext) error { - var email string - err := sqlx.GetContext(context.Background(), q, &email, `SELECT email FROM host_emails WHERE host_id = ? AND source = ?`, hostResp.Host.ID, fleet.DeviceMappingMDMIdpAccounts) - require.NoError(t, err) - require.Equal(t, "sso_user@example.com", email) - return nil - }) - - // get app config and host detail queries ac, err := s.ds.AppConfig(context.Background()) require.NoError(t, err) + detailQueries := osquery_utils.GetDetailQueries(context.Background(), config.FleetConfig{}, ac, &ac.Features) // simulate osquery reporting mdm information @@ -8306,6 +8293,7 @@ func (s *integrationMDMTestSuite) TestLockUnlockWipeMacOS() { // lock the host without viewing the PIN s.Do("POST", fmt.Sprintf("/api/latest/fleet/hosts/%d/lock", host.ID), nil, http.StatusNoContent) + } func (s *integrationMDMTestSuite) TestZCustomConfigurationWebURL() { diff --git a/server/service/osquery_utils/queries.go b/server/service/osquery_utils/queries.go index 79a32ffc4dcb..b811fc0026ed 100644 --- a/server/service/osquery_utils/queries.go +++ b/server/service/osquery_utils/queries.go @@ -1712,18 +1712,11 @@ func directIngestMDMMac(ctx context.Context, logger log.Logger, host *fleet.Host fleetEnrollRef = serverURL.Query().Get("enrollment_reference") } if fleetEnrollRef != "" { - if err := ds.SetOrUpdateHostEmailsFromMDMIdPAccountsByLegacyEnrollRef(ctx, host.ID, fleetEnrollRef); err != nil { - level.Warn(logger).Log( - "component", "service", - "method", "directIngestMDMMac", - "msg", err.Error(), - ) - } - } else if installedFromDep { - // ensure that mdm_idp_accounts are included in host_emails for Apple DEP-enrolled hosts; - // note that we're relying on the osquery platform compatibility checks to ensure that this - // ingest function is only applied darwin hosts - if err := ds.SetOrUpdateEmailsFromMDMIdPAccountsByHostID(ctx, host.ID, host.UUID); err != nil { + if err := ds.SetOrUpdateHostEmailsFromMdmIdpAccounts(ctx, host.ID, fleetEnrollRef); err != nil { + if !fleet.IsNotFound(err) { + return ctxerr.Wrap(ctx, err, "updating host emails from mdm idp accounts") + } + level.Warn(logger).Log( "component", "service", "method", "directIngestMDMMac", diff --git a/server/service/osquery_utils/queries_test.go b/server/service/osquery_utils/queries_test.go index b26fe4236415..8fb86bcc1f86 100644 --- a/server/service/osquery_utils/queries_test.go +++ b/server/service/osquery_utils/queries_test.go @@ -596,15 +596,12 @@ func TestDirectIngestMDMMac(t *testing.T) { require.Equal(t, fleetEnrollmentRef, c.enrollRef) return nil } - ds.SetOrUpdateEmailsFromMDMIdPAccountsByHostIDFunc = func(ctx context.Context, hostID uint, hostUUID string) error { - return nil - } - ds.SetOrUpdateHostEmailsFromMDMIdPAccountsByLegacyEnrollRefFunc = func(ctx context.Context, hostID uint, fleetEnrollmentRef string) error { + ds.SetOrUpdateHostEmailsFromMdmIdpAccountsFunc = func(ctx context.Context, hostID uint, fleetEnrollmentRef string) error { return nil } if c.name == "with invalid enrollment reference" { - ds.SetOrUpdateHostEmailsFromMDMIdPAccountsByLegacyEnrollRefFunc = func(ctx context.Context, hostID uint, fleetEnrollmentRef string) error { + ds.SetOrUpdateHostEmailsFromMdmIdpAccountsFunc = func(ctx context.Context, hostID uint, fleetEnrollmentRef string) error { return &nfe{} } } @@ -619,7 +616,7 @@ func TestDirectIngestMDMMac(t *testing.T) { require.NoError(t, err) ds.SetOrUpdateMDMDataFuncInvoked = false if c.name != "with invalid enrollment reference" { - require.False(t, ds.SetOrUpdateHostEmailsFromMDMIdPAccountsByLegacyEnrollRefFuncInvoked) + require.False(t, ds.SetOrUpdateHostEmailsFromMdmIdpAccountsFuncInvoked) } } }) @@ -687,13 +684,10 @@ func TestDirectIngestMDMFleetEnrollRef(t *testing.T) { }, } { t.Run(tc.name, func(t *testing.T) { - ds.SetOrUpdateHostEmailsFromMDMIdPAccountsByLegacyEnrollRefFunc = func(ctx context.Context, hostID uint, fleetEnrollmentRef string) error { + ds.SetOrUpdateHostEmailsFromMdmIdpAccountsFunc = func(ctx context.Context, hostID uint, fleetEnrollmentRef string) error { require.Equal(t, tc.wantEnrollRef, fleetEnrollmentRef) return nil } - ds.SetOrUpdateEmailsFromMDMIdPAccountsByHostIDFunc = func(ctx context.Context, hostID uint, hostUUID string) error { - return nil - } ds.SetOrUpdateMDMDataFunc = func(ctx context.Context, hostID uint, isServer, enrolled bool, serverURL string, installedFromDep bool, name string, fleetEnrollmentRef string) error { require.False(t, isServer) require.True(t, enrolled) @@ -717,8 +711,8 @@ func TestDirectIngestMDMFleetEnrollRef(t *testing.T) { require.NoError(t, err) require.True(t, ds.SetOrUpdateMDMDataFuncInvoked) ds.SetOrUpdateMDMDataFuncInvoked = false - require.Equal(t, tc.wantHostEmailsCalled, ds.SetOrUpdateHostEmailsFromMDMIdPAccountsByLegacyEnrollRefFuncInvoked) - ds.SetOrUpdateHostEmailsFromMDMIdPAccountsByLegacyEnrollRefFuncInvoked = false + require.Equal(t, tc.wantHostEmailsCalled, ds.SetOrUpdateHostEmailsFromMdmIdpAccountsFuncInvoked) + ds.SetOrUpdateHostEmailsFromMdmIdpAccountsFuncInvoked = false }) } } @@ -942,10 +936,7 @@ func TestDirectIngestMDMWindows(t *testing.T) { require.Empty(t, fleetEnrollmentRef) return nil } - ds.SetOrUpdateEmailsFromMDMIdPAccountsByHostIDFunc = func(ctx context.Context, hostID uint, hostUUID string) error { - return nil - } - ds.SetOrUpdateHostEmailsFromMDMIdPAccountsByLegacyEnrollRefFunc = func(ctx context.Context, hostID uint, fleetEnrollmentRef string) error { + ds.SetOrUpdateHostEmailsFromMdmIdpAccountsFunc = func(ctx context.Context, hostID uint, fleetEnrollmentRef string) error { return nil } }) @@ -953,7 +944,7 @@ func TestDirectIngestMDMWindows(t *testing.T) { require.NoError(t, err) require.True(t, ds.SetOrUpdateMDMDataFuncInvoked) ds.SetOrUpdateMDMDataFuncInvoked = false - require.False(t, ds.SetOrUpdateHostEmailsFromMDMIdPAccountsByLegacyEnrollRefFuncInvoked) + require.False(t, ds.SetOrUpdateHostEmailsFromMdmIdpAccountsFuncInvoked) } } diff --git a/server/worker/apple_mdm.go b/server/worker/apple_mdm.go index 1be6fa98afe0..933a0c74410b 100644 --- a/server/worker/apple_mdm.go +++ b/server/worker/apple_mdm.go @@ -9,7 +9,6 @@ import ( "time" "github.com/fleetdm/fleet/v4/pkg/fleetdbase" - "github.com/fleetdm/fleet/v4/server/contexts/ctxdb" "github.com/fleetdm/fleet/v4/server/contexts/ctxerr" "github.com/fleetdm/fleet/v4/server/fleet" apple_mdm "github.com/fleetdm/fleet/v4/server/mdm/apple" @@ -107,9 +106,6 @@ func (a *AppleMDM) runPostManualEnrollment(ctx context.Context, args appleMDMArg func (a *AppleMDM) runPostDEPEnrollment(ctx context.Context, args appleMDMArgs) error { var awaitCmdUUIDs []string - // use primary db to ensure we have the latest records for enrollments - ctx = ctxdb.RequirePrimary(ctx, true) - if isMacOS(args.Platform) { fleetdCmdUUID, err := a.installFleetd(ctx, args.HostUUID) if err != nil { @@ -126,24 +122,18 @@ func (a *AppleMDM) runPostDEPEnrollment(ctx context.Context, args appleMDMArgs) } } - idpAcct, err := a.Datastore.GetMDMIdPAccountByHostUUID(ctx, args.HostUUID) - if err != nil && !fleet.IsNotFound(err) { - return ctxerr.Wrap(ctx, err, "getting idp account details") - } - if ref := args.EnrollReference; ref != "" { a.Log.Log("info", "got an enroll_reference", "host_uuid", args.HostUUID, "ref", ref) - idpAcct, err = a.Datastore.GetMDMIdPAccountByLegacyEnrollRef(ctx, ref) + appCfg, err := a.Datastore.AppConfig(ctx) if err != nil { - return ctxerr.Wrapf(ctx, err, "getting idp account details for enroll reference %s", ref) + return ctxerr.Wrap(ctx, err, "getting app config") } - } - if idpAcct != nil { - appCfg, err := a.Datastore.AppConfig(ctx) + acct, err := a.Datastore.GetMDMIdPAccountByUUID(ctx, ref) if err != nil { - return ctxerr.Wrap(ctx, err, "getting app config") + return ctxerr.Wrapf(ctx, err, "getting idp account details for enroll reference %s", ref) } + ssoEnabled := appCfg.MDM.MacOSSetup.EnableEndUserAuthentication if args.TeamID != nil { team, err := a.Datastore.Team(ctx, *args.TeamID) @@ -160,19 +150,12 @@ func (a *AppleMDM) runPostDEPEnrollment(ctx context.Context, args appleMDMArgs) ctx, []string{args.HostUUID}, cmdUUID, - idpAcct.Fullname, - idpAcct.Username, + acct.Fullname, + acct.Username, ); err != nil { return ctxerr.Wrap(ctx, err, "sending AccountConfiguration command") } awaitCmdUUIDs = append(awaitCmdUUIDs, cmdUUID) - - // NOTE: We only set the email address here if we have an MDM IdP account and sso is enabled. We rely on the - // `resetDarwin` lifecycle event to delete from `host_emails` for this host uuid if there is - // any email where `source = 'mdm_idp_account'`. - if err := a.Datastore.SetOrUpdateHostEmailsFromMDMIdPAccountsByHostUUID(ctx, args.HostUUID); err != nil { - return ctxerr.Wrap(ctx, err, "setting host emails from mdm idp accounts") - } } } diff --git a/server/worker/apple_mdm_test.go b/server/worker/apple_mdm_test.go index 879d75dba1d1..66d47070baed 100644 --- a/server/worker/apple_mdm_test.go +++ b/server/worker/apple_mdm_test.go @@ -2,7 +2,6 @@ package worker import ( "context" - "database/sql" "fmt" "os" "testing" @@ -403,7 +402,7 @@ func TestAppleMDM(t *testing.T) { require.Equal(t, "custom-team-bootstrap", ms.BootstrapPackageName) }) - t.Run("unknown legacy enroll reference", func(t *testing.T) { + t.Run("unknown enroll reference", func(t *testing.T) { mysql.SetTestABMAssets(t, ds) defer mysql.TruncateTables(t, ds) @@ -431,12 +430,12 @@ func TestAppleMDM(t *testing.T) { jobs, err := ds.GetQueuedJobs(ctx, 1, time.Time{}) require.NoError(t, err) require.Len(t, jobs, 1) - require.Contains(t, jobs[0].Error, "MDMIdPAccount with fleet_enroll_ref abcd was not found") + require.Contains(t, jobs[0].Error, "MDMIdPAccount with uuid abcd was not found") require.Equal(t, fleet.JobStateQueued, jobs[0].State) require.Equal(t, 1, jobs[0].Retries) }) - t.Run("legacy reference associated MDM IdP account but SSO disabled", func(t *testing.T) { + t.Run("enroll reference but SSO disabled", func(t *testing.T) { mysql.SetTestABMAssets(t, ds) defer mysql.TruncateTables(t, ds) @@ -450,15 +449,8 @@ func TestAppleMDM(t *testing.T) { idpAcc, err := ds.GetMDMIdPAccountByEmail(ctx, "test@example.com") require.NoError(t, err) - mysql.ExecAdhocSQL(t, ds, func(q sqlx.ExtContext) error { - _, err := q.ExecContext(ctx, `UPDATE mdm_idp_accounts mia SET fleet_enroll_ref = mia.uuid WHERE uuid = ?`, idpAcc.UUID) - return err - }) - h := createEnrolledHost(t, 1, nil, true) - require.NoError(t, ds.AssociateMDMIdPAccount(ctx, idpAcc.UUID, h.UUID)) - mdmWorker := &AppleMDM{ Datastore: ds, Log: nopLog, @@ -489,17 +481,9 @@ func TestAppleMDM(t *testing.T) { // confirm that AccountConfiguration command was not enqueued require.ElementsMatch(t, []string{"InstallEnterpriseApplication"}, getEnqueuedCommandTypes(t)) - - // ensure that host_emails entry was not created from mdm_idp_accounts - mysql.ExecAdhocSQL(t, ds, func(q sqlx.ExtContext) error { - var gotEmail string - err := sqlx.GetContext(ctx, q, &gotEmail, `SELECT email FROM host_emails WHERE host_id = ? AND source = ?`, h.ID, fleet.DeviceMappingMDMIdpAccounts) - require.ErrorIs(t, err, sql.ErrNoRows) - return nil - }) }) - t.Run("legacy reference associated MDM IdP account with SSO enabled", func(t *testing.T) { + t.Run("enroll reference with SSO enabled", func(t *testing.T) { mysql.SetTestABMAssets(t, ds) defer mysql.TruncateTables(t, ds) @@ -513,11 +497,6 @@ func TestAppleMDM(t *testing.T) { idpAcc, err := ds.GetMDMIdPAccountByEmail(ctx, "test@example.com") require.NoError(t, err) - mysql.ExecAdhocSQL(t, ds, func(q sqlx.ExtContext) error { - _, err := q.ExecContext(ctx, `UPDATE mdm_idp_accounts mia SET fleet_enroll_ref = mia.uuid WHERE uuid = ?`, idpAcc.UUID) - return err - }) - tm, err := ds.NewTeam(ctx, &fleet.Team{Name: "test"}) require.NoError(t, err) tm, err = ds.Team(ctx, tm.ID) @@ -528,8 +507,6 @@ func TestAppleMDM(t *testing.T) { h := createEnrolledHost(t, 1, &tm.ID, true) - require.NoError(t, ds.AssociateMDMIdPAccount(ctx, idpAcc.UUID, h.UUID)) - mdmWorker := &AppleMDM{ Datastore: ds, Log: nopLog, @@ -559,139 +536,6 @@ func TestAppleMDM(t *testing.T) { require.Equal(t, 0, jobs[0].Retries) // hasn't run yet require.ElementsMatch(t, []string{"InstallEnterpriseApplication", "AccountConfiguration"}, getEnqueuedCommandTypes(t)) - - // ensure that the host_emails entry was created from mdm_idp_accounts - mysql.ExecAdhocSQL(t, ds, func(q sqlx.ExtContext) error { - var gotEmail string - err := sqlx.GetContext(ctx, q, &gotEmail, `SELECT email FROM host_emails WHERE host_id = ? AND source = ?`, h.ID, fleet.DeviceMappingMDMIdpAccounts) - require.NoError(t, err) - require.Equal(t, "test@example.com", gotEmail) - return nil - }) - }) - - t.Run("associated MDM IdP account with SSO enabled", func(t *testing.T) { - mysql.SetTestABMAssets(t, ds) - defer mysql.TruncateTables(t, ds) - - err := ds.InsertMDMIdPAccount(ctx, &fleet.MDMIdPAccount{ - Username: "test", - Fullname: "test", - Email: "test@example.com", - }) - require.NoError(t, err) - - idpAcc, err := ds.GetMDMIdPAccountByEmail(ctx, "test@example.com") - require.NoError(t, err) - - tm, err := ds.NewTeam(ctx, &fleet.Team{Name: "test"}) - require.NoError(t, err) - tm, err = ds.Team(ctx, tm.ID) - require.NoError(t, err) - tm.Config.MDM.MacOSSetup.EnableEndUserAuthentication = true - _, err = ds.SaveTeam(ctx, tm) - require.NoError(t, err) - - h := createEnrolledHost(t, 1, &tm.ID, true) - - require.NoError(t, ds.AssociateMDMIdPAccount(ctx, idpAcc.UUID, h.UUID)) - - mdmWorker := &AppleMDM{ - Datastore: ds, - Log: nopLog, - Commander: apple_mdm.NewMDMAppleCommander(mdmStorage, mockPusher{}), - } - w := NewWorker(ds, nopLog) - w.Register(mdmWorker) - - err = QueueAppleMDMJob(ctx, ds, nopLog, AppleMDMPostDEPEnrollmentTask, h.UUID, "darwin", &tm.ID, "") - require.NoError(t, err) - - // run the worker, should succeed - err = w.ProcessJobs(ctx) - require.NoError(t, err) - - // ensure the job's not_before allows it to be returned if it were to run - // again - time.Sleep(time.Second) - - jobs, err := ds.GetQueuedJobs(ctx, 1, time.Now().UTC().Add(time.Minute)) // look in the future to catch any delayed job - require.NoError(t, err) - - // the post-DEP release device job is pending - require.Len(t, jobs, 1) - require.Equal(t, appleMDMJobName, jobs[0].Name) - require.Contains(t, string(*jobs[0].Args), AppleMDMPostDEPReleaseDeviceTask) - require.Equal(t, 0, jobs[0].Retries) // hasn't run yet - - require.ElementsMatch(t, []string{"InstallEnterpriseApplication", "AccountConfiguration"}, getEnqueuedCommandTypes(t)) - - // ensure that the host_emails entry was created from mdm_idp_accounts - mysql.ExecAdhocSQL(t, ds, func(q sqlx.ExtContext) error { - var gotEmail string - err := sqlx.GetContext(ctx, q, &gotEmail, `SELECT email FROM host_emails WHERE host_id = ? AND source = ?`, h.ID, fleet.DeviceMappingMDMIdpAccounts) - require.NoError(t, err) - require.Equal(t, "test@example.com", gotEmail) - return nil - }) - }) - - t.Run("associated MDM IdP account but SSO disabled", func(t *testing.T) { - mysql.SetTestABMAssets(t, ds) - defer mysql.TruncateTables(t, ds) - - err := ds.InsertMDMIdPAccount(ctx, &fleet.MDMIdPAccount{ - Username: "test", - Fullname: "test", - Email: "test@example.com", - }) - require.NoError(t, err) - - idpAcc, err := ds.GetMDMIdPAccountByEmail(ctx, "test@example.com") - require.NoError(t, err) - - h := createEnrolledHost(t, 1, nil, true) - - require.NoError(t, ds.AssociateMDMIdPAccount(ctx, idpAcc.UUID, h.UUID)) - - mdmWorker := &AppleMDM{ - Datastore: ds, - Log: nopLog, - Commander: apple_mdm.NewMDMAppleCommander(mdmStorage, mockPusher{}), - } - w := NewWorker(ds, nopLog) - w.Register(mdmWorker) - - err = QueueAppleMDMJob(ctx, ds, nopLog, AppleMDMPostDEPEnrollmentTask, h.UUID, "darwin", nil, "") - require.NoError(t, err) - - // run the worker, should succeed - err = w.ProcessJobs(ctx) - require.NoError(t, err) - - // ensure the job's not_before allows it to be returned if it were to run - // again - time.Sleep(time.Second) - - jobs, err := ds.GetQueuedJobs(ctx, 1, time.Now().UTC().Add(time.Minute)) // look in the future to catch any delayed job - require.NoError(t, err) - - // the post-DEP release device job is pending, having failed its first attempt - require.Len(t, jobs, 1) - require.Equal(t, appleMDMJobName, jobs[0].Name) - require.Contains(t, string(*jobs[0].Args), AppleMDMPostDEPReleaseDeviceTask) - require.Equal(t, 0, jobs[0].Retries) // hasn't run yet - - // confirm that AccountConfiguration command was not enqueued - require.ElementsMatch(t, []string{"InstallEnterpriseApplication"}, getEnqueuedCommandTypes(t)) - - // ensure that host_emails entry was not created from mdm_idp_accounts - mysql.ExecAdhocSQL(t, ds, func(q sqlx.ExtContext) error { - var gotEmail string - err := sqlx.GetContext(ctx, q, &gotEmail, `SELECT email FROM host_emails WHERE host_id = ? AND source = ?`, h.ID, fleet.DeviceMappingMDMIdpAccounts) - require.ErrorIs(t, err, sql.ErrNoRows) - return nil - }) }) t.Run("installs fleetd for manual enrollments", func(t *testing.T) {