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";
"http://tizen.org/privilege/externalstorage.appdata";
const char kSystemShareGroupName[] = "system_share";
-bool SetDirectoryOwnerAndPermissions(const bf::path& subpath, uid_t uid,
- gid_t gid) {
- // symlink and non directory will be skipped
- if (bf::is_symlink(symlink_status(subpath)) || !bf::is_directory(subpath))
- return true;
-
- bf::perms perms = bf::all_all ^ bf::group_write ^ bf::others_write;
- 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;
- }
- return common_installer::SetDirOwnershipAndPermissions(subpath, perms,
- uid, gid);
-}
+// the input path should be root directory of package.
+// for example: "../apps_rw/pkgid" or "../.shared/pkgid"
+bool SetPackageDirectoryOwnerAndPermissions(const bf::path& path, uid_t uid) {
+ boost::optional<gid_t> gid = ci::GetGidByUid(uid);
+ if (!gid)
+ return false;
-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;
+ bf::perms perms755 = bf::all_all ^ bf::group_write ^ bf::others_write;
+ bf::perms perms644 = perms755 ^ bf::group_exe ^ bf::others_exe;
+ bf::perms perms_setgid = perms755 | bf::set_gid_on_exe;
boost::optional<gid_t> system_share =
ci::GetGidByGroupName(kSystemShareGroupName);
- if (!system_share)
+ // root path
+ if (!ci::SetDirOwnershipAndPermissions(path, perms755, uid, *gid))
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*>
- 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;
- }
- }
-
- 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;
- }
- if (set_permissions) {
- if (!SetDirectoryOwnerAndPermissions(subpath, uid, gid))
+ for (bf::recursive_directory_iterator iter(path);
+ iter != bf::recursive_directory_iterator(); ++iter) {
+ if (bf::is_symlink(symlink_status(iter->path()))) {
+ // skip symlink path
+ continue;
+ } else if (bf::is_directory(iter->path()) && iter.level() == 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 (bf::is_directory(iter->path())) {
+ bool is_rw = false;
+ if (iter.level() == 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.level() == 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;
}
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)
- return false;
-
- std::string group_name = ci::GetGroupNameByGid(*gid);
- if (group_name != tzplatform_getenv(TZ_SYS_USER_GROUP))
- return false;
-
- LOG(DEBUG) << "Creating directories for uid: " << user << ", gid: "
- << *gid;
-
- bf::path apps_rw = GetDirectoryPathForStorage(user, apps_prefix);
- if (apps_rw.empty()) {
- LOG(DEBUG) << "Directory not exists: " << apps_rw;
- return false;
- }
-
- if (!CreateDirectories(apps_rw, pkgid,
- user, *gid, set_permissions)) {
- return false;
- }
- return true;
-}
-
bool DeleteSharedDataDirectories(const bf::path& path,
const std::string& pkgid) {
if (!ci::RemoveAll(path / pkgid / kSharedDataDir))
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 << ", error: "
- << error.message();
- return false;
- }
+ if (!ci::CreateDir(path)) {
+ LOG(ERROR) << "Failed to create dir: " << path;
+ return false;
}
std::vector<const char*> dirs(kEntries);
bs::error_code error;
for (auto& entry : dirs) {
bf::path subpath = path / entry;
- bf::create_directories(subpath, error);
- if (error && !bf::exists(subpath)) {
+ if (!ci::CreateDir(subpath)) {
LOG(ERROR) << "Failed to create directory: " << subpath;
return false;
}
return true;
}
+bool CreateExternalUserDirectories(uid_t user, const std::string& pkgid,
+ const std::string& apps_prefix) {
+ boost::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;
+
+ bf::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 {
const std::string& pkgid) {
bf::path storage_path = GetExternalCardPath();
- const bool set_permissions = false;
if (!bf::exists(storage_path)) {
LOG(WARNING) << "External storage (SD Card) is not mounted.";
return false;
}
}
- CreateUserDirectories(user, pkgid,
- storage_apps_path.c_str(), set_permissions);
+ if (CreateExternalUserDirectories(user, pkgid, storage_apps_path.string()))
+ return false;
+
return true;
}
return true;
}
+bool CreatePerUserStorageDirectories(const std::string& pkgid, bool trusted,
+ bool shareddata, bool is_readonly,
+ const std::vector<const char*> additional_dirs) {
+ // create skel dir
+ bf::path skel_apps_rw = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
+ bf::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, 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;
+ }
+
+ // create per user dir
+ UserList list = ci::GetUserList();
+ for (auto l : list) {
+ uid_t uid = std::get<0>(l);
+ bf::path apps_rw = std::get<2>(l) / "apps_rw";
+ LOG(DEBUG) << "Creating directories for user: " << uid;
+ if (!::CreateStorageDirectories(apps_rw, pkgid, trusted, shareddata,
+ additional_dirs)) {
+ LOG(ERROR) << "Failed to create storage directory for user: " << uid;
+ return false;
+ }
+
+ if (!::SetPackageDirectoryOwnerAndPermissions(apps_rw / pkgid, uid))
+ return false;
+
+ if (shareddata) {
+ std::vector<std::string> shared_dirs(kSharedDataEntries);
+ for (auto entry : shared_dirs) {
+ bf::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 DeletePerUserStorageDirectories(const std::string& pkgid) {
+ // delete skel dir
+ bf::path skel_apps_rw = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
+ bf::path(kSkelAppDir);
+ if (!ci::RemoveAll(skel_apps_rw / pkgid)) {
+ LOG(ERROR) << "Failed to delete skeleton storage directories";
+ return false;
+ }
+
+ // delete per user dir
+ UserList list = ci::GetUserList();
+ for (auto l : list) {
+ uid_t uid = std::get<0>(l);
+ bf::path apps_rw = std::get<2>(l) / "apps_rw";
+ LOG(DEBUG) << "Deleting directories for user: " << uid;
+ if (!ci::RemoveAll(apps_rw / pkgid)) {
+ LOG(ERROR) << "Failed to delete storage directory for user: " << uid;
+ return false;
+ }
+
+ if (!ci::DeletePerUserSharedDataDir(pkgid)) {
+ LOG(ERROR) << "Failed to delete per user shared data dir";
+ return false;
+ }
+ }
+
+ return true;
+}
+
bool CreateStorageDirectories(const boost::filesystem::path& path,
const std::string& pkgid, uid_t uid,
bool trusted, bool shareddata) {
return false;
}
+ if (!::SetPackageDirectoryOwnerAndPermissions(path / pkgid, uid))
+ return false;
+
std::string error_message;
if (!RegisterSecurityContextForPath(pkgid, path / pkgid, uid, false,
&error_message)) {
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 root_path = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
- bf::path(kSkelAppDir);
-
- 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, root_path / pkgid, kGlobalUserUid,
- is_readonly, &error_message)) {
- 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, root_path / pkgid);
- }
-
- return result;
-}
-
-bool DeleteSkelDirectories(const std::string& pkgid) {
- bf::path path = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
- bf::path(kSkelAppDir);
- if (!DeleteDirectories(path, pkgid))
- return false;
-
- return DeleteSharedDataDirectories(
- bf::path(tzplatform_getenv(TZ_SYS_ETC)) / bf::path(kSkelAppDir), pkgid);
-}
-
-
-bool DeleteUserDirectories(const std::string& pkgid) {
- UserList list = ci::GetUserList();
- for (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;
- }
-
- 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;
- }
- }
- return true;
-}
-
bool DeleteUserExternalDirectories(const std::string& pkgid) {
UserList list = ci::GetUserList();
for (auto l : list) {
return true;
}
-bool CopyUserDirectories(const std::string& 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, false))
- continue;
-
- 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);
- iter != bf::recursive_directory_iterator(); ++iter) {
- if (!SetDirectoryOwnerAndPermissions(iter->path(),
- uid, gid))
- 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 CreateGlobalAppSymlinksForAllUsers(const std::string& pkgid) {
bf::path src_dir = bf::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
if (!bf::exists(src_dir)) {
}
bool SetPackageDirectoryOwnerAndPermissions(const bf::path& path, uid_t uid) {
- boost::optional<gid_t> gid = ci::GetGidByUid(uid);
- if (!gid)
- 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))
- return false;
- } else if (iter.level() == 1 &&
- iter->path().parent_path().filename() == "bin") {
- // bin files
- if (!SetDirOwnershipAndPermissions(iter->path(), perms755, uid, *gid))
- return false;
- } else {
- // other files
- if (!SetDirOwnershipAndPermissions(iter->path(), perms644, uid, *gid))
- return false;
- }
- }
- return true;
+ return ::SetPackageDirectoryOwnerAndPermissions(path, uid);
}
bool ShouldSupportLegacySharedDataDir(const std::string& api_version) {
ci::UserList list = ci::GetUserList();
for (auto l : list) {
uid_t uid = std::get<0>(l);
- uid_t gid = std::get<1>(l);
LOG(DEBUG) << "Adding shareddata directory for uid: " << uid;
bf::path apps_rw = ci::GetRootAppPath(false, uid);
std::vector<std::string> shared_dirs(kSharedDataEntries);
for (auto entry : shared_dirs) {
bf::path shared_dst = apps_rw / entry / pkgid;
- if (!SetDirectoryOwnerAndPermissions(shared_dst, uid, gid))
- return false;
- }
-
- for (bf::recursive_directory_iterator iter(apps_rw / pkgid);
- iter != bf::recursive_directory_iterator(); ++iter) {
- if (!SetSharedDirOwnerAndPermissions(iter->path(), uid))
+ if (!::SetPackageDirectoryOwnerAndPermissions(shared_dst, uid))
return false;
}
bool PerformExternalDirectoryDeletionForAllUsers(const std::string& pkgid);
/**
- * \brief Creates storage directories in path
+ * \brief Creates per user storage directories in path
*
- * \param path base path, where storage directories will be created in
* \param pkgid package id
- * \param uid user id
* \param trusted signed package flag
* \param shareddata shared data privilege flag
+ * \param is_readonly readonly flag
+ * \param additional_dirs additional directories vector
*
* \return true if succeed, false otherwise
*/
-bool CreateStorageDirectories(const boost::filesystem::path& path,
- const std::string& pkgid, uid_t uid,
- bool trusted, bool shareddata);
-
-/**
- * \brief Deletes storage directories in path
- *
- * \param path base path, which contains storage directories
- * \param pkgid package id
- *
- * \return true if succeed, false otherwise
- */
-bool DeleteStorageDirectories(const boost::filesystem::path& path,
- const std::string& pkgid);
-
-/**
- * \brief Deletes shared directories in path
- *
- * \param path base path, which containsshared directories
- * \param pkgid package id
- *
- * \return true if succeed, false otherwise
- */
-bool DeleteSharedDirectories(const boost::filesystem::path& path,
- const std::string& pkgid);
+bool CreatePerUserStorageDirectories(const std::string& pkgid,
+ bool trusted, bool shareddata,
+ bool is_readonly,
+ const std::vector<const char*>
+ additional_dirs = std::vector<const char*>());
/**
- * \brief Create skeleton directories for package
+ * \brief Creates storage directories in path
*
+ * \param path base path, where storage directories will be created in
* \param pkgid package id
+ * \param uid user id
* \param trusted signed package flag
* \param shareddata shared data privilege flag
- * \param is_readonly readonly flag
- * \param additional_dirs additional directories vector
- *
- * \return bool true if succeed, false otherwise
*
+ * \return true if succeed, false otherwise
*/
-bool CreateSkelDirectories(const std::string& pkgid,
- bool trusted, bool shareddata, bool is_readonly,
- const std::vector<const char*>
- additional_dirs = std::vector<const char*>());
+bool CreateStorageDirectories(const boost::filesystem::path& path,
+ const std::string& pkgid, uid_t uid,
+ bool trusted, bool shareddata);
/**
- * \brief Performs deletion of directories
+ * \brief Deletes per user storage directories in path
*
* \param pkgid package id
*
* \return true if succeed, false otherwise
- *
*/
-bool DeleteSkelDirectories(const std::string& pkgid);
+bool DeletePerUserStorageDirectories(const std::string& pkgid);
/**
- * \brief Delete per-user directories
+ * \brief Deletes storage directories in path
*
+ * \param path base path, which contains storage directories
* \param pkgid package id
*
* \return true if succeed, false otherwise
- *
*/
-bool DeleteUserDirectories(const std::string& pkgid);
+bool DeleteStorageDirectories(const boost::filesystem::path& path,
+ const std::string& pkgid);
/**
- * \brief Copy per-user directories
+ * \brief Deletes shared directories in path
*
+ * \param path base path, which containsshared directories
* \param pkgid package id
*
- * \return bool true if succeed, false otherwise
- *
+ * \return true if succeed, false otherwise
*/
-bool CopyUserDirectories(const std::string& pkgid);
+bool DeleteSharedDirectories(const boost::filesystem::path& path,
+ const std::string& pkgid);
/**
* \brief Returns path prefix for internal storage, typically '/home'