Refactor creating shared data logic 29/221429/23
authorSangyoon Jang <jeremy.jang@samsung.com>
Thu, 2 Jan 2020 08:16:49 +0000 (17:16 +0900)
committerSangyoon Jang <jeremy.jang@samsung.com>
Wed, 12 Feb 2020 05:05:59 +0000 (14:05 +0900)
Creating shared data logic is fragmented.
The shared data directories are created by using base directory(apps_rw) and
some flags. This patch also fixes that installer can set setgid bit
rwdata only.

Change-Id: I997f401bd0d4dcad355422e36b51df03ed07201d
Signed-off-by: Sangyoon Jang <jeremy.jang@samsung.com>
src/common/shared_dirs.cc
src/common/shared_dirs.h
src/common/step/filesystem/step_create_storage_directories.cc
src/common/step/filesystem/step_create_storage_directories.h
src/common/step/filesystem/step_remove_per_user_storage_directories.cc
src/common/step/filesystem/step_remove_user_data.cc

index 2aee1c7..7750f5e 100644 (file)
@@ -75,6 +75,7 @@ const char kSharedCacheDir[] = "shared/cache";
 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";
@@ -83,82 +84,52 @@ const char kExternalStoragePrivilege[] =
     "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;
 }
 
@@ -172,32 +143,6 @@ bf::path GetDirectoryPathForStorage(uid_t user, std::string apps_prefix) {
   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))
@@ -328,16 +273,9 @@ bool CreateStorageDirectories(const boost::filesystem::path& root_path,
                               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);
@@ -348,8 +286,7 @@ bool CreateStorageDirectories(const boost::filesystem::path& root_path,
   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;
     }
