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