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