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'/>"
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'/>"
171 static GDBusNodeInfo *instropection_data;
173 static guint owner_id;
174 static GHashTable *req_table;
176 static char *__generate_reqkey(const char *pkgid)
180 char timestr[MAX_PKG_ARGS_LEN];
184 gettimeofday(&tv, NULL);
185 curtime = tv.tv_sec * 1000000 + tv.tv_usec;
186 snprintf(timestr, sizeof(timestr), "%ld", curtime);
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");
194 snprintf(str_req_key, size, "%s_%s", pkgid, timestr);
199 static int __is_admin_user(uid_t uid)
202 GumUserType ut = GUM_USERTYPE_NONE;
206 guser = gum_user_get_sync(uid, FALSE);
208 ERR("cannot get user information from gumd, retry");
210 usleep(RETRY_WAIT_USEC);
214 } while (retry_cnt <= RETRY_MAX);
217 ERR("cannot get user information from gumd, failed");
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);
226 } else if (ut != GUM_USERTYPE_ADMIN) {
227 g_object_unref(guser);
231 g_object_unref(guser);
236 #define REGULAR_USER 5000
237 static int __check_caller_permission(uid_t uid,
238 GDBusMethodInvocation *invocation, GVariant *parameters)
244 if (uid < REGULAR_USER)
247 v = g_variant_get_child_value(parameters, 0);
249 g_dbus_method_invocation_return_error_literal(invocation,
250 G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
255 target_uid = g_variant_get_uint32(v);
257 if (uid == target_uid)
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,
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 "
277 static int __handle_request_install(uid_t caller_uid,
278 GDBusMethodInvocation *invocation, GVariant *parameters)
280 uid_t target_uid = (uid_t)-1;
282 char *pkgpath = NULL;
285 gchar **tmp_args = NULL;
292 g_variant_get(parameters, "(u&s@as)", &target_uid, &pkgpath, &value);
293 tmp_args = (gchar **)g_variant_get_strv(value, &args_count);
295 for (i = 0; i < args_count; i++)
296 len = len + strlen(tmp_args[i]) + 1;
298 args = (char *)calloc(len, sizeof(char));
300 ERR("calloc failed");
301 g_dbus_method_invocation_return_value(invocation,
302 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
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(" "));
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, ""));
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, ""));
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, ""));
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, ""));
344 g_dbus_method_invocation_return_value(invocation,
345 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
362 static int __handle_request_mount_install(uid_t caller_uid,
363 GDBusMethodInvocation *invocation, GVariant *parameters)
365 uid_t target_uid = (uid_t)-1;
367 char *pkgpath = NULL;
370 gchar **tmp_args = NULL;
377 g_variant_get(parameters, "(u&s@as)", &target_uid, &pkgpath, &value);
378 tmp_args = (gchar **)g_variant_get_strv(value, &args_count);
380 for (i = 0; i < args_count; i++)
381 len = len + strlen(tmp_args[i]) + 1;
383 args = (char *)calloc(len, sizeof(char));
385 ERR("calloc failed");
386 g_dbus_method_invocation_return_value(invocation,
387 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
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(" "));
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, ""));
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, ""));
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, ""));
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, ""));
430 g_dbus_method_invocation_return_value(invocation,
431 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
447 static int __handle_request_reinstall(uid_t caller_uid,
448 GDBusMethodInvocation *invocation, GVariant *parameters)
450 uid_t target_uid = (uid_t)-1;
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, ""));
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, ""));
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, ""));
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, ""));
485 g_dbus_method_invocation_return_value(invocation,
486 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
493 static int __handle_request_uninstall(uid_t caller_uid,
494 GDBusMethodInvocation *invocation, GVariant *parameters)
496 uid_t target_uid = (uid_t)-1;
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, ""));
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, ""));
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, ""));
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, ""));
531 g_dbus_method_invocation_return_value(invocation,
532 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
539 static int __handle_request_move(uid_t caller_uid,
540 GDBusMethodInvocation *invocation, GVariant *parameters)
542 uid_t target_uid = (uid_t)-1;
547 char buf[4] = { '\0' };
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, ""));
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, ""));
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, ""));
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, ""));
581 g_dbus_method_invocation_return_value(invocation,
582 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
589 static int __handle_request_enable_pkgs(uid_t caller_uid,
590 GDBusMethodInvocation *invocation, GVariant *parameters)
592 uid_t target_uid = (uid_t)-1;
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, ""));
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, ""));
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, ""));
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, ""));
634 g_dbus_method_invocation_return_value(invocation,
635 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
641 static int __handle_request_disable_pkgs(uid_t caller_uid,
642 GDBusMethodInvocation *invocation, GVariant *parameters)
644 uid_t target_uid = (uid_t)-1;
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, ""));
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, ""));
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, ""));
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, ""));
686 g_dbus_method_invocation_return_value(invocation,
687 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
693 static int __handle_request_enable_app(uid_t caller_uid,
694 GDBusMethodInvocation *invocation, GVariant *parameters)
696 uid_t target_uid = (uid_t)-1;
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, ""));
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, ""));
716 if (_push_queue(target_uid, caller_uid, reqkey,
717 REQUEST_TYPE_ENABLE_APP, "default",
719 g_dbus_method_invocation_return_value(invocation,
720 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
725 g_dbus_method_invocation_return_value(invocation,
726 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
737 static int __handle_request_disable_app(uid_t caller_uid,
738 GDBusMethodInvocation *invocation, GVariant *parameters)
740 uid_t target_uid = (uid_t)-1;
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, ""));
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, ""));
760 if (_push_queue(target_uid, caller_uid, reqkey,
761 REQUEST_TYPE_DISABLE_APP, "default",
763 g_dbus_method_invocation_return_value(invocation,
764 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
769 g_dbus_method_invocation_return_value(invocation,
770 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
781 static int __handle_request_enable_global_app_for_uid(uid_t caller_uid,
782 GDBusMethodInvocation *invocation, GVariant *parameters)
784 uid_t target_uid = (uid_t)-1;
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, ""));
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, ""));
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, ""));
813 g_dbus_method_invocation_return_value(invocation,
814 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
825 static int __handle_request_disable_global_app_for_uid(uid_t caller_uid,
826 GDBusMethodInvocation *invocation, GVariant *parameters)
828 uid_t target_uid = (uid_t)-1;
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, ""));
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, ""));
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, ""));
857 g_dbus_method_invocation_return_value(invocation,
858 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
869 static int __handle_request_getsize(uid_t caller_uid,
870 GDBusMethodInvocation *invocation, GVariant *parameters)
872 uid_t target_uid = (uid_t)-1;
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, ""));
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, ""));
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, ""));
901 g_dbus_method_invocation_return_value(invocation,
902 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
908 static int __handle_request_cleardata(uid_t caller_uid,
909 GDBusMethodInvocation *invocation, GVariant *parameters)
911 uid_t target_uid = (uid_t)-1;
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));
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));
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));
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));
947 g_dbus_method_invocation_return_value(invocation,
948 g_variant_new("(i)", PKGMGR_R_OK));
956 static int __handle_request_clearcache(uid_t caller_uid,
957 GDBusMethodInvocation *invocation, GVariant *parameters)
959 uid_t target_uid = (uid_t)-1;
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));
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));
976 g_dbus_method_invocation_return_value(invocation,
977 g_variant_new("(i)", PKGMGR_R_OK));
982 static int __handle_request_kill(uid_t caller_uid,
983 GDBusMethodInvocation *invocation, GVariant *parameters)
985 uid_t target_uid = (uid_t)-1;
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));
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));
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));
1011 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1012 (gpointer)invocation))
1013 ERR("reqkey already exists");
1018 static int __handle_request_check(uid_t caller_uid,
1019 GDBusMethodInvocation *invocation, GVariant *parameters)
1021 uid_t target_uid = (uid_t)-1;
1023 char *reqkey = NULL;
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));
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));
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));
1047 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1048 (gpointer)invocation))
1049 ERR("reqkey already exists");
1054 static int __handle_request_generate_license_request(uid_t caller_uid,
1055 GDBusMethodInvocation *invocation, GVariant *parameters)
1058 char *resp_data = NULL;
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, "", ""));
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, "",
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, "",
1085 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1086 (gpointer)invocation))
1087 ERR("reqkey already exists");
1092 static int __handle_request_register_license(uid_t caller_uid,
1093 GDBusMethodInvocation *invocation, GVariant *parameters)
1096 char *resp_data = NULL;
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));
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));
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));
1121 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1122 (gpointer)invocation))
1123 ERR("reqkey already exists");
1128 static int __handle_request_decrypt_package(uid_t caller_uid,
1129 GDBusMethodInvocation *invocation, GVariant *parameters)
1132 char *drm_file_path = NULL;
1133 char *decrypted_file_path = NULL;
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));
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));
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));
1160 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1161 (gpointer)invocation))
1162 ERR("reqkey already exists");
1167 static int __update_app_splash_screen(uid_t caller_uid,
1168 GDBusMethodInvocation *invocation, GVariant *parameters,
1171 uid_t target_uid = (uid_t)-1;
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));
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));
1191 if (_push_queue(target_uid, caller_uid, reqkey, req_type, "default",
1193 ERR("Failed to push request");
1194 g_dbus_method_invocation_return_value(invocation,
1195 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1200 g_dbus_method_invocation_return_value(invocation,
1201 g_variant_new("(i)", PKGMGR_R_OK));
1209 static int __handle_request_enable_app_splash_screen(uid_t caller_uid,
1210 GDBusMethodInvocation *invocation, GVariant *parameters)
1212 return __update_app_splash_screen(caller_uid, invocation, parameters,
1213 REQUEST_TYPE_ENABLE_APP_SPLASH_SCREEN);
1216 static int __handle_request_disable_app_splash_screen(uid_t caller_uid,
1217 GDBusMethodInvocation *invocation, GVariant *parameters)
1219 return __update_app_splash_screen(caller_uid, invocation, parameters,
1220 REQUEST_TYPE_DISABLE_APP_SPLASH_SCREEN);
1223 static int __handle_request_set_restriction_mode(uid_t caller_uid,
1224 GDBusMethodInvocation *invocation, GVariant *parameters)
1226 uid_t target_uid = (uid_t)-1;
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));
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));
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));
1256 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1257 (gpointer)invocation))
1258 ERR("reqkey already exists");
1263 static int __handle_request_unset_restriction_mode(uid_t caller_uid,
1264 GDBusMethodInvocation *invocation, GVariant *parameters)
1266 uid_t target_uid = (uid_t)-1;
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));
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));
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));
1296 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1297 (gpointer)invocation))
1298 ERR("reqkey already exists");
1303 static int __handle_request_get_restriction_mode(uid_t caller_uid,
1304 GDBusMethodInvocation *invocation, GVariant *parameters)
1306 uid_t target_uid = (uid_t)-1;
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));
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));
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));
1333 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1334 (gpointer)invocation))
1335 ERR("reqkey already exists");
1340 static int __handle_request_set_app_label(uid_t uid,
1341 GDBusMethodInvocation *invocation, GVariant *parameters)
1343 uid_t target_uid = (uid_t)-1;
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));
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));
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));
1371 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1372 (gpointer)invocation))
1373 ERR("reqkey already exists");
1378 static uid_t __get_caller_uid(GDBusConnection *connection, const char *name)
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);
1395 g_variant_get(result, "(u)", &uid);
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,
1409 uid = __get_caller_uid(connection,
1410 g_dbus_method_invocation_get_sender(invocation));
1411 if (uid == (uid_t)-1)
1414 if (__check_caller_permission(uid, invocation, parameters))
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,
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,
1455 else if (g_strcmp0(method_name, "register_license") == 0)
1456 ret = __handle_request_register_license(uid, invocation,
1458 else if (g_strcmp0(method_name, "decrypt_package") == 0)
1459 ret = __handle_request_decrypt_package(uid, invocation,
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,
1470 else if (g_strcmp0(method_name, "unset_restriction_mode") == 0)
1471 ret = __handle_request_unset_restriction_mode(uid, invocation,
1473 else if (g_strcmp0(method_name, "get_restriction_mode") == 0)
1474 ret = __handle_request_get_restriction_mode(uid, invocation,
1476 else if (g_strcmp0(method_name, "set_app_label") == 0)
1477 ret = __handle_request_set_app_label(uid, invocation, parameters);
1482 g_idle_add(queue_job, NULL);
1485 int _return_value_to_caller(const char *req_key, GVariant *result)
1487 GDBusMethodInvocation *invocation;
1489 invocation = (GDBusMethodInvocation *)g_hash_table_lookup(req_table,
1491 if (invocation == NULL) {
1492 ERR("no such request id");
1496 g_dbus_method_invocation_return_value(invocation, result);
1497 g_hash_table_remove(req_table, (gpointer)req_key);
1502 static const GDBusInterfaceVTable interface_vtable = {
1503 __handle_method_call,
1508 static void __on_bus_acquired(GDBusConnection *connection, const gchar *name,
1513 DBG("on bus acquired");
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);
1521 ERR("failed to register object: %s", err->message);
1526 static void __on_name_acquired(GDBusConnection *connection, const gchar *name,
1529 DBG("on name acquired: %s", name);
1532 static void __on_name_lost(GDBusConnection *connection, const gchar *name,
1535 DBG("on name lost: %s", name);
1538 int _init_request_handler(void)
1540 instropection_data = g_dbus_node_info_new_for_xml(instropection_xml,
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);
1547 req_table = g_hash_table_new_full(g_str_hash, g_str_equal,
1549 if (req_table == NULL)
1555 void _fini_request_handler(void)
1557 g_hash_table_destroy(req_table);
1558 g_bus_unown_name(owner_id);
1559 g_dbus_node_info_unref(instropection_data);