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

Commit 586a4e71 authored by Pavel Grafov's avatar Pavel Grafov
Browse files

Remove mActiveAdmin from EnforcingAdmin

The field was only set when EnforcingAdmin was created for authorization
purposes, but not when it was loaded from XML, so the getter can't be
reliably used on all instances. All EnfrocingAdmins created for a DPC or
DA have component name set, which can be used to recover ActiveAdmin if
necessary.

Bug: 335663055
Test: btest a.d.c.WipeDataTest
Test: btest a.d.c.LockTest
Test: btest a.d.c.PasswordComplexityTest
Flag: android.app.admin.flags.active_admin_cleanup
Change-Id: Iabd5a4e9ee4a309ef4e781faaf2900a55004772b
parent 913ca7a3
Loading
Loading
Loading
Loading
+10 −0
Original line number Original line Diff line number Diff line
@@ -342,6 +342,16 @@ flag {
    }
    }
}
}


flag {
    name: "active_admin_cleanup"
    namespace: "enterprise"
    description: "Remove ActiveAdmin from EnforcingAdmin and related cleanups"
    bug: "335663055"
    metadata {
        purpose: PURPOSE_BUGFIX
    }
}

flag {
flag {
    name: "user_provisioning_same_state"
    name: "user_provisioning_same_state"
    namespace: "enterprise"
    namespace: "enterprise"
+75 −36
Original line number Original line Diff line number Diff line
@@ -5563,13 +5563,25 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                caller.getUserId());
                caller.getUserId());
        Preconditions.checkArgument(!calledOnParent || isProfileOwner(caller));
        Preconditions.checkArgument(!calledOnParent || isProfileOwner(caller));
        ActiveAdmin activeAdmin = admin.getActiveAdmin();
        final ActiveAdmin activeAdmin;
        if (Flags.activeAdminCleanup()) {
            if (admin.hasAuthority(EnforcingAdmin.DPC_AUTHORITY)) {
                synchronized (getLockObject()) {
                    activeAdmin = getActiveAdminUncheckedLocked(
                            admin.getComponentName(), admin.getUserId());
                }
            } else {
                activeAdmin = null;
            }
        } else {
            activeAdmin = admin.getActiveAdmin();
        }
        // We require the caller to explicitly clear any password quality requirements set
        // We require the caller to explicitly clear any password quality requirements set
        // on the parent DPM instance, to avoid the case where password requirements are
        // on the parent DPM instance, to avoid the case where password requirements are
        // specified in the form of quality on the parent but complexity on the profile
        // specified in the form of quality on the parent but complexity on the profile
        // itself.
        // itself.
        if (!calledOnParent) {
        if (activeAdmin != null && !calledOnParent) {
            final boolean hasQualityRequirementsOnParent = activeAdmin.hasParentActiveAdmin()
            final boolean hasQualityRequirementsOnParent = activeAdmin.hasParentActiveAdmin()
                    && activeAdmin.getParentActiveAdmin().mPasswordPolicy.quality
                    && activeAdmin.getParentActiveAdmin().mPasswordPolicy.quality
                    != PASSWORD_QUALITY_UNSPECIFIED;
                    != PASSWORD_QUALITY_UNSPECIFIED;
@@ -5593,20 +5605,22 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
        }
        }
        mInjector.binderWithCleanCallingIdentity(() -> {
        mInjector.binderWithCleanCallingIdentity(() -> {
            if (activeAdmin != null) {
                // Reset the password policy.
                // Reset the password policy.
                if (calledOnParent) {
                if (calledOnParent) {
                    activeAdmin.getParentActiveAdmin().mPasswordPolicy = new PasswordPolicy();
                    activeAdmin.getParentActiveAdmin().mPasswordPolicy = new PasswordPolicy();
                } else {
                } else {
                    activeAdmin.mPasswordPolicy = new PasswordPolicy();
                    activeAdmin.mPasswordPolicy = new PasswordPolicy();
                }
                }
                updatePasswordQualityCacheForUserGroup(caller.getUserId());
            }
            synchronized (getLockObject()) {
            synchronized (getLockObject()) {
                updatePasswordValidityCheckpointLocked(caller.getUserId(), calledOnParent);
                updatePasswordValidityCheckpointLocked(caller.getUserId(), calledOnParent);
            }
            }
            updatePasswordQualityCacheForUserGroup(caller.getUserId());
            saveSettingsLocked(caller.getUserId());
            saveSettingsLocked(caller.getUserId());
        });
        });
        DevicePolicyEventLogger
        DevicePolicyEventLogger
                .createEvent(DevicePolicyEnums.SET_PASSWORD_COMPLEXITY)
                .createEvent(DevicePolicyEnums.SET_PASSWORD_COMPLEXITY)
                .setAdmin(caller.getPackageName())
                .setAdmin(caller.getPackageName())
