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::RemoveAll(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))
374 bool BackupSharedDataDirectories(const bf::path& apps_rw,
375 const std::string& pkgid) {
376 if (!ci::MakeBackup(apps_rw / pkgid / kSharedDataDir))
378 if (!ci::MakeBackup(apps_rw / kSharedDir / pkgid / kData))
380 if (!ci::MakeBackup(apps_rw / kSharedTmpDir / pkgid))
385 bool RestoreSharedDataDirectories(const bf::path& apps_rw,
386 const std::string& pkgid) {
387 if (!ci::RestoreBackup(apps_rw / pkgid / kSharedDataDir))
389 if (!ci::RestoreBackup(apps_rw / kSharedDir / pkgid / kData))
391 if (!ci::RestoreBackup(apps_rw / kSharedTmpDir / pkgid))
396 bool RemoveBackupSharedDataDirectories(const bf::path& apps_rw,
397 const std::string& pkgid) {
398 if (!ci::RemoveBackup(apps_rw / pkgid / kSharedDataDir))
400 if (!ci::RemoveBackup(apps_rw / kSharedDir / pkgid / kData))
402 if (!ci::RemoveBackup(apps_rw / kSharedTmpDir / pkgid))
409 namespace common_installer {
411 std::string GetDirectoryPathForInternalStorage() {
412 const char* internal_storage_prefix = tzplatform_getenv(TZ_SYS_HOME);
413 if (internal_storage_prefix)
414 return std::string(internal_storage_prefix);
415 return tzplatform_getenv(TZ_SYS_HOME);
418 std::string GetDirectoryPathForExternalStorage() {
419 return GetExternalCardPath().string();
422 bool PerformExternalDirectoryCreationForUser(uid_t user,
423 const std::string& pkgid) {
424 bf::path storage_path = GetExternalCardPath();
426 const bool set_permissions = false;
427 if (!bf::exists(storage_path)) {
428 LOG(WARNING) << "External storage (SD Card) is not mounted.";
432 bf::path storage_apps_path = storage_path / "apps";
433 if (!bf::exists(storage_apps_path)) {
434 bs::error_code error;
435 bf::create_directories(storage_apps_path, error);
437 LOG(ERROR) << "Failed to create directory: "
438 << storage_apps_path.c_str();
443 CreateUserDirectories(user, pkgid,
444 storage_apps_path.c_str(), set_permissions);
448 bool PerformExternalDirectoryDeletionForUser(uid_t user,
449 const std::string& pkgid) {
450 bf::path storage_path = GetExternalCardPath();
451 if (!bf::exists(storage_path)) {
452 LOG(WARNING) << "External storage (SD Card) is not mounted. "
453 << "It will be ignored";
457 bf::path storage_apps_path = bf::path(storage_path) / "apps";
458 return DeleteDirectories(
459 GetDirectoryPathForStorage(user, storage_apps_path.string()), pkgid);
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 ret = pkgmgrinfo_pkginfo_get_pkgid(handle, &pkgid);
495 if (ret != PMINFO_R_OK)
497 if (!PerformExternalDirectoryCreationForUser(uid, 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 CreateStorageDirectories(const boost::filesystem::path& path,
534 const std::string& pkgid, uid_t uid,
535 bool trusted, bool shareddata) {
536 if (!::CreateStorageDirectories(path, pkgid, trusted,
537 shareddata, std::vector<const char*>())) {
538 LOG(ERROR) << "Failed to create storage directory for path: " << path;
542 std::string error_message;
543 if (!RegisterSecurityContextForPath(pkgid, path, uid, false,
545 LOG(ERROR) << "Failed to register security context for path: " << path
546 << ", error_message: " << error_message;
553 bool DeleteStorageDirectories(const boost::filesystem::path& path,
554 const std::string& pkgid) {
555 std::vector<const char*> dirs;
556 dirs.assign(kEntries.begin() + 1, kEntries.end());
557 dirs.push_back(kSharedTrustedDir);
558 dirs.push_back(kSharedCacheDir);
559 for (auto& entry : dirs) {
560 bf::path subpath = path / pkgid / entry;
561 if (!ci::RemoveAll(subpath))
564 if (!DeleteSharedDataDirectories(path, pkgid))
570 bool DeleteSharedDirectories(const bf::path& path,
571 const std::string& pkgid) {
572 return DeleteSharedDataDirectories(path, pkgid);
575 bool CreateSkelDirectories(const std::string& pkgid,
576 bool trusted, bool shareddata, bool is_readonly,
577 const std::vector<const char*> additional_dirs) {
578 bf::path root_path = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
579 bf::path(kSkelAppDir);
581 if (!::CreateStorageDirectories(root_path, pkgid, trusted,
582 shareddata, additional_dirs)) {
583 LOG(ERROR) << "Failed to create storage directory for path: "
584 << root_path / pkgid;
588 std::string error_message;
589 if (!RegisterSecurityContextForPath(pkgid, root_path / pkgid, kGlobalUserUid,
590 is_readonly, &error_message)) {
591 LOG(ERROR) << "Failed to register security context for path: "
593 << ", error_message: " << error_message;
599 bf::path src_dir = bf::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
600 result = CreateSymlinkFiles(src_dir, root_path / pkgid);
606 bool DeleteSkelDirectories(const std::string& pkgid) {
607 bf::path path = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
608 bf::path(kSkelAppDir);
609 if (!DeleteDirectories(path, pkgid))
612 return DeleteSharedDataDirectories(
613 bf::path(tzplatform_getenv(TZ_SYS_ETC)) / bf::path(kSkelAppDir), pkgid);
617 bool DeleteUserDirectories(const std::string& pkgid) {
618 UserList list = ci::GetUserList();
619 for (auto l : list) {
620 uid_t uid = std::get<0>(l);
621 ci::PkgQueryInterface pkg_query(pkgid, uid);
622 if (pkg_query.IsPackageInstalled()) {
623 LOG(INFO) << pkgid << " is installed for user " << std::get<0>(l);
627 LOG(DEBUG) << "Deleting directories of " << pkgid
628 << ", for uid: " << std::get<0>(l);
629 bf::path apps_rw(std::get<2>(l) / "apps_rw");
630 if (!DeleteDirectories(apps_rw, pkgid)) {
637 bool DeleteUserExternalDirectories(const std::string& pkgid) {
638 UserList list = ci::GetUserList();
639 for (auto l : list) {
640 uid_t uid = std::get<0>(l);
641 ci::PkgQueryInterface pkg_query(pkgid, uid);
642 if (pkg_query.IsPackageInstalled()) {
643 LOG(INFO) << pkgid << " is installed for user " << uid;
647 LOG(DEBUG) << "Deleting external directories of " << pkgid
648 << ", for uid: " << uid;
649 bf::path apps_rw(std::get<2>(l) / "apps_rw");
650 if (!DeleteDirectories(apps_rw, pkgid)) {
657 bool CopyUserDirectories(const std::string& pkgid) {
658 UserList list = ci::GetUserList();
659 for (auto l : list) {
660 uid_t uid = std::get<0>(l);
661 gid_t gid = std::get<1>(l);
662 LOG(DEBUG) << "Copying directories for uid: " << uid;
663 bf::path apps_rw(std::get<2>(l) / "apps_rw");
664 bf::path src = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
665 bf::path(kSkelAppDir) / pkgid;
666 bf::path dst = apps_rw / pkgid;
667 if (!ci::CopyDir(src, dst, FSFlag::FS_NONE, false))
670 std::vector<std::string> shared_dirs(kSharedDataEntries);
671 for (auto entry : shared_dirs) {
672 bf::path shared_src = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
673 bf::path(kSkelAppDir) / entry / pkgid;
674 if (!bf::exists(shared_src))
677 bf::path shared_dst = apps_rw / entry / pkgid;
678 if (!ci::CopyDir(shared_src, shared_dst, FSFlag::FS_NONE, true))
681 if (!SetDirectoryOwnerAndPermissions(shared_dst, uid, gid))
684 for (bf::recursive_directory_iterator iter(dst);
685 iter != bf::recursive_directory_iterator(); ++iter) {
686 if (!SetSharedDirOwnerAndPermissions(iter->path(), uid))
691 if (!SetDirectoryOwnerAndPermissions(dst, uid, gid))
693 for (bf::recursive_directory_iterator iter(dst);
694 iter != bf::recursive_directory_iterator(); ++iter) {
695 if (!SetDirectoryOwnerAndPermissions(iter->path(),
699 std::string error_message;
700 if (!RegisterSecurityContextForPath(pkgid, dst, uid,
701 false, &error_message)) {
702 LOG(ERROR) << "Failed to register security context for path: " << dst
703 << ", error_message: " << error_message;
710 bool CreateGlobalAppSymlinksForAllUsers(const std::string& pkgid) {
711 bf::path src_dir = bf::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
712 if (!bf::exists(src_dir)) {
713 LOG(ERROR) << "src_dir not exists";
718 UserList list = ci::GetUserList();
719 for (auto l : list) {
720 uid_t uid = std::get<0>(l);
721 LOG(DEBUG) << "Creating symlinks for uid: " << uid;
722 // check installed user private app.
723 ci::PkgQueryInterface pkg_query(pkgid, uid);
724 if (pkg_query.IsPackageInstalled())
726 bf::path apps_rw(std::get<2>(l) / "apps_rw");
727 bf::path dst_dir = apps_rw / pkgid;
728 if (!bf::exists(dst_dir)) {
729 LOG(WARNING) << "dst_dir not exists";
732 result = CreateSymlinkFiles(src_dir, dst_dir);
737 bool CreateGlobalAppSymlinksForUser(const std::string& pkgid, uid_t uid) {
738 bf::path src_dir = bf::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
739 if (!bf::exists(src_dir)) {
740 LOG(WARNING) << "src_dir(" << src_dir << ") not exists";
744 tzplatform_set_user(uid);
745 bf::path dst_dir = bf::path(tzplatform_getenv(TZ_USER_APP)) / pkgid;
746 tzplatform_reset_user();
747 if (!bf::exists(dst_dir)) {
748 LOG(WARNING) << "dst_dir not exists";
751 bool result = CreateSymlinkFiles(src_dir, dst_dir);
756 bool DeleteGlobalAppSymlinksForAllUsers(const std::string& pkgid) {
757 bf::path src_dir = bf::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
758 if (!bf::exists(src_dir)) {
759 LOG(WARNING) << "src_dir(" << src_dir << ") not exists";
764 UserList list = ci::GetUserList();
765 for (auto l : list) {
766 uid_t uid = std::get<0>(l);
767 LOG(DEBUG) << "Deleting symlinks for uid: " << uid;
768 // check installed user private app.
769 ci::PkgQueryInterface pkg_query(pkgid, uid);
770 if (pkg_query.IsPackageInstalled())
772 bf::path apps_rw(std::get<2>(l) / "apps_rw");
773 bf::path dst_dir = apps_rw / pkgid;
774 if (!bf::exists(dst_dir)) {
775 LOG(WARNING) << "dst_dir not exists";
778 result = DeleteSymlinkFiles(src_dir, dst_dir);
783 bool DeleteGlobalAppSymlinksForUser(const std::string& pkgid, uid_t uid) {
784 bf::path src_dir = bf::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
785 if (!bf::exists(src_dir)) {
786 LOG(ERROR) << "src_dir not exists";
790 tzplatform_set_user(uid);
791 bf::path dst_dir = bf::path(tzplatform_getenv(TZ_USER_APP)) / pkgid;
792 tzplatform_reset_user();
793 if (!bf::exists(dst_dir)) {
794 LOG(WARNING) << "dst_dir not exists";
797 bool result = DeleteSymlinkFiles(src_dir, dst_dir);
801 bool SetPackageDirectoryOwnerAndPermissions(const bf::path& path, uid_t uid) {
802 boost::optional<gid_t> gid = ci::GetGidByUid(uid);
806 bf::owner_read | bf::owner_write | bf::group_read | bf::others_read;
808 perms644 | bf::owner_exe | bf::group_exe | bf::others_exe;
809 for (bf::recursive_directory_iterator iter(path);
810 iter != bf::recursive_directory_iterator(); ++iter) {
811 if (bf::is_symlink(symlink_status(iter->path())) ||
812 (bf::is_directory(iter->path()) &&
813 (iter->path().filename() == ".mmc" ||
814 iter->path().filename() == ".pkg" ||
815 iter->path().filename() == "tep"))) {
816 // skip symlink or path which is related to
817 // mount or directory installer creates
819 } else if (bf::is_directory(iter->path())) {
821 if (!SetDirectoryOwnerAndPermissions(iter->path(), uid, *gid))
823 } else if (iter.level() == 1 &&
824 iter->path().parent_path().filename() == "bin") {
826 if (!SetDirOwnershipAndPermissions(iter->path(), perms755, uid, *gid))
830 if (!SetDirOwnershipAndPermissions(iter->path(), perms644, uid, *gid))
837 bool ShouldSupportLegacySharedDataDir(const std::string& api_version) {
838 if (bf::exists(kDisableLegacySharedDataDirSupport))
840 utils::VersionNumber api_ver(api_version);
847 bool CreateSharedDataDir(const std::string& pkgid, uid_t uid) {
848 bf::path apps_rw = ci::GetRootAppPath(false, uid);
849 if (!CreateSharedDataDirectories(apps_rw, pkgid))
852 bf::path path = apps_rw / pkgid;
853 std::string error_message;
854 if (!ci::RegisterSecurityContextForPath(pkgid, path, uid, false,
856 LOG(ERROR) << "Failed to register security context for path: " << path
857 << ", error_message: " << error_message;
864 bool CreatePerUserSharedDataDir(const std::string& pkgid) {
866 bf::path skel_apps_rw = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
867 bf::path(kSkelAppDir);
868 LOG(DEBUG) << "Creating directory : " << skel_apps_rw;
869 if (!CreateSharedDataDirectories(skel_apps_rw, pkgid))
872 std::string error_message;
873 if (!ci::RegisterSecurityContextForPath(pkgid, skel_apps_rw / pkgid,
874 kGlobalUserUid, false, &error_message)) {
875 LOG(ERROR) << "Failed to register security context for path: "
876 << skel_apps_rw / pkgid << ", error_message: " << error_message;
880 // create per user dir
881 ci::UserList list = ci::GetUserList();
882 for (auto l : list) {
883 uid_t uid = std::get<0>(l);
884 LOG(DEBUG) << "Adding shareddata directory for uid: " << uid;
886 bf::path apps_rw = ci::GetRootAppPath(false, uid);
887 if (!CreateSharedDataDirectories(apps_rw, pkgid))
890 std::string error_message;
891 if (!ci::RegisterSecurityContextForPath(pkgid, apps_rw / pkgid, uid,
892 false, &error_message)) {
893 LOG(ERROR) << "Failed to register security context for path: "
894 << apps_rw / pkgid << ", error_message: " << error_message;
902 bool DeleteSharedDataDir(const std::string& pkgid, uid_t uid) {
903 bf::path apps_rw = ci::GetRootAppPath(false, uid);
904 return DeleteSharedDataDirectories(apps_rw, pkgid);
907 bool DeletePerUserSharedDataDir(const std::string& pkgid) {
908 bf::path skel_apps_rw = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
909 bf::path(kSkelAppDir);
910 if (!DeleteSharedDataDirectories(skel_apps_rw, pkgid))
913 ci::UserList list = ci::GetUserList();
914 for (auto l : list) {
915 uid_t uid = std::get<0>(l);
916 bf::path apps_rw = ci::GetRootAppPath(false, uid);
917 if (!DeleteSharedDataDirectories(apps_rw, pkgid))
924 bool BackupSharedDataDir(const std::string& pkgid, uid_t uid) {
925 bf::path apps_rw = ci::GetRootAppPath(false, uid);
926 return BackupSharedDataDirectories(apps_rw, pkgid);
929 bool BackupPerUserSharedDataDir(const std::string& pkgid) {
930 bf::path skel_apps_rw = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
931 bf::path(kSkelAppDir);
932 if (!BackupSharedDataDirectories(skel_apps_rw, pkgid))
935 ci::UserList list = ci::GetUserList();
936 for (auto l : list) {
937 uid_t uid = std::get<0>(l);
938 if (!BackupSharedDataDir(pkgid, uid))
945 bool RestoreSharedDataDir(const std::string& pkgid, uid_t uid) {
946 bf::path apps_rw = ci::GetRootAppPath(false, uid);
947 return RestoreSharedDataDirectories(apps_rw, pkgid);
950 bool RestorePerUserSharedDataDir(const std::string& pkgid) {
951 bf::path skel_apps_rw = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
952 bf::path(kSkelAppDir);
953 if (!RestoreSharedDataDirectories(skel_apps_rw, pkgid))
956 ci::UserList list = ci::GetUserList();
957 for (auto l : list) {
958 uid_t uid = std::get<0>(l);
959 if (!RestoreSharedDataDir(pkgid, uid))
966 bool RemoveBackupSharedDataDir(const std::string& pkgid, uid_t uid) {
967 bf::path apps_rw = ci::GetRootAppPath(false, uid);
968 return RemoveBackupSharedDataDirectories(apps_rw, pkgid);
971 bool RemoveBackupPerUserSharedDataDir(const std::string& pkgid) {
972 bf::path skel_apps_rw = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
973 bf::path(kSkelAppDir);
974 if (!RemoveBackupSharedDataDirectories(skel_apps_rw, pkgid))
977 ci::UserList list = ci::GetUserList();
978 for (auto l : list) {
979 uid_t uid = std::get<0>(l);
980 if (!RemoveBackupSharedDataDir(pkgid, uid))
987 } // namespace common_installer