2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
9 // http://www.apache.org/licenses/LICENSE-2.0
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.
18 * @file PermissionManager.cpp
19 * @brief This is the implementation file for %PermissionManager class.
25 #include <unique_ptr.h>
27 #include <FBaseUtilStringUtil.h>
29 #include <FIoDirectory.h>
30 #include <FBase_StringConverter.h>
31 #include <FIo_FileImpl.h>
33 #include "PermissionManager.h"
34 #include "InstallerUtil.h"
35 #include "SmackManager.h"
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;
43 PermissionManager::PermissionManager(void)
47 PermissionManager::~PermissionManager(void)
52 PermissionManager::SetDirectory(InstallationContext* pContext)
58 SmackManager smackManager;
59 smackManager.Construct(pContext);
61 appRootPath = pContext->__rootPath;
62 PackageId packageId = pContext->__packageId;
65 // InstallerUtil::ChangeOwner(appRootPath);
66 InstallerUtil::ChangeMode(appRootPath, PERM_BASE | PERM_EXECUTE);
67 smackManager.AddLabelDir(packageId, appRootPath, true);
69 if (pContext->__isPreloaded == true)
71 String preloadedAppPath(PATH_USR_APPS);
72 preloadedAppPath += L"/";
73 preloadedAppPath += packageId;
75 smackManager.AddLabelDir(L"_", preloadedAppPath, true);
79 destPath = appRootPath + DIR_BIN;
80 InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE | PERM_EXECUTE, false);
81 smackManager.SetupPath(packageId, destPath, SMACK_DIR_TYPE_PRIVATE);
84 destPath = appRootPath + DIR_INFO;
85 InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, false);
86 smackManager.SetupPath(packageId, destPath, SMACK_DIR_TYPE_PRIVATE);
89 destPath = appRootPath + DIR_RES;
90 InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, false);
91 smackManager.SetupPath(packageId, destPath, SMACK_DIR_TYPE_PRIVATE);
94 destPath = appRootPath + DIR_LIB;
95 InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE | PERM_EXECUTE, false);
96 smackManager.SetupPath(packageId, destPath, SMACK_DIR_TYPE_PRIVATE);
99 destPath = appRootPath + DIR_SHARED;
100 if (File::IsFileExist(destPath) == false)
102 r = Directory::Create(destPath, false);
103 TryReturn(!IsFailed(r), INSTALLER_ERROR_INTERNAL_STATE, "Directory::Create() failed");
105 InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, false);
107 // appRoot/shared/res
108 destPath = appRootPath + DIR_SHARED_RES;
109 if (File::IsFileExist(destPath) == false)
111 String iconPath = appRootPath + DIR_ICONS;
112 InstallerUtil::CreateSymlink(iconPath, destPath);
114 InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, false);
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);
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);
127 destPath = appRootPath + DIR_CONTENTS;
128 InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, false);
129 smackManager.SetupPath(packageId, destPath, SMACK_DIR_TYPE_PRIVATE);
132 destPath = appRootPath + DIR_SETTING;
133 if (File::IsFileExist(destPath) == true)
135 String appVersion = pContext->__version;
137 String settingXmlPath;
138 srcPath = destPath + L"/setting." + appVersion + L".xml";
139 settingXmlPath = destPath + L"/setting.xml";
141 InstallerUtil::Remove(settingXmlPath);
142 InstallerUtil::CreateSymlink(srcPath, settingXmlPath);
144 InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE | PERM_WRITE, false);
145 smackManager.SetupPath(packageId, destPath, SMACK_DIR_TYPE_SETTINGS_RW);
149 destPath = appRootPath + DIR_DATA;
150 if (File::IsFileExist(destPath) == false)
152 r = Directory::Create(destPath, false);
153 TryReturn(!IsFailed(r), false, "Directory::Create() failed");
155 InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, true);
156 smackManager.SetupPath(packageId, destPath, SMACK_DIR_TYPE_PRIVATE);
158 String apiVersion = pContext->__apiVersion;
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());
165 if (pContext->__isOspCompat == true)
167 AppLog("[Tizen::Io] OSP 2.0 application");
169 if (_FileImpl::PrepareDataCaging(appRootPath, packageId) == false)
171 AppLog("[Tizen::Io] _FileImpl::PrepareDataCaging() failed");
175 SetSymLink(pContext);
179 AppLog("[Tizen::Io] apiVersion is equal to or greater than Tizen 2.0");
181 if (_FileImpl::CreateOspApplicationDirectories(appRootPath, packageId) == false)
183 AppLog("[Tizen::Io] _FileImpl::CreateOspApplicationDirectories() failed");
188 if (pContext->__isVirtualRoot == true)
190 if (pContext->__pSymbolicLinkList->GetCount() > 0)
192 std::unique_ptr< IMapEnumeratorT<String*, String*> > pEnum(pContext->__pSymbolicLinkList->GetMapEnumeratorN());
193 TryReturn(pEnum, false, "pSymbolicLinkList->GetMapEnumeratorN() failed.");
194 while (pEnum->MoveNext() == E_SUCCESS)
197 String* pValue = null;
200 pEnum->GetValue(pValue);
202 AppLog("SymbolicLink - Src = [%ls], Des = [%ls]", pKey->GetPointer(), pValue->GetPointer());
206 AppLog("------------------------------------------");
212 PermissionManager::SetFile(InstallationContext* pContext)
215 String appRootPath = pContext->__rootPath;
217 IListT<AppData*>* pAppDataList = pContext->__pAppDataList;
218 TryReturn(pAppDataList, false, "pAppDataList is null");
220 for (int i = 0 ; i < pAppDataList->GetCount(); i++)
222 AppData* pAppData = null;
223 pAppDataList->GetAt(i, pAppData);
224 TryReturn(pAppData, false, "pAppData is null");
226 // set permission(755) to bin file.
227 destPath = appRootPath + DIR_BIN + L"/" + pAppData->__name + L".exe";
228 if (File::IsFileExist(destPath) == true)
230 InstallerUtil::ChangeMode(destPath, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
238 PermissionManager::SetSymLink(InstallationContext* pContext)
242 String appRootPath = pContext->__rootPath;
245 oldPath = appRootPath + DIR_RES;
246 newPath = appRootPath + L"/Res";
247 InstallerUtil::CreateSymlink(oldPath, newPath);
249 newPath = appRootPath + L"/Res";
250 std::unique_ptr< char[] > pResPath(_StringConverter::CopyToCharArrayN(newPath));
251 int ret = symlink("./res", pResPath.get());
255 oldPath = appRootPath + DIR_DATA;
256 newPath = appRootPath + L"/Home";
257 InstallerUtil::CreateSymlink(oldPath, newPath);
259 newPath = appRootPath + L"/Home";
260 std::unique_ptr< char[] > pHomePath(_StringConverter::CopyToCharArrayN(newPath));
261 ret = symlink("./data", pHomePath.get());
264 oldPath = appRootPath + DIR_RES + L"/screen-size-normal";
265 newPath = appRootPath + L"/Res/ScreenSize-Normal";
266 InstallerUtil::CreateSymlink(oldPath, newPath);
268 oldPath = appRootPath + DIR_RES + L"/screen-density-high";
269 newPath = appRootPath + L"/Res/ScreenDensity-High";
270 InstallerUtil::CreateSymlink(oldPath, newPath);
272 oldPath = appRootPath + DIR_RES + L"/screen-density-middle";
273 newPath = appRootPath + L"/Res/ScreenDensity-Middle";
274 InstallerUtil::CreateSymlink(oldPath, newPath);
276 oldPath = appRootPath + DIR_RES + L"/screen-density-low";
277 newPath = appRootPath + L"/Res/ScreenDensity-Low";
278 InstallerUtil::CreateSymlink(oldPath, newPath);
284 PermissionManager::CopyForRds(InstallationContext* pContext, IList* pFileList, bool& isInstallRequired)
286 TryReturn(pFileList, false, "pFileList is null.");
288 for (int idx = 0; idx < pFileList->GetCount(); idx++)
290 String* pFilePath = static_cast<String *>(pFileList->GetAt(idx));
291 TryReturn(pFilePath, false, "pFilePath is null.");
293 String srcFile = DIR_APPLICATIONS_TMP;
294 srcFile += L"/" + pContext->__packageId + L"/" + *pFilePath;
295 String destFile = pContext->__rootPath + L"/" + *pFilePath;
297 AppLog("copy file from[%ls] to[%ls]", srcFile.GetPointer(), destFile.GetPointer());
300 result r = E_SUCCESS;
303 if (destFile.EndsWith(L"/") == true)
306 if (File::IsFileExist(destDir) == false)
308 Directory::Create(destDir, true);
314 r = destFile.LastIndexOf(L'/', destFile.GetLength() -1, pos);
315 if (IsFailed(r) == true)
317 AppLog("destFile is invalid[%ls]", destFile.GetPointer());
320 destFile.SubString(0, pos, destDir);
323 if (File::IsFileExist(destDir) == false)
325 Directory::Create(destDir, true);
327 InstallerUtil::Remove(destFile);
328 File::Copy(srcFile, destFile, true);
330 if (*pFilePath == L"info/manifest.xml")
332 AppLog("Install required, [%ls] is found", pFilePath->GetPointer());
333 isInstallRequired = true;
335 else if (pFilePath->StartsWith("setting/setting", 0) == true)
337 AppLog("Install required, [%ls] is found", pFilePath->GetPointer());
338 isInstallRequired = true;
346 PermissionManager::ApplyPermissionForRds(InstallationContext* pContext)
350 SmackManager smackManager;
351 smackManager.Construct(pContext);
353 appRootPath = pContext->__rootPath;
354 PackageId packageId = pContext->__packageId;
357 InstallerUtil::ChangeMode(appRootPath, PERM_BASE | PERM_EXECUTE);
358 smackManager.AddLabelDir(packageId, appRootPath, true);
361 destPath = appRootPath + DIR_BIN;
362 InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE | PERM_EXECUTE, false);
363 smackManager.SetupPath(packageId, destPath, SMACK_DIR_TYPE_PRIVATE);
366 destPath = appRootPath + DIR_INFO;
367 InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, false);
368 smackManager.SetupPath(packageId, destPath, SMACK_DIR_TYPE_PRIVATE);
371 destPath = appRootPath + DIR_RES;
372 InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, false);
373 smackManager.SetupPath(packageId, destPath, SMACK_DIR_TYPE_PRIVATE);
376 destPath = appRootPath + DIR_LIB;
377 InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE | PERM_EXECUTE, false);
378 smackManager.SetupPath(packageId, destPath, SMACK_DIR_TYPE_PRIVATE);
381 destPath = appRootPath + DIR_SHARED;
382 InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, false);
384 // appRoot/shared/res
385 destPath = appRootPath + DIR_SHARED_RES;
386 InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, false);
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);
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);
399 destPath = appRootPath + DIR_SETTING;
400 InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE | PERM_WRITE, false);
401 smackManager.SetupPath(packageId, destPath, SMACK_DIR_TYPE_SETTINGS_RW);
404 destPath = appRootPath + DIR_DATA;
405 InstallerUtil::ChangeDirectoryPermission(destPath, PERM_BASE, true);
406 smackManager.SetupPath(packageId, destPath, SMACK_DIR_TYPE_PRIVATE);
413 PermissionManager::ApplyPermission(InstallationContext* pContext, const IList* pFileList)
415 TryReturn(pContext, false, "pContext is null");
416 TryReturn(pFileList, false, "pFileList is null");
418 // dir | type | owner | mode | smack
419 static RdsPermssions perms[] =
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},
435 static int permCount = sizeof(perms) / sizeof(RdsPermssions);
436 bool isInstallRequired = false;
437 SmackManager smackManager;
438 smackManager.Construct(pContext);
440 for (int i = 0; i < pFileList->GetCount(); i++)
442 const String *pFilePath = static_cast<const String *>(pFileList->GetAt(i));
443 TryReturn(pFilePath, false, "pFilePath is null");
445 AppLog("pFilePath=(%ls)", pFilePath->GetPointer());
448 for (permIdx = 0; permIdx < permCount; permIdx++)
450 if (pFilePath->StartsWith(perms[permIdx].pDir, 0) == true)
452 if (perms[permIdx].dirType == PERM_DIR_INFO)
454 if (*pFilePath == L"info/manifest.xml")
456 AppLog("Install required, [%ls] is found", pFilePath->GetPointer());
457 isInstallRequired = true;
460 else if (perms[permIdx].dirType == PERM_DIR_SETTING)
462 if (pFilePath->StartsWith("setting/setting", 0) == true)
464 AppLog("Install required, [%ls] is found", pFilePath->GetPointer());
465 isInstallRequired = true;
469 AppLog("dirType=(%d), owner=(%d), mode=(%d), smack=(%d)",
470 perms[permIdx].dirType, perms[permIdx].ownerIndex, perms[permIdx].modeIndex, perms[permIdx].smackIndex);
472 String srcFile = DIR_APPLICATIONS_TMP;
473 srcFile += L"/" + pContext->__packageId + L"/" + *pFilePath;
474 String destFile = pContext->__rootPath + L"/" + *pFilePath;
476 AppLog("copy file: from[%ls] to[%ls]", srcFile.GetPointer(), destFile.GetPointer());
477 File::Copy(srcFile, destFile, false);
479 bool isAppOwner = false;
480 if (perms[permIdx].ownerIndex == PERM_OWNER_APP)
486 if (perms[permIdx].dirType != PERM_DIR_ROOT)
488 destPath = pContext->__rootPath + L"/" + perms[permIdx].pDir;
489 InstallerUtil::ChangeDirectoryPermission(destPath, perms[permIdx].modeIndex, isAppOwner);
493 destPath = pContext->__rootPath + L"/" + *pFilePath;
494 InstallerUtil::ChangeMode(*pFilePath, perms[permIdx].modeIndex);
496 smackManager.AddLabelSharedDir(pContext->__packageId, destPath);