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/paths.h"
38 #include "common/security_registration.h"
39 #include "common/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 kSharedDir[] = ".shared";
79 const char kSharedTmpDir[] = ".shared_tmp";
80 const char kSharedTrustedDir[] = "shared/trusted";
81 const char kSkelAppDir[] = "skel/apps_rw";
82 const char kExternalStoragePrivilege[] =
83 "http://tizen.org/privilege/externalstorage.appdata";
84 const char kSystemShareGroupName[] = "system_share";
86 bool SetDirectoryOwnerAndPermissions(const bf::path& subpath, uid_t uid,
88 // symlink and non directory will be skipped
89 if (bf::is_symlink(symlink_status(subpath)) || !bf::is_directory(subpath))
92 bf::perms perms = bf::all_all ^ bf::group_write ^ bf::others_write;
93 if (subpath.filename() == "data" || subpath.filename() == "cache") {
94 perms |= bf::group_write | bf::set_gid_on_exe;
95 boost::optional<gid_t> system_share =
96 ci::GetGidByGroupName(kSystemShareGroupName);
101 return common_installer::SetDirOwnershipAndPermissions(subpath, perms,
105 bool SetSharedDirOwnerAndPermissions(const bf::path& subpath, uid_t uid) {
106 if (!bf::is_directory(subpath) || subpath.filename() != "data")
108 bf::perms perms = (bf::all_all | bf::set_uid_on_exe) ^ bf::others_write;
109 boost::optional<gid_t> system_share =
110 ci::GetGidByGroupName(kSystemShareGroupName);
113 gid_t gid = *system_share;
115 return common_installer::SetDirOwnershipAndPermissions(subpath, perms,
119 bool CreateDirectories(const bf::path& app_dir, const std::string& pkgid,
120 uid_t uid, gid_t gid, const bool set_permissions,
121 const std::vector<const char*>
122 additional_dirs = std::vector<const char*>()) {
123 bf::path base_dir = app_dir / pkgid;
124 if (bf::exists(base_dir)) {
125 LOG(DEBUG) << "Directory for user already exist: " << base_dir;
128 bs::error_code error;
129 bf::create_directories(base_dir, error);
131 LOG(ERROR) << "Failed to create directory: " << base_dir;
136 bs::error_code error;
137 std::vector<const char*> dirs(kEntries);
138 dirs.insert(dirs.end(), additional_dirs.begin(), additional_dirs.end());
140 dirs.push_back(kSharedTrustedDir);
141 for (auto& entry : dirs) {
142 bf::path subpath = base_dir / entry;
143 bf::create_directories(subpath, error);
145 LOG(ERROR) << "Failed to create directory: " << subpath;
149 if (set_permissions) {
150 if (!SetDirectoryOwnerAndPermissions(subpath, uid, gid))
154 for (bf::recursive_directory_iterator iter(subpath);
155 iter != bf::recursive_directory_iterator(); ++iter) {
156 if (!SetDirectoryOwnerAndPermissions(iter->path(), uid, gid))
165 bf::path GetDirectoryPathForStorage(uid_t user, std::string apps_prefix) {
166 std::string username = ci::GetUsernameByUid(user);
167 if (username.empty())
171 apps_rw = bf::path(apps_prefix.c_str()) / username / "apps_rw";
175 bool CreateUserDirectories(uid_t user, const std::string& pkgid,
176 const std::string& apps_prefix, const bool set_permissions) {
177 boost::optional<gid_t> gid = ci::GetGidByUid(user);
181 std::string group_name = ci::GetGroupNameByGid(*gid);
182 if (group_name != tzplatform_getenv(TZ_SYS_USER_GROUP))
185 LOG(DEBUG) << "Creating directories for uid: " << user << ", gid: "
188 bf::path apps_rw = GetDirectoryPathForStorage(user, apps_prefix);
189 if (apps_rw.empty()) {
190 LOG(DEBUG) << "Directory not exists: " << apps_rw;
194 if (!CreateDirectories(apps_rw, pkgid,
195 user, *gid, set_permissions)) {
201 bool DeleteSharedDataDirectories(const bf::path& path,
202 const std::string& pkgid) {
203 if (!ci::Remove(path / pkgid / kSharedDataDir))
206 std::vector<std::string> shared_dirs(kSharedDataEntries);
207 for (auto entry : shared_dirs) {
208 if (!ci::RemoveAll(path / entry / pkgid))
215 bool CreateSharedDataDirectories(const bf::path& path,
216 const std::string& pkgid) {
217 if (!ci::CreateDir(path / kSharedDir / pkgid / kData) ||
218 !ci::CreateDir(path / kSharedTmpDir / pkgid))
221 bf::current_path(path / pkgid / kShared);
222 if (bf::exists(path / pkgid / kShared / kData))
224 bf::path relative_path = ci::RelativePath(path / kSharedDir / pkgid / kData,
225 bf::current_path() / kData);
226 bs::error_code error;
227 bf::create_symlink(relative_path, kData, error);
229 LOG(ERROR) << "Failed to create symlink : " << error.message();
236 bool DeleteDirectories(const bf::path& app_dir, const std::string& pkgid) {
237 bf::path base_dir = app_dir / pkgid;
238 if (!ci::RemoveAll(base_dir))
240 if (!DeleteSharedDataDirectories(app_dir, pkgid))
245 bool CreateSymlinkFiles(const bf::path& src_dir, const bf::path& dst_dir) {
246 std::vector<std::string> rofiles(kReadOnlyEntries);
247 for (bf::directory_iterator file(src_dir);
248 file != bf::directory_iterator();
250 if (bf::is_regular_file(file->path())) {
251 bf::path current(file->path());
252 bf::path file_name = current.filename();
253 LOG(DEBUG) << "file_name: " << file_name;
254 rofiles.push_back(file_name.string());
258 bs::error_code error;
259 for (auto& entry : rofiles) {
260 bf::path src_path = src_dir / entry;
261 bf::path dst_path = dst_dir / entry;
262 if (!bf::exists(src_path)) {
263 // check if symlink for .mmc/bin,lib,res, then do not skip
264 if (!bf::is_symlink(symlink_status(src_path))) {
265 LOG(INFO) << "src_path not exist : " << src_path;
269 if (bf::exists(dst_path) || bf::is_symlink(symlink_status(dst_path))) {
270 LOG(WARNING) << "dst_path exist, skip : " << dst_path;
273 bf::create_symlink(src_path, dst_path, error);
275 LOG(ERROR) << "Symlink creation failure src_path: " << src_path
276 << " dst_path: " << dst_path;
277 LOG(ERROR) << "error: " << error.message();
284 bool DeleteSymlinkFiles(const bf::path& src_dir, const bf::path& dst_dir) {
285 bs::error_code error;
286 for (bf::directory_iterator file(dst_dir);
287 file != bf::directory_iterator();
289 bf::path current(file->path());
290 if (bf::is_symlink(symlink_status(current))) {
291 bf::path resolved_path = bf::read_symlink(current, error);
293 LOG(ERROR) << "Getting resolved path of symlink: " << current;
294 LOG(ERROR) << "resolved_path: " << resolved_path;
295 LOG(ERROR) << "error: " << error.message();
298 LOG(DEBUG) << "resolved_path: " << resolved_path;
299 bf::path parent = resolved_path.parent_path();
300 if (!parent.empty() && (parent == src_dir)) {
301 bf::remove(current, error);
303 LOG(ERROR) << "Symlink deletion failure for: " << current
304 << ", error: " << error.message();
307 LOG(DEBUG) << "removed: " << current;
309 LOG(WARNING) << "Parent is empty or not equal to src, parenet: ("
314 bf::path shared_res = dst_dir / kSharedResDir;
315 if (bf::is_symlink(symlink_status(shared_res))) {
316 bf::remove(shared_res, error);
318 LOG(ERROR) << "Symlink deletion failure for: " << shared_res
319 << ", error: " << error.message();
326 bool CreateStorageDirectories(const boost::filesystem::path& root_path,
327 const std::string& pkgid,
328 bool trusted, bool shareddata,
329 const std::vector<const char*> additional_dirs) {
330 bf::path path(root_path / pkgid);
331 if (!bf::exists(path)) {
332 LOG(DEBUG) << "Creating directories in: " << path;
333 bs::error_code error;
334 bf::create_directories(path, error);
336 LOG(ERROR) << "Failed to create directory: "
337 << path << ", error: "
343 std::vector<const char*> dirs(kEntries);
344 dirs.insert(dirs.end(), additional_dirs.begin(), additional_dirs.end());
346 dirs.push_back(kSharedTrustedDir);
348 bs::error_code error;
349 for (auto& entry : dirs) {
350 bf::path subpath = path / entry;
351 bf::create_directories(subpath, error);
352 if (error && !bf::exists(subpath)) {
353 LOG(ERROR) << "Failed to create directory: " << subpath;
359 if (!CreateSharedDataDirectories(root_path, pkgid))
362 if (!DeleteSharedDataDirectories(root_path, pkgid))
366 bf::path shared_cache_path = path / kSharedCacheDir;
367 // remove shared/cache (do not support)
368 if (!ci::RemoveAll(shared_cache_path))
376 namespace common_installer {
378 std::string GetDirectoryPathForInternalStorage() {
379 const char* internal_storage_prefix = tzplatform_getenv(TZ_SYS_HOME);
380 if (internal_storage_prefix)
381 return std::string(internal_storage_prefix);
382 return tzplatform_getenv(TZ_SYS_HOME);
385 std::string GetDirectoryPathForExternalStorage() {
386 return GetExternalCardPath().string();
389 bool PerformExternalDirectoryCreationForUser(uid_t user,
390 const std::string& pkgid) {
391 bf::path storage_path = GetExternalCardPath();
393 const bool set_permissions = false;
394 if (!bf::exists(storage_path)) {
395 LOG(WARNING) << "External storage (SD Card) is not mounted.";
399 bf::path storage_apps_path = storage_path / "apps";
400 if (!bf::exists(storage_apps_path)) {
401 bs::error_code error;
402 bf::create_directories(storage_apps_path, error);
404 LOG(ERROR) << "Failed to create directory: "
405 << storage_apps_path.c_str();
410 CreateUserDirectories(user, pkgid,
411 storage_apps_path.c_str(), set_permissions);
415 bool PerformExternalDirectoryDeletionForUser(uid_t user,
416 const std::string& pkgid) {
417 bf::path storage_path = GetExternalCardPath();
418 if (!bf::exists(storage_path)) {
419 LOG(WARNING) << "External storage (SD Card) is not mounted. "
420 << "It will be ignored";
424 bf::path storage_apps_path = bf::path(storage_path) / "apps";
425 return DeleteDirectories(
426 GetDirectoryPathForStorage(user, storage_apps_path.string()), pkgid);
429 bool PerformExternalDirectoryCreationForAllUsers(const std::string& pkgid) {
430 UserList list = ci::GetUserList();
431 for (auto l : list) {
432 if (!PerformExternalDirectoryCreationForUser(std::get<0>(l),
434 LOG(WARNING) << "Could not create external storage directories for user: "
440 bool PerformExternalDirectoryCreationForAllPkgs() {
441 UserList list = ci::GetUserList();
442 for (auto l : list) {
443 uid_t uid = std::get<0>(l);
444 pkgmgrinfo_pkginfo_filter_h filter_handle = nullptr;
445 int ret = pkgmgrinfo_pkginfo_filter_create(&filter_handle);
446 if (ret != PMINFO_R_OK)
448 ret = pkgmgrinfo_pkginfo_filter_add_string(filter_handle,
449 PMINFO_PKGINFO_PROP_PACKAGE_PRIVILEGE, kExternalStoragePrivilege);
450 if (ret != PMINFO_R_OK) {
451 pkgmgrinfo_pkginfo_filter_destroy(filter_handle);
455 ret = pkgmgrinfo_pkginfo_filter_foreach_pkginfo(filter_handle,
456 [](const pkgmgrinfo_pkginfo_h handle, void* user_data) -> int {
458 static_cast<uid_t>(reinterpret_cast<uintptr_t>(user_data));
459 char* pkgid = nullptr;
461 int ret = pkgmgrinfo_pkginfo_get_pkgid(handle, &pkgid);
462 if (ret != PMINFO_R_OK)
464 if (!PerformExternalDirectoryCreationForUser(uid, pkgid))
469 reinterpret_cast<void*>(static_cast<uintptr_t>(uid)));
470 if (ret != PMINFO_R_OK) {
471 LOG(DEBUG) << "Failed to create external directoy";
472 pkgmgrinfo_pkginfo_filter_destroy(filter_handle);
475 pkgmgrinfo_pkginfo_filter_destroy(filter_handle);
481 bool PerformExternalDirectoryDeletionForAllUsers(const std::string& pkgid) {
482 UserList list = ci::GetUserList();
483 for (auto l : list) {
484 uid_t uid = std::get<0>(l);
485 ci::PkgQueryInterface pkg_query(pkgid, uid);
486 LOG(DEBUG) << "Deleting directories for user: " << uid;
487 if (pkg_query.IsPackageInstalled()) {
488 LOG(DEBUG) << "Package: " << pkgid << " for uid: " << uid
489 << " still exists. Skipping";
493 if (!PerformExternalDirectoryDeletionForUser(uid, pkgid))
494 LOG(WARNING) << "Could not delete external storage directories for user: "
500 bool CreateStorageDirectories(const boost::filesystem::path& path,
501 const std::string& pkgid, uid_t uid,
502 bool trusted, bool shareddata) {
503 if (!::CreateStorageDirectories(path, pkgid, trusted,
504 shareddata, std::vector<const char*>())) {
505 LOG(ERROR) << "Failed to create storage directory for path: " << path;
509 std::string error_message;
510 if (!RegisterSecurityContextForPath(pkgid, path, uid, false,
512 LOG(ERROR) << "Failed to register security context for path: " << path
513 << ", error_message: " << error_message;
520 bool DeleteStorageDirectories(const boost::filesystem::path& path,
521 const std::string& pkgid) {
522 std::vector<const char*> dirs;
523 dirs.assign(kEntries.begin() + 1, kEntries.end());
524 dirs.push_back(kSharedTrustedDir);
525 dirs.push_back(kSharedCacheDir);
526 for (auto& entry : dirs) {
527 bf::path subpath = path / pkgid / entry;
528 if (!ci::RemoveAll(subpath))
531 if (!DeleteSharedDataDirectories(path, pkgid))
537 bool DeleteSharedDirectories(const bf::path& path,
538 const std::string& pkgid) {
539 return DeleteSharedDataDirectories(path, pkgid);
542 bool CreateSkelDirectories(const std::string& pkgid,
543 bool trusted, bool shareddata, bool is_readonly,
544 const std::vector<const char*> additional_dirs) {
545 bf::path root_path = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
546 bf::path(kSkelAppDir);
548 if (!::CreateStorageDirectories(root_path, pkgid, trusted,
549 shareddata, additional_dirs)) {
550 LOG(ERROR) << "Failed to create storage directory for path: "
551 << root_path / pkgid;
555 std::string error_message;
556 if (!RegisterSecurityContextForPath(pkgid, root_path / pkgid, kGlobalUserUid,
557 is_readonly, &error_message)) {
558 LOG(ERROR) << "Failed to register security context for path: "
560 << ", error_message: " << error_message;
566 bf::path src_dir = bf::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
567 result = CreateSymlinkFiles(src_dir, root_path / pkgid);
573 bool UpdateSkelDirectories(const std::string& pkgid,
574 bool is_remove_shareddata) {
575 bf::path root_path = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
576 bf::path(kSkelAppDir);
577 LOG(DEBUG) << ((is_remove_shareddata) ? "Removing" : "Creating")
578 << " skel directory for pkgid: " << pkgid;
579 if (is_remove_shareddata) {
580 if (!DeleteSharedDataDirectories(root_path, pkgid))
585 if (!CreateSharedDataDirectories(root_path, pkgid))
588 std::string error_message;
589 if (!RegisterSecurityContextForPath(pkgid, root_path / pkgid, kGlobalUserUid,
590 false, &error_message)) {
591 LOG(ERROR) << "Failed to register security context for path: "
593 << ", error_message: " << error_message;
600 bool DeleteSkelDirectories(const std::string& pkgid) {
601 bf::path path = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
602 bf::path(kSkelAppDir);
603 if (!DeleteDirectories(path, pkgid))
606 return DeleteSharedDataDirectories(
607 bf::path(tzplatform_getenv(TZ_SYS_ETC)) / bf::path(kSkelAppDir), pkgid);
611 bool DeleteUserDirectories(const std::string& pkgid) {
612 UserList list = ci::GetUserList();
613 for (auto l : list) {
614 uid_t uid = std::get<0>(l);
615 ci::PkgQueryInterface pkg_query(pkgid, uid);
616 if (pkg_query.IsPackageInstalled()) {
617 LOG(INFO) << pkgid << " is installed for user " << std::get<0>(l);
621 LOG(DEBUG) << "Deleting directories of " << pkgid
622 << ", for uid: " << std::get<0>(l);
623 bf::path apps_rw(std::get<2>(l) / "apps_rw");
624 if (!DeleteDirectories(apps_rw, pkgid)) {
631 bool DeleteUserExternalDirectories(const std::string& pkgid) {
632 UserList list = ci::GetUserList();
633 for (auto l : list) {
634 uid_t uid = std::get<0>(l);
635 ci::PkgQueryInterface pkg_query(pkgid, uid);
636 if (pkg_query.IsPackageInstalled()) {
637 LOG(INFO) << pkgid << " is installed for user " << uid;
641 LOG(DEBUG) << "Deleting external directories of " << pkgid
642 << ", for uid: " << uid;
643 bf::path apps_rw(std::get<2>(l) / "apps_rw");
644 if (!DeleteDirectories(apps_rw, pkgid)) {
651 bool CopyUserDirectories(const std::string& pkgid) {
652 UserList list = ci::GetUserList();
653 for (auto l : list) {
654 uid_t uid = std::get<0>(l);
655 gid_t gid = std::get<1>(l);
656 LOG(DEBUG) << "Copying directories for uid: " << uid;
657 bf::path apps_rw(std::get<2>(l) / "apps_rw");
658 bf::path src = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
659 bf::path(kSkelAppDir) / pkgid;
660 bf::path dst = apps_rw / pkgid;
661 if (!ci::CopyDir(src, dst, FSFlag::FS_NONE, false))
664 std::vector<std::string> shared_dirs(kSharedDataEntries);
665 for (auto entry : shared_dirs) {
666 bf::path shared_src = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
667 bf::path(kSkelAppDir) / entry / pkgid;
668 if (!bf::exists(shared_src))
671 bf::path shared_dst = apps_rw / entry / pkgid;
672 if (!ci::CopyDir(shared_src, shared_dst, FSFlag::FS_NONE, true))
675 if (!SetDirectoryOwnerAndPermissions(shared_dst, uid, gid))
678 for (bf::recursive_directory_iterator iter(dst);
679 iter != bf::recursive_directory_iterator(); ++iter) {
680 if (!SetSharedDirOwnerAndPermissions(iter->path(), uid))
685 if (!SetDirectoryOwnerAndPermissions(dst, uid, gid))
687 for (bf::recursive_directory_iterator iter(dst);
688 iter != bf::recursive_directory_iterator(); ++iter) {
689 if (!SetDirectoryOwnerAndPermissions(iter->path(),
693 std::string error_message;
694 if (!RegisterSecurityContextForPath(pkgid, dst, uid,
695 false, &error_message)) {
696 LOG(ERROR) << "Failed to register security context for path: " << dst
697 << ", error_message: " << error_message;
704 bool CreateSharedData(const bf::path& path,
705 const std::string& pkgid) {
706 return CreateSharedDataDirectories(path, pkgid);
709 bool UpdateUserDirectory(const std::string& pkgid, bool is_remove_shareddata) {
710 UserList list = ci::GetUserList();
711 for (auto l : list) {
712 bf::path root_path(std::get<2>(l) / "apps_rw");
713 bf::path pkg_path(root_path / pkgid);
714 uid_t uid = std::get<0>(l);
715 LOG(DEBUG) << ((is_remove_shareddata) ? "Deleting" : "Adding")
716 << " shareddata directory for uid: " << uid;
718 if (is_remove_shareddata)
719 return DeleteSharedDataDirectories(root_path, pkgid);
721 if (!CreateSharedDataDirectories(root_path, pkgid)) {
722 LOG(ERROR) << "Failed to create shared directory: "
723 << root_path / pkgid;
727 gid_t gid = std::get<1>(l);
728 std::vector<std::string> shared_dirs(kSharedDataEntries);
729 for (auto entry : shared_dirs) {
730 bf::path dst = root_path / entry / pkgid;
731 if (!SetDirectoryOwnerAndPermissions(dst, uid, gid))
733 for (bf::recursive_directory_iterator iter(dst);
734 iter != bf::recursive_directory_iterator(); ++iter) {
735 if (!SetSharedDirOwnerAndPermissions(iter->path(), uid))
740 if (!SetDirectoryOwnerAndPermissions(pkg_path, uid, gid))
742 for (bf::recursive_directory_iterator iter(pkg_path);
743 iter != bf::recursive_directory_iterator(); ++iter) {
744 if (!SetDirectoryOwnerAndPermissions(iter->path(),
749 std::string error_message;
750 if (!RegisterSecurityContextForPath(pkgid, pkg_path, uid,
751 false, &error_message)) {
752 LOG(ERROR) << "Failed to register security context for path: "
753 << pkg_path << ", error_message: " << error_message;
760 bool CreateGlobalAppSymlinksForAllUsers(const std::string& pkgid) {
761 bf::path src_dir = bf::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
762 if (!bf::exists(src_dir)) {
763 LOG(ERROR) << "src_dir not exists";
768 UserList list = ci::GetUserList();
769 for (auto l : list) {
770 uid_t uid = std::get<0>(l);
771 LOG(DEBUG) << "Creating symlinks for uid: " << uid;
772 // check installed user private app.
773 ci::PkgQueryInterface pkg_query(pkgid, uid);
774 if (pkg_query.IsPackageInstalled())
776 bf::path apps_rw(std::get<2>(l) / "apps_rw");
777 bf::path dst_dir = apps_rw / pkgid;
778 if (!bf::exists(dst_dir)) {
779 LOG(WARNING) << "dst_dir not exists";
782 result = CreateSymlinkFiles(src_dir, dst_dir);
787 bool CreateGlobalAppSymlinksForUser(const std::string& pkgid, uid_t uid) {
788 bf::path src_dir = bf::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
789 if (!bf::exists(src_dir)) {
790 LOG(WARNING) << "src_dir(" << src_dir << ") not exists";
794 tzplatform_set_user(uid);
795 bf::path dst_dir = bf::path(tzplatform_getenv(TZ_USER_APP)) / pkgid;
796 tzplatform_reset_user();
797 if (!bf::exists(dst_dir)) {
798 LOG(WARNING) << "dst_dir not exists";
801 bool result = CreateSymlinkFiles(src_dir, dst_dir);
806 bool DeleteGlobalAppSymlinksForAllUsers(const std::string& pkgid) {
807 bf::path src_dir = bf::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
808 if (!bf::exists(src_dir)) {
809 LOG(WARNING) << "src_dir(" << src_dir << ") not exists";
814 UserList list = ci::GetUserList();
815 for (auto l : list) {
816 uid_t uid = std::get<0>(l);
817 LOG(DEBUG) << "Deleting symlinks for uid: " << uid;
818 // check installed user private app.
819 ci::PkgQueryInterface pkg_query(pkgid, uid);
820 if (pkg_query.IsPackageInstalled())
822 bf::path apps_rw(std::get<2>(l) / "apps_rw");
823 bf::path dst_dir = apps_rw / pkgid;
824 if (!bf::exists(dst_dir)) {
825 LOG(WARNING) << "dst_dir not exists";
828 result = DeleteSymlinkFiles(src_dir, dst_dir);
833 bool DeleteGlobalAppSymlinksForUser(const std::string& pkgid, uid_t uid) {
834 bf::path src_dir = bf::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
835 if (!bf::exists(src_dir)) {
836 LOG(ERROR) << "src_dir not exists";
840 tzplatform_set_user(uid);
841 bf::path dst_dir = bf::path(tzplatform_getenv(TZ_USER_APP)) / pkgid;
842 tzplatform_reset_user();
843 if (!bf::exists(dst_dir)) {
844 LOG(WARNING) << "dst_dir not exists";
847 bool result = DeleteSymlinkFiles(src_dir, dst_dir);
851 bool SetPackageDirectoryOwnerAndPermissions(const bf::path& path, uid_t uid) {
852 boost::optional<gid_t> gid = ci::GetGidByUid(uid);
856 bf::owner_read | bf::owner_write | bf::group_read | bf::others_read;
858 perms644 | bf::owner_exe | bf::group_exe | bf::others_exe;
859 for (bf::recursive_directory_iterator iter(path);
860 iter != bf::recursive_directory_iterator(); ++iter) {
861 if (bf::is_symlink(symlink_status(iter->path())) ||
862 (bf::is_directory(iter->path()) &&
863 (iter->path().filename() == ".mmc" ||
864 iter->path().filename() == ".pkg" ||
865 iter->path().filename() == "tep"))) {
866 // skip symlink or path which is related to
867 // mount or directory installer creates
869 } else if (bf::is_directory(iter->path())) {
871 if (!SetDirectoryOwnerAndPermissions(iter->path(), uid, *gid))
873 } else if (iter.level() == 1 &&
874 iter->path().parent_path().filename() == "bin") {
876 if (!SetDirOwnershipAndPermissions(iter->path(), perms755, uid, *gid))
880 if (!SetDirOwnershipAndPermissions(iter->path(), perms644, uid, *gid))
887 bool ShouldSupportLegacySharedDataDir(const std::string& api_version) {
888 if (bf::exists(kDisableLegacySharedDataDirSupport))
890 utils::VersionNumber api_ver(api_version);
897 } // namespace common_installer