• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "permission_checker.h"
17 
18 #include "access_token.h"
19 #include "admin_manager.h"
20 #include "edm_constants.h"
21 #include "edm_ipc_interface_code.h"
22 #include "edm_log.h"
23 #include "func_code_utils.h"
24 #include "ipc_skeleton.h"
25 #include "permission_manager.h"
26 
27 namespace OHOS {
28 namespace EDM {
29 
30 std::shared_ptr<PermissionChecker> PermissionChecker::instance_;
31 std::once_flag PermissionChecker::flag_;
32 
33 std::vector<uint32_t> PermissionChecker::supportAdminNullPolicyCode_ = {
34     EdmInterfaceCode::DISALLOW_ADD_OS_ACCOUNT_BY_USER,
35     EdmInterfaceCode::DISALLOW_ADD_LOCAL_ACCOUNT,
36     EdmInterfaceCode::DISABLE_BLUETOOTH,
37     EdmInterfaceCode::ALLOWED_BLUETOOTH_DEVICES,
38     EdmInterfaceCode::SET_BROWSER_POLICIES,
39     EdmInterfaceCode::MANAGED_BROWSER_POLICY,
40     EdmInterfaceCode::DISALLOW_MODIFY_DATETIME,
41     EdmInterfaceCode::LOCATION_POLICY,
42     EdmInterfaceCode::FINGERPRINT_AUTH,
43     EdmInterfaceCode::DISABLE_MICROPHONE,
44     EdmInterfaceCode::DISABLED_PRINTER,
45     EdmInterfaceCode::DISABLED_HDC,
46     EdmInterfaceCode::DISABLE_USB,
47     EdmInterfaceCode::DISALLOWED_USB_DEVICES,
48     EdmInterfaceCode::USB_READ_ONLY,
49     EdmInterfaceCode::ALLOWED_USB_DEVICES,
50     EdmInterfaceCode::DISABLE_WIFI,
51     EdmInterfaceCode::DISABLE_MTP_CLIENT,
52     EdmInterfaceCode::DISABLE_MTP_SERVER,
53     EdmInterfaceCode::DISALLOWED_TETHERING,
54     EdmInterfaceCode::INACTIVE_USER_FREEZE,
55     EdmInterfaceCode::DISABLE_CAMERA,
56     EdmInterfaceCode::PASSWORD_POLICY,
57     EdmInterfaceCode::POLICY_CODE_END + EdmConstants::PolicyCode::DISALLOW_SCREEN_SHOT,
58     EdmInterfaceCode::POLICY_CODE_END + EdmConstants::PolicyCode::DISALLOW_SCREEN_RECORD,
59     EdmInterfaceCode::POLICY_CODE_END + EdmConstants::PolicyCode::DISABLE_DISK_RECOVERY_KEY,
60     EdmInterfaceCode::POLICY_CODE_END + EdmConstants::PolicyCode::DISALLOW_NEAR_LINK,
61     EdmInterfaceCode::POLICY_CODE_END + EdmConstants::PolicyCode::DISABLE_DEVELOPER_MODE,
62     EdmInterfaceCode::POLICY_CODE_END + EdmConstants::PolicyCode::DISABLE_RESET_FACTORY
63 };
64 
GetInstance()65 std::shared_ptr<PermissionChecker> PermissionChecker::GetInstance()
66 {
67     std::call_once(flag_, []() {
68         if (instance_ == nullptr) {
69             instance_.reset(new (std::nothrow) PermissionChecker());
70         }
71     });
72     return instance_;
73 }
74 
GetExternalManagerFactory()75 std::shared_ptr<IExternalManagerFactory> PermissionChecker::GetExternalManagerFactory()
76 {
77     return externalManagerFactory_;
78 }
79 
CheckCallerPermission(std::shared_ptr<Admin> admin,const std::string & permission,bool isNeedSuperAdmin)80 ErrCode PermissionChecker::CheckCallerPermission(std::shared_ptr<Admin> admin, const std::string &permission,
81     bool isNeedSuperAdmin)
82 {
83     if (admin == nullptr) {
84         return EdmReturnErrCode::ADMIN_INACTIVE;
85     }
86     Security::AccessToken::AccessTokenID tokenId = IPCSkeleton::GetCallingTokenID();
87     if (!GetExternalManagerFactory()->CreateAccessTokenManager()->VerifyCallingPermission(tokenId, permission)) {
88         EDMLOGE("CheckCallerPermission verify calling permission failed.");
89         return EdmReturnErrCode::PERMISSION_DENIED;
90     }
91     if (FAILED(CheckCallingUid(admin->adminInfo_.packageName_))) {
92         EDMLOGE("CheckCallerPermission check calling uid failed.");
93         return EdmReturnErrCode::PERMISSION_DENIED;
94     }
95     if (isNeedSuperAdmin && admin->GetAdminType() != AdminType::ENT) {
96         EDMLOGE("CheckCallerPermission caller not a super admin.");
97         return EdmReturnErrCode::ADMIN_EDM_PERMISSION_DENIED;
98     }
99     if (!isNeedSuperAdmin && admin->GetAdminType() == AdminType::VIRTUAL_ADMIN) {
100         EDMLOGE("CheckCallerPermission delegated admin does not have permission to handle.");
101         return EdmReturnErrCode::ADMIN_EDM_PERMISSION_DENIED;
102     }
103     if (!isNeedSuperAdmin && admin->GetAdminType() == AdminType::BYOD) {
104         EDMLOGE("CheckCallerPermission byod admin does not have permission to handle.");
105         return EdmReturnErrCode::ADMIN_EDM_PERMISSION_DENIED;
106     }
107     return ERR_OK;
108 }
109 
CheckCallingUid(const std::string & bundleName)110 ErrCode PermissionChecker::CheckCallingUid(const std::string &bundleName)
111 {
112     // super admin can be removed by itself
113     int uid = IPCSkeleton::GetCallingUid();
114     std::string callingBundleName;
115     if (GetExternalManagerFactory()->CreateBundleManager()->GetNameForUid(uid, callingBundleName) != ERR_OK) {
116         EDMLOGW("CheckCallingUid failed: get bundleName for uid %{public}d fail.", uid);
117         return ERR_EDM_PERMISSION_ERROR;
118     }
119     if (bundleName == callingBundleName) {
120         return ERR_OK;
121     }
122     EDMLOGW("CheckCallingUid failed: only the app %{public}s can remove itself.", callingBundleName.c_str());
123     return ERR_EDM_PERMISSION_ERROR;
124 }
125 
CheckSystemCalling(IPlugin::ApiType apiType,const std::string & permissionTag)126 ErrCode PermissionChecker::CheckSystemCalling(IPlugin::ApiType apiType, const std::string &permissionTag)
127 {
128     bool isCheckSystem = (apiType == IPlugin::ApiType::SYSTEM)
129         || (permissionTag == EdmConstants::PERMISSION_TAG_SYSTEM_API);
130     if (isCheckSystem && !CheckIsSystemAppOrNative()) {
131         EDMLOGE("CheckSystemCalling: not system app or native process");
132         return EdmReturnErrCode::SYSTEM_API_DENIED;
133     }
134     return ERR_OK;
135 }
136 
GetAllPermissionsByAdmin(const std::string & bundleInfoName,AdminType adminType,int32_t userId,std::vector<std::string> & permissionList)137 ErrCode PermissionChecker::GetAllPermissionsByAdmin(const std::string &bundleInfoName, AdminType adminType,
138     int32_t userId, std::vector<std::string> &permissionList)
139 {
140     permissionList.clear();
141     AppExecFwk::BundleInfo bundleInfo;
142     EDMLOGD("GetAllPermissionsByAdmin GetBundleInfo: bundleInfoName %{public}s userid %{public}d",
143         bundleInfoName.c_str(), userId);
144     bool ret = GetExternalManagerFactory()->CreateBundleManager()->GetBundleInfo(bundleInfoName,
145         AppExecFwk::BundleFlag::GET_BUNDLE_WITH_REQUESTED_PERMISSION, bundleInfo, userId);
146     if (!ret) {
147         EDMLOGW("GetAllPermissionsByAdmin: GetBundleInfo failed %{public}d", ret);
148         return ERR_EDM_PARAM_ERROR;
149     }
150     PermissionManager::GetInstance()->GetAdminGrantedPermission(bundleInfo.reqPermissions, adminType, permissionList);
151     return ERR_OK;
152 }
153 
CheckHandlePolicyPermission(FuncOperateType operateType,const std::string & bundleName,const std::string & policyName,const std::string & permissionName,int32_t userId)154 ErrCode PermissionChecker::CheckHandlePolicyPermission(FuncOperateType operateType,
155     const std::string &bundleName, const std::string &policyName, const std::string &permissionName, int32_t userId)
156 {
157     if (operateType == FuncOperateType::SET && permissionName.empty()) {
158         EDMLOGE("CheckHandlePolicyPermission failed, set policy need permission.");
159         return EdmReturnErrCode::PERMISSION_DENIED;
160     }
161     if (permissionName == NONE_PERMISSION_MATCH) {
162         EDMLOGE("CheckHandlePolicyPermission: GetPermission failed!");
163         return EdmReturnErrCode::SYSTEM_ABNORMALLY;
164     }
165     std::shared_ptr<Admin> deviceAdmin = AdminManager::GetInstance()->GetAdminByPkgName(bundleName, GetCurrentUserId());
166     if (deviceAdmin == nullptr) {
167         EDMLOGE("CheckHandlePolicyPermission: get admin failed");
168         return EdmReturnErrCode::ADMIN_INACTIVE;
169     }
170     if (FAILED(CheckCallingUid(deviceAdmin->adminInfo_.packageName_))) {
171         EDMLOGE("CheckHandlePolicyPermission: CheckCallingUid failed.");
172         return EdmReturnErrCode::PERMISSION_DENIED;
173     }
174     if (operateType == FuncOperateType::SET && deviceAdmin->GetAdminType() == AdminType::NORMAL &&
175         userId != GetCurrentUserId()) {
176         EDMLOGE("CheckHandlePolicyPermission: this admin does not have permission to handle policy of other account.");
177         return EdmReturnErrCode::ADMIN_EDM_PERMISSION_DENIED;
178     }
179     if (!permissionName.empty()) {
180         EDMLOGI("CheckHandlePolicyPermission: permissionName:%{public}s", permissionName.c_str());
181         auto ret = CheckAndUpdatePermission(deviceAdmin, IPCSkeleton::GetCallingTokenID(), permissionName, userId);
182         if (FAILED(ret)) {
183             return ret;
184         }
185     }
186     if (permissionName.empty() && deviceAdmin->GetAdminType() == AdminType::BYOD) {
187         return EdmReturnErrCode::PERMISSION_DENIED;
188     }
189     if (!AdminManager::GetInstance()->HasPermissionToHandlePolicy(deviceAdmin, policyName)) {
190         EDMLOGE("CheckHandlePolicyPermission: this admin does not have permission to handle the policy.");
191         return EdmReturnErrCode::ADMIN_EDM_PERMISSION_DENIED;
192     }
193     return ERR_OK;
194 }
195 
CheckAndUpdatePermission(std::shared_ptr<Admin> admin,Security::AccessToken::AccessTokenID tokenId,const std::string & permission,int32_t userId)196 ErrCode PermissionChecker::CheckAndUpdatePermission(std::shared_ptr<Admin> admin,
197     Security::AccessToken::AccessTokenID tokenId, const std::string &permission, int32_t userId)
198 {
199     if (admin == nullptr) {
200         EDMLOGE("CheckHandlePolicyPermission: this admin does not have permission to handle the policy.");
201         return EdmReturnErrCode::SYSTEM_ABNORMALLY;
202     }
203     bool callingPermission = VerifyCallingPermission(tokenId, permission);
204     bool adminPermission = admin->CheckPermission(permission);
205     EDMLOGI("CheckAndUpdatePermission::callingPermission: %{public}d.adminPermission:%{public}d", callingPermission,
206         adminPermission);
207     if (callingPermission != adminPermission) {
208         std::vector<std::string> permissionList;
209         if (FAILED(GetAllPermissionsByAdmin(admin->adminInfo_.packageName_,
210             admin->GetAdminType(), userId, permissionList))) {
211             EDMLOGE("CheckAndUpdatePermission get all permission that admin request failed.");
212             return EdmReturnErrCode::SYSTEM_ABNORMALLY;
213         }
214         auto hasPermission = std::find(permissionList.begin(), permissionList.end(), permission);
215         if (!callingPermission && hasPermission != permissionList.end()) {
216             EDMLOGE("CheckAndUpdatePermission access token check abnormally.");
217             return EdmReturnErrCode::SYSTEM_ABNORMALLY;
218         }
219         if (!adminPermission && hasPermission == permissionList.end()) {
220             EDMLOGE("CheckAndUpdatePermission this admin does not have the permission.");
221             return EdmReturnErrCode::ADMIN_EDM_PERMISSION_DENIED;
222         }
223         Admin updateAdmin(admin->adminInfo_.packageName_, admin->GetAdminType(), permissionList);
224         updateAdmin.SetAccessiblePolicies(admin->adminInfo_.accessiblePolicies_);
225         if (FAILED(AdminManager::GetInstance()->UpdateAdmin(admin, userId, updateAdmin))) {
226             return EdmReturnErrCode::SYSTEM_ABNORMALLY;
227         }
228     }
229     if (!callingPermission) {
230         return EdmReturnErrCode::PERMISSION_DENIED;
231     }
232     return ERR_OK;
233 }
234 
GetCurrentUserId()235 int32_t PermissionChecker::GetCurrentUserId()
236 {
237     std::vector<int32_t> ids;
238     auto fac = GetExternalManagerFactory();
239     ErrCode ret = fac->CreateOsAccountManager()->QueryActiveOsAccountIds(ids);
240     if (FAILED(ret) || ids.empty()) {
241         EDMLOGE("PermissionChecker GetCurrentUserId failed");
242         return -1;
243     }
244     EDMLOGD("PermissionChecker GetCurrentUserId user id = %{public}d", ids.at(0));
245     return (ids.at(0));
246 }
247 
AdminTypeToPermissionType(AdminType adminType)248 IPlugin::PermissionType PermissionChecker::AdminTypeToPermissionType(AdminType adminType)
249 {
250     if (adminType == AdminType::BYOD) {
251         return IPlugin::PermissionType::BYOD_DEVICE_ADMIN;
252     }
253     return IPlugin::PermissionType::SUPER_DEVICE_ADMIN;
254 }
255 
CheckElementNullPermission(uint32_t funcCode,const std::string & permissionName)256 bool PermissionChecker::CheckElementNullPermission(uint32_t funcCode, const std::string &permissionName)
257 {
258     std::uint32_t code = FuncCodeUtils::GetPolicyCode(funcCode);
259     auto item = std::find(supportAdminNullPolicyCode_.begin(), supportAdminNullPolicyCode_.end(), code);
260     if (item == supportAdminNullPolicyCode_.end()) {
261         EDMLOGE("PermissionChecker not support element null query code is %{public}d", code);
262         return false;
263     }
264     if (permissionName.empty()) {
265         return true;
266     }
267     if (CheckSpecialPolicyCallQuery(code)) {
268         return true;
269     }
270     Security::AccessToken::AccessTokenID tokenId = IPCSkeleton::GetCallingTokenID();
271     if (!VerifyCallingPermission(tokenId, permissionName)) {
272         EDMLOGE("PermissionChecker element null query no permission code is %{public}d", code);
273         return false;
274     }
275     return true;
276 }
277 
CheckSpecialPolicyCallQuery(uint32_t code)278 bool PermissionChecker::CheckSpecialPolicyCallQuery(uint32_t code)
279 {
280     bool isSystemAppCall = GetExternalManagerFactory()->CreateAccessTokenManager()->IsSystemAppCall();
281     if (isSystemAppCall) {
282         return true;
283     }
284     bool isNativeCall = GetExternalManagerFactory()->CreateAccessTokenManager()->IsNativeCall();
285     if (isNativeCall) {
286         int uid = IPCSkeleton::GetCallingUid();
287         if (code == EdmInterfaceCode::ALLOWED_BLUETOOTH_DEVICES) {
288             return uid == EdmConstants::BLUETOOTH_SERVICE_UID;
289         } else if (code == EdmInterfaceCode::PASSWORD_POLICY) {
290             return uid == EdmConstants::USERIAM_SERVICE_UID;
291         }
292     }
293     return false;
294 }
295 
CheckIsDebug()296 bool PermissionChecker::CheckIsDebug()
297 {
298     return GetExternalManagerFactory()->CreateAccessTokenManager()->IsDebug();
299 }
300 
CheckIsSystemAppOrNative()301 bool PermissionChecker::CheckIsSystemAppOrNative()
302 {
303     return GetExternalManagerFactory()->CreateAccessTokenManager()->IsSystemAppOrNative();
304 }
305 
VerifyCallingPermission(Security::AccessToken::AccessTokenID tokenId,const std::string & permissionName)306 bool PermissionChecker::VerifyCallingPermission(Security::AccessToken::AccessTokenID tokenId,
307     const std::string &permissionName)
308 {
309     return GetExternalManagerFactory()->CreateAccessTokenManager()->VerifyCallingPermission(tokenId, permissionName);
310 }
311 } // namespace EDM
312 } // namespace OHOS
313