Modify smack label for osp-compat
[platform/framework/native/installer.git] / src / Manager / PermissionManager.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 /**
18  * @file        PermissionManager.cpp
19  * @brief       This is the implementation file for %PermissionManager class.
20  */
21
22 #include <stdio.h>
23 #include <sys/stat.h>
24 #include <unistd.h>
25 #include <unique_ptr.h>
26
27 #include <FBaseUtilStringUtil.h>
28 #include <FIoFile.h>
29 #include <FIoDirectory.h>
30 #include <FBase_StringConverter.h>
31 #include <FIo_FileImpl.h>
32
33 #include "PermissionManager.h"
34 #include "InstallerUtil.h"
35 #include "SmackManager.h"
36 #include "CompatibilityManager.h"
37
38 using namespace Tizen::Base;
39 using namespace Tizen::Base::Collection;
40 using namespace Tizen::Base::Utility;
41 using namespace Tizen::Io;
42 using namespace Tizen::App;
43
44 PermissionManager::PermissionManager(void)
45 {
46 }
47
48 PermissionManager::~PermissionManager(void)
49 {
50 }
51
52 bool
53 PermissionManager::SetDirectory(InstallationContext* pContext)
54 {
55         result r = E_SUCCESS;
56         bool res = true;
57
58         String destPath;
59         String appRootPath;
60         SmackManager smackManager;
61         smackManager.Construct(pContext);
62
63         appRootPath = pContext->__rootPath;
64         PackageId packageId = pContext->__packageId;
65
66         // appRoot
67         // InstallerUtil::ChangeOwner(appRootPath);
68         InstallerUtil::ChangeMode(appRootPath, PERM_BASE | PERM_EXECUTE);
69         smackManager.SetupPath(packageId, appRootPath, SMACK_DIR_TYPE_ANY_LABEL, L"_");
70
71         if (pContext->__isPreloaded == true)
72         {
73                 String preloadedAppPath(PATH_USR_APPS);
74                 preloadedAppPath += L"/";
75                 preloadedAppPath += packageId;
76
77                 smackManager.SetupPath(packageId, preloadedAppPath, SMACK_DIR_TYPE_ANY_LABEL, L"_");
78         }
79
80         // appRoot/bin
81         destPath = appRootPath + DIR_BIN;
82         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE | PERM_EXECUTE, false);
83         smackManager.SetupPath(packageId, destPath, SMACK_DIR_TYPE_PRIVATE);
84
85         // appRoot/info
86         destPath = appRootPath + DIR_INFO;
87         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, false);
88         smackManager.SetupPath(packageId, destPath, SMACK_DIR_TYPE_PRIVATE);
89
90         // appRoot/res
91         destPath = appRootPath + DIR_RES;
92         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, false);
93         smackManager.SetupPath(packageId, destPath, SMACK_DIR_TYPE_PRIVATE);
94
95         // appRoot/lib
96         destPath = appRootPath + DIR_LIB;
97         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE | PERM_EXECUTE, false);
98         smackManager.SetupPath(packageId, destPath, SMACK_DIR_TYPE_PRIVATE);
99
100         // appRoot/shared
101         destPath = appRootPath + DIR_SHARED;
102         if (File::IsFileExist(destPath) == false)
103         {
104                 r = Directory::Create(destPath, false);
105                 TryReturn(!IsFailed(r), INSTALLER_ERROR_INTERNAL_STATE, "Directory::Create() failed");
106         }
107         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, false);
108
109         // appRoot/shared/res
110         destPath = appRootPath + DIR_SHARED_RES;
111         if (File::IsFileExist(destPath) == false)
112         {
113                 String iconPath = appRootPath + DIR_ICONS;
114                 InstallerUtil::CreateSymlink(iconPath, destPath);
115         }
116         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, false);
117
118         // appRoot/shared/data
119         destPath = appRootPath + DIR_SHARED_DATA;
120         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, true);
121         smackManager.SetupPath(packageId, destPath, SMACK_DIR_TYPE_PUBLIC_RO);
122
123         // appRoot/shared/trusted
124         destPath = appRootPath + DIR_SHARED_TRUSTED;
125         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, true);
126         smackManager.SetupPath(packageId, destPath, SMACK_DIR_TYPE_GROUP_RW);
127
128         // appRoot/contents
129         destPath = appRootPath + DIR_CONTENTS;
130         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, false);
131         smackManager.SetupPath(packageId, destPath, SMACK_DIR_TYPE_PRIVATE);
132
133         // appRoot/setting
134         destPath = appRootPath + DIR_SETTING;
135         if (File::IsFileExist(destPath) == true)
136         {
137                 String appVersion = pContext->__version;
138                 String srcPath;
139                 String settingXmlPath;
140                 srcPath = destPath + L"/setting." + appVersion + L".xml";
141                 settingXmlPath = destPath + L"/setting.xml";
142
143                 InstallerUtil::Remove(settingXmlPath);
144                 InstallerUtil::CreateSymlink(srcPath, settingXmlPath);
145
146                 InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE | PERM_WRITE, false);
147                 smackManager.SetupPath(packageId, destPath, SMACK_DIR_TYPE_SETTINGS_RW);
148         }
149
150         // appRoot/data
151         destPath = appRootPath + DIR_DATA;
152         if (File::IsFileExist(destPath) == false)
153         {
154                 r = Directory::Create(destPath, false);
155                 TryReturn(!IsFailed(r), false, "Directory::Create() failed");
156         }
157         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, true);
158         smackManager.SetupPath(packageId, destPath, SMACK_DIR_TYPE_PRIVATE);
159
160         String apiVersion = pContext->__apiVersion;
161
162         AppLog("------------------------------------------");
163         AppLog("[Tizen::Io] # path = [%ls]", appRootPath.GetPointer());
164         AppLog("[Tizen::Io] # package = [%ls]", packageId.GetPointer());
165         AppLog("[Tizen::Io] # apiVersion = [%ls]", apiVersion.GetPointer());
166
167         if (pContext->__isOspCompat == true)
168         {
169                 AppLog("[Tizen::Io] OSP 2.0 application");
170
171                 res = CompatibilityManager::PrepareDataCaging(appRootPath, packageId);
172                 TryReturn(res == true, false, "[Tizen::Io] CompatibilityManager::PrepareDataCaging() failed.");
173
174                 SetSymLink(pContext);
175         }
176         else
177         {
178                 AppLog("[Tizen::Io] apiVersion is equal to or greater than Tizen 2.0");
179
180                 res = CompatibilityManager::CleanDirectories(appRootPath, packageId);
181                 TryReturn(res == true, false, "[Tizen::Io] CompatibilityManager::CleanDirectories() failed.");
182
183                 res = CompatibilityManager::LinkOspSharePath(appRootPath, packageId);
184                 TryReturn(res == true, false, "[Tizen::Io] CompatibilityManager::LinkOspSharePath() failed.");
185         }
186
187         if (pContext->__isVirtualRoot == true)
188         {
189                 res = CompatibilityManager::PrepareVirtualRoot(appRootPath, packageId);
190                 TryReturn(res == true, false, "[Tizen::Io] CompatibilityManager::PrepareVirtualRoot() failed.");
191         }
192         AppLog("------------------------------------------");
193
194         return true;
195 }
196
197 bool
198 PermissionManager::SetFile(InstallationContext* pContext)
199 {
200         String destPath;
201         String appRootPath = pContext->__rootPath;
202
203         IListT<AppData*>* pAppDataList = pContext->__pAppDataList;
204         TryReturn(pAppDataList, false, "pAppDataList is null");
205
206         for (int i = 0 ; i < pAppDataList->GetCount(); i++)
207         {
208                 AppData* pAppData = null;
209                 pAppDataList->GetAt(i, pAppData);
210                 TryReturn(pAppData, false, "pAppData is null");
211
212                 // set permission(755) to bin file.
213                 destPath = appRootPath + DIR_BIN + L"/" + pAppData->__name + L".exe";
214                 if (File::IsFileExist(destPath) == true)
215                 {
216                         InstallerUtil::ChangeMode(destPath, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
217                 }
218         }
219
220         return true;
221 }
222
223 bool
224 PermissionManager::SetSymLink(InstallationContext* pContext)
225 {
226         String oldPath;
227         String newPath;
228         String appRootPath = pContext->__rootPath;
229
230         SmackManager smackManager;
231         smackManager.Construct(pContext);
232
233 #if 0
234         oldPath = appRootPath + DIR_RES;
235         newPath = appRootPath + L"/Res";
236         InstallerUtil::CreateSymlink(oldPath, newPath);
237 #else
238         newPath = appRootPath + L"/Res";
239         InstallerUtil::CreateSymlink(L"./res", newPath, false);
240 #endif
241
242 #if 0
243         oldPath = appRootPath + DIR_DATA;
244         newPath = appRootPath + L"/Home";
245         InstallerUtil::CreateSymlink(oldPath, newPath);
246 #else
247         newPath = appRootPath + L"/Home";
248         InstallerUtil::CreateSymlink(L"./data", newPath, false);
249 #endif
250
251         oldPath = appRootPath + DIR_RES + L"/screen-size-normal";
252         newPath = appRootPath + L"/Res/ScreenSize-Normal";
253         InstallerUtil::CreateSymlink(oldPath, newPath, false);
254
255         oldPath = appRootPath + DIR_RES + L"/screen-density-high";
256         newPath = appRootPath + L"/Res/ScreenDensity-High";
257         InstallerUtil::CreateSymlink(oldPath, newPath, false);
258
259         oldPath = appRootPath + DIR_RES + L"/screen-density-middle";
260         newPath = appRootPath + L"/Res/ScreenDensity-Middle";
261         InstallerUtil::CreateSymlink(oldPath, newPath, false);
262
263         oldPath = appRootPath + DIR_RES + L"/screen-density-low";
264         newPath = appRootPath + L"/Res/ScreenDensity-Low";
265         InstallerUtil::CreateSymlink(oldPath, newPath, false);
266
267         return true;
268 }
269
270 bool
271 PermissionManager::CopyForRds(InstallationContext* pContext, IList* pFileList, bool& isInstallRequired)
272 {
273         TryReturn(pFileList, false, "pFileList is null.");
274
275         for (int idx = 0; idx < pFileList->GetCount(); idx++)
276         {
277                 String* pFilePath = static_cast<String *>(pFileList->GetAt(idx));
278                 TryReturn(pFilePath, false, "pFilePath is null.");
279
280                 String srcFile = DIR_APPLICATIONS_TMP;
281                 srcFile += L"/" + pContext->__packageId + L"/" + *pFilePath;
282                 String destFile = pContext->__rootPath + L"/" + *pFilePath;
283
284                 AppLog("copy file from[%ls] to[%ls]", srcFile.GetPointer(), destFile.GetPointer());
285
286                 int pos = 0;
287                 result r = E_SUCCESS;
288                 String destDir;
289
290                 if (destFile.EndsWith(L"/") == true)
291                 {
292                         destDir = destFile;
293                         if (File::IsFileExist(destDir) == false)
294                         {
295                                 Directory::Create(destDir, true);
296                         }
297                         continue;
298                 }
299                 else
300                 {
301                         r = destFile.LastIndexOf(L'/', destFile.GetLength() -1, pos);
302                         if (IsFailed(r) == true)
303                         {
304                                 AppLog("destFile is invalid[%ls]", destFile.GetPointer());
305                                 continue;
306                         }
307                         destFile.SubString(0, pos, destDir);
308                 }
309
310                 if (File::IsFileExist(destDir) == false)
311                 {
312                         Directory::Create(destDir, true);
313                 }
314                 InstallerUtil::Remove(destFile);
315                 r = File::Copy(srcFile, destFile, true);
316                 if (IsFailed(r) == true)
317                 {
318                         AppLog("File::Copy() failed. [%ls] -> [%ls]", srcFile.GetPointer(), destFile.GetPointer());
319                         continue;
320                 }
321
322                 if (*pFilePath == L"info/manifest.xml")
323                 {
324                         AppLog("Install required, [%ls] is found", pFilePath->GetPointer());
325                         isInstallRequired = true;
326                 }
327                 else if (pFilePath->StartsWith("setting/setting", 0) == true)
328                 {
329                         AppLog("Install required, [%ls] is found", pFilePath->GetPointer());
330                         isInstallRequired = true;
331                 }
332         }
333
334         return true;
335 }
336
337 bool
338 PermissionManager::ApplyPermissionForRds(InstallationContext* pContext)
339 {
340         String destPath;
341         String appRootPath;
342         SmackManager smackManager;
343         smackManager.Construct(pContext);
344
345         appRootPath = pContext->__rootPath;
346         PackageId packageId = pContext->__packageId;
347
348         // appRoot
349         InstallerUtil::ChangeMode(appRootPath, PERM_BASE | PERM_EXECUTE);
350         smackManager.SetupPath(packageId, appRootPath, SMACK_DIR_TYPE_ANY_LABEL, L"_");
351
352         // appRoot/bin
353         destPath = appRootPath + DIR_BIN;
354         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE | PERM_EXECUTE, false);
355         smackManager.SetupPath(packageId, destPath, SMACK_DIR_TYPE_PRIVATE);
356
357         // appRoot/info
358         destPath = appRootPath + DIR_INFO;
359         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, false);
360         smackManager.SetupPath(packageId, destPath, SMACK_DIR_TYPE_PRIVATE);
361
362         // appRoot/res
363         destPath = appRootPath + DIR_RES;
364         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, false);
365         smackManager.SetupPath(packageId, destPath, SMACK_DIR_TYPE_PRIVATE);
366
367         // appRoot/lib
368         destPath = appRootPath + DIR_LIB;
369         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE | PERM_EXECUTE, false);
370         smackManager.SetupPath(packageId, destPath, SMACK_DIR_TYPE_PRIVATE);
371
372         // appRoot/shared
373         destPath = appRootPath + DIR_SHARED;
374         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, false);
375
376         // appRoot/shared/res
377         destPath = appRootPath + DIR_SHARED_RES;
378         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, false);
379
380         // appRoot/shared/data
381         destPath = appRootPath + DIR_SHARED_DATA;
382         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, true);
383         smackManager.SetupPath(packageId, destPath, SMACK_DIR_TYPE_PUBLIC_RO);
384
385         // appRoot/shared/trusted
386         destPath = appRootPath + DIR_SHARED_TRUSTED;
387         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, true);
388         smackManager.SetupPath(packageId, destPath, SMACK_DIR_TYPE_GROUP_RW);
389
390         // appRoot/setting
391         destPath = appRootPath + DIR_SETTING;
392         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE | PERM_WRITE, false);
393         smackManager.SetupPath(packageId, destPath, SMACK_DIR_TYPE_SETTINGS_RW);
394
395         // appRoot/data
396         destPath = appRootPath + DIR_DATA;
397         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, true);
398         smackManager.SetupPath(packageId, destPath, SMACK_DIR_TYPE_PRIVATE);
399
400         return true;
401 }
402
403 #if 0
404 bool
405 PermissionManager::ApplyPermission(InstallationContext* pContext, const IList* pFileList)
406 {
407         TryReturn(pContext, false, "pContext is null");
408         TryReturn(pFileList, false, "pFileList is null");
409
410         // dir | type | owner | mode | smack
411         static RdsPermssions perms[] =
412         {
413                 {"res",                         PERM_DIR_RES,                           PERM_OWNER_ROOT,        PERM_BASE,                                              PERM_SMACK_0},
414                 {"data",                        PERM_DIR_DATA,                          PERM_OWNER_APP,         PERM_BASE,                                              PERM_SMACK_0},
415                 {"bin",                         PERM_DIR_BIN,                           PERM_OWNER_ROOT,        (PERM_BASE | PERM_EXECUTE),             PERM_SMACK_0},
416                 {"info",                        PERM_DIR_INFO,                          PERM_OWNER_ROOT,        PERM_BASE,                                              PERM_SMACK_0},
417                 {"lib",                         PERM_DIR_LIB,                           PERM_OWNER_ROOT,        (PERM_BASE | PERM_EXECUTE),             PERM_SMACK_0},
418                 {"setting",                     PERM_DIR_SETTING,                       PERM_OWNER_ROOT,        (PERM_BASE | PERM_WRITE),               PERM_SMACK_0},
419                 {"shared/res",          PERM_DIR_SHARED_RES,            PERM_OWNER_ROOT,        PERM_BASE,                                              PERM_SMACK_0},
420                 {"shared/data",         PERM_DIR_SHARED_DATA,           PERM_OWNER_APP,         PERM_BASE,                                              PERM_SMACK_0},
421                 {"shared/trusted",      PERM_DIR_SHARED_TRUSTED,        PERM_OWNER_APP,         PERM_BASE,                                              PERM_SMACK_0},
422                 {"shared",                      PERM_DIR_SHARED,                        PERM_OWNER_ROOT,        PERM_BASE,                                              PERM_SMACK_0},
423                 {"author",                      PERM_DIR_ROOT,                          PERM_OWNER_ROOT,        PERM_BASE,                                              PERM_SMACK_0},
424                 {"signature",           PERM_DIR_ROOT,                          PERM_OWNER_ROOT,        PERM_BASE,                                              PERM_SMACK_0},
425         };
426
427         static int permCount = sizeof(perms) / sizeof(RdsPermssions);
428         bool isInstallRequired = false;
429         SmackManager smackManager;
430         smackManager.Construct(pContext);
431
432         for (int i = 0; i < pFileList->GetCount(); i++)
433         {
434                 const String *pFilePath = static_cast<const String *>(pFileList->GetAt(i));
435                 TryReturn(pFilePath, false, "pFilePath is null");
436
437                 AppLog("pFilePath=(%ls)", pFilePath->GetPointer());
438
439                 int permIdx = 0;
440                 for (permIdx = 0; permIdx < permCount; permIdx++)
441                 {
442                         if (pFilePath->StartsWith(perms[permIdx].pDir, 0) == true)
443                         {
444                                 if (perms[permIdx].dirType == PERM_DIR_INFO)
445                                 {
446                                         if (*pFilePath == L"info/manifest.xml")
447                                         {
448                                                 AppLog("Install required, [%ls] is found", pFilePath->GetPointer());
449                                                 isInstallRequired = true;
450                                         }
451                                 }
452                                 else if (perms[permIdx].dirType == PERM_DIR_SETTING)
453                                 {
454                                         if (pFilePath->StartsWith("setting/setting", 0) == true)
455                                         {
456                                                 AppLog("Install required, [%ls] is found", pFilePath->GetPointer());
457                                                 isInstallRequired = true;
458                                         }
459                                 }
460
461                                 AppLog("dirType=(%d), owner=(%d), mode=(%d), smack=(%d)",
462                                                 perms[permIdx].dirType, perms[permIdx].ownerIndex, perms[permIdx].modeIndex, perms[permIdx].smackIndex);
463
464                                 String srcFile = DIR_APPLICATIONS_TMP;
465                                 srcFile += L"/" + pContext->__packageId + L"/" + *pFilePath;
466                                 String destFile = pContext->__rootPath + L"/" + *pFilePath;
467
468                                 AppLog("copy file: from[%ls] to[%ls]", srcFile.GetPointer(), destFile.GetPointer());
469                                 File::Copy(srcFile, destFile, false);
470
471                                 bool isAppOwner = false;
472                                 if (perms[permIdx].ownerIndex == PERM_OWNER_APP)
473                                 {
474                                         isAppOwner = true;
475                                 }
476
477                                 String destPath;
478                                 if (perms[permIdx].dirType != PERM_DIR_ROOT)
479                                 {
480                                         destPath = pContext->__rootPath + L"/" + perms[permIdx].pDir;
481                                         InstallerUtil::ChangeDirectoryPermission(destPath, perms[permIdx].modeIndex, isAppOwner);
482                                 }
483                                 else
484                                 {
485                                         destPath = pContext->__rootPath + L"/" + *pFilePath;
486                                         InstallerUtil::ChangeMode(*pFilePath, perms[permIdx].modeIndex);
487                                 }
488                                 smackManager.AddLabelSharedDir(pContext->__packageId, destPath);
489
490                                 break;
491                         }
492                 }
493         }
494
495         return true;
496 }
497 #endif
498
499