7 #include <gum/gum-user.h>
8 #include <gum/common/gum-user-types.h>
11 #include "pkgmgr-server.h"
12 #include "package-manager.h"
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"
19 static const char instropection_xml[] =
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'/>"
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'/>"
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'/>"
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'/>"
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'/>"
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'/>"
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'/>"
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'/>"
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'/>"
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'/>"
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'/>"
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'/>"
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'/>"
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'/>"
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'/>"
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'/>"
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'/>"
126 " <method name='register_license'>"
127 " <arg type='s' name='resp_data' direction='in'/>"
128 " <arg type='i' name='ret' direction='out'/>"
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'/>"
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'/>"
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'/>"
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'/>"
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'/>"
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'/>"
165 static GDBusNodeInfo *instropection_data;
167 static guint owner_id;
168 static GHashTable *req_table;
170 static char *__generate_reqkey(const char *pkgid)
174 char timestr[MAX_PKG_ARGS_LEN];
178 gettimeofday(&tv, NULL);
179 curtime = tv.tv_sec * 1000000 + tv.tv_usec;
180 snprintf(timestr, sizeof(timestr), "%ld", curtime);
182 size = strlen(pkgid) + strlen(timestr) + 2;
183 str_req_key = (char *)calloc(size, sizeof(char));
184 if (str_req_key == NULL) {
185 DBG("calloc failed");
188 snprintf(str_req_key, size, "%s_%s", pkgid, timestr);
193 static int __is_admin_user(uid_t uid)
196 GumUserType ut = GUM_USERTYPE_NONE;
200 guser = gum_user_get_sync(uid, FALSE);
202 ERR("cannot get user information from gumd, retry");
204 usleep(RETRY_WAIT_USEC);
208 } while (retry_cnt <= RETRY_MAX);
211 ERR("cannot get user information from gumd, failed");
215 g_object_get(G_OBJECT(guser), "usertype", &ut, NULL);
216 if (ut == GUM_USERTYPE_NONE) {
217 ERR("cannot get user type");
218 g_object_unref(guser);
220 } else if (ut != GUM_USERTYPE_ADMIN) {
221 g_object_unref(guser);
225 g_object_unref(guser);
230 #define REGULAR_USER 5000
231 static int __check_caller_permission(uid_t uid,
232 GDBusMethodInvocation *invocation, GVariant *parameters)
238 if (uid < REGULAR_USER)
241 v = g_variant_get_child_value(parameters, 0);
243 g_dbus_method_invocation_return_error_literal(invocation,
244 G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
249 target_uid = g_variant_get_uint32(v);
251 if (uid == target_uid)
254 is_admin = __is_admin_user(uid);
255 if (is_admin == -1) {
256 g_dbus_method_invocation_return_error_literal(invocation,
257 G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
260 } else if (is_admin == 0) {
261 g_dbus_method_invocation_return_error_literal(invocation,
262 G_DBUS_ERROR, G_DBUS_ERROR_ACCESS_DENIED,
263 "Non-admin user cannot request operation to "
271 static int __handle_request_install(uid_t caller_uid,
272 GDBusMethodInvocation *invocation, GVariant *parameters)
274 uid_t target_uid = (uid_t)-1;
276 char *pkgpath = NULL;
279 gchar **tmp_args = NULL;
286 g_variant_get(parameters, "(u&s@as)", &target_uid, &pkgpath, &value);
287 tmp_args = (gchar **)g_variant_get_strv(value, &args_count);
289 for (i = 0; i < args_count; i++)
290 len = len + strlen(tmp_args[i]) + 1;
292 args = (char *)calloc(len, sizeof(char));
294 ERR("calloc failed");
295 g_dbus_method_invocation_return_value(invocation,
296 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
301 for (i = 0; i < args_count; i++) {
302 strncat(args, tmp_args[i], strlen(tmp_args[i]));
303 if (i != args_count - 1)
304 strncat(args, " ", strlen(" "));
307 if (target_uid == (uid_t)-1 || pkgpath == NULL) {
308 g_dbus_method_invocation_return_value(invocation,
309 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
314 pkgtype = _get_pkgtype_from_file(pkgpath);
315 if (pkgtype == NULL) {
316 g_dbus_method_invocation_return_value(invocation,
317 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
322 reqkey = __generate_reqkey(pkgpath);
323 if (reqkey == NULL) {
324 g_dbus_method_invocation_return_value(invocation,
325 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
330 if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_INSTALL,
331 pkgtype, pkgpath, args)) {
332 g_dbus_method_invocation_return_value(invocation,
333 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
338 g_dbus_method_invocation_return_value(invocation,
339 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
356 static int __handle_request_mount_install(uid_t caller_uid,
357 GDBusMethodInvocation *invocation, GVariant *parameters)
359 uid_t target_uid = (uid_t)-1;
361 char *pkgpath = NULL;
364 gchar **tmp_args = NULL;
371 g_variant_get(parameters, "(u&s@as)", &target_uid, &pkgpath, &value);
372 tmp_args = (gchar **)g_variant_get_strv(value, &args_count);
374 for (i = 0; i < args_count; i++)
375 len = len + strlen(tmp_args[i]) + 1;
377 args = (char *)calloc(len, sizeof(char));
379 ERR("calloc failed");
380 g_dbus_method_invocation_return_value(invocation,
381 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
386 for (i = 0; i < args_count; i++) {
387 strncat(args, tmp_args[i], strlen(tmp_args[i]));
388 if (i != args_count - 1)
389 strncat(args, " ", strlen(" "));
392 if (target_uid == (uid_t)-1 || pkgpath == NULL) {
393 g_dbus_method_invocation_return_value(invocation,
394 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
399 pkgtype = _get_pkgtype_from_file(pkgpath);
400 if (pkgtype == NULL) {
401 g_dbus_method_invocation_return_value(invocation,
402 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
407 reqkey = __generate_reqkey(pkgpath);
408 if (reqkey == NULL) {
409 g_dbus_method_invocation_return_value(invocation,
410 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
415 if (_push_queue(target_uid, caller_uid, reqkey,
416 REQUEST_TYPE_MOUNT_INSTALL,
417 pkgtype, pkgpath, args)) {
418 g_dbus_method_invocation_return_value(invocation,
419 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
424 g_dbus_method_invocation_return_value(invocation,
425 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
441 static int __handle_request_reinstall(uid_t caller_uid,
442 GDBusMethodInvocation *invocation, GVariant *parameters)
444 uid_t target_uid = (uid_t)-1;
449 g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
450 if (target_uid == (uid_t)-1 || pkgid == NULL) {
451 g_dbus_method_invocation_return_value(invocation,
452 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
456 pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
457 if (pkgtype == NULL) {
458 g_dbus_method_invocation_return_value(invocation,
459 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
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, ""));
470 if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_REINSTALL,
471 pkgtype, pkgid, NULL)) {
472 g_dbus_method_invocation_return_value(invocation,
473 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
479 g_dbus_method_invocation_return_value(invocation,
480 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
487 static int __handle_request_uninstall(uid_t caller_uid,
488 GDBusMethodInvocation *invocation, GVariant *parameters)
490 uid_t target_uid = (uid_t)-1;
495 g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
496 if (target_uid == (uid_t)-1 || pkgid == NULL) {
497 g_dbus_method_invocation_return_value(invocation,
498 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
502 pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
503 if (pkgtype == NULL) {
504 g_dbus_method_invocation_return_value(invocation,
505 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
509 reqkey = __generate_reqkey(pkgid);
510 if (reqkey == NULL) {
511 g_dbus_method_invocation_return_value(invocation,
512 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
516 if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_UNINSTALL,
517 pkgtype, pkgid, NULL)) {
518 g_dbus_method_invocation_return_value(invocation,
519 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
525 g_dbus_method_invocation_return_value(invocation,
526 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
533 static int __handle_request_move(uid_t caller_uid,
534 GDBusMethodInvocation *invocation, GVariant *parameters)
536 uid_t target_uid = (uid_t)-1;
541 char buf[4] = { '\0' };
543 g_variant_get(parameters, "(u&si)", &target_uid, &pkgid, &move_type);
544 if (target_uid == (uid_t)-1 || pkgid == NULL) {
545 g_dbus_method_invocation_return_value(invocation,
546 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
550 pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
551 if (pkgtype == NULL) {
552 g_dbus_method_invocation_return_value(invocation,
553 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
557 reqkey = __generate_reqkey(pkgid);
558 if (reqkey == NULL) {
559 g_dbus_method_invocation_return_value(invocation,
560 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
565 snprintf(buf, sizeof(buf), "%d", move_type);
566 if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_MOVE,
567 pkgtype, pkgid, buf)) {
568 g_dbus_method_invocation_return_value(invocation,
569 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
575 g_dbus_method_invocation_return_value(invocation,
576 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
583 static int __handle_request_enable_pkgs(uid_t caller_uid,
584 GDBusMethodInvocation *invocation, GVariant *parameters)
586 uid_t target_uid = (uid_t)-1;
592 g_variant_get(parameters, "(uas)", &target_uid, &iter);
593 if (target_uid == (uid_t)-1 || iter == NULL) {
594 g_dbus_method_invocation_return_value(invocation,
595 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
599 reqkey = __generate_reqkey("enable_pkgs");
600 if (reqkey == NULL) {
601 g_dbus_method_invocation_return_value(invocation,
602 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
606 while (g_variant_iter_next(iter, "&s", &pkgid)) {
607 pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
608 if (pkgtype == NULL) {
609 g_dbus_method_invocation_return_value(invocation,
610 g_variant_new("(is)",
611 PKGMGR_R_ESYSTEM, ""));
615 if (_push_queue(target_uid, caller_uid, reqkey,
616 REQUEST_TYPE_ENABLE_PKG,
617 pkgtype, pkgid, NULL)) {
618 g_dbus_method_invocation_return_value(invocation,
619 g_variant_new("(is)",
620 PKGMGR_R_ESYSTEM, ""));
628 g_dbus_method_invocation_return_value(invocation,
629 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
635 static int __handle_request_disable_pkgs(uid_t caller_uid,
636 GDBusMethodInvocation *invocation, GVariant *parameters)
638 uid_t target_uid = (uid_t)-1;
644 g_variant_get(parameters, "(uas)", &target_uid, &iter);
645 if (target_uid == (uid_t)-1 || iter == NULL) {
646 g_dbus_method_invocation_return_value(invocation,
647 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
651 reqkey = __generate_reqkey("disable_pkgs");
652 if (reqkey == NULL) {
653 g_dbus_method_invocation_return_value(invocation,
654 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
658 while (g_variant_iter_next(iter, "&s", &pkgid)) {
659 pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
660 if (pkgtype == NULL) {
661 g_dbus_method_invocation_return_value(invocation,
662 g_variant_new("(is)",
663 PKGMGR_R_ESYSTEM, ""));
667 if (_push_queue(target_uid, caller_uid, reqkey,
668 REQUEST_TYPE_DISABLE_PKG,
669 pkgtype, pkgid, NULL)) {
670 g_dbus_method_invocation_return_value(invocation,
671 g_variant_new("(is)",
672 PKGMGR_R_ESYSTEM, ""));
680 g_dbus_method_invocation_return_value(invocation,
681 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
687 static int __handle_request_enable_app(uid_t caller_uid,
688 GDBusMethodInvocation *invocation, GVariant *parameters)
690 uid_t target_uid = (uid_t)-1;
695 g_variant_get(parameters, "(u&s)", &target_uid, &appid);
696 if (target_uid == (uid_t)-1 || appid == NULL) {
697 g_dbus_method_invocation_return_value(invocation,
698 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
702 reqkey = __generate_reqkey(appid);
703 if (reqkey == NULL) {
704 g_dbus_method_invocation_return_value(invocation,
705 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
710 if (_push_queue(target_uid, caller_uid, reqkey,
711 REQUEST_TYPE_ENABLE_APP, "default",
713 g_dbus_method_invocation_return_value(invocation,
714 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
719 g_dbus_method_invocation_return_value(invocation,
720 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
731 static int __handle_request_disable_app(uid_t caller_uid,
732 GDBusMethodInvocation *invocation, GVariant *parameters)
734 uid_t target_uid = (uid_t)-1;
739 g_variant_get(parameters, "(u&s)", &target_uid, &appid);
740 if (target_uid == (uid_t)-1 || appid == NULL) {
741 g_dbus_method_invocation_return_value(invocation,
742 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
746 reqkey = __generate_reqkey(appid);
747 if (reqkey == NULL) {
748 g_dbus_method_invocation_return_value(invocation,
749 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
754 if (_push_queue(target_uid, caller_uid, reqkey,
755 REQUEST_TYPE_DISABLE_APP, "default",
757 g_dbus_method_invocation_return_value(invocation,
758 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
763 g_dbus_method_invocation_return_value(invocation,
764 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
775 static int __handle_request_enable_global_app_for_uid(uid_t caller_uid,
776 GDBusMethodInvocation *invocation, GVariant *parameters)
778 uid_t target_uid = (uid_t)-1;
783 g_variant_get(parameters, "(u&s)", &target_uid, &appid);
784 if (target_uid == (uid_t)-1 || appid == NULL) {
785 g_dbus_method_invocation_return_value(invocation,
786 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
790 reqkey = __generate_reqkey(appid);
791 if (reqkey == NULL) {
792 g_dbus_method_invocation_return_value(invocation,
793 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
798 if (_push_queue(target_uid, caller_uid, reqkey,
799 REQUEST_TYPE_ENABLE_GLOBAL_APP_FOR_UID,
800 "default", appid, NULL)) {
801 g_dbus_method_invocation_return_value(invocation,
802 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
807 g_dbus_method_invocation_return_value(invocation,
808 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
819 static int __handle_request_disable_global_app_for_uid(uid_t caller_uid,
820 GDBusMethodInvocation *invocation, GVariant *parameters)
822 uid_t target_uid = (uid_t)-1;
827 g_variant_get(parameters, "(u&s)", &target_uid, &appid);
828 if (target_uid == (uid_t)-1 || appid == NULL) {
829 g_dbus_method_invocation_return_value(invocation,
830 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
834 reqkey = __generate_reqkey(appid);
835 if (reqkey == NULL) {
836 g_dbus_method_invocation_return_value(invocation,
837 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
842 if (_push_queue(target_uid, caller_uid, reqkey,
843 REQUEST_TYPE_DISABLE_GLOBAL_APP_FOR_UID,
844 "default", appid, NULL)) {
845 g_dbus_method_invocation_return_value(invocation,
846 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
851 g_dbus_method_invocation_return_value(invocation,
852 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
863 static int __handle_request_getsize(uid_t caller_uid,
864 GDBusMethodInvocation *invocation, GVariant *parameters)
866 uid_t target_uid = (uid_t)-1;
872 g_variant_get(parameters, "(u&si)", &target_uid, &pkgid, &get_type);
873 if (target_uid == (uid_t)-1 || pkgid == NULL || get_type == -1) {
874 g_dbus_method_invocation_return_value(invocation,
875 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
879 reqkey = __generate_reqkey(pkgid);
880 if (reqkey == NULL) {
881 g_dbus_method_invocation_return_value(invocation,
882 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
886 snprintf(buf, sizeof(buf), "%d", get_type);
887 if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_GETSIZE,
888 "pkgtool", pkgid, buf)) {
889 g_dbus_method_invocation_return_value(invocation,
890 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
895 g_dbus_method_invocation_return_value(invocation,
896 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
902 static int __handle_request_cleardata(uid_t caller_uid,
903 GDBusMethodInvocation *invocation, GVariant *parameters)
905 uid_t target_uid = (uid_t)-1;
910 g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
911 if (target_uid == (uid_t)-1 || pkgid == NULL) {
912 g_dbus_method_invocation_return_value(invocation,
913 g_variant_new("(i)", PKGMGR_R_ECOMM));
917 pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
918 if (pkgtype == NULL) {
919 g_dbus_method_invocation_return_value(invocation,
920 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
924 reqkey = __generate_reqkey(pkgid);
925 if (reqkey == NULL) {
926 g_dbus_method_invocation_return_value(invocation,
927 g_variant_new("(i)", PKGMGR_R_ENOMEM));
932 if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_CLEARDATA,
933 pkgtype, pkgid, NULL)) {
934 g_dbus_method_invocation_return_value(invocation,
935 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
941 g_dbus_method_invocation_return_value(invocation,
942 g_variant_new("(i)", PKGMGR_R_OK));
950 static int __handle_request_clearcache(uid_t caller_uid,
951 GDBusMethodInvocation *invocation, GVariant *parameters)
953 uid_t target_uid = (uid_t)-1;
956 g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
957 if (target_uid == (uid_t)-1 || pkgid == NULL) {
958 g_dbus_method_invocation_return_value(invocation,
959 g_variant_new("(i)", PKGMGR_R_ECOMM));
963 if (_push_queue(target_uid, caller_uid, NULL, REQUEST_TYPE_CLEARCACHE,
964 "pkgtool", pkgid, NULL)) {
965 g_dbus_method_invocation_return_value(invocation,
966 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
970 g_dbus_method_invocation_return_value(invocation,
971 g_variant_new("(i)", PKGMGR_R_OK));
976 static int __handle_request_kill(uid_t caller_uid,
977 GDBusMethodInvocation *invocation, GVariant *parameters)
979 uid_t target_uid = (uid_t)-1;
983 g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
984 if (target_uid == (uid_t)-1 || pkgid == NULL) {
985 g_dbus_method_invocation_return_value(invocation,
986 g_variant_new("(ii)", PKGMGR_R_ECOMM, 0));
990 reqkey = __generate_reqkey(pkgid);
991 if (reqkey == NULL) {
992 g_dbus_method_invocation_return_value(invocation,
993 g_variant_new("(ii)", PKGMGR_R_ENOMEM, 0));
997 if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_KILL,
998 "default", pkgid, NULL)) {
999 g_dbus_method_invocation_return_value(invocation,
1000 g_variant_new("(ii)", PKGMGR_R_ESYSTEM, 0));
1005 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1006 (gpointer)invocation))
1007 ERR("reqkey already exists");
1012 static int __handle_request_check(uid_t caller_uid,
1013 GDBusMethodInvocation *invocation, GVariant *parameters)
1015 uid_t target_uid = (uid_t)-1;
1017 char *reqkey = NULL;
1019 g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
1020 if (target_uid == (uid_t)-1 || pkgid == NULL) {
1021 g_dbus_method_invocation_return_value(invocation,
1022 g_variant_new("(ii)", PKGMGR_R_ECOMM, 0));
1026 reqkey = __generate_reqkey(pkgid);
1027 if (reqkey == NULL) {
1028 g_dbus_method_invocation_return_value(invocation,
1029 g_variant_new("(ii)", PKGMGR_R_ENOMEM, 0));
1033 if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_CHECK,
1034 "default", pkgid, NULL)) {
1035 g_dbus_method_invocation_return_value(invocation,
1036 g_variant_new("(ii)", PKGMGR_R_ESYSTEM, 0));
1041 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1042 (gpointer)invocation))
1043 ERR("reqkey already exists");
1048 static int __handle_request_generate_license_request(uid_t caller_uid,
1049 GDBusMethodInvocation *invocation, GVariant *parameters)
1052 char *resp_data = NULL;
1054 g_variant_get(parameters, "(&s)", &resp_data);
1055 if (resp_data == NULL) {
1056 g_dbus_method_invocation_return_value(invocation,
1057 g_variant_new("(iss)", PKGMGR_R_ECOMM, "", ""));
1061 reqkey = __generate_reqkey("drm");
1062 if (reqkey == NULL) {
1063 g_dbus_method_invocation_return_value(invocation,
1064 g_variant_new("(iss)", PKGMGR_R_ENOMEM, "",
1069 if (_push_queue(caller_uid, caller_uid, reqkey,
1070 REQUEST_TYPE_GENERATE_LICENSE_REQUEST,
1071 "default", NULL, resp_data)) {
1072 g_dbus_method_invocation_return_value(invocation,
1073 g_variant_new("(iss)", PKGMGR_R_ESYSTEM, "",
1079 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1080 (gpointer)invocation))
1081 ERR("reqkey already exists");
1086 static int __handle_request_register_license(uid_t caller_uid,
1087 GDBusMethodInvocation *invocation, GVariant *parameters)
1090 char *resp_data = NULL;
1092 g_variant_get(parameters, "(&s)", &resp_data);
1093 if (resp_data == NULL) {
1094 g_dbus_method_invocation_return_value(invocation,
1095 g_variant_new("(i)", PKGMGR_R_ECOMM));
1099 reqkey = __generate_reqkey("drm");
1100 if (reqkey == NULL) {
1101 g_dbus_method_invocation_return_value(invocation,
1102 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1106 if (_push_queue(caller_uid, caller_uid, reqkey,
1107 REQUEST_TYPE_REGISTER_LICENSE,
1108 "default", NULL, resp_data)) {
1109 g_dbus_method_invocation_return_value(invocation,
1110 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1115 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1116 (gpointer)invocation))
1117 ERR("reqkey already exists");
1122 static int __handle_request_decrypt_package(uid_t caller_uid,
1123 GDBusMethodInvocation *invocation, GVariant *parameters)
1126 char *drm_file_path = NULL;
1127 char *decrypted_file_path = NULL;
1129 g_variant_get(parameters, "(&s&s)", &drm_file_path,
1130 &decrypted_file_path);
1131 if (drm_file_path == NULL || decrypted_file_path == NULL) {
1132 g_dbus_method_invocation_return_value(invocation,
1133 g_variant_new("(i)", PKGMGR_R_ECOMM));
1137 reqkey = __generate_reqkey("drm");
1138 if (reqkey == NULL) {
1139 g_dbus_method_invocation_return_value(invocation,
1140 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1144 if (_push_queue(caller_uid, caller_uid, reqkey,
1145 REQUEST_TYPE_DECRYPT_PACKAGE,
1146 "default", drm_file_path,
1147 decrypted_file_path)) {
1148 g_dbus_method_invocation_return_value(invocation,
1149 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1154 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1155 (gpointer)invocation))
1156 ERR("reqkey already exists");
1161 static int __update_app_splash_screen(uid_t caller_uid,
1162 GDBusMethodInvocation *invocation, GVariant *parameters,
1165 uid_t target_uid = (uid_t)-1;
1169 g_variant_get(parameters, "(u&s)", &target_uid, &appid);
1170 if (target_uid == (uid_t)-1 || appid == NULL) {
1171 ERR("target_uid: %d, appid: %s", target_uid, appid);
1172 g_dbus_method_invocation_return_value(invocation,
1173 g_variant_new("(i)", PKGMGR_R_ECOMM));
1177 reqkey = __generate_reqkey(appid);
1178 if (reqkey == NULL) {
1179 ERR("Failed to generate request key");
1180 g_dbus_method_invocation_return_value(invocation,
1181 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1185 if (_push_queue(target_uid, caller_uid, reqkey, req_type, "default",
1187 ERR("Failed to push request");
1188 g_dbus_method_invocation_return_value(invocation,
1189 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1194 g_dbus_method_invocation_return_value(invocation,
1195 g_variant_new("(i)", PKGMGR_R_OK));
1203 static int __handle_request_enable_app_splash_screen(uid_t caller_uid,
1204 GDBusMethodInvocation *invocation, GVariant *parameters)
1206 return __update_app_splash_screen(caller_uid, invocation, parameters,
1207 REQUEST_TYPE_ENABLE_APP_SPLASH_SCREEN);
1210 static int __handle_request_disable_app_splash_screen(uid_t caller_uid,
1211 GDBusMethodInvocation *invocation, GVariant *parameters)
1213 return __update_app_splash_screen(caller_uid, invocation, parameters,
1214 REQUEST_TYPE_DISABLE_APP_SPLASH_SCREEN);
1217 static int __handle_request_set_restriction_mode(uid_t caller_uid,
1218 GDBusMethodInvocation *invocation, GVariant *parameters)
1220 uid_t target_uid = (uid_t)-1;
1226 g_variant_get(parameters, "(usi)", &target_uid, &pkgid, &mode);
1227 if (target_uid == (uid_t)-1 || pkgid == NULL || mode < 0) {
1228 g_dbus_method_invocation_return_value(invocation,
1229 g_variant_new("(i)", PKGMGR_R_ECOMM));
1233 reqkey = __generate_reqkey("restriction");
1234 if (reqkey == NULL) {
1235 g_dbus_method_invocation_return_value(invocation,
1236 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1240 snprintf(buf, sizeof(buf), "%d", mode);
1241 if (_push_queue(target_uid, caller_uid, reqkey,
1242 REQUEST_TYPE_SET_RESTRICTION_MODE,
1243 "default", pkgid, buf)) {
1244 g_dbus_method_invocation_return_value(invocation,
1245 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1250 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1251 (gpointer)invocation))
1252 ERR("reqkey already exists");
1257 static int __handle_request_unset_restriction_mode(uid_t caller_uid,
1258 GDBusMethodInvocation *invocation, GVariant *parameters)
1260 uid_t target_uid = (uid_t)-1;
1266 g_variant_get(parameters, "(usi)", &target_uid, &pkgid, &mode);
1267 if (target_uid == (uid_t)-1 || pkgid == NULL || mode < 0) {
1268 g_dbus_method_invocation_return_value(invocation,
1269 g_variant_new("(i)", PKGMGR_R_ECOMM));
1273 reqkey = __generate_reqkey("restriction");
1274 if (reqkey == NULL) {
1275 g_dbus_method_invocation_return_value(invocation,
1276 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1280 snprintf(buf, sizeof(buf), "%d", mode);
1281 if (_push_queue(target_uid, caller_uid, reqkey,
1282 REQUEST_TYPE_UNSET_RESTRICTION_MODE,
1283 "default", pkgid, buf)) {
1284 g_dbus_method_invocation_return_value(invocation,
1285 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1290 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1291 (gpointer)invocation))
1292 ERR("reqkey already exists");
1297 static int __handle_request_get_restriction_mode(uid_t caller_uid,
1298 GDBusMethodInvocation *invocation, GVariant *parameters)
1300 uid_t target_uid = (uid_t)-1;
1304 g_variant_get(parameters, "(us)", &target_uid, &pkgid);
1305 if (target_uid == (uid_t)-1 || pkgid == NULL) {
1306 g_dbus_method_invocation_return_value(invocation,
1307 g_variant_new("(i)", PKGMGR_R_ECOMM));
1311 reqkey = __generate_reqkey("restriction");
1312 if (reqkey == NULL) {
1313 g_dbus_method_invocation_return_value(invocation,
1314 g_variant_new("(ii)", -1, PKGMGR_R_ENOMEM));
1318 if (_push_queue(target_uid, caller_uid, reqkey,
1319 REQUEST_TYPE_GET_RESTRICTION_MODE,
1320 "default", pkgid, NULL)) {
1321 g_dbus_method_invocation_return_value(invocation,
1322 g_variant_new("(ii)", -1, PKGMGR_R_ESYSTEM));
1327 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1328 (gpointer)invocation))
1329 ERR("reqkey already exists");
1334 static uid_t __get_caller_uid(GDBusConnection *connection, const char *name)
1340 result = g_dbus_connection_call_sync(connection,
1341 "org.freedesktop.DBus", "/org/freedesktop/DBus",
1342 "org.freedesktop.DBus", "GetConnectionUnixUser",
1343 g_variant_new("(s)", name), NULL,
1344 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
1345 if (result == NULL) {
1346 ERR("failed to get caller uid: %s", err->message);
1351 g_variant_get(result, "(u)", &uid);
1356 static void __handle_method_call(GDBusConnection *connection,
1357 const gchar *sender, const gchar *object_path,
1358 const gchar *interface_name, const gchar *method_name,
1359 GVariant *parameters, GDBusMethodInvocation *invocation,
1365 uid = __get_caller_uid(connection,
1366 g_dbus_method_invocation_get_sender(invocation));
1367 if (uid == (uid_t)-1)
1370 if (__check_caller_permission(uid, invocation, parameters))
1373 if (g_strcmp0(method_name, "install") == 0)
1374 ret = __handle_request_install(uid, invocation, parameters);
1375 else if (g_strcmp0(method_name, "mount_install") == 0)
1376 ret = __handle_request_mount_install(uid, invocation,
1378 else if (g_strcmp0(method_name, "reinstall") == 0)
1379 ret = __handle_request_reinstall(uid, invocation, parameters);
1380 else if (g_strcmp0(method_name, "uninstall") == 0)
1381 ret = __handle_request_uninstall(uid, invocation, parameters);
1382 else if (g_strcmp0(method_name, "cleardata") == 0)
1383 ret = __handle_request_cleardata(uid, invocation, parameters);
1384 else if (g_strcmp0(method_name, "move") == 0)
1385 ret = __handle_request_move(uid, invocation, parameters);
1386 else if (g_strcmp0(method_name, "enable_pkgs") == 0)
1387 ret = __handle_request_enable_pkgs(uid, invocation, parameters);
1388 else if (g_strcmp0(method_name, "disable_pkgs") == 0)
1389 ret = __handle_request_disable_pkgs(uid, invocation, parameters);
1390 else if (g_strcmp0(method_name, "getsize") == 0)
1391 ret = __handle_request_getsize(uid, invocation, parameters);
1392 else if (g_strcmp0(method_name, "clearcache") == 0)
1393 ret = __handle_request_clearcache(uid, invocation, parameters);
1394 else if (g_strcmp0(method_name, "enable_app") == 0)
1395 ret = __handle_request_enable_app(uid, invocation, parameters);
1396 else if (g_strcmp0(method_name, "disable_app") == 0)
1397 ret = __handle_request_disable_app(uid, invocation, parameters);
1398 else if (g_strcmp0(method_name, "enable_global_app_for_uid") == 0)
1399 ret = __handle_request_enable_global_app_for_uid(uid,
1400 invocation, parameters);
1401 else if (g_strcmp0(method_name, "disable_global_app_for_uid") == 0)
1402 ret = __handle_request_disable_global_app_for_uid(uid,
1403 invocation, parameters);
1404 else if (g_strcmp0(method_name, "kill") == 0)
1405 ret = __handle_request_kill(uid, invocation, parameters);
1406 else if (g_strcmp0(method_name, "check") == 0)
1407 ret = __handle_request_check(uid, invocation, parameters);
1408 else if (g_strcmp0(method_name, "generate_license_request") == 0)
1409 ret = __handle_request_generate_license_request(uid, invocation,
1411 else if (g_strcmp0(method_name, "register_license") == 0)
1412 ret = __handle_request_register_license(uid, invocation,
1414 else if (g_strcmp0(method_name, "decrypt_package") == 0)
1415 ret = __handle_request_decrypt_package(uid, invocation,
1417 else if (g_strcmp0(method_name, "disable_app_splash_screen") == 0)
1418 ret = __handle_request_disable_app_splash_screen(uid,
1419 invocation, parameters);
1420 else if (g_strcmp0(method_name, "enable_app_splash_screen") == 0)
1421 ret = __handle_request_enable_app_splash_screen(uid,
1422 invocation, parameters);
1423 else if (g_strcmp0(method_name, "set_restriction_mode") == 0)
1424 ret = __handle_request_set_restriction_mode(uid, invocation,
1426 else if (g_strcmp0(method_name, "unset_restriction_mode") == 0)
1427 ret = __handle_request_unset_restriction_mode(uid, invocation,
1429 else if (g_strcmp0(method_name, "get_restriction_mode") == 0)
1430 ret = __handle_request_get_restriction_mode(uid, invocation,
1436 g_idle_add(queue_job, NULL);
1439 int _return_value_to_caller(const char *req_key, GVariant *result)
1441 GDBusMethodInvocation *invocation;
1443 invocation = (GDBusMethodInvocation *)g_hash_table_lookup(req_table,
1445 if (invocation == NULL) {
1446 ERR("no such request id");
1450 g_dbus_method_invocation_return_value(invocation, result);
1451 g_hash_table_remove(req_table, (gpointer)req_key);
1456 static const GDBusInterfaceVTable interface_vtable = {
1457 __handle_method_call,
1462 static void __on_bus_acquired(GDBusConnection *connection, const gchar *name,
1467 DBG("on bus acquired");
1469 reg_id = g_dbus_connection_register_object(connection,
1470 PKGMGR_DBUS_OBJECT_PATH,
1471 instropection_data->interfaces[0],
1472 &interface_vtable, NULL, NULL, &err);
1475 ERR("failed to register object: %s", err->message);
1480 static void __on_name_acquired(GDBusConnection *connection, const gchar *name,
1483 DBG("on name acquired: %s", name);
1486 static void __on_name_lost(GDBusConnection *connection, const gchar *name,
1489 DBG("on name lost: %s", name);
1492 int _init_request_handler(void)
1494 instropection_data = g_dbus_node_info_new_for_xml(instropection_xml,
1497 owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, PKGMGR_DBUS_SERVICE,
1498 G_BUS_NAME_OWNER_FLAGS_NONE, __on_bus_acquired,
1499 __on_name_acquired, __on_name_lost, NULL, NULL);
1501 req_table = g_hash_table_new_full(g_str_hash, g_str_equal,
1503 if (req_table == NULL)
1509 void _fini_request_handler(void)
1511 g_hash_table_destroy(req_table);
1512 g_bus_unown_name(owner_id);
1513 g_dbus_node_info_unref(instropection_data);