2a3d0525934a37944db38239a56d8ce4f997544d
[platform/core/appfw/app-installers.git] / src / common / step / configuration / step_configure.cc
1 // Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by a apache 2.0 license that can be
3 // found in the LICENSE file.
4
5 #include "common/step/configuration/step_configure.h"
6
7 #include <boost/filesystem/path.hpp>
8
9 #include <pkgmgr-info.h>
10 #include <sys/stat.h>
11 #include <sys/types.h>
12 #include <unistd.h>
13 #include <tzplatform_config.h>
14
15 #include <memory>
16 #include <string>
17 #include <utility>
18
19 #include "common/utils/pkgmgr_query.h"
20 #include "common/utils/file_util.h"
21 #include "common/utils/user_util.h"
22 #include "common/utils/request.h"
23
24 namespace bf = boost::filesystem;
25
26 namespace common_installer {
27 namespace configuration {
28
29 const char kStrEmpty[] = "";
30 const char kAppFWUser[] = "app_fw";
31
32 StepConfigure::StepConfigure(InstallerContext* context, PkgMgrPtr pkgmgr)
33     : Step(context),
34       pkgmgr_(pkgmgr) {
35 }
36
37 Step::Status StepConfigure::process() {
38   SetupRequestMode(pkgmgr_->GetUid());
39   SetupRequestType();
40   SetupFileCreationMask();
41   SetupDebugMode();
42   SetupSkipCheckReference();
43   SetupSkipOptimization();
44
45   if (!SetupRootAppDirectory())
46     return Status::CONFIG_ERROR;
47
48   RequestType request_type = context_->request_type.get();
49   switch (request_type) {
50     case RequestType::Install:
51     case RequestType::Update:
52       context_->file_path.set(pkgmgr_->GetRequestInfo(context_->index.get()));
53       if (!pkgmgr_->GetTepPath().empty()) {
54         context_->tep_path.set(pkgmgr_->GetTepPath());
55         context_->is_tep_move.set(pkgmgr_->GetIsTepMove());
56       }
57       break;
58     case RequestType::PartialUninstall:
59     case RequestType::Uninstall:
60       if (request_type == RequestType::PartialUninstall)
61         SetupIsPartialRW();
62       SetupIsKeepRWData();
63       SetupIsForceRemoval();
64       context_->pkgid.set(pkgmgr_->GetRequestInfo(context_->index.get()));
65       context_->file_path.set(kStrEmpty);
66       break;
67     case RequestType::Reinstall:
68       context_->unpacked_dir_path.set(
69           bf::path(tzplatform_getenv(TZ_SDK_TOOLS)) / "tmp" /
70           pkgmgr_->GetRequestInfo(context_->index.get()));
71       context_->pkgid.set(pkgmgr_->GetRequestInfo(context_->index.get()));
72       context_->file_path.set(kStrEmpty);
73       break;
74     case RequestType::Delta:
75       context_->unpacked_dir_path.set(kStrEmpty);
76       context_->pkgid.set(pkgmgr_->GetRequestInfo(context_->index.get()));
77       context_->file_path.set(pkgmgr_->GetRequestInfo(context_->index.get()));
78       break;
79     case RequestType::Move:
80       context_->pkgid.set(pkgmgr_->GetRequestInfo(context_->index.get()));
81       context_->is_move_to_external.set(pkgmgr_->GetIsMoveToExternal());
82       SetupMoveType();
83       break;
84     case RequestType::Recovery:
85       context_->file_path.set(pkgmgr_->GetRequestInfo(context_->index.get()));
86       context_->recovery_info.set(
87           RecoveryInfo(context_->file_path.get(),
88               pkgmgr_->GetRecoveryCleanup()));
89       break;
90     case RequestType::MountInstall:
91     case RequestType::MountUpdate:
92       context_->file_path.set(pkgmgr_->GetRequestInfo(context_->index.get()));
93       if (!pkgmgr_->GetTepPath().empty()) {
94         context_->tep_path.set(pkgmgr_->GetTepPath());
95         context_->is_tep_move.set(pkgmgr_->GetIsTepMove());
96       }
97       break;
98     case RequestType::ManifestPartialInstall:
99     case RequestType::ManifestPartialUpdate:
100     case RequestType::ManifestDirectInstall:
101     case RequestType::ManifestDirectUpdate: {
102       if (request_type == RequestType::ManifestPartialInstall ||
103           request_type == RequestType::ManifestPartialUpdate)
104         SetupIsPartialRW();
105       context_->pkgid.set(pkgmgr_->GetRequestInfo(context_->index.get()));
106       bf::path xml_path =
107           bf::path(getUserManifestPath(context_->uid.get(),
108               context_->is_readonly_package.get()))
109           / bf::path(context_->pkgid.get());
110       xml_path += ".xml";
111       context_->unpacked_dir_path.set(context_->GetPkgPath());
112       context_->xml_path.set(xml_path);
113       break;
114     }
115     case RequestType::ReadonlyUpdateInstall:
116       context_->file_path.set(pkgmgr_->GetRequestInfo(context_->index.get()));
117       if (!pkgmgr_->GetTepPath().empty()) {
118         context_->tep_path.set(pkgmgr_->GetTepPath());
119         context_->is_tep_move.set(pkgmgr_->GetIsTepMove());
120       }
121       break;
122     case RequestType::ReadonlyUpdateUninstall: {
123       context_->pkgid.set(pkgmgr_->GetRequestInfo(context_->index.get()));
124       bf::path original_path =
125           bf::path(tzplatform_getenv(TZ_SYS_RO_APP)) / context_->pkgid.get();
126       context_->unpacked_dir_path.set(original_path);
127       context_->file_path.set(kStrEmpty);
128       SetupIsKeepRWData();
129       break;
130     }
131     case RequestType::DisablePkg:
132     case RequestType::EnablePkg:
133       context_->pkgid.set(pkgmgr_->GetRequestInfo(context_->index.get()));
134       break;
135     case RequestType::MigrateExtImg: {
136       context_->pkgid.set(pkgmgr_->GetRequestInfo(context_->index.get()));
137       break;
138     }
139     case RequestType::RecoverDB: {
140       context_->pkgid.set(pkgmgr_->GetRequestInfo(context_->index.get()));
141       break;
142     }
143     default:
144       LOG(ERROR) << "Unknown request type";
145       return Status::CONFIG_ERROR;
146   }
147
148   LOG(INFO) << "Request Type: " << GetRequestTypeString(request_type);
149
150   return Status::OK;
151 }
152
153 Step::Status StepConfigure::precheck() {
154   SetupIsPreloadRequest();
155   SetupIsPreloadRWRequest();
156
157   bool is_readonly = context_->is_readonly_package.get();
158   bool is_preload_rw = context_->is_preload_rw_package.get();
159   if (is_readonly && is_preload_rw) {
160     LOG(ERROR) << "Conflict of preload request!";
161     return Status::ERROR;
162   }
163
164   if (is_readonly || is_preload_rw)
165     SetupIsNoRemoval();
166
167   uid_t uid = pkgmgr_->GetUid();
168   context_->uid.set(uid);
169   if (getuid() == 0)
170     return Status::OK;
171
172   boost::optional<uid_t> appfw_uid = GetUidByUserName(kAppFWUser);
173   if (!appfw_uid)
174     return Status::ERROR;
175
176   if (getuid() != *appfw_uid) {
177     LOG(ERROR) << "App-installer should not run with normal user!";
178     return Status::OPERATION_NOT_ALLOWED;
179   }
180
181   return Status::OK;
182 }
183
184 bool StepConfigure::SetupRootAppDirectory() {
185   if (context_->root_application_path.get().empty()) {
186     std::string root_app_path =
187         GetRootAppPath(context_->is_readonly_package.get(),
188         context_->uid.get());
189     if (root_app_path.empty())
190       return false;
191
192     context_->root_application_path.set(root_app_path);
193   }
194   if (!boost::filesystem::exists(context_->root_application_path.get())) {
195     boost::system::error_code error;
196     boost::filesystem::create_directories(
197         context_->root_application_path.get());
198     if (error) {
199       LOG(ERROR) << "Cannot create directory: "
200                  << context_->root_application_path.get();
201       return false;
202     }
203   }
204   LOG(INFO) << "AppDir(" << context_->root_application_path.get() << ")";
205   return true;
206 }
207
208 void StepConfigure::SetupRequestMode(uid_t uid) {
209   context_->request_mode.set(GetRequestMode(uid));
210 }
211
212 void StepConfigure::SetupRequestType() {
213   context_->request_type.set(pkgmgr_->GetRequestType(context_->index.get()));
214 }
215
216 void StepConfigure::SetupFileCreationMask() {
217   mode_t old_mask, new_mask;
218   old_mask = new_mask = 0;
219
220   switch (context_->request_mode.get()) {
221     case RequestMode::USER:
222       new_mask = 033;  // results in 744 privileges
223       break;
224     case RequestMode::GLOBAL:
225       new_mask = 022;  // results in 755 privileges
226       break;
227   }
228
229   old_mask = umask(new_mask);
230
231   LOG(INFO) << "Changed file creation mask from " << std::oct <<  old_mask
232       << " to " << std::oct <<  new_mask;
233 }
234
235 void StepConfigure::SetupIsPreloadRequest() {
236   context_->is_readonly_package.set(pkgmgr_->GetIsPreloadRequest());
237 }
238
239 void StepConfigure::SetupIsPreloadRWRequest() {
240   context_->is_preload_rw_package.set(pkgmgr_->GetIsPreloadRWRequest());
241 }
242
243 void StepConfigure::SetupIsForceRemoval() {
244   context_->force_remove.set(pkgmgr_->GetIsForceRemoval());
245 }
246
247 void StepConfigure::SetupIsNoRemoval() {
248   context_->no_remove.set(pkgmgr_->GetIsNoRemoval());
249 }
250
251 void StepConfigure::SetupIsKeepRWData() {
252   context_->keep_rwdata.set(pkgmgr_->GetIsKeepRWData());
253 }
254
255 void StepConfigure::SetupIsPartialRW() {
256   context_->partial_rw.set(pkgmgr_->GetIsPartialRW());
257 }
258
259 void StepConfigure::SetupDebugMode() {
260   context_->debug_mode.set(pkgmgr_->GetDebugMode());
261 }
262
263 void StepConfigure::SetupSkipCheckReference() {
264   context_->skip_check_reference.set(pkgmgr_->GetIsSkipCheckReference());
265 }
266
267 void StepConfigure::SetupSkipOptimization() {
268   context_->skip_optimization.set(pkgmgr_->GetSkipOptimization());
269 }
270
271 void StepConfigure::SetupMoveType() {
272   int move_type = pkgmgr_->GetMoveType();
273   switch (move_type) {
274     case 0:
275       context_->move_type.set(MoveType::TO_INTERNAL);
276       break;
277     case 1:
278       context_->move_type.set(MoveType::TO_EXTERNAL);
279       break;
280     case 2:
281       context_->move_type.set(MoveType::TO_EXTENDED);
282       break;
283     default:
284       context_->move_type.set(MoveType::TO_INTERNAL);
285       break;
286   }
287 }
288
289 }  // namespace configuration
290 }  // namespace common_installer