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='pkgtype' direction='in'/>"
25 " <arg type='s' name='pkgpath' direction='in'/>"
26 " <arg type='as' name='args' direction='in'/>"
27 " <arg type='i' name='ret' direction='out'/>"
28 " <arg type='s' name='reqkey' direction='out'/>"
30 " <method name='reinstall'>"
31 " <arg type='u' name='uid' direction='in'/>"
32 " <arg type='s' name='pkgid' direction='in'/>"
33 " <arg type='i' name='ret' direction='out'/>"
34 " <arg type='s' name='reqkey' direction='out'/>"
36 " <method name='mount_install'>"
37 " <arg type='u' name='uid' direction='in'/>"
38 " <arg type='s' name='pkgtype' direction='in'/>"
39 " <arg type='s' name='pkgpath' direction='in'/>"
40 " <arg type='as' name='args' direction='in'/>"
41 " <arg type='i' name='ret' direction='out'/>"
42 " <arg type='s' name='reqkey' direction='out'/>"
44 " <method name='uninstall'>"
45 " <arg type='u' name='uid' direction='in'/>"
46 " <arg type='s' name='pkgid' direction='in'/>"
47 " <arg type='i' name='ret' direction='out'/>"
48 " <arg type='s' name='reqkey' direction='out'/>"
50 " <method name='move'>"
51 " <arg type='u' name='uid' direction='in'/>"
52 " <arg type='s' name='pkgid' direction='in'/>"
53 " <arg type='i' name='movetype' direction='in'/>"
54 " <arg type='i' name='ret' direction='out'/>"
55 " <arg type='s' name='reqkey' direction='out'/>"
57 " <method name='enable_pkgs'>"
58 " <arg type='u' name='uid' direction='in'/>"
59 " <arg type='as' name='pkgids' direction='in'/>"
60 " <arg type='i' name='ret' direction='out'/>"
61 " <arg type='s' name='reqkey' direction='out'/>"
63 " <method name='disable_pkgs'>"
64 " <arg type='u' name='uid' direction='in'/>"
65 " <arg type='as' name='pkgids' direction='in'/>"
66 " <arg type='i' name='ret' direction='out'/>"
67 " <arg type='s' name='reqkey' direction='out'/>"
69 " <method name='enable_app'>"
70 " <arg type='u' name='uid' direction='in'/>"
71 " <arg type='s' name='appid' direction='in'/>"
72 " <arg type='i' name='ret' direction='out'/>"
73 " <arg type='s' name='reqkey' direction='out'/>"
75 " <method name='disable_app'>"
76 " <arg type='u' name='uid' direction='in'/>"
77 " <arg type='s' name='appid' direction='in'/>"
78 " <arg type='i' name='ret' direction='out'/>"
79 " <arg type='s' name='reqkey' direction='out'/>"
81 " <method name='enable_global_app_for_uid'>"
82 " <arg type='u' name='uid' direction='in'/>"
83 " <arg type='s' name='appid' direction='in'/>"
84 " <arg type='i' name='ret' direction='out'/>"
85 " <arg type='s' name='reqkey' direction='out'/>"
87 " <method name='disable_global_app_for_uid'>"
88 " <arg type='u' name='uid' direction='in'/>"
89 " <arg type='s' name='appid' direction='in'/>"
90 " <arg type='i' name='ret' direction='out'/>"
91 " <arg type='s' name='reqkey' direction='out'/>"
93 " <method name='getsize'>"
94 " <arg type='u' name='uid' direction='in'/>"
95 " <arg type='s' name='pkgid' direction='in'/>"
96 " <arg type='i' name='get_type' direction='in'/>"
97 " <arg type='i' name='ret' direction='out'/>"
98 " <arg type='s' name='reqkey' direction='out'/>"
100 " <method name='cleardata'>"
101 " <arg type='u' name='uid' direction='in'/>"
102 " <arg type='s' name='pkgid' direction='in'/>"
103 " <arg type='i' name='ret' direction='out'/>"
105 " <method name='clearcache'>"
106 " <arg type='u' name='uid' direction='in'/>"
107 " <arg type='s' name='pkgid' direction='in'/>"
108 " <arg type='i' name='ret' direction='out'/>"
110 " <method name='kill'>"
111 " <arg type='u' name='uid' direction='in'/>"
112 " <arg type='s' name='pkgid' direction='in'/>"
113 " <arg type='i' name='ret' direction='out'/>"
114 " <arg type='i' name='pid' direction='out'/>"
116 " <method name='check'>"
117 " <arg type='u' name='uid' direction='in'/>"
118 " <arg type='s' name='pkgid' direction='in'/>"
119 " <arg type='i' name='ret' direction='out'/>"
120 " <arg type='i' name='pid' direction='out'/>"
122 " <method name='generate_license_request'>"
123 " <arg type='s' name='resp_data' direction='in'/>"
124 " <arg type='i' name='ret' direction='out'/>"
125 " <arg type='s' name='req_data' direction='out'/>"
126 " <arg type='s' name='license_url' direction='out'/>"
128 " <method name='register_license'>"
129 " <arg type='s' name='resp_data' direction='in'/>"
130 " <arg type='i' name='ret' direction='out'/>"
132 " <method name='decrypt_package'>"
133 " <arg type='s' name='drm_file_path' direction='in'/>"
134 " <arg type='s' name='decrypted_file_path' direction='in'/>"
135 " <arg type='i' name='ret' direction='out'/>"
137 " <method name='enable_app_splash_screen'>"
138 " <arg type='u' name='uid' direction='in'/>"
139 " <arg type='s' name='appid' direction='in'/>"
140 " <arg type='i' name='ret' direction='out'/>"
142 " <method name='disable_app_splash_screen'>"
143 " <arg type='u' name='uid' direction='in'/>"
144 " <arg type='s' name='appid' direction='in'/>"
145 " <arg type='i' name='ret' direction='out'/>"
147 " <method name='set_restriction_mode'>"
148 " <arg type='u' name='uid' direction='in'/>"
149 " <arg type='s' name='pkgid' direction='in'/>"
150 " <arg type='i' name='mode' direction='in'/>"
151 " <arg type='i' name='ret' direction='out'/>"
153 " <method name='unset_restriction_mode'>"
154 " <arg type='u' name='uid' direction='in'/>"
155 " <arg type='s' name='pkgid' direction='in'/>"
156 " <arg type='i' name='mode' direction='in'/>"
157 " <arg type='i' name='ret' direction='out'/>"
159 " <method name='get_restriction_mode'>"
160 " <arg type='u' name='uid' direction='in'/>"
161 " <arg type='s' name='pkgid' direction='in'/>"
162 " <arg type='i' name='result' direction='out'/>"
163 " <arg type='i' name='ret' direction='out'/>"
165 " <method name='set_app_label'>"
166 " <arg type='u' name='uid' direction='in'/>"
167 " <arg type='s' name='appid' direction='in'/>"
168 " <arg type='s' name='label' direction='in'/>"
169 " <arg type='i' name='ret' direction='out'/>"
173 static GDBusNodeInfo *instropection_data;
175 static guint owner_id;
176 static GHashTable *req_table;
178 static char *__generate_reqkey(const char *pkgid)
182 char timestr[MAX_PKG_ARGS_LEN];
186 gettimeofday(&tv, NULL);
187 curtime = tv.tv_sec * 1000000 + tv.tv_usec;
188 snprintf(timestr, sizeof(timestr), "%ld", curtime);
190 size = strlen(pkgid) + strlen(timestr) + 2;
191 str_req_key = (char *)calloc(size, sizeof(char));
192 if (str_req_key == NULL) {
193 DBG("calloc failed");
196 snprintf(str_req_key, size, "%s_%s", pkgid, timestr);
201 static int __is_admin_user(uid_t uid)
204 GumUserType ut = GUM_USERTYPE_NONE;
208 guser = gum_user_get_sync(uid, FALSE);
210 ERR("cannot get user information from gumd, retry");
212 usleep(RETRY_WAIT_USEC);
216 } while (retry_cnt <= RETRY_MAX);
219 ERR("cannot get user information from gumd, failed");
223 g_object_get(G_OBJECT(guser), "usertype", &ut, NULL);
224 if (ut == GUM_USERTYPE_NONE) {
225 ERR("cannot get user type");
226 g_object_unref(guser);
228 } else if (ut != GUM_USERTYPE_ADMIN) {
229 g_object_unref(guser);
233 g_object_unref(guser);
238 static int __check_caller_permission(uid_t uid,
239 GDBusMethodInvocation *invocation, GVariant *parameters)
245 if (uid < REGULAR_USER)
248 v = g_variant_get_child_value(parameters, 0);
250 g_dbus_method_invocation_return_error_literal(invocation,
251 G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
256 target_uid = g_variant_get_uint32(v);
258 if (uid == target_uid)
261 is_admin = __is_admin_user(uid);
262 if (is_admin == -1) {
263 g_dbus_method_invocation_return_error_literal(invocation,
264 G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
267 } else if (is_admin == 0) {
268 g_dbus_method_invocation_return_error_literal(invocation,
269 G_DBUS_ERROR, G_DBUS_ERROR_ACCESS_DENIED,
270 "Non-admin user cannot request operation to "
278 static int __handle_request_install(uid_t caller_uid,
279 GDBusMethodInvocation *invocation, GVariant *parameters)
281 uid_t target_uid = (uid_t)-1;
282 char *arg_pkgtype = NULL;
284 char *pkgpath = NULL;
287 gchar **tmp_args = NULL;
294 g_variant_get(parameters, "(u&s&s@as)", &target_uid, &arg_pkgtype,
296 tmp_args = (gchar **)g_variant_get_strv(value, &args_count);
298 for (i = 0; i < args_count; i++)
299 len = len + strlen(tmp_args[i]) + 1;
301 args = (char *)calloc(len, sizeof(char));
303 ERR("calloc failed");
304 g_dbus_method_invocation_return_value(invocation,
305 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
310 for (i = 0; i < args_count; i++) {
311 strncat(args, tmp_args[i], strlen(tmp_args[i]));
312 if (i != args_count - 1)
313 strncat(args, " ", strlen(" "));
316 if (target_uid == (uid_t)-1 || pkgpath == NULL) {
317 g_dbus_method_invocation_return_value(invocation,
318 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
323 pkgtype = _get_pkgtype_from_file(pkgpath, caller_uid);
324 if (!pkgtype && arg_pkgtype && strlen(arg_pkgtype))
325 pkgtype = (const char *)arg_pkgtype;
326 if (pkgtype == NULL) {
327 g_dbus_method_invocation_return_value(invocation,
328 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
333 reqkey = __generate_reqkey(pkgpath);
334 if (reqkey == NULL) {
335 g_dbus_method_invocation_return_value(invocation,
336 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
341 if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_INSTALL,
342 pkgtype, pkgpath, args)) {
343 g_dbus_method_invocation_return_value(invocation,
344 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
349 g_dbus_method_invocation_return_value(invocation,
350 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
367 static int __handle_request_mount_install(uid_t caller_uid,
368 GDBusMethodInvocation *invocation, GVariant *parameters)
370 uid_t target_uid = (uid_t)-1;
371 char *arg_pkgtype = NULL;
373 char *pkgpath = NULL;
376 gchar **tmp_args = NULL;
383 g_variant_get(parameters, "(u&s&s@as)", &target_uid, &arg_pkgtype,
385 tmp_args = (gchar **)g_variant_get_strv(value, &args_count);
387 for (i = 0; i < args_count; i++)
388 len = len + strlen(tmp_args[i]) + 1;
390 args = (char *)calloc(len, sizeof(char));
392 ERR("calloc failed");
393 g_dbus_method_invocation_return_value(invocation,
394 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
399 for (i = 0; i < args_count; i++) {
400 strncat(args, tmp_args[i], strlen(tmp_args[i]));
401 if (i != args_count - 1)
402 strncat(args, " ", strlen(" "));
405 if (target_uid == (uid_t)-1 || pkgpath == NULL) {
406 g_dbus_method_invocation_return_value(invocation,
407 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
412 pkgtype = _get_pkgtype_from_file(pkgpath, caller_uid);
413 if (!pkgtype && arg_pkgtype && strlen(arg_pkgtype))
414 pkgtype = (const char *)arg_pkgtype;
415 if (pkgtype == NULL) {
416 g_dbus_method_invocation_return_value(invocation,
417 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
422 reqkey = __generate_reqkey(pkgpath);
423 if (reqkey == NULL) {
424 g_dbus_method_invocation_return_value(invocation,
425 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
430 if (_push_queue(target_uid, caller_uid, reqkey,
431 REQUEST_TYPE_MOUNT_INSTALL,
432 pkgtype, pkgpath, args)) {
433 g_dbus_method_invocation_return_value(invocation,
434 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
439 g_dbus_method_invocation_return_value(invocation,
440 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
456 static int __handle_request_reinstall(uid_t caller_uid,
457 GDBusMethodInvocation *invocation, GVariant *parameters)
459 uid_t target_uid = (uid_t)-1;
464 g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
465 if (target_uid == (uid_t)-1 || pkgid == NULL) {
466 g_dbus_method_invocation_return_value(invocation,
467 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
471 pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
472 if (pkgtype == NULL) {
473 g_dbus_method_invocation_return_value(invocation,
474 g_variant_new("(is)", PKGMGR_R_ENOPKG, ""));
478 reqkey = __generate_reqkey(pkgid);
479 if (reqkey == NULL) {
480 g_dbus_method_invocation_return_value(invocation,
481 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
485 if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_REINSTALL,
486 pkgtype, pkgid, NULL)) {
487 g_dbus_method_invocation_return_value(invocation,
488 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
494 g_dbus_method_invocation_return_value(invocation,
495 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
502 static int __handle_request_uninstall(uid_t caller_uid,
503 GDBusMethodInvocation *invocation, GVariant *parameters)
505 uid_t target_uid = (uid_t)-1;
510 g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
511 if (target_uid == (uid_t)-1 || pkgid == NULL) {
512 g_dbus_method_invocation_return_value(invocation,
513 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
517 pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
518 if (pkgtype == NULL) {
519 g_dbus_method_invocation_return_value(invocation,
520 g_variant_new("(is)", PKGMGR_R_ENOPKG, ""));
524 reqkey = __generate_reqkey(pkgid);
525 if (reqkey == NULL) {
526 g_dbus_method_invocation_return_value(invocation,
527 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
531 if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_UNINSTALL,
532 pkgtype, pkgid, NULL)) {
533 g_dbus_method_invocation_return_value(invocation,
534 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
540 g_dbus_method_invocation_return_value(invocation,
541 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
548 static int __handle_request_move(uid_t caller_uid,
549 GDBusMethodInvocation *invocation, GVariant *parameters)
551 uid_t target_uid = (uid_t)-1;
556 char buf[4] = { '\0' };
558 g_variant_get(parameters, "(u&si)", &target_uid, &pkgid, &move_type);
559 if (target_uid == (uid_t)-1 || pkgid == NULL) {
560 g_dbus_method_invocation_return_value(invocation,
561 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
565 pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
566 if (pkgtype == NULL) {
567 g_dbus_method_invocation_return_value(invocation,
568 g_variant_new("(is)", PKGMGR_R_ENOPKG, ""));
572 reqkey = __generate_reqkey(pkgid);
573 if (reqkey == NULL) {
574 g_dbus_method_invocation_return_value(invocation,
575 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
580 snprintf(buf, sizeof(buf), "%d", move_type);
581 if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_MOVE,
582 pkgtype, pkgid, buf)) {
583 g_dbus_method_invocation_return_value(invocation,
584 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
590 g_dbus_method_invocation_return_value(invocation,
591 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
598 static int __handle_request_enable_pkgs(uid_t caller_uid,
599 GDBusMethodInvocation *invocation, GVariant *parameters)
601 uid_t target_uid = (uid_t)-1;
607 g_variant_get(parameters, "(uas)", &target_uid, &iter);
608 if (target_uid == (uid_t)-1 || iter == NULL) {
609 g_dbus_method_invocation_return_value(invocation,
610 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
614 reqkey = __generate_reqkey("enable_pkgs");
615 if (reqkey == NULL) {
616 g_dbus_method_invocation_return_value(invocation,
617 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
621 while (g_variant_iter_next(iter, "&s", &pkgid)) {
622 pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
623 if (pkgtype == NULL) {
624 g_dbus_method_invocation_return_value(invocation,
625 g_variant_new("(is)",
626 PKGMGR_R_ENOPKG, ""));
630 if (_push_queue(target_uid, caller_uid, reqkey,
631 REQUEST_TYPE_ENABLE_PKG,
632 pkgtype, pkgid, NULL)) {
633 g_dbus_method_invocation_return_value(invocation,
634 g_variant_new("(is)",
635 PKGMGR_R_ESYSTEM, ""));
643 g_dbus_method_invocation_return_value(invocation,
644 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
650 static int __handle_request_disable_pkgs(uid_t caller_uid,
651 GDBusMethodInvocation *invocation, GVariant *parameters)
653 uid_t target_uid = (uid_t)-1;
659 g_variant_get(parameters, "(uas)", &target_uid, &iter);
660 if (target_uid == (uid_t)-1 || iter == NULL) {
661 g_dbus_method_invocation_return_value(invocation,
662 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
666 reqkey = __generate_reqkey("disable_pkgs");
667 if (reqkey == NULL) {
668 g_dbus_method_invocation_return_value(invocation,
669 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
673 while (g_variant_iter_next(iter, "&s", &pkgid)) {
674 pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
675 if (pkgtype == NULL) {
676 g_dbus_method_invocation_return_value(invocation,
677 g_variant_new("(is)",
678 PKGMGR_R_ENOPKG, ""));
682 if (_push_queue(target_uid, caller_uid, reqkey,
683 REQUEST_TYPE_DISABLE_PKG,
684 pkgtype, pkgid, NULL)) {
685 g_dbus_method_invocation_return_value(invocation,
686 g_variant_new("(is)",
687 PKGMGR_R_ESYSTEM, ""));
695 g_dbus_method_invocation_return_value(invocation,
696 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
702 static int __handle_request_enable_app(uid_t caller_uid,
703 GDBusMethodInvocation *invocation, GVariant *parameters)
705 uid_t target_uid = (uid_t)-1;
710 g_variant_get(parameters, "(u&s)", &target_uid, &appid);
711 if (target_uid == (uid_t)-1 || appid == NULL) {
712 g_dbus_method_invocation_return_value(invocation,
713 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
717 reqkey = __generate_reqkey(appid);
718 if (reqkey == NULL) {
719 g_dbus_method_invocation_return_value(invocation,
720 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
725 if (_push_queue(target_uid, caller_uid, reqkey,
726 REQUEST_TYPE_ENABLE_APP, "default",
728 g_dbus_method_invocation_return_value(invocation,
729 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
734 g_dbus_method_invocation_return_value(invocation,
735 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
746 static int __handle_request_disable_app(uid_t caller_uid,
747 GDBusMethodInvocation *invocation, GVariant *parameters)
749 uid_t target_uid = (uid_t)-1;
754 g_variant_get(parameters, "(u&s)", &target_uid, &appid);
755 if (target_uid == (uid_t)-1 || appid == NULL) {
756 g_dbus_method_invocation_return_value(invocation,
757 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
761 reqkey = __generate_reqkey(appid);
762 if (reqkey == NULL) {
763 g_dbus_method_invocation_return_value(invocation,
764 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
769 if (_push_queue(target_uid, caller_uid, reqkey,
770 REQUEST_TYPE_DISABLE_APP, "default",
772 g_dbus_method_invocation_return_value(invocation,
773 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
778 g_dbus_method_invocation_return_value(invocation,
779 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
790 static int __handle_request_enable_global_app_for_uid(uid_t caller_uid,
791 GDBusMethodInvocation *invocation, GVariant *parameters)
793 uid_t target_uid = (uid_t)-1;
798 g_variant_get(parameters, "(u&s)", &target_uid, &appid);
799 if (target_uid == (uid_t)-1 || appid == NULL) {
800 g_dbus_method_invocation_return_value(invocation,
801 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
805 reqkey = __generate_reqkey(appid);
806 if (reqkey == NULL) {
807 g_dbus_method_invocation_return_value(invocation,
808 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
813 if (_push_queue(target_uid, caller_uid, reqkey,
814 REQUEST_TYPE_ENABLE_GLOBAL_APP_FOR_UID,
815 "default", appid, NULL)) {
816 g_dbus_method_invocation_return_value(invocation,
817 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
822 g_dbus_method_invocation_return_value(invocation,
823 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
834 static int __handle_request_disable_global_app_for_uid(uid_t caller_uid,
835 GDBusMethodInvocation *invocation, GVariant *parameters)
837 uid_t target_uid = (uid_t)-1;
842 g_variant_get(parameters, "(u&s)", &target_uid, &appid);
843 if (target_uid == (uid_t)-1 || appid == NULL) {
844 g_dbus_method_invocation_return_value(invocation,
845 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
849 reqkey = __generate_reqkey(appid);
850 if (reqkey == NULL) {
851 g_dbus_method_invocation_return_value(invocation,
852 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
857 if (_push_queue(target_uid, caller_uid, reqkey,
858 REQUEST_TYPE_DISABLE_GLOBAL_APP_FOR_UID,
859 "default", appid, NULL)) {
860 g_dbus_method_invocation_return_value(invocation,
861 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
866 g_dbus_method_invocation_return_value(invocation,
867 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
878 static int __handle_request_getsize(uid_t caller_uid,
879 GDBusMethodInvocation *invocation, GVariant *parameters)
881 uid_t target_uid = (uid_t)-1;
887 g_variant_get(parameters, "(u&si)", &target_uid, &pkgid, &get_type);
888 if (target_uid == (uid_t)-1 || pkgid == NULL || get_type == -1) {
889 g_dbus_method_invocation_return_value(invocation,
890 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
894 reqkey = __generate_reqkey(pkgid);
895 if (reqkey == NULL) {
896 g_dbus_method_invocation_return_value(invocation,
897 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
901 snprintf(buf, sizeof(buf), "%d", get_type);
902 if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_GETSIZE,
903 "pkgtool", pkgid, buf)) {
904 g_dbus_method_invocation_return_value(invocation,
905 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
910 g_dbus_method_invocation_return_value(invocation,
911 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
917 static int __handle_request_cleardata(uid_t caller_uid,
918 GDBusMethodInvocation *invocation, GVariant *parameters)
920 uid_t target_uid = (uid_t)-1;
925 g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
926 if (target_uid == (uid_t)-1 || pkgid == NULL) {
927 g_dbus_method_invocation_return_value(invocation,
928 g_variant_new("(i)", PKGMGR_R_ECOMM));
932 pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
933 if (pkgtype == NULL) {
934 g_dbus_method_invocation_return_value(invocation,
935 g_variant_new("(i)", PKGMGR_R_ENOPKG));
939 reqkey = __generate_reqkey(pkgid);
940 if (reqkey == NULL) {
941 g_dbus_method_invocation_return_value(invocation,
942 g_variant_new("(i)", PKGMGR_R_ENOMEM));
947 if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_CLEARDATA,
948 pkgtype, pkgid, NULL)) {
949 g_dbus_method_invocation_return_value(invocation,
950 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
956 g_dbus_method_invocation_return_value(invocation,
957 g_variant_new("(i)", PKGMGR_R_OK));
965 static int __handle_request_clearcache(uid_t caller_uid,
966 GDBusMethodInvocation *invocation, GVariant *parameters)
968 uid_t target_uid = (uid_t)-1;
971 g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
972 if (target_uid == (uid_t)-1 || pkgid == NULL) {
973 g_dbus_method_invocation_return_value(invocation,
974 g_variant_new("(i)", PKGMGR_R_ECOMM));
978 if (_push_queue(target_uid, caller_uid, NULL, REQUEST_TYPE_CLEARCACHE,
979 "pkgtool", pkgid, NULL)) {
980 g_dbus_method_invocation_return_value(invocation,
981 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
985 g_dbus_method_invocation_return_value(invocation,
986 g_variant_new("(i)", PKGMGR_R_OK));
991 static int __handle_request_kill(uid_t caller_uid,
992 GDBusMethodInvocation *invocation, GVariant *parameters)
994 uid_t target_uid = (uid_t)-1;
998 g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
999 if (target_uid == (uid_t)-1 || pkgid == NULL) {
1000 g_dbus_method_invocation_return_value(invocation,
1001 g_variant_new("(ii)", PKGMGR_R_ECOMM, 0));
1005 reqkey = __generate_reqkey(pkgid);
1006 if (reqkey == NULL) {
1007 g_dbus_method_invocation_return_value(invocation,
1008 g_variant_new("(ii)", PKGMGR_R_ENOMEM, 0));
1012 if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_KILL,
1013 "default", pkgid, NULL)) {
1014 g_dbus_method_invocation_return_value(invocation,
1015 g_variant_new("(ii)", PKGMGR_R_ESYSTEM, 0));
1020 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1021 (gpointer)invocation))
1022 ERR("reqkey already exists");
1027 static int __handle_request_check(uid_t caller_uid,
1028 GDBusMethodInvocation *invocation, GVariant *parameters)
1030 uid_t target_uid = (uid_t)-1;
1032 char *reqkey = NULL;
1034 g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
1035 if (target_uid == (uid_t)-1 || pkgid == NULL) {
1036 g_dbus_method_invocation_return_value(invocation,
1037 g_variant_new("(ii)", PKGMGR_R_ECOMM, 0));
1041 reqkey = __generate_reqkey(pkgid);
1042 if (reqkey == NULL) {
1043 g_dbus_method_invocation_return_value(invocation,
1044 g_variant_new("(ii)", PKGMGR_R_ENOMEM, 0));
1048 if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_CHECK,
1049 "default", pkgid, NULL)) {
1050 g_dbus_method_invocation_return_value(invocation,
1051 g_variant_new("(ii)", PKGMGR_R_ESYSTEM, 0));
1056 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1057 (gpointer)invocation))
1058 ERR("reqkey already exists");
1063 static int __handle_request_generate_license_request(uid_t caller_uid,
1064 GDBusMethodInvocation *invocation, GVariant *parameters)
1067 char *resp_data = NULL;
1069 g_variant_get(parameters, "(&s)", &resp_data);
1070 if (resp_data == NULL) {
1071 g_dbus_method_invocation_return_value(invocation,
1072 g_variant_new("(iss)", PKGMGR_R_ECOMM, "", ""));
1076 reqkey = __generate_reqkey("drm");
1077 if (reqkey == NULL) {
1078 g_dbus_method_invocation_return_value(invocation,
1079 g_variant_new("(iss)", PKGMGR_R_ENOMEM, "",
1084 if (_push_queue(caller_uid, caller_uid, reqkey,
1085 REQUEST_TYPE_GENERATE_LICENSE_REQUEST,
1086 "default", NULL, resp_data)) {
1087 g_dbus_method_invocation_return_value(invocation,
1088 g_variant_new("(iss)", PKGMGR_R_ESYSTEM, "",
1094 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1095 (gpointer)invocation))
1096 ERR("reqkey already exists");
1101 static int __handle_request_register_license(uid_t caller_uid,
1102 GDBusMethodInvocation *invocation, GVariant *parameters)
1105 char *resp_data = NULL;
1107 g_variant_get(parameters, "(&s)", &resp_data);
1108 if (resp_data == NULL) {
1109 g_dbus_method_invocation_return_value(invocation,
1110 g_variant_new("(i)", PKGMGR_R_ECOMM));
1114 reqkey = __generate_reqkey("drm");
1115 if (reqkey == NULL) {
1116 g_dbus_method_invocation_return_value(invocation,
1117 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1121 if (_push_queue(caller_uid, caller_uid, reqkey,
1122 REQUEST_TYPE_REGISTER_LICENSE,
1123 "default", NULL, resp_data)) {
1124 g_dbus_method_invocation_return_value(invocation,
1125 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1130 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1131 (gpointer)invocation))
1132 ERR("reqkey already exists");
1137 static int __handle_request_decrypt_package(uid_t caller_uid,
1138 GDBusMethodInvocation *invocation, GVariant *parameters)
1141 char *drm_file_path = NULL;
1142 char *decrypted_file_path = NULL;
1144 g_variant_get(parameters, "(&s&s)", &drm_file_path,
1145 &decrypted_file_path);
1146 if (drm_file_path == NULL || decrypted_file_path == NULL) {
1147 g_dbus_method_invocation_return_value(invocation,
1148 g_variant_new("(i)", PKGMGR_R_ECOMM));
1152 reqkey = __generate_reqkey("drm");
1153 if (reqkey == NULL) {
1154 g_dbus_method_invocation_return_value(invocation,
1155 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1159 if (_push_queue(caller_uid, caller_uid, reqkey,
1160 REQUEST_TYPE_DECRYPT_PACKAGE,
1161 "default", drm_file_path,
1162 decrypted_file_path)) {
1163 g_dbus_method_invocation_return_value(invocation,
1164 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1169 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1170 (gpointer)invocation))
1171 ERR("reqkey already exists");
1176 static int __update_app_splash_screen(uid_t caller_uid,
1177 GDBusMethodInvocation *invocation, GVariant *parameters,
1180 uid_t target_uid = (uid_t)-1;
1184 g_variant_get(parameters, "(u&s)", &target_uid, &appid);
1185 if (target_uid == (uid_t)-1 || appid == NULL) {
1186 ERR("target_uid: %d, appid: %s", target_uid, appid);
1187 g_dbus_method_invocation_return_value(invocation,
1188 g_variant_new("(i)", PKGMGR_R_ECOMM));
1192 reqkey = __generate_reqkey(appid);
1193 if (reqkey == NULL) {
1194 ERR("Failed to generate request key");
1195 g_dbus_method_invocation_return_value(invocation,
1196 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1200 if (_push_queue(target_uid, caller_uid, reqkey, req_type, "default",
1202 ERR("Failed to push request");
1203 g_dbus_method_invocation_return_value(invocation,
1204 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1209 g_dbus_method_invocation_return_value(invocation,
1210 g_variant_new("(i)", PKGMGR_R_OK));
1218 static int __handle_request_enable_app_splash_screen(uid_t caller_uid,
1219 GDBusMethodInvocation *invocation, GVariant *parameters)
1221 return __update_app_splash_screen(caller_uid, invocation, parameters,
1222 REQUEST_TYPE_ENABLE_APP_SPLASH_SCREEN);
1225 static int __handle_request_disable_app_splash_screen(uid_t caller_uid,
1226 GDBusMethodInvocation *invocation, GVariant *parameters)
1228 return __update_app_splash_screen(caller_uid, invocation, parameters,
1229 REQUEST_TYPE_DISABLE_APP_SPLASH_SCREEN);
1232 static int __handle_request_set_restriction_mode(uid_t caller_uid,
1233 GDBusMethodInvocation *invocation, GVariant *parameters)
1235 uid_t target_uid = (uid_t)-1;
1241 g_variant_get(parameters, "(usi)", &target_uid, &pkgid, &mode);
1242 if (target_uid == (uid_t)-1 || pkgid == NULL || mode < 0) {
1243 g_dbus_method_invocation_return_value(invocation,
1244 g_variant_new("(i)", PKGMGR_R_ECOMM));
1248 reqkey = __generate_reqkey("restriction");
1249 if (reqkey == NULL) {
1250 g_dbus_method_invocation_return_value(invocation,
1251 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1255 snprintf(buf, sizeof(buf), "%d", mode);
1256 if (_push_queue(target_uid, caller_uid, reqkey,
1257 REQUEST_TYPE_SET_RESTRICTION_MODE,
1258 "default", pkgid, buf)) {
1259 g_dbus_method_invocation_return_value(invocation,
1260 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1265 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1266 (gpointer)invocation))
1267 ERR("reqkey already exists");
1272 static int __handle_request_unset_restriction_mode(uid_t caller_uid,
1273 GDBusMethodInvocation *invocation, GVariant *parameters)
1275 uid_t target_uid = (uid_t)-1;
1281 g_variant_get(parameters, "(usi)", &target_uid, &pkgid, &mode);
1282 if (target_uid == (uid_t)-1 || pkgid == NULL || mode < 0) {
1283 g_dbus_method_invocation_return_value(invocation,
1284 g_variant_new("(i)", PKGMGR_R_ECOMM));
1288 reqkey = __generate_reqkey("restriction");
1289 if (reqkey == NULL) {
1290 g_dbus_method_invocation_return_value(invocation,
1291 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1295 snprintf(buf, sizeof(buf), "%d", mode);
1296 if (_push_queue(target_uid, caller_uid, reqkey,
1297 REQUEST_TYPE_UNSET_RESTRICTION_MODE,
1298 "default", pkgid, buf)) {
1299 g_dbus_method_invocation_return_value(invocation,
1300 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1305 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1306 (gpointer)invocation))
1307 ERR("reqkey already exists");
1312 static int __handle_request_get_restriction_mode(uid_t caller_uid,
1313 GDBusMethodInvocation *invocation, GVariant *parameters)
1315 uid_t target_uid = (uid_t)-1;
1319 g_variant_get(parameters, "(us)", &target_uid, &pkgid);
1320 if (target_uid == (uid_t)-1 || pkgid == NULL) {
1321 g_dbus_method_invocation_return_value(invocation,
1322 g_variant_new("(i)", PKGMGR_R_ECOMM));
1326 reqkey = __generate_reqkey("restriction");
1327 if (reqkey == NULL) {
1328 g_dbus_method_invocation_return_value(invocation,
1329 g_variant_new("(ii)", -1, PKGMGR_R_ENOMEM));
1333 if (_push_queue(target_uid, caller_uid, reqkey,
1334 REQUEST_TYPE_GET_RESTRICTION_MODE,
1335 "default", pkgid, NULL)) {
1336 g_dbus_method_invocation_return_value(invocation,
1337 g_variant_new("(ii)", -1, PKGMGR_R_ESYSTEM));
1342 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1343 (gpointer)invocation))
1344 ERR("reqkey already exists");
1349 static int __handle_request_set_app_label(uid_t uid,
1350 GDBusMethodInvocation *invocation, GVariant *parameters)
1352 uid_t target_uid = (uid_t)-1;
1357 g_variant_get(parameters, "(uss)", &target_uid, &appid, &label);
1358 if (target_uid == (uid_t)-1 || appid == NULL || label == NULL) {
1359 g_dbus_method_invocation_return_value(invocation,
1360 g_variant_new("(i)", PKGMGR_R_ECOMM));
1364 reqkey = __generate_reqkey("appid");
1365 if (reqkey == NULL) {
1366 g_dbus_method_invocation_return_value(invocation,
1367 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1371 if (_push_queue(target_uid, uid, reqkey,
1372 REQUEST_TYPE_SET_APP_LABEL,
1373 "default", appid, label)) {
1374 g_dbus_method_invocation_return_value(invocation,
1375 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1380 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1381 (gpointer)invocation))
1382 ERR("reqkey already exists");
1387 static uid_t __get_caller_uid(GDBusConnection *connection, const char *name)
1393 result = g_dbus_connection_call_sync(connection,
1394 "org.freedesktop.DBus", "/org/freedesktop/DBus",
1395 "org.freedesktop.DBus", "GetConnectionUnixUser",
1396 g_variant_new("(s)", name), NULL,
1397 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
1398 if (result == NULL) {
1399 ERR("failed to get caller uid: %s", err->message);
1404 g_variant_get(result, "(u)", &uid);
1409 static void __handle_method_call(GDBusConnection *connection,
1410 const gchar *sender, const gchar *object_path,
1411 const gchar *interface_name, const gchar *method_name,
1412 GVariant *parameters, GDBusMethodInvocation *invocation,
1418 uid = __get_caller_uid(connection,
1419 g_dbus_method_invocation_get_sender(invocation));
1420 if (uid == (uid_t)-1)
1423 if (__check_caller_permission(uid, invocation, parameters))
1426 if (g_strcmp0(method_name, "install") == 0)
1427 ret = __handle_request_install(uid, invocation, parameters);
1428 else if (g_strcmp0(method_name, "mount_install") == 0)
1429 ret = __handle_request_mount_install(uid, invocation,
1431 else if (g_strcmp0(method_name, "reinstall") == 0)
1432 ret = __handle_request_reinstall(uid, invocation, parameters);
1433 else if (g_strcmp0(method_name, "uninstall") == 0)
1434 ret = __handle_request_uninstall(uid, invocation, parameters);
1435 else if (g_strcmp0(method_name, "cleardata") == 0)
1436 ret = __handle_request_cleardata(uid, invocation, parameters);
1437 else if (g_strcmp0(method_name, "move") == 0)
1438 ret = __handle_request_move(uid, invocation, parameters);
1439 else if (g_strcmp0(method_name, "enable_pkgs") == 0)
1440 ret = __handle_request_enable_pkgs(uid, invocation, parameters);
1441 else if (g_strcmp0(method_name, "disable_pkgs") == 0)
1442 ret = __handle_request_disable_pkgs(uid, invocation, parameters);
1443 else if (g_strcmp0(method_name, "getsize") == 0)
1444 ret = __handle_request_getsize(uid, invocation, parameters);
1445 else if (g_strcmp0(method_name, "clearcache") == 0)
1446 ret = __handle_request_clearcache(uid, invocation, parameters);
1447 else if (g_strcmp0(method_name, "enable_app") == 0)
1448 ret = __handle_request_enable_app(uid, invocation, parameters);
1449 else if (g_strcmp0(method_name, "disable_app") == 0)
1450 ret = __handle_request_disable_app(uid, invocation, parameters);
1451 else if (g_strcmp0(method_name, "enable_global_app_for_uid") == 0)
1452 ret = __handle_request_enable_global_app_for_uid(uid,
1453 invocation, parameters);
1454 else if (g_strcmp0(method_name, "disable_global_app_for_uid") == 0)
1455 ret = __handle_request_disable_global_app_for_uid(uid,
1456 invocation, parameters);
1457 else if (g_strcmp0(method_name, "kill") == 0)
1458 ret = __handle_request_kill(uid, invocation, parameters);
1459 else if (g_strcmp0(method_name, "check") == 0)
1460 ret = __handle_request_check(uid, invocation, parameters);
1461 else if (g_strcmp0(method_name, "generate_license_request") == 0)
1462 ret = __handle_request_generate_license_request(uid, invocation,
1464 else if (g_strcmp0(method_name, "register_license") == 0)
1465 ret = __handle_request_register_license(uid, invocation,
1467 else if (g_strcmp0(method_name, "decrypt_package") == 0)
1468 ret = __handle_request_decrypt_package(uid, invocation,
1470 else if (g_strcmp0(method_name, "disable_app_splash_screen") == 0)
1471 ret = __handle_request_disable_app_splash_screen(uid,
1472 invocation, parameters);
1473 else if (g_strcmp0(method_name, "enable_app_splash_screen") == 0)
1474 ret = __handle_request_enable_app_splash_screen(uid,
1475 invocation, parameters);
1476 else if (g_strcmp0(method_name, "set_restriction_mode") == 0)
1477 ret = __handle_request_set_restriction_mode(uid, invocation,
1479 else if (g_strcmp0(method_name, "unset_restriction_mode") == 0)
1480 ret = __handle_request_unset_restriction_mode(uid, invocation,
1482 else if (g_strcmp0(method_name, "get_restriction_mode") == 0)
1483 ret = __handle_request_get_restriction_mode(uid, invocation,
1485 else if (g_strcmp0(method_name, "set_app_label") == 0)
1486 ret = __handle_request_set_app_label(uid, invocation, parameters);
1491 g_idle_add(queue_job, NULL);
1494 int _return_value_to_caller(const char *req_key, GVariant *result)
1496 GDBusMethodInvocation *invocation;
1498 invocation = (GDBusMethodInvocation *)g_hash_table_lookup(req_table,
1500 if (invocation == NULL) {
1501 ERR("no such request id");
1505 g_dbus_method_invocation_return_value(invocation, result);
1506 g_hash_table_remove(req_table, (gpointer)req_key);
1511 static const GDBusInterfaceVTable interface_vtable = {
1512 __handle_method_call,
1517 static void __on_bus_acquired(GDBusConnection *connection, const gchar *name,
1522 DBG("on bus acquired");
1524 reg_id = g_dbus_connection_register_object(connection,
1525 PKGMGR_DBUS_OBJECT_PATH,
1526 instropection_data->interfaces[0],
1527 &interface_vtable, NULL, NULL, &err);
1530 ERR("failed to register object: %s", err->message);
1535 static void __on_name_acquired(GDBusConnection *connection, const gchar *name,
1538 DBG("on name acquired: %s", name);
1541 static void __on_name_lost(GDBusConnection *connection, const gchar *name,
1544 DBG("on name lost: %s", name);
1547 int _init_request_handler(void)
1549 instropection_data = g_dbus_node_info_new_for_xml(instropection_xml,
1552 owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, PKGMGR_DBUS_SERVICE,
1553 G_BUS_NAME_OWNER_FLAGS_NONE, __on_bus_acquired,
1554 __on_name_acquired, __on_name_lost, NULL, NULL);
1556 req_table = g_hash_table_new_full(g_str_hash, g_str_equal,
1558 if (req_table == NULL)
1564 void _fini_request_handler(void)
1566 g_hash_table_destroy(req_table);
1567 g_bus_unown_name(owner_id);
1568 g_dbus_node_info_unref(instropection_data);