diff options
| author | 2024-01-24 17:27:25 +0000 | |
|---|---|---|
| committer | 2024-02-13 19:19:36 +0000 | |
| commit | 8668395a6d6a5767cd92973da84e8cc83cdebeac (patch) | |
| tree | f4a37519adf36f1f2115f240966edd8754d371e3 | |
| parent | 9027446c37c6e5a2d61ebc063d4a9c27294b5ea9 (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
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 ); /** |