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 "bundle_mgr_client.h"
19 #ifdef USER_CRYPTO_MANAGER
20 #include "crypto/key_manager.h"
21 #endif
22 #include "ipc/istorage_daemon.h"
23 #include "storage_service_constant.h"
24 #include "storage_service_errno.h"
25 #include "storage_service_log.h"
26 #include "utils/string_utils.h"
27
28 using namespace std;
29
30 namespace OHOS {
31 namespace StorageDaemon {
32 std::shared_ptr<UserManager> UserManager::instance_ = nullptr;
UserManager()33 UserManager::UserManager()
34 : rootDirVec_{{"/data/app/%s/%d", 0711, OID_ROOT, OID_ROOT},
35 {"/data/service/%s/%d", 0711, OID_ROOT, OID_ROOT},
36 {"/data/chipset/%s/%d", 0711, OID_ROOT, OID_ROOT}},
37 eceSeceDirVec_{{"/data/app/%s/%d", 0711, OID_ROOT, OID_ROOT},
38 {"/data/service/%s/%d", 0711, OID_ROOT, OID_ROOT}},
39 subDirVec_{{"/data/app/%s/%d/base", 0711, OID_ROOT, OID_ROOT},
40 {"/data/app/%s/%d/database", 0711, OID_ROOT, OID_ROOT}},
41 el2DirVec_{{"/data/service/el2/%d/backup", 02771, OID_BACKUP, OID_BACKUP},
42 {"/data/service/el2/%d/backup/backup_sa", 0711, OID_BACKUP, OID_BACKUP},
43 {"/data/app/el2/%d/log", 0711, OID_ROOT, OID_ROOT}},
44 el1DirVec_{{"/data/service/el1/%d/distributeddata", 0711, OID_DDMS, OID_DDMS},
45 {"/data/service/el1/%d/backup", 02711, OID_BACKUP, OID_BACKUP}}
46 {
47 }
48
GetInstance()49 std::shared_ptr<UserManager> UserManager::GetInstance()
50 {
51 static std::once_flag onceFlag;
52 std::call_once(onceFlag, [&]() { instance_ = std::make_shared<UserManager>(); });
53
54 return instance_;
55 }
56
StartUser(int32_t userId)57 int32_t UserManager::StartUser(int32_t userId)
58 {
59 LOGI("start user %{public}d", userId);
60 std::lock_guard<std::mutex> lock(mutex_);
61 int32_t err = CheckUserIdRange(userId);
62 if (err != E_OK) {
63 LOGE("UserManager::StartUser userId %{public}d out of range", userId);
64 return err;
65 }
66 return MountManager::GetInstance()->MountByUser(userId);
67 }
68
StopUser(int32_t userId)69 int32_t UserManager::StopUser(int32_t userId)
70 {
71 LOGI("stop user %{public}d", userId);
72 std::lock_guard<std::mutex> lock(mutex_);
73 int32_t err = CheckUserIdRange(userId);
74 if (err != E_OK) {
75 LOGE("UserManager::StopUser userId %{public}d out of range", userId);
76 return err;
77 }
78 return MountManager::GetInstance()->UmountByUser(userId);
79 }
80
PrepareUserDirs(int32_t userId,uint32_t flags)81 int32_t UserManager::PrepareUserDirs(int32_t userId, uint32_t flags)
82 {
83 LOGI("prepare user dirs for %{public}d, flags %{public}u", userId, flags);
84 std::lock_guard<std::mutex> lock(mutex_);
85 int32_t err = CheckUserIdRange(userId);
86 if (err != E_OK) {
87 LOGE("UserManager::PrepareUserDirs userId %{public}d out of range", userId);
88 return err;
89 }
90 if (flags & IStorageDaemon::CRYPTO_FLAG_EL1) {
91 err = PrepareDirsFromIdAndLevel(userId, EL1);
92 if (err != E_OK) {
93 return err;
94 }
95 err = PrepareEl1BundleDir(userId);
96 if (err != E_OK) {
97 return err;
98 }
99 int32_t errorCode = PrepareEl1Dir(userId);
100 if (errorCode != E_OK) {
101 LOGW("Prepare el1 dir fail, %{public}d.", errorCode);
102 }
103 }
104 if (flags & IStorageDaemon::CRYPTO_FLAG_EL2) {
105 err = PrepareDirsFromIdAndLevel(userId, EL2);
106 if (err != E_OK) {
107 return err;
108 }
109 err = PrepareEl2BackupDir(userId);
110 if (err != E_OK) {
111 return err;
112 }
113 }
114 if (flags & IStorageDaemon::CRYPTO_FLAG_EL3) {
115 err = PrepareDirsFromIdAndLevel(userId, EL3);
116 if (err != E_OK) {
117 return err;
118 }
119 }
120 if (flags & IStorageDaemon::CRYPTO_FLAG_EL4) {
121 err = PrepareDirsFromIdAndLevel(userId, EL4);
122 if (err != E_OK) {
123 return err;
124 }
125 }
126 if (flags & IStorageDaemon::CRYPTO_FLAG_EL2) {
127 err = MountManager::GetInstance()->PrepareHmdfsDirs(userId);
128 if (err != E_OK) {
129 LOGE("Prepare hmdfs dir error");
130 return err;
131 }
132 err = MountManager::GetInstance()->PrepareFileManagerDirs(userId);
133 if (err != E_OK) {
134 LOGE("Prepare fileManager dir error");
135 return err;
136 }
137 }
138
139 return E_OK;
140 }
141
DestroyUserDirs(int32_t userId,uint32_t flags)142 int32_t UserManager::DestroyUserDirs(int32_t userId, uint32_t flags)
143 {
144 LOGI("destroy user dirs for %{public}d, flags %{public}u", userId, flags);
145 std::lock_guard<std::mutex> lock(mutex_);
146 int32_t err = CheckUserIdRange(userId);
147 if (err != E_OK) {
148 LOGE("UserManager::DestroyUserDirs userId %{public}d out of range", userId);
149 return err;
150 }
151 int32_t ret = E_OK;
152 if (flags & IStorageDaemon::CRYPTO_FLAG_EL1) {
153 err = DestroyDirsFromIdAndLevel(userId, EL1);
154 ret = (err != E_OK) ? err : ret;
155
156 err = DestroyEl1BundleDir(userId);
157 ret = (err != E_OK) ? err : ret;
158 }
159 if (flags & IStorageDaemon::CRYPTO_FLAG_EL2) {
160 err = DestroyDirsFromIdAndLevel(userId, EL2);
161 ret = (err != E_OK) ? err : ret;
162
163 err = MountManager::GetInstance()->DestroyFileManagerDirs(userId);
164 ret = (err != E_OK) ? err : ret;
165
166 err = MountManager::GetInstance()->DestroyHmdfsDirs(userId);
167 ret = (err != E_OK) ? err : ret;
168
169 err = MountManager::GetInstance()->DestroySystemServiceDirs(userId);
170 ret = (err != E_OK) ? err : ret;
171
172 err = DestroyEl2BackupDir(userId);
173 ret = (err != E_OK) ? err : ret;
174
175 err = DestroyEl1Dir(userId);
176 ret = (err != E_OK) ? err : ret;
177 }
178 if (flags & IStorageDaemon::CRYPTO_FLAG_EL3) {
179 err = DestroyDirsFromIdAndLevel(userId, EL3);
180 ret = (err != E_OK) ? err : ret;
181 }
182 if (flags & IStorageDaemon::CRYPTO_FLAG_EL4) {
183 err = DestroyDirsFromIdAndLevel(userId, EL4);
184 ret = (err != E_OK) ? err : ret;
185 }
186
187 return ret;
188 }
189
PrepareDirsFromVec(int32_t userId,const std::string & level,const std::vector<DirInfo> & vec)190 inline bool PrepareDirsFromVec(int32_t userId, const std::string &level, const std::vector<DirInfo> &vec)
191 {
192 for (const DirInfo &dir : vec) {
193 if (!PrepareDir(StringPrintf(dir.path.c_str(), level.c_str(), userId), dir.mode, dir.uid, dir.gid)) {
194 return false;
195 }
196 }
197
198 return true;
199 }
200
DestroyDirsFromVec(int32_t userId,const std::string & level,const std::vector<DirInfo> & vec)201 inline bool DestroyDirsFromVec(int32_t userId, const std::string &level, const std::vector<DirInfo> &vec)
202 {
203 bool err = true;
204
205 for (const DirInfo &dir : vec) {
206 if (IsEndWith(dir.path.c_str(), "%d")) {
207 err = RmDirRecurse(StringPrintf(dir.path.c_str(), level.c_str(), userId));
208 }
209 }
210
211 return err;
212 }
213
PrepareDirsFromIdAndLevel(int32_t userId,const std::string & level)214 int32_t UserManager::PrepareDirsFromIdAndLevel(int32_t userId, const std::string &level)
215 {
216 std::vector<FileList> list;
217 if (level != EL3 && level != EL4) {
218 if (!PrepareDirsFromVec(userId, level, rootDirVec_)) {
219 LOGE("failed to prepare %{public}s root dirs for userid %{public}d", level.c_str(), userId);
220 return E_PREPARE_DIR;
221 }
222 // set policy here
223 for (auto item : rootDirVec_) {
224 FileList temp;
225 temp.userId = static_cast<uint32_t>(userId);
226 temp.path = StringPrintf(item.path.c_str(), level.c_str(), userId);
227 list.push_back(temp);
228 }
229 } else {
230 if (!PrepareDirsFromVec(userId, level, eceSeceDirVec_)) {
231 LOGE("failed to prepare %{public}s root dirs for userid %{public}d", level.c_str(), userId);
232 return E_PREPARE_DIR;
233 }
234 // set policy here
235 for (auto item : eceSeceDirVec_) {
236 FileList temp;
237 temp.userId = static_cast<uint32_t>(userId);
238 temp.path = StringPrintf(item.path.c_str(), level.c_str(), userId);
239 list.push_back(temp);
240 }
241 }
242 int ret = SetElDirFscryptPolicy(userId, level, list);
243 if (ret != E_OK) {
244 LOGE("Set el poilcy failed");
245 return ret;
246 }
247
248 if (!PrepareDirsFromVec(userId, level, subDirVec_)) {
249 LOGE("failed to prepare %{public}s sub dirs for userid %{public}d", level.c_str(), userId);
250 return E_PREPARE_DIR;
251 }
252
253 return E_OK;
254 }
255
DestroyDirsFromIdAndLevel(int32_t userId,const std::string & level)256 int32_t UserManager::DestroyDirsFromIdAndLevel(int32_t userId, const std::string &level)
257 {
258 if (level != EL3 && level != EL4) {
259 if (!DestroyDirsFromVec(userId, level, rootDirVec_)) {
260 LOGE("failed to destroy %{public}s dirs for userid %{public}d", level.c_str(), userId);
261 return E_DESTROY_DIR;
262 }
263 } else {
264 if (!DestroyDirsFromVec(userId, level, eceSeceDirVec_)) {
265 LOGE("failed to destroy %{public}s dirs for userid %{public}d", level.c_str(), userId);
266 return E_DESTROY_DIR;
267 }
268 }
269 return E_OK;
270 }
271
PrepareEl1BundleDir(int32_t userId)272 int32_t UserManager::PrepareEl1BundleDir(int32_t userId)
273 {
274 if (!PrepareDir(StringPrintf(bundle_.c_str(), userId), 0711, OID_ROOT, OID_ROOT)) {
275 return E_PREPARE_DIR;
276 }
277
278 // set policy here
279 std::vector<FileList> list;
280 FileList temp;
281 temp.userId = static_cast<uint32_t>(userId);
282 temp.path = StringPrintf(bundle_.c_str(), userId);
283 list.push_back(temp);
284 int ret = SetElDirFscryptPolicy(userId, EL1, list);
285 if (ret != E_OK) {
286 LOGE("Set el1 poilcy failed");
287 return ret;
288 }
289
290 return E_OK;
291 }
292
DestroyEl1BundleDir(int32_t userId)293 int32_t UserManager::DestroyEl1BundleDir(int32_t userId)
294 {
295 if (!RmDirRecurse(StringPrintf(bundle_.c_str(), userId))) {
296 return E_DESTROY_DIR;
297 }
298
299 return E_OK;
300 }
301
SetElDirFscryptPolicy(int32_t userId,const std::string & level,const std::vector<FileList> & list)302 int32_t UserManager::SetElDirFscryptPolicy(int32_t userId, const std::string &level,
303 const std::vector<FileList> &list)
304 {
305 #ifdef USER_CRYPTO_MANAGER
306 if (EL_DIR_MAP.find(level) == EL_DIR_MAP.end()) {
307 LOGE("el type error");
308 return E_SET_POLICY;
309 }
310 if (KeyManager::GetInstance()->SetDirectoryElPolicy(userId, EL_DIR_MAP[level], list)) {
311 LOGE("Set user dir el1 policy error");
312 return E_SET_POLICY;
313 }
314 #endif
315
316 return E_OK;
317 }
318
PrepareEl2BackupDir(int32_t userId)319 int32_t UserManager::PrepareEl2BackupDir(int32_t userId)
320 {
321 for (const DirInfo &dir : el2DirVec_) {
322 if (!PrepareDir(StringPrintf(dir.path.c_str(), userId), dir.mode, dir.uid, dir.gid)) {
323 return E_PREPARE_DIR;
324 }
325 }
326
327 return E_OK;
328 }
329
DestroyEl2BackupDir(int32_t userId)330 int32_t UserManager::DestroyEl2BackupDir(int32_t userId)
331 {
332 for (const DirInfo &dir : el2DirVec_) {
333 if (!RmDirRecurse(StringPrintf(dir.path.c_str(), userId))) {
334 return E_DESTROY_DIR;
335 }
336 }
337
338 return E_OK;
339 }
340
PrepareEl1Dir(int32_t userId)341 int32_t UserManager::PrepareEl1Dir(int32_t userId)
342 {
343 for (const DirInfo &dir : el1DirVec_) {
344 if (!PrepareDir(StringPrintf(dir.path.c_str(), userId), dir.mode, dir.uid, dir.gid)) {
345 return E_PREPARE_DIR;
346 }
347 }
348
349 return E_OK;
350 }
351
DestroyEl1Dir(int32_t userId)352 int32_t UserManager::DestroyEl1Dir(int32_t userId)
353 {
354 for (const DirInfo &dir : el1DirVec_) {
355 if (!RmDirRecurse(StringPrintf(dir.path.c_str(), userId))) {
356 return E_DESTROY_DIR;
357 }
358 }
359
360 return E_OK;
361 }
362
CheckUserIdRange(int32_t userId)363 int32_t UserManager::CheckUserIdRange(int32_t userId)
364 {
365 if ((userId < StorageService::START_USER_ID && userId != StorageService::ZERO_USER_ID)||
366 userId > StorageService::MAX_USER_ID) {
367 LOGE("UserManager: userId:%{public}d is out of range", userId);
368 return E_USERID_RANGE;
369 }
370 return E_OK;
371 }
372
CreateBundleDataDir(uint32_t userId)373 void UserManager::CreateBundleDataDir(uint32_t userId)
374 {
375 OHOS::AppExecFwk::BundleMgrClient client;
376 LOGI("CreateBundleDataDir start: userId %{public}u", userId);
377 auto ret = client.CreateBundleDataDir(userId);
378 LOGI("CreateBundleDataDir end: userId %{public}u, ret %{public}d", userId, ret);
379 }
380 } // namespace StorageDaemon
381 } // namespace OHOS
382