tpk/wgt backend will run as system session 06/78206/23 submit/tizen/20160811.013634
authorJunghyun Yeon <jungh.yeon@samsung.com>
Mon, 4 Jul 2016 12:34:34 +0000 (21:34 +0900)
committerJunghyun Yeon <jungh.yeon@samsung.com>
Thu, 11 Aug 2016 04:23:37 +0000 (13:23 +0900)
Related changes
[slp-pkgmgr] https://review.tizen.org/gerrit/80764
[pkgmgr-server] https://review.tizen.org/gerrit/#/c/78205/
[app-installers] https://review.tizen.org/gerrit/#/c/78206/
[wgt-backend] https://review.tizen.org/gerrit/#/c/81099/

Change-Id: I0bd615388f539da3dc25594deb9b9eab999603a9
Signed-off-by: Junghyun Yeon <jungh.yeon@samsung.com>
14 files changed:
src/common/CMakeLists.txt
src/common/pkgmgr_interface.cc
src/common/pkgmgr_interface.h
src/common/pkgmgr_query.cc
src/common/pkgmgr_query.h
src/common/pkgmgr_signal.cc
src/common/request.cc
src/common/request.h
src/common/step/configuration/step_configure.cc
src/common/step/configuration/step_configure.h
src/common/step/filesystem/step_change_owner.cc [new file with mode: 0644]
src/common/step/filesystem/step_change_owner.h [new file with mode: 0644]
src/common/step/filesystem/step_delta_patch.cc
src/common/step/pkgmgr/step_kill_apps.cc

index 15288ab..ceb14e7 100644 (file)
@@ -37,6 +37,7 @@ SET(SRCS
   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
index 879c959..d919f1d 100644 (file)
@@ -145,6 +145,10 @@ RequestType PkgMgrInterface::GetRequestType() const {
   }
 }
 
+uid_t PkgMgrInterface::GetUid() const {
+  return pkgmgr_installer_get_uid(pi_);
+}
+
 const char* PkgMgrInterface::GetRequestInfo() const {
   return pkgmgr_installer_get_request_info(pi_);
 }
index e2dee7d..b174d42 100644 (file)
@@ -68,6 +68,13 @@ class PkgMgrInterface {
   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
index 27f2df5..6ccef74 100644 (file)
@@ -157,9 +157,9 @@ std::string QueryStorageForPkgId(const std::string& pkg_id, uid_t uid) {
 }
 
 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)
index 0b1212a..16a705f 100644 (file)
@@ -89,11 +89,12 @@ std::string QueryStorageForPkgId(const std::string& pkg_id, uid_t uid);
  *
  * \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
index 9c38de2..d9648f1 100644 (file)
@@ -157,7 +157,7 @@ const char* PkgmgrSignal::GetResultKey(Step::Status result) const {
 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(),
index ca9e796..ed4b3c7 100644 (file)
@@ -10,17 +10,22 @@ namespace bf = boost::filesystem;
 
 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
index 9b29019..c320e9b 100644 (file)
@@ -41,14 +41,14 @@ enum class RequestMode : int {
  *
  * \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
 
index 25694cc..60c97f5 100644 (file)
@@ -30,7 +30,7 @@ StepConfigure::StepConfigure(InstallerContext* context, PkgMgrPtr pkgmgr)
 }
 
 Step::Status StepConfigure::process() {
-  SetupRequestMode();
+  SetupRequestMode(pkgmgr_->GetUid());
   SetupRequestType();
   SetupFileCreationMask();
 
@@ -154,6 +154,7 @@ Step::Status StepConfigure::precheck() {
       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()) {
@@ -179,7 +180,7 @@ Step::Status StepConfigure::clean() {
 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;
 
@@ -199,8 +200,8 @@ bool StepConfigure::SetupRootAppDirectory() {
   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() {
index 2041344..95e52db 100644 (file)
@@ -56,7 +56,7 @@ class StepConfigure : public Step {
 
  private:
   bool SetupRootAppDirectory();
-  void SetupRequestMode();
+  void SetupRequestMode(uid_t uid);
   void SetupRequestType();
   void SetupFileCreationMask();
   void SetupIsPreloadRequest();
diff --git a/src/common/step/filesystem/step_change_owner.cc b/src/common/step/filesystem/step_change_owner.cc
new file mode 100644 (file)
index 0000000..c1e1348
--- /dev/null
@@ -0,0 +1,159 @@
+/* 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
diff --git a/src/common/step/filesystem/step_change_owner.h b/src/common/step/filesystem/step_change_owner.h
new file mode 100644 (file)
index 0000000..8e158f5
--- /dev/null
@@ -0,0 +1,36 @@
+/* 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_
index bd28b7f..74cd25c 100644 (file)
@@ -100,10 +100,10 @@ bool ApplyDeletedFiles(const delta::DeltaInfo& info, const bf::path& app_dir) {
 }
 
 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)) {
@@ -183,10 +183,10 @@ bool ApplyAddedFiles(const delta::DeltaInfo& info, const bf::path& app_dir,
 }
 
 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;
@@ -302,7 +302,7 @@ Step::Status StepDeltaPatch::process() {
 
   // 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;
index 7a68b55..24e29a5 100644 (file)
@@ -35,12 +35,11 @@ bool CheckAndKill(const std::string& appid, uid_t uid) {
   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)) {
@@ -73,7 +72,7 @@ Step::Status StepKillApps::process() {
       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;
 }