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