@@ -6287,28 +6301,33 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
        final int callingUserId = caller.getUserId();
        final int callingUserId = caller.getUserId();
        ComponentName adminComponent = null;
        ComponentName adminComponent = null;
        synchronized (getLockObject()) {
        synchronized (getLockObject()) {
            ActiveAdmin admin;
            // Make sure the caller has any active admin with the right policy or
            // Make sure the caller has any active admin with the right policy or
            // the required permission.
            // the required permission.
            if (Flags.lockNowCoexistence()) {
            if (Flags.lockNowCoexistence()) {
                admin = enforcePermissionsAndGetEnforcingAdmin(
                EnforcingAdmin enforcingAdmin = enforcePermissionsAndGetEnforcingAdmin(
                        /* admin= */ null,
                        /* admin= */ null,
                        /* permissions= */ new String[]{MANAGE_DEVICE_POLICY_LOCK, LOCK_DEVICE},
                        /* permissions= */ new String[]{MANAGE_DEVICE_POLICY_LOCK, LOCK_DEVICE},
                        /* deviceAdminPolicy= */ USES_POLICY_FORCE_LOCK,
                        /* deviceAdminPolicy= */ USES_POLICY_FORCE_LOCK,
                        caller.getPackageName(),
                        caller.getPackageName(),
                        getAffectedUser(parent)
                        getAffectedUser(parent)
                 ).getActiveAdmin();
                );
                if (Flags.activeAdminCleanup()) {
                    adminComponent = enforcingAdmin.getComponentName();
                } else {
                } else {
                admin = getActiveAdminOrCheckPermissionForCallerLocked(
                    ActiveAdmin admin = enforcingAdmin.getActiveAdmin();
                    adminComponent = admin == null ? null : admin.info.getComponent();
                }
            } else {
                ActiveAdmin admin = getActiveAdminOrCheckPermissionForCallerLocked(
                        null,
                        null,
                        DeviceAdminInfo.USES_POLICY_FORCE_LOCK,
                        DeviceAdminInfo.USES_POLICY_FORCE_LOCK,
                        parent,
                        parent,
                        LOCK_DEVICE);
                        LOCK_DEVICE);
                adminComponent = admin == null ? null : admin.info.getComponent();
            }
            }
            checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_LOCK_NOW);
            checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_LOCK_NOW);
            final long ident = mInjector.binderClearCallingIdentity();
            final long ident = mInjector.binderClearCallingIdentity();
            try {
            try {
                adminComponent = admin == null ? null : admin.info.getComponent();
                if (adminComponent != null) {
                if (adminComponent != null) {
                    // For Profile Owners only, callers with only permission not allowed.
                    // For Profile Owners only, callers with only permission not allowed.
                    if ((flags & DevicePolicyManager.FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY) != 0) {
                    if ((flags & DevicePolicyManager.FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY) != 0) {
@@ -7777,7 +7796,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                USES_POLICY_WIPE_DATA,
                USES_POLICY_WIPE_DATA,
                caller.getPackageName(),
                caller.getPackageName(),
                factoryReset ? UserHandle.USER_ALL : getAffectedUser(calledOnParentInstance));
                factoryReset ? UserHandle.USER_ALL : getAffectedUser(calledOnParentInstance));
        ActiveAdmin admin = enforcingAdmin.getActiveAdmin();
        checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_WIPE_DATA);
        checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_WIPE_DATA);
@@ -7786,10 +7804,20 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                    calledByProfileOwnerOnOrgOwnedDevice, calledOnParentInstance);
                    calledByProfileOwnerOnOrgOwnedDevice, calledOnParentInstance);
        }
        }
        int userId = admin != null ? admin.getUserHandle().getIdentifier()
        int userId;
        ActiveAdmin admin = null;
        if (Flags.activeAdminCleanup()) {
            userId = enforcingAdmin.getUserId();
            Slogf.i(LOG_TAG, "wipeDataWithReason(%s): admin=%s, user=%d", wipeReasonForUser,
                    enforcingAdmin, userId);
        } else {
            admin = enforcingAdmin.getActiveAdmin();
            userId = admin != null ? admin.getUserHandle().getIdentifier()
                    : caller.getUserId();
                    : caller.getUserId();
            Slogf.i(LOG_TAG, "wipeDataWithReason(%s): admin=%s, user=%d", wipeReasonForUser, admin,
            Slogf.i(LOG_TAG, "wipeDataWithReason(%s): admin=%s, user=%d", wipeReasonForUser, admin,
                    userId);
                    userId);
        }
        if (calledByProfileOwnerOnOrgOwnedDevice) {
        if (calledByProfileOwnerOnOrgOwnedDevice) {
            // When wipeData is called on the parent instance, it implies wiping the entire device.
            // When wipeData is called on the parent instance, it implies wiping the entire device.
            if (calledOnParentInstance) {
            if (calledOnParentInstance) {
@@ -7810,6 +7838,16 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
        final String adminName;
        final String adminName;
        final ComponentName adminComp;
        final ComponentName adminComp;
        if (Flags.activeAdminCleanup()) {
            adminComp = enforcingAdmin.getComponentName();
            adminName = adminComp != null
                    ? adminComp.flattenToShortString()
                    : enforcingAdmin.getPackageName();
            event.setAdmin(enforcingAdmin.getPackageName());
            // Not including any HSUM handling here because the "else" branch in the "flag off"
            // case below is unreachable under normal circumstances and for permission-based
            // callers admin won't be null.
        } else {
            if (admin != null) {
            if (admin != null) {
                if (admin.isPermissionBased) {
                if (admin.isPermissionBased) {
                    adminComp = null;
                    adminComp = null;
@@ -7831,6 +7869,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                    userId = UserHandle.USER_SYSTEM;
                    userId = UserHandle.USER_SYSTEM;
                }
                }
            }
            }
        }
        event.write();
        event.write();
        String internalReason = String.format(
        String internalReason = String.format(
+9 −0
Original line number Original line Diff line number Diff line
@@ -23,6 +23,7 @@ import android.app.admin.DeviceAdminAuthority;
import android.app.admin.DpcAuthority;
import android.app.admin.DpcAuthority;
import android.app.admin.RoleAuthority;
import android.app.admin.RoleAuthority;
import android.app.admin.UnknownAuthority;
import android.app.admin.UnknownAuthority;
import android.app.admin.flags.Flags;
import android.content.ComponentName;
import android.content.ComponentName;
import android.os.UserHandle;
import android.os.UserHandle;


@@ -291,9 +292,17 @@ final class EnforcingAdmin {


    @Nullable
    @Nullable
    public ActiveAdmin getActiveAdmin() {
    public ActiveAdmin getActiveAdmin() {
        if (Flags.activeAdminCleanup()) {
            throw new UnsupportedOperationException("getActiveAdmin() no longer supported");
        }
        return mActiveAdmin;
        return mActiveAdmin;
    }
    }


    @Nullable
    ComponentName getComponentName() {
        return mComponentName;
    }

    @NonNull
    @NonNull
    android.app.admin.EnforcingAdmin getParcelableAdmin() {
    android.app.admin.EnforcingAdmin getParcelableAdmin() {
        Authority authority;
        Authority authority;