7fb6e2047966f3d033f66c85c1ce835b9d046ee7
[platform/core/appfw/pkgmgr-server.git] / src / request.c
1 #include <stdlib.h>
2 #include <sys/types.h>
3 #include <sys/time.h>
4
5 #include <glib.h>
6 #include <gio/gio.h>
7 #include <gum/gum-user.h>
8 #include <gum/common/gum-user-types.h>
9
10 #include "queue.h"
11 #include "pkgmgr-server.h"
12 #include "package-manager.h"
13
14 #define RETRY_MAX 5
15 #define RETRY_WAIT_USEC (1000000 / 2) /* 0.5 sec */
16 #define PKGMGR_DBUS_SERVICE "org.tizen.pkgmgr"
17 #define PKGMGR_DBUS_OBJECT_PATH "/org/tizen/pkgmgr"
18
19 static const char instropection_xml[] =
20         "<node>"
21         "  <interface name='org.tizen.pkgmgr'>"
22         "    <method name='install'>"
23         "      <arg type='u' name='uid' direction='in'/>"
24         "      <arg type='s' name='pkgtype' direction='in'/>"
25         "      <arg type='s' name='pkgpath' direction='in'/>"
26         "      <arg type='as' name='args' direction='in'/>"
27         "      <arg type='i' name='ret' direction='out'/>"
28         "      <arg type='s' name='reqkey' direction='out'/>"
29         "    </method>"
30         "    <method name='reinstall'>"
31         "      <arg type='u' name='uid' direction='in'/>"
32         "      <arg type='s' name='pkgid' direction='in'/>"
33         "      <arg type='i' name='ret' direction='out'/>"
34         "      <arg type='s' name='reqkey' direction='out'/>"
35         "    </method>"
36         "    <method name='mount_install'>"
37         "      <arg type='u' name='uid' direction='in'/>"
38         "      <arg type='s' name='pkgtype' direction='in'/>"
39         "      <arg type='s' name='pkgpath' direction='in'/>"
40         "      <arg type='as' name='args' direction='in'/>"
41         "      <arg type='i' name='ret' direction='out'/>"
42         "      <arg type='s' name='reqkey' direction='out'/>"
43         "    </method>"
44         "    <method name='uninstall'>"
45         "      <arg type='u' name='uid' direction='in'/>"
46         "      <arg type='s' name='pkgid' direction='in'/>"
47         "      <arg type='i' name='ret' direction='out'/>"
48         "      <arg type='s' name='reqkey' direction='out'/>"
49         "    </method>"
50         "    <method name='move'>"
51         "      <arg type='u' name='uid' direction='in'/>"
52         "      <arg type='s' name='pkgid' direction='in'/>"
53         "      <arg type='i' name='movetype' direction='in'/>"
54         "      <arg type='i' name='ret' direction='out'/>"
55         "      <arg type='s' name='reqkey' direction='out'/>"
56         "    </method>"
57         "    <method name='enable_pkgs'>"
58         "      <arg type='u' name='uid' direction='in'/>"
59         "      <arg type='as' name='pkgids' direction='in'/>"
60         "      <arg type='i' name='ret' direction='out'/>"
61         "      <arg type='s' name='reqkey' direction='out'/>"
62         "    </method>"
63         "    <method name='disable_pkgs'>"
64         "      <arg type='u' name='uid' direction='in'/>"
65         "      <arg type='as' name='pkgids' direction='in'/>"
66         "      <arg type='i' name='ret' direction='out'/>"
67         "      <arg type='s' name='reqkey' direction='out'/>"
68         "    </method>"
69         "    <method name='enable_app'>"
70         "      <arg type='u' name='uid' direction='in'/>"
71         "      <arg type='s' name='appid' direction='in'/>"
72         "      <arg type='i' name='ret' direction='out'/>"
73         "      <arg type='s' name='reqkey' direction='out'/>"
74         "    </method>"
75         "    <method name='disable_app'>"
76         "      <arg type='u' name='uid' direction='in'/>"
77         "      <arg type='s' name='appid' direction='in'/>"
78         "      <arg type='i' name='ret' direction='out'/>"
79         "      <arg type='s' name='reqkey' direction='out'/>"
80         "    </method>"
81         "    <method name='enable_global_app_for_uid'>"
82         "      <arg type='u' name='uid' direction='in'/>"
83         "      <arg type='s' name='appid' direction='in'/>"
84         "      <arg type='i' name='ret' direction='out'/>"
85         "      <arg type='s' name='reqkey' direction='out'/>"
86         "    </method>"
87         "    <method name='disable_global_app_for_uid'>"
88         "      <arg type='u' name='uid' direction='in'/>"
89         "      <arg type='s' name='appid' direction='in'/>"
90         "      <arg type='i' name='ret' direction='out'/>"
91         "      <arg type='s' name='reqkey' direction='out'/>"
92         "    </method>"
93         "    <method name='getsize'>"
94         "      <arg type='u' name='uid' direction='in'/>"
95         "      <arg type='s' name='pkgid' direction='in'/>"
96         "      <arg type='i' name='get_type' direction='in'/>"
97         "      <arg type='i' name='ret' direction='out'/>"
98         "      <arg type='s' name='reqkey' direction='out'/>"
99         "    </method>"
100         "    <method name='cleardata'>"
101         "      <arg type='u' name='uid' direction='in'/>"
102         "      <arg type='s' name='pkgid' direction='in'/>"
103         "      <arg type='i' name='ret' direction='out'/>"
104         "    </method>"
105         "    <method name='clearcache'>"
106         "      <arg type='u' name='uid' direction='in'/>"
107         "      <arg type='s' name='pkgid' direction='in'/>"
108         "      <arg type='i' name='ret' direction='out'/>"
109         "    </method>"
110         "    <method name='kill'>"
111         "      <arg type='u' name='uid' direction='in'/>"
112         "      <arg type='s' name='pkgid' direction='in'/>"
113         "      <arg type='i' name='ret' direction='out'/>"
114         "      <arg type='i' name='pid' direction='out'/>"
115         "    </method>"
116         "    <method name='check'>"
117         "      <arg type='u' name='uid' direction='in'/>"
118         "      <arg type='s' name='pkgid' direction='in'/>"
119         "      <arg type='i' name='ret' direction='out'/>"
120         "      <arg type='i' name='pid' direction='out'/>"
121         "    </method>"
122         "    <method name='generate_license_request'>"
123         "      <arg type='s' name='resp_data' direction='in'/>"
124         "      <arg type='i' name='ret' direction='out'/>"
125         "      <arg type='s' name='req_data' direction='out'/>"
126         "      <arg type='s' name='license_url' direction='out'/>"
127         "    </method>"
128         "    <method name='register_license'>"
129         "      <arg type='s' name='resp_data' direction='in'/>"
130         "      <arg type='i' name='ret' direction='out'/>"
131         "    </method>"
132         "    <method name='decrypt_package'>"
133         "      <arg type='s' name='drm_file_path' direction='in'/>"
134         "      <arg type='s' name='decrypted_file_path' direction='in'/>"
135         "      <arg type='i' name='ret' direction='out'/>"
136         "    </method>"
137         "    <method name='enable_app_splash_screen'>"
138         "      <arg type='u' name='uid' direction='in'/>"
139         "      <arg type='s' name='appid' direction='in'/>"
140         "      <arg type='i' name='ret' direction='out'/>"
141         "    </method>"
142         "    <method name='disable_app_splash_screen'>"
143         "      <arg type='u' name='uid' direction='in'/>"
144         "      <arg type='s' name='appid' direction='in'/>"
145         "      <arg type='i' name='ret' direction='out'/>"
146         "    </method>"
147         "    <method name='set_restriction_mode'>"
148         "      <arg type='u' name='uid' direction='in'/>"
149         "      <arg type='s' name='pkgid' direction='in'/>"
150         "      <arg type='i' name='mode' direction='in'/>"
151         "      <arg type='i' name='ret' direction='out'/>"
152         "    </method>"
153         "    <method name='unset_restriction_mode'>"
154         "      <arg type='u' name='uid' direction='in'/>"
155         "      <arg type='s' name='pkgid' direction='in'/>"
156         "      <arg type='i' name='mode' direction='in'/>"
157         "      <arg type='i' name='ret' direction='out'/>"
158         "    </method>"
159         "    <method name='get_restriction_mode'>"
160         "      <arg type='u' name='uid' direction='in'/>"
161         "      <arg type='s' name='pkgid' direction='in'/>"
162         "      <arg type='i' name='result' direction='out'/>"
163         "      <arg type='i' name='ret' direction='out'/>"
164         "    </method>"
165         "    <method name='set_app_label'>"
166         "      <arg type='u' name='uid' direction='in'/>"
167         "      <arg type='s' name='appid' direction='in'/>"
168         "      <arg type='s' name='label' direction='in'/>"
169         "      <arg type='i' name='ret' direction='out'/>"
170         "    </method>"
171         "  </interface>"
172         "</node>";
173 static GDBusNodeInfo *instropection_data;
174 static guint reg_id;
175 static guint owner_id;
176 static GHashTable *req_table;
177
178 static char *__generate_reqkey(const char *pkgid)
179 {
180         struct timeval tv;
181         long curtime;
182         char timestr[MAX_PKG_ARGS_LEN];
183         char *str_req_key;
184         int size;
185
186         gettimeofday(&tv, NULL);
187         curtime = tv.tv_sec * 1000000 + tv.tv_usec;
188         snprintf(timestr, sizeof(timestr), "%ld", curtime);
189
190         size = strlen(pkgid) + strlen(timestr) + 2;
191         str_req_key = (char *)calloc(size, sizeof(char));
192         if (str_req_key == NULL) {
193                 DBG("calloc failed");
194                 return NULL;
195         }
196         snprintf(str_req_key, size, "%s_%s", pkgid, timestr);
197
198         return str_req_key;
199 }
200
201 static int __is_admin_user(uid_t uid)
202 {
203         GumUser *guser;
204         GumUserType ut = GUM_USERTYPE_NONE;
205         int retry_cnt = 0;
206
207         do {
208                 guser = gum_user_get_sync(uid, FALSE);
209                 if (guser == NULL) {
210                         ERR("cannot get user information from gumd, retry");
211                         retry_cnt++;
212                         usleep(RETRY_WAIT_USEC);
213                         continue;
214                 }
215                 break;
216         } while (retry_cnt <= RETRY_MAX);
217
218         if (guser == NULL) {
219                 ERR("cannot get user information from gumd, failed");
220                 return -1;
221         }
222
223         g_object_get(G_OBJECT(guser), "usertype", &ut, NULL);
224         if (ut == GUM_USERTYPE_NONE) {
225                 ERR("cannot get user type");
226                 g_object_unref(guser);
227                 return -1;
228         } else if (ut != GUM_USERTYPE_ADMIN) {
229                 g_object_unref(guser);
230                 return 0;
231         }
232
233         g_object_unref(guser);
234
235         return 1;
236 }
237
238 #define REGULAR_USER 5000
239 static int __check_caller_permission(uid_t uid,
240                 GDBusMethodInvocation *invocation, GVariant *parameters)
241 {
242         GVariant *v;
243         uid_t target_uid;
244         int is_admin;
245
246         if (uid < REGULAR_USER)
247                 return 0;
248
249         v = g_variant_get_child_value(parameters, 0);
250         if (v == NULL) {
251                 g_dbus_method_invocation_return_error_literal(invocation,
252                                 G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
253                                 "Internal error.");
254                 return -1;
255         }
256
257         target_uid = g_variant_get_uint32(v);
258         g_variant_unref(v);
259         if (uid == target_uid)
260                 return 0;
261
262         is_admin = __is_admin_user(uid);
263         if (is_admin == -1) {
264                 g_dbus_method_invocation_return_error_literal(invocation,
265                                 G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
266                                 "Internal error.");
267                 return -1;
268         } else if (is_admin == 0) {
269                 g_dbus_method_invocation_return_error_literal(invocation,
270                                 G_DBUS_ERROR, G_DBUS_ERROR_ACCESS_DENIED,
271                                 "Non-admin user cannot request operation to "
272                                 "other users.");
273                 return -1;
274         }
275
276         return 0;
277 }
278
279 static int __handle_request_install(uid_t caller_uid,
280                 GDBusMethodInvocation *invocation, GVariant *parameters)
281 {
282         uid_t target_uid = (uid_t)-1;
283         char *arg_pkgtype = NULL;
284         const char *pkgtype;
285         char *pkgpath = NULL;
286         char *args = NULL;
287         char *reqkey = NULL;
288         gchar **tmp_args = NULL;
289         gsize args_count;
290         int ret = -1;
291         GVariant *value;
292         int i = 0;
293         int len = 0;
294
295         g_variant_get(parameters, "(u&s&s@as)", &target_uid, &arg_pkgtype,
296                         &pkgpath, &value);
297         tmp_args = (gchar **)g_variant_get_strv(value, &args_count);
298
299         for (i = 0; i < args_count; i++)
300                 len = len + strlen(tmp_args[i]) + 1;
301
302         args = (char *)calloc(len, sizeof(char));
303         if (args == NULL) {
304                 ERR("calloc failed");
305                 g_dbus_method_invocation_return_value(invocation,
306                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
307                 ret = -1;
308                 goto catch;
309         }
310
311         for (i = 0; i < args_count; i++) {
312                 strncat(args, tmp_args[i], strlen(tmp_args[i]));
313                 if (i != args_count - 1)
314                         strncat(args, " ", strlen(" "));
315         }
316
317         if (target_uid == (uid_t)-1 || pkgpath == NULL) {
318                 g_dbus_method_invocation_return_value(invocation,
319                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
320                 ret = -1;
321                 goto catch;
322         }
323
324         pkgtype = _get_pkgtype_from_file(pkgpath);
325         if (!pkgtype && arg_pkgtype && strlen(arg_pkgtype))
326                 pkgtype = (const char *)arg_pkgtype;
327         if (pkgtype == NULL) {
328                 g_dbus_method_invocation_return_value(invocation,
329                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
330                 ret = -1;
331                 goto catch;
332         }
333
334         reqkey = __generate_reqkey(pkgpath);
335         if (reqkey == NULL) {
336                 g_dbus_method_invocation_return_value(invocation,
337                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
338                 ret = -1;
339                 goto catch;
340         }
341
342         if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_INSTALL,
343                                 pkgtype, pkgpath, args)) {
344                 g_dbus_method_invocation_return_value(invocation,
345                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
346                 ret = -1;
347                 goto catch;
348         }
349
350         g_dbus_method_invocation_return_value(invocation,
351                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
352
353         ret = 0;
354
355 catch:
356         if (reqkey)
357                 free(reqkey);
358
359         if (args)
360                 free(args);
361
362         if (tmp_args)
363                 g_free(tmp_args);
364
365         return ret;
366 }
367
368 static int __handle_request_mount_install(uid_t caller_uid,
369         GDBusMethodInvocation *invocation, GVariant *parameters)
370 {
371         uid_t target_uid = (uid_t)-1;
372         char *arg_pkgtype = NULL;
373         const char *pkgtype;
374         char *pkgpath = NULL;
375         char *args = NULL;
376         char *reqkey = NULL;
377         gchar **tmp_args = NULL;
378         gsize args_count;
379         int ret = -1;
380         GVariant *value;
381         int i = 0;
382         int len = 0;
383
384         g_variant_get(parameters, "(u&s&s@as)", &target_uid, &arg_pkgtype,
385                         &pkgpath, &value);
386         tmp_args = (gchar **)g_variant_get_strv(value, &args_count);
387
388         for (i = 0; i < args_count; i++)
389                 len = len + strlen(tmp_args[i]) + 1;
390
391         args = (char *)calloc(len, sizeof(char));
392         if (args == NULL) {
393                 ERR("calloc failed");
394                 g_dbus_method_invocation_return_value(invocation,
395                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
396                 ret = -1;
397                 goto catch;
398         }
399
400         for (i = 0; i < args_count; i++) {
401                 strncat(args, tmp_args[i], strlen(tmp_args[i]));
402                 if (i != args_count - 1)
403                         strncat(args, " ", strlen(" "));
404         }
405
406         if (target_uid == (uid_t)-1 || pkgpath == NULL) {
407                 g_dbus_method_invocation_return_value(invocation,
408                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
409                 ret = -1;
410                 goto catch;
411         }
412
413         pkgtype = _get_pkgtype_from_file(pkgpath);
414         if (!pkgtype && arg_pkgtype && strlen(arg_pkgtype))
415                 pkgtype = (const char *)arg_pkgtype;
416         if (pkgtype == NULL) {
417                 g_dbus_method_invocation_return_value(invocation,
418                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
419                 ret = -1;
420                 goto catch;
421         }
422
423         reqkey = __generate_reqkey(pkgpath);
424         if (reqkey == NULL) {
425                 g_dbus_method_invocation_return_value(invocation,
426                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
427                 ret = -1;
428                 goto catch;
429         }
430
431         if (_push_queue(target_uid, caller_uid, reqkey,
432                                 REQUEST_TYPE_MOUNT_INSTALL,
433                                 pkgtype, pkgpath, args)) {
434                 g_dbus_method_invocation_return_value(invocation,
435                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
436                 ret = -1;
437                 goto catch;
438         }
439
440         g_dbus_method_invocation_return_value(invocation,
441                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
442         ret = 0;
443
444 catch:
445         if (reqkey)
446                 free(reqkey);
447
448         if (args)
449                 free(args);
450
451         if (tmp_args)
452                 g_free(tmp_args);
453
454         return ret;
455 }
456
457 static int __handle_request_reinstall(uid_t caller_uid,
458                 GDBusMethodInvocation *invocation, GVariant *parameters)
459 {
460         uid_t target_uid = (uid_t)-1;
461         char *pkgtype;
462         char *pkgid = NULL;
463         char *reqkey;
464
465         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
466         if (target_uid == (uid_t)-1 || pkgid == NULL) {
467                 g_dbus_method_invocation_return_value(invocation,
468                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
469                 return -1;
470         }
471
472         pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
473         if (pkgtype == NULL) {
474                 g_dbus_method_invocation_return_value(invocation,
475                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
476                 return -1;
477         }
478
479         reqkey = __generate_reqkey(pkgid);
480         if (reqkey == NULL) {
481                 g_dbus_method_invocation_return_value(invocation,
482                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
483                 free(pkgtype);
484                 return -1;
485         }
486         if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_REINSTALL,
487                                 pkgtype, pkgid, NULL)) {
488                 g_dbus_method_invocation_return_value(invocation,
489                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
490                 free(reqkey);
491                 free(pkgtype);
492                 return -1;
493         }
494
495         g_dbus_method_invocation_return_value(invocation,
496                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
497         free(reqkey);
498         free(pkgtype);
499
500         return 0;
501 }
502
503 static int __handle_request_uninstall(uid_t caller_uid,
504                 GDBusMethodInvocation *invocation, GVariant *parameters)
505 {
506         uid_t target_uid = (uid_t)-1;
507         char *pkgtype;
508         char *pkgid = NULL;
509         char *reqkey;
510
511         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
512         if (target_uid == (uid_t)-1 || pkgid == NULL) {
513                 g_dbus_method_invocation_return_value(invocation,
514                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
515                 return -1;
516         }
517
518         pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
519         if (pkgtype == NULL) {
520                 g_dbus_method_invocation_return_value(invocation,
521                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
522                 return -1;
523         }
524
525         reqkey = __generate_reqkey(pkgid);
526         if (reqkey == NULL) {
527                 g_dbus_method_invocation_return_value(invocation,
528                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
529                 free(pkgtype);
530                 return -1;
531         }
532         if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_UNINSTALL,
533                                 pkgtype, pkgid, NULL)) {
534                 g_dbus_method_invocation_return_value(invocation,
535                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
536                 free(reqkey);
537                 free(pkgtype);
538                 return -1;
539         }
540
541         g_dbus_method_invocation_return_value(invocation,
542                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
543         free(reqkey);
544         free(pkgtype);
545
546         return 0;
547 }
548
549 static int __handle_request_move(uid_t caller_uid,
550                 GDBusMethodInvocation *invocation, GVariant *parameters)
551 {
552         uid_t target_uid = (uid_t)-1;
553         char *pkgtype;
554         char *pkgid = NULL;
555         char *reqkey;
556         int move_type = -1;
557         char buf[4] = { '\0' };
558
559         g_variant_get(parameters, "(u&si)", &target_uid, &pkgid, &move_type);
560         if (target_uid == (uid_t)-1 || pkgid == NULL) {
561                 g_dbus_method_invocation_return_value(invocation,
562                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
563                 return -1;
564         }
565
566         pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
567         if (pkgtype == NULL) {
568                 g_dbus_method_invocation_return_value(invocation,
569                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
570                 return -1;
571         }
572
573         reqkey = __generate_reqkey(pkgid);
574         if (reqkey == NULL) {
575                 g_dbus_method_invocation_return_value(invocation,
576                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
577                 free(pkgtype);
578                 return -1;
579         }
580
581         snprintf(buf, sizeof(buf), "%d", move_type);
582         if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_MOVE,
583                                 pkgtype, pkgid, buf)) {
584                 g_dbus_method_invocation_return_value(invocation,
585                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
586                 free(reqkey);
587                 free(pkgtype);
588                 return -1;
589         }
590
591         g_dbus_method_invocation_return_value(invocation,
592                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
593         free(reqkey);
594         free(pkgtype);
595
596         return 0;
597 }
598
599 static int __handle_request_enable_pkgs(uid_t caller_uid,
600                 GDBusMethodInvocation *invocation, GVariant *parameters)
601 {
602         uid_t target_uid = (uid_t)-1;
603         char *pkgtype;
604         char *pkgid;
605         char *reqkey;
606         GVariantIter *iter;
607
608         g_variant_get(parameters, "(uas)", &target_uid, &iter);
609         if (target_uid == (uid_t)-1 || iter == NULL) {
610                 g_dbus_method_invocation_return_value(invocation,
611                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
612                 return -1;
613         }
614
615         reqkey = __generate_reqkey("enable_pkgs");
616         if (reqkey == NULL) {
617                 g_dbus_method_invocation_return_value(invocation,
618                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
619                 return -1;
620         }
621
622         while (g_variant_iter_next(iter, "&s", &pkgid)) {
623                 pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
624                 if (pkgtype == NULL) {
625                         g_dbus_method_invocation_return_value(invocation,
626                                         g_variant_new("(is)",
627                                                 PKGMGR_R_ESYSTEM, ""));
628                         free(reqkey);
629                         return -1;
630                 }
631                 if (_push_queue(target_uid, caller_uid, reqkey,
632                                         REQUEST_TYPE_ENABLE_PKG,
633                                         pkgtype, pkgid, NULL)) {
634                         g_dbus_method_invocation_return_value(invocation,
635                                         g_variant_new("(is)",
636                                                 PKGMGR_R_ESYSTEM, ""));
637                         free(pkgtype);
638                         free(reqkey);
639                         return -1;
640                 }
641                 free(pkgtype);
642         }
643
644         g_dbus_method_invocation_return_value(invocation,
645                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
646         free(reqkey);
647
648         return 0;
649 }
650
651 static int __handle_request_disable_pkgs(uid_t caller_uid,
652                 GDBusMethodInvocation *invocation, GVariant *parameters)
653 {
654         uid_t target_uid = (uid_t)-1;
655         char *pkgtype;
656         char *pkgid;
657         char *reqkey;
658         GVariantIter *iter;
659
660         g_variant_get(parameters, "(uas)", &target_uid, &iter);
661         if (target_uid == (uid_t)-1 || iter == NULL) {
662                 g_dbus_method_invocation_return_value(invocation,
663                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
664                 return -1;
665         }
666
667         reqkey = __generate_reqkey("disable_pkgs");
668         if (reqkey == NULL) {
669                 g_dbus_method_invocation_return_value(invocation,
670                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
671                 return -1;
672         }
673
674         while (g_variant_iter_next(iter, "&s", &pkgid)) {
675                 pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
676                 if (pkgtype == NULL) {
677                         g_dbus_method_invocation_return_value(invocation,
678                                         g_variant_new("(is)",
679                                                 PKGMGR_R_ESYSTEM, ""));
680                         free(reqkey);
681                         return -1;
682                 }
683                 if (_push_queue(target_uid, caller_uid, reqkey,
684                                         REQUEST_TYPE_DISABLE_PKG,
685                                         pkgtype, pkgid, NULL)) {
686                         g_dbus_method_invocation_return_value(invocation,
687                                         g_variant_new("(is)",
688                                                 PKGMGR_R_ESYSTEM, ""));
689                         free(pkgtype);
690                         free(reqkey);
691                         return -1;
692                 }
693                 free(pkgtype);
694         }
695
696         g_dbus_method_invocation_return_value(invocation,
697                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
698         free(reqkey);
699
700         return 0;
701 }
702
703 static int __handle_request_enable_app(uid_t caller_uid,
704                 GDBusMethodInvocation *invocation, GVariant *parameters)
705 {
706         uid_t target_uid = (uid_t)-1;
707         char *appid = NULL;
708         char *reqkey = NULL;
709         int ret = -1;
710
711         g_variant_get(parameters, "(u&s)", &target_uid, &appid);
712         if (target_uid == (uid_t)-1 || appid == NULL) {
713                 g_dbus_method_invocation_return_value(invocation,
714                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
715                 return -1;
716         }
717
718         reqkey = __generate_reqkey(appid);
719         if (reqkey == NULL) {
720                 g_dbus_method_invocation_return_value(invocation,
721                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
722                 ret = -1;
723                 goto catch;
724         }
725
726         if (_push_queue(target_uid, caller_uid, reqkey,
727                                 REQUEST_TYPE_ENABLE_APP, "default",
728                                 appid, NULL)) {
729                 g_dbus_method_invocation_return_value(invocation,
730                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
731                 ret = -1;
732                 goto catch;
733         }
734
735         g_dbus_method_invocation_return_value(invocation,
736                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
737
738         ret = 0;
739
740 catch:
741         if (reqkey)
742                 free(reqkey);
743
744         return ret;
745 }
746
747 static int __handle_request_disable_app(uid_t caller_uid,
748                 GDBusMethodInvocation *invocation, GVariant *parameters)
749 {
750         uid_t target_uid = (uid_t)-1;
751         char *appid = NULL;
752         char *reqkey = NULL;
753         int ret = -1;
754
755         g_variant_get(parameters, "(u&s)", &target_uid, &appid);
756         if (target_uid == (uid_t)-1 || appid == NULL) {
757                 g_dbus_method_invocation_return_value(invocation,
758                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
759                 return -1;
760         }
761
762         reqkey = __generate_reqkey(appid);
763         if (reqkey == NULL) {
764                 g_dbus_method_invocation_return_value(invocation,
765                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
766                 ret = -1;
767                 goto catch;
768         }
769
770         if (_push_queue(target_uid, caller_uid, reqkey,
771                                 REQUEST_TYPE_DISABLE_APP, "default",
772                                 appid, NULL)) {
773                 g_dbus_method_invocation_return_value(invocation,
774                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
775                 ret = -1;
776                 goto catch;
777         }
778
779         g_dbus_method_invocation_return_value(invocation,
780                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
781
782         ret = 0;
783
784 catch:
785         if (reqkey)
786                 free(reqkey);
787
788         return ret;
789 }
790
791 static int __handle_request_enable_global_app_for_uid(uid_t caller_uid,
792                 GDBusMethodInvocation *invocation, GVariant *parameters)
793 {
794         uid_t target_uid = (uid_t)-1;
795         char *appid = NULL;
796         char *reqkey = NULL;
797         int ret = -1;
798
799         g_variant_get(parameters, "(u&s)", &target_uid, &appid);
800         if (target_uid == (uid_t)-1 || appid == NULL) {
801                 g_dbus_method_invocation_return_value(invocation,
802                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
803                 return -1;
804         }
805
806         reqkey = __generate_reqkey(appid);
807         if (reqkey == NULL) {
808                 g_dbus_method_invocation_return_value(invocation,
809                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
810                 ret = -1;
811                 goto catch;
812         }
813
814         if (_push_queue(target_uid, caller_uid, reqkey,
815                                 REQUEST_TYPE_ENABLE_GLOBAL_APP_FOR_UID,
816                                 "default", appid, NULL)) {
817                 g_dbus_method_invocation_return_value(invocation,
818                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
819                 ret = -1;
820                 goto catch;
821         }
822
823         g_dbus_method_invocation_return_value(invocation,
824                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
825
826         ret = 0;
827
828 catch:
829         if (reqkey)
830                 free(reqkey);
831
832         return ret;
833 }
834
835 static int __handle_request_disable_global_app_for_uid(uid_t caller_uid,
836                 GDBusMethodInvocation *invocation, GVariant *parameters)
837 {
838         uid_t target_uid = (uid_t)-1;
839         char *appid = NULL;
840         char *reqkey = NULL;
841         int ret = -1;
842
843         g_variant_get(parameters, "(u&s)", &target_uid, &appid);
844         if (target_uid == (uid_t)-1 || appid == NULL) {
845                 g_dbus_method_invocation_return_value(invocation,
846                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
847                 return -1;
848         }
849
850         reqkey = __generate_reqkey(appid);
851         if (reqkey == NULL) {
852                 g_dbus_method_invocation_return_value(invocation,
853                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
854                 ret = -1;
855                 goto catch;
856         }
857
858         if (_push_queue(target_uid, caller_uid, reqkey,
859                                 REQUEST_TYPE_DISABLE_GLOBAL_APP_FOR_UID,
860                                 "default", appid, NULL)) {
861                 g_dbus_method_invocation_return_value(invocation,
862                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
863                 ret = -1;
864                 goto catch;
865         }
866
867         g_dbus_method_invocation_return_value(invocation,
868                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
869
870         ret = 0;
871
872 catch:
873         if (reqkey)
874                 free(reqkey);
875
876         return ret;
877 }
878
879 static int __handle_request_getsize(uid_t caller_uid,
880                 GDBusMethodInvocation *invocation, GVariant *parameters)
881 {
882         uid_t target_uid = (uid_t)-1;
883         char *pkgid = NULL;
884         int get_type = -1;
885         char *reqkey;
886         char buf[4];
887
888         g_variant_get(parameters, "(u&si)", &target_uid, &pkgid, &get_type);
889         if (target_uid == (uid_t)-1 || pkgid == NULL || get_type == -1) {
890                 g_dbus_method_invocation_return_value(invocation,
891                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
892                 return -1;
893         }
894
895         reqkey = __generate_reqkey(pkgid);
896         if (reqkey == NULL) {
897                 g_dbus_method_invocation_return_value(invocation,
898                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
899                 return -1;
900         }
901
902         snprintf(buf, sizeof(buf), "%d", get_type);
903         if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_GETSIZE,
904                                 "pkgtool", pkgid, buf)) {
905                 g_dbus_method_invocation_return_value(invocation,
906                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
907                 free(reqkey);
908                 return -1;
909         }
910
911         g_dbus_method_invocation_return_value(invocation,
912                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
913         free(reqkey);
914
915         return 0;
916 }
917
918 static int __handle_request_cleardata(uid_t caller_uid,
919                 GDBusMethodInvocation *invocation, GVariant *parameters)
920 {
921         uid_t target_uid = (uid_t)-1;
922         char *pkgtype;
923         char *pkgid = NULL;
924         char *reqkey = NULL;
925
926         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
927         if (target_uid == (uid_t)-1 || pkgid == NULL) {
928                 g_dbus_method_invocation_return_value(invocation,
929                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
930                 return -1;
931         }
932
933         pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
934         if (pkgtype == NULL) {
935                 g_dbus_method_invocation_return_value(invocation,
936                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
937                 return -1;
938         }
939
940         reqkey = __generate_reqkey(pkgid);
941         if (reqkey == NULL) {
942                 g_dbus_method_invocation_return_value(invocation,
943                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
944                 free(pkgtype);
945                 return -1;
946         }
947
948         if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_CLEARDATA,
949                                 pkgtype, pkgid, NULL)) {
950                 g_dbus_method_invocation_return_value(invocation,
951                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
952                 free(reqkey);
953                 free(pkgtype);
954                 return -1;
955         }
956
957         g_dbus_method_invocation_return_value(invocation,
958                         g_variant_new("(i)", PKGMGR_R_OK));
959
960         free(reqkey);
961         free(pkgtype);
962
963         return 0;
964 }
965
966 static int __handle_request_clearcache(uid_t caller_uid,
967                 GDBusMethodInvocation *invocation, GVariant *parameters)
968 {
969         uid_t target_uid = (uid_t)-1;
970         char *pkgid = NULL;
971
972         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
973         if (target_uid == (uid_t)-1 || pkgid == NULL) {
974                 g_dbus_method_invocation_return_value(invocation,
975                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
976                 return -1;
977         }
978
979         if (_push_queue(target_uid, caller_uid, NULL, REQUEST_TYPE_CLEARCACHE,
980                                 "pkgtool",  pkgid, NULL)) {
981                 g_dbus_method_invocation_return_value(invocation,
982                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
983                 return -1;
984         }
985
986         g_dbus_method_invocation_return_value(invocation,
987                         g_variant_new("(i)", PKGMGR_R_OK));
988
989         return 0;
990 }
991
992 static int __handle_request_kill(uid_t caller_uid,
993                 GDBusMethodInvocation *invocation, GVariant *parameters)
994 {
995         uid_t target_uid = (uid_t)-1;
996         char *pkgid = NULL;
997         char *reqkey = NULL;
998
999         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
1000         if (target_uid == (uid_t)-1 || pkgid == NULL) {
1001                 g_dbus_method_invocation_return_value(invocation,
1002                                 g_variant_new("(ii)", PKGMGR_R_ECOMM, 0));
1003                 return -1;
1004         }
1005
1006         reqkey = __generate_reqkey(pkgid);
1007         if (reqkey == NULL) {
1008                 g_dbus_method_invocation_return_value(invocation,
1009                                 g_variant_new("(ii)", PKGMGR_R_ENOMEM, 0));
1010                 return -1;
1011         }
1012
1013         if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_KILL,
1014                                 "default", pkgid, NULL)) {
1015                 g_dbus_method_invocation_return_value(invocation,
1016                                 g_variant_new("(ii)", PKGMGR_R_ESYSTEM, 0));
1017                 free(reqkey);
1018                 return -1;
1019         }
1020
1021         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1022                                 (gpointer)invocation))
1023                 ERR("reqkey already exists");
1024
1025         return 0;
1026 }
1027
1028 static int __handle_request_check(uid_t caller_uid,
1029                 GDBusMethodInvocation *invocation, GVariant *parameters)
1030 {
1031         uid_t target_uid = (uid_t)-1;
1032         char *pkgid = NULL;
1033         char *reqkey = NULL;
1034
1035         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
1036         if (target_uid == (uid_t)-1 || pkgid == NULL) {
1037                 g_dbus_method_invocation_return_value(invocation,
1038                                 g_variant_new("(ii)", PKGMGR_R_ECOMM, 0));
1039                 return -1;
1040         }
1041
1042         reqkey = __generate_reqkey(pkgid);
1043         if (reqkey == NULL) {
1044                 g_dbus_method_invocation_return_value(invocation,
1045                                 g_variant_new("(ii)", PKGMGR_R_ENOMEM, 0));
1046                 return -1;
1047         }
1048
1049         if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_CHECK,
1050                                 "default", pkgid, NULL)) {
1051                 g_dbus_method_invocation_return_value(invocation,
1052                                 g_variant_new("(ii)", PKGMGR_R_ESYSTEM, 0));
1053                 free(reqkey);
1054                 return -1;
1055         }
1056
1057         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1058                                 (gpointer)invocation))
1059                 ERR("reqkey already exists");
1060
1061         return 0;
1062 }
1063
1064 static int __handle_request_generate_license_request(uid_t caller_uid,
1065                 GDBusMethodInvocation *invocation, GVariant *parameters)
1066 {
1067         char *reqkey;
1068         char *resp_data = NULL;
1069
1070         g_variant_get(parameters, "(&s)", &resp_data);
1071         if (resp_data == NULL) {
1072                 g_dbus_method_invocation_return_value(invocation,
1073                                 g_variant_new("(iss)", PKGMGR_R_ECOMM, "", ""));
1074                 return -1;
1075         }
1076
1077         reqkey = __generate_reqkey("drm");
1078         if (reqkey == NULL) {
1079                 g_dbus_method_invocation_return_value(invocation,
1080                                 g_variant_new("(iss)", PKGMGR_R_ENOMEM, "",
1081                                         ""));
1082                 return -1;
1083         }
1084
1085         if (_push_queue(caller_uid, caller_uid, reqkey,
1086                                 REQUEST_TYPE_GENERATE_LICENSE_REQUEST,
1087                                 "default", NULL, resp_data)) {
1088                 g_dbus_method_invocation_return_value(invocation,
1089                                 g_variant_new("(iss)", PKGMGR_R_ESYSTEM, "",
1090                                         ""));
1091                 free(reqkey);
1092                 return -1;
1093         }
1094
1095         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1096                                 (gpointer)invocation))
1097                 ERR("reqkey already exists");
1098
1099         return 0;
1100 }
1101
1102 static int __handle_request_register_license(uid_t caller_uid,
1103                 GDBusMethodInvocation *invocation, GVariant *parameters)
1104 {
1105         char *reqkey;
1106         char *resp_data = NULL;
1107
1108         g_variant_get(parameters, "(&s)", &resp_data);
1109         if (resp_data == NULL) {
1110                 g_dbus_method_invocation_return_value(invocation,
1111                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
1112                 return -1;
1113         }
1114
1115         reqkey = __generate_reqkey("drm");
1116         if (reqkey == NULL) {
1117                 g_dbus_method_invocation_return_value(invocation,
1118                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1119                 return -1;
1120         }
1121
1122         if (_push_queue(caller_uid, caller_uid, reqkey,
1123                                 REQUEST_TYPE_REGISTER_LICENSE,
1124                                 "default", NULL, resp_data)) {
1125                 g_dbus_method_invocation_return_value(invocation,
1126                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1127                 free(reqkey);
1128                 return -1;
1129         }
1130
1131         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1132                                 (gpointer)invocation))
1133                 ERR("reqkey already exists");
1134
1135         return 0;
1136 }
1137
1138 static int __handle_request_decrypt_package(uid_t caller_uid,
1139                 GDBusMethodInvocation *invocation, GVariant *parameters)
1140 {
1141         char *reqkey;
1142         char *drm_file_path = NULL;
1143         char *decrypted_file_path = NULL;
1144
1145         g_variant_get(parameters, "(&s&s)", &drm_file_path,
1146                         &decrypted_file_path);
1147         if (drm_file_path == NULL || decrypted_file_path == NULL) {
1148                 g_dbus_method_invocation_return_value(invocation,
1149                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
1150                 return -1;
1151         }
1152
1153         reqkey = __generate_reqkey("drm");
1154         if (reqkey == NULL) {
1155                 g_dbus_method_invocation_return_value(invocation,
1156                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1157                 return -1;
1158         }
1159
1160         if (_push_queue(caller_uid, caller_uid, reqkey,
1161                                 REQUEST_TYPE_DECRYPT_PACKAGE,
1162                                 "default", drm_file_path,
1163                                 decrypted_file_path)) {
1164                 g_dbus_method_invocation_return_value(invocation,
1165                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1166                 free(reqkey);
1167                 return -1;
1168         }
1169
1170         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1171                                 (gpointer)invocation))
1172                 ERR("reqkey already exists");
1173
1174         return 0;
1175 }
1176
1177 static int __update_app_splash_screen(uid_t caller_uid,
1178                 GDBusMethodInvocation *invocation, GVariant *parameters,
1179                 int req_type)
1180 {
1181         uid_t target_uid = (uid_t)-1;
1182         char *appid = NULL;
1183         char *reqkey;
1184
1185         g_variant_get(parameters, "(u&s)", &target_uid, &appid);
1186         if (target_uid == (uid_t)-1 || appid == NULL) {
1187                 ERR("target_uid: %d, appid: %s", target_uid, appid);
1188                 g_dbus_method_invocation_return_value(invocation,
1189                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
1190                 return -1;
1191         }
1192
1193         reqkey = __generate_reqkey(appid);
1194         if (reqkey == NULL) {
1195                 ERR("Failed to generate request key");
1196                 g_dbus_method_invocation_return_value(invocation,
1197                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1198                 return -1;
1199         }
1200
1201         if (_push_queue(target_uid, caller_uid, reqkey, req_type, "default",
1202                                 appid, NULL)) {
1203                 ERR("Failed to push request");
1204                 g_dbus_method_invocation_return_value(invocation,
1205                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1206                 free(reqkey);
1207                 return -1;
1208         }
1209
1210         g_dbus_method_invocation_return_value(invocation,
1211                         g_variant_new("(i)", PKGMGR_R_OK));
1212
1213         if (reqkey)
1214                 free(reqkey);
1215
1216         return 0;
1217 }
1218
1219 static int __handle_request_enable_app_splash_screen(uid_t caller_uid,
1220                 GDBusMethodInvocation *invocation, GVariant *parameters)
1221 {
1222         return __update_app_splash_screen(caller_uid, invocation, parameters,
1223                         REQUEST_TYPE_ENABLE_APP_SPLASH_SCREEN);
1224 }
1225
1226 static int __handle_request_disable_app_splash_screen(uid_t caller_uid,
1227                 GDBusMethodInvocation *invocation, GVariant *parameters)
1228 {
1229         return __update_app_splash_screen(caller_uid, invocation, parameters,
1230                         REQUEST_TYPE_DISABLE_APP_SPLASH_SCREEN);
1231 }
1232
1233 static int __handle_request_set_restriction_mode(uid_t caller_uid,
1234                 GDBusMethodInvocation *invocation, GVariant *parameters)
1235 {
1236         uid_t target_uid = (uid_t)-1;
1237         char *pkgid = NULL;
1238         char *reqkey;
1239         int mode = -1;
1240         char buf[4];
1241
1242         g_variant_get(parameters, "(usi)", &target_uid, &pkgid, &mode);
1243         if (target_uid == (uid_t)-1 || pkgid == NULL || mode < 0) {
1244                 g_dbus_method_invocation_return_value(invocation,
1245                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
1246                 return -1;
1247         }
1248
1249         reqkey = __generate_reqkey("restriction");
1250         if (reqkey == NULL) {
1251                 g_dbus_method_invocation_return_value(invocation,
1252                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1253                 return -1;
1254         }
1255
1256         snprintf(buf, sizeof(buf), "%d", mode);
1257         if (_push_queue(target_uid, caller_uid, reqkey,
1258                                 REQUEST_TYPE_SET_RESTRICTION_MODE,
1259                                 "default", pkgid, buf)) {
1260                 g_dbus_method_invocation_return_value(invocation,
1261                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1262                 free(reqkey);
1263                 return -1;
1264         }
1265
1266         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1267                                 (gpointer)invocation))
1268                 ERR("reqkey already exists");
1269
1270         return 0;
1271 }
1272
1273 static int __handle_request_unset_restriction_mode(uid_t caller_uid,
1274                 GDBusMethodInvocation *invocation, GVariant *parameters)
1275 {
1276         uid_t target_uid = (uid_t)-1;
1277         char *pkgid = NULL;
1278         char *reqkey;
1279         int mode = -1;
1280         char buf[4];
1281
1282         g_variant_get(parameters, "(usi)", &target_uid, &pkgid, &mode);
1283         if (target_uid == (uid_t)-1 || pkgid == NULL || mode < 0) {
1284                 g_dbus_method_invocation_return_value(invocation,
1285                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
1286                 return -1;
1287         }
1288
1289         reqkey = __generate_reqkey("restriction");
1290         if (reqkey == NULL) {
1291                 g_dbus_method_invocation_return_value(invocation,
1292                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1293                 return -1;
1294         }
1295
1296         snprintf(buf, sizeof(buf), "%d", mode);
1297         if (_push_queue(target_uid, caller_uid, reqkey,
1298                                 REQUEST_TYPE_UNSET_RESTRICTION_MODE,
1299                                 "default", pkgid, buf)) {
1300                 g_dbus_method_invocation_return_value(invocation,
1301                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1302                 free(reqkey);
1303                 return -1;
1304         }
1305
1306         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1307                                 (gpointer)invocation))
1308                 ERR("reqkey already exists");
1309
1310         return 0;
1311 }
1312
1313 static int __handle_request_get_restriction_mode(uid_t caller_uid,
1314                 GDBusMethodInvocation *invocation, GVariant *parameters)
1315 {
1316         uid_t target_uid = (uid_t)-1;
1317         char *pkgid = NULL;
1318         char *reqkey;
1319
1320         g_variant_get(parameters, "(us)", &target_uid, &pkgid);
1321         if (target_uid == (uid_t)-1 || pkgid == NULL) {
1322                 g_dbus_method_invocation_return_value(invocation,
1323                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
1324                 return -1;
1325         }
1326
1327         reqkey = __generate_reqkey("restriction");
1328         if (reqkey == NULL) {
1329                 g_dbus_method_invocation_return_value(invocation,
1330                                 g_variant_new("(ii)", -1, PKGMGR_R_ENOMEM));
1331                 return -1;
1332         }
1333
1334         if (_push_queue(target_uid, caller_uid, reqkey,
1335                                 REQUEST_TYPE_GET_RESTRICTION_MODE,
1336                                 "default", pkgid, NULL)) {
1337                 g_dbus_method_invocation_return_value(invocation,
1338                                 g_variant_new("(ii)", -1, PKGMGR_R_ESYSTEM));
1339                 free(reqkey);
1340                 return -1;
1341         }
1342
1343         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1344                                 (gpointer)invocation))
1345                 ERR("reqkey already exists");
1346
1347         return 0;
1348 }
1349
1350 static int __handle_request_set_app_label(uid_t uid,
1351                 GDBusMethodInvocation *invocation, GVariant *parameters)
1352 {
1353         uid_t target_uid = (uid_t)-1;
1354         char *appid = NULL;
1355         char *label = NULL;
1356         char *reqkey;
1357
1358         g_variant_get(parameters, "(uss)", &target_uid, &appid, &label);
1359         if (target_uid == (uid_t)-1 || appid == NULL || label == NULL) {
1360                 g_dbus_method_invocation_return_value(invocation,
1361                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
1362                 return -1;
1363         }
1364
1365         reqkey = __generate_reqkey("appid");
1366         if (reqkey == NULL) {
1367                 g_dbus_method_invocation_return_value(invocation,
1368                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1369                 return -1;
1370         }
1371
1372         if (_push_queue(target_uid, uid, reqkey,
1373                                 REQUEST_TYPE_SET_APP_LABEL,
1374                                 "default", appid, label)) {
1375                 g_dbus_method_invocation_return_value(invocation,
1376                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1377                 free(reqkey);
1378                 return -1;
1379         }
1380
1381         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1382                                 (gpointer)invocation))
1383                 ERR("reqkey already exists");
1384
1385         return 0;
1386 }
1387
1388 static uid_t __get_caller_uid(GDBusConnection *connection, const char *name)
1389 {
1390         GError *err = NULL;
1391         GVariant *result;
1392         uid_t uid;
1393
1394         result = g_dbus_connection_call_sync(connection,
1395                         "org.freedesktop.DBus", "/org/freedesktop/DBus",
1396                         "org.freedesktop.DBus", "GetConnectionUnixUser",
1397                         g_variant_new("(s)", name), NULL,
1398                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
1399         if (result == NULL) {
1400                 ERR("failed to get caller uid: %s", err->message);
1401                 g_error_free(err);
1402                 return (uid_t)-1;
1403         }
1404
1405         g_variant_get(result, "(u)", &uid);
1406
1407         return uid;
1408 }
1409
1410 static void __handle_method_call(GDBusConnection *connection,
1411                 const gchar *sender, const gchar *object_path,
1412                 const gchar *interface_name, const gchar *method_name,
1413                 GVariant *parameters, GDBusMethodInvocation *invocation,
1414                 gpointer user_data)
1415 {
1416         int ret;
1417         uid_t uid;
1418
1419         uid = __get_caller_uid(connection,
1420                 g_dbus_method_invocation_get_sender(invocation));
1421         if (uid == (uid_t)-1)
1422                 return;
1423
1424         if (__check_caller_permission(uid, invocation, parameters))
1425                 return;
1426
1427         if (g_strcmp0(method_name, "install") == 0)
1428                 ret = __handle_request_install(uid, invocation, parameters);
1429         else if (g_strcmp0(method_name, "mount_install") == 0)
1430                 ret = __handle_request_mount_install(uid, invocation,
1431                                 parameters);
1432         else if (g_strcmp0(method_name, "reinstall") == 0)
1433                 ret = __handle_request_reinstall(uid, invocation, parameters);
1434         else if (g_strcmp0(method_name, "uninstall") == 0)
1435                 ret = __handle_request_uninstall(uid, invocation, parameters);
1436         else if (g_strcmp0(method_name, "cleardata") == 0)
1437                 ret = __handle_request_cleardata(uid, invocation, parameters);
1438         else if (g_strcmp0(method_name, "move") == 0)
1439                 ret = __handle_request_move(uid, invocation, parameters);
1440         else if (g_strcmp0(method_name, "enable_pkgs") == 0)
1441                 ret = __handle_request_enable_pkgs(uid, invocation, parameters);
1442         else if (g_strcmp0(method_name, "disable_pkgs") == 0)
1443                 ret = __handle_request_disable_pkgs(uid, invocation, parameters);
1444         else if (g_strcmp0(method_name, "getsize") == 0)
1445                 ret = __handle_request_getsize(uid, invocation, parameters);
1446         else if (g_strcmp0(method_name, "clearcache") == 0)
1447                 ret = __handle_request_clearcache(uid, invocation, parameters);
1448         else if (g_strcmp0(method_name, "enable_app") == 0)
1449                 ret = __handle_request_enable_app(uid, invocation, parameters);
1450         else if (g_strcmp0(method_name, "disable_app") == 0)
1451                 ret = __handle_request_disable_app(uid, invocation, parameters);
1452         else if (g_strcmp0(method_name, "enable_global_app_for_uid") == 0)
1453                 ret = __handle_request_enable_global_app_for_uid(uid,
1454                                 invocation, parameters);
1455         else if (g_strcmp0(method_name, "disable_global_app_for_uid") == 0)
1456                 ret = __handle_request_disable_global_app_for_uid(uid,
1457                                 invocation, parameters);
1458         else if (g_strcmp0(method_name, "kill") == 0)
1459                 ret = __handle_request_kill(uid, invocation, parameters);
1460         else if (g_strcmp0(method_name, "check") == 0)
1461                 ret = __handle_request_check(uid, invocation, parameters);
1462         else if (g_strcmp0(method_name, "generate_license_request") == 0)
1463                 ret = __handle_request_generate_license_request(uid, invocation,
1464                                 parameters);
1465         else if (g_strcmp0(method_name, "register_license") == 0)
1466                 ret = __handle_request_register_license(uid, invocation,
1467                                 parameters);
1468         else if (g_strcmp0(method_name, "decrypt_package") == 0)
1469                 ret = __handle_request_decrypt_package(uid, invocation,
1470                                 parameters);
1471         else if (g_strcmp0(method_name, "disable_app_splash_screen") == 0)
1472                 ret = __handle_request_disable_app_splash_screen(uid,
1473                                 invocation, parameters);
1474         else if (g_strcmp0(method_name, "enable_app_splash_screen") == 0)
1475                 ret = __handle_request_enable_app_splash_screen(uid,
1476                                 invocation, parameters);
1477         else if (g_strcmp0(method_name, "set_restriction_mode") == 0)
1478                 ret = __handle_request_set_restriction_mode(uid, invocation,
1479                                 parameters);
1480         else if (g_strcmp0(method_name, "unset_restriction_mode") == 0)
1481                 ret = __handle_request_unset_restriction_mode(uid, invocation,
1482                                 parameters);
1483         else if (g_strcmp0(method_name, "get_restriction_mode") == 0)
1484                 ret = __handle_request_get_restriction_mode(uid, invocation,
1485                                 parameters);
1486         else if (g_strcmp0(method_name, "set_app_label") == 0)
1487                 ret = __handle_request_set_app_label(uid, invocation, parameters);
1488         else
1489                 ret = -1;
1490
1491         if (ret == 0)
1492                 g_idle_add(queue_job, NULL);
1493 }
1494
1495 int _return_value_to_caller(const char *req_key, GVariant *result)
1496 {
1497         GDBusMethodInvocation *invocation;
1498
1499         invocation = (GDBusMethodInvocation *)g_hash_table_lookup(req_table,
1500                         (gpointer)req_key);
1501         if (invocation == NULL) {
1502                 ERR("no such request id");
1503                 return -1;
1504         }
1505
1506         g_dbus_method_invocation_return_value(invocation, result);
1507         g_hash_table_remove(req_table, (gpointer)req_key);
1508
1509         return 0;
1510 }
1511
1512 static const GDBusInterfaceVTable interface_vtable = {
1513         __handle_method_call,
1514         NULL,
1515         NULL,
1516 };
1517
1518 static void __on_bus_acquired(GDBusConnection *connection, const gchar *name,
1519                 gpointer user_data)
1520 {
1521         GError *err = NULL;
1522
1523         DBG("on bus acquired");
1524
1525         reg_id = g_dbus_connection_register_object(connection,
1526                         PKGMGR_DBUS_OBJECT_PATH,
1527                         instropection_data->interfaces[0],
1528                         &interface_vtable, NULL, NULL, &err);
1529
1530         if (reg_id == 0) {
1531                 ERR("failed to register object: %s", err->message);
1532                 g_error_free(err);
1533         }
1534 }
1535
1536 static void __on_name_acquired(GDBusConnection *connection, const gchar *name,
1537                 gpointer user_data)
1538 {
1539         DBG("on name acquired: %s", name);
1540 }
1541
1542 static void __on_name_lost(GDBusConnection *connection, const gchar *name,
1543                 gpointer user_data)
1544 {
1545         DBG("on name lost: %s", name);
1546 }
1547
1548 int _init_request_handler(void)
1549 {
1550         instropection_data = g_dbus_node_info_new_for_xml(instropection_xml,
1551                         NULL);
1552
1553         owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, PKGMGR_DBUS_SERVICE,
1554                         G_BUS_NAME_OWNER_FLAGS_NONE, __on_bus_acquired,
1555                         __on_name_acquired, __on_name_lost, NULL, NULL);
1556
1557         req_table = g_hash_table_new_full(g_str_hash, g_str_equal,
1558                         free, NULL);
1559         if (req_table == NULL)
1560                 return -1;
1561
1562         return 0;
1563 }
1564
1565 void _fini_request_handler(void)
1566 {
1567         g_hash_table_destroy(req_table);
1568         g_bus_unown_name(owner_id);
1569         g_dbus_node_info_unref(instropection_data);
1570 }