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