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 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, reqkey, REQUEST_TYPE_INSTALL, pkgtype,
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 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, reqkey, REQUEST_TYPE_MOUNT_INSTALL,
416 pkgtype, pkgpath, args)) {
417 g_dbus_method_invocation_return_value(invocation,
418 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
423 g_dbus_method_invocation_return_value(invocation,
424 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
440 static int __handle_request_reinstall(uid_t uid,
441 GDBusMethodInvocation *invocation, GVariant *parameters)
443 uid_t target_uid = (uid_t)-1;
448 g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
449 if (target_uid == (uid_t)-1 || pkgid == NULL) {
450 g_dbus_method_invocation_return_value(invocation,
451 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
455 pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
456 if (pkgtype == NULL) {
457 g_dbus_method_invocation_return_value(invocation,
458 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
462 reqkey = __generate_reqkey(pkgid);
463 if (reqkey == NULL) {
464 g_dbus_method_invocation_return_value(invocation,
465 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
469 if (_push_queue(target_uid, reqkey, REQUEST_TYPE_REINSTALL, pkgtype,
471 g_dbus_method_invocation_return_value(invocation,
472 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
478 g_dbus_method_invocation_return_value(invocation,
479 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
486 static int __handle_request_uninstall(uid_t uid,
487 GDBusMethodInvocation *invocation, GVariant *parameters)
489 uid_t target_uid = (uid_t)-1;
494 g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
495 if (target_uid == (uid_t)-1 || pkgid == NULL) {
496 g_dbus_method_invocation_return_value(invocation,
497 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
501 pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
502 if (pkgtype == NULL) {
503 g_dbus_method_invocation_return_value(invocation,
504 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
508 reqkey = __generate_reqkey(pkgid);
509 if (reqkey == NULL) {
510 g_dbus_method_invocation_return_value(invocation,
511 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
515 if (_push_queue(target_uid, reqkey, REQUEST_TYPE_UNINSTALL, pkgtype,
517 g_dbus_method_invocation_return_value(invocation,
518 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
524 g_dbus_method_invocation_return_value(invocation,
525 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
532 static int __handle_request_move(uid_t uid,
533 GDBusMethodInvocation *invocation, GVariant *parameters)
535 uid_t target_uid = (uid_t)-1;
540 char buf[4] = { '\0' };
542 g_variant_get(parameters, "(u&si)", &target_uid, &pkgid, &move_type);
543 if (target_uid == (uid_t)-1 || pkgid == NULL) {
544 g_dbus_method_invocation_return_value(invocation,
545 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
549 pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
550 if (pkgtype == NULL) {
551 g_dbus_method_invocation_return_value(invocation,
552 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
556 reqkey = __generate_reqkey(pkgid);
557 if (reqkey == NULL) {
558 g_dbus_method_invocation_return_value(invocation,
559 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
564 snprintf(buf, sizeof(buf), "%d", move_type);
565 if (_push_queue(target_uid, reqkey, REQUEST_TYPE_MOVE, pkgtype,
567 g_dbus_method_invocation_return_value(invocation,
568 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
574 g_dbus_method_invocation_return_value(invocation,
575 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
582 static int __handle_request_enable_pkgs(uid_t uid,
583 GDBusMethodInvocation *invocation, GVariant *parameters)
585 uid_t target_uid = (uid_t)-1;
591 g_variant_get(parameters, "(uas)", &target_uid, &iter);
592 if (target_uid == (uid_t)-1 || iter == NULL) {
593 g_dbus_method_invocation_return_value(invocation,
594 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
598 reqkey = __generate_reqkey("enable_pkgs");
599 if (reqkey == NULL) {
600 g_dbus_method_invocation_return_value(invocation,
601 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
605 while (g_variant_iter_next(iter, "&s", &pkgid)) {
606 pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
607 if (pkgtype == NULL) {
608 g_dbus_method_invocation_return_value(invocation,
609 g_variant_new("(is)",
610 PKGMGR_R_ESYSTEM, ""));
614 if (_push_queue(target_uid, reqkey, REQUEST_TYPE_ENABLE_PKG,
615 pkgtype, pkgid, NULL)) {
616 g_dbus_method_invocation_return_value(invocation,
617 g_variant_new("(is)",
618 PKGMGR_R_ESYSTEM, ""));
626 g_dbus_method_invocation_return_value(invocation,
627 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
633 static int __handle_request_disable_pkgs(uid_t uid,
634 GDBusMethodInvocation *invocation, GVariant *parameters)
636 uid_t target_uid = (uid_t)-1;
642 g_variant_get(parameters, "(uas)", &target_uid, &iter);
643 if (target_uid == (uid_t)-1 || iter == NULL) {
644 g_dbus_method_invocation_return_value(invocation,
645 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
649 reqkey = __generate_reqkey("disable_pkgs");
650 if (reqkey == NULL) {
651 g_dbus_method_invocation_return_value(invocation,
652 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
656 while (g_variant_iter_next(iter, "&s", &pkgid)) {
657 pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
658 if (pkgtype == NULL) {
659 g_dbus_method_invocation_return_value(invocation,
660 g_variant_new("(is)",
661 PKGMGR_R_ESYSTEM, ""));
665 if (_push_queue(target_uid, reqkey, REQUEST_TYPE_DISABLE_PKG,
666 pkgtype, pkgid, NULL)) {
667 g_dbus_method_invocation_return_value(invocation,
668 g_variant_new("(is)",
669 PKGMGR_R_ESYSTEM, ""));
677 g_dbus_method_invocation_return_value(invocation,
678 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
684 static int __handle_request_enable_app(uid_t uid,
685 GDBusMethodInvocation *invocation, GVariant *parameters)
687 uid_t target_uid = (uid_t)-1;
692 g_variant_get(parameters, "(u&s)", &target_uid, &appid);
693 if (target_uid == (uid_t)-1 || appid == NULL) {
694 g_dbus_method_invocation_return_value(invocation,
695 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
699 reqkey = __generate_reqkey(appid);
700 if (reqkey == NULL) {
701 g_dbus_method_invocation_return_value(invocation,
702 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
707 if (_push_queue(target_uid, reqkey, REQUEST_TYPE_ENABLE_APP, "default",
709 g_dbus_method_invocation_return_value(invocation,
710 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
715 g_dbus_method_invocation_return_value(invocation,
716 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
727 static int __handle_request_disable_app(uid_t uid,
728 GDBusMethodInvocation *invocation, GVariant *parameters)
730 uid_t target_uid = (uid_t)-1;
735 g_variant_get(parameters, "(u&s)", &target_uid, &appid);
736 if (target_uid == (uid_t)-1 || appid == NULL) {
737 g_dbus_method_invocation_return_value(invocation,
738 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
742 reqkey = __generate_reqkey(appid);
743 if (reqkey == NULL) {
744 g_dbus_method_invocation_return_value(invocation,
745 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
750 if (_push_queue(target_uid, reqkey, REQUEST_TYPE_DISABLE_APP, "default",
752 g_dbus_method_invocation_return_value(invocation,
753 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
758 g_dbus_method_invocation_return_value(invocation,
759 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
770 static int __handle_request_enable_global_app_for_uid(uid_t uid,
771 GDBusMethodInvocation *invocation, GVariant *parameters)
773 uid_t target_uid = (uid_t)-1;
778 g_variant_get(parameters, "(u&s)", &target_uid, &appid);
779 if (target_uid == (uid_t)-1 || appid == NULL) {
780 g_dbus_method_invocation_return_value(invocation,
781 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
785 reqkey = __generate_reqkey(appid);
786 if (reqkey == NULL) {
787 g_dbus_method_invocation_return_value(invocation,
788 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
793 if (_push_queue(target_uid, reqkey,
794 REQUEST_TYPE_ENABLE_GLOBAL_APP_FOR_UID,
795 "default", appid, NULL)) {
796 g_dbus_method_invocation_return_value(invocation,
797 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
802 g_dbus_method_invocation_return_value(invocation,
803 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
814 static int __handle_request_disable_global_app_for_uid(uid_t uid,
815 GDBusMethodInvocation *invocation, GVariant *parameters)
817 uid_t target_uid = (uid_t)-1;
822 g_variant_get(parameters, "(u&s)", &target_uid, &appid);
823 if (target_uid == (uid_t)-1 || appid == NULL) {
824 g_dbus_method_invocation_return_value(invocation,
825 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
829 reqkey = __generate_reqkey(appid);
830 if (reqkey == NULL) {
831 g_dbus_method_invocation_return_value(invocation,
832 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
837 if (_push_queue(target_uid, reqkey,
838 REQUEST_TYPE_DISABLE_GLOBAL_APP_FOR_UID,
839 "default", appid, NULL)) {
840 g_dbus_method_invocation_return_value(invocation,
841 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
846 g_dbus_method_invocation_return_value(invocation,
847 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
858 static int __handle_request_getsize(uid_t uid,
859 GDBusMethodInvocation *invocation, GVariant *parameters)
861 uid_t target_uid = (uid_t)-1;
867 g_variant_get(parameters, "(u&si)", &target_uid, &pkgid, &get_type);
868 if (target_uid == (uid_t)-1 || pkgid == NULL || get_type == -1) {
869 g_dbus_method_invocation_return_value(invocation,
870 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
874 reqkey = __generate_reqkey(pkgid);
875 if (reqkey == NULL) {
876 g_dbus_method_invocation_return_value(invocation,
877 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
881 snprintf(buf, sizeof(buf), "%d", get_type);
882 if (_push_queue(target_uid, reqkey, REQUEST_TYPE_GETSIZE, "pkgtool",
884 g_dbus_method_invocation_return_value(invocation,
885 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
890 g_dbus_method_invocation_return_value(invocation,
891 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
897 static int __handle_request_cleardata(uid_t uid,
898 GDBusMethodInvocation *invocation, GVariant *parameters)
900 uid_t target_uid = (uid_t)-1;
905 g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
906 if (target_uid == (uid_t)-1 || pkgid == NULL) {
907 g_dbus_method_invocation_return_value(invocation,
908 g_variant_new("(i)", PKGMGR_R_ECOMM));
912 pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
913 if (pkgtype == NULL) {
914 g_dbus_method_invocation_return_value(invocation,
915 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
919 reqkey = __generate_reqkey(pkgid);
920 if (reqkey == NULL) {
921 g_dbus_method_invocation_return_value(invocation,
922 g_variant_new("(i)", PKGMGR_R_ENOMEM));
927 if (_push_queue(target_uid, reqkey, REQUEST_TYPE_CLEARDATA, pkgtype,
929 g_dbus_method_invocation_return_value(invocation,
930 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
936 g_dbus_method_invocation_return_value(invocation,
937 g_variant_new("(i)", PKGMGR_R_OK));
945 static int __handle_request_clearcache(uid_t uid,
946 GDBusMethodInvocation *invocation, GVariant *parameters)
948 uid_t target_uid = (uid_t)-1;
951 g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
952 if (target_uid == (uid_t)-1 || pkgid == NULL) {
953 g_dbus_method_invocation_return_value(invocation,
954 g_variant_new("(i)", PKGMGR_R_ECOMM));
958 if (_push_queue(target_uid, NULL, REQUEST_TYPE_CLEARCACHE,
959 "pkgtool", pkgid, NULL)) {
960 g_dbus_method_invocation_return_value(invocation,
961 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
965 g_dbus_method_invocation_return_value(invocation,
966 g_variant_new("(i)", PKGMGR_R_OK));
971 static int __handle_request_kill(uid_t uid,
972 GDBusMethodInvocation *invocation, GVariant *parameters)
974 uid_t target_uid = (uid_t)-1;
978 g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
979 if (target_uid == (uid_t)-1 || pkgid == NULL) {
980 g_dbus_method_invocation_return_value(invocation,
981 g_variant_new("(ii)", PKGMGR_R_ECOMM, 0));
985 reqkey = __generate_reqkey(pkgid);
986 if (reqkey == NULL) {
987 g_dbus_method_invocation_return_value(invocation,
988 g_variant_new("(ii)", PKGMGR_R_ENOMEM, 0));
992 if (_push_queue(target_uid, reqkey, REQUEST_TYPE_KILL,
993 "default", pkgid, NULL)) {
994 g_dbus_method_invocation_return_value(invocation,
995 g_variant_new("(ii)", PKGMGR_R_ESYSTEM, 0));
1000 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1001 (gpointer)invocation))
1002 ERR("reqkey already exists");
1007 static int __handle_request_check(uid_t uid,
1008 GDBusMethodInvocation *invocation, GVariant *parameters)
1010 uid_t target_uid = (uid_t)-1;
1012 char *reqkey = NULL;
1014 g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
1015 if (target_uid == (uid_t)-1 || pkgid == NULL) {
1016 g_dbus_method_invocation_return_value(invocation,
1017 g_variant_new("(ii)", PKGMGR_R_ECOMM, 0));
1021 reqkey = __generate_reqkey(pkgid);
1022 if (reqkey == NULL) {
1023 g_dbus_method_invocation_return_value(invocation,
1024 g_variant_new("(ii)", PKGMGR_R_ENOMEM, 0));
1028 if (_push_queue(target_uid, reqkey, REQUEST_TYPE_CHECK,
1029 "default", pkgid, NULL)) {
1030 g_dbus_method_invocation_return_value(invocation,
1031 g_variant_new("(ii)", PKGMGR_R_ESYSTEM, 0));
1036 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1037 (gpointer)invocation))
1038 ERR("reqkey already exists");
1043 static int __handle_request_generate_license_request(uid_t uid,
1044 GDBusMethodInvocation *invocation, GVariant *parameters)
1047 char *resp_data = NULL;
1049 g_variant_get(parameters, "(&s)", &resp_data);
1050 if (resp_data == NULL) {
1051 g_dbus_method_invocation_return_value(invocation,
1052 g_variant_new("(iss)", PKGMGR_R_ECOMM, "", ""));
1056 reqkey = __generate_reqkey("drm");
1057 if (reqkey == NULL) {
1058 g_dbus_method_invocation_return_value(invocation,
1059 g_variant_new("(iss)", PKGMGR_R_ENOMEM, "",
1064 if (_push_queue(uid, reqkey,
1065 REQUEST_TYPE_GENERATE_LICENSE_REQUEST,
1066 "default", NULL, resp_data)) {
1067 g_dbus_method_invocation_return_value(invocation,
1068 g_variant_new("(iss)", PKGMGR_R_ESYSTEM, "",
1074 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1075 (gpointer)invocation))
1076 ERR("reqkey already exists");
1081 static int __handle_request_register_license(uid_t uid,
1082 GDBusMethodInvocation *invocation, GVariant *parameters)
1085 char *resp_data = NULL;
1087 g_variant_get(parameters, "(&s)", &resp_data);
1088 if (resp_data == NULL) {
1089 g_dbus_method_invocation_return_value(invocation,
1090 g_variant_new("(i)", PKGMGR_R_ECOMM));
1094 reqkey = __generate_reqkey("drm");
1095 if (reqkey == NULL) {
1096 g_dbus_method_invocation_return_value(invocation,
1097 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1101 if (_push_queue(uid, reqkey, REQUEST_TYPE_REGISTER_LICENSE,
1102 "default", NULL, resp_data)) {
1103 g_dbus_method_invocation_return_value(invocation,
1104 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1109 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1110 (gpointer)invocation))
1111 ERR("reqkey already exists");
1116 static int __handle_request_decrypt_package(uid_t uid,
1117 GDBusMethodInvocation *invocation, GVariant *parameters)
1120 char *drm_file_path = NULL;
1121 char *decrypted_file_path = NULL;
1123 g_variant_get(parameters, "(&s&s)", &drm_file_path,
1124 &decrypted_file_path);
1125 if (drm_file_path == NULL || decrypted_file_path == NULL) {
1126 g_dbus_method_invocation_return_value(invocation,
1127 g_variant_new("(i)", PKGMGR_R_ECOMM));
1131 reqkey = __generate_reqkey("drm");
1132 if (reqkey == NULL) {
1133 g_dbus_method_invocation_return_value(invocation,
1134 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1138 if (_push_queue(uid, reqkey, REQUEST_TYPE_DECRYPT_PACKAGE,
1139 "default", drm_file_path,
1140 decrypted_file_path)) {
1141 g_dbus_method_invocation_return_value(invocation,
1142 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1147 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1148 (gpointer)invocation))
1149 ERR("reqkey already exists");
1154 static int __update_app_splash_screen(uid_t uid,
1155 GDBusMethodInvocation *invocation, GVariant *parameters,
1158 uid_t target_uid = (uid_t)-1;
1162 g_variant_get(parameters, "(u&s)", &target_uid, &appid);
1163 if (target_uid == (uid_t)-1 || appid == NULL) {
1164 ERR("target_uid: %d, appid: %s", target_uid, appid);
1165 g_dbus_method_invocation_return_value(invocation,
1166 g_variant_new("(i)", PKGMGR_R_ECOMM));
1170 reqkey = __generate_reqkey(appid);
1171 if (reqkey == NULL) {
1172 ERR("Failed to generate request key");
1173 g_dbus_method_invocation_return_value(invocation,
1174 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1178 if (_push_queue(target_uid, reqkey, req_type, "default",
1180 ERR("Failed to push request");
1181 g_dbus_method_invocation_return_value(invocation,
1182 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1187 g_dbus_method_invocation_return_value(invocation,
1188 g_variant_new("(i)", PKGMGR_R_OK));
1196 static int __handle_request_enable_app_splash_screen(uid_t uid,
1197 GDBusMethodInvocation *invocation, GVariant *parameters)
1199 return __update_app_splash_screen(uid, invocation, parameters,
1200 REQUEST_TYPE_ENABLE_APP_SPLASH_SCREEN);
1203 static int __handle_request_disable_app_splash_screen(uid_t uid,
1204 GDBusMethodInvocation *invocation, GVariant *parameters)
1206 return __update_app_splash_screen(uid, invocation, parameters,
1207 REQUEST_TYPE_DISABLE_APP_SPLASH_SCREEN);
1210 static int __handle_request_set_restriction_mode(uid_t uid,
1211 GDBusMethodInvocation *invocation, GVariant *parameters)
1213 uid_t target_uid = (uid_t)-1;
1219 g_variant_get(parameters, "(usi)", &target_uid, &pkgid, &mode);
1220 if (target_uid == (uid_t)-1 || pkgid == NULL || mode < 0) {
1221 g_dbus_method_invocation_return_value(invocation,
1222 g_variant_new("(i)", PKGMGR_R_ECOMM));
1226 reqkey = __generate_reqkey("restriction");
1227 if (reqkey == NULL) {
1228 g_dbus_method_invocation_return_value(invocation,
1229 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1233 snprintf(buf, sizeof(buf), "%d", mode);
1234 if (_push_queue(target_uid, reqkey,
1235 REQUEST_TYPE_SET_RESTRICTION_MODE,
1236 "default", pkgid, buf)) {
1237 g_dbus_method_invocation_return_value(invocation,
1238 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1243 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1244 (gpointer)invocation))
1245 ERR("reqkey already exists");
1250 static int __handle_request_unset_restriction_mode(uid_t uid,
1251 GDBusMethodInvocation *invocation, GVariant *parameters)
1253 uid_t target_uid = (uid_t)-1;
1259 g_variant_get(parameters, "(usi)", &target_uid, &pkgid, &mode);
1260 if (target_uid == (uid_t)-1 || pkgid == NULL || mode < 0) {
1261 g_dbus_method_invocation_return_value(invocation,
1262 g_variant_new("(i)", PKGMGR_R_ECOMM));
1266 reqkey = __generate_reqkey("restriction");
1267 if (reqkey == NULL) {
1268 g_dbus_method_invocation_return_value(invocation,
1269 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1273 snprintf(buf, sizeof(buf), "%d", mode);
1274 if (_push_queue(target_uid, reqkey,
1275 REQUEST_TYPE_UNSET_RESTRICTION_MODE,
1276 "default", pkgid, buf)) {
1277 g_dbus_method_invocation_return_value(invocation,
1278 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1283 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1284 (gpointer)invocation))
1285 ERR("reqkey already exists");
1290 static int __handle_request_get_restriction_mode(uid_t uid,
1291 GDBusMethodInvocation *invocation, GVariant *parameters)
1293 uid_t target_uid = (uid_t)-1;
1297 g_variant_get(parameters, "(us)", &target_uid, &pkgid);
1298 if (target_uid == (uid_t)-1 || pkgid == NULL) {
1299 g_dbus_method_invocation_return_value(invocation,
1300 g_variant_new("(i)", PKGMGR_R_ECOMM));
1304 reqkey = __generate_reqkey("restriction");
1305 if (reqkey == NULL) {
1306 g_dbus_method_invocation_return_value(invocation,
1307 g_variant_new("(ii)", -1, PKGMGR_R_ENOMEM));
1311 if (_push_queue(target_uid, reqkey,
1312 REQUEST_TYPE_GET_RESTRICTION_MODE,
1313 "default", pkgid, NULL)) {
1314 g_dbus_method_invocation_return_value(invocation,
1315 g_variant_new("(ii)", -1, PKGMGR_R_ESYSTEM));
1320 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1321 (gpointer)invocation))
1322 ERR("reqkey already exists");
1327 static uid_t __get_caller_uid(GDBusConnection *connection, const char *name)
1333 result = g_dbus_connection_call_sync(connection,
1334 "org.freedesktop.DBus", "/org/freedesktop/DBus",
1335 "org.freedesktop.DBus", "GetConnectionUnixUser",
1336 g_variant_new("(s)", name), NULL,
1337 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
1338 if (result == NULL) {
1339 ERR("failed to get caller uid: %s", err->message);
1344 g_variant_get(result, "(u)", &uid);
1349 static void __handle_method_call(GDBusConnection *connection,
1350 const gchar *sender, const gchar *object_path,
1351 const gchar *interface_name, const gchar *method_name,
1352 GVariant *parameters, GDBusMethodInvocation *invocation,
1358 uid = __get_caller_uid(connection,
1359 g_dbus_method_invocation_get_sender(invocation));
1360 if (uid == (uid_t)-1)
1363 if (__check_caller_permission(uid, invocation, parameters))
1366 if (g_strcmp0(method_name, "install") == 0)
1367 ret = __handle_request_install(uid, invocation, parameters);
1368 else if (g_strcmp0(method_name, "mount_install") == 0)
1369 ret = __handle_request_mount_install(uid, invocation,
1371 else if (g_strcmp0(method_name, "reinstall") == 0)
1372 ret = __handle_request_reinstall(uid, invocation, parameters);
1373 else if (g_strcmp0(method_name, "uninstall") == 0)
1374 ret = __handle_request_uninstall(uid, invocation, parameters);
1375 else if (g_strcmp0(method_name, "cleardata") == 0)
1376 ret = __handle_request_cleardata(uid, invocation, parameters);
1377 else if (g_strcmp0(method_name, "move") == 0)
1378 ret = __handle_request_move(uid, invocation, parameters);
1379 else if (g_strcmp0(method_name, "enable_pkgs") == 0)
1380 ret = __handle_request_enable_pkgs(uid, invocation, parameters);
1381 else if (g_strcmp0(method_name, "disable_pkgs") == 0)
1382 ret = __handle_request_disable_pkgs(uid, invocation, parameters);
1383 else if (g_strcmp0(method_name, "getsize") == 0)
1384 ret = __handle_request_getsize(uid, invocation, parameters);
1385 else if (g_strcmp0(method_name, "clearcache") == 0)
1386 ret = __handle_request_clearcache(uid, invocation, parameters);
1387 else if (g_strcmp0(method_name, "enable_app") == 0)
1388 ret = __handle_request_enable_app(uid, invocation, parameters);
1389 else if (g_strcmp0(method_name, "disable_app") == 0)
1390 ret = __handle_request_disable_app(uid, invocation, parameters);
1391 else if (g_strcmp0(method_name, "enable_global_app_for_uid") == 0)
1392 ret = __handle_request_enable_global_app_for_uid(uid,
1393 invocation, parameters);
1394 else if (g_strcmp0(method_name, "disable_global_app_for_uid") == 0)
1395 ret = __handle_request_disable_global_app_for_uid(uid,
1396 invocation, parameters);
1397 else if (g_strcmp0(method_name, "kill") == 0)
1398 ret = __handle_request_kill(uid, invocation, parameters);
1399 else if (g_strcmp0(method_name, "check") == 0)
1400 ret = __handle_request_check(uid, invocation, parameters);
1401 else if (g_strcmp0(method_name, "generate_license_request") == 0)
1402 ret = __handle_request_generate_license_request(uid, invocation,
1404 else if (g_strcmp0(method_name, "register_license") == 0)
1405 ret = __handle_request_register_license(uid, invocation,
1407 else if (g_strcmp0(method_name, "decrypt_package") == 0)
1408 ret = __handle_request_decrypt_package(uid, invocation,
1410 else if (g_strcmp0(method_name, "disable_app_splash_screen") == 0)
1411 ret = __handle_request_disable_app_splash_screen(uid,
1412 invocation, parameters);
1413 else if (g_strcmp0(method_name, "enable_app_splash_screen") == 0)
1414 ret = __handle_request_enable_app_splash_screen(uid,
1415 invocation, parameters);
1416 else if (g_strcmp0(method_name, "set_restriction_mode") == 0)
1417 ret = __handle_request_set_restriction_mode(uid, invocation,
1419 else if (g_strcmp0(method_name, "unset_restriction_mode") == 0)
1420 ret = __handle_request_unset_restriction_mode(uid, invocation,
1422 else if (g_strcmp0(method_name, "get_restriction_mode") == 0)
1423 ret = __handle_request_get_restriction_mode(uid, invocation,
1429 g_idle_add(queue_job, NULL);
1432 int _return_value_to_caller(const char *req_key, GVariant *result)
1434 GDBusMethodInvocation *invocation;
1436 invocation = (GDBusMethodInvocation *)g_hash_table_lookup(req_table,
1438 if (invocation == NULL) {
1439 ERR("no such request id");
1443 g_dbus_method_invocation_return_value(invocation, result);
1444 g_hash_table_remove(req_table, (gpointer)req_key);
1449 static const GDBusInterfaceVTable interface_vtable = {
1450 __handle_method_call,
1455 static void __on_bus_acquired(GDBusConnection *connection, const gchar *name,
1460 DBG("on bus acquired");
1462 reg_id = g_dbus_connection_register_object(connection,
1463 PKGMGR_DBUS_OBJECT_PATH,
1464 instropection_data->interfaces[0],
1465 &interface_vtable, NULL, NULL, &err);
1468 ERR("failed to register object: %s", err->message);
1473 static void __on_name_acquired(GDBusConnection *connection, const gchar *name,
1476 DBG("on name acquired: %s", name);
1479 static void __on_name_lost(GDBusConnection *connection, const gchar *name,
1482 DBG("on name lost: %s", name);
1485 int _init_request_handler(void)
1487 instropection_data = g_dbus_node_info_new_for_xml(instropection_xml,
1490 owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, PKGMGR_DBUS_SERVICE,
1491 G_BUS_NAME_OWNER_FLAGS_NONE, __on_bus_acquired,
1492 __on_name_acquired, __on_name_lost, NULL, NULL);
1494 req_table = g_hash_table_new_full(g_str_hash, g_str_equal,
1496 if (req_table == NULL)
1502 void _fini_request_handler(void)
1504 g_hash_table_destroy(req_table);
1505 g_bus_unown_name(owner_id);
1506 g_dbus_node_info_unref(instropection_data);