Fix prevent issue
[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
37 using namespace Tizen::Base;
38 using namespace Tizen::Base::Collection;
39 using namespace Tizen::Base::Utility;
40 using namespace Tizen::Io;
41 using namespace Tizen::App;
42
43 PermissionManager::PermissionManager(void)
44 {
45 }
46
47 PermissionManager::~PermissionManager(void)
48 {
49 }
50
51 bool
52 PermissionManager::SetDirectory(InstallationContext* pContext)
53 {
54         result r = E_SUCCESS;
55
56         String destPath;
57         String appRootPath;
58         SmackManager smackManager;
59         smackManager.Construct(pContext);
60
61         appRootPath = pContext->__rootPath;
62         PackageId packageId = pContext->__packageId;
63
64         // appRoot
65         // InstallerUtil::ChangeOwner(appRootPath);
66         InstallerUtil::ChangeMode(appRootPath, PERM_BASE | PERM_EXECUTE);
67         smackManager.AddLabelDir(packageId, appRootPath, true);
68
69         if (pContext->__isPreloaded == true)
70         {
71                 String preloadedAppPath(PATH_USR_APPS);
72                 preloadedAppPath += L"/";
73                 preloadedAppPath += packageId;
74
75                 smackManager.AddLabelDir(L"_", preloadedAppPath, true);
76         }
77
78         // appRoot/bin
79         destPath = appRootPath + DIR_BIN;
80         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE | PERM_EXECUTE, false);
81         smackManager.AddLabelDir(packageId, destPath);
82
83         // appRoot/info
84         destPath = appRootPath + DIR_INFO;
85         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, false);
86         smackManager.AddLabelDir(packageId, destPath);
87
88         // appRoot/res
89         destPath = appRootPath + DIR_RES;
90         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, false);
91         smackManager.AddLabelDir(packageId, destPath);
92
93         // appRoot/lib
94         destPath = appRootPath + DIR_LIB;
95         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE | PERM_EXECUTE, false);
96         smackManager.AddLabelDir(packageId, destPath);
97
98         // appRoot/shared
99         destPath = appRootPath + DIR_SHARED;
100         if (File::IsFileExist(destPath) == false)
101         {
102                 r = Directory::Create(destPath, false);
103                 TryReturn(!IsFailed(r), INSTALLER_ERROR_INTERNAL_STATE, "Directory::Create() failed");
104         }
105         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, false);
106         smackManager.AddLabelDir(packageId, destPath);
107
108         // appRoot/shared/res
109         destPath = appRootPath + DIR_SHARED_RES;
110         if (File::IsFileExist(destPath) == false)
111         {
112                 String iconPath = appRootPath + DIR_ICONS;
113                 InstallerUtil::CreateSymlink(iconPath, destPath);
114         }
115         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, false);
116         smackManager.AddLabelDir(packageId, destPath);
117
118         // appRoot/shared/data
119         destPath = appRootPath + DIR_SHARED_DATA;
120         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, true);
121         smackManager.AddLabelSharedDir(packageId, destPath);
122
123         // appRoot/shared/trusted
124         destPath = appRootPath + DIR_SHARED_TRUSTED;
125         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, true);
126         smackManager.AddLabelSharedDir(packageId, destPath);
127
128         // appRoot/contents
129         destPath = appRootPath + DIR_CONTENTS;
130         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, false);
131         smackManager.AddLabelDir(packageId, destPath);
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                 String label = "*";
141                 //String label = packageId;
142                 //label.Append("_setting");
143
144                 srcPath = destPath + L"/setting." + appVersion + L".xml";
145                 settingXmlPath = destPath + L"/setting.xml";
146
147                 InstallerUtil::Remove(settingXmlPath);
148                 InstallerUtil::CreateSymlink(srcPath, settingXmlPath);
149
150                 InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE | PERM_WRITE, false);
151                 smackManager.AddLabelDir(label, destPath);
152         }
153
154         // appRoot/data
155         destPath = appRootPath + DIR_DATA;
156         if (File::IsFileExist(destPath) == false)
157         {
158                 r = Directory::Create(destPath, false);
159                 TryReturn(!IsFailed(r), false, "Directory::Create() failed");
160         }
161         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, true);
162         smackManager.AddLabelDir(packageId, destPath);
163
164         String apiVersion = pContext->__apiVersion;
165
166         AppLog("------------------------------------------");
167         AppLog("[Tizen::Io] # path = [%ls]", appRootPath.GetPointer());
168         AppLog("[Tizen::Io] # package = [%ls]", packageId.GetPointer());
169         AppLog("[Tizen::Io] # apiVersion = [%ls]", apiVersion.GetPointer());
170
171         if (pContext->__isOspCompat == true)
172         {
173                 AppLog("[Tizen::Io] OSP 2.0 application");
174
175                 if (_FileImpl::PrepareDataCaging(appRootPath, packageId) == false)
176                 {
177                         AppLog("[Tizen::Io] _FileImpl::PrepareDataCaging() failed");
178                         return false;
179                 }
180
181                 SetSymLink(pContext);
182         }
183         else
184         {
185                 AppLog("[Tizen::Io] apiVersion is equal to or greater than Tizen 2.0");
186
187                 if (_FileImpl::CreateOspApplicationDirectories(appRootPath, packageId) == false)
188                 {
189                         AppLog("[Tizen::Io] _FileImpl::CreateOspApplicationDirectories() failed");
190                         return false;
191                 }
192         }
193
194         if (pContext->__isVirtualRoot == true)
195         {
196                 if (pContext->__pSymbolicLinkList->GetCount() > 0)
197                 {
198                         std::unique_ptr< IMapEnumeratorT<String*, String*> > pEnum(pContext->__pSymbolicLinkList->GetMapEnumeratorN());
199                         TryReturn(pEnum, false, "pSymbolicLinkList->GetMapEnumeratorN() failed.");
200                         while (pEnum->MoveNext() == E_SUCCESS)
201                         {
202                                 String* pKey = null;
203                                 String* pValue = null;
204
205                                 pEnum->GetKey(pKey);
206                                 pEnum->GetValue(pValue);
207
208                                 AppLog("SymbolicLink - Src = [%ls], Des = [%ls]", pKey->GetPointer(), pValue->GetPointer());
209                         }
210                 }
211         }
212         AppLog("------------------------------------------");
213
214         return true;
215 }
216
217 bool
218 PermissionManager::SetFile(InstallationContext* pContext)
219 {
220         String destPath;
221         String appRootPath = pContext->__rootPath;
222
223         IListT<AppData*>* pAppDataList = pContext->__pAppDataList;
224         TryReturn(pAppDataList, false, "pAppDataList is null");
225
226         for (int i = 0 ; i < pAppDataList->GetCount(); i++)
227         {
228                 AppData* pAppData = null;
229                 pAppDataList->GetAt(i, pAppData);
230                 TryReturn(pAppData, false, "pAppData is null");
231
232                 // set permission(755) to bin file.
233                 destPath = appRootPath + DIR_BIN + L"/" + pAppData->__name + L".exe";
234                 if (File::IsFileExist(destPath) == true)
235                 {
236                         InstallerUtil::ChangeMode(destPath, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
237                 }
238         }
239
240         return true;
241 }
242
243 bool
244 PermissionManager::SetSymLink(InstallationContext* pContext)
245 {
246         String oldPath;
247         String newPath;
248         String appRootPath = pContext->__rootPath;
249
250         SmackManager smackManager;
251
252 #if 0
253         oldPath = appRootPath + DIR_RES;
254         newPath = appRootPath + L"/Res";
255         InstallerUtil::CreateSymlink(oldPath, newPath);
256 #else
257         newPath = appRootPath + L"/Res";
258         std::unique_ptr< char[] > pResPath(_StringConverter::CopyToCharArrayN(newPath));
259         int ret = symlink("./res", pResPath.get());
260         smackManager.AddLabelDir(pContext->__packageId, newPath);
261 #endif
262
263 #if 0
264         oldPath = appRootPath + DIR_DATA;
265         newPath = appRootPath + L"/Home";
266         InstallerUtil::CreateSymlink(oldPath, newPath);
267 #else
268         newPath = appRootPath + L"/Home";
269         std::unique_ptr< char[] > pHomePath(_StringConverter::CopyToCharArrayN(newPath));
270         ret = symlink("./data", pHomePath.get());
271         smackManager.AddLabelDir(pContext->__packageId, newPath);
272 #endif
273
274         oldPath = appRootPath + DIR_RES + L"/screen-size-normal";
275         newPath = appRootPath + L"/Res/ScreenSize-Normal";
276         InstallerUtil::CreateSymlink(oldPath, newPath);
277
278         oldPath = appRootPath + DIR_RES + L"/screen-density-high";
279         newPath = appRootPath + L"/Res/ScreenDensity-High";
280         InstallerUtil::CreateSymlink(oldPath, newPath);
281
282         oldPath = appRootPath + DIR_RES + L"/screen-density-middle";
283         newPath = appRootPath + L"/Res/ScreenDensity-Middle";
284         InstallerUtil::CreateSymlink(oldPath, newPath);
285
286         oldPath = appRootPath + DIR_RES + L"/screen-density-low";
287         newPath = appRootPath + L"/Res/ScreenDensity-Low";
288         InstallerUtil::CreateSymlink(oldPath, newPath);
289
290         return true;
291 }
292
293 bool
294 PermissionManager::CopyForRds(InstallationContext* pContext, IList* pFileList, bool& isInstallRequired)
295 {
296         TryReturn(pFileList, false, "pFileList is null.");
297
298         for (int idx = 0; idx < pFileList->GetCount(); idx++)
299         {
300                 String* pFilePath = static_cast<String *>(pFileList->GetAt(idx));
301                 TryReturn(pFilePath, false, "pFilePath is null.");
302
303                 String srcFile = DIR_APPLICATIONS_TMP;
304                 srcFile += L"/" + pContext->__packageId + L"/" + *pFilePath;
305                 String destFile = pContext->__rootPath + L"/" + *pFilePath;
306
307                 AppLog("copy file from[%ls] to[%ls]", srcFile.GetPointer(), destFile.GetPointer());
308
309                 int pos = 0;
310                 result r = E_SUCCESS;
311                 String destDir;
312
313                 if (destFile.EndsWith(L"/") == true)
314                 {
315                         destDir = destFile;
316                         if (File::IsFileExist(destDir) == false)
317                         {
318                                 Directory::Create(destDir, true);
319                         }
320                         continue;
321                 }
322                 else
323                 {
324                         r = destFile.LastIndexOf(L'/', destFile.GetLength() -1, pos);
325                         if (IsFailed(r) == true)
326                         {
327                                 AppLog("destFile is invalid[%ls]", destFile.GetPointer());
328                                 continue;
329                         }
330                         destFile.SubString(0, pos, destDir);
331                 }
332
333                 if (File::IsFileExist(destDir) == false)
334                 {
335                         Directory::Create(destDir, true);
336                 }
337
338                 InstallerUtil::Remove(destFile);
339                 r = File::Copy(srcFile, destFile, true);
340                 if (IsFailed(r) == true)
341                 {
342                         AppLog("File::Copy() failed. [%ls] -> [%ls]", srcFile.GetPointer(), destFile.GetPointer());
343                         continue;
344                 }
345
346                 if (*pFilePath == L"info/manifest.xml")
347                 {
348                         AppLog("Install required, [%ls] is found", pFilePath->GetPointer());
349                         isInstallRequired = true;
350                 }
351                 else if (pFilePath->StartsWith("setting/setting", 0) == true)
352                 {
353                         AppLog("Install required, [%ls] is found", pFilePath->GetPointer());
354                         isInstallRequired = true;
355                 }
356         }
357
358         return true;
359 }
360
361 bool
362 PermissionManager::ApplyPermissionForRds(InstallationContext* pContext)
363 {
364         String destPath;
365         String appRootPath;
366         SmackManager smackManager;
367         smackManager.Construct(pContext);
368
369         appRootPath = pContext->__rootPath;
370         PackageId packageId = pContext->__packageId;
371
372         // appRoot
373         InstallerUtil::ChangeMode(appRootPath, PERM_BASE | PERM_EXECUTE);
374         smackManager.AddLabelDir(packageId, appRootPath, true);
375
376         // appRoot/bin
377         destPath = appRootPath + DIR_BIN;
378         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE | PERM_EXECUTE, false);
379         smackManager.AddLabelDir(packageId, destPath);
380
381         // appRoot/info
382         destPath = appRootPath + DIR_INFO;
383         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, false);
384         smackManager.AddLabelDir(packageId, destPath);
385
386         // appRoot/res
387         destPath = appRootPath + DIR_RES;
388         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, false);
389         smackManager.AddLabelDir(packageId, destPath);
390
391         // appRoot/lib
392         destPath = appRootPath + DIR_LIB;
393         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE | PERM_EXECUTE, false);
394         smackManager.AddLabelDir(packageId, destPath);
395
396         // appRoot/shared
397         destPath = appRootPath + DIR_SHARED;
398         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, false);
399         smackManager.AddLabelDir(packageId, destPath);
400
401         // appRoot/shared/res
402         destPath = appRootPath + DIR_SHARED_RES;
403         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, false);
404         smackManager.AddLabelSharedDir(packageId, destPath);
405
406         // appRoot/shared/data
407         destPath = appRootPath + DIR_SHARED_DATA;
408         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, true);
409         smackManager.AddLabelSharedDir(packageId, destPath);
410
411         // appRoot/shared/trusted
412         destPath = appRootPath + DIR_SHARED_TRUSTED;
413         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, true);
414         smackManager.AddLabelSharedDir(packageId, destPath);
415
416         // appRoot/setting
417         destPath = appRootPath + DIR_SETTING;
418         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE | PERM_WRITE, false);
419         smackManager.AddLabelDir(packageId, destPath);
420
421         // appRoot/data
422         destPath = appRootPath + DIR_DATA;
423         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, true);
424         smackManager.AddLabelDir(packageId, destPath);
425
426         return true;
427 }
428
429 #if 0
430 bool
431 PermissionManager::ApplyPermission(InstallationContext* pContext, const IList* pFileList)
432 {
433         TryReturn(pContext, false, "pContext is null");
434         TryReturn(pFileList, false, "pFileList is null");
435
436         // dir | type | owner | mode | smack
437         static RdsPermssions perms[] =
438         {
439                 {"res",                         PERM_DIR_RES,                           PERM_OWNER_ROOT,        PERM_BASE,                                              PERM_SMACK_0},
440                 {"data",                        PERM_DIR_DATA,                          PERM_OWNER_APP,         PERM_BASE,                                              PERM_SMACK_0},
441                 {"bin",                         PERM_DIR_BIN,                           PERM_OWNER_ROOT,        (PERM_BASE | PERM_EXECUTE),             PERM_SMACK_0},
442                 {"info",                        PERM_DIR_INFO,                          PERM_OWNER_ROOT,        PERM_BASE,                                              PERM_SMACK_0},
443                 {"lib",                         PERM_DIR_LIB,                           PERM_OWNER_ROOT,        (PERM_BASE | PERM_EXECUTE),             PERM_SMACK_0},
444                 {"setting",                     PERM_DIR_SETTING,                       PERM_OWNER_ROOT,        (PERM_BASE | PERM_WRITE),               PERM_SMACK_0},
445                 {"shared/res",          PERM_DIR_SHARED_RES,            PERM_OWNER_ROOT,        PERM_BASE,                                              PERM_SMACK_0},
446                 {"shared/data",         PERM_DIR_SHARED_DATA,           PERM_OWNER_APP,         PERM_BASE,                                              PERM_SMACK_0},
447                 {"shared/trusted",      PERM_DIR_SHARED_TRUSTED,        PERM_OWNER_APP,         PERM_BASE,                                              PERM_SMACK_0},
448                 {"shared",                      PERM_DIR_SHARED,                        PERM_OWNER_ROOT,        PERM_BASE,                                              PERM_SMACK_0},
449                 {"author",                      PERM_DIR_ROOT,                          PERM_OWNER_ROOT,        PERM_BASE,                                              PERM_SMACK_0},
450                 {"signature",           PERM_DIR_ROOT,                          PERM_OWNER_ROOT,        PERM_BASE,                                              PERM_SMACK_0},
451         };
452
453         static int permCount = sizeof(perms) / sizeof(RdsPermssions);
454         bool isInstallRequired = false;
455         SmackManager smackManager;
456         smackManager.Construct(pContext);
457
458         for (int i = 0; i < pFileList->GetCount(); i++)
459         {
460                 const String *pFilePath = static_cast<const String *>(pFileList->GetAt(i));
461                 TryReturn(pFilePath, false, "pFilePath is null");
462
463                 AppLog("pFilePath=(%ls)", pFilePath->GetPointer());
464
465                 int permIdx = 0;
466                 for (permIdx = 0; permIdx < permCount; permIdx++)
467                 {
468                         if (pFilePath->StartsWith(perms[permIdx].pDir, 0) == true)
469                         {
470                                 if (perms[permIdx].dirType == PERM_DIR_INFO)
471                                 {
472                                         if (*pFilePath == L"info/manifest.xml")
473                                         {
474                                                 AppLog("Install required, [%ls] is found", pFilePath->GetPointer());
475                                                 isInstallRequired = true;
476                                         }
477                                 }
478                                 else if (perms[permIdx].dirType == PERM_DIR_SETTING)
479                                 {
480                                         if (pFilePath->StartsWith("setting/setting", 0) == true)
481                                         {
482                                                 AppLog("Install required, [%ls] is found", pFilePath->GetPointer());
483                                                 isInstallRequired = true;
484                                         }
485                                 }
486
487                                 AppLog("dirType=(%d), owner=(%d), mode=(%d), smack=(%d)",
488                                                 perms[permIdx].dirType, perms[permIdx].ownerIndex, perms[permIdx].modeIndex, perms[permIdx].smackIndex);
489
490                                 String srcFile = DIR_APPLICATIONS_TMP;
491                                 srcFile += L"/" + pContext->__packageId + L"/" + *pFilePath;
492                                 String destFile = pContext->__rootPath + L"/" + *pFilePath;
493
494                                 AppLog("copy file: from[%ls] to[%ls]", srcFile.GetPointer(), destFile.GetPointer());
495                                 File::Copy(srcFile, destFile, false);
496
497                                 bool isAppOwner = false;
498                                 if (perms[permIdx].ownerIndex == PERM_OWNER_APP)
499                                 {
500                                         isAppOwner = true;
501                                 }
502
503                                 String destPath;
504                                 if (perms[permIdx].dirType != PERM_DIR_ROOT)
505                                 {
506                                         destPath = pContext->__rootPath + L"/" + perms[permIdx].pDir;
507                                         InstallerUtil::ChangeDirectoryPermission(destPath, perms[permIdx].modeIndex, isAppOwner);
508                                 }
509                                 else
510                                 {
511                                         destPath = pContext->__rootPath + L"/" + *pFilePath;
512                                         InstallerUtil::ChangeMode(*pFilePath, perms[permIdx].modeIndex);
513                                 }
514                                 smackManager.AddLabelSharedDir(pContext->__packageId, destPath);
515
516                                 break;
517                         }
518                 }
519         }
520
521         return true;
522 }
523 #endif
524
525