1fc40121e25adb0b238f8254cbb39d0b4486c79c
[platform/framework/native/installer.git] / src / Manager / SmackManager.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        SmackManager.cpp
19  * @brief       This is the implementation file for %SmackManager class.
20  */
21
22 #include <dlfcn.h>
23 #include <unique_ptr.h>
24
25 #include <FIoFile.h>
26 #include <FIoRegistry.h>
27 #include <FSecCryptoSha1Hash.h>
28 #include <FBase_StringConverter.h>
29
30 #include "SmackManager.h"
31 #include "InstallerDefs.h"
32 #include "InstallerUtil.h"
33
34 using namespace Tizen::App;
35 using namespace Tizen::Base;
36 using namespace Tizen::Base::Collection;
37 using namespace Tizen::Base::Utility;
38 using namespace Tizen::Security::Cert;
39 using namespace Tizen::Security::Crypto;
40 using namespace Tizen::Io;
41
42 SmackManager::SmackManager(void)
43 :__pContext(null)
44 ,__isSmackEnable(false)
45 {
46         if (IsSmackEnable() == true)
47         {
48                 __isSmackEnable = true;
49         }
50 }
51
52 SmackManager::~SmackManager(void)
53 {
54 }
55
56 bool
57 SmackManager::Construct(InstallationContext* pContext)
58 {
59         __pContext = pContext;
60
61         return true;
62 }
63
64 bool
65 SmackManager::Install(const PackageId& packageId)
66 {
67         if (__isSmackEnable == false)
68         {
69                 return true;
70         }
71
72         int res = 0;
73
74         std::unique_ptr<char[]> pPackageId(_StringConverter::CopyToCharArrayN(packageId));
75         TryReturn(pPackageId, false, "pPackageId is null.");
76
77         res = Install(pPackageId.get());
78
79         return true;
80 }
81
82 bool
83 SmackManager::Uninstall(const PackageId& packageId)
84 {
85         if (__isSmackEnable == false)
86         {
87                 return true;
88         }
89
90         int res = 0;
91
92         std::unique_ptr<char[]> pPackageId(_StringConverter::CopyToCharArrayN(packageId));
93         TryReturn(pPackageId, false, "pPackageId is null.");
94
95         res = Uninstall(pPackageId.get());
96
97         return true;
98 }
99
100 bool
101 SmackManager::AddLabelDir(const String& label, const String& dirPath, bool rootDirectory)
102 {
103         if (__isSmackEnable == false)
104         {
105                 return true;
106         }
107
108         int res = 0;
109         String realPath;
110
111         std::unique_ptr<char[]> pPath(_StringConverter::CopyToCharArrayN(dirPath));
112         TryReturn(pPath, false, "pPath is null.");
113
114         if (InstallerUtil::IsSymlink(dirPath) == true)
115         {
116                 res = AddLabelDir("_", pPath.get());
117                 InstallerUtil::GetRealPath(dirPath, realPath);
118         }
119         else
120         {
121                 realPath = dirPath;
122         }
123
124         std::unique_ptr<char[]> pRealPath(_StringConverter::CopyToCharArrayN(realPath));
125         TryReturn(pRealPath, false, "pRealPath is null");
126
127         if (rootDirectory == true)
128         {
129                 res = AddLabelDir("_", pRealPath.get());
130         }
131         else if (dirPath.Contains(L"shared") == true)
132         {
133                 res = AddLabelDir("*", pRealPath.get());
134         }
135         else
136         {
137                 std::unique_ptr<char[]> pPackageId(_StringConverter::CopyToCharArrayN(label));
138                 TryReturn(pPackageId, false, "pPackageId is null");
139
140                 res = AddLabelDir(pPackageId.get(), pRealPath.get());
141         }
142
143         return true;
144 }
145
146 bool
147 SmackManager::AddLabelSharedDir(const PackageId& packageId, const String& dirPath)
148 {
149         if (__isSmackEnable == false)
150         {
151                 return true;
152         }
153
154         TryReturn(__pContext, false, "__pContext is null");
155
156         if (__pContext->__isVerificationMode == false)
157         {
158                 AppLog("VerificationMode is off.");
159                 return true;
160         }
161
162         int res = 0;
163         String label = packageId;
164
165         std::unique_ptr<char[]> pPackageId(_StringConverter::CopyToCharArrayN(packageId));
166         TryReturn(pPackageId, false, "pPackageId is null.");
167
168         std::unique_ptr<char[]> pPath(_StringConverter::CopyToCharArrayN(dirPath));
169         TryReturn(pPath, false, "pPath is null.");
170
171         if (dirPath.Contains(L"shared/data") == true)
172         {
173                 label = L"*";
174                 //label.Append("_shareddata");
175         }
176         else if (dirPath.Contains(L"shared/res") == true)
177         {
178                 label = L"*";
179                 //label.Append("_sharedres");
180         }
181         else if (dirPath.Contains(L"shared/trusted") == true)
182         {
183                 Sha1Hash hash;
184                 String base64Value;
185                 result r = E_SUCCESS;
186
187                 IListT<String *>* pAuthorCertList = __pContext->__pAuthorCertList;
188                 TryReturn(pAuthorCertList, false, "pAuthorCertList is null.");
189
190                 String *pEntity = null;
191                 r = pAuthorCertList->GetAt(0, pEntity);
192                 TryReturn(!IsFailed(r), false, "pAuthorCertList->GetAt() is failed.");
193                 TryReturn(pEntity, false, "pEntity is null.");
194
195                 std::unique_ptr<ByteBuffer> pEncodedData(StringUtil::DecodeBase64StringN(*pEntity));
196                 TryReturn(pEncodedData, false, "pEncodedData is null.");
197
198                 std::unique_ptr<ByteBuffer> pHashValue(hash.GetHashN(*pEncodedData.get()));
199                 TryReturn(pHashValue, false, "pHashValue is null.");
200
201                 r = StringUtil::EncodeToBase64String(*pHashValue, base64Value);
202                 TryReturn(r == E_SUCCESS, false, "EncodeToBase64String() is failed.");
203
204                 std::unique_ptr<char[]> pHashEncodedValue(_StringConverter::CopyToCharArrayN(base64Value));
205                 TryReturn(pHashEncodedValue, false, "pHashEncodedValue is null.");
206
207                 label = pHashEncodedValue.get();
208                 AppLog("pHashEncodedValue = [%s]", pHashEncodedValue.get());
209         }
210         else
211         {
212                 AppLog("Invalid Directory = [%ls]", dirPath.GetPointer());
213                 return false;
214         }
215
216         std::unique_ptr<char[]> pLabel(_StringConverter::CopyToCharArrayN(label));
217         TryReturn(pLabel, false, "pLabel is null.");
218
219         res = AddLabelSharedDir(pPackageId.get(), pLabel.get(), pPath.get());
220
221         return true;
222 }
223
224 bool
225 SmackManager::AddSharedDirReaders(const Tizen::Base::String& label)
226 {
227         if (__isSmackEnable == false)
228         {
229                 return true;
230         }
231
232         //int AddSharedDirReaders(const char* pSharedLabel, const char** ppAppList);
233
234         return true;
235 }
236
237 bool
238 SmackManager::AddFriend(const Tizen::App::PackageId& packageId1, const Tizen::App::PackageId& packageId2)
239 {
240         if (__isSmackEnable == false)
241         {
242                 return true;
243         }
244
245         //int AddFriend(const char* pPackageId1, const char* pPackageId2);
246
247         return true;
248 }
249
250 bool
251 SmackManager::EnablePermissions(const PackageId& packageId)
252 {
253         if (__isSmackEnable == false)
254         {
255                 return true;
256         }
257
258         TryReturn(__pContext, false, "__pContext is null");
259
260         int res = 0;
261
262         std::unique_ptr<char[]> pPackageId(_StringConverter::CopyToCharArrayN(packageId));
263         TryReturn(pPackageId, false, "pPackageId is null.");
264
265         int count = __pContext->__pPrivilegeList->GetCount();
266
267         const char** pList = new (std::nothrow) const char*[count+1];
268         TryReturn(pList, false, "pList is null.");
269
270         for (int i = 0; i < count; i++)
271         {
272                 String* pPrivilege = dynamic_cast < String* >(__pContext->__pPrivilegeList->GetAt(i));
273                 if (pPrivilege)
274                 {
275                         char* pPrivilegeString = _StringConverter::CopyToCharArrayN(*pPrivilege);
276                         TryReturn(pPrivilegeString, false, "pPrivilegeString is null.");
277
278                         pList[i] = pPrivilegeString;
279                 }
280          }
281
282         pList[count] = null;
283
284         res = EnablePermissions(pPackageId.get(), 1, pList, true);
285
286         if (__pContext->__isPreloaded == true)
287         {
288                 String smackFile(L"/etc/smack/accesses2.d/");
289                 smackFile.Append(packageId);
290                 smackFile.Append(L"-temp.rule");
291
292                 String smackContext(packageId);
293                 smackContext.Append(L" all.rule include");
294
295                 InstallerUtil::CreateInfoFile(smackFile, &smackContext);
296         }
297         else
298         {
299                 String script("/usr/bin/smackload-app.sh");
300                 bool exist = File::IsFileExist(script);
301                 script.Append(L" ");
302                 script.Append(packageId);
303
304                 std::unique_ptr<char[]> pScript(_StringConverter::CopyToCharArrayN(script));
305                 TryReturn(pScript, false, "pScript is null.");
306
307                 if (exist == true)
308                 {
309                         res = system(pScript.get());
310                         AppLog("[smack] system(%s), result = [%d]", pScript.get(), res);
311                 }
312                 else
313                 {
314                         AppLog("[%ls] not found", script.GetPointer());
315                 }
316         }
317
318         for (int i = 0; pList[i] != null; i++)
319         {
320                 AppLog("delete Privilege - [%s]", pList[i]);
321                 delete[] pList[i];
322          }
323         delete[] pList;
324
325         return true;
326 }
327
328 #if 0
329 bool
330 SmackManager::AddPermissions(const PackageId& packageId)
331 {
332         if (__isSmackEnable == false)
333         {
334                 return true;
335         }
336
337         TryReturn(__pContext, false, "__pContext is null");
338
339         int res = 0;
340
341         std::unique_ptr<char[]> pPackageId(_StringConverter::CopyToCharArrayN(packageId));
342         TryReturn(pPackageId, false, "pPackageId is null.");
343
344         int count = __pContext->__pPrivilegeList->GetCount();
345
346         const char** pList = new (std::nothrow) const char*[count+1];
347         TryReturn(pList, false, "pList is null.");
348
349         for (int i = 0; i < count; i++)
350         {
351                 String* pPrivilege = dynamic_cast < String* >(__pContext->__pPrivilegeList->GetAt(i));
352                 if (pPrivilege)
353                 {
354                         char* pPrivilegeString = _StringConverter::CopyToCharArrayN(*pPrivilege);
355                         TryReturn(pPrivilegeString, false, "pPrivilegeString is null.");
356
357                         pList[i] = pPrivilegeString;
358                 }
359          }
360
361         pList[count] = null;
362
363         res = AddPermissions(pPackageId.get(), pList);
364
365         if (__pContext->__isPreloaded == true)
366         {
367                 String smackFile(L"/etc/smack/accesses2.d/");
368                 smackFile.Append(packageId);
369                 smackFile.Append(L"-temp.rule");
370
371                 String smackContext(packageId);
372                 smackContext.Append(L" all.rule include");
373
374                 InstallerUtil::CreateInfoFile(smackFile, &smackContext);
375         }
376         else
377         {
378                 String script("/usr/bin/smackload-app.sh");
379                 bool exist = File::IsFileExist(script);
380                 script.Append(L" ");
381                 script.Append(packageId);
382
383                 std::unique_ptr<char[]> pScript(_StringConverter::CopyToCharArrayN(script));
384                 TryReturn(pScript, false, "pScript is null.");
385
386                 if (exist == true)
387                 {
388                         res = system(pScript.get());
389                         AppLog("[smack] system(%s), result = [%d]", pScript.get(), res);
390                 }
391                 else
392                 {
393                         AppLog("[%ls] not found", script.GetPointer());
394                 }
395         }
396
397         for (int i = 0; pList[i] != null; i++)
398         {
399                 AppLog("delete Privilege - [%s]", pList[i]);
400                 delete[] pList[i];
401          }
402         delete[] pList;
403
404         return true;
405 }
406 #endif
407
408 bool
409 SmackManager::RevokePermissions(const PackageId& packageId)
410 {
411         if (__isSmackEnable == false)
412         {
413                 return true;
414         }
415
416         int res = 0;
417
418         std::unique_ptr<char[]> pPackageId(_StringConverter::CopyToCharArrayN(packageId));
419         TryReturn(pPackageId, false, "pPackageId is null.");
420
421         res = RevokePermissions(pPackageId.get());
422
423         return true;
424 }
425
426 bool
427 SmackManager::IsSmackEnable()
428 {
429         result r;
430         Registry reg;
431         String section(L"feature");
432         String entry(L"smack");
433         String value;
434
435         r = reg.Construct(CONFIG_PATH, "r");
436         TryReturn(!IsFailed(r), false, "CONFIG file is not found.");
437
438         r = reg.GetValue(section, entry, value);
439         TryReturn(!IsFailed(r), false, "GetValue is failed. entry = [%ls]", entry.GetPointer());
440
441         AppLog("[%ls is %ls.]", entry.GetPointer(), value.GetPointer());
442
443         if (value == L"on")
444         {
445                 return true;
446         }
447
448         return false;
449 }
450
451 int
452 SmackManager::Install(const char* pPackageId)
453 {
454         int ret = 0;
455         void* pHandle = null;
456         char* pErrorMsg = null;
457         int (*app_install)(const char*) = null;
458
459         pHandle = dlopen("libprivilege-control.so.0", RTLD_LAZY | RTLD_GLOBAL);
460         if (!pHandle)
461         {
462                 AppLog("Install(): dlopen() failed. [%s]", dlerror());
463                 return -1;
464         }
465
466         app_install = reinterpret_cast <int (*)(const char*)>(dlsym(pHandle, "app_install"));
467         pErrorMsg = dlerror();
468         if ((pErrorMsg != null) || (app_install == null))
469         {
470                 AppLog("Install(): dlsym() failed. [%s]", pErrorMsg);
471                 dlclose(pHandle);
472                 return -1;
473         }
474
475         ret = app_install(pPackageId);
476         AppLog("[smack] app_install(%s), result = [%d]", pPackageId, ret);
477
478         dlclose(pHandle);
479
480         return ret;
481 }
482
483 int
484 SmackManager::Uninstall(const char* pPackageId)
485 {
486         int ret = 0;
487         void* pHandle = null;
488         char* pErrorMsg = null;
489         int (*app_uninstall)(const char*) = null;
490
491         pHandle = dlopen("libprivilege-control.so.0", RTLD_LAZY | RTLD_GLOBAL);
492         if (!pHandle)
493         {
494                 AppLog("Uninstall(): dlopen() failed. [%s]", dlerror());
495                 return -1;
496         }
497
498         app_uninstall = reinterpret_cast <int (*)(const char*)>(dlsym(pHandle, "app_uninstall"));
499         pErrorMsg = dlerror();
500         if ((pErrorMsg != null) || (app_uninstall == null))
501         {
502                 AppLog("Uninstall(): dlsym() failed. [%s]", pErrorMsg);
503                 dlclose(pHandle);
504                 return -1;
505         }
506
507         ret = app_uninstall(pPackageId);
508         AppLog("[smack] app_uninstall(%s), result = [%d]", pPackageId, ret);
509
510         dlclose(pHandle);
511
512         return ret;
513 }
514
515 int
516 SmackManager::AddLabelDir(const char* pLabel, const char* pDirPath)
517 {
518         int ret = 0;
519         void* pHandle = null;
520         char* pErrorMsg = null;
521         int (*app_label_dir)(const char*, const char*) = null;
522
523         pHandle = dlopen("libprivilege-control.so.0", RTLD_LAZY | RTLD_GLOBAL);
524         if (!pHandle)
525         {
526                 AppLog("AddLabelDir(): dlopen() failed. [%s]", dlerror());
527                 return -1;
528         }
529
530         app_label_dir = reinterpret_cast <int (*)(const char*, const char*)>(dlsym(pHandle, "app_label_dir"));
531         pErrorMsg = dlerror();
532         if ((pErrorMsg != null) || (app_label_dir == null))
533         {
534                 AppLog("AddLabelDir(): dlsym() failed. [%s]", pErrorMsg);
535                 dlclose(pHandle);
536                 return -1;
537         }
538
539         ret = app_label_dir(pLabel, pDirPath);
540         AppLog("[smack] app_label_dir(%s, %s), result = [%d]", pLabel, pDirPath, ret);
541
542         dlclose(pHandle);
543
544         return 0;
545 }
546
547 int
548 SmackManager::AddLabelSharedDir(const char* pLabel, const char* pSharedLabel, const char* pDirPath)
549 {
550         int ret = 0;
551         void* pHandle = null;
552         char* pErrorMsg = null;
553         int (*app_label_shared_dir)(const char*, const char*, const char*) = null;
554
555         pHandle = dlopen("libprivilege-control.so.0", RTLD_LAZY | RTLD_GLOBAL);
556         if (!pHandle)
557         {
558                 AppLog("AddLabelSharedDir(): dlopen() failed. [%s]", dlerror());
559                 return -1;
560         }
561
562         app_label_shared_dir = reinterpret_cast <int (*)(const char*, const char*, const char*)>(dlsym(pHandle, "app_label_shared_dir"));
563         pErrorMsg = dlerror();
564         if ((pErrorMsg != null) || (app_label_shared_dir == null))
565         {
566                 AppLog("AddLabelSharedDir(): dlsym() failed. [%s]", pErrorMsg);
567                 dlclose(pHandle);
568                 return -1;
569         }
570
571         ret = app_label_shared_dir(pLabel, pSharedLabel, pDirPath);
572         AppLog("[smack] app_label_shared_dir(%s, %s, %s), result = [%d]", pLabel, pSharedLabel, pDirPath, ret);
573
574         dlclose(pHandle);
575
576         return 0;
577 }
578
579 int
580 SmackManager::AddSharedDirReaders(const char* pSharedLabel, const char** ppAppList)
581 {
582         int ret = 0;
583         void* pHandle = null;
584         char* pErrorMsg = null;
585         int (*add_shared_dir_readers)(const char*, const char**) = null;
586
587         pHandle = dlopen("libprivilege-control.so.0", RTLD_LAZY | RTLD_GLOBAL);
588         if (!pHandle)
589         {
590                 AppLog("AddSharedDirReaders(): dlopen() failed. [%s]", dlerror());
591                 return -1;
592         }
593
594         add_shared_dir_readers = reinterpret_cast <int (*)(const char*, const char**)>(dlsym(pHandle, "add_shared_dir_readers"));
595         pErrorMsg = dlerror();
596         if ((pErrorMsg != null) || (add_shared_dir_readers == null))
597         {
598                 AppLog("AddSharedDirReaders(): dlsym() failed. [%s]", pErrorMsg);
599                 dlclose(pHandle);
600                 return -1;
601         }
602
603         ret = add_shared_dir_readers(pSharedLabel, ppAppList);
604         AppLog("[smack] add_shared_dir_readers(%s), result = [%d]", pSharedLabel, ret);
605
606         dlclose(pHandle);
607
608         return 0;
609 }
610
611 int
612 SmackManager::AddFriend(const char* pPackageId1, const char* pPackageId2)
613 {
614         int ret = 0;
615         void* pHandle = null;
616         char* pErrorMsg = null;
617         int (*app_add_friend)(const char*, const char*) = null;
618
619         pHandle = dlopen("libprivilege-control.so.0", RTLD_LAZY | RTLD_GLOBAL);
620         if (!pHandle)
621         {
622                 AppLog("AddFriend(): dlopen() failed. [%s]", dlerror());
623                 return -1;
624         }
625
626         app_add_friend = reinterpret_cast <int (*)(const char*, const char*)>(dlsym(pHandle, "app_add_friend"));
627         pErrorMsg = dlerror();
628         if ((pErrorMsg != null) || (app_add_friend == null))
629         {
630                 AppLog("AddFriend(): dlsym() failed. [%s]", pErrorMsg);
631                 dlclose(pHandle);
632                 return -1;
633         }
634
635         ret = app_add_friend(pPackageId1, pPackageId2);
636         AppLog("[smack] app_add_friend(%s, %s), result = [%d]", pPackageId1, pPackageId2, ret);
637
638         dlclose(pHandle);
639
640         return 0;
641 }
642
643 int
644 SmackManager::EnablePermissions(const char* pPackageId, int appType, const char** ppPermissions, bool persistent)
645 {
646         int ret = 0;
647         void* pHandle = null;
648         char* pErrorMsg = null;
649         int (*app_enable_permissions)(const char*, int, const char**, bool) = null;
650
651         pHandle = dlopen("libprivilege-control.so.0", RTLD_LAZY | RTLD_GLOBAL);
652         if (!pHandle)
653         {
654                 AppLog("EnablePermissions(): dlopen() failed. [%s]", dlerror());
655                 return -1;
656         }
657
658         app_enable_permissions = reinterpret_cast <int (*)(const char*, int, const char**, bool)>(dlsym(pHandle, "app_enable_permissions"));
659         pErrorMsg = dlerror();
660         if ((pErrorMsg != null) || (app_enable_permissions == null))
661         {
662                 AppLog("EnablePermissions(): dlsym() failed. [%s]", pErrorMsg);
663                 dlclose(pHandle);
664                 return -1;
665         }
666
667         ret = app_enable_permissions(pPackageId, appType, ppPermissions, persistent);
668         AppLog("[smack] app_enable_permissions(%s, %d), result = [%d]", pPackageId, appType, ret);
669
670         dlclose(pHandle);
671
672         return 0;
673 }
674
675 int
676 SmackManager::RevokePermissions(const char* pPackageId)
677 {
678         int ret = 0;
679         void* pHandle = null;
680         char* pErrorMsg = null;
681         int (*app_revoke_permissions)(const char*) = null;
682
683         pHandle = dlopen("libprivilege-control.so.0", RTLD_LAZY | RTLD_GLOBAL);
684         if (!pHandle)
685         {
686                 AppLog("RevokePermissions(): dlopen() failed. [%s][%s]", pPackageId, dlerror());
687                 return -1;
688         }
689
690         app_revoke_permissions = reinterpret_cast <int (*)(const char*)>(dlsym(pHandle, "app_revoke_permissions"));
691         pErrorMsg = dlerror();
692         if ((pErrorMsg != null) || (app_revoke_permissions == null))
693         {
694                 AppLog("RevokePermissions(): dlsym() failed. [%s][%s]", pPackageId, pErrorMsg);
695                 dlclose(pHandle);
696                 return -1;
697         }
698
699         ret = app_revoke_permissions(pPackageId);
700         AppLog("[smack] app_revoke_permissions(%s), result = [%d]", pPackageId, ret);
701
702         dlclose(pHandle);
703
704         return 0;
705 }
706
707 #if 0
708 int
709 SmackManager::AddPermissions(const char* pPackageId, const char** ppPermissions)
710 {
711         int ret = 0;
712         void* pHandle = null;
713         char* pErrorMsg = null;
714         int (*app_add_permissions)(const char*, const char**) = null;
715
716         pHandle = dlopen("libprivilege-control.so.0", RTLD_LAZY | RTLD_GLOBAL);
717         if (!pHandle)
718         {
719                 AppLog("AddPermissions(): dlopen() failed. [%s][%s]", pPackageId, dlerror());
720                 return -1;
721         }
722
723         app_add_permissions = reinterpret_cast <int (*)(const char*, const char**)>(dlsym(pHandle, "app_add_permissions"));
724         pErrorMsg = dlerror();
725         if ((pErrorMsg != null) || (app_add_permissions == null))
726         {
727                 AppLog("AddPermissions(): dlsym() failed. [%s][%s]", pPackageId, pErrorMsg);
728                 dlclose(pHandle);
729                 return -1;
730         }
731
732         for (int i = 0; ppPermissions[i] != null; i++)
733         {
734                 AppLog("Privilege - [%s]", ppPermissions[i]);
735          }
736
737         ret = app_add_permissions(pPackageId, ppPermissions);
738         AppLog("[smack] app_add_permissions(%s), result = [%d]", pPackageId, ret);
739
740         dlclose(pHandle);
741
742         return 0;
743 }
744 #endif