diff --git a/api/current.txt b/api/current.txt index cfb9398ac2315..ec56ce05ea0a0 100644 --- a/api/current.txt +++ b/api/current.txt @@ -17,7 +17,6 @@ package android { field public static final java.lang.String ACCESS_WIFI_STATE = "android.permission.ACCESS_WIFI_STATE"; field public static final java.lang.String ACCOUNT_MANAGER = "android.permission.ACCOUNT_MANAGER"; field public static final java.lang.String ADD_VOICEMAIL = "com.android.voicemail.permission.ADD_VOICEMAIL"; - field public static final java.lang.String AUTHENTICATE_ACCOUNTS = "android.permission.AUTHENTICATE_ACCOUNTS"; field public static final java.lang.String BATTERY_STATS = "android.permission.BATTERY_STATS"; field public static final java.lang.String BIND_ACCESSIBILITY_SERVICE = "android.permission.BIND_ACCESSIBILITY_SERVICE"; field public static final java.lang.String BIND_APPWIDGET = "android.permission.BIND_APPWIDGET"; @@ -86,7 +85,6 @@ package android { field public static final java.lang.String INTERNET = "android.permission.INTERNET"; field public static final java.lang.String KILL_BACKGROUND_PROCESSES = "android.permission.KILL_BACKGROUND_PROCESSES"; field public static final java.lang.String LOCATION_HARDWARE = "android.permission.LOCATION_HARDWARE"; - field public static final java.lang.String MANAGE_ACCOUNTS = "android.permission.MANAGE_ACCOUNTS"; field public static final java.lang.String MANAGE_APP_TOKENS = "android.permission.MANAGE_APP_TOKENS"; field public static final java.lang.String MANAGE_DOCUMENTS = "android.permission.MANAGE_DOCUMENTS"; field public static final java.lang.String MASTER_CLEAR = "android.permission.MASTER_CLEAR"; @@ -145,7 +143,6 @@ package android { field public static final java.lang.String TRANSMIT_IR = "android.permission.TRANSMIT_IR"; field public static final java.lang.String UNINSTALL_SHORTCUT = "com.android.launcher.permission.UNINSTALL_SHORTCUT"; field public static final java.lang.String UPDATE_DEVICE_STATS = "android.permission.UPDATE_DEVICE_STATS"; - field public static final java.lang.String USE_CREDENTIALS = "android.permission.USE_CREDENTIALS"; field public static final java.lang.String USE_FINGERPRINT = "android.permission.USE_FINGERPRINT"; field public static final java.lang.String USE_SIP = "android.permission.USE_SIP"; field public static final java.lang.String VIBRATE = "android.permission.VIBRATE"; diff --git a/api/system-current.txt b/api/system-current.txt index 6035ef29b48af..5ec8a62f8637a 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -24,7 +24,6 @@ package android { field public static final java.lang.String ACCOUNT_MANAGER = "android.permission.ACCOUNT_MANAGER"; field public static final java.lang.String ADD_VOICEMAIL = "com.android.voicemail.permission.ADD_VOICEMAIL"; field public static final java.lang.String ALLOW_ANY_CODEC_FOR_PLAYBACK = "android.permission.ALLOW_ANY_CODEC_FOR_PLAYBACK"; - field public static final java.lang.String AUTHENTICATE_ACCOUNTS = "android.permission.AUTHENTICATE_ACCOUNTS"; field public static final java.lang.String BACKUP = "android.permission.BACKUP"; field public static final java.lang.String BATTERY_STATS = "android.permission.BATTERY_STATS"; field public static final java.lang.String BIND_ACCESSIBILITY_SERVICE = "android.permission.BIND_ACCESSIBILITY_SERVICE"; @@ -117,7 +116,6 @@ package android { field public static final java.lang.String LOCAL_MAC_ADDRESS = "android.permission.LOCAL_MAC_ADDRESS"; field public static final java.lang.String LOCATION_HARDWARE = "android.permission.LOCATION_HARDWARE"; field public static final java.lang.String LOOP_RADIO = "android.permission.LOOP_RADIO"; - field public static final java.lang.String MANAGE_ACCOUNTS = "android.permission.MANAGE_ACCOUNTS"; field public static final java.lang.String MANAGE_ACTIVITY_STACKS = "android.permission.MANAGE_ACTIVITY_STACKS"; field public static final java.lang.String MANAGE_APP_TOKENS = "android.permission.MANAGE_APP_TOKENS"; field public static final java.lang.String MANAGE_CA_CERTIFICATES = "android.permission.MANAGE_CA_CERTIFICATES"; @@ -217,7 +215,6 @@ package android { field public static final java.lang.String UPDATE_DEVICE_STATS = "android.permission.UPDATE_DEVICE_STATS"; field public static final java.lang.String UPDATE_LOCK = "android.permission.UPDATE_LOCK"; field public static final java.lang.String USER_ACTIVITY = "android.permission.USER_ACTIVITY"; - field public static final java.lang.String USE_CREDENTIALS = "android.permission.USE_CREDENTIALS"; field public static final java.lang.String USE_FINGERPRINT = "android.permission.USE_FINGERPRINT"; field public static final java.lang.String USE_SIP = "android.permission.USE_SIP"; field public static final java.lang.String VIBRATE = "android.permission.VIBRATE"; diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java index 31e129b787f62..993b53d17d705 100644 --- a/core/java/android/accounts/AccountManager.java +++ b/core/java/android/accounts/AccountManager.java @@ -51,10 +51,7 @@ import java.util.concurrent.FutureTask; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import static android.Manifest.permission.AUTHENTICATE_ACCOUNTS; import static android.Manifest.permission.GET_ACCOUNTS; -import static android.Manifest.permission.MANAGE_ACCOUNTS; -import static android.Manifest.permission.USE_CREDENTIALS; /** * This class provides access to a centralized registry of the user's @@ -319,14 +316,12 @@ public class AccountManager { * *
It is safe to call this method from the main thread. * - *
This method requires the caller to hold the permission - * {@link android.Manifest.permission#AUTHENTICATE_ACCOUNTS} - * and to have the same UID as the account's authenticator. + *
This method requires the caller to have a signature match with the + * authenticator that owns the specified account. * - * @param account The account to query for a password + * @param account The account to query for a password. Must not be {@code null}. * @return The account's password, null if none or if the account doesn't exist */ - @RequiresPermission(AUTHENTICATE_ACCOUNTS) public String getPassword(final Account account) { if (account == null) throw new IllegalArgumentException("account is null"); try { @@ -345,14 +340,12 @@ public class AccountManager { * *
It is safe to call this method from the main thread. * - *
This method requires the caller to hold the permission - * {@link android.Manifest.permission#AUTHENTICATE_ACCOUNTS} - * and to have the same UID as the account's authenticator. + *
This method requires the caller to have a signature match with the + * authenticator that owns the specified account. * * @param account The account to query for user data * @return The user data, null if the account or key doesn't exist */ - @RequiresPermission(AUTHENTICATE_ACCOUNTS) public String getUserData(final Account account, final String key) { if (account == null) throw new IllegalArgumentException("account is null"); if (key == null) throw new IllegalArgumentException("key is null"); @@ -662,10 +655,8 @@ public class AccountManager { * wizards associated with authenticators, not directly by applications. * *
It is safe to call this method from the main thread. - * - *
This method requires the caller to hold the permission - * {@link android.Manifest.permission#AUTHENTICATE_ACCOUNTS} - * and to have the same UID as the added account's authenticator. + *
This method requires the caller to have a signature match with the + * authenticator that owns the specified account. * * @param account The {@link Account} to add * @param password The password to associate with the account, null for none @@ -673,7 +664,6 @@ public class AccountManager { * @return True if the account was successfully added, false if the account * already exists, the account is null, or another error occurs. */ - @RequiresPermission(AUTHENTICATE_ACCOUNTS) public boolean addAccountExplicitly(Account account, String password, Bundle userdata) { if (account == null) throw new IllegalArgumentException("account is null"); try { @@ -692,14 +682,13 @@ public class AccountManager { *
* It is not safe to call this method from the main thread. As such, call it * from another thread. - *
- * This method requires the caller to hold the permission - * {@link android.Manifest.permission#AUTHENTICATE_ACCOUNTS} and should be - * called from the account's authenticator. + *
This method requires the caller to have a signature match with the + * authenticator that owns the specified account. * * @param account The {@link Account} to be updated. + * @return boolean {@code true} if the authentication of the account has been successfully + * acknowledged. Otherwise {@code false}. */ - @RequiresPermission(AUTHENTICATE_ACCOUNTS) public boolean notifyAccountAuthenticated(Account account) { if (account == null) throw new IllegalArgumentException("account is null"); @@ -717,9 +706,8 @@ public class AccountManager { * *
It is safe to call this method from the main thread. * - *
This method requires the caller to hold the permission - * {@link android.Manifest.permission#AUTHENTICATE_ACCOUNTS} - * and have the same UID as the account's authenticator. + *
This method requires the caller to have a signature match with the
+ * authenticator that manages the specified account.
*
* @param account The {@link Account} to rename
* @param newName String name to be associated with the account.
@@ -731,7 +719,6 @@ public class AccountManager {
* after the name change. If successful the account's name will be the
* specified new name.
*/
- @RequiresPermission(AUTHENTICATE_ACCOUNTS)
public AccountManagerFuture This method may be called from any thread, but the returned
- * {@link AccountManagerFuture} must not be used on the main thread.
- *
- * This method requires the caller to hold the permission
- * {@link android.Manifest.permission#MANAGE_ACCOUNTS}.
+ * This method requires the caller to have a signature match with the
+ * authenticator that manages the specified account.
*
* @param account The {@link Account} to remove
* @param callback Callback to invoke when the request completes,
@@ -800,15 +784,16 @@ public class AccountManager {
* {@link #removeAccount(Account, Activity, AccountManagerCallback, Handler)}
* instead
*/
- @RequiresPermission(MANAGE_ACCOUNTS)
@Deprecated
public AccountManagerFuture This method may be called from any thread, but the returned
* {@link AccountManagerFuture} must not be used on the main thread.
*
- * This method requires the caller to hold the permission
- * {@link android.Manifest.permission#MANAGE_ACCOUNTS}.
+ * This method requires the caller to have a signature match with the
+ * authenticator that manages the specified account.
*
* @param account The {@link Account} to remove
* @param activity The {@link Activity} context to use for launching a new
@@ -855,11 +840,11 @@ public class AccountManager {
* adding accounts (of this type) has been disabled by policy
*
*/
- @RequiresPermission(MANAGE_ACCOUNTS)
public AccountManagerFuture
* It is safe to call this method from the main thread.
- *
- * This method requires the caller to hold the permission
- * {@link android.Manifest.permission#AUTHENTICATE_ACCOUNTS} and to have the
- * same UID or signature as the account's authenticator.
+ * This method requires the caller to have a signature match with the
+ * authenticator that manages the specified account.
*
* @param account The {@link Account} to delete.
* @return True if the account was successfully deleted, false if the
* account did not exist, the account is null, or another error
* occurs.
*/
- @RequiresPermission(AUTHENTICATE_ACCOUNTS)
public boolean removeAccountExplicitly(Account account) {
if (account == null) throw new IllegalArgumentException("account is null");
try {
@@ -948,14 +932,9 @@ public class AccountManager {
*
* It is safe to call this method from the main thread.
*
- * This method requires the caller to hold the permission
- * {@link android.Manifest.permission#MANAGE_ACCOUNTS} or
- * {@link android.Manifest.permission#USE_CREDENTIALS}
- *
* @param accountType The account type of the auth token to invalidate, must not be null
* @param authToken The auth token to invalidate, may be null
*/
- @RequiresPermission(anyOf = {MANAGE_ACCOUNTS, USE_CREDENTIALS})
public void invalidateAuthToken(final String accountType, final String authToken) {
if (accountType == null) throw new IllegalArgumentException("accountType is null");
try {
@@ -976,16 +955,15 @@ public class AccountManager {
*
* It is safe to call this method from the main thread.
*
- * This method requires the caller to hold the permission
- * {@link android.Manifest.permission#AUTHENTICATE_ACCOUNTS}
- * and to have the same UID as the account's authenticator.
+ * This method requires the caller to have a signature match with the
+ * authenticator that manages the specified account.
*
- * @param account The account to fetch an auth token for
- * @param authTokenType The type of auth token to fetch, see {#getAuthToken}
+ * @param account The account for which an auth token is to be fetched. Cannot be {@code null}.
+ * @param authTokenType The type of auth token to fetch. Cannot be {@code null}.
* @return The cached auth token for this account and type, or null if
* no auth token is cached or the account does not exist.
+ * @see #getAuthToken
*/
- @RequiresPermission(AUTHENTICATE_ACCOUNTS)
public String peekAuthToken(final Account account, final String authTokenType) {
if (account == null) throw new IllegalArgumentException("account is null");
if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
@@ -1005,14 +983,12 @@ public class AccountManager {
*
* It is safe to call this method from the main thread.
*
- * This method requires the caller to hold the permission
- * {@link android.Manifest.permission#AUTHENTICATE_ACCOUNTS}
- * and have the same UID as the account's authenticator.
+ * This method requires the caller to have a signature match with the
+ * authenticator that manages the specified account.
*
- * @param account The account to set a password for
+ * @param account The account whose password is to be set. Cannot be {@code null}.
* @param password The password to set, null to clear the password
*/
- @RequiresPermission(AUTHENTICATE_ACCOUNTS)
public void setPassword(final Account account, final String password) {
if (account == null) throw new IllegalArgumentException("account is null");
try {
@@ -1030,14 +1006,14 @@ public class AccountManager {
* permissions, and may be used by applications or management interfaces
* to "sign out" from an account.
*
- * It is safe to call this method from the main thread.
+ * This method only successfully clear the account's password when the
+ * caller has the same signature as the authenticator that owns the
+ * specified account. Otherwise, this method will silently fail.
*
- * This method requires the caller to hold the permission
- * {@link android.Manifest.permission#MANAGE_ACCOUNTS}
+ * It is safe to call this method from the main thread.
*
* @param account The account whose password to clear
*/
- @RequiresPermission(MANAGE_ACCOUNTS)
public void clearPassword(final Account account) {
if (account == null) throw new IllegalArgumentException("account is null");
try {
@@ -1055,15 +1031,13 @@ public class AccountManager {
*
* It is safe to call this method from the main thread.
*
- * This method requires the caller to hold the permission
- * {@link android.Manifest.permission#AUTHENTICATE_ACCOUNTS}
- * and to have the same UID as the account's authenticator.
+ * This method requires the caller to have a signature match with the
+ * authenticator that manages the specified account.
*
- * @param account The account to set the userdata for
- * @param key The userdata key to set. Must not be null
- * @param value The value to set, null to clear this userdata key
+ * @param account Account whose user data is to be set. Must not be {@code null}.
+ * @param key String user data key to set. Must not be null
+ * @param value String value to set, {@code null} to clear this user data key
*/
- @RequiresPermission(AUTHENTICATE_ACCOUNTS)
public void setUserData(final Account account, final String key, final String value) {
if (account == null) throw new IllegalArgumentException("account is null");
if (key == null) throw new IllegalArgumentException("key is null");
@@ -1083,15 +1057,13 @@ public class AccountManager {
*
* It is safe to call this method from the main thread.
*
- * This method requires the caller to hold the permission
- * {@link android.Manifest.permission#AUTHENTICATE_ACCOUNTS}
- * and to have the same UID as the account's authenticator.
+ * This method requires the caller to have a signature match with the
+ * authenticator that manages the specified account.
*
* @param account The account to set an auth token for
* @param authTokenType The type of the auth token, see {#getAuthToken}
* @param authToken The auth token to add to the cache
*/
- @RequiresPermission(AUTHENTICATE_ACCOUNTS)
public void setAuthToken(Account account, final String authTokenType, final String authToken) {
if (account == null) throw new IllegalArgumentException("account is null");
if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
@@ -1110,9 +1082,6 @@ public class AccountManager {
* This method may block while a network request completes, and must
* never be made from the main thread.
*
- * This method requires the caller to hold the permission
- * {@link android.Manifest.permission#USE_CREDENTIALS}.
- *
* @param account The account to fetch an auth token for
* @param authTokenType The auth token type, see {@link #getAuthToken getAuthToken()}
* @param notifyAuthFailure If true, display a notification and return null
@@ -1126,7 +1095,6 @@ public class AccountManager {
* @throws java.io.IOException if the authenticator experienced an I/O problem
* creating a new auth token, usually because of network trouble
*/
- @RequiresPermission(USE_CREDENTIALS)
public String blockingGetAuthToken(Account account, String authTokenType,
boolean notifyAuthFailure)
throws OperationCanceledException, IOException, AuthenticatorException {
@@ -1165,9 +1133,6 @@ public class AccountManager {
* This method may be called from any thread, but the returned
* {@link AccountManagerFuture} must not be used on the main thread.
*
- * This method requires the caller to hold the permission
- * {@link android.Manifest.permission#USE_CREDENTIALS}.
- *
* @param account The account to fetch an auth token for
* @param authTokenType The auth token type, an authenticator-dependent
* string token, must not be null
@@ -1201,7 +1166,6 @@ public class AccountManager {
* authenticator-dependent. The caller should verify the validity of the
* account before requesting an auth token.
*/
- @RequiresPermission(USE_CREDENTIALS)
public AccountManagerFuture This method may be called from any thread, but the returned
* {@link AccountManagerFuture} must not be used on the main thread.
*
- * This method requires the caller to hold the permission
- * {@link android.Manifest.permission#USE_CREDENTIALS}.
- *
* @param account The account to fetch an auth token for
* @param authTokenType The auth token type, an authenticator-dependent
* string token, must not be null
@@ -1292,7 +1253,6 @@ public class AccountManager {
* boolean, AccountManagerCallback, android.os.Handler)} instead
*/
@Deprecated
- @RequiresPermission(USE_CREDENTIALS)
public AccountManagerFuture This method may be called from any thread, but the returned
* {@link AccountManagerFuture} must not be used on the main thread.
*
- * This method requires the caller to hold the permission
- * {@link android.Manifest.permission#USE_CREDENTIALS}.
- *
* @param account The account to fetch an auth token for
* @param authTokenType The auth token type, an authenticator-dependent
* string token, must not be null
@@ -1371,7 +1328,6 @@ public class AccountManager {
* authenticator-dependent. The caller should verify the validity of the
* account before requesting an auth token.
*/
- @RequiresPermission(USE_CREDENTIALS)
public AccountManagerFuture This method may be called from any thread, but the returned
* {@link AccountManagerFuture} must not be used on the main thread.
*
- * This method requires the caller to hold the permission
- * {@link android.Manifest.permission#MANAGE_ACCOUNTS}.
- *
* @param accountType The type of account to add; must not be null
* @param authTokenType The type of auth token (see {@link #getAuthToken})
* this account will need to be able to generate, null for none
@@ -1441,7 +1394,6 @@ public class AccountManager {
* creating a new account, usually because of network trouble
*
*/
- @RequiresPermission(MANAGE_ACCOUNTS)
public AccountManagerFuture This method may be called from any thread, but the returned
* {@link AccountManagerFuture} must not be used on the main thread.
*
- * This method requires the caller to hold the permission
- * {@link android.Manifest.permission#MANAGE_ACCOUNTS}.
- *
* @param account The account to confirm password knowledge for
* @param options Authenticator-specific options for the request;
* if the {@link #KEY_PASSWORD} string field is present, the
@@ -1615,11 +1564,11 @@ public class AccountManager {
* If no activity or password was specified, the returned Bundle contains
* {@link #KEY_INTENT} with the {@link Intent} needed to launch the
* password prompt.
- *
+ *
* Also the returning Bundle may contain {@link
* #KEY_LAST_AUTHENTICATED_TIME} indicating the last time the
* credential was validated/created.
- *
+ *
* If an error occurred,{@link AccountManagerFuture#getResult()} throws:
* This method may be called from any thread, but the returned
* {@link AccountManagerFuture} must not be used on the main thread.
*
- * This method requires the caller to hold the permission
- * {@link android.Manifest.permission#MANAGE_ACCOUNTS}.
- *
* @param account The account to update credentials for
* @param authTokenType The credentials entered must allow an auth token
* of this type to be created (but no actual auth token is returned);
@@ -1706,7 +1651,6 @@ public class AccountManager {
* verifying the password, usually because of network trouble
*
*/
- @RequiresPermission(MANAGE_ACCOUNTS)
public AccountManagerFuture This method may be called from any thread, but the returned
* {@link AccountManagerFuture} must not be used on the main thread.
*
- * This method requires the caller to hold the permission
- * {@link android.Manifest.permission#MANAGE_ACCOUNTS}.
+ * This method requires the caller to have the same signature as the
+ * authenticator associated with the specified account type.
*
* @param accountType The account type associated with the authenticator
* to adjust
@@ -1758,7 +1702,6 @@ public class AccountManager {
* updating settings, usually because of network trouble
*
*/
- @RequiresPermission(MANAGE_ACCOUNTS)
public AccountManagerFuture This method may be called from any thread, but the returned
* {@link AccountManagerFuture} must not be used on the main thread.
*
- * This method requires the caller to hold the permission
- * {@link android.Manifest.permission#MANAGE_ACCOUNTS}.
- *
* @param accountType The account type required
* (see {@link #getAccountsByType}), must not be null
* @param authTokenType The desired auth token type
@@ -2292,7 +2232,6 @@ public class AccountManager {
* updating settings, usually because of network trouble
*
*/
- @RequiresPermission(MANAGE_ACCOUNTS)
public AccountManagerFuture
The following snippet shows how to add the permissions:
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 21f96c9dbdbdb..49d9988ac5495 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -87,11 +87,8 @@ import java.io.File;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
-import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
@@ -100,7 +97,6 @@ import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
-import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
@@ -526,14 +522,20 @@ public class AccountManagerService
@Override
public String getPassword(Account account) {
+ int callingUid = Binder.getCallingUid();
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "getPassword: " + account
+ ", caller's uid " + Binder.getCallingUid()
+ ", pid " + Binder.getCallingPid());
}
if (account == null) throw new IllegalArgumentException("account is null");
- checkAuthenticateAccountsPermission(account);
-
+ if (!isAccountOwnedByCallingUid(account.type, callingUid)) {
+ String msg = String.format(
+ "uid %s cannot get secrets for accounts of type: %s",
+ callingUid,
+ account.type);
+ throw new SecurityException(msg);
+ }
UserAccounts accounts = getUserAccountsForCaller();
long identityToken = clearCallingIdentity();
try {
@@ -617,15 +619,21 @@ public class AccountManagerService
@Override
public String getUserData(Account account, String key) {
+ final int callingUid = Binder.getCallingUid();
if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "getUserData: " + account
- + ", key " + key
- + ", caller's uid " + Binder.getCallingUid()
- + ", pid " + Binder.getCallingPid());
+ String msg = String.format("getUserData( account: %s, key: %s, callerUid: %s, pid: %s",
+ account, key, callingUid, Binder.getCallingPid());
+ Log.v(TAG, msg);
}
if (account == null) throw new IllegalArgumentException("account is null");
if (key == null) throw new IllegalArgumentException("key is null");
- checkAuthenticateAccountsPermission(account);
+ if (!isAccountOwnedByCallingUid(account.type, callingUid)) {
+ String msg = String.format(
+ "uid %s cannot get user data for accounts of type: %s",
+ callingUid,
+ account.type);
+ throw new SecurityException(msg);
+ }
UserAccounts accounts = getUserAccountsForCaller();
long identityToken = clearCallingIdentity();
try {
@@ -676,13 +684,20 @@ public class AccountManagerService
@Override
public boolean addAccountExplicitly(Account account, String password, Bundle extras) {
+ final int callingUid = Binder.getCallingUid();
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "addAccountExplicitly: " + account
- + ", caller's uid " + Binder.getCallingUid()
+ + ", caller's uid " + callingUid
+ ", pid " + Binder.getCallingPid());
}
if (account == null) throw new IllegalArgumentException("account is null");
- checkAuthenticateAccountsPermission(account);
+ if (!isAccountOwnedByCallingUid(account.type, callingUid)) {
+ String msg = String.format(
+ "uid %s cannot explicitly add accounts of type: %s",
+ callingUid,
+ account.type);
+ throw new SecurityException(msg);
+ }
/*
* Child users are not allowed to add accounts. Only the accounts that are
* shared by the parent profile can be added to child profile.
@@ -758,10 +773,24 @@ public class AccountManagerService
@Override
public boolean accountAuthenticated(final Account account) {
+ final int callingUid = Binder.getCallingUid();
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ String msg = String.format(
+ "accountAuthenticated( account: %s, callerUid: %s)",
+ account,
+ callingUid);
+ Log.v(TAG, msg);
+ }
if (account == null) {
throw new IllegalArgumentException("account is null");
}
- checkAuthenticateAccountsPermission(account);
+ if (!isAccountOwnedByCallingUid(account.type, callingUid)) {
+ String msg = String.format(
+ "uid %s cannot notify authentication for accounts of type: %s",
+ callingUid,
+ account.type);
+ throw new SecurityException(msg);
+ }
int userId = Binder.getCallingUserHandle().getIdentifier();
if (!canUserModifyAccounts(userId) || !canUserModifyAccountsForType(userId, account.type)) {
return false;
@@ -1007,16 +1036,21 @@ public class AccountManagerService
@Override
public void renameAccount(
IAccountManagerResponse response, Account accountToRename, String newName) {
+ final int callingUid = Binder.getCallingUid();
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "renameAccount: " + accountToRename + " -> " + newName
- + ", caller's uid " + Binder.getCallingUid()
+ + ", caller's uid " + callingUid
+ ", pid " + Binder.getCallingPid());
}
if (accountToRename == null) throw new IllegalArgumentException("account is null");
- checkAuthenticateAccountsPermission(accountToRename);
+ if (!isAccountOwnedByCallingUid(accountToRename.type, callingUid)) {
+ String msg = String.format(
+ "uid %s cannot rename accounts of type: %s",
+ callingUid,
+ accountToRename.type);
+ throw new SecurityException(msg);
+ }
UserAccounts accounts = getUserAccountsForCaller();
-
- int callingUid = getCallingUid();
long identityToken = clearCallingIdentity();
try {
Account resultingAccount = renameAccountInternal(accounts, accountToRename, newName,
@@ -1125,65 +1159,21 @@ public class AccountManagerService
@Override
public void removeAccount(IAccountManagerResponse response, Account account,
boolean expectActivityLaunch) {
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "removeAccount: " + account
- + ", response " + response
- + ", caller's uid " + Binder.getCallingUid()
- + ", pid " + Binder.getCallingPid());
- }
- if (response == null) throw new IllegalArgumentException("response is null");
- if (account == null) throw new IllegalArgumentException("account is null");
- checkManageAccountsPermission();
- UserHandle user = Binder.getCallingUserHandle();
- UserAccounts accounts = getUserAccountsForCaller();
- int userId = Binder.getCallingUserHandle().getIdentifier();
- if (!canUserModifyAccounts(userId)) {
- try {
- // TODO: This should be ERROR_CODE_USER_RESTRICTED instead. See http://b/16322768
- response.onError(AccountManager.ERROR_CODE_UNSUPPORTED_OPERATION,
- "User cannot modify accounts");
- } catch (RemoteException re) {
- }
- return;
- }
- if (!canUserModifyAccountsForType(userId, account.type)) {
- try {
- response.onError(AccountManager.ERROR_CODE_MANAGEMENT_DISABLED_FOR_ACCOUNT_TYPE,
- "User cannot modify accounts of this type (policy).");
- } catch (RemoteException re) {
- }
- return;
- }
-
- long identityToken = clearCallingIdentity();
-
- cancelNotification(getSigninRequiredNotificationId(accounts, account), user);
- synchronized (accounts.credentialsPermissionNotificationIds) {
- for (Pair
*
*/
- @RequiresPermission(MANAGE_ACCOUNTS)
public AccountManagerFuture