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