Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 803d6757 authored by Makoto Onuki's avatar Makoto Onuki
Browse files

Do not allow DO and PO running on the same user.

Bug 25346603

Change-Id: Ic5fbed82466a538fbf64ef802fc2624dd67313bb
parent b59db97f
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -4799,10 +4799,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
        if (info.isGuest()) {
            throw new IllegalStateException("Cannot set a profile owner on a guest");
        }
        if (getProfileOwner(userHandle) != null) {
        if (mOwners.hasProfileOwner(userHandle)) {
            throw new IllegalStateException("Trying to set the profile owner, but profile owner "
                    + "is already set.");
        }
        if (mOwners.hasDeviceOwner() && mOwners.getDeviceOwnerUserId() == userHandle) {
            throw new IllegalStateException("Trying to set the profile owner, but the user "
                    + "already has a device owner.");
        }
        int callingUid = mInjector.binderGetCallingUid();
        if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID) {
            if (hasUserSetupCompleted(userHandle) &&
@@ -4832,6 +4836,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
            throw new IllegalStateException("Trying to set the device owner, but device owner "
                    + "is already set.");
        }
        if (mOwners.hasProfileOwner(userId)) {
            throw new IllegalStateException("Trying to set the device owner, but the user already "
                    + "has a profile owner.");
        }
        if (!mUserManager.isUserRunning(new UserHandle(userId))) {
            throw new IllegalStateException("User not running: " + userId);
        }
+15 −8
Original line number Diff line number Diff line
@@ -121,9 +121,7 @@ class Owners {
                if (!legacy.delete()) {
                    Slog.e(TAG, "Failed to remove the legacy setting file");
                }
                return;
            }

            } else {
                // No legacy file, read from the new format files.
                new DeviceOwnerReadWriter().readFromFileLocked();

@@ -133,6 +131,11 @@ class Owners {
                }
            }
        }
        if (hasDeviceOwner() && hasProfileOwner(getDeviceOwnerUserId())) {
            Slog.w(TAG, String.format("User %d has both DO and PO, which is not supported",
                    getDeviceOwnerUserId()));
        }
    }

    String getDeviceOwnerPackageName() {
        return mDeviceOwner != null ? mDeviceOwner.packageName : null;
@@ -218,6 +221,10 @@ class Owners {
        return mDeviceOwner != null;
    }

    boolean hasProfileOwner(int userId) {
        return getProfileOwnerComponent(userId) != null;
    }

    /**
     * @return true if user restrictions need to be migrated for DO.
     */
+24 −0
Original line number Diff line number Diff line
@@ -490,6 +490,17 @@ public class DevicePolicyManagerTest extends DpmTestBase {

        assertEquals(admin1.getPackageName(), dpm.getDeviceOwner());

        // Try to set a profile owner on the same user, which should fail.
        setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_SYSTEM_USER_UID);
        dpm.setActiveAdmin(admin2, /* refreshing= */ true, UserHandle.USER_SYSTEM);
        try {
            dpm.setProfileOwner(admin2, "owner-name", UserHandle.USER_SYSTEM);
            fail("IllegalStateException not thrown");
        } catch (IllegalStateException expected) {
            assertTrue("Message was: " + expected.getMessage(),
                    expected.getMessage().contains("already has a device owner"));
        }

        // TODO Test getDeviceOwnerName() too.  To do so, we need to change
        // DPMS.getApplicationLabel() because Context.createPackageContextAsUser() is not mockable.
    }
@@ -509,6 +520,8 @@ public class DevicePolicyManagerTest extends DpmTestBase {
            dpm.setDeviceOwner(new ComponentName("a.b.c", ".def"));
            fail("Didn't throw IllegalArgumentException");
        } catch (IllegalArgumentException expected) {
            assertTrue("Message was: " + expected.getMessage(),
                    expected.getMessage().contains("Invalid component"));
        }
    }

@@ -597,6 +610,17 @@ public class DevicePolicyManagerTest extends DpmTestBase {

    public void testSetProfileOwner() throws Exception {
        setAsProfileOwner(admin1);

        // Try setting DO on the same user, which should fail.
        setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID);
        dpm.setActiveAdmin(admin2, /* refreshing= */ true, DpmMockContext.CALLER_USER_HANDLE);
        try {
            dpm.setDeviceOwner(admin2, "owner-name", DpmMockContext.CALLER_USER_HANDLE);
            fail("IllegalStateException not thrown");
        } catch (IllegalStateException expected) {
            assertTrue("Message was: " + expected.getMessage(),
                    expected.getMessage().contains("already has a profile owner"));
        }
    }

    public void testSetProfileOwner_failures() throws Exception {