Add smack label for preloaded app
[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), INSTALLER_ERROR_INTERNAL_STATE, "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         AppLog("------------------------------------------");
194
195         return true;
196 }
197
198 bool
199 PermissionManager::SetFile(InstallationContext* pContext)
200 {
201         String destPath;
202         String appRootPath = pContext->__rootPath;
203
204         IListT<AppData*>* pAppDataList = pContext->__pAppDataList;
205         TryReturn(pAppDataList, false, "pAppDataList is null");
206
207         for (int i = 0 ; i < pAppDataList->GetCount(); i++)
208         {
209                 AppData* pAppData = null;
210                 pAppDataList->GetAt(i, pAppData);
211                 TryReturn(pAppData, false, "pAppData is null");
212
213                 // set permission(755) to bin file.
214                 destPath = appRootPath + DIR_BIN + L"/" + pAppData->__name + L".exe";
215                 if (File::IsFileExist(destPath) == true)
216                 {
217                         InstallerUtil::ChangeMode(destPath, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
218                 }
219         }
220
221         return true;
222 }
223
224 bool
225 PermissionManager::SetSymLink(InstallationContext* pContext)
226 {
227         String oldPath;
228         String newPath;
229         String appRootPath = pContext->__rootPath;
230
231 #if 0
232         oldPath = appRootPath + DIR_RES;
233         newPath = appRootPath + L"/Res";
234         InstallerUtil::CreateSymlink(oldPath, newPath);
235 #else
236         newPath = appRootPath + L"/Res";
237         std::unique_ptr< char[] > pResPath(_StringConverter::CopyToCharArrayN(newPath));
238         int ret = symlink("./res", pResPath.get());
239 #endif
240
241 #if 0
242         oldPath = appRootPath + DIR_DATA;
243         newPath = appRootPath + L"/Home";
244         InstallerUtil::CreateSymlink(oldPath, newPath);
245 #else
246         newPath = appRootPath + L"/Home";
247         std::unique_ptr< char[] > pHomePath(_StringConverter::CopyToCharArrayN(newPath));
248         ret = symlink("./data", pHomePath.get());
249 #endif
250
251         oldPath = appRootPath + DIR_RES + L"/screen-size-normal";
252         newPath = appRootPath + L"/Res/ScreenSize-Normal";
253         InstallerUtil::CreateSymlink(oldPath, newPath);
254
255         oldPath = appRootPath + DIR_RES + L"/screen-density-high";
256         newPath = appRootPath + L"/Res/ScreenDensity-High";
257         InstallerUtil::CreateSymlink(oldPath, newPath);
258
259         oldPath = appRootPath + DIR_RES + L"/screen-density-middle";
260         newPath = appRootPath + L"/Res/ScreenDensity-Middle";
261         InstallerUtil::CreateSymlink(oldPath, newPath);
262
263         oldPath = appRootPath + DIR_RES + L"/screen-density-low";
264         newPath = appRootPath + L"/Res/ScreenDensity-Low";
265         InstallerUtil::CreateSymlink(oldPath, newPath);
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                 File::Copy(srcFile, destFile, true);
316
317                 if (*pFilePath == L"info/manifest.xml")
318                 {
319                         AppLog("Install required, [%ls] is found", pFilePath->GetPointer());
320                         isInstallRequired = true;
321                 }
322                 else if (pFilePath->StartsWith("setting/setting", 0) == true)
323                 {
324                         AppLog("Install required, [%ls] is found", pFilePath->GetPointer());
325                         isInstallRequired = true;
326                 }
327         }
328
329         return true;
330 }
331
332 bool
333 PermissionManager::ApplyPermissionForRds(InstallationContext* pContext)
334 {
335         String destPath;
336         String appRootPath;
337         SmackManager smackManager;
338         smackManager.Construct(pContext);
339
340         appRootPath = pContext->__rootPath;
341         PackageId packageId = pContext->__packageId;
342
343         // appRoot
344         InstallerUtil::ChangeMode(appRootPath, PERM_BASE | PERM_EXECUTE);
345         smackManager.AddLabelDir(packageId, appRootPath, true);
346
347         // appRoot/bin
348         destPath = appRootPath + DIR_BIN;
349         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE | PERM_EXECUTE, false);
350         smackManager.AddLabelDir(packageId, destPath);
351
352         // appRoot/info
353         destPath = appRootPath + DIR_INFO;
354         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, false);
355         smackManager.AddLabelDir(packageId, destPath);
356
357         // appRoot/res
358         destPath = appRootPath + DIR_RES;
359         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, false);
360         smackManager.AddLabelDir(packageId, destPath);
361
362         // appRoot/lib
363         destPath = appRootPath + DIR_LIB;
364         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE | PERM_EXECUTE, false);
365         smackManager.AddLabelDir(packageId, destPath);
366
367         // appRoot/shared
368         destPath = appRootPath + DIR_SHARED;
369         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, false);
370         smackManager.AddLabelDir(packageId, destPath);
371
372         // appRoot/shared/res
373         destPath = appRootPath + DIR_SHARED_RES;
374         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, false);
375         smackManager.AddLabelSharedDir(packageId, destPath);
376
377         // appRoot/shared/data
378         destPath = appRootPath + DIR_SHARED_DATA;
379         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, true);
380         smackManager.AddLabelSharedDir(packageId, destPath);
381
382         // appRoot/shared/trusted
383         destPath = appRootPath + DIR_SHARED_TRUSTED;
384         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, true);
385         smackManager.AddLabelSharedDir(packageId, destPath);
386
387         // appRoot/setting
388         destPath = appRootPath + DIR_SETTING;
389         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE | PERM_WRITE, false);
390         smackManager.AddLabelDir(packageId, destPath);
391
392         // appRoot/data
393         destPath = appRootPath + DIR_DATA;
394         InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, true);
395         smackManager.AddLabelDir(packageId, destPath);
396
397         return true;
398 }
399
400 #if 0
401 bool
402 PermissionManager::ApplyPermission(InstallationContext* pContext, const IList* pFileList)
403 {
404         TryReturn(pContext, false, "pContext is null");
405         TryReturn(pFileList, false, "pFileList is null");
406
407         // dir | type | owner | mode | smack
408         static RdsPermssions perms[] =
409         {
410                 {"res",                         PERM_DIR_RES,                           PERM_OWNER_ROOT,        PERM_BASE,                                              PERM_SMACK_0},
411                 {"data",                        PERM_DIR_DATA,                          PERM_OWNER_APP,         PERM_BASE,                                              PERM_SMACK_0},
412                 {"bin",                         PERM_DIR_BIN,                           PERM_OWNER_ROOT,        (PERM_BASE | PERM_EXECUTE),             PERM_SMACK_0},
413                 {"info",                        PERM_DIR_INFO,                          PERM_OWNER_ROOT,        PERM_BASE,                                              PERM_SMACK_0},
414                 {"lib",                         PERM_DIR_LIB,                           PERM_OWNER_ROOT,        (PERM_BASE | PERM_EXECUTE),             PERM_SMACK_0},
415                 {"setting",                     PERM_DIR_SETTING,                       PERM_OWNER_ROOT,        (PERM_BASE | PERM_WRITE),               PERM_SMACK_0},
416                 {"shared/res",          PERM_DIR_SHARED_RES,            PERM_OWNER_ROOT,        PERM_BASE,                                              PERM_SMACK_0},
417                 {"shared/data",         PERM_DIR_SHARED_DATA,           PERM_OWNER_APP,         PERM_BASE,                                              PERM_SMACK_0},
418                 {"shared/trusted",      PERM_DIR_SHARED_TRUSTED,        PERM_OWNER_APP,         PERM_BASE,                                              PERM_SMACK_0},
419                 {"shared",                      PERM_DIR_SHARED,                        PERM_OWNER_ROOT,        PERM_BASE,                                              PERM_SMACK_0},
420                 {"author",                      PERM_DIR_ROOT,                          PERM_OWNER_ROOT,        PERM_BASE,                                              PERM_SMACK_0},
421                 {"signature",           PERM_DIR_ROOT,                          PERM_OWNER_ROOT,        PERM_BASE,                                              PERM_SMACK_0},
422         };
423
424         static int permCount = sizeof(perms) / sizeof(RdsPermssions);
425         bool isInstallRequired = false;
426         SmackManager smackManager;
427         smackManager.Construct(pContext);
428
429         for (int i = 0; i < pFileList->GetCount(); i++)
430         {
431                 const String *pFilePath = static_cast<const String *>(pFileList->GetAt(i));
432                 TryReturn(pFilePath, false, "pFilePath is null");
433
434                 AppLog("pFilePath=(%ls)", pFilePath->GetPointer());
435
436                 int permIdx = 0;
437                 for (permIdx = 0; permIdx < permCount; permIdx++)
438                 {
439                         if (pFilePath->StartsWith(perms[permIdx].pDir, 0) == true)
440                         {
441                                 if (perms[permIdx].dirType == PERM_DIR_INFO)
442                                 {
443                                         if (*pFilePath == L"info/manifest.xml")
444                                         {
445                                                 AppLog("Install required, [%ls] is found", pFilePath->GetPointer());
446                                                 isInstallRequired = true;
447                                         }
448                                 }
449                                 else if (perms[permIdx].dirType == PERM_DIR_SETTING)
450                                 {
451                                         if (pFilePath->StartsWith("setting/setting", 0) == true)
452                                         {
453                                                 AppLog("Install required, [%ls] is found", pFilePath->GetPointer());
454                                                 isInstallRequired = true;
455                                         }
456                                 }
457
458                                 AppLog("dirType=(%d), owner=(%d), mode=(%d), smack=(%d)",
459                                                 perms[permIdx].dirType, perms[permIdx].ownerIndex, perms[permIdx].modeIndex, perms[permIdx].smackIndex);
460
461                                 String srcFile = DIR_APPLICATIONS_TMP;
462                                 srcFile += L"/" + pContext->__packageId + L"/" + *pFilePath;
463                                 String destFile = pContext->__rootPath + L"/" + *pFilePath;
464
465                                 AppLog("copy file: from[%ls] to[%ls]", srcFile.GetPointer(), destFile.GetPointer());
466                                 File::Copy(srcFile, destFile, false);
467
468                                 bool isAppOwner = false;
469                                 if (perms[permIdx].ownerIndex == PERM_OWNER_APP)
470                                 {
471                                         isAppOwner = true;
472                                 }
473
474                                 String destPath;
475                                 if (perms[permIdx].dirType != PERM_DIR_ROOT)
476                                 {
477                                         destPath = pContext->__rootPath + L"/" + perms[permIdx].pDir;
478                                         InstallerUtil::ChangeDirectoryPermission(destPath, perms[permIdx].modeIndex, isAppOwner);
479                                 }
480                                 else
481                                 {
482                                         destPath = pContext->__rootPath + L"/" + *pFilePath;
483                                         InstallerUtil::ChangeMode(*pFilePath, perms[permIdx].modeIndex);
484                                 }
485                                 smackManager.AddLabelSharedDir(pContext->__packageId, destPath);
486
487                                 break;
488                         }
489                 }
490         }
491
492         return true;
493 }
494 #endif
495
496