Merge "Migrate account management disabled policy" into udc-dev

This commit is contained in:
Kholoud Mohamed
2023-04-17 09:49:24 +00:00
committed by Android (Google) Code Review
3 changed files with 128 additions and 31 deletions

View File

@@ -631,6 +631,38 @@ final class DevicePolicyEngine {
} }
} }
/**
* Returns all the {@code policyKeys} set by any admin that share the same
* {@link PolicyKey#getIdentifier()} as the provided {@code policyDefinition}.
*
* <p>For example, getLocalPolicyKeysSetByAllAdmins(PERMISSION_GRANT) returns all permission
* grants set by any admin.
*
* <p>Note that this will always return at most one item for policies that do not require
* additional params (e.g. {@link PolicyDefinition#LOCK_TASK} vs
* {@link PolicyDefinition#PERMISSION_GRANT(String, String)}).
*
*/
@NonNull
<V> Set<PolicyKey> getLocalPolicyKeysSetByAllAdmins(
@NonNull PolicyDefinition<V> policyDefinition,
int userId) {
Objects.requireNonNull(policyDefinition);
synchronized (mLock) {
if (policyDefinition.isGlobalOnlyPolicy() || !mLocalPolicies.contains(userId)) {
return Set.of();
}
Set<PolicyKey> keys = new HashSet<>();
for (PolicyKey key : mLocalPolicies.get(userId).keySet()) {
if (key.hasSameIdentifierAs(policyDefinition.getPolicyKey())) {
keys.add(key);
}
}
return keys;
}
}
/** /**
* Returns all user restriction policies set by the given admin. * Returns all user restriction policies set by the given admin.
* *

View File

@@ -280,6 +280,7 @@ import android.app.Notification;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.app.StatusBarManager; import android.app.StatusBarManager;
import android.app.admin.AccountTypePolicyKey;
import android.app.admin.BooleanPolicyValue; import android.app.admin.BooleanPolicyValue;
import android.app.admin.BundlePolicyValue; import android.app.admin.BundlePolicyValue;
import android.app.admin.ComponentNamePolicyValue; import android.app.admin.ComponentNamePolicyValue;
@@ -14019,16 +14020,28 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
caller = getCallerIdentity(who); caller = getCallerIdentity(who);
} }
synchronized (getLockObject()) { synchronized (getLockObject()) {
final ActiveAdmin ap;
if (isPermissionCheckFlagEnabled()) { if (isPermissionCheckFlagEnabled()) {
int affectedUser = getAffectedUser(parent);
EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin( EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin(
who, who,
MANAGE_DEVICE_POLICY_ACCOUNT_MANAGEMENT, MANAGE_DEVICE_POLICY_ACCOUNT_MANAGEMENT,
caller.getPackageName(), caller.getPackageName(),
getAffectedUser(parent) affectedUser
); );
ap = enforcingAdmin.getActiveAdmin(); if (disabled) {
mDevicePolicyEngine.setLocalPolicy(
PolicyDefinition.ACCOUNT_MANAGEMENT_DISABLED(accountType),
enforcingAdmin,
new BooleanPolicyValue(disabled),
affectedUser);
} else { } else {
mDevicePolicyEngine.removeLocalPolicy(
PolicyDefinition.ACCOUNT_MANAGEMENT_DISABLED(accountType),
enforcingAdmin,
affectedUser);
}
} else {
final ActiveAdmin ap;
Objects.requireNonNull(who, "ComponentName is null"); Objects.requireNonNull(who, "ComponentName is null");
/* /*
* When called on the parent DPM instance (parent == true), affects active admin * When called on the parent DPM instance (parent == true), affects active admin
@@ -14045,7 +14058,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
ap = getParentOfAdminIfRequired( ap = getParentOfAdminIfRequired(
getProfileOwnerOrDeviceOwnerLocked(caller.getUserId()), parent); getProfileOwnerOrDeviceOwnerLocked(caller.getUserId()), parent);
} }
}
if (disabled) { if (disabled) {
ap.accountTypesWithManagementDisabled.add(accountType); ap.accountTypesWithManagementDisabled.add(accountType);
} else { } else {
@@ -14054,6 +14066,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
saveSettingsLocked(UserHandle.getCallingUserId()); saveSettingsLocked(UserHandle.getCallingUserId());
} }
} }
}
@Override @Override
public String[] getAccountTypesWithManagementDisabled(String callerPackageName) { public String[] getAccountTypesWithManagementDisabled(String callerPackageName) {
@@ -14069,22 +14082,43 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
} }
CallerIdentity caller; CallerIdentity caller;
Preconditions.checkArgumentNonnegative(userId, "Invalid userId"); Preconditions.checkArgumentNonnegative(userId, "Invalid userId");
final ArraySet<String> resultSet = new ArraySet<>();
if (isPermissionCheckFlagEnabled()) { if (isPermissionCheckFlagEnabled()) {
int affectedUser = parent ? getProfileParentId(userId) : userId;
caller = getCallerIdentity(callerPackageName); caller = getCallerIdentity(callerPackageName);
if (!hasPermission(MANAGE_DEVICE_POLICY_ACCOUNT_MANAGEMENT, if (!hasPermission(MANAGE_DEVICE_POLICY_ACCOUNT_MANAGEMENT,
caller.getPackageName(), userId) callerPackageName, affectedUser)
&& !hasFullCrossUsersPermission(caller, userId)) { && !hasFullCrossUsersPermission(caller, userId)) {
throw new SecurityException("Caller does not have permission to call this on user: " throw new SecurityException("Caller does not have permission to call this on user: "
+ userId); + affectedUser);
} }
Set<PolicyKey> keys = mDevicePolicyEngine.getLocalPolicyKeysSetByAllAdmins(
PolicyDefinition.GENERIC_ACCOUNT_MANAGEMENT_DISABLED,
affectedUser);
for (PolicyKey key : keys) {
if (!(key instanceof AccountTypePolicyKey)) {
throw new IllegalStateException("PolicyKey for "
+ "MANAGE_DEVICE_POLICY_ACCOUNT_MANAGEMENT is not of type "
+ "AccountTypePolicyKey");
}
AccountTypePolicyKey parsedKey =
(AccountTypePolicyKey) key;
String accountType = Objects.requireNonNull(parsedKey.getAccountType());
Boolean disabled = mDevicePolicyEngine.getResolvedPolicy(
PolicyDefinition.ACCOUNT_MANAGEMENT_DISABLED(accountType),
affectedUser);
if (disabled != null && disabled) {
resultSet.add(accountType);
}
}
} else { } else {
caller = getCallerIdentity(); caller = getCallerIdentity();
Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(caller, userId)); Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(caller, userId));
}
synchronized (getLockObject()) { synchronized (getLockObject()) {
final ArraySet<String> resultSet = new ArraySet<>();
if (!parent) { if (!parent) {
final DevicePolicyData policy = getUserData(userId); final DevicePolicyData policy = getUserData(userId);
for (ActiveAdmin admin : policy.mAdminList) { for (ActiveAdmin admin : policy.mAdminList) {
@@ -14092,19 +14126,21 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
} }
} }
// Check if there's a profile owner of an org-owned device and the method is called for // Check if there's a profile owner of an org-owned device and the method is called
// the parent user of this profile owner. // for the parent user of this profile owner.
final ActiveAdmin orgOwnedAdmin = final ActiveAdmin orgOwnedAdmin =
getProfileOwnerOfOrganizationOwnedDeviceLocked(userId); getProfileOwnerOfOrganizationOwnedDeviceLocked(userId);
final boolean shouldGetParentAccounts = orgOwnedAdmin != null && (parent final boolean shouldGetParentAccounts = orgOwnedAdmin != null && (parent
|| UserHandle.getUserId(orgOwnedAdmin.getUid()) != userId); || UserHandle.getUserId(orgOwnedAdmin.getUid()) != userId);
if (shouldGetParentAccounts) { if (shouldGetParentAccounts) {
resultSet.addAll( resultSet.addAll(
orgOwnedAdmin.getParentActiveAdmin().accountTypesWithManagementDisabled); orgOwnedAdmin.getParentActiveAdmin()
.accountTypesWithManagementDisabled);
}
}
} }
return resultSet.toArray(new String[resultSet.size()]); return resultSet.toArray(new String[resultSet.size()]);
} }
}
@Override @Override
public void setUninstallBlocked(ComponentName who, String callerPackage, String packageName, public void setUninstallBlocked(ComponentName who, String callerPackage, String packageName,

View File

@@ -18,6 +18,7 @@ package com.android.server.devicepolicy;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.app.admin.AccountTypePolicyKey;
import android.app.admin.BooleanPolicyValue; import android.app.admin.BooleanPolicyValue;
import android.app.admin.DevicePolicyIdentifiers; import android.app.admin.DevicePolicyIdentifiers;
import android.app.admin.DevicePolicyManager; import android.app.admin.DevicePolicyManager;
@@ -281,6 +282,32 @@ final class PolicyDefinition<V> {
DevicePolicyIdentifiers.APPLICATION_HIDDEN_POLICY, packageName)); DevicePolicyIdentifiers.APPLICATION_HIDDEN_POLICY, packageName));
} }
// This is saved in the static map sPolicyDefinitions so that we're able to reconstruct the
// actual policy with the correct arguments (i.e. packageName) when reading the policies from
// xml.
static PolicyDefinition<Boolean> GENERIC_ACCOUNT_MANAGEMENT_DISABLED =
new PolicyDefinition<>(
new AccountTypePolicyKey(
DevicePolicyIdentifiers.ACCOUNT_MANAGEMENT_DISABLED_POLICY),
TRUE_MORE_RESTRICTIVE,
POLICY_FLAG_LOCAL_ONLY_POLICY,
// Nothing is enforced, we just need to store it
(Boolean value, Context context, Integer userId, PolicyKey policyKey) -> true,
new BooleanPolicySerializer());
/**
* Passing in {@code null} for {@code accountType} will return
* {@link #GENERIC_ACCOUNT_MANAGEMENT_DISABLED}.
*/
static PolicyDefinition<Boolean> ACCOUNT_MANAGEMENT_DISABLED(String accountType) {
if (accountType == null) {
return GENERIC_ACCOUNT_MANAGEMENT_DISABLED;
}
return GENERIC_ACCOUNT_MANAGEMENT_DISABLED.createPolicyDefinition(
new AccountTypePolicyKey(
DevicePolicyIdentifiers.ACCOUNT_MANAGEMENT_DISABLED_POLICY, accountType));
}
private static final Map<String, PolicyDefinition<?>> POLICY_DEFINITIONS = new HashMap<>(); private static final Map<String, PolicyDefinition<?>> POLICY_DEFINITIONS = new HashMap<>();
private static Map<String, Integer> USER_RESTRICTION_FLAGS = new HashMap<>(); private static Map<String, Integer> USER_RESTRICTION_FLAGS = new HashMap<>();
@@ -304,6 +331,8 @@ final class PolicyDefinition<V> {
KEYGUARD_DISABLED_FEATURES); KEYGUARD_DISABLED_FEATURES);
POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.APPLICATION_HIDDEN_POLICY, POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.APPLICATION_HIDDEN_POLICY,
GENERIC_APPLICATION_HIDDEN); GENERIC_APPLICATION_HIDDEN);
POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.ACCOUNT_MANAGEMENT_DISABLED_POLICY,
GENERIC_ACCOUNT_MANAGEMENT_DISABLED);
// User Restriction Policies // User Restriction Policies
USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_MODIFY_ACCOUNTS, /* flags= */ 0); USER_RESTRICTION_FLAGS.put(UserManager.DISALLOW_MODIFY_ACCOUNTS, /* flags= */ 0);