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