@@ -404,6 +341,37 @@ bool RemoveBackupSharedDataDirectories(const bf::path& apps_rw,
   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 {
@@ -423,7 +391,6 @@ bool PerformExternalDirectoryCreationForUser(uid_t user,
                                              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;
@@ -440,8 +407,9 @@ bool PerformExternalDirectoryCreationForUser(uid_t user,
     }
   }
 
-  CreateUserDirectories(user, pkgid,
-                            storage_apps_path.c_str(), set_permissions);
+  if (CreateExternalUserDirectories(user, pkgid, storage_apps_path.string()))
+    return false;
+
   return true;
 }
 
@@ -530,6 +498,90 @@ bool PerformExternalDirectoryDeletionForAllUsers(const std::string& pkgid) {
   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) {
@@ -539,6 +591,9 @@ bool CreateStorageDirectories(const boost::filesystem::path& path,
     return false;
   }
 
+  if (!::SetPackageDirectoryOwnerAndPermissions(path / pkgid, uid))
+    return false;
+
   std::string error_message;
   if (!RegisterSecurityContextForPath(pkgid, path / pkgid, uid, false,
                                       &error_message)) {
@@ -572,68 +627,6 @@ bool DeleteSharedDirectories(const bf::path& path,
   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) {
@@ -654,59 +647,6 @@ bool DeleteUserExternalDirectories(const std::string& pkgid) {
   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)) {
@@ -799,39 +739,7 @@ bool DeleteGlobalAppSymlinksForUser(const std::string& pkgid, uid_t uid) {
 }
 
 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) {
@@ -881,7 +789,6 @@ bool CreatePerUserSharedDataDir(const std::string& pkgid) {
   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);
@@ -891,13 +798,7 @@ bool CreatePerUserSharedDataDir(const std::string& pkgid) {
     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;
     }
 
index b260196..e79aa90 100644 (file)
@@ -64,88 +64,67 @@ bool PerformExternalDirectoryCreationForAllPkgs();
 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'
index b55162b..929be93 100644 (file)
@@ -20,6 +20,7 @@
 
 namespace bf = boost::filesystem;
 namespace bs = boost::system;
+namespace ci = common_installer;
 
 namespace common_installer {
 namespace filesystem {
@@ -41,15 +42,9 @@ bool StepCreateStorageDirectories::CreatePerUserStorageDirs(
   }
 
   bool is_readonly = context_->is_readonly_package.get();
-  if (!CreateSkelDirectories(context_->pkgid.get(),
-      trusted, shareddata, is_readonly,
-      additional_shared_dirs_)) {
-    LOG(ERROR) << "Failed to create skel dirs";
-    return false;
-  }
-
-  if (!CopyUserDirectories(context_->pkgid.get())) {
-    LOG(ERROR) << "Failed to create shared dirs for users";
+  if (!CreatePerUserStorageDirectories(context_->pkgid.get(), trusted,
+        shareddata, is_readonly, additional_shared_dirs_)) {
+    LOG(ERROR) << "Failed to create per-user storage directories";
     return false;
   }
 
@@ -67,6 +62,10 @@ bool StepCreateStorageDirectories::CreateStorageDirs(
   return true;
 }
 
+bool StepCreateStorageDirectories::DeletePerUserStorageDirs() {
+  return ci::DeletePerUserStorageDirectories(context_->pkgid.get());
+}
+
 Step::Status StepCreateStorageDirectories::process() {
   bool trusted = false;
   std::string author_id = context_->certificate_info.get().author_id.get();
@@ -98,11 +97,10 @@ Step::Status StepCreateStorageDirectories::undo() {
   if (context_->request_mode.get() != RequestMode::GLOBAL)
     return Step::Status::OK;
 
-  if (!DeleteSkelDirectories(context_->pkgid.get()))
-    return Status::APP_DIR_ERROR;
-
-  if (!DeleteUserDirectories(context_->pkgid.get()))
+  if (!DeletePerUserStorageDirs()) {
+    LOG(ERROR) << "Failed to delete per user storage directories";
     return Status::APP_DIR_ERROR;
+  }
 
   return Status::OK;
 }
index cab1310..b9fd440 100644 (file)
@@ -49,6 +49,7 @@ class StepCreateStorageDirectories : public common_installer::Step {
  private:
   bool CreatePerUserStorageDirs(bool trusted, bool shareddata);
   bool CreateStorageDirs(bool trusted, bool shareddata);
+  bool DeletePerUserStorageDirs();
 
   std::vector<const char*> additional_shared_dirs_;
 
index ec40082..be8d19c 100644 (file)
@@ -18,17 +18,8 @@ Step::Status StepRemovePerUserStorageDirectories::process() {
       context_->keep_rwdata.get())
     return Step::Status::OK;
 
-  std::string package_id = context_->pkgid.get();
-
-  if (!common_installer::DeleteSkelDirectories(package_id)) {
-    LOG(ERROR) << "Failed to delete skel dirs";
-    return Status::APP_DIR_ERROR;
-  }
-
-  if (!DeleteUserDirectories(package_id)) {
-    LOG(ERROR) << "Failed to delete shared dirs for users";
+  if (!common_installer::DeletePerUserStorageDirectories(context_->pkgid.get()))
     return Status::APP_DIR_ERROR;
-  }
 
   return Step::Status::OK;
 }
index 8396cb2..72d1fb3 100644 (file)
@@ -8,6 +8,32 @@
 
 #include "common/installer_context.h"
 #include "common/shared_dirs.h"
+#include "common/utils/file_util.h"
+#include "common/utils/user_util.h"
+
+namespace bf = boost::filesystem;
+namespace ci = common_installer;
+
+namespace {
+
+const char kDataDir[] = "data";
+const char kCacheDir[] = "cache";
+const char kSharedDir[] = ".shared";
+
+bool RemoveContents(const bf::path& path) {
+  if (!bf::exists(path))
+    return true;
+
+  for (bf::recursive_directory_iterator iter(path);
+      iter != bf::recursive_directory_iterator(); ++iter) {
+    if (!ci::RemoveAll(iter->path()))
+      return false;
+  }
+
+  return true;
+}
+
+}  // namespace
 
 namespace common_installer {
 namespace filesystem {
@@ -17,16 +43,22 @@ Step::Status StepRemoveUserData::process() {
   if (context_->keep_rwdata.get())
     return Step::Status::OK;
 
-  std::string package_id = context_->pkgid.get();
-
-  if (!DeleteUserDirectories(package_id)) {
-    LOG(ERROR) << "Failed to delete shared dirs for users";
-    return Status::APP_DIR_ERROR;
-  }
-
-  if (!CopyUserDirectories(package_id)) {
-    LOG(ERROR) << "Failed to create shared dirs for users";
-    return Status::APP_DIR_ERROR;
+  UserList list = ci::GetUserList();
+  for (auto l : list) {
+    bf::path apps_rw(std::get<2>(l) / "apps_rw");
+    if (!RemoveContents(apps_rw / context_->pkgid.get() / kDataDir)) {
+      LOG(ERROR) << "Failed to remove contents of data dir";
+      return Step::Status::APP_DIR_ERROR;
+    }
+    if (!RemoveContents(apps_rw / context_->pkgid.get() / kCacheDir)) {
+      LOG(ERROR) << "Failed to remove contents of cache dir";
+      return Step::Status::APP_DIR_ERROR;
+    }
+    if (!RemoveContents(
+            apps_rw / kSharedDir / context_->pkgid.get() / kDataDir)) {
+      LOG(ERROR) << "Failed to remove contents of shared/data dir";
+      return Step::Status::APP_DIR_ERROR;
+    }
   }
 
   return Step::Status::OK;