e486db66c144b204ebf9d9deaf10e3407f1ba3cc
[platform/core/appfw/app-installers.git] / src / common / step / filesystem / step_recover_change_owner.cc
1 // Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by an apache-2.0 license that can be
3 // found in the LICENSE file.
4
5 #include "common/step/filesystem/step_recover_change_owner.h"
6
7 #include <boost/filesystem/path.hpp>
8 #include <boost/optional/optional.hpp>
9
10 #include <unistd.h>
11 #include <sys/types.h>
12 #include <fcntl.h>
13 #include <pkgmgr-info.h>
14 #include <tzplatform_config.h>
15
16 #include <cassert>
17 #include <cstring>
18 #include <string>
19 #include <utility>
20 #include <vector>
21
22 #include "common/utils/paths.h"
23 #include "common/shared_dirs.h"
24 #include "common/utils/file_util.h"
25 #include "common/utils/glist_range.h"
26 #include "common/utils/user_util.h"
27
28 namespace bf = boost::filesystem;
29 namespace ci = common_installer;
30
31 namespace {
32
33 const char kSkelAppDir[] = "skel/apps_rw";
34 const char kData[] = "data";
35 const char kShared[] = ".shared";
36 const char kSharedTmp[] = ".shared_tmp";
37 const char kSystemShareGroupName[] = "system_share";
38 const char kSubssesionDir[] = "subsession";
39 const uid_t kGlobalUserUid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
40 const gid_t kGlobalUserGid = tzplatform_getgid(TZ_SYS_GLOBALAPP_USER);
41
42 bool SetSharedDirOwnershipAndPermissions(const bf::path& apps_rw,
43     const std::string& pkgid, uid_t uid, gid_t gid) {
44   bf::perms perms = (bf::all_all | bf::set_uid_on_exe) ^ bf::others_write;
45   bf::path shared = apps_rw / kShared / pkgid / kData;
46   if (!bf::exists(shared))
47     return true;
48   boost::optional<gid_t> system_share =
49       ci::GetGidByGroupName(kSystemShareGroupName);
50   if (!system_share)
51     return false;
52
53   if (!ci::SetDirOwnershipAndPermissions(shared, perms, uid, *system_share))
54     return false;
55
56   perms = bf::all_all ^ bf::group_write ^ bf::others_write;
57   bf::path shared_tmp = apps_rw / kSharedTmp / pkgid;
58   if (!ci::SetDirOwnershipAndPermissions(shared_tmp, perms, uid, gid))
59     return false;
60
61   return true;
62 }
63
64 }  // namespace
65
66 namespace common_installer {
67 namespace filesystem {
68
69 Step::Status StepRecoverChangeOwner::RecoveryUpdate() {
70   uid_t uid = context_->uid.get();
71   // Change owner of files at root path
72   if (!ci::SetPackageDirectoryOwnerAndPermissions(context_->GetPkgPath(),
73       uid))
74     return Step::Status::ERROR;
75
76   boost::optional<gid_t> gid = ci::GetGidByUid(uid);
77   if (!gid)
78     return Step::Status::ERROR;
79
80   if (context_->request_mode.get() == RequestMode::GLOBAL) {
81     bf::path skel_apps_rw = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
82         bf::path(kSkelAppDir);
83     if (!SetSharedDirOwnershipAndPermissions(skel_apps_rw,
84             context_->pkgid.get(), kGlobalUserUid, kGlobalUserGid))
85       return Step::Status::ERROR;
86
87     ci::UserList list = ci::GetUserList();
88     for (auto l : list) {
89       uid_t lu = std::get<0>(l);
90       gid_t lg = std::get<1>(l);
91       bf::path owner_apps_rw = ci::GetRootAppPath(false, lu);
92       std::vector<bf::path> apps_rw_paths;
93       apps_rw_paths.push_back(std::move(owner_apps_rw));
94       for (auto& lw_user : GetLightUserList(uid))
95         apps_rw_paths.push_back(std::get<2>(l) / kSubssesionDir / lw_user /
96                                 "apps_rw");
97
98       for (auto& apps_rw : apps_rw_paths) {
99         bf::path pkg_root = apps_rw / context_->pkgid.get();
100         if (!ci::SetPackageDirectoryOwnerAndPermissions(pkg_root, lu))
101           return Step::Status::ERROR;
102
103         if (!SetSharedDirOwnershipAndPermissions(apps_rw,
104                 context_->pkgid.get(), lu, lg))
105           return Step::Status::ERROR;
106       }
107     }
108   } else {
109     ci::UserList list = ci::GetUserList();
110     for (auto& l : list) {
111       uid_t lu = std::get<0>(l);
112       if (lu != uid)
113         continue;
114
115       bf::path owner_apps_rw = ci::GetRootAppPath(false, uid);
116       std::vector<bf::path> apps_rw_paths;
117       apps_rw_paths.push_back(std::move(owner_apps_rw));
118       for (auto& lw_user : GetLightUserList(uid))
119         apps_rw_paths.push_back(std::get<2>(l) / kSubssesionDir / lw_user /
120                                 "apps_rw");
121
122       for (auto& apps_rw : apps_rw_paths) {
123         if (!SetSharedDirOwnershipAndPermissions(apps_rw,
124                 context_->pkgid.get(), context_->uid.get(), *gid))
125           return Step::Status::ERROR;
126       }
127     }
128   }
129
130   return ChangeOwnershipIconsAndManifest(gid, uid);
131 }
132
133 Step::Status StepRecoverChangeOwner::ChangeOwnershipIconsAndManifest(
134     const boost::optional<gid_t> gid, const uid_t uid) {
135   if (!gid)
136     return Step::Status::ERROR;
137
138   // For icon files
139   const char *iconpath = getIconPath(uid, context_->is_readonly_package.get());
140   if (iconpath) {
141     for (application_x* app :
142         GListRange<application_x*>(
143         context_->manifest_data.get()->application)) {
144       if (!app->icon)
145         continue;
146
147       icon_x* icon = reinterpret_cast<icon_x*>(app->icon->data);
148       bf::path icon_path = icon->text;
149       //  bf::path base_path = iconpath;
150       bf::path found_icon_path = GetIconPath(iconpath,
151           context_->pkgid.get(), icon_path.filename(),
152           context_->root_application_path.get());
153       if (!found_icon_path.empty()) {
154         if (!ci::SetOwnership(found_icon_path, uid, *gid))
155           return Step::Status::ERROR;
156       }
157     }
158   }
159
160   // Manifest files for global apps
161   if (!context_->xml_path.get().empty()) {
162     if (!ci::SetOwnership(context_->xml_path.get(), uid, *gid))
163       return Step::Status::ERROR;
164   }
165
166   return Step::Status::OK;
167 }
168
169 }  // namespace filesystem
170 }  // namespace common_installer