step/configuration/step_parse_manifest.cc
step/configuration/step_parse_preload.cc
step/filesystem/step_acquire_external_storage.cc
+ step/filesystem/step_change_owner.cc
step/filesystem/step_clear_data.cc
step/filesystem/step_copy.cc
step/filesystem/step_copy_storage_directories.cc
}
}
+uid_t PkgMgrInterface::GetUid() const {
+ return pkgmgr_installer_get_uid(pi_);
+}
+
const char* PkgMgrInterface::GetRequestInfo() const {
return pkgmgr_installer_get_request_info(pi_);
}
RequestType GetRequestType() const;
/**
+ * Returns uid passed from pkgmgr_installer
+ *
+ * \return uid retrieved from pkgmgr_installer
+ */
+ uid_t GetUid() const;
+
+ /**
* Returns Request info passed from pkgmgr_installer
*
* \return request info retrieved from pkgmgr_installer
}
bool QueryIsPackageInstalled(const std::string& pkg_id,
- RequestMode request_mode) {
+ RequestMode request_mode, uid_t uid) {
pkgmgrinfo_pkginfo_h handle;
- int ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkg_id.c_str(), getuid(),
+ int ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkg_id.c_str(), uid,
&handle);
if (ret != PMINFO_R_OK) {
if (ret != PMINFO_R_ENOENT)
*
* \param pkg_id package id
* \param request_mode request mode
+ * \param uid user id
*
* \return true if package is installed
*/
bool QueryIsPackageInstalled(const std::string& pkg_id,
- RequestMode request_mode);
+ RequestMode request_mode, uid_t uid);
/**
* \brief Adapter interface for external PkgMgr module used for checking
bool PkgmgrSignal::SendAppids(const std::string& type,
const std::string& pkgid) const {
std::vector<std::string> appids;
- if (!QueryAppidsForPkgId(pkgid, &appids, getuid()))
+ if (!QueryAppidsForPkgId(pkgid, &appids, pkgmgr_installer_get_uid(pi_)))
return true;
for (auto& appid : appids) {
if (pkgmgr_installer_send_app_uninstall_signal(pi_, type.c_str(),
namespace common_installer {
-RequestMode GetRequestMode() {
- return (getuid() == tzplatform_getuid(TZ_SYS_GLOBALAPP_USER) ||
+RequestMode GetRequestMode(uid_t uid) {
+ return (uid == tzplatform_getuid(TZ_SYS_GLOBALAPP_USER) ||
getuid() == 0) ?
RequestMode::GLOBAL : RequestMode::USER;
}
// Now, preload app is always installed RO location.
-const char *GetRootAppPath(bool is_preload) {
- return GetRequestMode() == RequestMode::USER ?
- tzplatform_getenv(TZ_USER_APP) : is_preload ?
- tzplatform_getenv(TZ_SYS_RO_APP) : tzplatform_getenv(TZ_SYS_RW_APP);
+const char* GetRootAppPath(bool is_preload, uid_t uid) {
+ if (GetRequestMode(uid) == RequestMode::GLOBAL) {
+ return is_preload ?
+ tzplatform_getenv(TZ_SYS_RO_APP) : tzplatform_getenv(TZ_SYS_RW_APP);
+ } else {
+ tzplatform_set_user(uid);
+ const char* rootpath = tzplatform_getenv(TZ_USER_APP);
+ tzplatform_reset_user();
+ return rootpath;
+ }
}
-
} // namespace common_installer
*
* \return request mode
*/
-RequestMode GetRequestMode();
+RequestMode GetRequestMode(uid_t uid);
/**
* Get apps root path for current request (GLOBAL/USER)
*
* \return root application path (eg. $HOME/apps_rw/)
*/
-const char *GetRootAppPath(bool is_preload);
+const char* GetRootAppPath(bool is_preload, uid_t uid);
} // namespace common_installer
}
Step::Status StepConfigure::process() {
- SetupRequestMode();
+ SetupRequestMode(pkgmgr_->GetUid());
SetupRequestType();
SetupFileCreationMask();
return Status::OPERATION_NOT_ALLOWED;
}
} else {
+ context_->uid.set(pkgmgr_->GetUid());
if (pkgmgr_->GetRequestType() == RequestType::ManifestDirectInstall ||
pkgmgr_->GetRequestType() == RequestType::ManifestDirectUpdate) {
if (context_->is_preload_request.get()) {
bool StepConfigure::SetupRootAppDirectory() {
if (context_->root_application_path.get().empty()) {
std::string root_app_path =
- GetRootAppPath(context_->is_preload_request.get());
+ GetRootAppPath(context_->is_preload_request.get(), context_->uid.get());
if (root_app_path.empty())
return false;
return true;
}
-void StepConfigure::SetupRequestMode() {
- context_->request_mode.set(GetRequestMode());
+void StepConfigure::SetupRequestMode(uid_t uid) {
+ context_->request_mode.set(GetRequestMode(uid));
}
void StepConfigure::SetupRequestType() {
private:
bool SetupRootAppDirectory();
- void SetupRequestMode();
+ void SetupRequestMode(uid_t uid);
void SetupRequestType();
void SetupFileCreationMask();
void SetupIsPreloadRequest();
--- /dev/null
+/* 2016, Copyright © Intel Coporation, license APACHE-2.0, see LICENSE file */
+// 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_change_owner.h"
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <grp.h>
+#include <pwd.h>
+#include <fcntl.h>
+#include <pkgmgr-info.h>
+#include <cassert>
+
+#include <cstring>
+#include <string>
+#include <vector>
+
+#include "common/shared_dirs.h"
+#include "common/utils/file_util.h"
+#include "common/utils/glist_range.h"
+
+namespace bf = boost::filesystem;
+namespace bs = boost::system;
+
+namespace {
+
+const int32_t kPWBufSize = sysconf(_SC_GETPW_R_SIZE_MAX);
+const int32_t kGRBufSize = sysconf(_SC_GETGR_R_SIZE_MAX);
+
+bool SetOwner(const bf::path& subpath, uid_t uid, gid_t gid) {
+ int fd = open(subpath.c_str(), O_RDONLY);
+ if (fd < 0) {
+ LOG(ERROR) << "Can't open directory : " << subpath;
+ return false;
+ }
+
+ int ret = fchown(fd, uid, gid);
+ close(fd);
+ if (ret != 0) {
+ LOG(ERROR) << "Failed to change owner of: " << subpath;
+ return false;
+ }
+ return true;
+}
+
+bf::path FindIconPath(const bf::path& base_path, const std::string& pkgid,
+ const bf::path& icon_filename,
+ const bf::path& root_path) {
+ std::vector<bf::path> paths;
+ bf::path system_path = base_path / icon_filename;
+ bf::path small_system_path = base_path / "default" / "small" / icon_filename;
+ bf::path res_path = root_path / pkgid / "res" / "icons" / icon_filename;
+
+ paths.push_back(system_path);
+ paths.push_back(small_system_path);
+ paths.push_back(res_path);
+
+ for (auto& path : paths) {
+ if (bf::exists(path))
+ return path;
+ }
+
+ return {};
+}
+
+} // namespace
+
+namespace common_installer {
+namespace filesystem {
+
+Step::Status StepChangeOwner::precheck() {
+ if (context_->root_application_path.get().empty()) {
+ LOG(ERROR) << "root_application_path attribute is empty";
+ return Step::Status::INVALID_VALUE;
+ }
+
+ if (!boost::filesystem::exists(context_->root_application_path.get())) {
+ LOG(ERROR) << "root_application_path ("
+ << context_->root_application_path.get()
+ << ") path does not exist";
+ return Step::Status::INVALID_VALUE;
+ }
+
+ if (context_->pkgid.get().empty()) {
+ LOG(ERROR) << "pkgid attribute is empty";
+ return Step::Status::PACKAGE_NOT_FOUND;
+ }
+
+ return Step::Status::OK;
+}
+
+Step::Status StepChangeOwner::process() {
+ struct passwd pwd;
+ struct passwd* pwd_result;
+ char buf_pw[kPWBufSize];
+
+ int ret = getpwuid_r(context_->uid.get(), &pwd, buf_pw,
+ sizeof(buf_pw), &pwd_result);
+ if (ret != 0 || pwd_result == nullptr) {
+ LOG(WARNING) << "Failed to get user for home directory: " <<
+ context_->uid.get();
+ return Status::ERROR;
+ }
+
+ struct group gr;
+ struct group* gr_result;
+ char buf_gr[kGRBufSize];
+ ret = getgrgid_r(pwd.pw_gid, &gr, buf_gr, sizeof(buf_gr), &gr_result);
+ if (ret != 0)
+ return Status::ERROR;
+
+ // Change owner of files at root path
+ bf::path start_path = context_->pkg_path.get();
+ if (!SetOwner(start_path, pwd.pw_uid, pwd.pw_gid))
+ return Status::ERROR;
+ for (bf::recursive_directory_iterator iter(start_path);
+ iter != bf::recursive_directory_iterator(); ++iter) {
+ if (bf::is_symlink(symlink_status(iter->path())))
+ continue;
+ if (!SetOwner(iter->path(), pwd.pw_uid, pwd.pw_gid))
+ return Status::ERROR;
+ }
+
+ // For icon files
+ const char *iconpath = getIconPath(context_->uid.get(),
+ context_->is_preload_request.get());
+ if (!iconpath) {
+ for (application_x* app :
+ GListRange<application_x*>(
+ context_->manifest_data.get()->application)) {
+ if (!app->icon)
+ continue;
+
+ icon_x* icon = reinterpret_cast<icon_x*>(app->icon->data);
+ bf::path icon_path = icon->text;
+ //bf::path base_path = iconpath;
+ bf::path found_icon_path = FindIconPath(iconpath,
+ context_->pkgid.get(), icon_path.filename(),
+ context_->root_application_path.get());
+ if (!found_icon_path.empty()) {
+ if (!SetOwner(found_icon_path, pwd.pw_uid, pwd.pw_gid))
+ return Status::ERROR;
+ }
+ }
+ }
+
+ // Manifest files for global apps
+ if (!context_->xml_path.get().empty()) {
+ if (!SetOwner(context_->xml_path.get(), pwd.pw_uid, pwd.pw_gid))
+ return Status::ERROR;
+ }
+
+ return Status::OK;
+}
+
+} // namespace filesystem
+} // namespace common_installer
--- /dev/null
+/* 2016, Copyright © Intel Coporation, license APACHE-2.0, see LICENSE file */
+// 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.
+
+#ifndef COMMON_STEP_FILESYSTEM_STEP_CHANGE_OWNER_H_
+#define COMMON_STEP_FILESYSTEM_STEP_CHANGE_OWNER_H_
+
+#include <manifest_parser/utils/logging.h>
+
+#include "common/installer_context.h"
+
+#include "common/step/step.h"
+
+namespace common_installer {
+namespace filesystem {
+
+/**
+ * \brief step responsible for changing ownership from system uid to actual user.
+ * Used by WGT and TPK
+ */
+class StepChangeOwner : public Step {
+ public:
+ using Step::Step;
+
+ Status process() override;
+ Status clean() override { return Status::OK; }
+ Status undo() override { return Status::OK; }
+ Status precheck() override;
+ STEP_NAME(ChangeOwner)
+};
+
+} // namespace filesystem
+} // namespace common_installer
+
+#endif // COMMON_STEP_FILESYSTEM_STEP_CHANGE_OWNER_H_
}
bool ApplyModifiedFiles(const delta::DeltaInfo& info, const bf::path& app_dir,
- const bf::path& patch_dir, bool is_preload) {
+ const bf::path& patch_dir, bool is_preload, uid_t uid) {
for (auto& relative : info.modified()) {
bf::path temp_file = ci::GenerateTemporaryPath(
- bf::path(ci::GetRootAppPath(is_preload)) / "tmp_file");
+ bf::path(ci::GetRootAppPath(is_preload, uid)) / "tmp_file");
bf::path patch_file = patch_dir / relative;
bf::path input = app_dir / relative;
if (!bf::is_regular_file(input)) {
}
bool ApplyPatch(const delta::DeltaInfo& info, const bf::path& app_dir,
- const bf::path& patch_dir, bool is_preload) {
+ const bf::path& patch_dir, bool is_preload, uid_t uid) {
if (!ApplyDeletedFiles(info, app_dir))
return false;
- if (!ApplyModifiedFiles(info, app_dir, patch_dir, is_preload))
+ if (!ApplyModifiedFiles(info, app_dir, patch_dir, is_preload, uid))
return false;
if (!ApplyAddedFiles(info, app_dir, patch_dir))
return false;
// apply changes mentioned in delta
if (!ApplyPatch(*delta_info, context_->unpacked_dir_path.get(), patch_dir_,
- context_->is_preload_request.get()))
+ context_->is_preload_request.get(), context_->uid.get()))
return Status::DELTA_ERROR;
bs::error_code error;
return true;
}
-bool KillApp(const std::string& appid) {
+bool KillApp(const std::string& appid, const uid_t uid) {
uid_t* uids = nullptr;
int ret = -1;
int i;
- uid_t uid = getuid();
if (uid == 0 || uid == tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)) {
ret = sd_get_uids(&uids);
if (ret < 0 || (ret == 0 || uids == nullptr)) {
context_->old_manifest_data.get() : context_->manifest_data.get();
for (application_x* app :
GListRange<application_x*>(old_manifest->application)) {
- (void) KillApp(app->appid);
+ (void) KillApp(app->appid, context_->uid.get());
}
return Status::OK;
}