Check enrollment type for mobile apple devices and block personal enrollments (#32844)

fixes: #32164 

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files)
for more information.

## Testing

- [x] Added/updated automated tests
- [x] QA'd all new/changed functionality manually
This commit is contained in:
Magnus Jensen
2025-09-11 16:02:18 +03:00
committed by GitHub
parent 8f8c7581ea
commit 863b1997d6
4 changed files with 43 additions and 0 deletions
@@ -0,0 +1 @@
* Fixed a bug where blocking of VPP installs on personally enrolled apple devices was not in place
+11
View File
@@ -25,6 +25,7 @@ import (
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/fleetdm/fleet/v4/server/mdm/apple/vpp"
maintained_apps "github.com/fleetdm/fleet/v4/server/mdm/maintainedapps"
"github.com/fleetdm/fleet/v4/server/mdm/nanomdm/mdm"
"github.com/fleetdm/fleet/v4/server/ptr"
"github.com/go-kit/log"
kitlog "github.com/go-kit/log"
@@ -1085,6 +1086,16 @@ func (svc *Service) InstallSoftwareTitle(ctx context.Context, hostID uint, softw
}
return svc.installSoftwareTitleUsingInstaller(ctx, host, installer)
}
} else {
// Get the enrollment type of the mobile apple device.
enrollment, err := svc.ds.GetNanoMDMEnrollment(ctx, host.UUID)
if err != nil {
return ctxerr.Wrap(ctx, err, "getting nano mdm enrollment")
}
if enrollment.Type == mdm.EnrollType(mdm.UserEnrollmentDevice).String() {
return fleet.NewUserMessageError(errors.New(fleet.InstallSoftwarePersonalAppleDeviceErrMsg), http.StatusUnprocessableEntity)
}
}
vppApp, err := svc.ds.GetVPPAppByTeamAndTitleID(ctx, host.TeamID, softwareTitleID)
@@ -16,6 +16,7 @@ import (
"github.com/fleetdm/fleet/v4/server/authz"
"github.com/fleetdm/fleet/v4/server/contexts/viewer"
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/fleetdm/fleet/v4/server/mdm/nanomdm/mdm"
"github.com/fleetdm/fleet/v4/server/mock"
"github.com/fleetdm/fleet/v4/server/ptr"
"github.com/stretchr/testify/assert"
@@ -212,6 +213,33 @@ func TestUninstallSoftwareTitle(t *testing.T) {
require.ErrorContains(t, svc.UninstallSoftwareTitle(context.Background(), 1, 10), fleet.RunScriptsOrbitDisabledErrMsg)
}
// TestInstallSoftwareTitle is mostly tested in enterprise integration test. This test hits is placed to hit some edge cases.
func TestInstallSoftwareTitle(t *testing.T) {
t.Parallel()
ds := new(mock.Store)
svc := newTestService(t, ds)
ctx := viewer.NewContext(context.Background(), viewer.Viewer{User: &fleet.User{GlobalRole: ptr.String(fleet.RoleAdmin)}})
host := &fleet.Host{
UUID: "personal-ios",
OrbitNodeKey: ptr.String("orbit_key"),
Platform: "ios",
TeamID: ptr.Uint(1),
}
ds.HostFunc = func(ctx context.Context, id uint) (*fleet.Host, error) {
return host, nil
}
ds.GetNanoMDMEnrollmentFunc = func(ctx context.Context, id string) (*fleet.NanoEnrollment, error) {
return &fleet.NanoEnrollment{
Type: mdm.EnrollType(mdm.UserEnrollmentDevice).String(),
}, nil
}
require.ErrorContains(t, svc.InstallSoftwareTitle(ctx, 1, 10), fleet.InstallSoftwarePersonalAppleDeviceErrMsg)
}
func TestSoftwareInstallerPayloadFromSlug(t *testing.T) {
t.Parallel()
ds := new(mock.Store)
+3
View File
@@ -641,6 +641,9 @@ const (
RunScripUnsavedMaxLenErrMsg = "Script is too large. It's limited to 10,000 characters (approximately 125 lines)."
RunScriptGatewayTimeoutErrMsg = "Gateway timeout. Fleet didn't hear back from the host and doesn't know if the script ran. Please make sure your load balancer timeout isn't shorter than the Fleet server timeout."
// Software
InstallSoftwarePersonalAppleDeviceErrMsg = "Couldn't install. Currently, software install isn't supported on personal (BYOD) iOS and iPadOS hosts."
// End user authentication
EndUserAuthDEPWebURLConfiguredErrMsg = `End user authentication can't be configured when the configured automatic enrollment (DEP) profile specifies a configuration_web_url.` // #nosec G101