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