#include "common/step/filesystem/step_recover_change_owner.h"
+#include <boost/filesystem/path.hpp>
+#include <boost/optional/optional.hpp>
+
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <pkgmgr-info.h>
-#include <cassert>
+#include <tzplatform_config.h>
+#include <cassert>
#include <cstring>
#include <string>
#include <vector>
namespace {
+const char kSkelAppDir[] = "skel/apps_rw";
+const char kData[] = "data";
+const char kShared[] = ".shared";
+const char kSharedTmp[] = ".shared_tmp";
const char kSystemShareGroupName[] = "system_share";
-const std::vector<const char*> kDataDirEntries = {
- {"data"},
- {"shared/data"},
- {"cache"},
-};
-
-bool ChangeDataDir(const bf::path& pkg_path, uid_t uid) {
- if (ci::GetRequestMode(uid) == ci::RequestMode::GLOBAL)
+const uid_t kGlobalUserUid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
+const gid_t kGlobalUserGid = tzplatform_getgid(TZ_SYS_GLOBALAPP_USER);
+
+bool SetSharedDirOwnershipAndPermissions(const bf::path& apps_rw,
+ const std::string& pkgid, uid_t uid, gid_t gid) {
+ bf::perms perms = (bf::all_all | bf::set_uid_on_exe) ^ bf::others_write;
+ bf::path shared = apps_rw / kShared / pkgid / kData;
+ if (!bf::exists(shared))
return true;
- boost::optional<gid_t> gid = ci::GetGidByGroupName(kSystemShareGroupName);
- if (!gid) {
- LOG(ERROR) << "Failed to get gid of " << kSystemShareGroupName;
+ boost::optional<gid_t> system_share =
+ ci::GetGidByGroupName(kSystemShareGroupName);
+ if (!system_share)
return false;
- }
- bf::perms prms = bf::add_perms | bf::group_write | bf::set_gid_on_exe;
- for (auto& entry : kDataDirEntries) {
- bf::path path = pkg_path / entry;
- if (!bf::exists(path))
- continue;
- if (!ci::SetDirOwnershipAndPermissions(path, prms, uid, *gid))
- return false;
- }
+ if (!ci::SetDirOwnershipAndPermissions(shared, perms, uid, *system_share))
+ return false;
+
+ perms = bf::all_all ^ bf::group_write ^ bf::others_write;
+ bf::path shared_tmp = apps_rw / kSharedTmp / pkgid;
+ if (!ci::SetDirOwnershipAndPermissions(shared_tmp, perms, uid, gid))
+ return false;
return true;
}
if (!gid)
return Step::Status::ERROR;
- return ChangeOwnershipIconsAndManifest(gid, uid);
-}
-
-Step::Status StepRecoverChangeOwner::RecoveryMountUpdate() {
- uid_t uid = context_->uid.get();
- // Change owner of files at root path
- if (!ci::SetPackageDirectoryOwnerAndPermissions(context_->GetPkgPath(),
- uid))
- return Step::Status::ERROR;
-
- boost::optional<gid_t> gid = ci::GetGidByUid(uid);
- if (!gid)
- return Step::Status::ERROR;
-
- // Change owner of files at root path
- if (!ci::SetOwnershipAll(context_->GetPkgPath(), uid, *gid))
- return Status::ERROR;
+ if (context_->request_mode.get() == RequestMode::GLOBAL) {
+ bf::path skel_apps_rw = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
+ bf::path(kSkelAppDir);
+ if (!SetSharedDirOwnershipAndPermissions(skel_apps_rw,
+ context_->pkgid.get(), kGlobalUserUid, kGlobalUserGid))
+ return Step::Status::ERROR;
- if (!ChangeDataDir(context_->GetPkgPath(), uid))
- return Status::ERROR;
+ ci::UserList list = ci::GetUserList();
+ for (auto l : list) {
+ uid_t uid = std::get<0>(l);
+ gid_t gid = std::get<1>(l);
+ bf::path apps_rw = ci::GetRootAppPath(false, uid);
+ bf::path pkg_root = apps_rw / context_->pkgid.get();
+ if (!ci::SetPackageDirectoryOwnerAndPermissions(pkg_root, uid))
+ return Step::Status::ERROR;
+
+ if (!SetSharedDirOwnershipAndPermissions(apps_rw, context_->pkgid.get(),
+ uid, gid))
+ return Step::Status::ERROR;
+ }
+ } else {
+ bf::path apps_rw = ci::GetRootAppPath(false, uid);
+ if (!SetSharedDirOwnershipAndPermissions(apps_rw, context_->pkgid.get(),
+ context_->uid.get(), *gid))
+ return Step::Status::ERROR;
+ }
return ChangeOwnershipIconsAndManifest(gid, uid);
}