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