Sync to the latest code
[framework/appfw/slp-pkgmgr.git] / tool / pkg_smack.c
1 /*
2  * slp-pkgmgr
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>,
7  * Jaeho Lee <jaeho81.lee@samsung.com>, Shobhit Srivastava <shobhit.s@samsung.com>
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  */
22
23 #define _GNU_SOURCE
24
25 #include <unistd.h>
26 #include <stdio.h>
27 #include <errno.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <stdbool.h>
31 #include <dlfcn.h>
32 #include <sys/stat.h>
33
34 #include <pkgmgr-info.h>
35
36 static int __pkg_list_cb (const pkgmgrinfo_pkginfo_h handle, void *user_data);
37
38
39 #ifdef _E
40 #undef _E
41 #endif
42 #define _E(fmt, arg...) fprintf(stderr, "[PKG_SMACK][E][%s,%d] "fmt"\n", __FUNCTION__, __LINE__, ##arg);
43
44 #ifdef _D
45 #undef _D
46 #endif
47 #define _D(fmt, arg...) fprintf(stderr, "[PKG_SMACK][D][%s,%d] "fmt"\n", __FUNCTION__, __LINE__, ##arg);
48
49 #define LIB_PRIVILEGE_CONTROL           "libprivilege-control.so.0"
50 #define LIB_SMACK                                       "libsmack.so.1"
51
52 #define BUFF_SIZE                       256
53 #define APP_OWNER_ID            5000
54 #define APP_GROUP_ID            5000
55
56 enum rpm_path_type {
57         RPM_PATH_PRIVATE,
58         RPM_PATH_GROUP_RW,
59         RPM_PATH_PUBLIC_RO,
60         RPM_PATH_SETTINGS_RW,
61         RPM_PATH_ANY_LABEL
62 };
63
64 static int __is_dir(char *dirname)
65 {
66         struct stat stFileInfo;
67         stat(dirname, &stFileInfo);
68         if (S_ISDIR(stFileInfo.st_mode)) {
69                 return 1;
70         }
71         return 0;
72 }
73
74 int __pkg_smack_register_package(const char *pkgid)
75 {
76         int ret = 0;
77         void *handle = NULL;
78         char *errmsg = NULL;
79         int (*app_install)(const char*) = NULL;
80
81         if (pkgid == NULL)
82                 return -1;
83
84         handle = dlopen(LIB_PRIVILEGE_CONTROL, RTLD_LAZY | RTLD_GLOBAL);
85         if (!handle) {
86                 _E( "register package: dlopen() failed. [%s]", dlerror());
87                 return -1;
88         }
89
90         app_install = dlsym(handle, "app_install");
91         errmsg = dlerror();
92         if ((errmsg != NULL) || (app_install == NULL)) {
93                 _E( "register package: dlsym() failed. [%s]", errmsg);
94                 dlclose(handle);
95                 return -1;
96         }
97
98         _E( "[smack] app_install(%s)", pkgid);
99         ret = app_install(pkgid);
100         _E( "[smack] app_install(%s), result = [%d]", pkgid, ret);
101
102         dlclose(handle);
103         return ret;
104 }
105
106 int __pkg_smack_unregister_package(const char *pkgid)
107 {
108         int ret = 0;
109         void *handle = NULL;
110         char *errmsg = NULL;
111         int (*app_uninstall)(const char*) = NULL;
112
113         if (pkgid == NULL)
114                 return -1;
115
116         handle = dlopen(LIB_PRIVILEGE_CONTROL, RTLD_LAZY | RTLD_GLOBAL);
117         if (!handle) {
118                 _E( "unregister package: dlopen() failed. [%s]", dlerror());
119                 return -1;
120         }
121
122         app_uninstall = dlsym(handle, "app_uninstall");
123         errmsg = dlerror();
124         if ((errmsg != NULL) || (app_uninstall == NULL)) {
125                 _E( "unregister package: dlsym() failed. [%s]", errmsg);
126                 dlclose(handle);
127                 return -1;
128         }
129
130         _E( "[smack] app_uninstall(%s)", pkgid);
131         ret = app_uninstall(pkgid);
132         _E( "[smack] app_uninstall(%s), result = [%d]", pkgid, ret);
133
134         dlclose(handle);
135         return ret;
136 }
137
138 int __pkg_smack_revoke_permissions(const char *pkgid)
139 {
140         int ret = 0;
141         void *handle = NULL;
142         char *errmsg = NULL;
143         int (*app_revoke_permissions)(const char*) = NULL;
144
145         if (pkgid == NULL)
146                 return -1;
147
148         handle = dlopen(LIB_PRIVILEGE_CONTROL, RTLD_LAZY | RTLD_GLOBAL);
149         if (!handle) {
150                 _E( "revoke permissions: dlopen() failed. [%s][%s]", pkgid, dlerror());
151                 return -1;
152         }
153
154         app_revoke_permissions = dlsym(handle, "app_revoke_permissions");
155         errmsg = dlerror();
156         if ((errmsg != NULL) || (app_revoke_permissions == NULL)) {
157                 _E( "revoke permissions(): dlsym() failed. [%s][%s]", pkgid, errmsg);
158                 dlclose(handle);
159                 return -1;
160         }
161
162         _E( "[smack] app_revoke_permissions(%s)", pkgid);
163         ret = app_revoke_permissions(pkgid);
164         _E( "[smack] app_revoke_permissions(%s), result = [%d]", pkgid, ret);
165
166         dlclose(handle);
167         return ret;
168 }
169
170 int __pkg_smack_enable_permissions(const char *pkgid, int apptype,
171                                                 const char **perms, int persistent)
172 {
173         int ret = 0;
174         void *handle = NULL;
175         char *errmsg = NULL;
176         int (*app_enable_permissions)(const char*, int, const char**, bool) = NULL;
177
178         if (pkgid == NULL)
179                 return -1;
180
181         handle = dlopen(LIB_PRIVILEGE_CONTROL, RTLD_LAZY | RTLD_GLOBAL);
182         if (!handle) {
183                 _E( "enable permissions(): dlopen() failed. [%s]", dlerror());
184                 return -1;
185         }
186
187         app_enable_permissions = dlsym(handle, "app_enable_permissions");
188         errmsg = dlerror();
189         if ((errmsg != NULL) || (app_enable_permissions == NULL)) {
190                 _E( "enable permissions(): dlsym() failed. [%s]", errmsg);
191                 dlclose(handle);
192                 return -1;
193         }
194
195         _E( "[smack] app_enable_permissions(%s, %d)", pkgid, apptype);
196         ret = app_enable_permissions(pkgid, apptype, perms, persistent);
197         _E( "[smack] app_enable_permissions(%s, %d), result = [%d]", pkgid, apptype, ret);
198
199         dlclose(handle);
200         return ret;
201 }
202
203 int __pkg_smack_setup_path(const char *pkgid, const char *dirpath,
204                                                 int apppathtype, const char *groupid)
205 {
206         int ret = 0;
207         void *handle = NULL;
208         char *errmsg = NULL;
209         int (*app_setup_path)(const char*, const char*, int, ...) = NULL;
210
211         if (pkgid == NULL || dirpath == NULL)
212                 return -1;
213
214         handle = dlopen(LIB_PRIVILEGE_CONTROL, RTLD_LAZY | RTLD_GLOBAL);
215         if (!handle) {
216                 _E( "setup path: dlopen() failed. [%s]", dlerror());
217                 return -1;
218         }
219
220         app_setup_path = dlsym(handle, "app_setup_path");
221         errmsg = dlerror();
222         if ((errmsg != NULL) || (app_setup_path == NULL)) {
223                 _E( "setup path: dlsym() failed. [%s]", errmsg);
224                 dlclose(handle);
225                 return -1;
226         }
227
228         if (groupid == NULL) {
229                 _E( "[smack] app_setup_path(%s, %s, %d)", pkgid, dirpath, apppathtype);
230                 ret = app_setup_path(pkgid, dirpath, apppathtype);
231                 _E( "[smack] app_setup_path(), result = [%d]", ret);
232         } else {
233                 _E( "[smack] app_setup_path(%s, %s, %d, %s)", pkgid, dirpath, apppathtype, groupid);
234                 ret = app_setup_path(pkgid, dirpath, apppathtype, groupid);
235                 _E( "[smack] app_setup_path(), result = [%d]", ret);
236         }
237
238         dlclose(handle);
239         return ret;
240 }
241
242 int __pkg_smack_add_friend(const char *pkgid1, const char *pkgid2)
243 {
244         int ret = 0;
245         void *handle = NULL;
246         char *errmsg = NULL;
247         int (*app_add_friend)(const char*, const char*) = NULL;
248
249         if (pkgid1 == NULL || pkgid2 == NULL)
250                 return -1;
251
252         handle = dlopen(LIB_PRIVILEGE_CONTROL, RTLD_LAZY | RTLD_GLOBAL);
253         if (!handle) {
254                 _E( "add friend: dlopen() failed. [%s]", dlerror());
255                 return -1;
256         }
257
258         app_add_friend = dlsym(handle, "app_add_friend");
259         errmsg = dlerror();
260         if ((errmsg != NULL) || (app_add_friend == NULL)) {
261                 _E( "add friend: dlsym() failed. [%s]", errmsg);
262                 dlclose(handle);
263                 return -1;
264         }
265
266         _E( "[smack] app_add_friend(%s, %s)", pkgid1, pkgid2);
267         ret = app_add_friend(pkgid1, pkgid2);
268         _E( "[smack] app_add_friend(%s, %s), result = [%d]", pkgid1, pkgid2, ret);
269
270         dlclose(handle);
271         return ret;
272 }
273
274 int __pkg_smack_change_smack_label(const char *path, const char *label,
275                                                 int label_type)
276 {
277         if (path == NULL || label == NULL)
278                 return -1;
279         int ret = 0;
280         void *handle = NULL;
281         char *errmsg = NULL;
282         int (*smack_lsetlabel)(const char*, const char*, int) = NULL;
283
284         handle = dlopen(LIB_SMACK, RTLD_LAZY | RTLD_GLOBAL);
285         if (!handle) {
286                 _E( "change smack label: dlopen() failed. [%s]", dlerror());
287                 return -1;
288         }
289
290         smack_lsetlabel = dlsym(handle, "smack_lsetlabel");
291         errmsg = dlerror();
292         if ((errmsg != NULL) || (smack_lsetlabel == NULL)) {
293                 _E( "change smack label: dlsym() failed. [%s]", errmsg);
294                 dlclose(handle);
295                 return -1;
296         }
297
298         _E( "[smack] smack_lsetlabel(%s, %s, %d)", path, label, label_type);
299         ret = smack_lsetlabel(path, label, label_type);
300         _E( "[smack] smack_lsetlabel(%s, %s, %d), result = [%d]", path, label, label_type, ret);
301
302         dlclose(handle);
303         return ret;
304 }
305
306 static void __apply_shared_privileges(char *pkgname, int flag)
307 {
308         char dirpath[BUFF_SIZE] = {'\0'};
309         /*execute privilege APIs. The APIs should not fail*/
310         __pkg_smack_register_package(pkgname);
311
312 #if 1
313         /*home dir. Dont setup path but change smack access to "_" */
314         snprintf(dirpath, BUFF_SIZE, "/usr/apps/%s", pkgname);
315         if (__is_dir(dirpath))
316                 __pkg_smack_change_smack_label(dirpath, "_", 0);/*0 is SMACK_LABEL_ACCESS*/
317         memset(dirpath, '\0', BUFF_SIZE);
318         snprintf(dirpath, BUFF_SIZE, "/opt/usr/apps/%s", pkgname);
319         if (__is_dir(dirpath))
320                 __pkg_smack_change_smack_label(dirpath, "_", 0);/*0 is SMACK_LABEL_ACCESS*/
321         memset(dirpath, '\0', BUFF_SIZE);
322
323         /*/shared dir. Dont setup path but change smack access to "_" */
324         snprintf(dirpath, BUFF_SIZE, "/usr/apps/%s/shared", pkgname);
325         if (__is_dir(dirpath))
326                 __pkg_smack_change_smack_label(dirpath, "_", 0);/*0 is SMACK_LABEL_ACCESS*/
327         memset(dirpath, '\0', BUFF_SIZE);
328         snprintf(dirpath, BUFF_SIZE, "/opt/usr/apps/%s/shared", pkgname);
329         if (__is_dir(dirpath))
330                 __pkg_smack_change_smack_label(dirpath, "_", 0);/*0 is SMACK_LABEL_ACCESS*/
331         memset(dirpath, '\0', BUFF_SIZE);
332
333         /*/shared/res dir. Dont setup path but change smack access to "_" */
334         if (flag == 0)
335                 snprintf(dirpath, BUFF_SIZE, "/usr/apps/%s/shared/res", pkgname);
336         else
337                 snprintf(dirpath, BUFF_SIZE, "/opt/usr/apps/%s/shared/res", pkgname);
338         if (__is_dir(dirpath))
339                 __pkg_smack_setup_path(pkgname, dirpath, RPM_PATH_ANY_LABEL, "_");
340         memset(dirpath, '\0', BUFF_SIZE);
341
342         /*/shared/data dir. setup path and change group to 'app'*/
343         if (flag == 0)
344                 snprintf(dirpath, BUFF_SIZE, "/usr/apps/%s/shared/data", pkgname);
345         else
346                 snprintf(dirpath, BUFF_SIZE, "/opt/usr/apps/%s/shared/data", pkgname);
347         if (__is_dir(dirpath)) {
348                 chown(dirpath, APP_OWNER_ID, APP_GROUP_ID);
349                 __pkg_smack_setup_path(pkgname, dirpath, RPM_PATH_PUBLIC_RO, NULL);
350         } else {
351                 memset(dirpath, '\0', BUFF_SIZE);
352                 if (flag == 0)
353                         snprintf(dirpath, BUFF_SIZE, "/opt/usr/apps/%s/shared/data", pkgname);
354                 else
355                         snprintf(dirpath, BUFF_SIZE, "/usr/apps/%s/shared/data", pkgname);
356                 if (__is_dir(dirpath))
357                         chown(dirpath, APP_OWNER_ID, APP_GROUP_ID);
358                         __pkg_smack_setup_path(pkgname, dirpath, RPM_PATH_PUBLIC_RO, NULL);
359         }
360 #endif
361 }
362
363 static int __is_authorized()
364 {
365         /* pkg_init db should be called by as root privilege. */
366
367         uid_t uid = getuid();
368         if ((uid_t) 0 == uid)
369                 return 1;
370         else
371                 return 0;
372 }
373
374 static int __pkg_list_cb (const pkgmgrinfo_pkginfo_h handle, void *user_data)
375 {
376         int ret = -1;
377         char *pkgid = NULL;
378
379         ret = pkgmgrinfo_pkginfo_get_pkgid(handle, &pkgid);
380         if(ret < 0) {
381                 printf("pkgmgrinfo_pkginfo_get_pkgid() failed\n");
382         }
383
384         __apply_shared_privileges(pkgid, 0);
385
386         return 0;
387 }
388
389 static int __additional_rpm_for_smack()
390 {
391         char *pkgid = "ui-gadget::client";
392         char *perm[] = {"http://tizen.org/privilege/appsetting", NULL};
393
394         __apply_shared_privileges(pkgid, 0);
395         __pkg_smack_enable_permissions(pkgid, 1, perm, 1);
396         return 0;
397 }
398
399 static int __find_rpm_for_smack()
400 {
401         int ret = 0;
402         pkgmgrinfo_pkginfo_filter_h handle = NULL;
403
404         ret = pkgmgrinfo_pkginfo_filter_create(&handle);
405         if (ret > 0) {
406                 printf("pkginfo filter handle create failed\n");
407                 return -1;
408         }
409
410         ret = pkgmgrinfo_pkginfo_filter_add_string(handle,
411                 PMINFO_PKGINFO_PROP_PACKAGE_TYPE, "rpm");
412         if (ret < 0) {
413                 printf("pkgmgrinfo_pkginfo_filter_add_string() failed\n");
414                 ret = -1;
415         }
416
417         ret = pkgmgrinfo_pkginfo_filter_foreach_pkginfo(handle, __pkg_list_cb, NULL);
418         if (ret < 0) {
419                 printf("pkgmgrinfo_pkginfo_filter_foreach_pkginfo() failed\n");
420                 ret = -1;
421         }
422
423         pkgmgrinfo_pkginfo_filter_destroy(handle);
424         return ret;
425 }
426
427 int main(int argc, char *argv[])
428 {
429         int ret = 0;
430
431         if (!__is_authorized()) {
432                 _E("You are not an authorized user!\n");
433                 return -1;
434         }
435
436         ret = __find_rpm_for_smack();
437         if (ret < 0)
438                 printf("__find_rpm_for_smack() failed\n");
439
440         ret = __additional_rpm_for_smack();
441         if (ret < 0)
442                 printf("__additional_rpm_for_smack() failed\n");
443
444         return 0;
445 }
446
447