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"
8 #include <boost/range/iterator_range.hpp>
11 #include <sys/types.h>
13 #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 bf = boost::filesystem;
28 namespace ci = common_installer;
32 const char kSystemShareGroupName[] = "system_share";
33 const std::vector<const char*> kDataDirEntries = {
39 bool GrantPermission755(const bf::path& path) {
40 auto permission = bf::perms::owner_all |
41 bf::perms::group_read | bf::perms::group_exe |
42 bf::perms::others_read | bf::perms::others_exe;
43 if (!ci::SetDirPermissions(path, permission)) {
44 LOG(ERROR) << "Grant permission error" << " path: " << path
45 << " permission: " << permission;
51 bool GrantPermission644(const bf::path& path) {
52 auto permission = bf::perms::owner_read | bf::perms::owner_write |
53 bf::perms::group_read | bf::perms::others_read;
54 if (!ci::SetDirPermissions(path, permission)) {
55 LOG(ERROR) << "Grant permission error" << " path: " << path
56 << " permission: " << permission;
62 bool ChangeDataDir(const bf::path& pkg_path, uid_t uid) {
63 if (ci::GetRequestMode(uid) == ci::RequestMode::GLOBAL)
65 boost::optional<gid_t> gid = ci::GetGidByGroupName(kSystemShareGroupName);
67 LOG(ERROR) << "Failed to get gid of " << kSystemShareGroupName;
71 bf::perms prms = bf::add_perms | bf::group_write | bf::set_gid_on_exe;
72 for (auto& entry : kDataDirEntries) {
73 bf::path path = pkg_path / entry;
74 if (!bf::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)) {
82 LOG(ERROR) << "Failed to change permission: " << path
91 bool GrantDefaultPermissions(bf::path pkg_path, bool skip_symlink) {
92 if (bf::is_directory(pkg_path)) {
93 if (!GrantPermission755(pkg_path))
97 boost::make_iterator_range(bf::directory_iterator(pkg_path), {})) {
98 auto path = entry.path();
100 if (skip_symlink && bf::is_symlink(symlink_status(path)))
103 // skip path, which is related to mount or directory installer creates
104 if (bf::is_directory(path) &&
105 (path.filename() == ".mmc" || path.filename() == ".pkg" ||
106 path.filename() == "tep"))
109 if (bf::is_directory(path) && path.filename() == "bin") {
110 if (!GrantPermission755(path))
112 for (auto& bin_entry :
113 boost::make_iterator_range(bf::directory_iterator(path), {})) {
114 auto bin_path = bin_entry.path();
115 if (bf::is_symlink(symlink_status(bin_path)))
118 if (bf::is_regular_file(bin_path)) {
119 if (!GrantPermission755(bin_path))
126 if (bf::is_directory(path) && path.filename() == "lib") {
127 if (!GrantPermission755(path))
129 for (auto& lib_entry :
130 boost::make_iterator_range(bf::directory_iterator(path), {})) {
131 auto lib_path = lib_entry.path();
132 if (bf::is_symlink(symlink_status(lib_path)))
135 if (bf::is_regular_file(lib_path)) {
136 if (!GrantPermission644(lib_path))
143 if (bf::is_directory(path)) {
144 if (!GrantPermission755(path))
149 if (bf::is_regular_file(path)) {
150 if (!GrantPermission644(path))
161 namespace common_installer {
162 namespace filesystem {
164 StepChangeOwnershipAndPermission::StepChangeOwnershipAndPermission(
165 InstallerContext* context, bool skip_symlink = false)
167 skip_symlink_(skip_symlink) {
170 Step::Status StepChangeOwnershipAndPermission::precheck() {
171 if (context_->root_application_path.get().empty()) {
172 LOG(ERROR) << "root_application_path attribute is empty";
173 return Step::Status::INVALID_VALUE;
176 if (!boost::filesystem::exists(context_->root_application_path.get())) {
177 LOG(ERROR) << "root_application_path ("
178 << context_->root_application_path.get()
179 << ") path does not exist";
180 return Step::Status::INVALID_VALUE;
183 if (context_->pkgid.get().empty()) {
184 LOG(ERROR) << "pkgid attribute is empty";
185 return Step::Status::PACKAGE_NOT_FOUND;
188 return Step::Status::OK;
191 Step::Status StepChangeOwnershipAndPermission::process() {
192 uid_t uid = context_->uid.get();
193 boost::optional<gid_t> gid = ci::GetGidByUid(uid);
195 return Status::ERROR;
197 // Grant default permissions
198 if (!GrantDefaultPermissions(context_->GetPkgPath(), skip_symlink_))
199 return Status::GRANT_PERMISSION_ERROR;
201 // Change owner of files at root path
202 if (!ci::SetOwnershipAll(context_->GetPkgPath(), uid, *gid))
203 return Status::ERROR;
205 if (!ChangeDataDir(context_->GetPkgPath(), uid))
206 return Status::ERROR;
209 const char *iconpath = getIconPath(uid, context_->is_readonly_package.get());
211 for (application_x* app :
212 GListRange<application_x*>(
213 context_->manifest_data.get()->application)) {
217 icon_x* icon = reinterpret_cast<icon_x*>(app->icon->data);
218 bf::path icon_path = icon->text;
219 bf::path found_icon_path = GetIconPath(iconpath,
220 context_->pkgid.get(), icon_path.filename(),
221 context_->root_application_path.get());
222 if (!found_icon_path.empty()) {
223 if (!ci::SetOwnership(found_icon_path, uid, *gid))
224 return Status::ERROR;
229 // Manifest files for global apps
230 if (!context_->xml_path.get().empty()) {
231 if (!ci::SetOwnership(context_->xml_path.get(), uid, *gid))
232 return Status::ERROR;
238 } // namespace filesystem
239 } // namespace common_installer