Home | History | Annotate | Download | only in jni
      1 /*
      2  * Copyright 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "permission_helpers.h"
     18 
     19 #include <base/logging.h>
     20 #include <base/strings/stringprintf.h>
     21 #include <binder/IPCThreadState.h>
     22 #include <binder/IServiceManager.h>
     23 #include <pwd.h>
     24 #include <sys/types.h>
     25 #include "IUserManager.h"
     26 
     27 using ::android::binder::Status;
     28 
     29 namespace android {
     30 namespace bluetooth {
     31 
     32 uid_t foregroundUserId;
     33 uid_t systemUiUid;
     34 static uid_t SYSTEM_UID = 1000;
     35 constexpr int PER_USER_RANGE = 100000;
     36 
     37 Status checkPermission(const char* permission) {
     38   int32_t pid;
     39   int32_t uid;
     40 
     41   if (android::checkCallingPermission(String16(permission), &pid, &uid)) {
     42     return Status::ok();
     43   }
     44 
     45   auto err = ::base::StringPrintf("UID %d / PID %d lacks permission %s", uid,
     46                                   pid, permission);
     47   return Status::fromExceptionCode(Status::EX_SECURITY, String8(err.c_str()));
     48 }
     49 
     50 bool isCallerActiveUser() {
     51   IPCThreadState* ipcState = IPCThreadState::selfOrNull();
     52   if (!ipcState) return true;  // It's a local call
     53 
     54   uid_t callingUid = ipcState->getCallingUid();
     55   uid_t callingUser = callingUid / PER_USER_RANGE;
     56   if (callingUid == getuid()) return true;  // It's a local call
     57 
     58   return (foregroundUserId == callingUser) || (systemUiUid == callingUid) ||
     59          (SYSTEM_UID == callingUid);
     60 }
     61 
     62 bool isCallerActiveUserOrManagedProfile() {
     63   IPCThreadState* ipcState = IPCThreadState::selfOrNull();
     64   if (!ipcState) return true;  // It's a local call
     65 
     66   uid_t callingUid = ipcState->getCallingUid();
     67   uid_t callingUser = callingUid / PER_USER_RANGE;
     68   if (callingUid == getuid()) return true;  // It's a local call
     69 
     70   if ((foregroundUserId == callingUser) || (systemUiUid == callingUid) ||
     71       (SYSTEM_UID == callingUid))
     72     return true;
     73 
     74   uid_t parentUser = callingUser;
     75 
     76   sp<IServiceManager> sm = defaultServiceManager();
     77   sp<IBinder> binder = sm->getService(String16("user"));
     78   sp<IUserManager> um = interface_cast<IUserManager>(binder);
     79   if (um != NULL) {
     80     // Must use Bluetooth process identity when making call to get parent user
     81     int64_t ident = ipcState->clearCallingIdentity();
     82     parentUser = um->getProfileParentId(callingUser);
     83     ipcState->restoreCallingIdentity(ident);
     84   }
     85 
     86   return foregroundUserId == parentUser;
     87 }
     88 
     89 }  // namespace bluetooth
     90 }  // namespace android
     91