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
18#include <algorithm>
19#include <ctime>
20#include <fstream>
21#include <iostream>
22
23#include "directory_ex.h"
24#include "edm_constants.h"
25#include "edm_log.h"
26#include "permission_manager.h"
27#include "super_admin.h"
28
29namespace OHOS {
30namespace EDM {
31std::shared_ptr<AdminManager> AdminManager::instance_;
32std::mutex AdminManager::mutexLock_;
33
34std::shared_ptr<AdminManager> AdminManager::GetInstance()
35{
36    if (instance_ == nullptr) {
37        std::lock_guard<std::mutex> autoLock(mutexLock_);
38        if (instance_ == nullptr) {
39            instance_.reset(new (std::nothrow) AdminManager());
40        }
41    }
42    return instance_;
43}
44
45AdminManager::AdminManager()
46{
47    EDMLOGI("AdminManager::AdminManager");
48}
49
50AdminManager::~AdminManager()
51{
52    EDMLOGI("AdminManager::~AdminManager");
53    admins_.clear();
54}
55
56ErrCode AdminManager::GetReqPermission(const std::vector<std::string> &permissions,
57    std::vector<EdmPermission> &reqPermissions)
58{
59    EDMLOGD("AdminManager::GetReqPermission");
60    PermissionManager::GetInstance()->GetReqPermission(permissions, reqPermissions);
61    return reqPermissions.empty() ? ERR_EDM_EMPTY_PERMISSIONS : ERR_OK;
62}
63
64bool AdminManager::GetAdminByUserId(int32_t userId, std::vector<std::shared_ptr<Admin>> &userAdmin)
65{
66    userAdmin.clear();
67    auto iter = admins_.find(userId);
68    if (iter == admins_.end()) {
69        EDMLOGW("GetAdminByUserId::get userId Admin failed. userId = %{public}d", userId);
70        return false;
71    }
72    userAdmin = iter->second;
73    return true;
74}
75
76void AdminManager::GetAdminBySubscribeEvent(ManagedEvent event,
77    std::unordered_map<int32_t, std::vector<std::shared_ptr<Admin>>> &subscribeAdmins)
78{
79    for (const auto &adminItem : admins_) {
80        std::vector<std::shared_ptr<Admin>> subAdmin;
81        for (const auto &it : adminItem.second) {
82            std::vector<ManagedEvent> events = it->adminInfo_.managedEvents_;
83            if (std::find(events.begin(), events.end(), event) != events.end()) {
84                subAdmin.push_back(it);
85            }
86        }
87        if (!subAdmin.empty()) {
88            subscribeAdmins[adminItem.first] = subAdmin;
89        }
90    }
91}
92
93ErrCode AdminManager::SetAdminValue(int32_t userId, Admin &adminItem)
94{
95    auto adminPoliciesStorageRdb = AdminPoliciesStorageRdb::GetInstance();
96    if (adminPoliciesStorageRdb == nullptr) {
97        EDMLOGE("AdminManager::SetAdminValue get adminPoliciesStorageRdb failed.");
98        return ERR_GET_STORAGE_RDB_FAILED;
99    }
100    std::vector<AdminPermission> reqPermission;
101    std::vector<std::string> permissionNames;
102    PermissionManager::GetInstance()->GetReqPermission(adminItem.adminInfo_.permission_, reqPermission);
103    if (reqPermission.empty()) {
104        EDMLOGW("SetAdminValue::the application is requesting useless permissions");
105    }
106    for (const auto &it : reqPermission) {
107        if (adminItem.adminInfo_.adminType_ == AdminType::NORMAL && it.adminType == AdminType::ENT) {
108            return ERR_EDM_DENY_PERMISSION;
109        }
110        permissionNames.push_back(it.permissionName);
111    }
112    std::shared_ptr<Admin> getAdmin = GetAdminByPkgName(adminItem.adminInfo_.packageName_, userId);
113    if (getAdmin != nullptr) {
114        if (!adminPoliciesStorageRdb->UpdateAdmin(userId, adminItem)) {
115            EDMLOGE("AdminManager::SetAdminValue update failed.");
116            return ERR_EDM_ADD_ADMIN_FAILED;
117        }
118        getAdmin->adminInfo_.adminType_ = adminItem.adminInfo_.adminType_;
119        getAdmin->adminInfo_.entInfo_ = adminItem.adminInfo_.entInfo_;
120        getAdmin->adminInfo_.permission_ = permissionNames;
121        return ERR_OK;
122    }
123    if (!adminPoliciesStorageRdb->InsertAdmin(userId, adminItem)) {
124        EDMLOGE("AdminManager::SetAdminValue insert failed.");
125        return ERR_EDM_ADD_ADMIN_FAILED;
126    }
127    std::vector<std::shared_ptr<Admin>> admins;
128    GetAdminByUserId(userId, admins);
129    adminItem.adminInfo_.permission_ = permissionNames;
130    std::shared_ptr<Admin> admin = std::make_shared<Admin>(adminItem);
131    admins.emplace_back(admin);
132    admins_[userId] = admins;
133    return ERR_OK;
134}
135
136std::shared_ptr<Admin> AdminManager::GetAdminByPkgName(const std::string &packageName, int32_t userId)
137{
138    std::shared_ptr<Admin> subOrSuperAdmin;
139    if (SUCCEEDED(GetSubOrSuperAdminByPkgName(packageName, subOrSuperAdmin))) {
140        EDMLOGD("GetAdminByPkgName::get sub-super or super admin: %{public}s", packageName.c_str());
141        return subOrSuperAdmin;
142    }
143    std::vector<std::shared_ptr<Admin>> userAdmin;
144    if (!GetAdminByUserId(userId, userAdmin)) {
145        EDMLOGW("GetAdminByPkgName::get userId Admin failed. userId = %{public}d", userId);
146        return nullptr;
147    }
148    for (const auto &item : userAdmin) {
149        if (item->adminInfo_.packageName_ == packageName) {
150            return item;
151        }
152    }
153    EDMLOGD("GetAdminByPkgName::get admin failed. admin size = %{public}u, packageName = %{public}s",
154        (uint32_t)userAdmin.size(), packageName.c_str());
155    return nullptr;
156}
157
158ErrCode AdminManager::DeleteAdmin(const std::string &packageName, int32_t userId)
159{
160    auto iterMap = admins_.find(userId);
161    if (iterMap == admins_.end()) {
162        EDMLOGW("DeleteAdmin::get userId Admin failed. userId = %{public}d", userId);
163        return ERR_EDM_UNKNOWN_ADMIN;
164    }
165    auto adminPoliciesStorageRdb = AdminPoliciesStorageRdb::GetInstance();
166    if (adminPoliciesStorageRdb == nullptr) {
167        EDMLOGE("AdminManager::DeleteAdmin get adminPoliciesStorageRdb failed.");
168        return ERR_GET_STORAGE_RDB_FAILED;
169    }
170    if (!adminPoliciesStorageRdb->DeleteAdmin(userId, packageName)) {
171        EDMLOGW("delete admin (%{public}s) failed!", packageName.c_str());
172        return ERR_EDM_DEL_ADMIN_FAILED;
173    }
174    auto iter = std::remove_if(iterMap->second.begin(), iterMap->second.end(),
175        [&](std::shared_ptr<Admin> admin) { return admin->adminInfo_.packageName_ == packageName; });
176    iterMap->second.erase(iter, iterMap->second.end());
177    if (iterMap->second.empty()) {
178        admins_.erase(iterMap);
179    }
180    return ERR_OK;
181}
182
183ErrCode AdminManager::GetGrantedPermission(std::vector<std::string> &permissions, AdminType type)
184{
185    if (permissions.empty()) {
186        EDMLOGW("GetGrantedPermission::permissions is empty");
187        return ERR_OK;
188    }
189    // filtering out non-edm permissions
190    std::vector<AdminPermission> reqPermission;
191    PermissionManager::GetInstance()->GetReqPermission(permissions, reqPermission);
192    if (reqPermission.empty()) {
193        EDMLOGW("GetGrantedPermission::edm permission is empty");
194        return ERR_OK;
195    }
196
197    // filter out super permissions if admin is NORMAL
198    std::vector<std::string> permissionNameList;
199    for (const auto &it : reqPermission) {
200        if ((type == AdminType::NORMAL) && (it.adminType == AdminType::ENT)) {
201            continue;
202        }
203        permissionNameList.push_back(it.permissionName);
204    }
205    permissions.assign(permissionNameList.begin(), permissionNameList.end());
206    return ERR_OK;
207}
208
209ErrCode AdminManager::UpdateAdmin(AppExecFwk::ExtensionAbilityInfo &abilityInfo,
210    const std::vector<std::string> &permissions, int32_t userId)
211{
212    auto adminItem = GetAdminByPkgName(abilityInfo.bundleName, userId);
213    if (adminItem == nullptr) {
214        EDMLOGW("UpdateAdmin::get null admin, never get here");
215        return ERR_EDM_UNKNOWN_ADMIN;
216    }
217    auto adminPoliciesStorageRdb = AdminPoliciesStorageRdb::GetInstance();
218    if (adminPoliciesStorageRdb == nullptr) {
219        EDMLOGE("AdminManager::UpdateAdmin get adminPoliciesStorageRdb failed.");
220        return ERR_GET_STORAGE_RDB_FAILED;
221    }
222
223    std::vector<std::string> combinePermission = permissions;
224    ErrCode ret = GetGrantedPermission(combinePermission, adminItem->adminInfo_.adminType_);
225    if (ret != ERR_OK) {
226        EDMLOGW("UpdateAdmin::GetGrantedPermission failed");
227        return ret;
228    }
229
230    if (!adminPoliciesStorageRdb->UpdateAdmin(userId, abilityInfo.bundleName, abilityInfo.name, combinePermission)) {
231        EDMLOGW("UpdateAdmin::update admin failed.");
232        return ERR_EDM_UNKNOWN_ADMIN;
233    }
234    adminItem->adminInfo_.permission_ = combinePermission;
235    adminItem->adminInfo_.packageName_ = abilityInfo.bundleName;
236    adminItem->adminInfo_.className_ = abilityInfo.name;
237    return ERR_OK;
238}
239
240// success is returned as long as there is a super administrator
241bool AdminManager::IsSuperAdminExist()
242{
243    std::vector<std::shared_ptr<Admin>> userAdmin;
244    bool ret = GetAdminByUserId(DEFAULT_USER_ID, userAdmin);
245    if (!ret) {
246        EDMLOGD("IsSuperAdminExist::not find super Admin");
247        return false;
248    }
249    return std::any_of(userAdmin.begin(), userAdmin.end(),
250        [](const std::shared_ptr<Admin> &admin) { return admin->adminInfo_.adminType_ == AdminType::ENT; });
251}
252
253bool AdminManager::IsSuperAdmin(const std::string &bundleName)
254{
255    std::shared_ptr<Admin> admin = GetAdminByPkgName(bundleName, DEFAULT_USER_ID);
256    if (admin == nullptr) {
257        EDMLOGW("IsSuperAdmin: admin == nullptr.");
258        return false;
259    }
260    if (admin->adminInfo_.adminType_ == AdminType::ENT) {
261        EDMLOGW("IsSuperAdmin: admin->adminInfo_.adminType_ == AdminType::ENT.");
262        return true;
263    }
264    return false;
265}
266
267bool AdminManager::IsAdminExist()
268{
269    return !admins_.empty();
270}
271
272bool AdminManager::IsSuperOrSubSuperAdmin(const std::string &bundleName)
273{
274    std::shared_ptr<Admin> superAdmin;
275    superAdmin = GetAdminByPkgName(bundleName, DEFAULT_USER_ID);
276    if (superAdmin == nullptr) {
277        return false;
278    }
279    return superAdmin->adminInfo_.adminType_ == AdminType::ENT ||
280        superAdmin->adminInfo_.adminType_ == AdminType::SUB_SUPER_ADMIN;
281}
282
283/*
284 * There are different administrator types according to the input parameters.
285 * Returns a list of package names
286 */
287void AdminManager::GetEnabledAdmin(AdminType role, std::vector<std::string> &packageNameList, int32_t userId)
288{
289    packageNameList.clear();
290    std::vector<std::shared_ptr<Admin>> userAdmin;
291    bool ret = GetAdminByUserId(userId, userAdmin);
292    if (!ret) {
293        EDMLOGW("GetEnabledAdmin::not find enabled Admin. userId = %{public}d", userId);
294        return;
295    }
296    EDMLOGD("AdminManager:GetEnabledAdmin adminType: %{public}d , admin size: %{public}zu", role, userAdmin.size());
297    if (static_cast<int32_t>(role) >= static_cast<int32_t>(AdminType::UNKNOWN) ||
298        static_cast<int32_t>(role) < static_cast<int32_t>(AdminType::NORMAL)) {
299        EDMLOGD("there is no admin(%{public}u) device manager package name list!", role);
300        return;
301    }
302
303    for (const auto &item : userAdmin) {
304        if (item->adminInfo_.adminType_ == role) {
305            std::string adminName = item->adminInfo_.packageName_ + "/" + item->adminInfo_.className_;
306            packageNameList.push_back(adminName);
307        }
308    }
309}
310
311ErrCode AdminManager::GetSubOrSuperAdminByPkgName(const std::string &subAdminName,
312    std::shared_ptr<Admin> &subOrSuperAdmin)
313{
314    std::vector<std::shared_ptr<Admin>> userAdmin;
315    if (!GetAdminByUserId(DEFAULT_USER_ID, userAdmin)) {
316        EDMLOGW("GetSubOrSuperAdminByPkgName::not find Admin under default user id");
317        return ERR_EDM_SUPER_ADMIN_NOT_FOUND;
318    }
319    auto adminItem = std::find_if(userAdmin.begin(), userAdmin.end(), [&](const std::shared_ptr<Admin> &admin) {
320        return admin->adminInfo_.packageName_ == subAdminName && (admin->adminInfo_.adminType_ == AdminType::ENT ||
321            admin->adminInfo_.adminType_ == AdminType::SUB_SUPER_ADMIN);
322    });
323    if (adminItem == userAdmin.end()) {
324        EDMLOGW("GetSubOrSuperAdminByPkgName::not find sub-super admin or super Admin");
325        return ERR_EDM_SUPER_ADMIN_NOT_FOUND;
326    }
327    subOrSuperAdmin = *adminItem;
328    return ERR_OK;
329}
330
331ErrCode AdminManager::GetSubSuperAdminsByParentName(const std::string &parentName, std::vector<std::string> &subAdmins)
332{
333    if (subAdmins.size() > 0) {
334        subAdmins.clear();
335    }
336    std::vector<std::shared_ptr<Admin>> userAdmin;
337    if (!GetAdminByUserId(DEFAULT_USER_ID, userAdmin)) {
338        EDMLOGE("GetSubSuperAdminsByParentName::not find Admin under default user id.");
339        return ERR_EDM_SUPER_ADMIN_NOT_FOUND;
340    }
341    for (const auto &admin : userAdmin) {
342        if (admin->adminInfo_.adminType_ == AdminType::SUB_SUPER_ADMIN &&
343            admin->adminInfo_.parentAdminName_ == parentName) {
344            subAdmins.push_back(admin->adminInfo_.packageName_);
345        }
346    }
347    return ERR_OK;
348}
349
350ErrCode AdminManager::GetEntInfo(const std::string &packageName, EntInfo &entInfo, int32_t userId)
351{
352    std::vector<std::shared_ptr<Admin>> userAdmin;
353    bool ret = GetAdminByUserId(userId, userAdmin);
354    if (!ret) {
355        EDMLOGW("GetEntInfo::not find Admin. userId = %{public}d", userId);
356        return ERR_EDM_UNKNOWN_ADMIN;
357    }
358    for (const auto &item : userAdmin) {
359        if (item->adminInfo_.packageName_ == packageName) {
360            entInfo = item->adminInfo_.entInfo_;
361            return ERR_OK;
362        }
363    }
364    return ERR_EDM_UNKNOWN_ADMIN;
365}
366
367ErrCode AdminManager::SetEntInfo(const std::string &packageName, EntInfo &entInfo, int32_t userId)
368{
369    std::vector<std::shared_ptr<Admin>> userAdmin;
370    bool ret = GetAdminByUserId(userId, userAdmin);
371    if (!ret) {
372        EDMLOGW("SetEntInfo::not find Admin. userId = %{public}d", userId);
373        return ERR_EDM_UNKNOWN_ADMIN;
374    }
375    auto adminPoliciesStorageRdb = AdminPoliciesStorageRdb::GetInstance();
376    if (adminPoliciesStorageRdb == nullptr) {
377        EDMLOGE("AdminManager::SetEntInfo get adminPoliciesStorageRdb failed.");
378        return ERR_GET_STORAGE_RDB_FAILED;
379    }
380    for (auto &item : userAdmin) {
381        if (item->adminInfo_.packageName_ == packageName &&
382            adminPoliciesStorageRdb->UpdateEntInfo(userId, packageName, entInfo)) {
383            item->adminInfo_.entInfo_ = entInfo;
384            return ERR_OK;
385        }
386    }
387    return ERR_EDM_UNKNOWN_ADMIN;
388}
389
390ErrCode AdminManager::SaveSubscribeEvents(const std::vector<uint32_t> &events, const std::string &bundleName,
391    int32_t userId)
392{
393    std::shared_ptr<Admin> admin = GetAdminByPkgName(bundleName, userId);
394    if (admin == nullptr) {
395        return ERR_EDM_UNKNOWN_ADMIN;
396    }
397    auto adminPoliciesStorageRdb = AdminPoliciesStorageRdb::GetInstance();
398    if (adminPoliciesStorageRdb == nullptr) {
399        EDMLOGE("AdminManager::SaveSubscribeEvents get adminPoliciesStorageRdb failed.");
400        return ERR_GET_STORAGE_RDB_FAILED;
401    }
402    std::vector<ManagedEvent> oldManagedEvents = admin->adminInfo_.managedEvents_;
403    size_t eventsNumber = admin->adminInfo_.managedEvents_.size();
404    for (const auto &event : events) {
405        std::vector<ManagedEvent> managedEvents = admin->adminInfo_.managedEvents_;
406        ManagedEvent subEvent = static_cast<ManagedEvent>(event);
407        if (std::find(managedEvents.begin(), managedEvents.end(), subEvent) == managedEvents.end()) {
408            admin->adminInfo_.managedEvents_.push_back(subEvent);
409        }
410    }
411    if (admin->adminInfo_.managedEvents_.size() > eventsNumber &&
412        !adminPoliciesStorageRdb->UpdateManagedEvents(userId, admin->adminInfo_.packageName_,
413            admin->adminInfo_.managedEvents_)) {
414        admin->adminInfo_.managedEvents_ = oldManagedEvents;
415        return ERR_EDM_UNKNOWN_ADMIN;
416    }
417    return ERR_OK;
418}
419
420ErrCode AdminManager::RemoveSubscribeEvents(const std::vector<uint32_t> &events, const std::string &bundleName,
421    int32_t userId)
422{
423    std::shared_ptr<Admin> admin = GetAdminByPkgName(bundleName, userId);
424    if (admin == nullptr) {
425        return ERR_EDM_UNKNOWN_ADMIN;
426    }
427    auto adminPoliciesStorageRdb = AdminPoliciesStorageRdb::GetInstance();
428    if (adminPoliciesStorageRdb == nullptr) {
429        EDMLOGE("AdminManager::RemoveSubscribeEvents get adminPoliciesStorageRdb failed.");
430        return ERR_GET_STORAGE_RDB_FAILED;
431    }
432
433    std::vector<ManagedEvent> oldManagedEvents = admin->adminInfo_.managedEvents_;
434    size_t eventsNumber = admin->adminInfo_.managedEvents_.size();
435    auto iter = std::remove_if(admin->adminInfo_.managedEvents_.begin(), admin->adminInfo_.managedEvents_.end(),
436        [&](ManagedEvent managedEvent) {
437            return std::find(events.begin(), events.end(), static_cast<uint32_t>(managedEvent)) != events.end();
438        });
439    admin->adminInfo_.managedEvents_.erase(iter, admin->adminInfo_.managedEvents_.end());
440
441    if (admin->adminInfo_.managedEvents_.size() < eventsNumber &&
442        !adminPoliciesStorageRdb->UpdateManagedEvents(userId, admin->adminInfo_.packageName_,
443            admin->adminInfo_.managedEvents_)) {
444        admin->adminInfo_.managedEvents_ = oldManagedEvents;
445        return ERR_EDM_UNKNOWN_ADMIN;
446    }
447    return ERR_OK;
448}
449
450ErrCode AdminManager::SaveAuthorizedAdmin(const std::string &bundleName, const std::vector<std::string> &permissions,
451    const std::string &parentName)
452{
453    std::vector<std::shared_ptr<Admin>> admin;
454    if (!GetAdminByUserId(DEFAULT_USER_ID, admin)) {
455        return ERR_SAVE_AUTHORIZED_ADMIN_FAILED;
456    }
457    std::shared_ptr<Admin> adminItem = GetAdminByPkgName(bundleName, DEFAULT_USER_ID);
458    if (!adminItem &&
459        !AdminPoliciesStorageRdb::GetInstance()->InsertAuthorizedAdmin(bundleName, permissions, parentName)) {
460        EDMLOGE("AdminManager::InsertAuthorizedAdmin save authorized failed.");
461        return ERR_SAVE_AUTHORIZED_ADMIN_FAILED;
462    }
463    if (adminItem) {
464        if (adminItem->GetAdminType() != AdminType::SUB_SUPER_ADMIN) {
465            EDMLOGE("AdminManager::UpdateAuthorizedAdmin can only update sub-super admin.");
466            return ERR_SAVE_AUTHORIZED_ADMIN_FAILED;
467        }
468        if (!AdminPoliciesStorageRdb::GetInstance()->UpdateAuthorizedAdmin(bundleName, permissions, parentName)) {
469            EDMLOGE("AdminManager::UpdateAuthorizedAdmin save authorized failed.");
470            return ERR_SAVE_AUTHORIZED_ADMIN_FAILED;
471        }
472    }
473    if (!adminItem) {
474        admin.emplace_back(std::make_shared<Admin>());
475        admins_[DEFAULT_USER_ID] = admin;
476        adminItem = admin.back();
477        adminItem->adminInfo_.adminType_ = AdminType::SUB_SUPER_ADMIN;
478    }
479    adminItem->adminInfo_.packageName_ = bundleName;
480    adminItem->adminInfo_.permission_ = permissions;
481    adminItem->adminInfo_.parentAdminName_ = parentName;
482    return ERR_OK;
483}
484
485std::shared_ptr<Admin> AdminManager::GetSuperAdmin()
486{
487    if (admins_.find(DEFAULT_USER_ID) != admins_.end()) {
488        auto item = std::find_if(admins_[DEFAULT_USER_ID].begin(), admins_[DEFAULT_USER_ID].end(),
489            [&](const std::shared_ptr<Admin>& admin) { return admin->GetAdminType() == AdminType::ENT; });
490        if (item != admins_[DEFAULT_USER_ID].end()) {
491            return *item;
492        }
493    }
494    return nullptr;
495}
496
497// init
498void AdminManager::Init()
499{
500    auto adminPoliciesStorageRdb = AdminPoliciesStorageRdb::GetInstance();
501    if (adminPoliciesStorageRdb != nullptr) {
502        admins_ = adminPoliciesStorageRdb->QueryAllAdmin();
503    } else {
504        EDMLOGE("AdminManager::Init failed.");
505    }
506}
507
508void AdminManager::Dump()
509{
510    for (const auto &entry : admins_) {
511        EDMLOGI("AdminManager::Dump %{public}d.", entry.first);
512        for (const auto &admin : entry.second) {
513            EDMLOGI("AdminManager::Dump admin info adminType_ %{public}d.",
514                admin->adminInfo_.adminType_);
515            EDMLOGI("AdminManager::Dump admin info packageName_ %{public}s.",
516                admin->adminInfo_.packageName_.c_str());
517            EDMLOGI("AdminManager::Dump admin info parentAdminName_ %{public}s.",
518                admin->adminInfo_.parentAdminName_.c_str());
519        }
520    }
521}
522} // namespace EDM
523} // namespace OHOS
524