Handle abnormally terminated installer process
[platform/core/appfw/pkgmgr-info.git] / src / server / worker_thread.cc
index 34a4e6d..129ff1d 100644 (file)
 #include <tzplatform_config.h>
 
 #include "abstract_parcelable.hh"
+#include "cynara_checker.hh"
 #include "request_handler_factory.hh"
 #include "server/database/db_handle_provider.hh"
+#include "server/database/remove_cache_db_handler.hh"
 #include "utils/logging.hh"
 
 #include "pkgmgrinfo_debug.h"
@@ -56,6 +58,19 @@ uid_t ConvertUID(uid_t uid) {
     return uid;
 }
 
+const char PRIVILEGE_PACKAGE_MANAGER_ADMIN[] =
+    "http://tizen.org/privilege/packagemanager.admin";
+
+std::vector<std::string> GetPrivileges(pkgmgr_common::ReqType type) {
+  std::vector<std::string> ret;
+  if (type == pkgmgr_common::SET_CERT_INFO)
+    ret.emplace_back(PRIVILEGE_PACKAGE_MANAGER_ADMIN);
+  else if (type == pkgmgr_common::SET_PKG_INFO)
+    ret.emplace_back(PRIVILEGE_PACKAGE_MANAGER_ADMIN);
+
+  return ret;
+}
+
 }  // namespace
 
 namespace pkgmgr_server {
@@ -105,9 +120,21 @@ void WorkerThread::Run() {
     if (req == nullptr)
       return;
 
+    if (!req->GetPrivilegeChecked()) {
+      if (!req->ReceiveData()) {
+        LOG(ERROR) << "Fail to receive data";
+        continue;
+      }
+
+      pkgmgr_common::ReqType type = req->GetRequestType();
+      std::vector<std::string> privileges = GetPrivileges(type);
+      if (!CynaraChecker::GetInst().CheckPrivilege(this, req, privileges))
+        continue;
+    }
+
     auto type = req->GetRequestType();
     LOG(WARNING) << "Request type: " << pkgmgr_common::ReqTypeToString(type)
-                 << " pid: " << req->GetSenderPID();
+        << " pid: " << req->GetSenderPID() << " tid: " << req->GetSenderTID();
     auto handler = factory.GetRequestHandler(type);
     if (handler == nullptr)
       continue;
@@ -116,15 +143,15 @@ void WorkerThread::Run() {
       handler->PreExec();
       handler->SetUID(ConvertUID(req->GetSenderUID()));
       handler->SetPID(req->GetSenderPID());
-      if (!handler->HandleRequest(req->GetData(), req->GetSize(),
+      if (!handler->HandleRequest(req->DetachData(), req->GetSize(),
           locale_.GetObject()))
         LOG(ERROR) << "Failed to handle request";
 
-      std::vector<uint8_t> result_data = handler->ExtractResult();
-      if (req->SendData(result_data.data(), result_data.size()) == false)
+      if (req->SendData(handler->ExtractResult()) == false)
         LOG(ERROR) << "Failed to send response pid: " << req->GetSenderPID();
       else
-        LOG(WARNING) << "Success response pid: " << req->GetSenderPID();
+        LOG(WARNING) << "Success response pid: " << req->GetSenderPID()
+            << " tid: " << req->GetSenderTID();
     } catch (const std::exception& err) {
       LOG(ERROR) << "Exception occurred: " << err.what()
                  << ", pid: " << req->GetSenderPID();
@@ -155,8 +182,13 @@ gboolean WorkerThread::TrimMemory(void* data) {
     h->timer_ = 0;
   }
 
-  if (database::DBHandleProvider::IsCrashedWriteRequest())
-    database::DBHandleProvider::GetInst(getuid()).UnsetMemoryMode(getpid());
+  auto crashed_writer_pids =
+      database::DBHandleProvider::CrashedWriteRequestPIDs();
+  if (!crashed_writer_pids.empty()) {
+    database::RemoveCacheDBHandler db(getuid(), std::move(crashed_writer_pids));
+    db.SetLocale(h->locale_.GetObject());
+    db.Execute();
+  }
 
   sqlite3_release_memory(-1);
   malloc_trim(0);
@@ -174,8 +206,7 @@ void WorkerThread::SendError(const std::shared_ptr<PkgRequest>& req) {
       0, pkgmgr_common::parcel::ParcelableType::Unknown, PMINFO_R_ERROR);
   tizen_base::Parcel p;
   p.WriteParcelable(parcelable);
-  std::vector<uint8_t> raw = p.GetRaw();
-  req->SendData(&raw[0], raw.size());
+  req->SendData(p);
 }
 
 }  // namespace pkgmgr_server