{"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 kSharedDir[] = ".shared";
+const char kSharedTmpDir[] = ".shared_tmp";
const char kSharedTrustedDir[] = "shared/trusted";
const char kSkelAppDir[] = "skel/apps_rw";
const char kExternalStoragePrivilege[] =
uid, gid);
}
+bool SetSharedDirOwnerAndPermissions(const bf::path& subpath, uid_t uid) {
+ if (!bf::is_directory(subpath) || subpath.filename() != "data")
+ return true;
+ bf::perms perms = (bf::all_all | bf::set_uid_on_exe) ^ bf::others_write;
+ boost::optional<gid_t> system_share =
+ ci::GetGidByGroupName(kSystemShareGroupName);
+ if (!system_share)
+ return false;
+ gid_t gid = *system_share;
+
+ return common_installer::SetDirOwnershipAndPermissions(subpath, perms,
+ uid, gid);
+}
+
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*>
return true;
}
+bool DeleteSharedDataDirectories(const bf::path& path,
+ const std::string& pkgid) {
+ if (!ci::Remove(path / pkgid / kSharedDataDir))
+ return false;
+
+ std::vector<std::string> shared_dirs(kSharedDataEntries);
+ for (auto entry : shared_dirs) {
+ if (!ci::RemoveAll(path / entry / pkgid))
+ return false;
+ }
+
+ return true;
+}
+
+bool CreateSharedDataDirectories(const bf::path& path,
+ const std::string& pkgid) {
+ if (!ci::CreateDir(path / kSharedDir / pkgid / kData) ||
+ !ci::CreateDir(path / kSharedTmpDir / pkgid))
+ return false;
+
+ bf::current_path(path / pkgid / kShared);
+ if (bf::exists(path / pkgid / kShared / kData))
+ return true;
+ bf::path relative_path = ci::RelativePath(path / kSharedDir / pkgid / kData,
+ bf::current_path() / kData);
+ bs::error_code error;
+ bf::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);
+ 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<std::string> rofiles(kReadOnlyEntries);
for (bf::directory_iterator file(src_dir);
return true;
}
-bool CreateStorageDirectories(const boost::filesystem::path& path,
+bool CreateStorageDirectories(const boost::filesystem::path& root_path,
+ const std::string& pkgid,
bool trusted, bool shareddata,
const std::vector<const char*> additional_dirs) {
+ bf::path path(root_path / pkgid);
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;
+ LOG(ERROR) << "Failed to create directory: "
+ << path << ", error: "
+ << error.message();
return false;
}
}
dirs.insert(dirs.end(), additional_dirs.begin(), additional_dirs.end());
if (trusted)
dirs.push_back(kSharedTrustedDir);
- if (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;
- }
+
+ bs::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)) {
}
}
+ if (shareddata) {
+ if (!CreateSharedDataDirectories(root_path, pkgid))
+ return false;
+ } else {
+ if (!DeleteSharedDataDirectories(root_path, pkgid))
+ return false;
+ }
+
bf::path shared_cache_path = path / kSharedCacheDir;
// remove shared/cache (do not support)
if (!ci::RemoveAll(shared_cache_path))
bool CreateStorageDirectories(const boost::filesystem::path& path,
const std::string& pkgid, uid_t uid,
bool trusted, bool shareddata) {
- if (!::CreateStorageDirectories(path, trusted, shareddata,
- std::vector<const char*>())) {
+ if (!::CreateStorageDirectories(path, pkgid, trusted,
+ shareddata, std::vector<const char*>())) {
LOG(ERROR) << "Failed to create storage directory for path: " << path;
return false;
}
return true;
}
-bool DeleteStorageDirectories(const boost::filesystem::path& path) {
+bool DeleteStorageDirectories(const boost::filesystem::path& path,
+ const std::string& pkgid) {
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;
+ bf::path subpath = path / pkgid / entry;
if (!ci::RemoveAll(subpath))
return false;
}
+ if (!DeleteSharedDataDirectories(path, pkgid))
+ return false;
+
return true;
}
+bool DeleteSharedDirectories(const bf::path& path,
+ const std::string& pkgid) {
+ return DeleteSharedDataDirectories(path, pkgid);
+}
+
bool CreateSkelDirectories(const std::string& pkgid,
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;
+ bf::path root_path = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
+ bf::path(kSkelAppDir);
- if (!::CreateStorageDirectories(path, trusted, shareddata,
- additional_dirs)) {
- LOG(ERROR) << "Failed to create storage directory for path: " << path;
+ if (!::CreateStorageDirectories(root_path, pkgid, trusted,
+ shareddata, additional_dirs)) {
+ LOG(ERROR) << "Failed to create storage directory for path: "
+ << root_path / pkgid;
return false;
}
std::string error_message;
- if (!RegisterSecurityContextForPath(pkgid, path, kGlobalUserUid,
+ if (!RegisterSecurityContextForPath(pkgid, root_path / pkgid, kGlobalUserUid,
is_readonly, &error_message)) {
- LOG(ERROR) << "Failed to register security context for path: " << path
+ LOG(ERROR) << "Failed to register security context for path: "
+ << root_path / 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);
+ result = CreateSymlinkFiles(src_dir, root_path / pkgid);
}
return result;
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;
+ bf::path root_path = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
+ bf::path(kSkelAppDir);
LOG(DEBUG) << ((is_remove_shareddata) ? "Removing" : "Creating")
- << " directory : " << shared_data_path;
-
- if (!is_remove_shareddata) {
- if (!CreateDir(shared_data_path))
+ << " skel directory for pkgid: " << pkgid;
+ if (is_remove_shareddata) {
+ if (!DeleteSharedDataDirectories(root_path, pkgid))
return false;
+ return true;
+ }
- 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;
- }
- } else {
- return ci::RemoveAll(shared_data_path);
+ if (!CreateSharedDataDirectories(root_path, pkgid))
+ return false;
+
+ std::string error_message;
+ if (!RegisterSecurityContextForPath(pkgid, root_path / pkgid, kGlobalUserUid,
+ false, &error_message)) {
+ LOG(ERROR) << "Failed to register security context for path: "
+ << root_path / pkgid
+ << ", error_message: " << error_message;
+ return false;
}
+
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);
+ if (!DeleteDirectories(path, pkgid))
+ return false;
+
+ return DeleteSharedDataDirectories(
+ bf::path(tzplatform_getenv(TZ_SYS_ETC)) / bf::path(kSkelAppDir), pkgid);
}
UserList list = ci::GetUserList();
for (auto l : list) {
uid_t uid = std::get<0>(l);
+ gid_t gid = std::get<1>(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))
+ if (!ci::CopyDir(src, dst, FSFlag::FS_NONE, false))
continue;
- gid_t gid = std::get<1>(l);
+
+ std::vector<std::string> shared_dirs(kSharedDataEntries);
+ for (auto entry : shared_dirs) {
+ bf::path shared_src = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
+ bf::path(kSkelAppDir) / entry / pkgid;
+ if (!bf::exists(shared_src))
+ break;
+
+ bf::path shared_dst = apps_rw / entry / pkgid;
+ if (!ci::CopyDir(shared_src, shared_dst, FSFlag::FS_NONE, true))
+ continue;
+
+ if (!SetDirectoryOwnerAndPermissions(shared_dst, uid, gid))
+ return false;
+
+ for (bf::recursive_directory_iterator iter(dst);
+ iter != bf::recursive_directory_iterator(); ++iter) {
+ if (!SetSharedDirOwnerAndPermissions(iter->path(), uid))
+ return false;
+ }
+ }
+
if (!SetDirectoryOwnerAndPermissions(dst, uid, gid))
return false;
for (bf::recursive_directory_iterator iter(dst);
return true;
}
+bool CreateSharedData(const bf::path& path,
+ const std::string& pkgid) {
+ return CreateSharedDataDirectories(path, pkgid);
+}
+
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;
+ bf::path root_path(std::get<2>(l) / "apps_rw");
+ bf::path pkg_path(root_path / pkgid);
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;
- }
+ if (is_remove_shareddata)
+ return DeleteSharedDataDirectories(root_path, pkgid);
+
+ if (!CreateSharedDataDirectories(root_path, pkgid)) {
+ LOG(ERROR) << "Failed to create shared directory: "
+ << root_path / pkgid;
+ return false;
+ }
- gid_t gid = std::get<1>(l);
- if (!SetDirectoryOwnerAndPermissions(root_dst, uid, gid))
+ gid_t gid = std::get<1>(l);
+ std::vector<std::string> shared_dirs(kSharedDataEntries);
+ for (auto entry : shared_dirs) {
+ bf::path dst = root_path / entry / pkgid;
+ if (!SetDirectoryOwnerAndPermissions(dst, uid, gid))
return false;
- for (bf::recursive_directory_iterator iter(root_dst);
+ for (bf::recursive_directory_iterator iter(dst);
iter != bf::recursive_directory_iterator(); ++iter) {
- if (!SetDirectoryOwnerAndPermissions(iter->path(),
- uid, gid))
+ if (!SetSharedDirOwnerAndPermissions(iter->path(), uid))
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;
+ if (!SetDirectoryOwnerAndPermissions(pkg_path, uid, gid))
+ return false;
+ for (bf::recursive_directory_iterator iter(pkg_path);
+ iter != bf::recursive_directory_iterator(); ++iter) {
+ if (!SetDirectoryOwnerAndPermissions(iter->path(),
+ uid, gid))
return false;
- }
- } else {
- return ci::RemoveAll(shareddir_dst);
+ }
+
+ std::string error_message;
+ if (!RegisterSecurityContextForPath(pkgid, pkg_path, uid,
+ false, &error_message)) {
+ LOG(ERROR) << "Failed to register security context for path: "
+ << pkg_path << ", error_message: " << error_message;
+ return false;
}
}
return true;