3269b246d9f4978fba42d4b4a2cc8375bd8f0d37
[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 caller_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, caller_uid, reqkey, REQUEST_TYPE_INSTALL,
331                                 pkgtype, 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 caller_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, caller_uid, reqkey,
416                                 REQUEST_TYPE_MOUNT_INSTALL,
417                                 pkgtype, pkgpath, args)) {
418                 g_dbus_method_invocation_return_value(invocation,
419                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
420                 ret = -1;
421                 goto catch;
422         }
423
424         g_dbus_method_invocation_return_value(invocation,
425                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
426         ret = 0;
427
428 catch:
429         if (reqkey)
430                 free(reqkey);
431
432         if (args)
433                 free(args);
434
435         if (tmp_args)
436                 g_free(tmp_args);
437
438         return ret;
439 }
440
441 static int __handle_request_reinstall(uid_t caller_uid,
442                 GDBusMethodInvocation *invocation, GVariant *parameters)
443 {
444         uid_t target_uid = (uid_t)-1;
445         char *pkgtype;
446         char *pkgid = NULL;
447         char *reqkey;
448
449         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
450         if (target_uid == (uid_t)-1 || pkgid == NULL) {
451                 g_dbus_method_invocation_return_value(invocation,
452                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
453                 return -1;
454         }
455
456         pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
457         if (pkgtype == NULL) {
458                 g_dbus_method_invocation_return_value(invocation,
459                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
460                 return -1;
461         }
462
463         reqkey = __generate_reqkey(pkgid);
464         if (reqkey == NULL) {
465                 g_dbus_method_invocation_return_value(invocation,
466                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
467                 free(pkgtype);
468                 return -1;
469         }
470         if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_REINSTALL,
471                                 pkgtype, pkgid, NULL)) {
472                 g_dbus_method_invocation_return_value(invocation,
473                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
474                 free(reqkey);
475                 free(pkgtype);
476                 return -1;
477         }
478
479         g_dbus_method_invocation_return_value(invocation,
480                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
481         free(reqkey);
482         free(pkgtype);
483
484         return 0;
485 }
486
487 static int __handle_request_uninstall(uid_t caller_uid,
488                 GDBusMethodInvocation *invocation, GVariant *parameters)
489 {
490         uid_t target_uid = (uid_t)-1;
491         char *pkgtype;
492         char *pkgid = NULL;
493         char *reqkey;
494
495         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
496         if (target_uid == (uid_t)-1 || pkgid == NULL) {
497                 g_dbus_method_invocation_return_value(invocation,
498                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
499                 return -1;
500         }
501
502         pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
503         if (pkgtype == NULL) {
504                 g_dbus_method_invocation_return_value(invocation,
505                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
506                 return -1;
507         }
508
509         reqkey = __generate_reqkey(pkgid);
510         if (reqkey == NULL) {
511                 g_dbus_method_invocation_return_value(invocation,
512                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
513                 free(pkgtype);
514                 return -1;
515         }
516         if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_UNINSTALL,
517                                 pkgtype, pkgid, NULL)) {
518                 g_dbus_method_invocation_return_value(invocation,
519                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
520                 free(reqkey);
521                 free(pkgtype);
522                 return -1;
523         }
524
525         g_dbus_method_invocation_return_value(invocation,
526                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
527         free(reqkey);
528         free(pkgtype);
529
530         return 0;
531 }
532
533 static int __handle_request_move(uid_t caller_uid,
534                 GDBusMethodInvocation *invocation, GVariant *parameters)
535 {
536         uid_t target_uid = (uid_t)-1;
537         char *pkgtype;
538         char *pkgid = NULL;
539         char *reqkey;
540         int move_type = -1;
541         char buf[4] = { '\0' };
542
543         g_variant_get(parameters, "(u&si)", &target_uid, &pkgid, &move_type);
544         if (target_uid == (uid_t)-1 || pkgid == NULL) {
545                 g_dbus_method_invocation_return_value(invocation,
546                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
547                 return -1;
548         }
549
550         pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
551         if (pkgtype == NULL) {
552                 g_dbus_method_invocation_return_value(invocation,
553                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
554                 return -1;
555         }
556
557         reqkey = __generate_reqkey(pkgid);
558         if (reqkey == NULL) {
559                 g_dbus_method_invocation_return_value(invocation,
560                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
561                 free(pkgtype);
562                 return -1;
563         }
564
565         snprintf(buf, sizeof(buf), "%d", move_type);
566         if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_MOVE,
567                                 pkgtype, pkgid, buf)) {
568                 g_dbus_method_invocation_return_value(invocation,
569                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
570                 free(reqkey);
571                 free(pkgtype);
572                 return -1;
573         }
574
575         g_dbus_method_invocation_return_value(invocation,
576                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
577         free(reqkey);
578         free(pkgtype);
579
580         return 0;
581 }
582
583 static int __handle_request_enable_pkgs(uid_t caller_uid,
584                 GDBusMethodInvocation *invocation, GVariant *parameters)
585 {
586         uid_t target_uid = (uid_t)-1;
587         char *pkgtype;
588         char *pkgid;
589         char *reqkey;
590         GVariantIter *iter;
591
592         g_variant_get(parameters, "(uas)", &target_uid, &iter);
593         if (target_uid == (uid_t)-1 || iter == NULL) {
594                 g_dbus_method_invocation_return_value(invocation,
595                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
596                 return -1;
597         }
598
599         reqkey = __generate_reqkey("enable_pkgs");
600         if (reqkey == NULL) {
601                 g_dbus_method_invocation_return_value(invocation,
602                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
603                 return -1;
604         }
605
606         while (g_variant_iter_next(iter, "&s", &pkgid)) {
607                 pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
608                 if (pkgtype == NULL) {
609                         g_dbus_method_invocation_return_value(invocation,
610                                         g_variant_new("(is)",
611                                                 PKGMGR_R_ESYSTEM, ""));
612                         free(reqkey);
613                         return -1;
614                 }
615                 if (_push_queue(target_uid, caller_uid, reqkey,
616                                         REQUEST_TYPE_ENABLE_PKG,
617                                         pkgtype, pkgid, NULL)) {
618                         g_dbus_method_invocation_return_value(invocation,
619                                         g_variant_new("(is)",
620                                                 PKGMGR_R_ESYSTEM, ""));
621                         free(pkgtype);
622                         free(reqkey);
623                         return -1;
624                 }
625                 free(pkgtype);
626         }
627
628         g_dbus_method_invocation_return_value(invocation,
629                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
630         free(reqkey);
631
632         return 0;
633 }
634
635 static int __handle_request_disable_pkgs(uid_t caller_uid,
636                 GDBusMethodInvocation *invocation, GVariant *parameters)
637 {
638         uid_t target_uid = (uid_t)-1;
639         char *pkgtype;
640         char *pkgid;
641         char *reqkey;
642         GVariantIter *iter;
643
644         g_variant_get(parameters, "(uas)", &target_uid, &iter);
645         if (target_uid == (uid_t)-1 || iter == NULL) {
646                 g_dbus_method_invocation_return_value(invocation,
647                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
648                 return -1;
649         }
650
651         reqkey = __generate_reqkey("disable_pkgs");
652         if (reqkey == NULL) {
653                 g_dbus_method_invocation_return_value(invocation,
654                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
655                 return -1;
656         }
657
658         while (g_variant_iter_next(iter, "&s", &pkgid)) {
659                 pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
660                 if (pkgtype == NULL) {
661                         g_dbus_method_invocation_return_value(invocation,
662                                         g_variant_new("(is)",
663                                                 PKGMGR_R_ESYSTEM, ""));
664                         free(reqkey);
665                         return -1;
666                 }
667                 if (_push_queue(target_uid, caller_uid, reqkey,
668                                         REQUEST_TYPE_DISABLE_PKG,
669                                         pkgtype, pkgid, NULL)) {
670                         g_dbus_method_invocation_return_value(invocation,
671                                         g_variant_new("(is)",
672                                                 PKGMGR_R_ESYSTEM, ""));
673                         free(pkgtype);
674                         free(reqkey);
675                         return -1;
676                 }
677                 free(pkgtype);
678         }
679
680         g_dbus_method_invocation_return_value(invocation,
681                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
682         free(reqkey);
683
684         return 0;
685 }
686
687 static int __handle_request_enable_app(uid_t caller_uid,
688                 GDBusMethodInvocation *invocation, GVariant *parameters)
689 {
690         uid_t target_uid = (uid_t)-1;
691         char *appid = NULL;
692         char *reqkey = NULL;
693         int ret = -1;
694
695         g_variant_get(parameters, "(u&s)", &target_uid, &appid);
696         if (target_uid == (uid_t)-1 || appid == NULL) {
697                 g_dbus_method_invocation_return_value(invocation,
698                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
699                 return -1;
700         }
701
702         reqkey = __generate_reqkey(appid);
703         if (reqkey == NULL) {
704                 g_dbus_method_invocation_return_value(invocation,
705                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
706                 ret = -1;
707                 goto catch;
708         }
709
710         if (_push_queue(target_uid, caller_uid, reqkey,
711                                 REQUEST_TYPE_ENABLE_APP, "default",
712                                 appid, NULL)) {
713                 g_dbus_method_invocation_return_value(invocation,
714                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
715                 ret = -1;
716                 goto catch;
717         }
718
719         g_dbus_method_invocation_return_value(invocation,
720                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
721
722         ret = 0;
723
724 catch:
725         if (reqkey)
726                 free(reqkey);
727
728         return ret;
729 }
730
731 static int __handle_request_disable_app(uid_t caller_uid,
732                 GDBusMethodInvocation *invocation, GVariant *parameters)
733 {
734         uid_t target_uid = (uid_t)-1;
735         char *appid = NULL;
736         char *reqkey = NULL;
737         int ret = -1;
738
739         g_variant_get(parameters, "(u&s)", &target_uid, &appid);
740         if (target_uid == (uid_t)-1 || appid == NULL) {
741                 g_dbus_method_invocation_return_value(invocation,
742                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
743                 return -1;
744         }
745
746         reqkey = __generate_reqkey(appid);
747         if (reqkey == NULL) {
748                 g_dbus_method_invocation_return_value(invocation,
749                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
750                 ret = -1;
751                 goto catch;
752         }
753
754         if (_push_queue(target_uid, caller_uid, reqkey,
755                                 REQUEST_TYPE_DISABLE_APP, "default",
756                                 appid, NULL)) {
757                 g_dbus_method_invocation_return_value(invocation,
758                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
759                 ret = -1;
760                 goto catch;
761         }
762
763         g_dbus_method_invocation_return_value(invocation,
764                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
765
766         ret = 0;
767
768 catch:
769         if (reqkey)
770                 free(reqkey);
771
772         return ret;
773 }
774
775 static int __handle_request_enable_global_app_for_uid(uid_t caller_uid,
776                 GDBusMethodInvocation *invocation, GVariant *parameters)
777 {
778         uid_t target_uid = (uid_t)-1;
779         char *appid = NULL;
780         char *reqkey = NULL;
781         int ret = -1;
782
783         g_variant_get(parameters, "(u&s)", &target_uid, &appid);
784         if (target_uid == (uid_t)-1 || appid == NULL) {
785                 g_dbus_method_invocation_return_value(invocation,
786                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
787                 return -1;
788         }
789
790         reqkey = __generate_reqkey(appid);
791         if (reqkey == NULL) {
792                 g_dbus_method_invocation_return_value(invocation,
793                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
794                 ret = -1;
795                 goto catch;
796         }
797
798         if (_push_queue(target_uid, caller_uid, reqkey,
799                                 REQUEST_TYPE_ENABLE_GLOBAL_APP_FOR_UID,
800                                 "default", appid, NULL)) {
801                 g_dbus_method_invocation_return_value(invocation,
802                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
803                 ret = -1;
804                 goto catch;
805         }
806
807         g_dbus_method_invocation_return_value(invocation,
808                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
809
810         ret = 0;
811
812 catch:
813         if (reqkey)
814                 free(reqkey);
815
816         return ret;
817 }
818
819 static int __handle_request_disable_global_app_for_uid(uid_t caller_uid,
820                 GDBusMethodInvocation *invocation, GVariant *parameters)
821 {
822         uid_t target_uid = (uid_t)-1;
823         char *appid = NULL;
824         char *reqkey = NULL;
825         int ret = -1;
826
827         g_variant_get(parameters, "(u&s)", &target_uid, &appid);
828         if (target_uid == (uid_t)-1 || appid == NULL) {
829                 g_dbus_method_invocation_return_value(invocation,
830                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
831                 return -1;
832         }
833
834         reqkey = __generate_reqkey(appid);
835         if (reqkey == NULL) {
836                 g_dbus_method_invocation_return_value(invocation,
837                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
838                 ret = -1;
839                 goto catch;
840         }
841
842         if (_push_queue(target_uid, caller_uid, reqkey,
843                                 REQUEST_TYPE_DISABLE_GLOBAL_APP_FOR_UID,
844                                 "default", appid, NULL)) {
845                 g_dbus_method_invocation_return_value(invocation,
846                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
847                 ret = -1;
848                 goto catch;
849         }
850
851         g_dbus_method_invocation_return_value(invocation,
852                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
853
854         ret = 0;
855
856 catch:
857         if (reqkey)
858                 free(reqkey);
859
860         return ret;
861 }
862
863 static int __handle_request_getsize(uid_t caller_uid,
864                 GDBusMethodInvocation *invocation, GVariant *parameters)
865 {
866         uid_t target_uid = (uid_t)-1;
867         char *pkgid = NULL;
868         int get_type = -1;
869         char *reqkey;
870         char buf[4];
871
872         g_variant_get(parameters, "(u&si)", &target_uid, &pkgid, &get_type);
873         if (target_uid == (uid_t)-1 || pkgid == NULL || get_type == -1) {
874                 g_dbus_method_invocation_return_value(invocation,
875                                 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
876                 return -1;
877         }
878
879         reqkey = __generate_reqkey(pkgid);
880         if (reqkey == NULL) {
881                 g_dbus_method_invocation_return_value(invocation,
882                                 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
883                 return -1;
884         }
885
886         snprintf(buf, sizeof(buf), "%d", get_type);
887         if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_GETSIZE,
888                                 "pkgtool", pkgid, buf)) {
889                 g_dbus_method_invocation_return_value(invocation,
890                                 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
891                 free(reqkey);
892                 return -1;
893         }
894
895         g_dbus_method_invocation_return_value(invocation,
896                         g_variant_new("(is)", PKGMGR_R_OK, reqkey));
897         free(reqkey);
898
899         return 0;
900 }
901
902 static int __handle_request_cleardata(uid_t caller_uid,
903                 GDBusMethodInvocation *invocation, GVariant *parameters)
904 {
905         uid_t target_uid = (uid_t)-1;
906         char *pkgtype;
907         char *pkgid = NULL;
908         char *reqkey = NULL;
909
910         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
911         if (target_uid == (uid_t)-1 || pkgid == NULL) {
912                 g_dbus_method_invocation_return_value(invocation,
913                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
914                 return -1;
915         }
916
917         pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
918         if (pkgtype == NULL) {
919                 g_dbus_method_invocation_return_value(invocation,
920                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
921                 return -1;
922         }
923
924         reqkey = __generate_reqkey(pkgid);
925         if (reqkey == NULL) {
926                 g_dbus_method_invocation_return_value(invocation,
927                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
928                 free(pkgtype);
929                 return -1;
930         }
931
932         if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_CLEARDATA,
933                                 pkgtype, pkgid, NULL)) {
934                 g_dbus_method_invocation_return_value(invocation,
935                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
936                 free(reqkey);
937                 free(pkgtype);
938                 return -1;
939         }
940
941         g_dbus_method_invocation_return_value(invocation,
942                         g_variant_new("(i)", PKGMGR_R_OK));
943
944         free(reqkey);
945         free(pkgtype);
946
947         return 0;
948 }
949
950 static int __handle_request_clearcache(uid_t caller_uid,
951                 GDBusMethodInvocation *invocation, GVariant *parameters)
952 {
953         uid_t target_uid = (uid_t)-1;
954         char *pkgid = NULL;
955
956         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
957         if (target_uid == (uid_t)-1 || pkgid == NULL) {
958                 g_dbus_method_invocation_return_value(invocation,
959                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
960                 return -1;
961         }
962
963         if (_push_queue(target_uid, caller_uid, NULL, REQUEST_TYPE_CLEARCACHE,
964                                 "pkgtool",  pkgid, NULL)) {
965                 g_dbus_method_invocation_return_value(invocation,
966                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
967                 return -1;
968         }
969
970         g_dbus_method_invocation_return_value(invocation,
971                         g_variant_new("(i)", PKGMGR_R_OK));
972
973         return 0;
974 }
975
976 static int __handle_request_kill(uid_t caller_uid,
977                 GDBusMethodInvocation *invocation, GVariant *parameters)
978 {
979         uid_t target_uid = (uid_t)-1;
980         char *pkgid = NULL;
981         char *reqkey = NULL;
982
983         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
984         if (target_uid == (uid_t)-1 || pkgid == NULL) {
985                 g_dbus_method_invocation_return_value(invocation,
986                                 g_variant_new("(ii)", PKGMGR_R_ECOMM, 0));
987                 return -1;
988         }
989
990         reqkey = __generate_reqkey(pkgid);
991         if (reqkey == NULL) {
992                 g_dbus_method_invocation_return_value(invocation,
993                                 g_variant_new("(ii)", PKGMGR_R_ENOMEM, 0));
994                 return -1;
995         }
996
997         if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_KILL,
998                                 "default", pkgid, NULL)) {
999                 g_dbus_method_invocation_return_value(invocation,
1000                                 g_variant_new("(ii)", PKGMGR_R_ESYSTEM, 0));
1001                 free(reqkey);
1002                 return -1;
1003         }
1004
1005         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1006                                 (gpointer)invocation))
1007                 ERR("reqkey already exists");
1008
1009         return 0;
1010 }
1011
1012 static int __handle_request_check(uid_t caller_uid,
1013                 GDBusMethodInvocation *invocation, GVariant *parameters)
1014 {
1015         uid_t target_uid = (uid_t)-1;
1016         char *pkgid = NULL;
1017         char *reqkey = NULL;
1018
1019         g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
1020         if (target_uid == (uid_t)-1 || pkgid == NULL) {
1021                 g_dbus_method_invocation_return_value(invocation,
1022                                 g_variant_new("(ii)", PKGMGR_R_ECOMM, 0));
1023                 return -1;
1024         }
1025
1026         reqkey = __generate_reqkey(pkgid);
1027         if (reqkey == NULL) {
1028                 g_dbus_method_invocation_return_value(invocation,
1029                                 g_variant_new("(ii)", PKGMGR_R_ENOMEM, 0));
1030                 return -1;
1031         }
1032
1033         if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_CHECK,
1034                                 "default", pkgid, NULL)) {
1035                 g_dbus_method_invocation_return_value(invocation,
1036                                 g_variant_new("(ii)", PKGMGR_R_ESYSTEM, 0));
1037                 free(reqkey);
1038                 return -1;
1039         }
1040
1041         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1042                                 (gpointer)invocation))
1043                 ERR("reqkey already exists");
1044
1045         return 0;
1046 }
1047
1048 static int __handle_request_generate_license_request(uid_t caller_uid,
1049                 GDBusMethodInvocation *invocation, GVariant *parameters)
1050 {
1051         char *reqkey;
1052         char *resp_data = NULL;
1053
1054         g_variant_get(parameters, "(&s)", &resp_data);
1055         if (resp_data == NULL) {
1056                 g_dbus_method_invocation_return_value(invocation,
1057                                 g_variant_new("(iss)", PKGMGR_R_ECOMM, "", ""));
1058                 return -1;
1059         }
1060
1061         reqkey = __generate_reqkey("drm");
1062         if (reqkey == NULL) {
1063                 g_dbus_method_invocation_return_value(invocation,
1064                                 g_variant_new("(iss)", PKGMGR_R_ENOMEM, "",
1065                                         ""));
1066                 return -1;
1067         }
1068
1069         if (_push_queue(caller_uid, caller_uid, reqkey,
1070                                 REQUEST_TYPE_GENERATE_LICENSE_REQUEST,
1071                                 "default", NULL, resp_data)) {
1072                 g_dbus_method_invocation_return_value(invocation,
1073                                 g_variant_new("(iss)", PKGMGR_R_ESYSTEM, "",
1074                                         ""));
1075                 free(reqkey);
1076                 return -1;
1077         }
1078
1079         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1080                                 (gpointer)invocation))
1081                 ERR("reqkey already exists");
1082
1083         return 0;
1084 }
1085
1086 static int __handle_request_register_license(uid_t caller_uid,
1087                 GDBusMethodInvocation *invocation, GVariant *parameters)
1088 {
1089         char *reqkey;
1090         char *resp_data = NULL;
1091
1092         g_variant_get(parameters, "(&s)", &resp_data);
1093         if (resp_data == NULL) {
1094                 g_dbus_method_invocation_return_value(invocation,
1095                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
1096                 return -1;
1097         }
1098
1099         reqkey = __generate_reqkey("drm");
1100         if (reqkey == NULL) {
1101                 g_dbus_method_invocation_return_value(invocation,
1102                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1103                 return -1;
1104         }
1105
1106         if (_push_queue(caller_uid, caller_uid, reqkey,
1107                                 REQUEST_TYPE_REGISTER_LICENSE,
1108                                 "default", NULL, resp_data)) {
1109                 g_dbus_method_invocation_return_value(invocation,
1110                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1111                 free(reqkey);
1112                 return -1;
1113         }
1114
1115         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1116                                 (gpointer)invocation))
1117                 ERR("reqkey already exists");
1118
1119         return 0;
1120 }
1121
1122 static int __handle_request_decrypt_package(uid_t caller_uid,
1123                 GDBusMethodInvocation *invocation, GVariant *parameters)
1124 {
1125         char *reqkey;
1126         char *drm_file_path = NULL;
1127         char *decrypted_file_path = NULL;
1128
1129         g_variant_get(parameters, "(&s&s)", &drm_file_path,
1130                         &decrypted_file_path);
1131         if (drm_file_path == NULL || decrypted_file_path == NULL) {
1132                 g_dbus_method_invocation_return_value(invocation,
1133                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
1134                 return -1;
1135         }
1136
1137         reqkey = __generate_reqkey("drm");
1138         if (reqkey == NULL) {
1139                 g_dbus_method_invocation_return_value(invocation,
1140                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1141                 return -1;
1142         }
1143
1144         if (_push_queue(caller_uid, caller_uid, reqkey,
1145                                 REQUEST_TYPE_DECRYPT_PACKAGE,
1146                                 "default", drm_file_path,
1147                                 decrypted_file_path)) {
1148                 g_dbus_method_invocation_return_value(invocation,
1149                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1150                 free(reqkey);
1151                 return -1;
1152         }
1153
1154         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1155                                 (gpointer)invocation))
1156                 ERR("reqkey already exists");
1157
1158         return 0;
1159 }
1160
1161 static int __update_app_splash_screen(uid_t caller_uid,
1162                 GDBusMethodInvocation *invocation, GVariant *parameters,
1163                 int req_type)
1164 {
1165         uid_t target_uid = (uid_t)-1;
1166         char *appid = NULL;
1167         char *reqkey;
1168
1169         g_variant_get(parameters, "(u&s)", &target_uid, &appid);
1170         if (target_uid == (uid_t)-1 || appid == NULL) {
1171                 ERR("target_uid: %d, appid: %s", target_uid, appid);
1172                 g_dbus_method_invocation_return_value(invocation,
1173                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
1174                 return -1;
1175         }
1176
1177         reqkey = __generate_reqkey(appid);
1178         if (reqkey == NULL) {
1179                 ERR("Failed to generate request key");
1180                 g_dbus_method_invocation_return_value(invocation,
1181                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1182                 return -1;
1183         }
1184
1185         if (_push_queue(target_uid, caller_uid, reqkey, req_type, "default",
1186                                 appid, NULL)) {
1187                 ERR("Failed to push request");
1188                 g_dbus_method_invocation_return_value(invocation,
1189                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1190                 free(reqkey);
1191                 return -1;
1192         }
1193
1194         g_dbus_method_invocation_return_value(invocation,
1195                         g_variant_new("(i)", PKGMGR_R_OK));
1196
1197         if (reqkey)
1198                 free(reqkey);
1199
1200         return 0;
1201 }
1202
1203 static int __handle_request_enable_app_splash_screen(uid_t caller_uid,
1204                 GDBusMethodInvocation *invocation, GVariant *parameters)
1205 {
1206         return __update_app_splash_screen(caller_uid, invocation, parameters,
1207                         REQUEST_TYPE_ENABLE_APP_SPLASH_SCREEN);
1208 }
1209
1210 static int __handle_request_disable_app_splash_screen(uid_t caller_uid,
1211                 GDBusMethodInvocation *invocation, GVariant *parameters)
1212 {
1213         return __update_app_splash_screen(caller_uid, invocation, parameters,
1214                         REQUEST_TYPE_DISABLE_APP_SPLASH_SCREEN);
1215 }
1216
1217 static int __handle_request_set_restriction_mode(uid_t caller_uid,
1218                 GDBusMethodInvocation *invocation, GVariant *parameters)
1219 {
1220         uid_t target_uid = (uid_t)-1;
1221         char *pkgid = NULL;
1222         char *reqkey;
1223         int mode = -1;
1224         char buf[4];
1225
1226         g_variant_get(parameters, "(usi)", &target_uid, &pkgid, &mode);
1227         if (target_uid == (uid_t)-1 || pkgid == NULL || mode < 0) {
1228                 g_dbus_method_invocation_return_value(invocation,
1229                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
1230                 return -1;
1231         }
1232
1233         reqkey = __generate_reqkey("restriction");
1234         if (reqkey == NULL) {
1235                 g_dbus_method_invocation_return_value(invocation,
1236                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1237                 return -1;
1238         }
1239
1240         snprintf(buf, sizeof(buf), "%d", mode);
1241         if (_push_queue(target_uid, caller_uid, reqkey,
1242                                 REQUEST_TYPE_SET_RESTRICTION_MODE,
1243                                 "default", pkgid, buf)) {
1244                 g_dbus_method_invocation_return_value(invocation,
1245                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1246                 free(reqkey);
1247                 return -1;
1248         }
1249
1250         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1251                                 (gpointer)invocation))
1252                 ERR("reqkey already exists");
1253
1254         return 0;
1255 }
1256
1257 static int __handle_request_unset_restriction_mode(uid_t caller_uid,
1258                 GDBusMethodInvocation *invocation, GVariant *parameters)
1259 {
1260         uid_t target_uid = (uid_t)-1;
1261         char *pkgid = NULL;
1262         char *reqkey;
1263         int mode = -1;
1264         char buf[4];
1265
1266         g_variant_get(parameters, "(usi)", &target_uid, &pkgid, &mode);
1267         if (target_uid == (uid_t)-1 || pkgid == NULL || mode < 0) {
1268                 g_dbus_method_invocation_return_value(invocation,
1269                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
1270                 return -1;
1271         }
1272
1273         reqkey = __generate_reqkey("restriction");
1274         if (reqkey == NULL) {
1275                 g_dbus_method_invocation_return_value(invocation,
1276                                 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1277                 return -1;
1278         }
1279
1280         snprintf(buf, sizeof(buf), "%d", mode);
1281         if (_push_queue(target_uid, caller_uid, reqkey,
1282                                 REQUEST_TYPE_UNSET_RESTRICTION_MODE,
1283                                 "default", pkgid, buf)) {
1284                 g_dbus_method_invocation_return_value(invocation,
1285                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1286                 free(reqkey);
1287                 return -1;
1288         }
1289
1290         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1291                                 (gpointer)invocation))
1292                 ERR("reqkey already exists");
1293
1294         return 0;
1295 }
1296
1297 static int __handle_request_get_restriction_mode(uid_t caller_uid,
1298                 GDBusMethodInvocation *invocation, GVariant *parameters)
1299 {
1300         uid_t target_uid = (uid_t)-1;
1301         char *pkgid = NULL;
1302         char *reqkey;
1303
1304         g_variant_get(parameters, "(us)", &target_uid, &pkgid);
1305         if (target_uid == (uid_t)-1 || pkgid == NULL) {
1306                 g_dbus_method_invocation_return_value(invocation,
1307                                 g_variant_new("(i)", PKGMGR_R_ECOMM));
1308                 return -1;
1309         }
1310
1311         reqkey = __generate_reqkey("restriction");
1312         if (reqkey == NULL) {
1313                 g_dbus_method_invocation_return_value(invocation,
1314                                 g_variant_new("(ii)", -1, PKGMGR_R_ENOMEM));
1315                 return -1;
1316         }
1317
1318         if (_push_queue(target_uid, caller_uid, reqkey,
1319                                 REQUEST_TYPE_GET_RESTRICTION_MODE,
1320                                 "default", pkgid, NULL)) {
1321                 g_dbus_method_invocation_return_value(invocation,
1322                                 g_variant_new("(ii)", -1, PKGMGR_R_ESYSTEM));
1323                 free(reqkey);
1324                 return -1;
1325         }
1326
1327         if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1328                                 (gpointer)invocation))
1329                 ERR("reqkey already exists");
1330
1331         return 0;
1332 }
1333
1334 static uid_t __get_caller_uid(GDBusConnection *connection, const char *name)
1335 {
1336         GError *err = NULL;
1337         GVariant *result;
1338         uid_t uid;
1339
1340         result = g_dbus_connection_call_sync(connection,
1341                         "org.freedesktop.DBus", "/org/freedesktop/DBus",
1342                         "org.freedesktop.DBus", "GetConnectionUnixUser",
1343                         g_variant_new("(s)", name), NULL,
1344                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
1345         if (result == NULL) {
1346                 ERR("failed to get caller uid: %s", err->message);
1347                 g_error_free(err);
1348                 return (uid_t)-1;
1349         }
1350
1351         g_variant_get(result, "(u)", &uid);
1352
1353         return uid;
1354 }
1355
1356 static void __handle_method_call(GDBusConnection *connection,
1357                 const gchar *sender, const gchar *object_path,
1358                 const gchar *interface_name, const gchar *method_name,
1359                 GVariant *parameters, GDBusMethodInvocation *invocation,
1360                 gpointer user_data)
1361 {
1362         int ret;
1363         uid_t uid;
1364
1365         uid = __get_caller_uid(connection,
1366                 g_dbus_method_invocation_get_sender(invocation));
1367         if (uid == (uid_t)-1)
1368                 return;
1369
1370         if (__check_caller_permission(uid, invocation, parameters))
1371                 return;
1372
1373         if (g_strcmp0(method_name, "install") == 0)
1374                 ret = __handle_request_install(uid, invocation, parameters);
1375         else if (g_strcmp0(method_name, "mount_install") == 0)
1376                 ret = __handle_request_mount_install(uid, invocation,
1377                                 parameters);
1378         else if (g_strcmp0(method_name, "reinstall") == 0)
1379                 ret = __handle_request_reinstall(uid, invocation, parameters);
1380         else if (g_strcmp0(method_name, "uninstall") == 0)
1381                 ret = __handle_request_uninstall(uid, invocation, parameters);
1382         else if (g_strcmp0(method_name, "cleardata") == 0)
1383                 ret = __handle_request_cleardata(uid, invocation, parameters);
1384         else if (g_strcmp0(method_name, "move") == 0)
1385                 ret = __handle_request_move(uid, invocation, parameters);
1386         else if (g_strcmp0(method_name, "enable_pkgs") == 0)
1387                 ret = __handle_request_enable_pkgs(uid, invocation, parameters);
1388         else if (g_strcmp0(method_name, "disable_pkgs") == 0)
1389                 ret = __handle_request_disable_pkgs(uid, invocation, parameters);
1390         else if (g_strcmp0(method_name, "getsize") == 0)
1391                 ret = __handle_request_getsize(uid, invocation, parameters);
1392         else if (g_strcmp0(method_name, "clearcache") == 0)
1393                 ret = __handle_request_clearcache(uid, invocation, parameters);
1394         else if (g_strcmp0(method_name, "enable_app") == 0)
1395                 ret = __handle_request_enable_app(uid, invocation, parameters);
1396         else if (g_strcmp0(method_name, "disable_app") == 0)
1397                 ret = __handle_request_disable_app(uid, invocation, parameters);
1398         else if (g_strcmp0(method_name, "enable_global_app_for_uid") == 0)
1399                 ret = __handle_request_enable_global_app_for_uid(uid,
1400                                 invocation, parameters);
1401         else if (g_strcmp0(method_name, "disable_global_app_for_uid") == 0)
1402                 ret = __handle_request_disable_global_app_for_uid(uid,
1403                                 invocation, parameters);
1404         else if (g_strcmp0(method_name, "kill") == 0)
1405                 ret = __handle_request_kill(uid, invocation, parameters);
1406         else if (g_strcmp0(method_name, "check") == 0)
1407                 ret = __handle_request_check(uid, invocation, parameters);
1408         else if (g_strcmp0(method_name, "generate_license_request") == 0)
1409                 ret = __handle_request_generate_license_request(uid, invocation,
1410                                 parameters);
1411         else if (g_strcmp0(method_name, "register_license") == 0)
1412                 ret = __handle_request_register_license(uid, invocation,
1413                                 parameters);
1414         else if (g_strcmp0(method_name, "decrypt_package") == 0)
1415                 ret = __handle_request_decrypt_package(uid, invocation,
1416                                 parameters);
1417         else if (g_strcmp0(method_name, "disable_app_splash_screen") == 0)
1418                 ret = __handle_request_disable_app_splash_screen(uid,
1419                                 invocation, parameters);
1420         else if (g_strcmp0(method_name, "enable_app_splash_screen") == 0)
1421                 ret = __handle_request_enable_app_splash_screen(uid,
1422                                 invocation, parameters);
1423         else if (g_strcmp0(method_name, "set_restriction_mode") == 0)
1424                 ret = __handle_request_set_restriction_mode(uid, invocation,
1425                                 parameters);
1426         else if (g_strcmp0(method_name, "unset_restriction_mode") == 0)
1427                 ret = __handle_request_unset_restriction_mode(uid, invocation,
1428                                 parameters);
1429         else if (g_strcmp0(method_name, "get_restriction_mode") == 0)
1430                 ret = __handle_request_get_restriction_mode(uid, invocation,
1431                                 parameters);
1432         else
1433                 ret = -1;
1434
1435         if (ret == 0)
1436                 g_idle_add(queue_job, NULL);
1437 }
1438
1439 int _return_value_to_caller(const char *req_key, GVariant *result)
1440 {
1441         GDBusMethodInvocation *invocation;
1442
1443         invocation = (GDBusMethodInvocation *)g_hash_table_lookup(req_table,
1444                         (gpointer)req_key);
1445         if (invocation == NULL) {
1446                 ERR("no such request id");
1447                 return -1;
1448         }
1449
1450         g_dbus_method_invocation_return_value(invocation, result);
1451         g_hash_table_remove(req_table, (gpointer)req_key);
1452
1453         return 0;
1454 }
1455
1456 static const GDBusInterfaceVTable interface_vtable = {
1457         __handle_method_call,
1458         NULL,
1459         NULL,
1460 };
1461
1462 static void __on_bus_acquired(GDBusConnection *connection, const gchar *name,
1463                 gpointer user_data)
1464 {
1465         GError *err = NULL;
1466
1467         DBG("on bus acquired");
1468
1469         reg_id = g_dbus_connection_register_object(connection,
1470                         PKGMGR_DBUS_OBJECT_PATH,
1471                         instropection_data->interfaces[0],
1472                         &interface_vtable, NULL, NULL, &err);
1473
1474         if (reg_id == 0) {
1475                 ERR("failed to register object: %s", err->message);
1476                 g_error_free(err);
1477         }
1478 }
1479
1480 static void __on_name_acquired(GDBusConnection *connection, const gchar *name,
1481                 gpointer user_data)
1482 {
1483         DBG("on name acquired: %s", name);
1484 }
1485
1486 static void __on_name_lost(GDBusConnection *connection, const gchar *name,
1487                 gpointer user_data)
1488 {
1489         DBG("on name lost: %s", name);
1490 }
1491
1492 int _init_request_handler(void)
1493 {
1494         instropection_data = g_dbus_node_info_new_for_xml(instropection_xml,
1495                         NULL);
1496
1497         owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, PKGMGR_DBUS_SERVICE,
1498                         G_BUS_NAME_OWNER_FLAGS_NONE, __on_bus_acquired,
1499                         __on_name_acquired, __on_name_lost, NULL, NULL);
1500
1501         req_table = g_hash_table_new_full(g_str_hash, g_str_equal,
1502                         free, NULL);
1503         if (req_table == NULL)
1504                 return -1;
1505
1506         return 0;
1507 }
1508
1509 void _fini_request_handler(void)
1510 {
1511         g_hash_table_destroy(req_table);
1512         g_bus_unown_name(owner_id);
1513         g_dbus_node_info_unref(instropection_data);
1514 }