1 // Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by an apache-2.0 license that can be
3 // found in the LICENSE file.
5 #include "common/shared_dirs.h"
7 #include <manifest_parser/utils/logging.h>
8 #include <manifest_parser/utils/version_number.h>
10 #include <boost/filesystem/operations.hpp>
11 #include <boost/filesystem/path.hpp>
12 #include <boost/program_options.hpp>
13 #include <boost/system/error_code.hpp>
17 #include <vcore/Certificate.h>
18 #include <pkgmgr-info.h>
19 #include <sys/types.h>
22 #include <tzplatform_config.h>
23 #include <sys/xattr.h>
37 #include "common/utils/paths.h"
38 #include "common/security_registration.h"
39 #include "common/utils/pkgmgr_query.h"
40 #include "common/utils/base64.h"
41 #include "common/utils/file_util.h"
42 #include "common/utils/user_util.h"
43 #include "common/utils/glist_range.h"
45 namespace bf = boost::filesystem;
46 namespace bpo = boost::program_options;
47 namespace bs = boost::system;
48 namespace ci = common_installer;
52 const uid_t kGlobalUserUid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
53 const utils::VersionNumber ver30("3.0");
54 const char kDisableLegacySharedDataDirSupport[] =
55 "/usr/share/app-installers/disable_legacy_shareddata_support";
57 const std::vector<const char*> kEntries = {
62 const std::vector<std::string> kReadOnlyEntries = {
68 const std::vector<std::string> kSharedDataEntries = {
73 const char kSharedResDir[] = "shared/res";
74 const char kSharedCacheDir[] = "shared/cache";
75 const char kSharedDataDir[] = "shared/data";
76 const char kShared[] = "shared";
77 const char kData[] = "data";
78 const char kCache[] = "cache";
79 const char kSharedDir[] = ".shared";
80 const char kSharedTmpDir[] = ".shared_tmp";
81 const char kSharedTrustedDir[] = "shared/trusted";
82 const char kSkelAppDir[] = "skel/apps_rw";
83 const char kExternalStoragePrivilege[] =
84 "http://tizen.org/privilege/externalstorage.appdata";
85 const char kSystemShareGroupName[] = "system_share";
86 const char kSubssesionDir[] = "subsession";
87 // the input path should be root directory of package.
88 // for example: "../apps_rw/pkgid" or "../.shared/pkgid"
89 bool SetPackageDirectoryOwnerAndPermissions(const bf::path& path, uid_t uid) {
90 boost::optional<gid_t> gid = ci::GetGidByUid(uid);
94 bf::perms perms755 = bf::all_all ^ bf::group_write ^ bf::others_write;
96 bf::owner_read | bf::owner_write | bf::group_read | bf::others_read;
97 bf::perms perms_setgid = perms755 | bf::set_gid_on_exe;
98 boost::optional<gid_t> system_share =
99 ci::GetGidByGroupName(kSystemShareGroupName);
101 if (!ci::SetDirOwnershipAndPermissions(path, perms755, uid, *gid))
104 for (bf::recursive_directory_iterator iter(path);
105 iter != bf::recursive_directory_iterator(); ++iter) {
106 if (bf::is_symlink(symlink_status(iter->path()))) {
109 } else if (bf::is_directory(iter->path()) && iter.level() == 0 &&
110 (iter->path().filename() == ".mmc" ||
111 iter->path().filename() == ".pkg" ||
112 iter->path().filename() == "tep")) {
113 // skip path which is related to mount or directory installer creates
115 } else if (bf::is_directory(iter->path())) {
117 if (iter.level() == 0 &&
118 (iter->path().filename() == kData ||
119 iter->path().filename() == kCache))
121 if (!ci::SetDirOwnershipAndPermissions(
122 iter->path(), is_rw ? perms_setgid : perms755, uid,
123 is_rw ? *system_share : *gid))
127 if (iter.level() == 1 && iter->path().parent_path().filename() == "bin")
129 if (!ci::SetDirOwnershipAndPermissions(
130 iter->path(), is_bin ? perms755 : perms644, uid, *gid))
137 bf::path GetDirectoryPathForStorage(uid_t user, std::string apps_prefix) {
138 std::string username = ci::GetUsernameByUid(user);
139 if (username.empty())
143 apps_rw = bf::path(apps_prefix.c_str()) / username / "apps_rw";
147 bool DeleteSharedDataDirectories(const bf::path& path,
148 const std::string& pkgid) {
149 if (!ci::RemoveAll(path / pkgid / kSharedDataDir))
152 std::vector<std::string> shared_dirs(kSharedDataEntries);
153 for (auto entry : shared_dirs) {
154 if (!ci::RemoveAll(path / entry / pkgid))
161 bool CreateSharedDataDirectories(const bf::path& path,
162 const std::string& pkgid) {
163 if (!ci::CreateDir(path / kSharedDir / pkgid / kData) ||
164 !ci::CreateDir(path / kSharedTmpDir / pkgid) ||
165 !ci::CreateDir(path / pkgid / kShared))
168 bf::current_path(path / pkgid / kShared);
169 if (bf::exists(path / pkgid / kShared / kData))
171 bf::path relative_path = ci::RelativePath(path / kSharedDir / pkgid / kData,
172 bf::current_path() / kData);
173 bs::error_code error;
174 bf::create_symlink(relative_path, kData, error);
176 LOG(ERROR) << "Failed to create symlink : " << error.message();
183 bool DeleteDirectories(const bf::path& app_dir, const std::string& pkgid) {
184 bf::path base_dir = app_dir / pkgid;
185 if (!ci::RemoveAll(base_dir))
187 if (!DeleteSharedDataDirectories(app_dir, pkgid))
192 bool CreateSymlinkFiles(const bf::path& src_dir, const bf::path& dst_dir) {
193 std::vector<std::string> rofiles(kReadOnlyEntries);
194 for (bf::directory_iterator file(src_dir);
195 file != bf::directory_iterator();
197 if (bf::is_regular_file(file->path())) {
198 bf::path current(file->path());
199 bf::path file_name = current.filename();
200 LOG(DEBUG) << "file_name: " << file_name;
201 rofiles.push_back(file_name.string());
205 bs::error_code error;
206 for (auto& entry : rofiles) {
207 bf::path src_path = src_dir / entry;
208 bf::path dst_path = dst_dir / entry;
209 if (!bf::exists(src_path)) {
210 // check if symlink for .mmc/bin,lib,res, then do not skip
211 if (!bf::is_symlink(symlink_status(src_path))) {
212 LOG(INFO) << "src_path not exist : " << src_path;
216 if (bf::exists(dst_path) || bf::is_symlink(symlink_status(dst_path))) {
217 LOG(WARNING) << "dst_path exist, skip : " << dst_path;
220 bf::create_symlink(src_path, dst_path, error);
222 LOG(ERROR) << "Symlink creation failure src_path: " << src_path
223 << " dst_path: " << dst_path;
224 LOG(ERROR) << "error: " << error.message();
231 bool DeleteSymlinkFiles(const bf::path& src_dir, const bf::path& dst_dir) {
232 bs::error_code error;
233 for (bf::directory_iterator file(dst_dir);
234 file != bf::directory_iterator();
236 bf::path current(file->path());
237 if (!bf::is_symlink(symlink_status(current)))
239 bf::path resolved_path = bf::read_symlink(current, error);
241 LOG(ERROR) << "Failed to get resolved path of symlink: " << current
242 << ", error: " << error.message();
246 LOG(DEBUG) << "resolved_path: " << resolved_path;
247 bf::path parent = resolved_path.parent_path();
248 if (parent.empty() || (parent != src_dir)) {
249 LOG(WARNING) << "Parent is empty or not equal to src, parent: ("
253 bf::remove(current, error);
255 LOG(ERROR) << "Symlink deletion failure for: " << current
256 << ", error: " << error.message();
259 LOG(DEBUG) << "removed: " << current;
261 bf::path shared_res = dst_dir / kSharedResDir;
262 if (bf::is_symlink(symlink_status(shared_res))) {
263 bf::remove(shared_res, error);
265 LOG(ERROR) << "Symlink deletion failure for: " << shared_res
266 << ", error: " << error.message();
273 bool CreateStorageDirectories(const boost::filesystem::path& root_path,
274 const std::string& pkgid,
275 bool trusted, bool shareddata,
276 const std::vector<const char*> additional_dirs) {
277 bf::path path(root_path / pkgid);
278 if (!ci::CreateDir(path)) {
279 LOG(ERROR) << "Failed to create dir: " << path;
283 std::vector<const char*> dirs(kEntries);
284 dirs.insert(dirs.end(), additional_dirs.begin(), additional_dirs.end());
286 dirs.push_back(kSharedTrustedDir);
288 bs::error_code error;
289 for (auto& entry : dirs) {
290 bf::path subpath = path / entry;
291 if (!ci::CreateDir(subpath)) {
292 LOG(ERROR) << "Failed to create directory: " << subpath;
298 if (!CreateSharedDataDirectories(root_path, pkgid))
301 if (!DeleteSharedDataDirectories(root_path, pkgid))
305 bf::path shared_cache_path = path / kSharedCacheDir;
306 // remove shared/cache (do not support)
307 if (!ci::RemoveAll(shared_cache_path))
313 bool BackupSharedDataDirectories(const bf::path& apps_rw,
314 const std::string& pkgid) {
315 if (!ci::MakeBackup(apps_rw / pkgid / kSharedDataDir))
317 if (!ci::MakeBackup(apps_rw / kSharedDir / pkgid))
319 if (!ci::MakeBackup(apps_rw / kSharedTmpDir / pkgid))
324 bool RestoreSharedDataDirectories(const bf::path& apps_rw,
325 const std::string& pkgid) {
326 if (!ci::RestoreBackup(apps_rw / pkgid / kSharedDataDir))
328 if (!ci::RestoreBackup(apps_rw / kSharedDir / pkgid))
330 if (!ci::RestoreBackup(apps_rw / kSharedTmpDir / pkgid))
335 bool RemoveBackupSharedDataDirectories(const bf::path& apps_rw,
336 const std::string& pkgid) {
337 if (!ci::RemoveBackup(apps_rw / pkgid / kSharedDataDir))
339 if (!ci::RemoveBackup(apps_rw / kSharedDir / pkgid))
341 if (!ci::RemoveBackup(apps_rw / kSharedTmpDir / pkgid))
346 bool CreateExternalUserDirectories(uid_t user, const std::string& pkgid,
347 const std::string& apps_prefix) {
348 boost::optional<gid_t> gid = ci::GetGidByUid(user);
352 std::string group_name = ci::GetGroupNameByGid(*gid);
353 if (group_name != tzplatform_getenv(TZ_SYS_USER_GROUP)) {
354 LOG(ERROR) << "Failed to get group name of gid: " << *gid;
358 LOG(DEBUG) << "Creating directories for uid: " << user << ", gid: "
361 bf::path apps_rw = GetDirectoryPathForStorage(user, apps_prefix);
362 if (apps_rw.empty()) {
363 LOG(DEBUG) << "Directory not exists: " << apps_rw;
367 if (!CreateStorageDirectories(apps_rw, pkgid, true, false,
368 std::vector<const char*>()))
371 if (!::SetPackageDirectoryOwnerAndPermissions(apps_rw / pkgid, user))
379 namespace common_installer {
381 std::string GetDirectoryPathForInternalStorage() {
382 const char* internal_storage_prefix = tzplatform_getenv(TZ_SYS_HOME);
383 if (internal_storage_prefix)
384 return std::string(internal_storage_prefix);
385 return tzplatform_getenv(TZ_SYS_HOME);
388 std::string GetDirectoryPathForExternalStorage() {
389 return GetExternalCardPath().string();
392 bool PerformExternalDirectoryCreationForUser(uid_t user,
393 const std::string& pkgid) {
394 bf::path storage_path = GetExternalCardPath();
396 if (!bf::exists(storage_path)) {
397 LOG(WARNING) << "External storage (SD Card) is not mounted.";
401 bf::path storage_apps_path = storage_path / "apps";
402 if (!bf::exists(storage_apps_path)) {
403 bs::error_code error;
404 bf::create_directories(storage_apps_path, error);
406 LOG(ERROR) << "Failed to create directory: "
407 << storage_apps_path.c_str();
412 if (CreateExternalUserDirectories(user, pkgid, storage_apps_path.string()))
415 for (auto& lw_user : GetLightUserList(user)) {
416 bf::path storage_apps_lw_path = storage_apps_path
417 / kSubssesionDir / lw_user / "apps";
418 if (!bf::exists(storage_apps_lw_path)) {
419 bs::error_code error;
420 bf::create_directories(storage_apps_lw_path, error);
422 LOG(ERROR) << "Failed to create directory: "
423 << storage_apps_lw_path.c_str();
428 if (CreateExternalUserDirectories(user, pkgid,
429 storage_apps_lw_path.string()))
436 bool PerformExternalDirectoryDeletionForUser(uid_t user,
437 const std::string& pkgid) {
438 bf::path storage_path = GetExternalCardPath();
439 if (!bf::exists(storage_path)) {
440 LOG(WARNING) << "External storage (SD Card) is not mounted. "
441 << "It will be ignored";
445 bf::path storage_apps_path = bf::path(storage_path) / "apps";
446 if (!DeleteDirectories(
447 GetDirectoryPathForStorage(user, storage_apps_path.string()), pkgid))
450 for (auto& lw_user : GetLightUserList(user)) {
451 bf::path storage_apps_lw_path =
452 storage_apps_path / kSubssesionDir / lw_user / "apps";
453 if (!DeleteDirectories(
454 GetDirectoryPathForStorage(user, storage_apps_lw_path.string()),
462 bool PerformExternalDirectoryCreationForAllUsers(const std::string& pkgid) {
463 UserList list = ci::GetUserList();
464 for (auto l : list) {
465 if (!PerformExternalDirectoryCreationForUser(std::get<0>(l),
467 LOG(WARNING) << "Could not create external storage directories for user: "
473 bool PerformExternalDirectoryCreationForAllPkgs() {
474 UserList list = ci::GetUserList();
475 for (auto l : list) {
476 uid_t uid = std::get<0>(l);
477 pkgmgrinfo_pkginfo_filter_h filter_handle = nullptr;
478 int ret = pkgmgrinfo_pkginfo_filter_create(&filter_handle);
479 if (ret != PMINFO_R_OK)
481 ret = pkgmgrinfo_pkginfo_filter_add_string(filter_handle,
482 PMINFO_PKGINFO_PROP_PACKAGE_PRIVILEGE, kExternalStoragePrivilege);
483 if (ret != PMINFO_R_OK) {
484 pkgmgrinfo_pkginfo_filter_destroy(filter_handle);
488 ret = pkgmgrinfo_pkginfo_filter_foreach_pkginfo(filter_handle,
489 [](const pkgmgrinfo_pkginfo_h handle, void* user_data) -> int {
491 static_cast<uid_t>(reinterpret_cast<uintptr_t>(user_data));
492 char* pkgid = nullptr;
494 int r = pkgmgrinfo_pkginfo_get_pkgid(handle, &pkgid);
495 if (r != PMINFO_R_OK)
497 if (!PerformExternalDirectoryCreationForUser(u, pkgid))
502 reinterpret_cast<void*>(static_cast<uintptr_t>(uid)));
503 if (ret != PMINFO_R_OK) {
504 LOG(DEBUG) << "Failed to create external directoy";
505 pkgmgrinfo_pkginfo_filter_destroy(filter_handle);
508 pkgmgrinfo_pkginfo_filter_destroy(filter_handle);
514 bool PerformExternalDirectoryDeletionForAllUsers(const std::string& pkgid) {
515 UserList list = ci::GetUserList();
516 for (auto l : list) {
517 uid_t uid = std::get<0>(l);
518 ci::PkgQueryInterface pkg_query(pkgid, uid);
519 LOG(DEBUG) << "Deleting directories for user: " << uid;
520 if (pkg_query.IsPackageInstalled()) {
521 LOG(DEBUG) << "Package: " << pkgid << " for uid: " << uid
522 << " still exists. Skipping";
526 if (!PerformExternalDirectoryDeletionForUser(uid, pkgid))
527 LOG(WARNING) << "Could not delete external storage directories for user: "
533 bool CreatePerUserStorageDirectories(const std::string& pkgid, bool trusted,
534 bool shareddata, bool is_readonly,
535 const std::vector<const char*> additional_dirs) {
537 bf::path skel_apps_rw = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
538 bf::path(kSkelAppDir);
539 if (!::CreateStorageDirectories(skel_apps_rw, pkgid, trusted, shareddata,
541 LOG(ERROR) << "Failed to create skeleton storage directories";
545 std::string error_message;
546 if (!RegisterSecurityContextForPath(pkgid, skel_apps_rw / pkgid,
547 kGlobalUserUid, is_readonly, &error_message)) {
548 LOG(ERROR) << "Failed to register security context for path: "
549 << skel_apps_rw / pkgid << ", error_message: " << error_message;
554 bf::path src_dir = bf::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
555 if (!CreateSymlinkFiles(src_dir, skel_apps_rw / pkgid))
559 // create per user dir
560 UserList list = ci::GetUserList();
561 for (auto l : list) {
562 uid_t uid = std::get<0>(l);
563 bf::path owner_apps_rw = std::get<2>(l) / "apps_rw";
564 std::vector<bf::path> apps_rw_paths;
565 apps_rw_paths.push_back(std::move(owner_apps_rw));
567 for (auto& lw_user : GetLightUserList(uid))
568 apps_rw_paths.push_back(std::get<2>(l)
569 / kSubssesionDir / lw_user / "apps_rw");
571 LOG(DEBUG) << "Creating directories for user: " << uid;
572 for (auto& apps_rw : apps_rw_paths) {
573 if (!::CreateStorageDirectories(apps_rw, pkgid, trusted, shareddata,
575 LOG(ERROR) << "Failed to create storage directory for user: " << uid;
579 if (!::SetPackageDirectoryOwnerAndPermissions(apps_rw / pkgid, uid))
583 std::vector<std::string> shared_dirs(kSharedDataEntries);
584 for (auto entry : shared_dirs) {
585 bf::path shared_dst = apps_rw / entry / pkgid;
586 if (!::SetPackageDirectoryOwnerAndPermissions(shared_dst, uid))
591 if (!RegisterSecurityContextForPath(pkgid, apps_rw / pkgid, uid, false,
593 LOG(ERROR) << "Failed to register security context for path: "
594 << apps_rw / pkgid << ", error_message: " << error_message;
603 bool DeletePerUserStorageDirectories(const std::string& pkgid,
606 bf::path skel_apps_rw = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
607 bf::path(kSkelAppDir);
608 if (!ci::RemoveAll(skel_apps_rw / pkgid)) {
609 LOG(ERROR) << "Failed to delete skeleton storage directories";
616 // delete per user dir
617 UserList list = ci::GetUserList();
618 for (auto l : list) {
619 uid_t uid = std::get<0>(l);
620 bf::path owner_apps_rw = std::get<2>(l) / "apps_rw";
621 std::vector<bf::path> apps_rw_paths;
622 apps_rw_paths.push_back(std::move(owner_apps_rw));
624 for (auto& lw_user : GetLightUserList(uid))
625 apps_rw_paths.push_back(std::get<2>(l) / kSubssesionDir / lw_user /
628 LOG(DEBUG) << "Deleting directories for user: " << uid;
629 for (auto& apps_rw : apps_rw_paths) {
630 if (!ci::RemoveAll(apps_rw / pkgid)) {
631 LOG(ERROR) << "Failed to delete storage directory for user: " << uid;
637 if (!ci::DeletePerUserSharedDataDir(pkgid)) {
638 LOG(ERROR) << "Failed to delete per user shared data dir";
645 bool CreateStorageDirectories(const boost::filesystem::path& path,
646 const std::string& pkgid, uid_t uid,
647 bool trusted, bool shareddata) {
648 if (!::CreateStorageDirectories(path, pkgid, trusted,
649 shareddata, std::vector<const char*>())) {
650 LOG(ERROR) << "Failed to create storage directory for path: " << path;
654 if (!::SetPackageDirectoryOwnerAndPermissions(path / pkgid, uid))
658 std::vector<std::string> shared_dirs(kSharedDataEntries);
659 for (auto entry : shared_dirs) {
660 bf::path shared_dst = path / entry / pkgid;
661 if (!::SetPackageDirectoryOwnerAndPermissions(shared_dst, uid))
666 std::string error_message;
667 if (!RegisterSecurityContextForPath(pkgid, path / pkgid, uid, false,
669 LOG(ERROR) << "Failed to register security context for path: " << path
670 << ", error_message: " << error_message;
677 void RemoveRWDirectories(const boost::filesystem::path& root) {
678 if (!RemoveAll(root / kCache))
679 LOG(ERROR) << "Failed to remove packaged cache directory";
680 if (!RemoveAll(root / kData))
681 LOG(ERROR) << "Failed to remove packaged data directory";
682 if (!RemoveAll(root / kSharedCacheDir))
683 LOG(ERROR) << "Failed to remove packaged shared/cache directory";
684 if (!RemoveAll(root / kSharedDataDir))
685 LOG(ERROR) << "Failed to remove packaged shared/data directory";
686 if (!RemoveAll(root / kSharedTrustedDir))
687 LOG(ERROR) << "Failed to remove packaged shared/trusted directory";
690 bool DeleteSharedDirectories(const bf::path& path,
691 const std::string& pkgid) {
692 return DeleteSharedDataDirectories(path, pkgid);
695 bool DeleteUserExternalDirectories(const std::string& pkgid) {
696 UserList list = ci::GetUserList();
697 for (auto l : list) {
698 uid_t uid = std::get<0>(l);
699 ci::PkgQueryInterface pkg_query(pkgid, uid);
700 if (pkg_query.IsPackageInstalled()) {
701 LOG(INFO) << pkgid << " is installed for user " << uid;
705 LOG(DEBUG) << "Deleting external directories of " << pkgid
706 << ", for uid: " << uid;
707 bf::path apps_rw(std::get<2>(l) / "apps_rw");
708 if (!DeleteDirectories(apps_rw, pkgid)) {
712 for (auto& lw_user : GetLightUserList(uid)) {
713 bf::path apps_rw_lw(std::get<2>(l) / kSubssesionDir / lw_user / "apps_rw");
714 if (!DeleteDirectories(apps_rw_lw, pkgid))
722 bool CreateGlobalAppSymlinksForAllUsers(const std::string& pkgid) {
723 bf::path src_dir = bf::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
724 if (!bf::exists(src_dir)) {
725 LOG(ERROR) << "src_dir not exists";
729 UserList list = ci::GetUserList();
730 for (auto l : list) {
731 uid_t uid = std::get<0>(l);
732 LOG(DEBUG) << "Creating symlinks for uid: " << uid;
733 // check installed user private app.
734 ci::PkgQueryInterface pkg_query(pkgid, uid);
735 if (pkg_query.IsPackageInstalled())
738 bf::path owner_apps_rw = std::get<2>(l) / "apps_rw";
739 std::vector<bf::path> apps_rw_paths;
740 apps_rw_paths.push_back(std::move(owner_apps_rw));
742 for (auto& lw_user : GetLightUserList(uid))
743 apps_rw_paths.push_back(std::get<2>(l) / kSubssesionDir / lw_user /
746 for (auto& apps_rw : apps_rw_paths) {
747 bf::path dst_dir = apps_rw / pkgid;
748 if (!bf::exists(dst_dir)) {
749 LOG(WARNING) << "dst_dir not exists";
753 if (!CreateSymlinkFiles(src_dir, dst_dir))
761 bool CreateGlobalAppSymlinksForUser(const std::string& pkgid, uid_t uid) {
762 bf::path src_dir = bf::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
763 if (!bf::exists(src_dir)) {
764 LOG(WARNING) << "src_dir(" << src_dir << ") not exists";
768 tzplatform_set_user(uid);
769 bf::path dst_dir = bf::path(tzplatform_getenv(TZ_USER_APP)) / pkgid;
770 tzplatform_reset_user();
771 if (!bf::exists(dst_dir)) {
772 LOG(WARNING) << "dst_dir not exists";
775 bool result = CreateSymlinkFiles(src_dir, dst_dir);
780 bool DeleteGlobalAppSymlinksForAllUsers(const std::string& pkgid) {
781 bf::path src_dir = bf::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
782 if (!bf::exists(src_dir)) {
783 LOG(WARNING) << "src_dir(" << src_dir << ") not exists";
787 UserList list = ci::GetUserList();
788 for (auto l : list) {
789 uid_t uid = std::get<0>(l);
790 LOG(DEBUG) << "Deleting symlinks for uid: " << uid;
792 // check installed user private app.
793 ci::PkgQueryInterface pkg_query(pkgid, uid);
794 if (pkg_query.IsPackageInstalled())
797 bf::path owner_apps_rw = std::get<2>(l) / "apps_rw";
798 std::vector<bf::path> apps_rw_paths;
799 apps_rw_paths.push_back(std::move(owner_apps_rw));
800 for (auto& lw_user : GetLightUserList(uid))
801 apps_rw_paths.push_back(std::get<2>(l) / kSubssesionDir / lw_user /
804 for (auto& apps_rw : apps_rw_paths) {
805 bf::path dst_dir = apps_rw / pkgid;
806 if (!bf::exists(dst_dir)) {
807 LOG(WARNING) << "dst_dir not exists";
811 if (!DeleteSymlinkFiles(src_dir, dst_dir))
819 bool DeleteGlobalAppSymlinksForUser(const std::string& pkgid, uid_t uid) {
820 bf::path src_dir = bf::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
821 if (!bf::exists(src_dir)) {
822 LOG(ERROR) << "src_dir not exists";
826 tzplatform_set_user(uid);
827 bf::path dst_dir = bf::path(tzplatform_getenv(TZ_USER_APP)) / pkgid;
828 tzplatform_reset_user();
829 if (!bf::exists(dst_dir)) {
830 LOG(WARNING) << "dst_dir not exists";
833 bool result = DeleteSymlinkFiles(src_dir, dst_dir);
837 bool SetPackageDirectoryOwnerAndPermissions(const bf::path& path, uid_t uid) {
838 return ::SetPackageDirectoryOwnerAndPermissions(path, uid);
841 bool ShouldSupportLegacySharedDataDir(const std::string& api_version) {
842 if (bf::exists(kDisableLegacySharedDataDirSupport))
844 utils::VersionNumber api_ver(api_version);
851 bool CreateSharedDataDir(const std::string& pkgid, uid_t uid) {
852 bf::path apps_rw = ci::GetRootAppPath(false, uid);
853 if (!CreateSharedDataDirectories(apps_rw, pkgid))
856 bf::path path = apps_rw / pkgid;
857 std::string error_message;
858 if (!ci::RegisterSecurityContextForPath(pkgid, path, uid, false,
860 LOG(ERROR) << "Failed to register security context for path: " << path
861 << ", error_message: " << error_message;
868 bool CreatePerUserSharedDataDir(const std::string& pkgid) {
870 bf::path skel_apps_rw = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
871 bf::path(kSkelAppDir);
872 LOG(DEBUG) << "Creating directory : " << skel_apps_rw;
873 if (!CreateSharedDataDirectories(skel_apps_rw, pkgid))
876 std::string error_message;
877 if (!ci::RegisterSecurityContextForPath(pkgid, skel_apps_rw / pkgid,
878 kGlobalUserUid, false, &error_message)) {
879 LOG(ERROR) << "Failed to register security context for path: "
880 << skel_apps_rw / pkgid << ", error_message: " << error_message;
884 // create per user dir
885 ci::UserList list = ci::GetUserList();
886 for (auto l : list) {
887 uid_t uid = std::get<0>(l);
888 LOG(DEBUG) << "Adding shareddata directory for uid: " << uid;
890 bf::path owner_apps_rw = ci::GetRootAppPath(false, uid);
891 std::vector<bf::path> apps_rw_paths;
892 apps_rw_paths.push_back(std::move(owner_apps_rw));
893 for (auto& lw_user : GetLightUserList(uid))
894 apps_rw_paths.push_back(std::get<2>(l) / kSubssesionDir / lw_user /
897 for (auto& apps_rw : apps_rw_paths) {
898 if (!CreateSharedDataDirectories(apps_rw, pkgid))
901 std::vector<std::string> shared_dirs(kSharedDataEntries);
902 for (auto entry : shared_dirs) {
903 bf::path shared_dst = apps_rw / entry / pkgid;
904 if (!::SetPackageDirectoryOwnerAndPermissions(shared_dst, uid))
908 if (!ci::RegisterSecurityContextForPath(pkgid, apps_rw / pkgid, uid,
909 false, &error_message)) {
910 LOG(ERROR) << "Failed to register security context for path: "
911 << apps_rw / pkgid << ", error_message: " << error_message;
920 bool DeleteSharedDataDir(const std::string& pkgid, uid_t uid) {
921 bf::path apps_rw = ci::GetRootAppPath(false, uid);
922 return DeleteSharedDataDirectories(apps_rw, pkgid);
925 bool DeletePerUserSharedDataDir(const std::string& pkgid) {
926 bf::path skel_apps_rw = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
927 bf::path(kSkelAppDir);
928 if (!DeleteSharedDataDirectories(skel_apps_rw, pkgid))
931 ci::UserList list = ci::GetUserList();
932 for (auto l : list) {
933 uid_t uid = std::get<0>(l);
935 bf::path owner_apps_rw = ci::GetRootAppPath(false, uid);
936 std::vector<bf::path> apps_rw_paths;
937 apps_rw_paths.push_back(std::move(owner_apps_rw));
938 for (auto& lw_user : GetLightUserList(uid))
939 apps_rw_paths.push_back(std::get<2>(l) / kSubssesionDir / lw_user /
942 for (auto& apps_rw : apps_rw_paths) {
943 if (!DeleteSharedDataDirectories(apps_rw, pkgid))
950 bool BackupSharedDataDir(const std::string& pkgid, uid_t uid) {
951 bf::path apps_rw = ci::GetRootAppPath(false, uid);
952 return BackupSharedDataDirectories(apps_rw, pkgid);
955 bool BackupPerUserSharedDataDir(const std::string& pkgid) {
956 bf::path skel_apps_rw = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
957 bf::path(kSkelAppDir);
958 if (!BackupSharedDataDirectories(skel_apps_rw, pkgid))
961 ci::UserList list = ci::GetUserList();
962 for (auto l : list) {
963 uid_t uid = std::get<0>(l);
964 bf::path owner_apps_rw = ci::GetRootAppPath(false, uid);
965 std::vector<bf::path> apps_rw_paths;
966 apps_rw_paths.push_back(std::move(owner_apps_rw));
967 for (auto& lw_user : GetLightUserList(uid))
968 apps_rw_paths.push_back(std::get<2>(l) / kSubssesionDir / lw_user /
971 for (auto& apps_rw : apps_rw_paths) {
972 if (!BackupSharedDataDirectories(apps_rw, pkgid))
980 bool RestoreSharedDataDir(const std::string& pkgid, uid_t uid) {
981 bf::path apps_rw = ci::GetRootAppPath(false, uid);
982 return RestoreSharedDataDirectories(apps_rw, pkgid);
985 bool RestorePerUserSharedDataDir(const std::string& pkgid) {
986 bf::path skel_apps_rw = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
987 bf::path(kSkelAppDir);
988 if (!RestoreSharedDataDirectories(skel_apps_rw, pkgid))
991 ci::UserList list = ci::GetUserList();
992 for (auto l : list) {
993 uid_t uid = std::get<0>(l);
994 bf::path owner_apps_rw = ci::GetRootAppPath(false, uid);
995 std::vector<bf::path> apps_rw_paths;
996 apps_rw_paths.push_back(std::move(owner_apps_rw));
997 for (auto& lw_user : GetLightUserList(uid))
998 apps_rw_paths.push_back(std::get<2>(l) / kSubssesionDir / lw_user /
1001 for (auto& apps_rw : apps_rw_paths) {
1002 if (!RestoreSharedDataDirectories(apps_rw, pkgid))
1010 bool RemoveBackupSharedDataDir(const std::string& pkgid, uid_t uid) {
1011 bf::path apps_rw = ci::GetRootAppPath(false, uid);
1012 return RemoveBackupSharedDataDirectories(apps_rw, pkgid);
1015 bool RemoveBackupPerUserSharedDataDir(const std::string& pkgid) {
1016 bf::path skel_apps_rw = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
1017 bf::path(kSkelAppDir);
1018 if (!RemoveBackupSharedDataDirectories(skel_apps_rw, pkgid))
1021 ci::UserList list = ci::GetUserList();
1022 for (auto l : list) {
1023 uid_t uid = std::get<0>(l);
1024 bf::path owner_apps_rw = ci::GetRootAppPath(false, uid);
1025 std::vector<bf::path> apps_rw_paths;
1026 apps_rw_paths.push_back(std::move(owner_apps_rw));
1027 for (auto& lw_user : GetLightUserList(uid))
1028 apps_rw_paths.push_back(std::get<2>(l) / kSubssesionDir / lw_user /
1031 for (auto& apps_rw : apps_rw_paths) {
1032 if (!RemoveBackupSharedDataDirectories(apps_rw, pkgid))
1040 } // namespace common_installer