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