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