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

Commit a47d72c3 authored by Sarup Dalwani's avatar Sarup Dalwani
Browse files

Restricting creation of Clone Profile when the device owner is set

As part of Android S, the restriction was enforced by CDD but the user creation flow did not
block creation of clone profile. Creating changes that will add user restriction
of type  UserManager.DISALLOW_ADD_CLONE_PROFILE while setting up device
owner. This restriction is checked while user creation flow and throws
UserManager.CheckedUserOperationException. When the device owner is
removed, the user restriction UserManager.DISALLOW_ADD_CLONE_PROFILE is
removed and creation of clone profile is allowed.

Bug: 211862605
Test: 1. atest FrameworksServicesTests:com.android.server.devicepolicy.DevicePolicyManagerTest
2. atest FrameworksServicesTests:com.android.server.pm.UserManagerTest
3. Manually tried creation of clone profile before setting device
owner, able to create clone profile
4. Manually set device owner and tried to create clone profile, unable to
create clone profile
5. Manually removed device owner and tried to create clone profile, able
to create clone profile.

Change-Id: Id87756601a25323e06036a3193f6a7f8f53fa71d
parent b9003c2a
Loading
Loading
Loading
Loading
+15 −0
Original line number Original line Diff line number Diff line
@@ -819,6 +819,20 @@ public class UserManager {
    @Deprecated
    @Deprecated
    public static final String DISALLOW_ADD_MANAGED_PROFILE = "no_add_managed_profile";
    public static final String DISALLOW_ADD_MANAGED_PROFILE = "no_add_managed_profile";


    /**
     * Specifies if a user is disallowed from creating clone profile.
     * <p>The default value for an unmanaged user is <code>false</code>.
     * For users with a device owner set, the default is <code>true</code>.
     *
     * <p>Key for user restrictions.
     * <p>Type: Boolean
     * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
     * @see DevicePolicyManager#clearUserRestriction(ComponentName, String)
     * @see #getUserRestrictions()
     * @hide
     */
    public static final String DISALLOW_ADD_CLONE_PROFILE = "no_add_clone_profile";

    /**
    /**
     * Specifies if a user is disallowed from disabling application verification. The default
     * Specifies if a user is disallowed from disabling application verification. The default
     * value is <code>false</code>.
     * value is <code>false</code>.
@@ -1497,6 +1511,7 @@ public class UserManager {
            DISALLOW_FACTORY_RESET,
            DISALLOW_FACTORY_RESET,
            DISALLOW_ADD_USER,
            DISALLOW_ADD_USER,
            DISALLOW_ADD_MANAGED_PROFILE,
            DISALLOW_ADD_MANAGED_PROFILE,
            DISALLOW_ADD_CLONE_PROFILE,
            ENSURE_VERIFY_APPS,
            ENSURE_VERIFY_APPS,
            DISALLOW_CONFIG_CELL_BROADCASTS,
            DISALLOW_CONFIG_CELL_BROADCASTS,
            DISALLOW_CONFIG_MOBILE_NETWORKS,
            DISALLOW_CONFIG_MOBILE_NETWORKS,
+12 −3
Original line number Original line Diff line number Diff line
@@ -3667,9 +3667,18 @@ public class UserManagerService extends IUserManager.Stub {
            @UserInfoFlag int flags, @UserIdInt int parentId,
            @UserInfoFlag int flags, @UserIdInt int parentId,
            @Nullable String[] disallowedPackages)
            @Nullable String[] disallowedPackages)
            throws UserManager.CheckedUserOperationException {
            throws UserManager.CheckedUserOperationException {
        String restriction = (UserManager.isUserTypeManagedProfile(userType))

                ? UserManager.DISALLOW_ADD_MANAGED_PROFILE
        // Checking user restriction before creating new user,
                : UserManager.DISALLOW_ADD_USER;
        // default check is for DISALLOW_ADD_USER
        // If new user is of type CLONE, check if creation of clone profile is allowed
        // If new user is of type MANAGED, check if creation of managed profile is allowed
        String restriction = UserManager.DISALLOW_ADD_USER;
        if (UserManager.isUserTypeCloneProfile(userType)) {
            restriction = UserManager.DISALLOW_ADD_CLONE_PROFILE;
        } else if (UserManager.isUserTypeManagedProfile(userType)) {
            restriction = UserManager.DISALLOW_ADD_MANAGED_PROFILE;
        }

        enforceUserRestriction(restriction, UserHandle.getCallingUserId(),
        enforceUserRestriction(restriction, UserHandle.getCallingUserId(),
                "Cannot add user");
                "Cannot add user");
        return createUserInternalUnchecked(name, userType, flags, parentId,
        return createUserInternalUnchecked(name, userType, flags, parentId,
+1 −0
Original line number Original line Diff line number Diff line
@@ -101,6 +101,7 @@ public class UserRestrictionsUtils {
            UserManager.DISALLOW_FACTORY_RESET,
            UserManager.DISALLOW_FACTORY_RESET,
            UserManager.DISALLOW_ADD_USER,
            UserManager.DISALLOW_ADD_USER,
            UserManager.DISALLOW_ADD_MANAGED_PROFILE,
            UserManager.DISALLOW_ADD_MANAGED_PROFILE,
            UserManager.DISALLOW_ADD_CLONE_PROFILE,
            UserManager.ENSURE_VERIFY_APPS,
            UserManager.ENSURE_VERIFY_APPS,
            UserManager.DISALLOW_CONFIG_CELL_BROADCASTS,
            UserManager.DISALLOW_CONFIG_CELL_BROADCASTS,
            UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS,
            UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS,
+26 −4
Original line number Original line Diff line number Diff line
@@ -2216,7 +2216,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
     * a managed profile.
     * a managed profile.
     */
     */
    @GuardedBy("getLockObject()")
    @GuardedBy("getLockObject()")
    private void applyManagedProfileRestrictionIfDeviceOwnerLocked() {
    private void applyProfileRestrictionsIfDeviceOwnerLocked() {
        final int doUserId = mOwners.getDeviceOwnerUserId();
        final int doUserId = mOwners.getDeviceOwnerUserId();
        if (doUserId == UserHandle.USER_NULL) {
        if (doUserId == UserHandle.USER_NULL) {
            if (VERBOSE_LOG) Slogf.d(LOG_TAG, "No DO found, skipping application of restriction.");
            if (VERBOSE_LOG) Slogf.d(LOG_TAG, "No DO found, skipping application of restriction.");
@@ -2224,7 +2224,17 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        }
        }
        final UserHandle doUserHandle = UserHandle.of(doUserId);
        final UserHandle doUserHandle = UserHandle.of(doUserId);
        // Set the restriction if not set.
        // Based on  CDD : https://source.android.com/compatibility/12/android-12-cdd#95_multi-user_support,
        // creation of clone profile is not allowed in case device owner is set.
        // Enforcing this restriction on setting up of device owner.
        if (!mUserManager.hasUserRestriction(
                UserManager.DISALLOW_ADD_CLONE_PROFILE, doUserHandle)) {
            mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_CLONE_PROFILE, true,
                    doUserHandle);
        }
        // Creation of managed profile is restricted in case device owner is set, enforcing this
        // restriction by setting user level restriction at time of device owner setup.
        if (!mUserManager.hasUserRestriction(
        if (!mUserManager.hasUserRestriction(
                UserManager.DISALLOW_ADD_MANAGED_PROFILE, doUserHandle)) {
                UserManager.DISALLOW_ADD_MANAGED_PROFILE, doUserHandle)) {
            mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_MANAGED_PROFILE, true,
            mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_MANAGED_PROFILE, true,
@@ -3133,7 +3143,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
            case SystemService.PHASE_ACTIVITY_MANAGER_READY:
            case SystemService.PHASE_ACTIVITY_MANAGER_READY:
                synchronized (getLockObject()) {
                synchronized (getLockObject()) {
                    migrateToProfileOnOrganizationOwnedDeviceIfCompLocked();
                    migrateToProfileOnOrganizationOwnedDeviceIfCompLocked();
                    applyManagedProfileRestrictionIfDeviceOwnerLocked();
                    applyProfileRestrictionsIfDeviceOwnerLocked();
                }
                }
                maybeStartSecurityLogMonitorOnActivityManagerReady();
                maybeStartSecurityLogMonitorOnActivityManagerReady();
                break;
                break;
@@ -3760,6 +3770,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
            mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_MANAGED_PROFILE, false,
            mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_MANAGED_PROFILE, false,
                    userHandle);
                    userHandle);
        }
        }
        // When a device owner is set, the system automatically restricts adding a clone profile.
        // Remove this restriction when the device owner is cleared.
        if (mUserManager.hasUserRestriction(UserManager.DISALLOW_ADD_CLONE_PROFILE, userHandle)) {
            mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_CLONE_PROFILE, false,
                    userHandle);
        }
    }
    }
    /**
    /**
@@ -8435,6 +8451,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
                // on the primary profile).
                // on the primary profile).
                mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_MANAGED_PROFILE, true,
                mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_MANAGED_PROFILE, true,
                        UserHandle.of(userId));
                        UserHandle.of(userId));
                // Restrict adding a clone profile when a device owner is set on the device.
                // That is to prevent the co-existence of a clone profile and a device owner
                // on the same device.
                // CDD for reference : https://source.android.com/compatibility/12/android-12-cdd#95_multi-user_support
                mUserManager.setUserRestriction(UserManager.DISALLOW_ADD_CLONE_PROFILE, true,
                        UserHandle.of(userId));
                // TODO Send to system too?
                // TODO Send to system too?
                sendOwnerChangedBroadcast(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED, userId);
                sendOwnerChangedBroadcast(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED, userId);
            });
            });
@@ -8907,7 +8929,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
        mOwners.writeProfileOwner(userId);
        mOwners.writeProfileOwner(userId);
        deleteTransferOwnershipBundleLocked(userId);
        deleteTransferOwnershipBundleLocked(userId);
        toggleBackupServiceActive(userId, true);
        toggleBackupServiceActive(userId, true);
        applyManagedProfileRestrictionIfDeviceOwnerLocked();
        applyProfileRestrictionsIfDeviceOwnerLocked();
        setNetworkLoggingActiveInternal(false);
        setNetworkLoggingActiveInternal(false);
    }
    }
+8 −0
Original line number Original line Diff line number Diff line
@@ -1110,6 +1110,10 @@ public class DevicePolicyManagerTest extends DpmTestBase {
                eq(UserManager.DISALLOW_ADD_MANAGED_PROFILE),
                eq(UserManager.DISALLOW_ADD_MANAGED_PROFILE),
                eq(true), eq(UserHandle.SYSTEM));
                eq(true), eq(UserHandle.SYSTEM));


        verify(getServices().userManager, times(1)).setUserRestriction(
                eq(UserManager.DISALLOW_ADD_CLONE_PROFILE),
                eq(true), eq(UserHandle.SYSTEM));

        verify(mContext.spiedContext, times(1)).sendBroadcastAsUser(
        verify(mContext.spiedContext, times(1)).sendBroadcastAsUser(
                MockUtils.checkIntentAction(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED),
                MockUtils.checkIntentAction(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED),
                MockUtils.checkUserHandle(UserHandle.USER_SYSTEM));
                MockUtils.checkUserHandle(UserHandle.USER_SYSTEM));
@@ -1391,6 +1395,10 @@ public class DevicePolicyManagerTest extends DpmTestBase {
                eq(false),
                eq(false),
                MockUtils.checkUserHandle(UserHandle.USER_SYSTEM));
                MockUtils.checkUserHandle(UserHandle.USER_SYSTEM));


        verify(getServices().userManager)
                .setUserRestriction(eq(UserManager.DISALLOW_ADD_CLONE_PROFILE), eq(false),
                MockUtils.checkUserHandle(UserHandle.USER_SYSTEM));

        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
        verify(getServices().userManagerInternal).setDevicePolicyUserRestrictions(
                eq(UserHandle.USER_SYSTEM), MockUtils.checkUserRestrictions(),
                eq(UserHandle.USER_SYSTEM), MockUtils.checkUserRestrictions(),
                MockUtils.checkUserRestrictions(UserHandle.USER_SYSTEM), eq(true));
                MockUtils.checkUserRestrictions(UserHandle.USER_SYSTEM), eq(true));
Loading