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