1 /*
2 * Copyright (c) 2021 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 "user/user_manager.h"
17 #include <cstdlib>
18 #include "crypto/key_manager.h"
19 #include "ipc/istorage_daemon.h"
20 #include "storage_service_errno.h"
21 #include "storage_service_log.h"
22 #include "utils/string_utils.h"
23
24 using namespace std;
25
26 namespace OHOS {
27 namespace StorageDaemon {
28 std::shared_ptr<UserManager> UserManager::instance_ = nullptr;
UserManager()29 UserManager::UserManager()
30 : rootDirVec_{{"/data/app/%s/%d", 0711, OID_ROOT, OID_ROOT},
31 {"/data/service/%s/%d", 0711, OID_ROOT, OID_ROOT},
32 {"/data/chipset/%s/%d", 0711, OID_ROOT, OID_ROOT}},
33 subDirVec_{{"/data/app/%s/%d/base", 0711, OID_ROOT, OID_ROOT},
34 {"/data/app/%s/%d/database", 0711, OID_ROOT, OID_ROOT}},
35 backupDirVec_{{"/data/service/el2/%d/backup", 02771, OID_BACKUP, OID_BACKUP},
36 {"/data/service/el2/%d/backup/backup_sa", 0711, OID_BACKUP, OID_BACKUP}}
37 {
38 }
39
GetInstance()40 std::shared_ptr<UserManager> UserManager::GetInstance()
41 {
42 static std::once_flag onceFlag;
43 std::call_once(onceFlag, [&]() { instance_ = std::make_shared<UserManager>(); });
44
45 return instance_;
46 }
47
StartUser(int32_t userId)48 int32_t UserManager::StartUser(int32_t userId)
49 {
50 LOGI("start user %{public}d", userId);
51 std::lock_guard<std::mutex> lock(mutex_);
52 return MountManager::GetInstance()->MountByUser(userId);
53 }
54
StopUser(int32_t userId)55 int32_t UserManager::StopUser(int32_t userId)
56 {
57 LOGI("stop user %{public}d", userId);
58 std::lock_guard<std::mutex> lock(mutex_);
59 return MountManager::GetInstance()->UmountByUser(userId);
60 }
61
PrepareUserDirs(int32_t userId,uint32_t flags)62 int32_t UserManager::PrepareUserDirs(int32_t userId, uint32_t flags)
63 {
64 LOGI("prepare user dirs for %{public}d, flags %{public}u", userId, flags);
65 std::lock_guard<std::mutex> lock(mutex_);
66 int32_t err = E_OK;
67
68 if (flags & IStorageDaemon::CRYPTO_FLAG_EL1) {
69 err = PrepareDirsFromIdAndLevel(userId, EL1);
70 if (err != E_OK) {
71 return err;
72 }
73
74 err = PrepareEl1BundleDir(userId);
75 if (err != E_OK) {
76 return err;
77 }
78 }
79
80 if (flags & IStorageDaemon::CRYPTO_FLAG_EL2) {
81 err = PrepareDirsFromIdAndLevel(userId, EL2);
82 if (err != E_OK) {
83 return err;
84 }
85
86 err = MountManager::GetInstance()->PrepareHmdfsDirs(userId);
87 if (err != E_OK) {
88 LOGE("Prepare hmdfs dir error");
89 return err;
90 }
91
92 err = PrepareEl2BackupDir(userId);
93 if (err != E_OK) {
94 return err;
95 }
96 }
97
98 return E_OK;
99 }
100
DestroyUserDirs(int32_t userId,uint32_t flags)101 int32_t UserManager::DestroyUserDirs(int32_t userId, uint32_t flags)
102 {
103 LOGI("destroy user dirs for %{public}d, flags %{public}u", userId, flags);
104 std::lock_guard<std::mutex> lock(mutex_);
105 int32_t ret = E_OK;
106 int32_t err;
107
108 if (flags & IStorageDaemon::CRYPTO_FLAG_EL1) {
109 err = DestroyDirsFromIdAndLevel(userId, EL1);
110 ret = (err != E_OK) ? err : ret;
111
112 err = DestroyEl1BundleDir(userId);
113 ret = (err != E_OK) ? err : ret;
114 }
115
116 if (flags & IStorageDaemon::CRYPTO_FLAG_EL2) {
117 err = DestroyDirsFromIdAndLevel(userId, EL2);
118 ret = (err != E_OK) ? err : ret;
119
120 err = MountManager::GetInstance()->DestroyHmdfsDirs(userId);
121 ret = (err != E_OK) ? err : ret;
122
123 err = DestroyEl2BackupDir(userId);
124 ret = (err != E_OK) ? err : ret;
125 }
126
127 return ret;
128 }
129
PrepareDirsFromVec(int32_t userId,const std::string & level,const std::vector<DirInfo> & vec)130 inline bool PrepareDirsFromVec(int32_t userId, const std::string &level, const std::vector<DirInfo> &vec)
131 {
132 for (const DirInfo &dir : vec) {
133 if (!PrepareDir(StringPrintf(dir.path.c_str(), level.c_str(), userId), dir.mode, dir.uid, dir.gid)) {
134 return false;
135 }
136 }
137
138 return true;
139 }
140
DestroyDirsFromVec(int32_t userId,const std::string & level,const std::vector<DirInfo> & vec)141 inline bool DestroyDirsFromVec(int32_t userId, const std::string &level, const std::vector<DirInfo> &vec)
142 {
143 bool err = true;
144
145 for (const DirInfo &dir : vec) {
146 if (IsEndWith(dir.path.c_str(), "%d")) {
147 err = RmDirRecurse(StringPrintf(dir.path.c_str(), level.c_str(), userId));
148 }
149 }
150
151 return err;
152 }
153
PrepareDirsFromIdAndLevel(int32_t userId,const std::string & level)154 int32_t UserManager::PrepareDirsFromIdAndLevel(int32_t userId, const std::string &level)
155 {
156 if (!PrepareDirsFromVec(userId, level, rootDirVec_)) {
157 LOGE("failed to prepare %{public}s root dirs for userid %{public}d", level.c_str(), userId);
158 return E_PREPARE_DIR;
159 }
160
161 // set policy here
162 std::vector<FileList> list;
163 for (auto item : rootDirVec_) {
164 FileList temp;
165 temp.userId = static_cast<uint32_t>(userId);
166 temp.path = StringPrintf(item.path.c_str(), level.c_str(), userId);
167 list.push_back(temp);
168 }
169 int ret = SetElDirFscryptPolicy(userId, level, list);
170 if (ret != E_OK) {
171 LOGE("Set el poilcy failed");
172 return ret;
173 }
174
175 if (!PrepareDirsFromVec(userId, level, subDirVec_)) {
176 LOGE("failed to prepare %{public}s sub dirs for userid %{public}d", level.c_str(), userId);
177 return E_PREPARE_DIR;
178 }
179
180 return E_OK;
181 }
182
DestroyDirsFromIdAndLevel(int32_t userId,const std::string & level)183 int32_t UserManager::DestroyDirsFromIdAndLevel(int32_t userId, const std::string &level)
184 {
185 if (!DestroyDirsFromVec(userId, level, rootDirVec_)) {
186 LOGE("failed to destroy %{public}s dirs for userid %{public}d", level.c_str(), userId);
187 return E_DESTROY_DIR;
188 }
189
190 return E_OK;
191 }
192
PrepareEl1BundleDir(int32_t userId)193 int32_t UserManager::PrepareEl1BundleDir(int32_t userId)
194 {
195 if (!PrepareDir(StringPrintf(bundle_.c_str(), userId), 0711, OID_ROOT, OID_ROOT)) {
196 return E_PREPARE_DIR;
197 }
198
199 // set policy here
200 std::vector<FileList> list;
201 FileList temp;
202 temp.userId = static_cast<uint32_t>(userId);
203 temp.path = StringPrintf(bundle_.c_str(), userId);
204 list.push_back(temp);
205 int ret = SetElDirFscryptPolicy(userId, EL1, list);
206 if (ret != E_OK) {
207 LOGE("Set el1 poilcy failed");
208 return ret;
209 }
210
211 return E_OK;
212 }
213
DestroyEl1BundleDir(int32_t userId)214 int32_t UserManager::DestroyEl1BundleDir(int32_t userId)
215 {
216 if (!RmDirRecurse(StringPrintf(bundle_.c_str(), userId))) {
217 return E_DESTROY_DIR;
218 }
219
220 return E_OK;
221 }
222
SetElDirFscryptPolicy(int32_t userId,const std::string & level,const std::vector<FileList> & list)223 int32_t UserManager::SetElDirFscryptPolicy(int32_t userId, const std::string &level,
224 const std::vector<FileList> &list)
225 {
226 if (EL_DIR_MAP.find(level) == EL_DIR_MAP.end()) {
227 LOGE("el type error");
228 return E_SET_POLICY;
229 }
230 if (KeyManager::GetInstance()->SetDirectoryElPolicy(userId, EL_DIR_MAP[level], list)) {
231 LOGE("Set user dir el1 policy error");
232 return E_SET_POLICY;
233 }
234
235 return E_OK;
236 }
237
PrepareEl2BackupDir(int32_t userId)238 int32_t UserManager::PrepareEl2BackupDir(int32_t userId)
239 {
240 for (const DirInfo &dir : backupDirVec_) {
241 if (!PrepareDir(StringPrintf(dir.path.c_str(), userId), dir.mode, dir.uid, dir.gid)) {
242 return E_PREPARE_DIR;
243 }
244 }
245
246 return E_OK;
247 }
248
DestroyEl2BackupDir(int32_t userId)249 int32_t UserManager::DestroyEl2BackupDir(int32_t userId)
250 {
251 for (const DirInfo &dir : backupDirVec_) {
252 if (!RmDirRecurse(StringPrintf(dir.path.c_str(), userId))) {
253 return E_DESTROY_DIR;
254 }
255 }
256
257 return E_OK;
258 }
259 } // namespace StorageDaemon
260 } // namespace OHOS
261