1 /* 2016, Copyright © Intel Coporation, license APACHE-2.0, see LICENSE file */
2 // Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3 // Use of this source code is governed by a apache 2.0 license that can be
4 // found in the LICENSE file.
6 #include "common/step/filesystem/step_change_ownership_and_permission.h"
11 #include <pkgmgr-info.h>
20 #include "common/utils/paths.h"
21 #include "common/shared_dirs.h"
22 #include "common/utils/file_util.h"
23 #include "common/utils/glist_range.h"
24 #include "common/utils/user_util.h"
25 #include "common/utils/request.h"
27 namespace ci = common_installer;
28 namespace fs = std::filesystem;
32 const char kSystemShareGroupName[] = "system_share";
33 const std::vector<const char*> kDataDirEntries = {
39 bool GrantPermission755(const fs::path& path) {
40 auto permission = fs::perms::owner_all |
41 fs::perms::group_read | fs::perms::group_exec |
42 fs::perms::others_read | fs::perms::others_exec;
43 if (!ci::SetDirPermissions(path, permission)) {
44 LOG(ERROR) << "Grant permission error" << " path: " << path
45 << " permission: 755";
51 bool GrantPermission644(const fs::path& path) {
52 auto permission = fs::perms::owner_read | fs::perms::owner_write |
53 fs::perms::group_read | fs::perms::others_read;
54 if (!ci::SetDirPermissions(path, permission)) {
55 LOG(ERROR) << "Grant permission error" << " path: " << path
56 << " permission: 644";
62 bool ChangeDataDir(const fs::path& pkg_path, uid_t uid) {
63 if (ci::GetRequestMode(uid) == ci::RequestMode::GLOBAL)
65 std::optional<gid_t> gid = ci::GetGidByGroupName(kSystemShareGroupName);
67 LOG(ERROR) << "Failed to get gid of " << kSystemShareGroupName;
71 fs::perms prms = fs::perms::group_write | fs::perms::set_gid;
72 for (auto& entry : kDataDirEntries) {
73 fs::path path = pkg_path / entry;
74 if (!fs::exists(path))
76 if (!ci::SetOwnership(path, uid, *gid)) {
77 LOG(ERROR) << "Failed to change owner: " << path
78 << "(" << uid << ", " << *gid << ")";
81 if (!ci::SetDirPermissions(path, prms, true)) {
82 LOG(ERROR) << "Failed to add data dir permission: " << path;
90 bool GrantDefaultPermissions(fs::path pkg_path, bool skip_symlink) {
91 if (fs::is_directory(pkg_path)) {
92 if (!GrantPermission755(pkg_path))
95 for (auto& entry : fs::directory_iterator(pkg_path)) {
96 if (skip_symlink && fs::is_symlink(symlink_status(entry)))
99 // skip path, which is related to mount or directory installer creates
100 if (fs::is_directory(entry) &&
101 (entry.path().filename() == ".mmc" || entry.path().filename() == ".pkg" ||
102 entry.path().filename() == "tep"))
105 if (fs::is_directory(entry) && entry.path().filename() == "bin") {
106 if (!GrantPermission755(entry))
108 for (auto& bin_entry : fs::directory_iterator(entry)) {
109 if (fs::is_symlink(symlink_status(bin_entry)))
112 if (fs::is_regular_file(bin_entry)) {
113 if (!GrantPermission755(bin_entry))
120 if (fs::is_directory(entry) && entry.path().filename() == "lib") {
121 if (!GrantPermission755(entry))
123 for (auto& lib_entry : fs::directory_iterator(entry)) {
124 if (fs::is_symlink(fs::symlink_status(lib_entry)))
127 if (fs::is_regular_file(lib_entry)) {
128 if (!GrantPermission644(lib_entry))
135 if (fs::is_directory(entry)) {
136 if (!GrantPermission755(entry))
141 if (fs::is_regular_file(entry)) {
142 if (!GrantPermission644(entry))
153 namespace common_installer {
154 namespace filesystem {
156 StepChangeOwnershipAndPermission::StepChangeOwnershipAndPermission(
157 InstallerContext* context, bool skip_symlink = false)
159 skip_symlink_(skip_symlink) {
162 Step::Status StepChangeOwnershipAndPermission::precheck() {
163 if (context_->root_application_path.get().empty()) {
164 LOG(ERROR) << "root_application_path attribute is empty";
165 return Step::Status::INVALID_VALUE;
168 if (!std::filesystem::exists(context_->root_application_path.get())) {
169 LOG(ERROR) << "root_application_path ("
170 << context_->root_application_path.get()
171 << ") path does not exist";
172 return Step::Status::INVALID_VALUE;
175 if (context_->pkgid.get().empty()) {
176 LOG(ERROR) << "pkgid attribute is empty";
177 return Step::Status::PACKAGE_NOT_FOUND;
180 return Step::Status::OK;
183 Step::Status StepChangeOwnershipAndPermission::process() {
184 uid_t uid = context_->uid.get();
185 std::optional<gid_t> gid = ci::GetGidByUid(uid);
187 return Status::ERROR;
189 // Grant default permissions
190 if (!GrantDefaultPermissions(context_->GetPkgPath(), skip_symlink_))
191 return Status::GRANT_PERMISSION_ERROR;
193 // Change owner of files at root path
194 if (!ci::SetOwnershipAll(context_->GetPkgPath(), uid, *gid))
195 return Status::ERROR;
197 if (!ChangeDataDir(context_->GetPkgPath(), uid))
198 return Status::ERROR;
201 const char *iconpath = getIconPath(uid, context_->is_readonly_package.get());
203 for (application_x* app :
204 GListRange<application_x*>(
205 context_->manifest_data.get()->application)) {
209 icon_x* icon = reinterpret_cast<icon_x*>(app->icon->data);
210 fs::path icon_path = icon->text;
211 fs::path found_icon_path = GetIconPath(iconpath,
212 context_->pkgid.get(), icon_path.filename(),
213 context_->root_application_path.get());
214 if (!found_icon_path.empty()) {
215 if (!ci::SetOwnership(found_icon_path, uid, *gid))
216 return Status::ERROR;
221 // Manifest files for global apps
222 if (!context_->xml_path.get().empty()) {
223 if (!ci::SetOwnership(context_->xml_path.get(), uid, *gid))
224 return Status::ERROR;
230 } // namespace filesystem
231 } // namespace common_installer