summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Rubin Xu <rubinxu@google.com> 2024-01-24 17:27:25 +0000
committer Rubin Xu <rubinxu@google.com> 2024-02-13 19:19:36 +0000
commit8668395a6d6a5767cd92973da84e8cc83cdebeac (patch)
treef4a37519adf36f1f2115f240966edd8754d371e3
parent9027446c37c6e5a2d61ebc063d4a9c27294b5ea9 (diff)
Make zero trust related APIs callable by permission holders
1. getEnrollmentSpecificId This is currently callable by DO, PO and DELEGATION_CERT_INSTALL delegates. Convert this to MANAGE_DEVICE_POLICY_CERTIFICATES permission which DO, PO and DELEGATION_CERT_INSTALL all holds already (the DMRH also has this permission granted already) 2. getPendingSystemUpdate A new MANAGE_DEVICE_POLICY_SYSTEM_UPDATE_INFO permission is added to guard getPendingSystemUpdate. We also allow system update services (identified by the existing NOTIFY_PENDING_SYSTEM_UPDATE permission) who sets system update information to retrieve what it previously set via getPendingSystemUpdate. 3. notifyPendingSystemUpdate Also send ACTION_NOTIFY_PENDING_SYSTEM_UPDATE to all instances of the Device Management Role Holder. Bug: 254653320 Bug: 289520697 Test: EnrollmentSpecificIdTest android.devicepolicy.cts.PendingSystemUpdateTest android.permissionpolicy.cts Change-Id: I35367d115564f624fa8b3302c8ed4e2825c67893
-rw-r--r--core/api/current.txt4
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java28
-rw-r--r--core/java/android/app/admin/IDevicePolicyManager.aidl2
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java60
4 files changed, 66 insertions, 28 deletions
diff --git a/core/api/current.txt b/core/api/current.txt
index 97f078bfe1ff..2565e3dc8733 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -8013,7 +8013,7 @@ package android.app.admin {
method public CharSequence getDeviceOwnerLockScreenInfo();
method @Nullable public String getDevicePolicyManagementRoleHolderPackage();
method public CharSequence getEndUserSessionMessage(@NonNull android.content.ComponentName);
- method @NonNull public String getEnrollmentSpecificId();
+ method @FlaggedApi("android.app.admin.flags.permission_migration_for_zero_trust_api_enabled") @NonNull @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_CERTIFICATES, conditional=true) public String getEnrollmentSpecificId();
method @Nullable @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_FACTORY_RESET, conditional=true) public android.app.admin.FactoryResetProtectionPolicy getFactoryResetProtectionPolicy(@Nullable android.content.ComponentName);
method @Nullable public String getGlobalPrivateDnsHost(@NonNull android.content.ComponentName);
method public int getGlobalPrivateDnsMode(@NonNull android.content.ComponentName);
@@ -8052,7 +8052,7 @@ package android.app.admin {
method @Deprecated public int getPasswordMinimumSymbols(@Nullable android.content.ComponentName);
method @Deprecated public int getPasswordMinimumUpperCase(@Nullable android.content.ComponentName);
method @Deprecated public int getPasswordQuality(@Nullable android.content.ComponentName);
- method @Nullable public android.app.admin.SystemUpdateInfo getPendingSystemUpdate(@NonNull android.content.ComponentName);
+ method @FlaggedApi("android.app.admin.flags.permission_migration_for_zero_trust_api_enabled") @Nullable @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_QUERY_SYSTEM_UPDATES, conditional=true) public android.app.admin.SystemUpdateInfo getPendingSystemUpdate(@Nullable android.content.ComponentName);
method @RequiresPermission(value=android.Manifest.permission.MANAGE_DEVICE_POLICY_RUNTIME_PERMISSIONS, conditional=true) public int getPermissionGrantState(@Nullable android.content.ComponentName, @NonNull String, @NonNull String);
method public int getPermissionPolicy(android.content.ComponentName);
method @Nullable public java.util.List<java.lang.String> getPermittedAccessibilityServices(@NonNull android.content.ComponentName);
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 9d50810425c6..2971caec110f 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -37,6 +37,7 @@ import static android.Manifest.permission.MANAGE_DEVICE_POLICY_MTE;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_ORGANIZATION_IDENTITY;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_PACKAGE_STATE;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_PROFILE_INTERACTION;
+import static android.Manifest.permission.MANAGE_DEVICE_POLICY_QUERY_SYSTEM_UPDATES;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_RESET_PASSWORD;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_RUNTIME_PERMISSIONS;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_SCREEN_CAPTURE;
@@ -13415,17 +13416,25 @@ public class DevicePolicyManager {
}
/**
- * Called by device or profile owners to get information about a pending system update.
+ * Get information about a pending system update.
+ *
+ * Can be called by device or profile owners, and starting from Android
+ * {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM}, holders of the permission
+ * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_QUERY_SYSTEM_UPDATES}.
*
* @param admin Which profile or device owner this request is associated with.
* @return Information about a pending system update or {@code null} if no update pending.
- * @throws SecurityException if {@code admin} is not a device or profile owner.
+ * @throws SecurityException if {@code admin} is not a device, profile owner or holders of
+ * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_QUERY_SYSTEM_UPDATES}.
* @see DeviceAdminReceiver#onSystemUpdatePending(Context, Intent, long)
*/
- public @Nullable SystemUpdateInfo getPendingSystemUpdate(@NonNull ComponentName admin) {
+ @RequiresPermission(value = MANAGE_DEVICE_POLICY_QUERY_SYSTEM_UPDATES, conditional = true)
+ @SuppressLint("RequiresPermission")
+ @FlaggedApi(Flags.FLAG_PERMISSION_MIGRATION_FOR_ZERO_TRUST_API_ENABLED)
+ public @Nullable SystemUpdateInfo getPendingSystemUpdate(@Nullable ComponentName admin) {
throwIfParentInstance("getPendingSystemUpdate");
try {
- return mService.getPendingSystemUpdate(admin);
+ return mService.getPendingSystemUpdate(admin, mContext.getPackageName());
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
@@ -16476,8 +16485,9 @@ public class DevicePolicyManager {
* The identifier would be consistent even if the work profile is removed and enrolled again
* (to the same organization), or the device is factory reset and re-enrolled.
*
- * Can only be called by the Profile Owner or Device Owner, if the
- * {@link #setOrganizationId(String)} was previously called.
+ * Can only be called by the Profile Owner and Device Owner, and starting from Android
+ * {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM}, holders of the permission
+ * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_CERTIFICATES}.
* If {@link #setOrganizationId(String)} was not called, then the returned value will be an
* empty string.
*
@@ -16490,8 +16500,12 @@ public class DevicePolicyManager {
* and must switch to using this method.
*
* @return A stable, enrollment-specific identifier.
- * @throws SecurityException if the caller is not a profile owner or device owner.
+ * @throws SecurityException if the caller is not a profile owner, device owner or holding the
+ * {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_CERTIFICATES} permission
*/
+ @RequiresPermission(value = MANAGE_DEVICE_POLICY_CERTIFICATES, conditional = true)
+ @SuppressLint("RequiresPermission")
+ @FlaggedApi(Flags.FLAG_PERMISSION_MIGRATION_FOR_ZERO_TRUST_API_ENABLED)
@NonNull public String getEnrollmentSpecificId() {
throwIfParentInstance("getEnrollmentSpecificId");
if (mService == null) {
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index f72fdc069db5..02d54a59c935 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -392,7 +392,7 @@ interface IDevicePolicyManager {
boolean getDoNotAskCredentialsOnBoot();
void notifyPendingSystemUpdate(in SystemUpdateInfo info);
- SystemUpdateInfo getPendingSystemUpdate(in ComponentName admin);
+ SystemUpdateInfo getPendingSystemUpdate(in ComponentName admin, in String callerPackage);
void setPermissionPolicy(in ComponentName admin, in String callerPackage, int policy);
int getPermissionPolicy(in ComponentName admin);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 36b838172fa2..7c9bcc392880 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -60,6 +60,7 @@ import static android.Manifest.permission.MANAGE_DEVICE_POLICY_PHYSICAL_MEDIA;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_PRINTING;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_PROFILES;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_PROFILE_INTERACTION;
+import static android.Manifest.permission.MANAGE_DEVICE_POLICY_QUERY_SYSTEM_UPDATES;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_RESET_PASSWORD;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_RESTRICT_PRIVATE_DNS;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_RUNTIME_PERMISSIONS;
@@ -85,6 +86,7 @@ import static android.Manifest.permission.MANAGE_DEVICE_POLICY_WINDOWS;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_WIPE_DATA;
import static android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS;
import static android.Manifest.permission.MASTER_CLEAR;
+import static android.Manifest.permission.NOTIFY_PENDING_SYSTEM_UPDATE;
import static android.Manifest.permission.QUERY_ADMIN_POLICY;
import static android.Manifest.permission.REQUEST_PASSWORD_COMPLEXITY;
import static android.Manifest.permission.SET_TIME;
@@ -230,6 +232,7 @@ import static android.app.admin.ProvisioningException.ERROR_STARTING_PROFILE_FAI
import static android.app.admin.flags.Flags.backupServiceSecurityLogEventEnabled;
import static android.app.admin.flags.Flags.dumpsysPolicyEngineMigrationEnabled;
import static android.app.admin.flags.Flags.headlessDeviceOwnerSingleUserEnabled;
+import static android.app.admin.flags.Flags.permissionMigrationForZeroTrustImplEnabled;
import static android.app.admin.flags.Flags.policyEngineMigrationV2Enabled;
import static android.app.admin.flags.Flags.assistContentUserRestrictionEnabled;
import static android.content.Intent.ACTION_MANAGED_PROFILE_AVAILABLE;
@@ -16182,7 +16185,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
@Override
public void notifyPendingSystemUpdate(@Nullable SystemUpdateInfo info) {
Preconditions.checkCallAuthorization(
- hasCallingOrSelfPermission(permission.NOTIFY_PENDING_SYSTEM_UPDATE),
+ hasCallingOrSelfPermission(NOTIFY_PENDING_SYSTEM_UPDATE),
"Only the system update service can broadcast update information");
mInjector.binderWithCleanCallingIdentity(() -> {
@@ -16223,12 +16226,21 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
// Send broadcasts to corresponding profile owners if any.
for (final int userId : runningUserIds) {
+ final ComponentName profileOwnerPackage;
synchronized (getLockObject()) {
- final ComponentName profileOwnerPackage =
- mOwners.getProfileOwnerComponent(userId);
- if (profileOwnerPackage != null) {
- intent.setComponent(profileOwnerPackage);
- mContext.sendBroadcastAsUser(intent, UserHandle.of(userId));
+ profileOwnerPackage = mOwners.getProfileOwnerComponent(userId);
+ }
+ if (profileOwnerPackage != null) {
+ intent.setComponent(profileOwnerPackage);
+ mContext.sendBroadcastAsUser(intent, UserHandle.of(userId));
+ }
+
+ if (permissionMigrationForZeroTrustImplEnabled()) {
+ final UserHandle user = UserHandle.of(userId);
+ final String roleHolderPackage = getRoleHolderPackageNameOnUser(
+ RoleManager.ROLE_DEVICE_POLICY_MANAGEMENT, userId);
+ if (roleHolderPackage != null) {
+ broadcastExplicitIntentToPackage(intent, roleHolderPackage, user);
}
}
}
@@ -16236,13 +16248,19 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
@Override
- public SystemUpdateInfo getPendingSystemUpdate(ComponentName admin) {
- Objects.requireNonNull(admin, "ComponentName is null");
-
- final CallerIdentity caller = getCallerIdentity(admin);
- Preconditions.checkCallAuthorization(
- isDefaultDeviceOwner(caller) || isProfileOwner(caller));
+ public SystemUpdateInfo getPendingSystemUpdate(ComponentName admin, String callerPackage) {
+ if (permissionMigrationForZeroTrustImplEnabled()) {
+ CallerIdentity caller = getCallerIdentity(admin, callerPackage);
+ enforcePermissions(new String[] {NOTIFY_PENDING_SYSTEM_UPDATE,
+ MANAGE_DEVICE_POLICY_QUERY_SYSTEM_UPDATES}, caller.getPackageName(),
+ caller.getUserId());
+ } else {
+ Objects.requireNonNull(admin, "ComponentName is null");
+ final CallerIdentity caller = getCallerIdentity(admin);
+ Preconditions.checkCallAuthorization(
+ isDefaultDeviceOwner(caller) || isProfileOwner(caller));
+ }
return mOwners.getSystemUpdateInfo();
}
@@ -20708,14 +20726,18 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
final CallerIdentity caller = getCallerIdentity(callerPackage);
- Preconditions.checkCallAuthorization(
- isDefaultDeviceOwner(caller) || isProfileOwner(caller)
- || isCallerDelegate(caller, DELEGATION_CERT_INSTALL));
+ if (permissionMigrationForZeroTrustImplEnabled()) {
+ enforcePermission(MANAGE_DEVICE_POLICY_CERTIFICATES, caller.getPackageName());
+ } else {
+ Preconditions.checkCallAuthorization(
+ isDefaultDeviceOwner(caller) || isProfileOwner(caller)
+ || isCallerDelegate(caller, DELEGATION_CERT_INSTALL));
+ }
synchronized (getLockObject()) {
final ActiveAdmin requiredAdmin = getDeviceOrProfileOwnerAdminLocked(
caller.getUserId());
- final String esid = requiredAdmin.mEnrollmentSpecificId;
+ final String esid = requiredAdmin != null ? requiredAdmin.mEnrollmentSpecificId : null;
return esid != null ? esid : "";
}
}
@@ -22385,7 +22407,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
MANAGE_DEVICE_POLICY_WINDOWS,
MANAGE_DEVICE_POLICY_WIPE_DATA,
SET_TIME,
- SET_TIME_ZONE
+ SET_TIME_ZONE,
+ MANAGE_DEVICE_POLICY_QUERY_SYSTEM_UPDATES
);
private static final List<String> FINANCED_DEVICE_OWNER_PERMISSIONS = List.of(
MANAGE_DEVICE_POLICY_ACROSS_USERS,
@@ -22448,7 +22471,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
MANAGE_DEVICE_POLICY_SYSTEM_DIALOGS,
MANAGE_DEVICE_POLICY_TIME,
MANAGE_DEVICE_POLICY_VPN,
- MANAGE_DEVICE_POLICY_WIPE_DATA
+ MANAGE_DEVICE_POLICY_WIPE_DATA,
+ MANAGE_DEVICE_POLICY_QUERY_SYSTEM_UPDATES
);
/**