1 /*
2 * Copyright (c) 2022 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 "admin_manager.h"
17 #include <algorithm>
18 #include <ctime>
19 #include <fstream>
20 #include <iostream>
21 #include "edm_log.h"
22 #include "permission_manager.h"
23 #include "super_admin.h"
24
25 namespace OHOS {
26 namespace EDM {
27 const std::string EDM_ADMIN_JSON_FILE = "/data/system/admin_policies.json";
28 std::shared_ptr<AdminManager> AdminManager::instance_;
29 std::mutex AdminManager::mutexLock_;
30
GetInstance()31 std::shared_ptr<AdminManager> AdminManager::GetInstance()
32 {
33 if (instance_ == nullptr) {
34 std::lock_guard<std::mutex> autoLock(mutexLock_);
35 if (instance_ == nullptr) {
36 instance_.reset(new AdminManager());
37 }
38 }
39 return instance_;
40 }
41
AdminManager()42 AdminManager::AdminManager()
43 {
44 EDMLOGI("AdminManager::AdminManager");
45 }
46
~AdminManager()47 AdminManager::~AdminManager()
48 {
49 EDMLOGI("AdminManager::~AdminManager");
50 admins_.clear();
51 }
52
GetReqPermission(const std::vector<std::string> & permissions,std::vector<EdmPermission> & reqPermissions)53 ErrCode AdminManager::GetReqPermission(const std::vector<std::string> &permissions,
54 std::vector<EdmPermission> &reqPermissions)
55 {
56 EDMLOGD("AdminManager::GetReqPermission");
57 PermissionManager::GetInstance()->GetReqPermission(permissions, reqPermissions);
58 return reqPermissions.empty() ? ERR_EDM_EMPTY_PERMISSIONS : ERR_OK;
59 }
60
SetAdminValue(AppExecFwk::AbilityInfo & abilityInfo,EntInfo & entInfo,AdminType role,std::vector<std::string> & permissions)61 ErrCode AdminManager::SetAdminValue(AppExecFwk::AbilityInfo &abilityInfo, EntInfo &entInfo, AdminType role,
62 std::vector<std::string> &permissions)
63 {
64 std::vector<AdminPermission> reqPermission;
65 std::vector<std::string> permissionNames;
66 PermissionManager::GetInstance()->GetReqPermission(permissions, reqPermission);
67 if (reqPermission.empty()) {
68 EDMLOGW("SetAdminValue::the application is requesting useless permissions");
69 }
70 for (const auto &it : reqPermission) {
71 if (role == AdminType::NORMAL && it.adminType == AdminType::ENT) {
72 return ERR_EDM_DENY_PERMISSION;
73 }
74 permissionNames.push_back(it.permissionName);
75 }
76
77 std::shared_ptr<Admin> adminItem = GetAdminByPkgName(abilityInfo.bundleName);
78 if (adminItem == nullptr) {
79 if (role == NORMAL) {
80 admins_.emplace_back(std::make_shared<Admin>());
81 } else {
82 admins_.emplace_back(std::make_shared<SuperAdmin>());
83 }
84 adminItem = admins_.back();
85 }
86 adminItem->adminInfo_.adminType_ = role;
87 adminItem->adminInfo_.entInfo_ = entInfo;
88 adminItem->adminInfo_.permission_ = permissionNames;
89 adminItem->adminInfo_.packageName_ = abilityInfo.bundleName;
90 adminItem->adminInfo_.className_ = abilityInfo.name;
91 SaveAdmin();
92 return ERR_OK;
93 }
94
GetAllAdmin(std::vector<std::shared_ptr<Admin>> & allAdmin)95 void AdminManager::GetAllAdmin(std::vector<std::shared_ptr<Admin>> &allAdmin)
96 {
97 allAdmin = admins_;
98 }
99
GetAdminByPkgName(const std::string & packageName)100 std::shared_ptr<Admin> AdminManager::GetAdminByPkgName(const std::string &packageName)
101 {
102 for (auto &item : admins_) {
103 if (item->adminInfo_.packageName_ == packageName) {
104 return item;
105 }
106 }
107 EDMLOGD("GetAdminByPkgName:get admin failed. admin size= %{public}u, packageName= %{public}s",
108 (uint32_t)admins_.size(), packageName.c_str());
109 return nullptr;
110 }
111
DeleteAdmin(const std::string & packageName)112 ErrCode AdminManager::DeleteAdmin(const std::string &packageName)
113 {
114 ErrCode retCode;
115 auto iter = admins_.begin();
116 while (iter != admins_.end()) {
117 if ((*iter)->adminInfo_.packageName_ == packageName) {
118 iter = admins_.erase(iter);
119 retCode = ERR_OK;
120 } else {
121 iter++;
122 }
123 }
124 if (SUCCEEDED(retCode)) {
125 EDMLOGD("SaveAdmin %{public}s", packageName.c_str());
126 SaveAdmin();
127 return retCode;
128 }
129
130 EDMLOGW("delete admin (%{public}s) failed!", packageName.c_str());
131 return ERR_EDM_UNKNOWN_ADMIN;
132 }
133
GetGrantedPermission(AppExecFwk::AbilityInfo & abilityInfo,std::vector<std::string> & permissions,AdminType type)134 ErrCode AdminManager::GetGrantedPermission(AppExecFwk::AbilityInfo &abilityInfo, std::vector<std::string> &permissions,
135 AdminType type)
136 {
137 if (permissions.empty()) {
138 EDMLOGW("GetGrantedPermission: permissions is empty");
139 return ERR_OK;
140 }
141 // filtering out non-edm permissions
142 std::vector<AdminPermission> reqPermission;
143 PermissionManager::GetInstance()->GetReqPermission(permissions, reqPermission);
144 if (reqPermission.empty()) {
145 EDMLOGW("GetGrantedPermission: edm permission is empty");
146 return ERR_OK;
147 }
148
149 // filter out super permissions if admin is NORMAL
150 std::vector<std::string> permissionNameList;
151 for (const auto &it : reqPermission) {
152 if ((type == AdminType::NORMAL) && (it.adminType == AdminType::ENT)) {
153 continue;
154 }
155 permissionNameList.push_back(it.permissionName);
156 }
157 permissions.assign(permissionNameList.begin(), permissionNameList.end());
158 return ERR_OK;
159 }
160
UpdateAdmin(AppExecFwk::AbilityInfo & abilityInfo,const std::vector<std::string> & permissions)161 ErrCode AdminManager::UpdateAdmin(AppExecFwk::AbilityInfo &abilityInfo, const std::vector<std::string> &permissions)
162 {
163 auto adminItem = GetAdminByPkgName(abilityInfo.bundleName);
164 if (adminItem == nullptr) {
165 EDMLOGW("UpdateAdmin: get null admin, never get here");
166 return ERR_EDM_UNKNOWN_ADMIN;
167 }
168
169 std::vector<std::string> combinePermission = permissions;
170 ErrCode ret = GetGrantedPermission(abilityInfo, combinePermission, adminItem->adminInfo_.adminType_);
171 if (ret != ERR_OK) {
172 EDMLOGW("UpdateAdmin: GetGrantedPermission failed");
173 return ret;
174 }
175
176 adminItem->adminInfo_.permission_ = combinePermission;
177 adminItem->adminInfo_.packageName_ = abilityInfo.bundleName;
178 adminItem->adminInfo_.className_ = abilityInfo.className;
179 SaveAdmin();
180 return ERR_OK;
181 }
182
183 // success is returned as long as there is a super administrator
IsSuperAdminExist()184 bool AdminManager::IsSuperAdminExist()
185 {
186 return std::any_of(admins_.begin(), admins_.end(),
187 [](const std::shared_ptr<Admin> &admin) { return admin->adminInfo_.adminType_ == AdminType::ENT; });
188 }
189
190 /*
191 * There are different administrator types according to the input parameters.
192 * Returns a list of package names
193 */
GetActiveAdmin(AdminType role,std::vector<std::string> & packageNameList)194 void AdminManager::GetActiveAdmin(AdminType role, std::vector<std::string> &packageNameList)
195 {
196 EDMLOGD("AdminManager:GetActiveAdmin adminType: %{public}d , admin size: %{public}zu", role, admins_.size());
197 packageNameList.clear();
198 if (role >= AdminType::UNKNOWN || role < AdminType::NORMAL) {
199 EDMLOGD("there is no admin(%{public}u) device manager package name list!", role);
200 return;
201 }
202
203 for (auto &item : admins_) {
204 if (item->adminInfo_.adminType_ == role) {
205 std::string adminName = item->adminInfo_.packageName_ + "/" + item->adminInfo_.className_;
206 packageNameList.push_back(adminName);
207 }
208 }
209 }
210
GetEntInfo(const std::string & packageName,EntInfo & entInfo)211 ErrCode AdminManager::GetEntInfo(const std::string &packageName, EntInfo &entInfo)
212 {
213 for (auto &item : admins_) {
214 if (item->adminInfo_.packageName_ == packageName) {
215 entInfo = item->adminInfo_.entInfo_;
216 return ERR_OK;
217 }
218 }
219 return ERR_EDM_UNKNOWN_ADMIN;
220 }
221
SetEntInfo(const std::string & packageName,EntInfo & entInfo)222 ErrCode AdminManager::SetEntInfo(const std::string &packageName, EntInfo &entInfo)
223 {
224 for (auto &item : admins_) {
225 if (item->adminInfo_.packageName_ == packageName) {
226 item->adminInfo_.entInfo_ = entInfo;
227 SaveAdmin();
228 return ERR_OK;
229 }
230 }
231 return ERR_EDM_UNKNOWN_ADMIN;
232 }
233
234 // init
Init()235 void AdminManager::Init()
236 {
237 RestoreAdminFromFile();
238 }
239
FindPackageAndClass(const std::string & name,std::string & packageName,std::string & className)240 void FindPackageAndClass(const std::string &name, std::string &packageName, std::string &className)
241 {
242 std::size_t initPos = name.find('/', 0);
243 std::size_t len = name.size();
244 packageName = name.substr(0, initPos);
245 className = name.substr(initPos + 1, len - (initPos + 1));
246 }
247
ReadJsonAdminType(Json::Value & admin)248 void AdminManager::ReadJsonAdminType(Json::Value &admin)
249 {
250 std::shared_ptr<Admin> activeAdmin;
251 if (admin["adminType"].asUInt() == AdminType::NORMAL) {
252 activeAdmin = std::make_shared<Admin>();
253 } else if (admin["adminType"].asUInt() == AdminType::ENT) {
254 activeAdmin = std::make_shared<SuperAdmin>();
255 } else {
256 EDMLOGD("admin type is error!");
257 return;
258 }
259
260 FindPackageAndClass(admin["name"].asString(), activeAdmin->adminInfo_.packageName_,
261 activeAdmin->adminInfo_.className_);
262 activeAdmin->adminInfo_.adminType_ = static_cast<AdminType>(admin["adminType"].asUInt());
263 activeAdmin->adminInfo_.entInfo_.enterpriseName = admin["enterpriseInfo"]["enterpriseName"].asString(); // object
264 activeAdmin->adminInfo_.entInfo_.description = admin["enterpriseInfo"]["declaration"].asString();
265 unsigned int adminSize = admin["permission"].size();
266 for (unsigned int i = 0; i < adminSize; i++) {
267 activeAdmin->adminInfo_.permission_.push_back(admin["permission"][i].asString()); // array
268 }
269
270 // read admin and store it in vector container
271 admins_.push_back(activeAdmin);
272 }
273
ReadJsonAdmin(const std::string & filePath)274 void AdminManager::ReadJsonAdmin(const std::string &filePath)
275 {
276 std::ifstream is(filePath);
277 JSONCPP_STRING errs;
278 Json::Value root, lang;
279 Json::CharReaderBuilder readerBuilder;
280
281 if (!is.is_open()) {
282 EDMLOGE("ReadJsonAdmin open admin policies file failed!");
283 return;
284 }
285 bool res = parseFromStream(readerBuilder, is, &root, &errs);
286 if (!res || !errs.empty()) {
287 // no data, return
288 EDMLOGW("AdminManager:read admin policies file is :%{public}d , is not empty: %{public}d", res, errs.empty());
289 is.close();
290 return;
291 }
292 is.close();
293
294 lang = root["admin"];
295 EDMLOGD("AdminManager: size of %{public}u", lang.size());
296
297 for (auto temp : lang) {
298 ReadJsonAdminType(temp);
299 }
300 }
301
302 // read admin from file
RestoreAdminFromFile()303 void AdminManager::RestoreAdminFromFile()
304 {
305 // admin information storage location
306 ReadJsonAdmin(EDM_ADMIN_JSON_FILE);
307 }
308
WriteJsonAdminType(std::shared_ptr<Admin> & activeAdmin,Json::Value & tree)309 void AdminManager::WriteJsonAdminType(std::shared_ptr<Admin> &activeAdmin, Json::Value &tree)
310 {
311 Json::Value entTree;
312 Json::Value permissionTree;
313
314 tree["name"] = activeAdmin->adminInfo_.packageName_ + "/" + activeAdmin->adminInfo_.className_;
315 tree["adminType"] = activeAdmin->adminInfo_.adminType_;
316
317 entTree["enterpriseName"] = activeAdmin->adminInfo_.entInfo_.enterpriseName;
318 entTree["declaration"] = activeAdmin->adminInfo_.entInfo_.description;
319 tree["enterpriseInfo"] = entTree;
320
321 for (auto &it : activeAdmin->adminInfo_.permission_) {
322 permissionTree.append(it);
323 }
324 tree["permission"] = permissionTree;
325 }
326
WriteJsonAdmin(const std::string & filePath)327 void AdminManager::WriteJsonAdmin(const std::string &filePath)
328 {
329 Json::Value root, tree, temp;
330
331 EDMLOGD("WriteJsonAdmin start! size = %{public}u empty = %{public}d", (uint32_t)admins_.size(), admins_.empty());
332 // structure of each admin
333 for (std::uint32_t i = 0; i < admins_.size(); i++) {
334 WriteJsonAdminType(admins_.at(i), temp);
335 tree.append(temp);
336 }
337 // root
338 root["admin"] = tree;
339
340 double time1 = clock();
341 // write to file
342 std::ofstream ofs(filePath);
343 if (!ofs.is_open()) {
344 EDMLOGE("WriteJsonAdmin open admin policies file failed!");
345 return;
346 }
347
348 Json::StreamWriterBuilder builder;
349 builder["indentation"] = " ";
350 const std::unique_ptr<Json::StreamWriter> writer(builder.newStreamWriter());
351 writer->write(root, &ofs);
352 ofs.flush();
353 ofs.close();
354 double time2 = clock();
355 if (time1 != 0 && time2 != 0) {
356 EDMLOGD("WriteJsonAdmin spend time %{public}f", (time2 - time1) / CLOCKS_PER_SEC);
357 }
358 }
359
360 // write admin to file
SaveAdmin()361 void AdminManager::SaveAdmin()
362 {
363 WriteJsonAdmin(EDM_ADMIN_JSON_FILE);
364 }
365 } // namespace EDM
366 } // namespace OHOS
367