e625e2b816c110195863f16dfe84485e25d2f474
[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         char *pkgtype;
1081
1082         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
1083         if (target_uid == (uid_t)-1 || pkgid == NULL) {
1084                 g_dbus_method_invocation_return_value(invocation,
1085                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
1086                 return -1;
1087         }
1088
1089         pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
1090         if (pkgtype == NULL) {
1091                 g_dbus_method_invocation_return_value(invocation,
1092                                 g_variant_new("(is)", PKGMGR_R_ENOPKG, ""));
1093                 return -1;
1094         }
1095
1096         if (_push_queue(target_uid, caller_uid, NULL, REQUEST_TYPE_CLEARDATA,
1097                                 pkgtype, pkgid, NULL)) {
1098                 g_dbus_method_invocation_return_value(invocation,
1099                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1100                 free(pkgtype);
1101                 return -1;
1102         }
1103
1104         g_dbus_method_invocation_return_value(invocation,
1105                         g_variant_new("(i)", PKGMGR_R_OK));
1106         free(pkgtype);
1107
1108         return 0;
1109 }
1110
1111 static int __handle_request_clearcache(uid_t caller_uid,
1112                 GDBusMethodInvocation *invocation, GVariant *parameters)
1113 {
1114         uid_t target_uid = (uid_t)-1;
1115         char *pkgid = NULL;
1116         char *pkgtype;
1117
1118         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
1119         if (target_uid == (uid_t)-1 || pkgid == NULL) {
1120                 g_dbus_method_invocation_return_value(invocation,
1121                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
1122                 return -1;
1123         }
1124
1125         if (strcmp(PKG_CLEAR_ALL_CACHE, pkgid) == 0)
1126                 pkgtype = strdup("pkgtool");
1127         else
1128                 pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
1129         if (pkgtype == NULL) {
1130                 g_dbus_method_invocation_return_value(invocation,
1131                                 g_variant_new("(is)", PKGMGR_R_ENOPKG, ""));
1132                 return -1;
1133         }
1134
1135         if (_push_queue(target_uid, caller_uid, NULL, REQUEST_TYPE_CLEARCACHE,
1136                                 pkgtype,  pkgid, NULL)) {
1137                 g_dbus_method_invocation_return_value(invocation,
1138                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1139                 free(pkgtype);
1140                 return -1;
1141         }
1142
1143         g_dbus_method_invocation_return_value(invocation,
1144                         g_variant_new("(i)", PKGMGR_R_OK));
1145         free(pkgtype);
1146
1147         return 0;
1148 }
1149
1150 static int __handle_request_kill(uid_t caller_uid,
1151                 GDBusMethodInvocation *invocation, GVariant *parameters)
1152 {
1153         uid_t target_uid = (uid_t)-1;
1154         char *pkgid = NULL;
1155         char *reqkey = NULL;
1156
1157         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
1158         if (target_uid == (uid_t)-1 || pkgid == NULL) {
1159                 g_dbus_method_invocation_return_value(invocation,
1160                                 g_variant_new("(ii)", PKGMGR_R_ECOMM, 0));
1161                 return -1;
1162         }
1163
1164         reqkey = __generate_reqkey(pkgid);
1165         if (reqkey == NULL) {
1166                 g_dbus_method_invocation_return_value(invocation,
1167                                 g_variant_new("(ii)", PKGMGR_R_ENOMEM, 0));
1168                 return -1;
1169         }
1170
1171         if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_KILL,
1172                                 "default", pkgid, NULL)) {
1173                 g_dbus_method_invocation_return_value(invocation,
1174                                 g_variant_new("(ii)", PKGMGR_R_ESYSTEM, 0));
1175                 free(reqkey);
1176                 return -1;
1177         }
1178
1179         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1180                                 (gpointer)invocation))
1181                 ERR("reqkey already exists");
1182
1183         return 0;
1184 }
1185
1186 static int __handle_request_check(uid_t caller_uid,
1187                 GDBusMethodInvocation *invocation, GVariant *parameters)
1188 {
1189         uid_t target_uid = (uid_t)-1;
1190         char *pkgid = NULL;
1191         char *reqkey = NULL;
1192
1193         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
1194         if (target_uid == (uid_t)-1 || pkgid == NULL) {
1195                 g_dbus_method_invocation_return_value(invocation,
1196                                 g_variant_new("(ii)", PKGMGR_R_ECOMM, 0));
1197                 return -1;
1198         }
1199
1200         reqkey = __generate_reqkey(pkgid);
1201         if (reqkey == NULL) {
1202                 g_dbus_method_invocation_return_value(invocation,
1203                                 g_variant_new("(ii)", PKGMGR_R_ENOMEM, 0));
1204                 return -1;
1205         }
1206
1207         if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_CHECK,
1208                                 "default", pkgid, NULL)) {
1209                 g_dbus_method_invocation_return_value(invocation,
1210                                 g_variant_new("(ii)", PKGMGR_R_ESYSTEM, 0));
1211                 free(reqkey);
1212                 return -1;
1213         }
1214
1215         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1216                                 (gpointer)invocation))
1217                 ERR("reqkey already exists");
1218
1219         return 0;
1220 }
1221
1222 static int __handle_request_generate_license_request(uid_t caller_uid,
1223                 GDBusMethodInvocation *invocation, GVariant *parameters)
1224 {
1225         char *reqkey;
1226         char *resp_data = NULL;
1227
1228         g_variant_get(parameters, "(&s)", &resp_data);
1229         if (resp_data == NULL) {
1230                 g_dbus_method_invocation_return_value(invocation,
1231                                 g_variant_new("(iss)", PKGMGR_R_ECOMM, "", ""));
1232                 return -1;
1233         }
1234
1235         reqkey = __generate_reqkey("drm");
1236         if (reqkey == NULL) {
1237                 g_dbus_method_invocation_return_value(invocation,
1238                                 g_variant_new("(iss)", PKGMGR_R_ENOMEM, "",
1239                                         ""));
1240                 return -1;
1241         }
1242
1243         if (_push_queue(caller_uid, caller_uid, reqkey,
1244                                 REQUEST_TYPE_GENERATE_LICENSE_REQUEST,
1245                                 "default", NULL, resp_data)) {
1246                 g_dbus_method_invocation_return_value(invocation,
1247                                 g_variant_new("(iss)", PKGMGR_R_ESYSTEM, "",
1248                                         ""));
1249                 free(reqkey);
1250                 return -1;
1251         }
1252
1253         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1254                                 (gpointer)invocation))
1255                 ERR("reqkey already exists");
1256
1257         return 0;
1258 }
1259
1260 static int __handle_request_register_license(uid_t caller_uid,
1261                 GDBusMethodInvocation *invocation, GVariant *parameters)
1262 {
1263         char *reqkey;
1264         char *resp_data = NULL;
1265
1266         g_variant_get(parameters, "(&s)", &resp_data);
1267         if (resp_data == NULL) {
1268                 g_dbus_method_invocation_return_value(invocation,
1269                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
1270                 return -1;
1271         }
1272
1273         reqkey = __generate_reqkey("drm");
1274         if (reqkey == NULL) {
1275                 g_dbus_method_invocation_return_value(invocation,
1276                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1277                 return -1;
1278         }
1279
1280         if (_push_queue(caller_uid, caller_uid, reqkey,
1281                                 REQUEST_TYPE_REGISTER_LICENSE,
1282                                 "default", NULL, resp_data)) {
1283                 g_dbus_method_invocation_return_value(invocation,
1284                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1285                 free(reqkey);
1286                 return -1;
1287         }
1288
1289         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1290                                 (gpointer)invocation))
1291                 ERR("reqkey already exists");
1292
1293         return 0;
1294 }
1295
1296 static int __handle_request_decrypt_package(uid_t caller_uid,
1297                 GDBusMethodInvocation *invocation, GVariant *parameters)
1298 {
1299         char *reqkey;
1300         char *drm_file_path = NULL;
1301         char *decrypted_file_path = NULL;
1302
1303         g_variant_get(parameters, "(&s&s)", &drm_file_path,
1304                         &decrypted_file_path);
1305         if (drm_file_path == NULL || decrypted_file_path == NULL) {
1306                 g_dbus_method_invocation_return_value(invocation,
1307                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
1308                 return -1;
1309         }
1310
1311         reqkey = __generate_reqkey("drm");
1312         if (reqkey == NULL) {
1313                 g_dbus_method_invocation_return_value(invocation,
1314                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1315                 return -1;
1316         }
1317
1318         if (_push_queue(caller_uid, caller_uid, reqkey,
1319                                 REQUEST_TYPE_DECRYPT_PACKAGE,
1320                                 "default", drm_file_path,
1321                                 decrypted_file_path)) {
1322                 g_dbus_method_invocation_return_value(invocation,
1323                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1324                 free(reqkey);
1325                 return -1;
1326         }
1327
1328         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1329                                 (gpointer)invocation))
1330                 ERR("reqkey already exists");
1331
1332         return 0;
1333 }
1334
1335 static int __update_app_splash_screen(uid_t caller_uid,
1336                 GDBusMethodInvocation *invocation, GVariant *parameters,
1337                 int req_type)
1338 {
1339         uid_t target_uid = (uid_t)-1;
1340         char *appid = NULL;
1341         char *reqkey;
1342
1343         g_variant_get(parameters, "(u&s)", &target_uid, &appid);
1344         if (target_uid == (uid_t)-1 || appid == NULL) {
1345                 ERR("target_uid: %d, appid: %s", target_uid, appid);
1346                 g_dbus_method_invocation_return_value(invocation,
1347                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
1348                 return -1;
1349         }
1350
1351         reqkey = __generate_reqkey(appid);
1352         if (reqkey == NULL) {
1353                 ERR("Failed to generate request key");
1354                 g_dbus_method_invocation_return_value(invocation,
1355                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1356                 return -1;
1357         }
1358
1359         if (_push_queue(target_uid, caller_uid, reqkey, req_type, "default",
1360                                 appid, NULL)) {
1361                 ERR("Failed to push request");
1362                 g_dbus_method_invocation_return_value(invocation,
1363                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1364                 free(reqkey);
1365                 return -1;
1366         }
1367
1368         g_dbus_method_invocation_return_value(invocation,
1369                         g_variant_new("(i)", PKGMGR_R_OK));
1370
1371         if (reqkey)
1372                 free(reqkey);
1373
1374         return 0;
1375 }
1376
1377 static int __handle_request_enable_app_splash_screen(uid_t caller_uid,
1378                 GDBusMethodInvocation *invocation, GVariant *parameters)
1379 {
1380         return __update_app_splash_screen(caller_uid, invocation, parameters,
1381                         REQUEST_TYPE_ENABLE_APP_SPLASH_SCREEN);
1382 }
1383
1384 static int __handle_request_disable_app_splash_screen(uid_t caller_uid,
1385                 GDBusMethodInvocation *invocation, GVariant *parameters)
1386 {
1387         return __update_app_splash_screen(caller_uid, invocation, parameters,
1388                         REQUEST_TYPE_DISABLE_APP_SPLASH_SCREEN);
1389 }
1390
1391 static int __handle_request_set_restriction_mode(uid_t caller_uid,
1392                 GDBusMethodInvocation *invocation, GVariant *parameters)
1393 {
1394         uid_t target_uid = (uid_t)-1;
1395         char *pkgid = NULL;
1396         char *reqkey;
1397         int mode = -1;
1398         char buf[4];
1399
1400         g_variant_get(parameters, "(usi)", &target_uid, &pkgid, &mode);
1401         if (target_uid == (uid_t)-1 || pkgid == NULL || mode < 0) {
1402                 g_dbus_method_invocation_return_value(invocation,
1403                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
1404                 return -1;
1405         }
1406
1407         reqkey = __generate_reqkey("restriction");
1408         if (reqkey == NULL) {
1409                 g_dbus_method_invocation_return_value(invocation,
1410                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1411                 return -1;
1412         }
1413
1414         snprintf(buf, sizeof(buf), "%d", mode);
1415         if (_push_queue(target_uid, caller_uid, reqkey,
1416                                 REQUEST_TYPE_SET_RESTRICTION_MODE,
1417                                 "default", pkgid, buf)) {
1418                 g_dbus_method_invocation_return_value(invocation,
1419                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1420                 free(reqkey);
1421                 return -1;
1422         }
1423
1424         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1425                                 (gpointer)invocation))
1426                 ERR("reqkey already exists");
1427
1428         return 0;
1429 }
1430
1431 static int __handle_request_unset_restriction_mode(uid_t caller_uid,
1432                 GDBusMethodInvocation *invocation, GVariant *parameters)
1433 {
1434         uid_t target_uid = (uid_t)-1;
1435         char *pkgid = NULL;
1436         char *reqkey;
1437         int mode = -1;
1438         char buf[4];
1439
1440         g_variant_get(parameters, "(usi)", &target_uid, &pkgid, &mode);
1441         if (target_uid == (uid_t)-1 || pkgid == NULL || mode < 0) {
1442                 g_dbus_method_invocation_return_value(invocation,
1443                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
1444                 return -1;
1445         }
1446
1447         reqkey = __generate_reqkey("restriction");
1448         if (reqkey == NULL) {
1449                 g_dbus_method_invocation_return_value(invocation,
1450                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1451                 return -1;
1452         }
1453
1454         snprintf(buf, sizeof(buf), "%d", mode);
1455         if (_push_queue(target_uid, caller_uid, reqkey,
1456                                 REQUEST_TYPE_UNSET_RESTRICTION_MODE,
1457                                 "default", pkgid, buf)) {
1458                 g_dbus_method_invocation_return_value(invocation,
1459                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1460                 free(reqkey);
1461                 return -1;
1462         }
1463
1464         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1465                                 (gpointer)invocation))
1466                 ERR("reqkey already exists");
1467
1468         return 0;
1469 }
1470
1471 static int __handle_request_get_restriction_mode(uid_t caller_uid,
1472                 GDBusMethodInvocation *invocation, GVariant *parameters)
1473 {
1474         uid_t target_uid = (uid_t)-1;
1475         char *pkgid = NULL;
1476         char *reqkey;
1477
1478         g_variant_get(parameters, "(us)", &target_uid, &pkgid);
1479         if (target_uid == (uid_t)-1 || pkgid == NULL) {
1480                 g_dbus_method_invocation_return_value(invocation,
1481                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
1482                 return -1;
1483         }
1484
1485         reqkey = __generate_reqkey("restriction");
1486         if (reqkey == NULL) {
1487                 g_dbus_method_invocation_return_value(invocation,
1488                                 g_variant_new("(ii)", -1, PKGMGR_R_ENOMEM));
1489                 return -1;
1490         }
1491
1492         if (_push_queue(target_uid, caller_uid, reqkey,
1493                                 REQUEST_TYPE_GET_RESTRICTION_MODE,
1494                                 "default", pkgid, NULL)) {
1495                 g_dbus_method_invocation_return_value(invocation,
1496                                 g_variant_new("(ii)", -1, PKGMGR_R_ESYSTEM));
1497                 free(reqkey);
1498                 return -1;
1499         }
1500
1501         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1502                                 (gpointer)invocation))
1503                 ERR("reqkey already exists");
1504
1505         return 0;
1506 }
1507
1508 static int __handle_request_set_app_label(uid_t uid,
1509                 GDBusMethodInvocation *invocation, GVariant *parameters)
1510 {
1511         uid_t target_uid = (uid_t)-1;
1512         char *appid = NULL;
1513         char *label = NULL;
1514         char *reqkey;
1515
1516         g_variant_get(parameters, "(uss)", &target_uid, &appid, &label);
1517         if (target_uid == (uid_t)-1 || appid == NULL || label == NULL) {
1518                 g_dbus_method_invocation_return_value(invocation,
1519                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
1520                 return -1;
1521         }
1522
1523         reqkey = __generate_reqkey("appid");
1524         if (reqkey == NULL) {
1525                 g_dbus_method_invocation_return_value(invocation,
1526                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1527                 return -1;
1528         }
1529
1530         if (_push_queue(target_uid, uid, reqkey,
1531                                 REQUEST_TYPE_SET_APP_LABEL,
1532                                 "default", appid, label)) {
1533                 g_dbus_method_invocation_return_value(invocation,
1534                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1535                 free(reqkey);
1536                 return -1;
1537         }
1538
1539         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1540                                 (gpointer)invocation))
1541                 ERR("reqkey already exists");
1542
1543         return 0;
1544 }
1545
1546 static int __handle_request_migrate_external_image(uid_t uid,
1547                 GDBusMethodInvocation *invocation, GVariant *parameters)
1548 {
1549         uid_t target_uid = (uid_t)-1;
1550         char *pkgid = NULL;
1551         char *pkgtype;
1552         char *reqkey;
1553
1554         g_variant_get(parameters, "(us)", &target_uid, &pkgid);
1555         if (target_uid == (uid_t)-1 || pkgid == NULL) {
1556                 g_dbus_method_invocation_return_value(invocation,
1557                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
1558                 return -1;
1559         }
1560
1561         pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
1562         if (pkgtype == NULL) {
1563                 g_dbus_method_invocation_return_value(invocation,
1564                                 g_variant_new("(i)", PKGMGR_R_ENOPKG));
1565                 return -1;
1566         }
1567
1568         reqkey = __generate_reqkey(pkgid);
1569         if (reqkey == NULL) {
1570                 g_dbus_method_invocation_return_value(invocation,
1571                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1572                 free(pkgtype);
1573                 return -1;
1574         }
1575
1576         if (_push_queue(target_uid, uid, reqkey,
1577                                 REQUEST_TYPE_MIGRATE_EXTERNAL_IMAGE,
1578                                 pkgtype, pkgid, NULL)) {
1579                 g_dbus_method_invocation_return_value(invocation,
1580                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1581                 free(reqkey);
1582                 free(pkgtype);
1583                 return -1;
1584         }
1585
1586         g_dbus_method_invocation_return_value(invocation,
1587                         g_variant_new("(i)", PKGMGR_R_OK));
1588
1589         free(reqkey);
1590         free(pkgtype);
1591
1592         return 0;
1593 }
1594
1595 static uid_t __get_caller_uid(GDBusConnection *connection, const char *name)
1596 {
1597         GError *err = NULL;
1598         GVariant *result;
1599         uid_t uid;
1600
1601         result = g_dbus_connection_call_sync(connection,
1602                         "org.freedesktop.DBus", "/org/freedesktop/DBus",
1603                         "org.freedesktop.DBus", "GetConnectionUnixUser",
1604                         g_variant_new("(s)", name), NULL,
1605                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
1606         if (result == NULL) {
1607                 ERR("failed to get caller uid: %s", err->message);
1608                 g_error_free(err);
1609                 return (uid_t)-1;
1610         }
1611
1612         g_variant_get(result, "(u)", &uid);
1613         g_variant_unref(result);
1614
1615         return uid;
1616 }
1617
1618 static void __handle_method_call(GDBusConnection *connection,
1619                 const gchar *sender, const gchar *object_path,
1620                 const gchar *interface_name, const gchar *method_name,
1621                 GVariant *parameters, GDBusMethodInvocation *invocation,
1622                 gpointer user_data)
1623 {
1624         int ret;
1625         uid_t uid;
1626
1627         uid = __get_caller_uid(connection,
1628                 g_dbus_method_invocation_get_sender(invocation));
1629         if (uid == (uid_t)-1)
1630                 return;
1631
1632         if (__check_caller_permission(uid, invocation, parameters))
1633                 return;
1634
1635         if (g_strcmp0(method_name, "install") == 0)
1636                 ret = __handle_request_install(uid, invocation, parameters);
1637         else if (g_strcmp0(method_name, "mount_install") == 0)
1638                 ret = __handle_request_mount_install(uid, invocation,
1639                                 parameters);
1640         else if (g_strcmp0(method_name, "reinstall") == 0)
1641                 ret = __handle_request_reinstall(uid, invocation, parameters);
1642         else if (g_strcmp0(method_name, "uninstall") == 0)
1643                 ret = __handle_request_uninstall(uid, invocation, parameters);
1644         else if (g_strcmp0(method_name, "cleardata") == 0)
1645                 ret = __handle_request_cleardata(uid, invocation, parameters);
1646         else if (g_strcmp0(method_name, "move") == 0)
1647                 ret = __handle_request_move(uid, invocation, parameters);
1648         else if (g_strcmp0(method_name, "enable_pkgs") == 0)
1649                 ret = __handle_request_enable_pkgs(uid, invocation, parameters);
1650         else if (g_strcmp0(method_name, "disable_pkgs") == 0)
1651                 ret = __handle_request_disable_pkgs(uid, invocation, parameters);
1652         else if (g_strcmp0(method_name, "getsize") == 0)
1653                 ret = __handle_request_getsize(uid, invocation, parameters);
1654         else if (g_strcmp0(method_name, "getsize_sync") == 0)
1655                 ret = __handle_request_getsize_sync(uid, invocation, parameters);
1656         else if (g_strcmp0(method_name, "clearcache") == 0)
1657                 ret = __handle_request_clearcache(uid, invocation, parameters);
1658         else if (g_strcmp0(method_name, "enable_app") == 0)
1659                 ret = __handle_request_enable_app(uid, invocation, parameters);
1660         else if (g_strcmp0(method_name, "disable_app") == 0)
1661                 ret = __handle_request_disable_app(uid, invocation, parameters);
1662         else if (g_strcmp0(method_name, "enable_apps") == 0)
1663                 ret = __handle_request_enable_apps(uid, invocation, parameters);
1664         else if (g_strcmp0(method_name, "disable_apps") == 0)
1665                 ret = __handle_request_disable_apps(uid, invocation, parameters);
1666         else if (g_strcmp0(method_name, "enable_global_app_for_uid") == 0)
1667                 ret = __handle_request_enable_global_app_for_uid(uid,
1668                                 invocation, parameters);
1669         else if (g_strcmp0(method_name, "disable_global_app_for_uid") == 0)
1670                 ret = __handle_request_disable_global_app_for_uid(uid,
1671                                 invocation, parameters);
1672         else if (g_strcmp0(method_name, "kill") == 0)
1673                 ret = __handle_request_kill(uid, invocation, parameters);
1674         else if (g_strcmp0(method_name, "check") == 0)
1675                 ret = __handle_request_check(uid, invocation, parameters);
1676         else if (g_strcmp0(method_name, "generate_license_request") == 0)
1677                 ret = __handle_request_generate_license_request(uid, invocation,
1678                                 parameters);
1679         else if (g_strcmp0(method_name, "register_license") == 0)
1680                 ret = __handle_request_register_license(uid, invocation,
1681                                 parameters);
1682         else if (g_strcmp0(method_name, "decrypt_package") == 0)
1683                 ret = __handle_request_decrypt_package(uid, invocation,
1684                                 parameters);
1685         else if (g_strcmp0(method_name, "disable_app_splash_screen") == 0)
1686                 ret = __handle_request_disable_app_splash_screen(uid,
1687                                 invocation, parameters);
1688         else if (g_strcmp0(method_name, "enable_app_splash_screen") == 0)
1689                 ret = __handle_request_enable_app_splash_screen(uid,
1690                                 invocation, parameters);
1691         else if (g_strcmp0(method_name, "set_restriction_mode") == 0)
1692                 ret = __handle_request_set_restriction_mode(uid, invocation,
1693                                 parameters);
1694         else if (g_strcmp0(method_name, "unset_restriction_mode") == 0)
1695                 ret = __handle_request_unset_restriction_mode(uid, invocation,
1696                                 parameters);
1697         else if (g_strcmp0(method_name, "get_restriction_mode") == 0)
1698                 ret = __handle_request_get_restriction_mode(uid, invocation,
1699                                 parameters);
1700         else if (g_strcmp0(method_name, "set_app_label") == 0)
1701                 ret = __handle_request_set_app_label(uid, invocation, parameters);
1702         else if (g_strcmp0(method_name, "migrate_external_image") == 0)
1703                 ret = __handle_request_migrate_external_image(uid, invocation,
1704                                 parameters);
1705         else
1706                 ret = -1;
1707
1708         if (ret == 0)
1709                 g_idle_add(queue_job, NULL);
1710 }
1711
1712 int _return_value_to_caller(const char *req_key, GVariant *result)
1713 {
1714         GDBusMethodInvocation *invocation;
1715
1716         invocation = (GDBusMethodInvocation *)g_hash_table_lookup(req_table,
1717                         (gpointer)req_key);
1718         if (invocation == NULL) {
1719                 ERR("no such request id");
1720                 return -1;
1721         }
1722
1723         g_dbus_method_invocation_return_value(invocation, result);
1724         g_hash_table_remove(req_table, (gpointer)req_key);
1725
1726         return 0;
1727 }
1728
1729 static const GDBusInterfaceVTable interface_vtable = {
1730         __handle_method_call,
1731         NULL,
1732         NULL,
1733 };
1734
1735 static void __on_bus_acquired(GDBusConnection *connection, const gchar *name,
1736                 gpointer user_data)
1737 {
1738         GError *err = NULL;
1739
1740         DBG("on bus acquired");
1741
1742         reg_id = g_dbus_connection_register_object(connection,
1743                         PKGMGR_DBUS_OBJECT_PATH,
1744                         instropection_data->interfaces[0],
1745                         &interface_vtable, NULL, NULL, &err);
1746
1747         if (reg_id == 0) {
1748                 ERR("failed to register object: %s", err->message);
1749                 g_error_free(err);
1750         }
1751 }
1752
1753 static void __on_name_acquired(GDBusConnection *connection, const gchar *name,
1754                 gpointer user_data)
1755 {
1756         DBG("on name acquired: %s", name);
1757 }
1758
1759 static void __on_name_lost(GDBusConnection *connection, const gchar *name,
1760                 gpointer user_data)
1761 {
1762         DBG("on name lost: %s", name);
1763 }
1764
1765 int _init_request_handler(void)
1766 {
1767         instropection_data = g_dbus_node_info_new_for_xml(instropection_xml,
1768                         NULL);
1769
1770         owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, PKGMGR_DBUS_SERVICE,
1771                         G_BUS_NAME_OWNER_FLAGS_NONE, __on_bus_acquired,
1772                         __on_name_acquired, __on_name_lost, NULL, NULL);
1773
1774         req_table = g_hash_table_new_full(g_str_hash, g_str_equal,
1775                         free, NULL);
1776         if (req_table == NULL)
1777                 return -1;
1778
1779         return 0;
1780 }
1781
1782 void _fini_request_handler(void)
1783 {
1784         g_hash_table_destroy(req_table);
1785         g_bus_unown_name(owner_id);
1786         g_dbus_node_info_unref(instropection_data);
1787 }