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 #define REGULAR_USER 5000
239 static int __check_caller_permission(uid_t uid,
240 GDBusMethodInvocation *invocation, GVariant *parameters)
246 if (uid < REGULAR_USER)
249 v = g_variant_get_child_value(parameters, 0);
251 g_dbus_method_invocation_return_error_literal(invocation,
252 G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
257 target_uid = g_variant_get_uint32(v);
259 if (uid == target_uid)
262 is_admin = __is_admin_user(uid);
263 if (is_admin == -1) {
264 g_dbus_method_invocation_return_error_literal(invocation,
265 G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
268 } else if (is_admin == 0) {
269 g_dbus_method_invocation_return_error_literal(invocation,
270 G_DBUS_ERROR, G_DBUS_ERROR_ACCESS_DENIED,
271 "Non-admin user cannot request operation to "
279 static int __handle_request_install(uid_t caller_uid,
280 GDBusMethodInvocation *invocation, GVariant *parameters)
282 uid_t target_uid = (uid_t)-1;
283 char *arg_pkgtype = NULL;
285 char *pkgpath = NULL;
288 gchar **tmp_args = NULL;
295 g_variant_get(parameters, "(u&s&s@as)", &target_uid, &arg_pkgtype,
297 tmp_args = (gchar **)g_variant_get_strv(value, &args_count);
299 for (i = 0; i < args_count; i++)
300 len = len + strlen(tmp_args[i]) + 1;
302 args = (char *)calloc(len, sizeof(char));
304 ERR("calloc failed");
305 g_dbus_method_invocation_return_value(invocation,
306 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
311 for (i = 0; i < args_count; i++) {
312 strncat(args, tmp_args[i], strlen(tmp_args[i]));
313 if (i != args_count - 1)
314 strncat(args, " ", strlen(" "));
317 if (target_uid == (uid_t)-1 || pkgpath == NULL) {
318 g_dbus_method_invocation_return_value(invocation,
319 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
324 pkgtype = _get_pkgtype_from_file(pkgpath);
325 if (!pkgtype && arg_pkgtype && strlen(arg_pkgtype))
326 pkgtype = (const char *)arg_pkgtype;
327 if (pkgtype == NULL) {
328 g_dbus_method_invocation_return_value(invocation,
329 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
334 reqkey = __generate_reqkey(pkgpath);
335 if (reqkey == NULL) {
336 g_dbus_method_invocation_return_value(invocation,
337 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
342 if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_INSTALL,
343 pkgtype, pkgpath, args)) {
344 g_dbus_method_invocation_return_value(invocation,
345 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
350 g_dbus_method_invocation_return_value(invocation,
351 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
368 static int __handle_request_mount_install(uid_t caller_uid,
369 GDBusMethodInvocation *invocation, GVariant *parameters)
371 uid_t target_uid = (uid_t)-1;
372 char *arg_pkgtype = NULL;
374 char *pkgpath = NULL;
377 gchar **tmp_args = NULL;
384 g_variant_get(parameters, "(u&s&s@as)", &target_uid, &arg_pkgtype,
386 tmp_args = (gchar **)g_variant_get_strv(value, &args_count);
388 for (i = 0; i < args_count; i++)
389 len = len + strlen(tmp_args[i]) + 1;
391 args = (char *)calloc(len, sizeof(char));
393 ERR("calloc failed");
394 g_dbus_method_invocation_return_value(invocation,
395 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
400 for (i = 0; i < args_count; i++) {
401 strncat(args, tmp_args[i], strlen(tmp_args[i]));
402 if (i != args_count - 1)
403 strncat(args, " ", strlen(" "));
406 if (target_uid == (uid_t)-1 || pkgpath == NULL) {
407 g_dbus_method_invocation_return_value(invocation,
408 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
413 pkgtype = _get_pkgtype_from_file(pkgpath);
414 if (!pkgtype && arg_pkgtype && strlen(arg_pkgtype))
415 pkgtype = (const char *)arg_pkgtype;
416 if (pkgtype == NULL) {
417 g_dbus_method_invocation_return_value(invocation,
418 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
423 reqkey = __generate_reqkey(pkgpath);
424 if (reqkey == NULL) {
425 g_dbus_method_invocation_return_value(invocation,
426 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
431 if (_push_queue(target_uid, caller_uid, reqkey,
432 REQUEST_TYPE_MOUNT_INSTALL,
433 pkgtype, pkgpath, args)) {
434 g_dbus_method_invocation_return_value(invocation,
435 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
440 g_dbus_method_invocation_return_value(invocation,
441 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
457 static int __handle_request_reinstall(uid_t caller_uid,
458 GDBusMethodInvocation *invocation, GVariant *parameters)
460 uid_t target_uid = (uid_t)-1;
465 g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
466 if (target_uid == (uid_t)-1 || pkgid == NULL) {
467 g_dbus_method_invocation_return_value(invocation,
468 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
472 pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
473 if (pkgtype == NULL) {
474 g_dbus_method_invocation_return_value(invocation,
475 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
479 reqkey = __generate_reqkey(pkgid);
480 if (reqkey == NULL) {
481 g_dbus_method_invocation_return_value(invocation,
482 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
486 if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_REINSTALL,
487 pkgtype, pkgid, NULL)) {
488 g_dbus_method_invocation_return_value(invocation,
489 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
495 g_dbus_method_invocation_return_value(invocation,
496 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
503 static int __handle_request_uninstall(uid_t caller_uid,
504 GDBusMethodInvocation *invocation, GVariant *parameters)
506 uid_t target_uid = (uid_t)-1;
511 g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
512 if (target_uid == (uid_t)-1 || pkgid == NULL) {
513 g_dbus_method_invocation_return_value(invocation,
514 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
518 pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
519 if (pkgtype == NULL) {
520 g_dbus_method_invocation_return_value(invocation,
521 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
525 reqkey = __generate_reqkey(pkgid);
526 if (reqkey == NULL) {
527 g_dbus_method_invocation_return_value(invocation,
528 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
532 if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_UNINSTALL,
533 pkgtype, pkgid, NULL)) {
534 g_dbus_method_invocation_return_value(invocation,
535 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
541 g_dbus_method_invocation_return_value(invocation,
542 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
549 static int __handle_request_move(uid_t caller_uid,
550 GDBusMethodInvocation *invocation, GVariant *parameters)
552 uid_t target_uid = (uid_t)-1;
557 char buf[4] = { '\0' };
559 g_variant_get(parameters, "(u&si)", &target_uid, &pkgid, &move_type);
560 if (target_uid == (uid_t)-1 || pkgid == NULL) {
561 g_dbus_method_invocation_return_value(invocation,
562 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
566 pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
567 if (pkgtype == NULL) {
568 g_dbus_method_invocation_return_value(invocation,
569 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
573 reqkey = __generate_reqkey(pkgid);
574 if (reqkey == NULL) {
575 g_dbus_method_invocation_return_value(invocation,
576 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
581 snprintf(buf, sizeof(buf), "%d", move_type);
582 if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_MOVE,
583 pkgtype, pkgid, buf)) {
584 g_dbus_method_invocation_return_value(invocation,
585 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
591 g_dbus_method_invocation_return_value(invocation,
592 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
599 static int __handle_request_enable_pkgs(uid_t caller_uid,
600 GDBusMethodInvocation *invocation, GVariant *parameters)
602 uid_t target_uid = (uid_t)-1;
608 g_variant_get(parameters, "(uas)", &target_uid, &iter);
609 if (target_uid == (uid_t)-1 || iter == NULL) {
610 g_dbus_method_invocation_return_value(invocation,
611 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
615 reqkey = __generate_reqkey("enable_pkgs");
616 if (reqkey == NULL) {
617 g_dbus_method_invocation_return_value(invocation,
618 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
622 while (g_variant_iter_next(iter, "&s", &pkgid)) {
623 pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
624 if (pkgtype == NULL) {
625 g_dbus_method_invocation_return_value(invocation,
626 g_variant_new("(is)",
627 PKGMGR_R_ESYSTEM, ""));
631 if (_push_queue(target_uid, caller_uid, reqkey,
632 REQUEST_TYPE_ENABLE_PKG,
633 pkgtype, pkgid, NULL)) {
634 g_dbus_method_invocation_return_value(invocation,
635 g_variant_new("(is)",
636 PKGMGR_R_ESYSTEM, ""));
644 g_dbus_method_invocation_return_value(invocation,
645 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
651 static int __handle_request_disable_pkgs(uid_t caller_uid,
652 GDBusMethodInvocation *invocation, GVariant *parameters)
654 uid_t target_uid = (uid_t)-1;
660 g_variant_get(parameters, "(uas)", &target_uid, &iter);
661 if (target_uid == (uid_t)-1 || iter == NULL) {
662 g_dbus_method_invocation_return_value(invocation,
663 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
667 reqkey = __generate_reqkey("disable_pkgs");
668 if (reqkey == NULL) {
669 g_dbus_method_invocation_return_value(invocation,
670 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
674 while (g_variant_iter_next(iter, "&s", &pkgid)) {
675 pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
676 if (pkgtype == NULL) {
677 g_dbus_method_invocation_return_value(invocation,
678 g_variant_new("(is)",
679 PKGMGR_R_ESYSTEM, ""));
683 if (_push_queue(target_uid, caller_uid, reqkey,
684 REQUEST_TYPE_DISABLE_PKG,
685 pkgtype, pkgid, NULL)) {
686 g_dbus_method_invocation_return_value(invocation,
687 g_variant_new("(is)",
688 PKGMGR_R_ESYSTEM, ""));
696 g_dbus_method_invocation_return_value(invocation,
697 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
703 static int __handle_request_enable_app(uid_t caller_uid,
704 GDBusMethodInvocation *invocation, GVariant *parameters)
706 uid_t target_uid = (uid_t)-1;
711 g_variant_get(parameters, "(u&s)", &target_uid, &appid);
712 if (target_uid == (uid_t)-1 || appid == NULL) {
713 g_dbus_method_invocation_return_value(invocation,
714 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
718 reqkey = __generate_reqkey(appid);
719 if (reqkey == NULL) {
720 g_dbus_method_invocation_return_value(invocation,
721 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
726 if (_push_queue(target_uid, caller_uid, reqkey,
727 REQUEST_TYPE_ENABLE_APP, "default",
729 g_dbus_method_invocation_return_value(invocation,
730 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
735 g_dbus_method_invocation_return_value(invocation,
736 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
747 static int __handle_request_disable_app(uid_t caller_uid,
748 GDBusMethodInvocation *invocation, GVariant *parameters)
750 uid_t target_uid = (uid_t)-1;
755 g_variant_get(parameters, "(u&s)", &target_uid, &appid);
756 if (target_uid == (uid_t)-1 || appid == NULL) {
757 g_dbus_method_invocation_return_value(invocation,
758 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
762 reqkey = __generate_reqkey(appid);
763 if (reqkey == NULL) {
764 g_dbus_method_invocation_return_value(invocation,
765 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
770 if (_push_queue(target_uid, caller_uid, reqkey,
771 REQUEST_TYPE_DISABLE_APP, "default",
773 g_dbus_method_invocation_return_value(invocation,
774 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
779 g_dbus_method_invocation_return_value(invocation,
780 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
791 static int __handle_request_enable_global_app_for_uid(uid_t caller_uid,
792 GDBusMethodInvocation *invocation, GVariant *parameters)
794 uid_t target_uid = (uid_t)-1;
799 g_variant_get(parameters, "(u&s)", &target_uid, &appid);
800 if (target_uid == (uid_t)-1 || appid == NULL) {
801 g_dbus_method_invocation_return_value(invocation,
802 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
806 reqkey = __generate_reqkey(appid);
807 if (reqkey == NULL) {
808 g_dbus_method_invocation_return_value(invocation,
809 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
814 if (_push_queue(target_uid, caller_uid, reqkey,
815 REQUEST_TYPE_ENABLE_GLOBAL_APP_FOR_UID,
816 "default", appid, NULL)) {
817 g_dbus_method_invocation_return_value(invocation,
818 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
823 g_dbus_method_invocation_return_value(invocation,
824 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
835 static int __handle_request_disable_global_app_for_uid(uid_t caller_uid,
836 GDBusMethodInvocation *invocation, GVariant *parameters)
838 uid_t target_uid = (uid_t)-1;
843 g_variant_get(parameters, "(u&s)", &target_uid, &appid);
844 if (target_uid == (uid_t)-1 || appid == NULL) {
845 g_dbus_method_invocation_return_value(invocation,
846 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
850 reqkey = __generate_reqkey(appid);
851 if (reqkey == NULL) {
852 g_dbus_method_invocation_return_value(invocation,
853 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
858 if (_push_queue(target_uid, caller_uid, reqkey,
859 REQUEST_TYPE_DISABLE_GLOBAL_APP_FOR_UID,
860 "default", appid, NULL)) {
861 g_dbus_method_invocation_return_value(invocation,
862 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
867 g_dbus_method_invocation_return_value(invocation,
868 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
879 static int __handle_request_getsize(uid_t caller_uid,
880 GDBusMethodInvocation *invocation, GVariant *parameters)
882 uid_t target_uid = (uid_t)-1;
888 g_variant_get(parameters, "(u&si)", &target_uid, &pkgid, &get_type);
889 if (target_uid == (uid_t)-1 || pkgid == NULL || get_type == -1) {
890 g_dbus_method_invocation_return_value(invocation,
891 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
895 reqkey = __generate_reqkey(pkgid);
896 if (reqkey == NULL) {
897 g_dbus_method_invocation_return_value(invocation,
898 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
902 snprintf(buf, sizeof(buf), "%d", get_type);
903 if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_GETSIZE,
904 "pkgtool", pkgid, buf)) {
905 g_dbus_method_invocation_return_value(invocation,
906 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
911 g_dbus_method_invocation_return_value(invocation,
912 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
918 static int __handle_request_cleardata(uid_t caller_uid,
919 GDBusMethodInvocation *invocation, GVariant *parameters)
921 uid_t target_uid = (uid_t)-1;
926 g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
927 if (target_uid == (uid_t)-1 || pkgid == NULL) {
928 g_dbus_method_invocation_return_value(invocation,
929 g_variant_new("(i)", PKGMGR_R_ECOMM));
933 pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
934 if (pkgtype == NULL) {
935 g_dbus_method_invocation_return_value(invocation,
936 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
940 reqkey = __generate_reqkey(pkgid);
941 if (reqkey == NULL) {
942 g_dbus_method_invocation_return_value(invocation,
943 g_variant_new("(i)", PKGMGR_R_ENOMEM));
948 if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_CLEARDATA,
949 pkgtype, pkgid, NULL)) {
950 g_dbus_method_invocation_return_value(invocation,
951 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
957 g_dbus_method_invocation_return_value(invocation,
958 g_variant_new("(i)", PKGMGR_R_OK));
966 static int __handle_request_clearcache(uid_t caller_uid,
967 GDBusMethodInvocation *invocation, GVariant *parameters)
969 uid_t target_uid = (uid_t)-1;
972 g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
973 if (target_uid == (uid_t)-1 || pkgid == NULL) {
974 g_dbus_method_invocation_return_value(invocation,
975 g_variant_new("(i)", PKGMGR_R_ECOMM));
979 if (_push_queue(target_uid, caller_uid, NULL, REQUEST_TYPE_CLEARCACHE,
980 "pkgtool", pkgid, NULL)) {
981 g_dbus_method_invocation_return_value(invocation,
982 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
986 g_dbus_method_invocation_return_value(invocation,
987 g_variant_new("(i)", PKGMGR_R_OK));
992 static int __handle_request_kill(uid_t caller_uid,
993 GDBusMethodInvocation *invocation, GVariant *parameters)
995 uid_t target_uid = (uid_t)-1;
999 g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
1000 if (target_uid == (uid_t)-1 || pkgid == NULL) {
1001 g_dbus_method_invocation_return_value(invocation,
1002 g_variant_new("(ii)", PKGMGR_R_ECOMM, 0));
1006 reqkey = __generate_reqkey(pkgid);
1007 if (reqkey == NULL) {
1008 g_dbus_method_invocation_return_value(invocation,
1009 g_variant_new("(ii)", PKGMGR_R_ENOMEM, 0));
1013 if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_KILL,
1014 "default", pkgid, NULL)) {
1015 g_dbus_method_invocation_return_value(invocation,
1016 g_variant_new("(ii)", PKGMGR_R_ESYSTEM, 0));
1021 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1022 (gpointer)invocation))
1023 ERR("reqkey already exists");
1028 static int __handle_request_check(uid_t caller_uid,
1029 GDBusMethodInvocation *invocation, GVariant *parameters)
1031 uid_t target_uid = (uid_t)-1;
1033 char *reqkey = NULL;
1035 g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
1036 if (target_uid == (uid_t)-1 || pkgid == NULL) {
1037 g_dbus_method_invocation_return_value(invocation,
1038 g_variant_new("(ii)", PKGMGR_R_ECOMM, 0));
1042 reqkey = __generate_reqkey(pkgid);
1043 if (reqkey == NULL) {
1044 g_dbus_method_invocation_return_value(invocation,
1045 g_variant_new("(ii)", PKGMGR_R_ENOMEM, 0));
1049 if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_CHECK,
1050 "default", pkgid, NULL)) {
1051 g_dbus_method_invocation_return_value(invocation,
1052 g_variant_new("(ii)", PKGMGR_R_ESYSTEM, 0));
1057 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1058 (gpointer)invocation))
1059 ERR("reqkey already exists");
1064 static int __handle_request_generate_license_request(uid_t caller_uid,
1065 GDBusMethodInvocation *invocation, GVariant *parameters)
1068 char *resp_data = NULL;
1070 g_variant_get(parameters, "(&s)", &resp_data);
1071 if (resp_data == NULL) {
1072 g_dbus_method_invocation_return_value(invocation,
1073 g_variant_new("(iss)", PKGMGR_R_ECOMM, "", ""));
1077 reqkey = __generate_reqkey("drm");
1078 if (reqkey == NULL) {
1079 g_dbus_method_invocation_return_value(invocation,
1080 g_variant_new("(iss)", PKGMGR_R_ENOMEM, "",
1085 if (_push_queue(caller_uid, caller_uid, reqkey,
1086 REQUEST_TYPE_GENERATE_LICENSE_REQUEST,
1087 "default", NULL, resp_data)) {
1088 g_dbus_method_invocation_return_value(invocation,
1089 g_variant_new("(iss)", PKGMGR_R_ESYSTEM, "",
1095 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1096 (gpointer)invocation))
1097 ERR("reqkey already exists");
1102 static int __handle_request_register_license(uid_t caller_uid,
1103 GDBusMethodInvocation *invocation, GVariant *parameters)
1106 char *resp_data = NULL;
1108 g_variant_get(parameters, "(&s)", &resp_data);
1109 if (resp_data == NULL) {
1110 g_dbus_method_invocation_return_value(invocation,
1111 g_variant_new("(i)", PKGMGR_R_ECOMM));
1115 reqkey = __generate_reqkey("drm");
1116 if (reqkey == NULL) {
1117 g_dbus_method_invocation_return_value(invocation,
1118 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1122 if (_push_queue(caller_uid, caller_uid, reqkey,
1123 REQUEST_TYPE_REGISTER_LICENSE,
1124 "default", NULL, resp_data)) {
1125 g_dbus_method_invocation_return_value(invocation,
1126 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1131 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1132 (gpointer)invocation))
1133 ERR("reqkey already exists");
1138 static int __handle_request_decrypt_package(uid_t caller_uid,
1139 GDBusMethodInvocation *invocation, GVariant *parameters)
1142 char *drm_file_path = NULL;
1143 char *decrypted_file_path = NULL;
1145 g_variant_get(parameters, "(&s&s)", &drm_file_path,
1146 &decrypted_file_path);
1147 if (drm_file_path == NULL || decrypted_file_path == NULL) {
1148 g_dbus_method_invocation_return_value(invocation,
1149 g_variant_new("(i)", PKGMGR_R_ECOMM));
1153 reqkey = __generate_reqkey("drm");
1154 if (reqkey == NULL) {
1155 g_dbus_method_invocation_return_value(invocation,
1156 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1160 if (_push_queue(caller_uid, caller_uid, reqkey,
1161 REQUEST_TYPE_DECRYPT_PACKAGE,
1162 "default", drm_file_path,
1163 decrypted_file_path)) {
1164 g_dbus_method_invocation_return_value(invocation,
1165 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1170 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1171 (gpointer)invocation))
1172 ERR("reqkey already exists");
1177 static int __update_app_splash_screen(uid_t caller_uid,
1178 GDBusMethodInvocation *invocation, GVariant *parameters,
1181 uid_t target_uid = (uid_t)-1;
1185 g_variant_get(parameters, "(u&s)", &target_uid, &appid);
1186 if (target_uid == (uid_t)-1 || appid == NULL) {
1187 ERR("target_uid: %d, appid: %s", target_uid, appid);
1188 g_dbus_method_invocation_return_value(invocation,
1189 g_variant_new("(i)", PKGMGR_R_ECOMM));
1193 reqkey = __generate_reqkey(appid);
1194 if (reqkey == NULL) {
1195 ERR("Failed to generate request key");
1196 g_dbus_method_invocation_return_value(invocation,
1197 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1201 if (_push_queue(target_uid, caller_uid, reqkey, req_type, "default",
1203 ERR("Failed to push request");
1204 g_dbus_method_invocation_return_value(invocation,
1205 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1210 g_dbus_method_invocation_return_value(invocation,
1211 g_variant_new("(i)", PKGMGR_R_OK));
1219 static int __handle_request_enable_app_splash_screen(uid_t caller_uid,
1220 GDBusMethodInvocation *invocation, GVariant *parameters)
1222 return __update_app_splash_screen(caller_uid, invocation, parameters,
1223 REQUEST_TYPE_ENABLE_APP_SPLASH_SCREEN);
1226 static int __handle_request_disable_app_splash_screen(uid_t caller_uid,
1227 GDBusMethodInvocation *invocation, GVariant *parameters)
1229 return __update_app_splash_screen(caller_uid, invocation, parameters,
1230 REQUEST_TYPE_DISABLE_APP_SPLASH_SCREEN);
1233 static int __handle_request_set_restriction_mode(uid_t caller_uid,
1234 GDBusMethodInvocation *invocation, GVariant *parameters)
1236 uid_t target_uid = (uid_t)-1;
1242 g_variant_get(parameters, "(usi)", &target_uid, &pkgid, &mode);
1243 if (target_uid == (uid_t)-1 || pkgid == NULL || mode < 0) {
1244 g_dbus_method_invocation_return_value(invocation,
1245 g_variant_new("(i)", PKGMGR_R_ECOMM));
1249 reqkey = __generate_reqkey("restriction");
1250 if (reqkey == NULL) {
1251 g_dbus_method_invocation_return_value(invocation,
1252 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1256 snprintf(buf, sizeof(buf), "%d", mode);
1257 if (_push_queue(target_uid, caller_uid, reqkey,
1258 REQUEST_TYPE_SET_RESTRICTION_MODE,
1259 "default", pkgid, buf)) {
1260 g_dbus_method_invocation_return_value(invocation,
1261 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1266 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1267 (gpointer)invocation))
1268 ERR("reqkey already exists");
1273 static int __handle_request_unset_restriction_mode(uid_t caller_uid,
1274 GDBusMethodInvocation *invocation, GVariant *parameters)
1276 uid_t target_uid = (uid_t)-1;
1282 g_variant_get(parameters, "(usi)", &target_uid, &pkgid, &mode);
1283 if (target_uid == (uid_t)-1 || pkgid == NULL || mode < 0) {
1284 g_dbus_method_invocation_return_value(invocation,
1285 g_variant_new("(i)", PKGMGR_R_ECOMM));
1289 reqkey = __generate_reqkey("restriction");
1290 if (reqkey == NULL) {
1291 g_dbus_method_invocation_return_value(invocation,
1292 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1296 snprintf(buf, sizeof(buf), "%d", mode);
1297 if (_push_queue(target_uid, caller_uid, reqkey,
1298 REQUEST_TYPE_UNSET_RESTRICTION_MODE,
1299 "default", pkgid, buf)) {
1300 g_dbus_method_invocation_return_value(invocation,
1301 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1306 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1307 (gpointer)invocation))
1308 ERR("reqkey already exists");
1313 static int __handle_request_get_restriction_mode(uid_t caller_uid,
1314 GDBusMethodInvocation *invocation, GVariant *parameters)
1316 uid_t target_uid = (uid_t)-1;
1320 g_variant_get(parameters, "(us)", &target_uid, &pkgid);
1321 if (target_uid == (uid_t)-1 || pkgid == NULL) {
1322 g_dbus_method_invocation_return_value(invocation,
1323 g_variant_new("(i)", PKGMGR_R_ECOMM));
1327 reqkey = __generate_reqkey("restriction");
1328 if (reqkey == NULL) {
1329 g_dbus_method_invocation_return_value(invocation,
1330 g_variant_new("(ii)", -1, PKGMGR_R_ENOMEM));
1334 if (_push_queue(target_uid, caller_uid, reqkey,
1335 REQUEST_TYPE_GET_RESTRICTION_MODE,
1336 "default", pkgid, NULL)) {
1337 g_dbus_method_invocation_return_value(invocation,
1338 g_variant_new("(ii)", -1, PKGMGR_R_ESYSTEM));
1343 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1344 (gpointer)invocation))
1345 ERR("reqkey already exists");
1350 static int __handle_request_set_app_label(uid_t uid,
1351 GDBusMethodInvocation *invocation, GVariant *parameters)
1353 uid_t target_uid = (uid_t)-1;
1358 g_variant_get(parameters, "(uss)", &target_uid, &appid, &label);
1359 if (target_uid == (uid_t)-1 || appid == NULL || label == NULL) {
1360 g_dbus_method_invocation_return_value(invocation,
1361 g_variant_new("(i)", PKGMGR_R_ECOMM));
1365 reqkey = __generate_reqkey("appid");
1366 if (reqkey == NULL) {
1367 g_dbus_method_invocation_return_value(invocation,
1368 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1372 if (_push_queue(target_uid, uid, reqkey,
1373 REQUEST_TYPE_SET_APP_LABEL,
1374 "default", appid, label)) {
1375 g_dbus_method_invocation_return_value(invocation,
1376 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1381 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1382 (gpointer)invocation))
1383 ERR("reqkey already exists");
1388 static uid_t __get_caller_uid(GDBusConnection *connection, const char *name)
1394 result = g_dbus_connection_call_sync(connection,
1395 "org.freedesktop.DBus", "/org/freedesktop/DBus",
1396 "org.freedesktop.DBus", "GetConnectionUnixUser",
1397 g_variant_new("(s)", name), NULL,
1398 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
1399 if (result == NULL) {
1400 ERR("failed to get caller uid: %s", err->message);
1405 g_variant_get(result, "(u)", &uid);
1410 static void __handle_method_call(GDBusConnection *connection,
1411 const gchar *sender, const gchar *object_path,
1412 const gchar *interface_name, const gchar *method_name,
1413 GVariant *parameters, GDBusMethodInvocation *invocation,
1419 uid = __get_caller_uid(connection,
1420 g_dbus_method_invocation_get_sender(invocation));
1421 if (uid == (uid_t)-1)
1424 if (__check_caller_permission(uid, invocation, parameters))
1427 if (g_strcmp0(method_name, "install") == 0)
1428 ret = __handle_request_install(uid, invocation, parameters);
1429 else if (g_strcmp0(method_name, "mount_install") == 0)
1430 ret = __handle_request_mount_install(uid, invocation,
1432 else if (g_strcmp0(method_name, "reinstall") == 0)
1433 ret = __handle_request_reinstall(uid, invocation, parameters);
1434 else if (g_strcmp0(method_name, "uninstall") == 0)
1435 ret = __handle_request_uninstall(uid, invocation, parameters);
1436 else if (g_strcmp0(method_name, "cleardata") == 0)
1437 ret = __handle_request_cleardata(uid, invocation, parameters);
1438 else if (g_strcmp0(method_name, "move") == 0)
1439 ret = __handle_request_move(uid, invocation, parameters);
1440 else if (g_strcmp0(method_name, "enable_pkgs") == 0)
1441 ret = __handle_request_enable_pkgs(uid, invocation, parameters);
1442 else if (g_strcmp0(method_name, "disable_pkgs") == 0)
1443 ret = __handle_request_disable_pkgs(uid, invocation, parameters);
1444 else if (g_strcmp0(method_name, "getsize") == 0)
1445 ret = __handle_request_getsize(uid, invocation, parameters);
1446 else if (g_strcmp0(method_name, "clearcache") == 0)
1447 ret = __handle_request_clearcache(uid, invocation, parameters);
1448 else if (g_strcmp0(method_name, "enable_app") == 0)
1449 ret = __handle_request_enable_app(uid, invocation, parameters);
1450 else if (g_strcmp0(method_name, "disable_app") == 0)
1451 ret = __handle_request_disable_app(uid, invocation, parameters);
1452 else if (g_strcmp0(method_name, "enable_global_app_for_uid") == 0)
1453 ret = __handle_request_enable_global_app_for_uid(uid,
1454 invocation, parameters);
1455 else if (g_strcmp0(method_name, "disable_global_app_for_uid") == 0)
1456 ret = __handle_request_disable_global_app_for_uid(uid,
1457 invocation, parameters);
1458 else if (g_strcmp0(method_name, "kill") == 0)
1459 ret = __handle_request_kill(uid, invocation, parameters);
1460 else if (g_strcmp0(method_name, "check") == 0)
1461 ret = __handle_request_check(uid, invocation, parameters);
1462 else if (g_strcmp0(method_name, "generate_license_request") == 0)
1463 ret = __handle_request_generate_license_request(uid, invocation,
1465 else if (g_strcmp0(method_name, "register_license") == 0)
1466 ret = __handle_request_register_license(uid, invocation,
1468 else if (g_strcmp0(method_name, "decrypt_package") == 0)
1469 ret = __handle_request_decrypt_package(uid, invocation,
1471 else if (g_strcmp0(method_name, "disable_app_splash_screen") == 0)
1472 ret = __handle_request_disable_app_splash_screen(uid,
1473 invocation, parameters);
1474 else if (g_strcmp0(method_name, "enable_app_splash_screen") == 0)
1475 ret = __handle_request_enable_app_splash_screen(uid,
1476 invocation, parameters);
1477 else if (g_strcmp0(method_name, "set_restriction_mode") == 0)
1478 ret = __handle_request_set_restriction_mode(uid, invocation,
1480 else if (g_strcmp0(method_name, "unset_restriction_mode") == 0)
1481 ret = __handle_request_unset_restriction_mode(uid, invocation,
1483 else if (g_strcmp0(method_name, "get_restriction_mode") == 0)
1484 ret = __handle_request_get_restriction_mode(uid, invocation,
1486 else if (g_strcmp0(method_name, "set_app_label") == 0)
1487 ret = __handle_request_set_app_label(uid, invocation, parameters);
1492 g_idle_add(queue_job, NULL);
1495 int _return_value_to_caller(const char *req_key, GVariant *result)
1497 GDBusMethodInvocation *invocation;
1499 invocation = (GDBusMethodInvocation *)g_hash_table_lookup(req_table,
1501 if (invocation == NULL) {
1502 ERR("no such request id");
1506 g_dbus_method_invocation_return_value(invocation, result);
1507 g_hash_table_remove(req_table, (gpointer)req_key);
1512 static const GDBusInterfaceVTable interface_vtable = {
1513 __handle_method_call,
1518 static void __on_bus_acquired(GDBusConnection *connection, const gchar *name,
1523 DBG("on bus acquired");
1525 reg_id = g_dbus_connection_register_object(connection,
1526 PKGMGR_DBUS_OBJECT_PATH,
1527 instropection_data->interfaces[0],
1528 &interface_vtable, NULL, NULL, &err);
1531 ERR("failed to register object: %s", err->message);
1536 static void __on_name_acquired(GDBusConnection *connection, const gchar *name,
1539 DBG("on name acquired: %s", name);
1542 static void __on_name_lost(GDBusConnection *connection, const gchar *name,
1545 DBG("on name lost: %s", name);
1548 int _init_request_handler(void)
1550 instropection_data = g_dbus_node_info_new_for_xml(instropection_xml,
1553 owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, PKGMGR_DBUS_SERVICE,
1554 G_BUS_NAME_OWNER_FLAGS_NONE, __on_bus_acquired,
1555 __on_name_acquired, __on_name_lost, NULL, NULL);
1557 req_table = g_hash_table_new_full(g_str_hash, g_str_equal,
1559 if (req_table == NULL)
1565 void _fini_request_handler(void)
1567 g_hash_table_destroy(req_table);
1568 g_bus_unown_name(owner_id);
1569 g_dbus_node_info_unref(instropection_data);