step/filesystem/step_copy_tep.cc
step/filesystem/step_create_icons.cc
step/filesystem/step_create_per_user_storage_directories.cc
+ step/filesystem/step_create_legacy_directories.cc
step/filesystem/step_create_storage_directories.cc
step/filesystem/step_delta_patch.cc
step/filesystem/step_move_installed_storage.cc
step/filesystem/step_remove_files.cc
step/filesystem/step_remove_icons.cc
step/filesystem/step_remove_per_user_storage_directories.cc
+ step/filesystem/step_remove_legacy_directories.cc
step/filesystem/step_remove_temporary_directory.cc
step/filesystem/step_remove_tep.cc
step/filesystem/step_remove_zip_image.cc
return true;
}
+bool RequestCreateLegacyDirectories(const std::string& pkgid) {
+ RequestUserDirectoryOperation("CreateLegacyDirs", pkgid);
+ return true;
+}
+
+bool RequestDeleteLegacyDirectories(const std::string& pkgid) {
+ RequestUserDirectoryOperation("DeleteLegacyDirs", pkgid);
+ return true;
+}
+
} // namespace common_installer
*/
bool RequestDeleteExternalDirectories(const std::string& pkgid);
+/**
+ * \brief Request to create legacy directories
+ *
+ * \param pkgid package id
+ *
+ * \return bool true if succeed, false otherwise
+ */
+bool RequestCreateLegacyDirectories(const std::string& pkgid);
+
+/**
+ * \brief Request to delete legacy directories
+ *
+ * \param pkgid package id
+ *
+ * \return bool true if succeed, false otherwise
+ */
+bool RequestDeleteLegacyDirectories(const std::string& pkgid);
+
} // namespace common_installer
#endif // COMMON_PKGDIR_TOOL_REQUEST_H_
};
const char kSharedDataDir[] = "shared/data";
-const char kTrustedDir[] = "shared/trusted";
+const char kSharedTrustedDir[] = "shared/trusted";
const char kSkelAppDir[] = "/etc/skel/apps_rw";
+const char kLegacyAppDir[] = "/opt/usr/apps";
const char kPackagePattern[] = R"(^[0-9a-zA-Z_-]+(\.?[0-9a-zA-Z_-]+)*$)";
const int32_t kPWBufSize = sysconf(_SC_GETPW_R_SIZE_MAX);
const int32_t kGRBufSize = sysconf(_SC_GETGR_R_SIZE_MAX);
ci::PkgList GetAllGlobalAppsInformation() {
ci::PkgList pkgs;
if (pkgmgrinfo_pkginfo_get_usr_list(&PkgmgrListCallback,
- &pkgs, tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)) != PMINFO_R_OK) {
+ &pkgs, GLOBAL_USER) != PMINFO_R_OK) {
LOG(ERROR) << "Failed to query global application list";
return {};
}
return pkgs;
}
-bool SetPackageDirectoryOwnerAndPermissions(const bf::path& subpath, uid_t uid,
- gid_t gid) {
+bool SetOwnerAndPermissions(const bf::path& subpath, uid_t uid,
+ gid_t gid, bf::perms perms) {
bs::error_code error;
- bf::perms perms = bf::owner_read |
- bf::owner_write |
- bf::group_read;
- if (bf::is_directory(subpath)) {
- perms |= bf::owner_exe | bf::group_exe | bf::others_exe;
- }
bf::permissions(subpath, perms, error);
if (error) {
LOG(ERROR) << "Failed to set permissions for: " << subpath;
return true;
}
+bool SetPackageDirectoryOwnerAndPermissions(const bf::path& subpath, uid_t uid,
+ gid_t gid) {
+ bs::error_code error;
+ bf::perms perms = bf::owner_read |
+ bf::owner_write |
+ bf::group_read;
+ if (bf::is_directory(subpath))
+ perms |= bf::owner_exe | bf::group_exe | bf::others_exe;
+
+ return SetOwnerAndPermissions(subpath, uid, gid, perms);
+}
+
+bool SetLegacyDirectoryOwnerAndPermissions(const bf::path& subpath) {
+ bs::error_code error;
+ bf::perms perms = bf::owner_read |
+ bf::owner_write |
+ bf::group_read |
+ bf::others_read;
+ if (bf::is_directory(subpath))
+ perms |= bf::owner_exe | bf::group_exe | bf::others_exe;
+
+ return SetOwnerAndPermissions(subpath, GLOBAL_USER,
+ tzplatform_getgid(TZ_SYS_GLOBALAPP_USER),
+ perms);
+}
+
bool CreateDirectories(const bf::path& app_dir, const std::string& pkgid,
bool trusted,
uid_t uid, gid_t gid, const bool set_permissions) {
bs::error_code error;
std::vector<const char*> dirs(kEntries);
if (trusted)
- dirs.push_back(kTrustedDir);
+ dirs.push_back(kSharedTrustedDir);
for (auto& entry : dirs) {
bf::path subpath = base_dir / entry;
bf::create_directories(subpath, error);
std::vector<const char*> dirs(kEntries);
if (trusted)
- dirs.push_back(kTrustedDir);
+ dirs.push_back(kSharedTrustedDir);
if (api_ver < ver30) {
dirs.push_back(kSharedDataDir);
}
}
std::string error_message;
- if (!RegisterSecurityContextForPath(pkgid, path,
- tzplatform_getuid(TZ_SYS_GLOBALAPP_USER), false, &error_message)) {
+ if (!RegisterSecurityContextForPath(pkgid, path, GLOBAL_USER,
+ false, &error_message)) {
LOG(ERROR) << "Failed to register security context for path: " << path
<< ", error_message: " << error_message;
return false;
GetAllGlobalAppsInformation() : GetPkgInformation(uid, *pkgs.begin());
}
+bool CreateLegacyDirectories(const std::string& pkgid) {
+ // create lagcay directories for backward compatibility
+ bs::error_code error;
+ bf::path path = bf::path(kLegacyAppDir) / pkgid;
+ bf::create_directories(path, error);
+ if (error && !bf::exists(path)) {
+ LOG(ERROR) << "Failed to create directory: " << path;
+ return false;
+ }
+
+ std::vector<const char*> dirs(kEntries);
+ dirs.push_back(kSharedTrustedDir);
+ dirs.push_back(kSharedDataDir);
+ for (auto& entry : dirs) {
+ bf::path subpath = path / entry;
+ bf::create_directories(subpath, error);
+ if (error && !bf::exists(subpath)) {
+ LOG(ERROR) << "Failed to create directory: " << subpath;
+ return false;
+ }
+ if (!SetLegacyDirectoryOwnerAndPermissions(subpath)) {
+ LOG(ERROR) << "Failed to set permission: " << subpath;
+ return false;
+ }
+ }
+
+ std::string error_message;
+ if (!RegisterSecurityContextForPath(pkgid, path, GLOBAL_USER,
+ false, &error_message)) {
+ LOG(ERROR) << "Failed to register security context for path: " << path
+ << ", error_message: " << error_message;
+ return false;
+ }
+
+ return true;
+}
+
+bool DeleteLegacyDirectories(uid_t uid, const std::string& pkgid) {
+ bool del_flag = true;
+ uid_t chk_uid;
+
+ user_list list = GetUserList();
+ if (list.empty())
+ return true;
+ for (auto l : list) {
+ chk_uid = std::get<0>(l);
+ if (chk_uid == uid)
+ continue;
+ LOG(DEBUG) << "Check package existence for uid: " << chk_uid;
+ if (QueryIsPackageInstalled(pkgid, chk_uid)) {
+ LOG(DEBUG) << "Package: " << pkgid << " for uid: " << chk_uid
+ << " still exists.";
+ del_flag = false;
+ break;;
+ }
+ }
+
+ if (del_flag && uid != GLOBAL_USER) {
+ if (QueryIsPackageInstalled(pkgid, GLOBAL_USER)) {
+ LOG(DEBUG) << "Package: " << pkgid << " for uid: " << GLOBAL_USER
+ << " still exists.";
+ del_flag = false;
+ }
+ }
+
+ if (del_flag) {
+ LOG(DEBUG) << "Delete legacy directories for package: " << pkgid;
+ DeleteDirectories(bf::path(kLegacyAppDir), pkgid);
+ }
+
+ return true;
+}
+
} // namespace common_installer
*/
std::string GetDirectoryPathForExternalStorage();
+/**
+ * \brief Create Legacy directories
+ *
+ * \param uid user id
+ * \param pkgid package id
+ *
+ * \return true if succeed, false otherwise
+ *
+ */
+bool CreateLegacyDirectories(const std::string& pkgid);
+
+/**
+ * \brief Delete Legacy directories
+ *
+ * \param pkgid package id
+ *
+ * \return true if succeed, false otherwise
+ *
+ */
+bool DeleteLegacyDirectories(uid_t uid, const std::string& pkgid);
+
} // namespace common_installer
#endif // COMMON_SHARED_DIRS_H_
--- /dev/null
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache 2.0 license that can be
+// found in the LICENSE file.
+
+#include "common/step/filesystem/step_create_legacy_directories.h"
+
+#include <string>
+
+#include "common/pkgdir_tool_request.h"
+#include "common/shared_dirs.h"
+
+namespace common_installer {
+namespace filesystem {
+
+common_installer::Step::Status StepCreateLegacyDirectories::process() {
+ std::string package_id = context_->pkgid.get();
+
+ LOG(INFO) << "Creating legacy directories for package: " << package_id;
+ common_installer::RequestCreateLegacyDirectories(package_id);
+
+ return Status::OK;
+}
+
+} // namespace filesystem
+} // namespace common_installer
--- /dev/null
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache 2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef COMMON_STEP_FILESYSTEM_STEP_CREATE_LEGACY_DIRECTORIES_H_
+#define COMMON_STEP_FILESYSTEM_STEP_CREATE_LEGACY_DIRECTORIES_H_
+
+#include <manifest_parser/utils/logging.h>
+
+#include "common/step/step.h"
+
+namespace common_installer {
+namespace filesystem {
+
+/**
+ * \brief Installation.
+ * Responsible for creating RW directoires under legacy app-root
+ * for backward compatibility. (wgt/tpk)
+ *
+ * * process method implements creation of data and shared directories
+ * under /opt/usr/apps.
+ *
+ * * Other methods are empty.
+ */
+class StepCreateLegacyDirectories : public common_installer::Step {
+ public:
+ using Step::Step;
+
+ Status process() override;
+ Status clean() override { return Status::OK; }
+ Status undo() override { return Status::OK; }
+ Status precheck() override { return Status::OK; }
+
+ STEP_NAME(CreateLegacyDirectories)
+};
+
+} // namespace filesystem
+} // namespace common_installer
+
+#endif // COMMON_STEP_FILESYSTEM_STEP_CREATE_LEGACY_DIRECTORIES_H_
namespace bf = boost::filesystem;
namespace {
+const char kSharedRes[] = "shared/res";
bool SkipDirectoryIfGlobal(const bf::path& path) {
static const std::vector<std::string> dirs_to_ignore = {
{"cache"},
if (context_->external_storage)
context_->external_storage->Commit();
- if (QueryIsPackageInstalled(context_->pkgid.get(), GLOBAL_USER)) {
+ // If global package, then some RW directories won't be removed here,
+ // instead, following StepRemoveLegacyDirectories will check and remove them.
+ if (QueryIsPackageInstalled(context_->pkgid.get(), GLOBAL_USER) ||
+ context_->uid.get() == GLOBAL_USER) {
for (bf::directory_iterator itr(pkg_path); itr != bf::directory_iterator();
++itr) {
if (bf::is_directory(itr->status())) {
bf::remove_all(itr->path(), error);
}
}
+ // The shared/res will be removed if it exists.
+ bf::path shared_res_path = pkg_path / kSharedRes;
+ bf::remove_all(shared_res_path, error);
} else {
bf::remove_all(pkg_path, error);
if (error) {
--- /dev/null
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a apache 2.0 license that can be
+// found in the LICENSE file.
+
+#include "common/step/filesystem/step_remove_legacy_directories.h"
+
+#include <string>
+
+#include "common/installer_context.h"
+#include "common/pkgdir_tool_request.h"
+
+namespace common_installer {
+namespace filesystem {
+
+Step::Status StepRemoveLegacyDirectories::process() {
+ std::string package_id = context_->pkgid.get();
+
+ common_installer::RequestDeleteLegacyDirectories(package_id);
+
+ return Step::Status::OK;
+}
+
+} // namespace filesystem
+} // namespace common_installer
+
--- /dev/null
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache 2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef COMMON_STEP_FILESYSTEM_STEP_REMOVE_LEGACY_DIRECTORIES_H_
+#define COMMON_STEP_FILESYSTEM_STEP_REMOVE_LEGACY_DIRECTORIES_H_
+
+#include <manifest_parser/utils/logging.h>
+
+#include "common/step/step.h"
+
+namespace common_installer {
+namespace filesystem {
+
+/**
+ * \brief Uninstallation.
+ * Responsible for removing RW directoires under legacy app-root
+ * (wgt/tpk)
+ *
+ * * process method implements removal of data and shared directories
+ * under /opt/usr/apps.
+ *
+ * * Other methods are empty.
+ *
+ */
+
+class StepRemoveLegacyDirectories : public common_installer::Step {
+ public:
+ using Step::Step;
+
+ Status process() override;
+ Status clean() override { return Status::OK; }
+ Status undo() override { return Status::OK; }
+ Status precheck() override { return Status::OK; }
+
+ STEP_NAME(RemoveLegacyDirectories)
+};
+
+} // namespace filesystem
+} // namespace common_installer
+
+#endif // COMMON_STEP_FILESYSTEM_STEP_REMOVE_LEGACY_DIRECTORIES_H_
<busconfig>
<policy user="root">
<allow own="org.tizen.pkgdir_tool"/>
- <allow send_destination="org.tizen.pkgdir_tool"/>
</policy>
- <policy user="tizenglobalapp">
- <allow send_destination="org.tizen.pkgdir_tool"/>
+ <policy user="app_fw">
+ <allow own="org.tizen.pkgdir_tool"/>
</policy>
<policy context="default">
- <deny send_destination="org.tizen.pkgdir_tool"/>
+ <check send_destination="org.tizen.pkgdir_tool" send_interface="org.tizen.pkgdir_tool" privilege="http://tizen.org/privilege/packagemanager.admin"/>
</policy>
</busconfig>
" <arg type='s' name='pkgid' direction='in'/>"
" <arg type='b' name='result' direction='out'/>"
" </method>"
+ " <method name='CreateLegacyDirs'>"
+ " <arg type='s' name='pkgid' direction='in'/>"
+ " <arg type='b' name='result' direction='out'/>"
+ " </method>"
+ " <method name='DeleteLegacyDirs'>"
+ " <arg type='s' name='pkgid' direction='in'/>"
+ " <arg type='b' name='result' direction='out'/>"
+ " </method>"
" </interface>"
"</node>";
const char kDBusServiceName[] = "org.tizen.pkgdir_tool";
gpointer user_data);
void OnBusAcquired(GDBusConnection* connection, const gchar* name,
gpointer user_data);
+ int GetSenderUnixId(GDBusConnection *connection, const gchar* sender);
GDBusNodeInfo* node_info_;
guint owner_id_;
this);
}
+int PkgdirToolService::GetSenderUnixId(GDBusConnection* connection,
+ const gchar* sender) {
+ int uid = -1;
+
+ GDBusMessage* msg = nullptr;
+ msg = g_dbus_message_new_method_call("org.freedesktop.DBus",
+ "/org/freedesktop/DBus",
+ "org.freedesktop.DBus",
+ "GetConnectionUnixUser");
+ if (!msg) {
+ LOG(ERROR) << "Failed to setup dbus message";
+ return -1;
+ }
+ g_dbus_message_set_body(msg, g_variant_new("(s)", sender));
+
+ GError* err = nullptr;
+ GDBusMessage* reply = nullptr;
+ reply = g_dbus_connection_send_message_with_reply_sync(connection, msg,
+ G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, nullptr, nullptr, &err);
+ if (!reply) {
+ LOG(ERROR) << "Failed to send dbus message";
+ if (err) {
+ LOG(ERROR) << "error message: " << err->message;
+ g_error_free(err);
+ }
+ g_object_unref(msg);
+ return -1;
+ }
+
+ GVariant* body = g_dbus_message_get_body(reply);
+ g_variant_get(body, "(u)", &uid);
+
+ g_object_unref(msg);
+ g_object_unref(reply);
+
+ return uid;
+}
+
void PkgdirToolService::HandleMethodCall(GDBusConnection* connection,
const gchar* sender, const gchar* object_path, const gchar* interface_name,
const gchar* method_name, GVariant* parameters,
GDBusMethodInvocation* invocation, gpointer user_data) {
- UNUSED(connection);
- UNUSED(sender);
UNUSED(object_path);
UNUSED(interface_name);
UNUSED(user_data);
char* val;
g_variant_get(parameters, "(s)", &val);
+
bool r = false;
LOG(INFO) << "Incomming method call: " << method_name;
+
if (g_strcmp0(method_name, "CopyUserDirs") == 0) {
r = ci::CopyUserDirectories(std::string(val));
} else if (g_strcmp0(method_name, "DeleteUserDirs") == 0) {
r = ci::PerformExternalDirectoryCreationForAllUsers(std::string(val));
} else if (g_strcmp0(method_name, "DeleteExternalDirs") == 0) {
r = ci::PerformExternalDirectoryDeletionForAllUsers(std::string(val));
+ } else if (g_strcmp0(method_name, "CreateLegacyDirs") == 0) {
+ r = ci::CreateLegacyDirectories(std::string(val));
+ } else if (g_strcmp0(method_name, "DeleteLegacyDirs") == 0) {
+ int sender_uid = GetSenderUnixId(connection, sender);
+ if (sender_uid < 0) {
+ LOG(ERROR) << "Failed to get sender_uid: " << sender_uid;
+ } else {
+ r = ci::DeleteLegacyDirectories((uid_t)sender_uid, std::string(val));
+ }
} else {
LOG(ERROR) << "Unknown method call: " << method_name;
}