#include <manifest_parser/utils/logging.h>
#include <manifest_parser/utils/version_number.h>
-#include <boost/filesystem/operations.hpp>
-#include <boost/filesystem/path.hpp>
-#include <boost/program_options.hpp>
-#include <boost/system/error_code.hpp>
-
#include <glib.h>
#include <gio/gio.h>
#include <vcore/Certificate.h>
#include <cstring>
#include <cstdio>
#include <exception>
+#include <filesystem>
#include <iterator>
+#include <optional>
#include <regex>
#include <string>
+#include <system_error>
#include <utility>
#include <vector>
#include <tuple>
-#include "common/paths.h"
+#include "common/utils/paths.h"
#include "common/security_registration.h"
-#include "common/pkgmgr_query.h"
+#include "common/utils/pkgmgr_query.h"
#include "common/utils/base64.h"
#include "common/utils/file_util.h"
#include "common/utils/user_util.h"
#include "common/utils/glist_range.h"
-namespace bf = boost::filesystem;
-namespace bpo = boost::program_options;
-namespace bs = boost::system;
namespace ci = common_installer;
+namespace fs = std::filesystem;
namespace {
const uid_t kGlobalUserUid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
const utils::VersionNumber ver30("3.0");
+const char kDisableLegacySharedDataDirSupport[] =
+ "/usr/share/app-installers/disable_legacy_shareddata_support";
const std::vector<const char*> kEntries = {
{"shared"},
{"cache"},
{"data"},
};
-const std::vector<const char*> kReadOnlyEntries = {
+const std::vector<std::string> kReadOnlyEntries = {
{"bin"},
{"lib"},
{"res"},
{"shared/res"},
};
+const std::vector<std::string> kSharedDataEntries = {
+ {".shared"},
+ {".shared_tmp"},
+};
const char kSharedResDir[] = "shared/res";
const char kSharedCacheDir[] = "shared/cache";
const char kSharedDataDir[] = "shared/data";
+const char kShared[] = "shared";
+const char kData[] = "data";
+const char kCache[] = "cache";
+const char kSharedDir[] = ".shared";
+const char kSharedTmpDir[] = ".shared_tmp";
const char kSharedTrustedDir[] = "shared/trusted";
const char kSkelAppDir[] = "skel/apps_rw";
const char kExternalStoragePrivilege[] =
"http://tizen.org/privilege/externalstorage.appdata";
const char kSystemShareGroupName[] = "system_share";
+const char kSubssesionDir[] = "subsession";
-bool SetDirectoryOwnerAndPermissions(const bf::path& subpath, uid_t uid,
- gid_t gid) {
- bf::perms perms = bf::owner_read |
- bf::owner_write |
- bf::group_read;
- // symlink will be skipped
- if (bf::is_symlink(symlink_status(subpath)))
- return true;
-
- // non directory will be skipped
- bool result = true;
- if (bf::is_directory(subpath)) {
- perms |= bf::owner_exe | bf::group_exe | bf::others_read | bf::others_exe;
- if (subpath.filename() == "data" || subpath.filename() == "cache") {
- perms |= bf::group_write | bf::set_gid_on_exe;
- boost::optional<gid_t> system_share =
- ci::GetGidByGroupName(kSystemShareGroupName);
- if (!system_share)
- return false;
- gid = *system_share;
- }
- result = common_installer::SetDirOwnershipAndPermissions(subpath, perms,
- uid, gid);
- }
-
- return result;
-}
+// the input path should be root directory of package.
+// for example: "../apps_rw/pkgid" or "../.shared/pkgid"
+bool SetPackageDirectoryOwnerAndPermissions(const fs::path& path, uid_t uid) {
+ std::optional<gid_t> gid = ci::GetGidByUid(uid);
+ if (!gid)
+ return false;
-bool CreateDirectories(const bf::path& app_dir, const std::string& pkgid,
- uid_t uid, gid_t gid, const bool set_permissions,
- const std::vector<const char*>
- additional_dirs = std::vector<const char*>()) {
- bf::path base_dir = app_dir / pkgid;
- if (bf::exists(base_dir)) {
- LOG(DEBUG) << "Directory for user already exist: " << base_dir;
- return true;
- } else {
- bs::error_code error;
- bf::create_directories(base_dir, error);
- if (error) {
- LOG(ERROR) << "Failed to create directory: " << base_dir;
- return false;
- }
- }
+ using fs::perms;
+ perms perms755 = perms::all ^ perms::group_write ^ perms::others_write;
+ perms perms644 = perms::owner_read | perms::owner_write |
+ perms::group_read | perms::others_read;
+ perms perms_setgid = perms755 | perms::set_gid;
- bs::error_code error;
- std::vector<const char*> dirs(kEntries);
- dirs.insert(dirs.end(), additional_dirs.begin(), additional_dirs.end());
- // always trusted
- dirs.push_back(kSharedTrustedDir);
- for (auto& entry : dirs) {
- bf::path subpath = base_dir / entry;
- bf::create_directories(subpath, error);
- if (error) {
- LOG(ERROR) << "Failed to create directory: " << subpath;
- return false;
- }
+ std::optional<gid_t> system_share =
+ ci::GetGidByGroupName(kSystemShareGroupName);
+ // root path
+ if (!ci::SetDirOwnershipAndPermissions(path, perms755, uid, *gid))
+ return false;
- if (set_permissions) {
- if (!SetDirectoryOwnerAndPermissions(subpath, uid, gid))
+ for (fs::recursive_directory_iterator iter(path);
+ iter != fs::recursive_directory_iterator(); ++iter) {
+ if (fs::is_symlink(symlink_status(iter->path()))) {
+ // skip symlink path
+ continue;
+ } else if (fs::is_directory(iter->path()) && iter.depth() == 0 &&
+ (iter->path().filename() == ".mmc" ||
+ iter->path().filename() == ".pkg" ||
+ iter->path().filename() == "tep")) {
+ // skip path which is related to mount or directory installer creates
+ continue;
+ } else if (fs::is_directory(iter->path())) {
+ bool is_rw = false;
+ if (iter.depth() == 0 &&
+ (iter->path().filename() == kData ||
+ iter->path().filename() == kCache))
+ is_rw = true;
+ if (!ci::SetDirOwnershipAndPermissions(
+ iter->path(), is_rw ? perms_setgid : perms755, uid,
+ is_rw ? *system_share : *gid))
+ return false;
+ } else {
+ bool is_bin = false;
+ if (iter.depth() == 1 && iter->path().parent_path().filename() == "bin")
+ is_bin = true;
+ if (!ci::SetDirOwnershipAndPermissions(
+ iter->path(), is_bin ? perms755 : perms644, uid, *gid))
return false;
-
- // for content
- for (bf::recursive_directory_iterator iter(subpath);
- iter != bf::recursive_directory_iterator(); ++iter) {
- if (!SetDirectoryOwnerAndPermissions(iter->path(), uid, gid))
- return false;
- }
}
}
-
return true;
}
-bf::path GetDirectoryPathForStorage(uid_t user, std::string apps_prefix) {
+fs::path GetDirectoryPathForStorage(uid_t user, std::string apps_prefix) {
std::string username = ci::GetUsernameByUid(user);
if (username.empty())
return {};
- bf::path apps_rw;
- apps_rw = bf::path(apps_prefix.c_str()) / username / "apps_rw";
+ fs::path apps_rw;
+ apps_rw = fs::path(apps_prefix.c_str()) / username / "apps_rw";
return apps_rw;
}
-bool CreateUserDirectories(uid_t user, const std::string& pkgid,
- const std::string& apps_prefix, const bool set_permissions) {
- boost::optional<gid_t> gid = ci::GetGidByUid(user);
- if (!gid)
+bool DeleteSharedDataDirectories(const fs::path& path,
+ const std::string& pkgid) {
+ if (!ci::RemoveAll(path / pkgid / kSharedDataDir))
return false;
- std::string group_name = ci::GetGroupNameByGid(*gid);
- if (group_name != tzplatform_getenv(TZ_SYS_USER_GROUP))
- return false;
+ std::vector<std::string> shared_dirs(kSharedDataEntries);
+ for (const auto& entry : shared_dirs) {
+ if (!ci::RemoveAll(path / entry / pkgid))
+ return false;
+ }
- LOG(DEBUG) << "Creating directories for uid: " << user << ", gid: "
- << *gid;
+ return true;
+}
- bf::path apps_rw = GetDirectoryPathForStorage(user, apps_prefix);
- if (apps_rw.empty()) {
- LOG(DEBUG) << "Directory not exists: " << apps_rw;
+bool CreateSharedDataDirectories(const fs::path& path,
+ const std::string& pkgid) {
+ if (!ci::CreateDir(path / kSharedDir / pkgid / kData) ||
+ !ci::CreateDir(path / kSharedTmpDir / pkgid) ||
+ !ci::CreateDir(path / pkgid / kShared))
return false;
- }
- if (!CreateDirectories(apps_rw, pkgid,
- user, *gid, set_permissions)) {
+ fs::current_path(path / pkgid / kShared);
+ if (fs::exists(path / pkgid / kShared / kData))
+ return true;
+ fs::path relative_path = fs::relative(path / kSharedDir / pkgid / kData,
+ fs::current_path());
+ std::error_code error;
+ fs::create_symlink(relative_path, kData, error);
+ if (error) {
+ LOG(ERROR) << "Failed to create symlink : " << error.message();
return false;
}
+
return true;
}
-bool DeleteDirectories(const bf::path& app_dir, const std::string& pkgid) {
- bf::path base_dir = app_dir / pkgid;
- return ci::RemoveAll(base_dir);
+bool DeleteDirectories(const fs::path& app_dir, const std::string& pkgid) {
+ fs::path base_dir = app_dir / pkgid;
+ if (!ci::RemoveAll(base_dir))
+ return false;
+ if (!DeleteSharedDataDirectories(app_dir, pkgid))
+ return false;
+ return true;
}
-
-bool CreateSymlinkFiles(const bf::path& src_dir, const bf::path& dst_dir) {
- std::vector<char*> rofiles;
- for (auto& entry : kReadOnlyEntries)
- rofiles.push_back(strdup(entry));
-
- for (bf::directory_iterator file(src_dir);
- file != bf::directory_iterator();
+bool CreateSymlinkFiles(const fs::path& src_dir, const fs::path& dst_dir) {
+ std::vector<std::string> rofiles(kReadOnlyEntries);
+ for (fs::directory_iterator file(src_dir);
+ file != fs::directory_iterator();
++file) {
- if (bf::is_regular_file(file->path())) {
- bf::path current(file->path());
- bf::path file_name = current.filename();
+ if (fs::is_regular_file(file->path())) {
+ fs::path current(file->path());
+ fs::path file_name = current.filename();
LOG(DEBUG) << "file_name: " << file_name;
- rofiles.push_back(strdup(file_name.c_str()));
+ rofiles.push_back(file_name.string());
}
}
- bs::error_code error;
+ std::error_code error;
for (auto& entry : rofiles) {
- bf::path src_path = src_dir / entry;
- bf::path dst_path = dst_dir / entry;
- free(const_cast<char*>(entry));
- if (!bf::exists(src_path)) {
+ fs::path src_path = src_dir / entry;
+ fs::path dst_path = dst_dir / entry;
+ if (!fs::exists(src_path)) {
// check if symlink for .mmc/bin,lib,res, then do not skip
- if (!bf::is_symlink(symlink_status(src_path))) {
+ if (!fs::is_symlink(symlink_status(src_path))) {
LOG(INFO) << "src_path not exist : " << src_path;
continue;
}
}
- if (bf::exists(dst_path) || bf::is_symlink(symlink_status(dst_path))) {
+ if (fs::exists(dst_path) || fs::is_symlink(symlink_status(dst_path))) {
LOG(WARNING) << "dst_path exist, skip : " << dst_path;
continue;
}
- bf::create_symlink(src_path, dst_path, error);
+ fs::create_symlink(src_path, dst_path, error);
if (error) {
LOG(ERROR) << "Symlink creation failure src_path: " << src_path
<< " dst_path: " << dst_path;
return true;
}
-bool DeleteSymlinkFiles(const bf::path& src_dir, const bf::path& dst_dir) {
- bs::error_code error;
- for (bf::directory_iterator file(dst_dir);
- file != bf::directory_iterator();
+bool DeleteSymlinkFiles(const fs::path& src_dir, const fs::path& dst_dir) {
+ std::error_code error;
+ for (fs::directory_iterator file(dst_dir);
+ file != fs::directory_iterator();
++file) {
- bf::path current(file->path());
- if (bf::is_symlink(symlink_status(current))) {
- bf::path resolved_path = bf::read_symlink(current, error);
- if (error) {
- LOG(ERROR) << "Getting resolved path of symlink: " << current;
- LOG(ERROR) << "resolved_path: " << resolved_path;
- LOG(ERROR) << "error: " << error.message();
- return false;
- }
- LOG(DEBUG) << "resolved_path: " << resolved_path;
- bf::path parent = resolved_path.parent_path();
- if (!parent.empty() && (parent == src_dir)) {
- bf::remove(current, error);
- if (error) {
- LOG(ERROR) << "Symlink deletion failure for: " << current
- << ", error: " << error.message();
- return false;
- }
- LOG(DEBUG) << "removed: " << current;
- } else {
- LOG(WARNING) << "Parent is empty or not equal to src, parenet: ("
+ fs::path current(file->path());
+ if (!fs::is_symlink(symlink_status(current)))
+ continue;
+ fs::path resolved_path = fs::read_symlink(current, error);
+ if (error) {
+ LOG(ERROR) << "Failed to get resolved path of symlink: " << current
+ << ", error: " << error.message();
+ return false;
+ }
+
+ LOG(DEBUG) << "resolved_path: " << resolved_path;
+ fs::path parent = resolved_path.parent_path();
+ if (parent.empty() || (parent != src_dir)) {
+ LOG(WARNING) << "Parent is empty or not equal to src, parent: ("
<< parent << ")";
- }
+ continue;
+ }
+ fs::remove(current, error);
+ if (error) {
+ LOG(ERROR) << "Symlink deletion failure for: " << current
+ << ", error: " << error.message();
+ return false;
}
+ LOG(DEBUG) << "removed: " << current;
}
- bf::path shared_res = dst_dir / kSharedResDir;
- if (bf::is_symlink(symlink_status(shared_res))) {
- bf::remove(shared_res, error);
+ fs::path shared_res = dst_dir / kSharedResDir;
+ if (fs::is_symlink(symlink_status(shared_res))) {
+ fs::remove(shared_res, error);
if (error) {
LOG(ERROR) << "Symlink deletion failure for: " << shared_res
<< ", error: " << error.message();
return true;
}
-bool CreateStorageDirectories(const boost::filesystem::path& path,
- const std::string& api_version,
+bool CreateStorageDirectories(const fs::path& root_path,
+ const std::string& pkgid,
bool trusted, bool shareddata,
const std::vector<const char*> additional_dirs) {
- if (!bf::exists(path)) {
- LOG(DEBUG) << "Creating directories in: " << path;
- bs::error_code error;
- bf::create_directories(path, error);
- if (error) {
- LOG(ERROR) << "Failed to create directory: " << path;
- return false;
- }
+ fs::path path(root_path / pkgid);
+ if (!ci::CreateDir(path)) {
+ LOG(ERROR) << "Failed to create dir: " << path;
+ return false;
}
- utils::VersionNumber api_ver(api_version);
std::vector<const char*> dirs(kEntries);
dirs.insert(dirs.end(), additional_dirs.begin(), additional_dirs.end());
if (trusted)
dirs.push_back(kSharedTrustedDir);
- if (api_ver < ver30 || shareddata) {
- dirs.push_back(kSharedDataDir);
- } else {
- bf::path shared_data_path = path / kSharedDataDir;
- // remove shared/data (deprecated)
- if (!ci::RemoveAll(shared_data_path))
- return false;
- }
+
+ std::error_code error;
for (auto& entry : dirs) {
- bs::error_code error;
- bf::path subpath = path / entry;
- bf::create_directories(subpath, error);
- if (error && !bf::exists(subpath)) {
+ fs::path subpath = path / entry;
+ if (!ci::CreateDir(subpath)) {
LOG(ERROR) << "Failed to create directory: " << subpath;
return false;
}
}
- bf::path shared_cache_path = path / kSharedCacheDir;
+ if (shareddata) {
+ if (!CreateSharedDataDirectories(root_path, pkgid))
+ return false;
+ } else {
+ if (!DeleteSharedDataDirectories(root_path, pkgid))
+ return false;
+ }
+
+ fs::path shared_cache_path = path / kSharedCacheDir;
// remove shared/cache (do not support)
if (!ci::RemoveAll(shared_cache_path))
return false;
return true;
}
+bool BackupSharedDataDirectories(const fs::path& apps_rw,
+ const std::string& pkgid) {
+ if (!ci::MakeBackup(apps_rw / pkgid / kSharedDataDir))
+ return false;
+ if (!ci::MakeBackup(apps_rw / kSharedDir / pkgid))
+ return false;
+ if (!ci::MakeBackup(apps_rw / kSharedTmpDir / pkgid))
+ return false;
+ return true;
+}
+
+bool RestoreSharedDataDirectories(const fs::path& apps_rw,
+ const std::string& pkgid) {
+ if (!ci::RestoreBackup(apps_rw / pkgid / kSharedDataDir))
+ return false;
+ if (!ci::RestoreBackup(apps_rw / kSharedDir / pkgid))
+ return false;
+ if (!ci::RestoreBackup(apps_rw / kSharedTmpDir / pkgid))
+ return false;
+ return true;
+}
+
+bool RemoveBackupSharedDataDirectories(const fs::path& apps_rw,
+ const std::string& pkgid) {
+ if (!ci::RemoveBackup(apps_rw / pkgid / kSharedDataDir))
+ return false;
+ if (!ci::RemoveBackup(apps_rw / kSharedDir / pkgid))
+ return false;
+ if (!ci::RemoveBackup(apps_rw / kSharedTmpDir / pkgid))
+ return false;
+ return true;
+}
+
+bool CreateExternalUserDirectories(uid_t user, const std::string& pkgid,
+ const std::string& apps_prefix) {
+ std::optional<gid_t> gid = ci::GetGidByUid(user);
+ if (!gid)
+ return false;
+
+ std::string group_name = ci::GetGroupNameByGid(*gid);
+ if (group_name != tzplatform_getenv(TZ_SYS_USER_GROUP)) {
+ LOG(ERROR) << "Failed to get group name of gid: " << *gid;
+ return false;
+ }
+
+ LOG(DEBUG) << "Creating directories for uid: " << user << ", gid: "
+ << *gid;
+
+ fs::path apps_rw = GetDirectoryPathForStorage(user, apps_prefix);
+ if (apps_rw.empty()) {
+ LOG(DEBUG) << "Directory not exists: " << apps_rw;
+ return false;
+ }
+
+ if (!CreateStorageDirectories(apps_rw, pkgid, true, false,
+ std::vector<const char*>()))
+ return false;
+
+ if (!::SetPackageDirectoryOwnerAndPermissions(apps_rw / pkgid, user))
+ return false;
+
+ return true;
+}
+
} // namespace
namespace common_installer {
bool PerformExternalDirectoryCreationForUser(uid_t user,
const std::string& pkgid) {
- bf::path storage_path = GetExternalCardPath();
+ fs::path storage_path = GetExternalCardPath();
- const bool set_permissions = false;
- if (!bf::exists(storage_path)) {
+ if (!fs::exists(storage_path)) {
LOG(WARNING) << "External storage (SD Card) is not mounted.";
return false;
}
- bf::path storage_apps_path = storage_path / "apps";
- if (!bf::exists(storage_apps_path)) {
- bs::error_code error;
- bf::create_directories(storage_apps_path, error);
+ fs::path storage_apps_path = storage_path / "apps";
+ if (!fs::exists(storage_apps_path)) {
+ std::error_code error;
+ fs::create_directories(storage_apps_path, error);
if (error) {
LOG(ERROR) << "Failed to create directory: "
<< storage_apps_path.c_str();
}
}
- CreateUserDirectories(user, pkgid,
- storage_apps_path.c_str(), set_permissions);
+ if (CreateExternalUserDirectories(user, pkgid, storage_apps_path.string()))
+ return false;
+
+ for (auto& lw_user : GetLightUserList(user)) {
+ fs::path storage_apps_lw_path = storage_apps_path
+ / kSubssesionDir / lw_user / "apps";
+ if (!fs::exists(storage_apps_lw_path)) {
+ std::error_code error;
+ fs::create_directories(storage_apps_lw_path, error);
+ if (error) {
+ LOG(ERROR) << "Failed to create directory: "
+ << storage_apps_lw_path.c_str();
+ return false;
+ }
+ }
+
+ if (CreateExternalUserDirectories(user, pkgid,
+ storage_apps_lw_path.string()))
+ return false;
+ }
+
return true;
}
bool PerformExternalDirectoryDeletionForUser(uid_t user,
const std::string& pkgid) {
- bf::path storage_path = GetExternalCardPath();
- if (!bf::exists(storage_path)) {
+ fs::path storage_path = GetExternalCardPath();
+ if (!fs::exists(storage_path)) {
LOG(WARNING) << "External storage (SD Card) is not mounted. "
<< "It will be ignored";
return true;
}
- bf::path storage_apps_path = bf::path(storage_path) / "apps";
- return DeleteDirectories(
- GetDirectoryPathForStorage(user, storage_apps_path.string()), pkgid);
+ fs::path storage_apps_path = fs::path(storage_path) / "apps";
+ if (!DeleteDirectories(
+ GetDirectoryPathForStorage(user, storage_apps_path.string()), pkgid))
+ return false;
+
+ for (auto& lw_user : GetLightUserList(user)) {
+ fs::path storage_apps_lw_path =
+ storage_apps_path / kSubssesionDir / lw_user / "apps";
+ if (!DeleteDirectories(
+ GetDirectoryPathForStorage(user, storage_apps_lw_path.string()),
+ pkgid))
+ return false;
+ }
+
+ return true;
}
bool PerformExternalDirectoryCreationForAllUsers(const std::string& pkgid) {
UserList list = ci::GetUserList();
- for (auto l : list) {
+ for (const auto& l : list) {
if (!PerformExternalDirectoryCreationForUser(std::get<0>(l),
pkgid))
LOG(WARNING) << "Could not create external storage directories for user: "
return true;
}
-int PrivilegeCallback(const pkgmgrinfo_pkginfo_h handle, void* user_data) {
- uid_t uid = static_cast<uid_t>(reinterpret_cast<uintptr_t>(user_data));
- char* pkgid = nullptr;
-
- int ret = pkgmgrinfo_pkginfo_get_pkgid(handle, &pkgid);
- if (ret != PMINFO_R_OK)
- return -1;
- if (!PerformExternalDirectoryCreationForUser(uid, pkgid))
- return -1;
-
- return 0;
-}
-
bool PerformExternalDirectoryCreationForAllPkgs() {
UserList list = ci::GetUserList();
- for (auto l : list) {
+ for (const auto& l : list) {
uid_t uid = std::get<0>(l);
pkgmgrinfo_pkginfo_filter_h filter_handle = nullptr;
int ret = pkgmgrinfo_pkginfo_filter_create(&filter_handle);
}
ret = pkgmgrinfo_pkginfo_filter_foreach_pkginfo(filter_handle,
- PrivilegeCallback,
+ [](const pkgmgrinfo_pkginfo_h handle, void* user_data) -> int {
+ uid_t u =
+ static_cast<uid_t>(reinterpret_cast<uintptr_t>(user_data));
+ char* pkgid = nullptr;
+
+ int r = pkgmgrinfo_pkginfo_get_pkgid(handle, &pkgid);
+ if (r != PMINFO_R_OK)
+ return -1;
+ if (!PerformExternalDirectoryCreationForUser(u, pkgid))
+ return -1;
+
+ return 0;
+ },
reinterpret_cast<void*>(static_cast<uintptr_t>(uid)));
if (ret != PMINFO_R_OK) {
LOG(DEBUG) << "Failed to create external directoy";
bool PerformExternalDirectoryDeletionForAllUsers(const std::string& pkgid) {
UserList list = ci::GetUserList();
- for (auto l : list) {
+ for (const auto& l : list) {
uid_t uid = std::get<0>(l);
ci::PkgQueryInterface pkg_query(pkgid, uid);
LOG(DEBUG) << "Deleting directories for user: " << uid;
return true;
}
-bool CreateStorageDirectories(const boost::filesystem::path& path,
- const std::string& api_version,
- bool trusted, bool shareddata) {
- return ::CreateStorageDirectories(path, api_version, trusted, shareddata,
- std::vector<const char*>());
-}
-
-bool DeleteStorageDirectories(const boost::filesystem::path& path) {
- std::vector<const char*> dirs;
- dirs.assign(kEntries.begin() + 1, kEntries.end());
- dirs.push_back(kSharedTrustedDir);
- dirs.push_back(kSharedDataDir);
- dirs.push_back(kSharedCacheDir);
- for (auto& entry : dirs) {
- bf::path subpath = path / entry;
- if (!ci::RemoveAll(subpath))
- return false;
- }
- return true;
-}
-
-bool CreateSkelDirectories(const std::string& pkgid,
- const std::string& api_version,
- bool trusted, bool shareddata, bool is_readonly,
- const std::vector<const char*> additional_dirs) {
- bf::path path = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
- bf::path(kSkelAppDir) / pkgid;
- LOG(DEBUG) << "Creating directories in: " << path;
-
- if (!::CreateStorageDirectories(path, api_version, trusted, shareddata,
- additional_dirs)) {
- LOG(ERROR) << "Failed to create storage directory for path: " << path;
+bool CreatePerUserStorageDirectories(const std::string& pkgid, bool trusted,
+ bool shareddata, bool is_readonly,
+ const std::vector<const char*> additional_dirs) {
+ // create skel dir
+ fs::path skel_apps_rw = fs::path(tzplatform_getenv(TZ_SYS_ETC)) /
+ fs::path(kSkelAppDir);
+ if (!::CreateStorageDirectories(skel_apps_rw, pkgid, trusted, shareddata,
+ additional_dirs)) {
+ LOG(ERROR) << "Failed to create skeleton storage directories";
return false;
}
std::string error_message;
- if (!RegisterSecurityContextForPath(pkgid, path, kGlobalUserUid,
- is_readonly, &error_message)) {
- LOG(ERROR) << "Failed to register security context for path: " << path
- << ", error_message: " << error_message;
+ if (!RegisterSecurityContextForPath(pkgid, skel_apps_rw / pkgid,
+ kGlobalUserUid, is_readonly, &error_message)) {
+ LOG(ERROR) << "Failed to register security context for path: "
+ << skel_apps_rw / pkgid << ", error_message: " << error_message;
return false;
}
- bool result = true;
if (!is_readonly) {
- bf::path src_dir = bf::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
- result = CreateSymlinkFiles(src_dir, path);
+ fs::path src_dir = fs::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
+ if (!CreateSymlinkFiles(src_dir, skel_apps_rw / pkgid))
+ return false;
}
- return result;
-}
+ // create per user dir
+ UserList list = ci::GetUserList();
+ for (const auto& l : list) {
+ uid_t uid = std::get<0>(l);
+ fs::path owner_apps_rw = std::get<2>(l) / "apps_rw";
+ std::vector<fs::path> apps_rw_paths;
+ apps_rw_paths.push_back(std::move(owner_apps_rw));
+
+ for (auto& lw_user : GetLightUserList(uid))
+ apps_rw_paths.push_back(std::get<2>(l)
+ / kSubssesionDir / lw_user / "apps_rw");
+
+ LOG(DEBUG) << "Creating directories for user: " << uid;
+ for (auto& apps_rw : apps_rw_paths) {
+ if (!::CreateStorageDirectories(apps_rw, pkgid, trusted, shareddata,
+ additional_dirs)) {
+ LOG(ERROR) << "Failed to create storage directory for user: " << uid;
+ return false;
+ }
-bool UpdateSkelDirectories(const std::string& pkgid,
- bool is_remove_shareddata) {
- bf::path path = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
- bf::path(kSkelAppDir) / pkgid;
- bf::path shared_data_path = path / kSharedDataDir;
- LOG(DEBUG) << ((is_remove_shareddata) ? "Removing" : "Creating")
- << " directory : " << shared_data_path;
+ if (!::SetPackageDirectoryOwnerAndPermissions(apps_rw / pkgid, uid))
+ return false;
- if (!is_remove_shareddata) {
- if (!CreateDir(shared_data_path))
- return false;
+ if (shareddata) {
+ std::vector<std::string> shared_dirs(kSharedDataEntries);
+ for (const auto& entry : shared_dirs) {
+ fs::path shared_dst = apps_rw / entry / pkgid;
+ if (!::SetPackageDirectoryOwnerAndPermissions(shared_dst, uid))
+ return false;
+ }
+ }
- std::string error_message;
- if (!RegisterSecurityContextForPath(pkgid, path, kGlobalUserUid,
- false, &error_message)) {
- LOG(ERROR) << "Failed to register security context for path: " << path
- << ", error_message: " << error_message;
- return false;
+ if (!RegisterSecurityContextForPath(pkgid, apps_rw / pkgid, uid, false,
+ &error_message)) {
+ LOG(ERROR) << "Failed to register security context for path: "
+ << apps_rw / pkgid << ", error_message: " << error_message;
+ return false;
+ }
}
- } else {
- return ci::RemoveAll(shared_data_path);
}
+
return true;
}
-bool DeleteSkelDirectories(const std::string& pkgid) {
- bf::path path = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
- bf::path(kSkelAppDir);
- return DeleteDirectories(path, pkgid);
-}
+bool DeletePerUserStorageDirectories(const std::string& pkgid,
+ bool keep_rwdata) {
+ // delete skel dir
+ fs::path skel_apps_rw = fs::path(tzplatform_getenv(TZ_SYS_ETC)) /
+ fs::path(kSkelAppDir);
+ if (!ci::RemoveAll(skel_apps_rw / pkgid)) {
+ LOG(ERROR) << "Failed to delete skeleton storage directories";
+ return false;
+ }
+ if (keep_rwdata)
+ return true;
-bool DeleteUserDirectories(const std::string& pkgid) {
+ // delete per user dir
UserList list = ci::GetUserList();
- for (auto l : list) {
+ for (const auto& l : list) {
uid_t uid = std::get<0>(l);
- ci::PkgQueryInterface pkg_query(pkgid, uid);
- if (pkg_query.IsPackageInstalled()) {
- LOG(INFO) << pkgid << " is installed for user " << std::get<0>(l);
- continue;
+ fs::path owner_apps_rw = std::get<2>(l) / "apps_rw";
+ std::vector<fs::path> apps_rw_paths;
+ apps_rw_paths.push_back(std::move(owner_apps_rw));
+
+ for (auto& lw_user : GetLightUserList(uid))
+ apps_rw_paths.push_back(std::get<2>(l) / kSubssesionDir / lw_user /
+ "apps_rw");
+
+ LOG(DEBUG) << "Deleting directories for user: " << uid;
+ for (auto& apps_rw : apps_rw_paths) {
+ if (!ci::RemoveAll(apps_rw / pkgid)) {
+ LOG(ERROR) << "Failed to delete storage directory for user: " << uid;
+ return false;
+ }
}
+ }
- LOG(DEBUG) << "Deleting directories of " << pkgid
- << ", for uid: " << std::get<0>(l);
- bf::path apps_rw(std::get<2>(l) / "apps_rw");
- if (!DeleteDirectories(apps_rw, pkgid)) {
- return false;
+ if (!ci::DeletePerUserSharedDataDir(pkgid)) {
+ LOG(ERROR) << "Failed to delete per user shared data dir";
+ return false;
+ }
+
+ return true;
+}
+
+bool CreateStorageDirectories(const fs::path& path,
+ const std::string& pkgid, uid_t uid,
+ bool trusted, bool shareddata) {
+ if (!::CreateStorageDirectories(path, pkgid, trusted,
+ shareddata, std::vector<const char*>())) {
+ LOG(ERROR) << "Failed to create storage directory for path: " << path;
+ return false;
+ }
+
+ if (!::SetPackageDirectoryOwnerAndPermissions(path / pkgid, uid))
+ return false;
+
+ if (shareddata) {
+ std::vector<std::string> shared_dirs(kSharedDataEntries);
+ for (const auto& entry : shared_dirs) {
+ fs::path shared_dst = path / entry / pkgid;
+ if (!::SetPackageDirectoryOwnerAndPermissions(shared_dst, uid))
+ return false;
}
}
+
+ std::string error_message;
+ if (!RegisterSecurityContextForPath(pkgid, path / pkgid, uid, false,
+ &error_message)) {
+ LOG(ERROR) << "Failed to register security context for path: " << path
+ << ", error_message: " << error_message;
+ return false;
+ }
+
return true;
}
+void RemoveRWDirectories(const fs::path& root) {
+ if (!RemoveAll(root / kCache))
+ LOG(ERROR) << "Failed to remove packaged cache directory";
+ if (!RemoveAll(root / kData))
+ LOG(ERROR) << "Failed to remove packaged data directory";
+ if (!RemoveAll(root / kSharedCacheDir))
+ LOG(ERROR) << "Failed to remove packaged shared/cache directory";
+ if (!RemoveAll(root / kSharedDataDir))
+ LOG(ERROR) << "Failed to remove packaged shared/data directory";
+ if (!RemoveAll(root / kSharedTrustedDir))
+ LOG(ERROR) << "Failed to remove packaged shared/trusted directory";
+}
+
+bool DeleteSharedDirectories(const fs::path& path,
+ const std::string& pkgid) {
+ return DeleteSharedDataDirectories(path, pkgid);
+}
+
bool DeleteUserExternalDirectories(const std::string& pkgid) {
UserList list = ci::GetUserList();
- for (auto l : list) {
+ for (const auto& l : list) {
uid_t uid = std::get<0>(l);
ci::PkgQueryInterface pkg_query(pkgid, uid);
if (pkg_query.IsPackageInstalled()) {
LOG(DEBUG) << "Deleting external directories of " << pkgid
<< ", for uid: " << uid;
- bf::path apps_rw(std::get<2>(l) / "apps_rw");
+ fs::path apps_rw(std::get<2>(l) / "apps_rw");
if (!DeleteDirectories(apps_rw, pkgid)) {
return false;
}
- }
- return true;
-}
-
-bool CopyUserDirectories(const std::string& pkgid) {
- UserList list = ci::GetUserList();
- for (auto l : list) {
- uid_t uid = std::get<0>(l);
- LOG(DEBUG) << "Copying directories for uid: " << uid;
- bf::path apps_rw(std::get<2>(l) / "apps_rw");
- bf::path src = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
- bf::path(kSkelAppDir) / pkgid;
- bf::path dst = apps_rw / pkgid;
- if (!ci::CopyDir(src, dst, FSFlag::FS_NONE, true))
- continue;
- gid_t gid = std::get<1>(l);
- if (!SetDirectoryOwnerAndPermissions(dst, uid, gid))
- return false;
- for (bf::recursive_directory_iterator iter(dst);
- iter != bf::recursive_directory_iterator(); ++iter) {
- if (!SetDirectoryOwnerAndPermissions(iter->path(),
- uid, gid))
+ for (auto& lw_user : GetLightUserList(uid)) {
+ fs::path apps_rw_lw(std::get<2>(l) / kSubssesionDir / lw_user / "apps_rw");
+ if (!DeleteDirectories(apps_rw_lw, pkgid))
return false;
}
- std::string error_message;
- if (!RegisterSecurityContextForPath(pkgid, dst, uid,
- false, &error_message)) {
- LOG(ERROR) << "Failed to register security context for path: " << dst
- << ", error_message: " << error_message;
- return false;
- }
}
- return true;
-}
-bool UpdateUserDirectory(const std::string& pkgid, bool is_remove_shareddata) {
- UserList list = ci::GetUserList();
- for (auto l : list) {
- bf::path apps_rw(std::get<2>(l) / "apps_rw");
- bf::path root_dst = apps_rw / pkgid;
- bf::path shareddir_dst = root_dst / kSharedDataDir;
- uid_t uid = std::get<0>(l);
- LOG(DEBUG) << ((is_remove_shareddata) ? "Deleting" : "Adding")
- << " shareddata directory for uid: " << uid;
-
- if (!is_remove_shareddata) {
- bs::error_code error;
- bf::create_directories(shareddir_dst, error);
- if (error && !bf::exists(shareddir_dst)) {
- LOG(ERROR) << "Failed to create directory: " << shareddir_dst;
- return false;
- }
-
- gid_t gid = std::get<1>(l);
- if (!SetDirectoryOwnerAndPermissions(root_dst, uid, gid))
- return false;
- for (bf::recursive_directory_iterator iter(root_dst);
- iter != bf::recursive_directory_iterator(); ++iter) {
- if (!SetDirectoryOwnerAndPermissions(iter->path(),
- uid, gid))
- return false;
- }
-
- std::string error_message;
- if (!RegisterSecurityContextForPath(pkgid, root_dst, uid,
- false, &error_message)) {
- LOG(ERROR) << "Failed to register security context for path: "
- << root_dst << ", error_message: " << error_message;
- return false;
- }
- } else {
- return ci::RemoveAll(shareddir_dst);
- }
- }
return true;
}
bool CreateGlobalAppSymlinksForAllUsers(const std::string& pkgid) {
- bf::path src_dir = bf::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
- if (!bf::exists(src_dir)) {
+ fs::path src_dir = fs::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
+ if (!fs::exists(src_dir)) {
LOG(ERROR) << "src_dir not exists";
return false;
}
- bool result = true;
UserList list = ci::GetUserList();
- for (auto l : list) {
+ for (const auto& l : list) {
uid_t uid = std::get<0>(l);
LOG(DEBUG) << "Creating symlinks for uid: " << uid;
// check installed user private app.
ci::PkgQueryInterface pkg_query(pkgid, uid);
if (pkg_query.IsPackageInstalled())
continue;
- bf::path apps_rw(std::get<2>(l) / "apps_rw");
- bf::path dst_dir = apps_rw / pkgid;
- if (!bf::exists(dst_dir)) {
- LOG(WARNING) << "dst_dir not exists";
- continue;
+
+ fs::path owner_apps_rw = std::get<2>(l) / "apps_rw";
+ std::vector<fs::path> apps_rw_paths;
+ apps_rw_paths.push_back(std::move(owner_apps_rw));
+
+ for (auto& lw_user : GetLightUserList(uid))
+ apps_rw_paths.push_back(std::get<2>(l) / kSubssesionDir / lw_user /
+ "apps_rw");
+
+ for (auto& apps_rw : apps_rw_paths) {
+ fs::path dst_dir = apps_rw / pkgid;
+ if (!fs::exists(dst_dir)) {
+ LOG(WARNING) << "dst_dir not exists";
+ continue;
+ }
+
+ if (!CreateSymlinkFiles(src_dir, dst_dir))
+ return false;
}
- result = CreateSymlinkFiles(src_dir, dst_dir);
}
- return result;
+
+ return true;
}
bool CreateGlobalAppSymlinksForUser(const std::string& pkgid, uid_t uid) {
- bf::path src_dir = bf::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
- if (!bf::exists(src_dir)) {
+ fs::path src_dir = fs::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
+ if (!fs::exists(src_dir)) {
LOG(WARNING) << "src_dir(" << src_dir << ") not exists";
return true;
}
tzplatform_set_user(uid);
- bf::path dst_dir = bf::path(tzplatform_getenv(TZ_USER_APP)) / pkgid;
+ fs::path dst_dir = fs::path(tzplatform_getenv(TZ_USER_APP)) / pkgid;
tzplatform_reset_user();
- if (!bf::exists(dst_dir)) {
+ if (!fs::exists(dst_dir)) {
LOG(WARNING) << "dst_dir not exists";
return true;
}
}
bool DeleteGlobalAppSymlinksForAllUsers(const std::string& pkgid) {
- bf::path src_dir = bf::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
- if (!bf::exists(src_dir)) {
+ fs::path src_dir = fs::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
+ if (!fs::exists(src_dir)) {
LOG(WARNING) << "src_dir(" << src_dir << ") not exists";
return true;
}
- bool result = true;
UserList list = ci::GetUserList();
- for (auto l : list) {
+ for (const auto& l : list) {
uid_t uid = std::get<0>(l);
LOG(DEBUG) << "Deleting symlinks for uid: " << uid;
+
// check installed user private app.
ci::PkgQueryInterface pkg_query(pkgid, uid);
if (pkg_query.IsPackageInstalled())
continue;
- bf::path apps_rw(std::get<2>(l) / "apps_rw");
- bf::path dst_dir = apps_rw / pkgid;
- if (!bf::exists(dst_dir)) {
- LOG(WARNING) << "dst_dir not exists";
- continue;
+
+ fs::path owner_apps_rw = std::get<2>(l) / "apps_rw";
+ std::vector<fs::path> apps_rw_paths;
+ apps_rw_paths.push_back(std::move(owner_apps_rw));
+ for (auto& lw_user : GetLightUserList(uid))
+ apps_rw_paths.push_back(std::get<2>(l) / kSubssesionDir / lw_user /
+ "apps_rw");
+
+ for (auto& apps_rw : apps_rw_paths) {
+ fs::path dst_dir = apps_rw / pkgid;
+ if (!fs::exists(dst_dir)) {
+ LOG(WARNING) << "dst_dir not exists";
+ continue;
+ }
+
+ if (!DeleteSymlinkFiles(src_dir, dst_dir))
+ return false;
}
- result = DeleteSymlinkFiles(src_dir, dst_dir);
}
- return result;
+
+ return true;
}
bool DeleteGlobalAppSymlinksForUser(const std::string& pkgid, uid_t uid) {
- bf::path src_dir = bf::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
- if (!bf::exists(src_dir)) {
+ fs::path src_dir = fs::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
+ if (!fs::exists(src_dir)) {
LOG(ERROR) << "src_dir not exists";
return false;
}
tzplatform_set_user(uid);
- bf::path dst_dir = bf::path(tzplatform_getenv(TZ_USER_APP)) / pkgid;
+ fs::path dst_dir = fs::path(tzplatform_getenv(TZ_USER_APP)) / pkgid;
tzplatform_reset_user();
- if (!bf::exists(dst_dir)) {
+ if (!fs::exists(dst_dir)) {
LOG(WARNING) << "dst_dir not exists";
return true;
}
return result;
}
-bool SetPackageDirectoryOwnerAndPermissions(const bf::path& path, uid_t uid) {
- boost::optional<gid_t> gid = ci::GetGidByUid(uid);
- if (!gid)
+bool SetPackageDirectoryOwnerAndPermissions(const fs::path& path, uid_t uid) {
+ return ::SetPackageDirectoryOwnerAndPermissions(path, uid);
+}
+
+bool ShouldSupportLegacySharedDataDir(const std::string& api_version) {
+ if (fs::exists(kDisableLegacySharedDataDirSupport))
return false;
- bf::perms perms644 =
- bf::owner_read | bf::owner_write | bf::group_read | bf::others_read;
- bf::perms perms755 =
- perms644 | bf::owner_exe | bf::group_exe | bf::others_exe;
- for (bf::recursive_directory_iterator iter(path);
- iter != bf::recursive_directory_iterator(); ++iter) {
- if (bf::is_symlink(symlink_status(iter->path())) ||
- (bf::is_directory(iter->path()) &&
- (iter->path().filename() == ".mmc" ||
- iter->path().filename() == ".pkg" ||
- iter->path().filename() == "tep"))) {
- // skip symlink or path which is related to
- // mount or directory installer creates
- continue;
- } else if (bf::is_directory(iter->path())) {
- // directories
- if (!SetDirectoryOwnerAndPermissions(iter->path(), uid, *gid))
+ utils::VersionNumber api_ver(api_version);
+ if (api_ver < ver30)
+ return true;
+ else
+ return false;
+}
+
+bool CreateSharedDataDir(const std::string& pkgid, uid_t uid) {
+ fs::path apps_rw = ci::GetRootAppPath(false, uid);
+ if (!CreateSharedDataDirectories(apps_rw, pkgid))
+ return false;
+
+ fs::path path = apps_rw / pkgid;
+ std::string error_message;
+ if (!ci::RegisterSecurityContextForPath(pkgid, path, uid, false,
+ &error_message)) {
+ LOG(ERROR) << "Failed to register security context for path: " << path
+ << ", error_message: " << error_message;
+ return false;
+ }
+
+ return true;
+}
+
+bool CreatePerUserSharedDataDir(const std::string& pkgid) {
+ // create skel dir
+ fs::path skel_apps_rw = fs::path(tzplatform_getenv(TZ_SYS_ETC)) /
+ fs::path(kSkelAppDir);
+ LOG(DEBUG) << "Creating directory : " << skel_apps_rw;
+ if (!CreateSharedDataDirectories(skel_apps_rw, pkgid))
+ return false;
+
+ std::string error_message;
+ if (!ci::RegisterSecurityContextForPath(pkgid, skel_apps_rw / pkgid,
+ kGlobalUserUid, false, &error_message)) {
+ LOG(ERROR) << "Failed to register security context for path: "
+ << skel_apps_rw / pkgid << ", error_message: " << error_message;
+ return false;
+ }
+
+ // create per user dir
+ ci::UserList list = ci::GetUserList();
+ for (const auto& l : list) {
+ uid_t uid = std::get<0>(l);
+ LOG(DEBUG) << "Adding shareddata directory for uid: " << uid;
+
+ fs::path owner_apps_rw = ci::GetRootAppPath(false, uid);
+ std::vector<fs::path> apps_rw_paths;
+ apps_rw_paths.push_back(std::move(owner_apps_rw));
+ for (auto& lw_user : GetLightUserList(uid))
+ apps_rw_paths.push_back(std::get<2>(l) / kSubssesionDir / lw_user /
+ "apps_rw");
+
+ for (auto& apps_rw : apps_rw_paths) {
+ if (!CreateSharedDataDirectories(apps_rw, pkgid))
return false;
- } else if (iter.level() == 1 &&
- iter->path().parent_path().filename() == "bin") {
- // bin files
- if (!SetDirOwnershipAndPermissions(iter->path(), perms755, uid, *gid))
+
+ std::vector<std::string> shared_dirs(kSharedDataEntries);
+ for (const auto& entry : shared_dirs) {
+ fs::path shared_dst = apps_rw / entry / pkgid;
+ if (!::SetPackageDirectoryOwnerAndPermissions(shared_dst, uid))
+ return false;
+ }
+
+ if (!ci::RegisterSecurityContextForPath(pkgid, apps_rw / pkgid, uid,
+ false, &error_message)) {
+ LOG(ERROR) << "Failed to register security context for path: "
+ << apps_rw / pkgid << ", error_message: " << error_message;
return false;
- } else {
- // other files
- if (!SetDirOwnershipAndPermissions(iter->path(), perms644, uid, *gid))
+ }
+ }
+ }
+
+ return true;
+}
+
+bool DeleteSharedDataDir(const std::string& pkgid, uid_t uid) {
+ fs::path apps_rw = ci::GetRootAppPath(false, uid);
+ return DeleteSharedDataDirectories(apps_rw, pkgid);
+}
+
+bool DeletePerUserSharedDataDir(const std::string& pkgid) {
+ fs::path skel_apps_rw = fs::path(tzplatform_getenv(TZ_SYS_ETC)) /
+ fs::path(kSkelAppDir);
+ if (!DeleteSharedDataDirectories(skel_apps_rw, pkgid))
+ return false;
+
+ ci::UserList list = ci::GetUserList();
+ for (const auto& l : list) {
+ uid_t uid = std::get<0>(l);
+
+ fs::path owner_apps_rw = ci::GetRootAppPath(false, uid);
+ std::vector<fs::path> apps_rw_paths;
+ apps_rw_paths.push_back(std::move(owner_apps_rw));
+ for (auto& lw_user : GetLightUserList(uid))
+ apps_rw_paths.push_back(std::get<2>(l) / kSubssesionDir / lw_user /
+ "apps_rw");
+
+ for (auto& apps_rw : apps_rw_paths) {
+ if (!DeleteSharedDataDirectories(apps_rw, pkgid))
return false;
}
}
return true;
}
+bool BackupSharedDataDir(const std::string& pkgid, uid_t uid) {
+ fs::path apps_rw = ci::GetRootAppPath(false, uid);
+ return BackupSharedDataDirectories(apps_rw, pkgid);
+}
+
+bool BackupPerUserSharedDataDir(const std::string& pkgid) {
+ fs::path skel_apps_rw = fs::path(tzplatform_getenv(TZ_SYS_ETC)) /
+ fs::path(kSkelAppDir);
+ if (!BackupSharedDataDirectories(skel_apps_rw, pkgid))
+ return false;
+
+ ci::UserList list = ci::GetUserList();
+ for (const auto& l : list) {
+ uid_t uid = std::get<0>(l);
+ fs::path owner_apps_rw = ci::GetRootAppPath(false, uid);
+ std::vector<fs::path> apps_rw_paths;
+ apps_rw_paths.push_back(std::move(owner_apps_rw));
+ for (auto& lw_user : GetLightUserList(uid))
+ apps_rw_paths.push_back(std::get<2>(l) / kSubssesionDir / lw_user /
+ "apps_rw");
+
+ for (auto& apps_rw : apps_rw_paths) {
+ if (!BackupSharedDataDirectories(apps_rw, pkgid))
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool RestoreSharedDataDir(const std::string& pkgid, uid_t uid) {
+ fs::path apps_rw = ci::GetRootAppPath(false, uid);
+ if (!RestoreSharedDataDirectories(apps_rw, pkgid))
+ return false;
+
+ if (!::SetPackageDirectoryOwnerAndPermissions(apps_rw / pkgid, uid))
+ return false;
+
+ std::vector<std::string> shared_dirs(kSharedDataEntries);
+ for (const auto& entry : shared_dirs) {
+ fs::path shared_dst = apps_rw / entry / pkgid;
+ if (!::SetPackageDirectoryOwnerAndPermissions(shared_dst, uid))
+ return false;
+ }
+
+ std::string error_message;
+ if (!RegisterSecurityContextForPath(pkgid, apps_rw / pkgid, uid, false,
+ &error_message)) {
+ LOG(ERROR) << "Failed to register security context for path: " << apps_rw
+ << ", error_message: " << error_message;
+ return false;
+ }
+
+ return true;
+}
+
+bool RestorePerUserSharedDataDir(const std::string& pkgid) {
+ fs::path skel_apps_rw = fs::path(tzplatform_getenv(TZ_SYS_ETC)) /
+ fs::path(kSkelAppDir);
+ if (!RestoreSharedDataDirectories(skel_apps_rw, pkgid))
+ return false;
+
+ std::string error_message;
+ ci::UserList list = ci::GetUserList();
+ for (const auto& l : list) {
+ uid_t uid = std::get<0>(l);
+ fs::path owner_apps_rw = ci::GetRootAppPath(false, uid);
+ std::vector<fs::path> apps_rw_paths;
+ apps_rw_paths.push_back(std::move(owner_apps_rw));
+ for (auto& lw_user : GetLightUserList(uid))
+ apps_rw_paths.push_back(std::get<2>(l) / kSubssesionDir / lw_user /
+ "apps_rw");
+
+ for (auto& apps_rw : apps_rw_paths) {
+ if (!RestoreSharedDataDirectories(apps_rw, pkgid))
+ return false;
+
+ if (!::SetPackageDirectoryOwnerAndPermissions(apps_rw / pkgid, uid))
+ return false;
+
+ std::vector<std::string> shared_dirs(kSharedDataEntries);
+ for (const auto& entry : shared_dirs) {
+ fs::path shared_dst = apps_rw / entry / pkgid;
+ if (!::SetPackageDirectoryOwnerAndPermissions(shared_dst, uid))
+ return false;
+ }
+
+ if (!RegisterSecurityContextForPath(pkgid, apps_rw / pkgid, uid,
+ false, &error_message)) {
+ LOG(ERROR) << "Failed to register security context for path: "
+ << apps_rw / pkgid << ", error_message: " << error_message;
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool RemoveBackupSharedDataDir(const std::string& pkgid, uid_t uid) {
+ fs::path apps_rw = ci::GetRootAppPath(false, uid);
+ return RemoveBackupSharedDataDirectories(apps_rw, pkgid);
+}
+
+bool RemoveBackupPerUserSharedDataDir(const std::string& pkgid) {
+ fs::path skel_apps_rw = fs::path(tzplatform_getenv(TZ_SYS_ETC)) /
+ fs::path(kSkelAppDir);
+ if (!RemoveBackupSharedDataDirectories(skel_apps_rw, pkgid))
+ return false;
+
+ ci::UserList list = ci::GetUserList();
+ for (const auto& l : list) {
+ uid_t uid = std::get<0>(l);
+ fs::path owner_apps_rw = ci::GetRootAppPath(false, uid);
+ std::vector<fs::path> apps_rw_paths;
+ apps_rw_paths.push_back(std::move(owner_apps_rw));
+ for (auto& lw_user : GetLightUserList(uid))
+ apps_rw_paths.push_back(std::get<2>(l) / kSubssesionDir / lw_user /
+ "apps_rw");
+
+ for (auto& apps_rw : apps_rw_paths) {
+ if (!RemoveBackupSharedDataDirectories(apps_rw, pkgid))
+ return false;
+ }
+ }
+
+ return true;
+}
+
} // namespace common_installer