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='pkgtype' direction='in'/>"
33 " <arg type='s' name='pkgid' direction='in'/>"
34 " <arg type='i' name='ret' direction='out'/>"
35 " <arg type='s' name='reqkey' direction='out'/>"
37 " <method name='mount_install'>"
38 " <arg type='u' name='uid' direction='in'/>"
39 " <arg type='s' name='pkgtype' direction='in'/>"
40 " <arg type='s' name='pkgpath' direction='in'/>"
41 " <arg type='as' name='args' direction='in'/>"
42 " <arg type='i' name='ret' direction='out'/>"
43 " <arg type='s' name='reqkey' direction='out'/>"
45 " <method name='uninstall'>"
46 " <arg type='u' name='uid' direction='in'/>"
47 " <arg type='s' name='pkgtype' direction='in'/>"
48 " <arg type='s' name='pkgid' direction='in'/>"
49 " <arg type='i' name='ret' direction='out'/>"
50 " <arg type='s' name='reqkey' direction='out'/>"
52 " <method name='move'>"
53 " <arg type='u' name='uid' direction='in'/>"
54 " <arg type='s' name='pkgtype' direction='in'/>"
55 " <arg type='s' name='pkgid' direction='in'/>"
56 " <arg type='i' name='movetype' direction='in'/>"
57 " <arg type='i' name='ret' direction='out'/>"
58 " <arg type='s' name='reqkey' direction='out'/>"
60 " <method name='enable_pkgs'>"
61 " <arg type='u' name='uid' direction='in'/>"
62 " <arg type='s' name='pkgtype' 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='disable_pkgs'>"
68 " <arg type='u' name='uid' direction='in'/>"
69 " <arg type='s' name='pkgtype' direction='in'/>"
70 " <arg type='as' name='pkgids' direction='in'/>"
71 " <arg type='i' name='ret' direction='out'/>"
72 " <arg type='s' name='reqkey' direction='out'/>"
74 " <method name='enable_app'>"
75 " <arg type='u' name='uid' direction='in'/>"
76 " <arg type='s' name='appid' direction='in'/>"
77 " <arg type='i' name='ret' direction='out'/>"
78 " <arg type='s' name='reqkey' direction='out'/>"
80 " <method name='disable_app'>"
81 " <arg type='u' name='uid' direction='in'/>"
82 " <arg type='s' name='appid' direction='in'/>"
83 " <arg type='i' name='ret' direction='out'/>"
84 " <arg type='s' name='reqkey' direction='out'/>"
86 " <method name='enable_global_app_for_uid'>"
87 " <arg type='u' name='uid' direction='in'/>"
88 " <arg type='s' name='appid' direction='in'/>"
89 " <arg type='i' name='ret' direction='out'/>"
90 " <arg type='s' name='reqkey' direction='out'/>"
92 " <method name='disable_global_app_for_uid'>"
93 " <arg type='u' name='uid' direction='in'/>"
94 " <arg type='s' name='appid' direction='in'/>"
95 " <arg type='i' name='ret' direction='out'/>"
96 " <arg type='s' name='reqkey' direction='out'/>"
98 " <method name='getsize'>"
99 " <arg type='u' name='uid' direction='in'/>"
100 " <arg type='s' name='pkgid' direction='in'/>"
101 " <arg type='i' name='get_type' direction='in'/>"
102 " <arg type='i' name='ret' direction='out'/>"
103 " <arg type='s' name='reqkey' direction='out'/>"
105 " <method name='cleardata'>"
106 " <arg type='u' name='uid' direction='in'/>"
107 " <arg type='s' name='pkgtype' direction='in'/>"
108 " <arg type='s' name='pkgid' direction='in'/>"
109 " <arg type='i' name='ret' direction='out'/>"
111 " <method name='clearcache'>"
112 " <arg type='u' name='uid' direction='in'/>"
113 " <arg type='s' name='pkgid' direction='in'/>"
114 " <arg type='i' name='ret' direction='out'/>"
116 " <method name='kill'>"
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='check'>"
123 " <arg type='u' name='uid' direction='in'/>"
124 " <arg type='s' name='pkgid' direction='in'/>"
125 " <arg type='i' name='ret' direction='out'/>"
126 " <arg type='i' name='pid' direction='out'/>"
128 " <method name='generate_license_request'>"
129 " <arg type='s' name='resp_data' direction='in'/>"
130 " <arg type='i' name='ret' direction='out'/>"
131 " <arg type='s' name='req_data' direction='out'/>"
132 " <arg type='s' name='license_url' direction='out'/>"
134 " <method name='register_license'>"
135 " <arg type='s' name='resp_data' direction='in'/>"
136 " <arg type='i' name='ret' direction='out'/>"
138 " <method name='decrypt_package'>"
139 " <arg type='s' name='drm_file_path' direction='in'/>"
140 " <arg type='s' name='decrypted_file_path' direction='in'/>"
141 " <arg type='i' name='ret' direction='out'/>"
143 " <method name='enable_app_splash_screen'>"
144 " <arg type='u' name='uid' direction='in'/>"
145 " <arg type='s' name='appid' direction='in'/>"
146 " <arg type='i' name='ret' direction='out'/>"
148 " <method name='disable_app_splash_screen'>"
149 " <arg type='u' name='uid' direction='in'/>"
150 " <arg type='s' name='appid' direction='in'/>"
151 " <arg type='i' name='ret' direction='out'/>"
153 " <method name='set_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='unset_restriction_mode'>"
160 " <arg type='u' name='uid' direction='in'/>"
161 " <arg type='s' name='pkgid' direction='in'/>"
162 " <arg type='i' name='mode' direction='in'/>"
163 " <arg type='i' name='ret' direction='out'/>"
165 " <method name='get_restriction_mode'>"
166 " <arg type='u' name='uid' direction='in'/>"
167 " <arg type='s' name='pkgid' direction='in'/>"
168 " <arg type='i' name='result' direction='out'/>"
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 uid,
280 GDBusMethodInvocation *invocation, GVariant *parameters)
282 uid_t target_uid = (uid_t)-1;
283 char *pkgtype = NULL;
284 char *pkgpath = NULL;
287 gchar **tmp_args = NULL;
294 g_variant_get(parameters, "(u&s&s@as)", &target_uid, &pkgtype, &pkgpath,
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 || pkgtype == NULL) {
317 g_dbus_method_invocation_return_value(invocation,
318 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
323 if (pkgpath == NULL) {
324 g_dbus_method_invocation_return_value(invocation,
325 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
330 reqkey = __generate_reqkey(pkgpath);
331 if (reqkey == NULL) {
332 g_dbus_method_invocation_return_value(invocation,
333 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
338 if (_push_queue(target_uid, reqkey, REQUEST_TYPE_INSTALL, pkgtype,
340 g_dbus_method_invocation_return_value(invocation,
341 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
346 g_dbus_method_invocation_return_value(invocation,
347 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
364 static int __handle_request_mount_install(uid_t uid,
365 GDBusMethodInvocation *invocation, GVariant *parameters)
367 uid_t target_uid = (uid_t)-1;
368 char *pkgtype = NULL;
369 char *pkgpath = NULL;
372 gchar **tmp_args = NULL;
379 g_variant_get(parameters, "(u&s&s@as)", &target_uid, &pkgtype, &pkgpath,
381 tmp_args = (gchar **)g_variant_get_strv(value, &args_count);
383 for (i = 0; i < args_count; i++)
384 len = len + strlen(tmp_args[i]) + 1;
386 args = (char *)calloc(len, sizeof(char));
388 ERR("calloc failed");
389 g_dbus_method_invocation_return_value(invocation,
390 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
395 for (i = 0; i < args_count; i++) {
396 strncat(args, tmp_args[i], strlen(tmp_args[i]));
397 if (i != args_count - 1)
398 strncat(args, " ", strlen(" "));
401 if (target_uid == (uid_t)-1 || pkgtype == NULL) {
402 g_dbus_method_invocation_return_value(invocation,
403 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
408 if (pkgpath == NULL) {
409 g_dbus_method_invocation_return_value(invocation,
410 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
415 reqkey = __generate_reqkey(pkgpath);
416 if (reqkey == NULL) {
417 g_dbus_method_invocation_return_value(invocation,
418 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
423 if (_push_queue(target_uid, reqkey, REQUEST_TYPE_MOUNT_INSTALL,
424 pkgtype, pkgpath, args)) {
425 g_dbus_method_invocation_return_value(invocation,
426 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
431 g_dbus_method_invocation_return_value(invocation,
432 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
448 static int __handle_request_reinstall(uid_t uid,
449 GDBusMethodInvocation *invocation, GVariant *parameters)
451 uid_t target_uid = (uid_t)-1;
452 char *pkgtype = NULL;
456 g_variant_get(parameters, "(u&s&s)", &target_uid, &pkgtype, &pkgid);
457 if (target_uid == (uid_t)-1 || pkgtype == NULL || pkgid == NULL) {
458 g_dbus_method_invocation_return_value(invocation,
459 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
463 reqkey = __generate_reqkey(pkgid);
464 if (reqkey == NULL) {
465 g_dbus_method_invocation_return_value(invocation,
466 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
469 if (_push_queue(target_uid, reqkey, REQUEST_TYPE_REINSTALL, pkgtype,
471 g_dbus_method_invocation_return_value(invocation,
472 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
477 g_dbus_method_invocation_return_value(invocation,
478 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
484 static int __handle_request_uninstall(uid_t uid,
485 GDBusMethodInvocation *invocation, GVariant *parameters)
487 uid_t target_uid = (uid_t)-1;
488 char *pkgtype = NULL;
492 g_variant_get(parameters, "(u&s&s)", &target_uid, &pkgtype, &pkgid);
493 if (target_uid == (uid_t)-1 || pkgtype == NULL || pkgid == NULL) {
494 g_dbus_method_invocation_return_value(invocation,
495 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
499 reqkey = __generate_reqkey(pkgid);
500 if (reqkey == NULL) {
501 g_dbus_method_invocation_return_value(invocation,
502 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
505 if (_push_queue(target_uid, reqkey, REQUEST_TYPE_UNINSTALL, pkgtype,
507 g_dbus_method_invocation_return_value(invocation,
508 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
513 g_dbus_method_invocation_return_value(invocation,
514 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
520 static int __handle_request_move(uid_t uid,
521 GDBusMethodInvocation *invocation, GVariant *parameters)
523 uid_t target_uid = (uid_t)-1;
524 char *pkgtype = NULL;
528 char buf[4] = { '\0' };
530 g_variant_get(parameters, "(u&s&si)", &target_uid, &pkgtype, &pkgid,
532 if (target_uid == (uid_t)-1 || pkgtype == NULL || pkgid == NULL) {
533 g_dbus_method_invocation_return_value(invocation,
534 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
538 reqkey = __generate_reqkey(pkgid);
539 if (reqkey == NULL) {
540 g_dbus_method_invocation_return_value(invocation,
541 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
545 snprintf(buf, sizeof(buf), "%d", move_type);
546 if (_push_queue(target_uid, reqkey, REQUEST_TYPE_MOVE, pkgtype,
548 g_dbus_method_invocation_return_value(invocation,
549 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
554 g_dbus_method_invocation_return_value(invocation,
555 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
561 static int __handle_request_enable_pkgs(uid_t uid,
562 GDBusMethodInvocation *invocation, GVariant *parameters)
564 uid_t target_uid = (uid_t)-1;
565 char *pkgtype = NULL;
570 g_variant_get(parameters, "(u&sas)", &target_uid, &pkgtype, &iter);
571 if (target_uid == (uid_t)-1 || pkgtype == NULL || iter == NULL) {
572 g_dbus_method_invocation_return_value(invocation,
573 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
577 reqkey = __generate_reqkey("enable_pkgs");
578 if (reqkey == NULL) {
579 g_dbus_method_invocation_return_value(invocation,
580 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
584 while (g_variant_iter_next(iter, "&s", &pkgid)) {
585 if (_push_queue(target_uid, reqkey, REQUEST_TYPE_ENABLE_PKG,
586 pkgtype, pkgid, NULL)) {
587 g_dbus_method_invocation_return_value(invocation,
588 g_variant_new("(is)",
589 PKGMGR_R_ESYSTEM, ""));
595 g_dbus_method_invocation_return_value(invocation,
596 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
602 static int __handle_request_disable_pkgs(uid_t uid,
603 GDBusMethodInvocation *invocation, GVariant *parameters)
605 uid_t target_uid = (uid_t)-1;
606 char *pkgtype = NULL;
611 g_variant_get(parameters, "(u&sas)", &target_uid, &pkgtype, &iter);
612 if (target_uid == (uid_t)-1 || pkgtype == NULL || iter == NULL) {
613 g_dbus_method_invocation_return_value(invocation,
614 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
618 reqkey = __generate_reqkey("disable_pkgs");
619 if (reqkey == NULL) {
620 g_dbus_method_invocation_return_value(invocation,
621 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
625 while (g_variant_iter_next(iter, "&s", &pkgid)) {
626 if (_push_queue(target_uid, reqkey, REQUEST_TYPE_DISABLE_PKG,
627 pkgtype, pkgid, NULL)) {
628 g_dbus_method_invocation_return_value(invocation,
629 g_variant_new("(is)",
630 PKGMGR_R_ESYSTEM, ""));
636 g_dbus_method_invocation_return_value(invocation,
637 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
643 static int __handle_request_enable_app(uid_t uid,
644 GDBusMethodInvocation *invocation, GVariant *parameters)
646 uid_t target_uid = (uid_t)-1;
651 g_variant_get(parameters, "(u&s)", &target_uid, &appid);
652 if (target_uid == (uid_t)-1 || appid == NULL) {
653 g_dbus_method_invocation_return_value(invocation,
654 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
658 reqkey = __generate_reqkey(appid);
659 if (reqkey == NULL) {
660 g_dbus_method_invocation_return_value(invocation,
661 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
666 if (_push_queue(target_uid, reqkey, REQUEST_TYPE_ENABLE_APP, "default",
668 g_dbus_method_invocation_return_value(invocation,
669 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
674 g_dbus_method_invocation_return_value(invocation,
675 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
686 static int __handle_request_disable_app(uid_t uid,
687 GDBusMethodInvocation *invocation, GVariant *parameters)
689 uid_t target_uid = (uid_t)-1;
694 g_variant_get(parameters, "(u&s)", &target_uid, &appid);
695 if (target_uid == (uid_t)-1 || appid == NULL) {
696 g_dbus_method_invocation_return_value(invocation,
697 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
701 reqkey = __generate_reqkey(appid);
702 if (reqkey == NULL) {
703 g_dbus_method_invocation_return_value(invocation,
704 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
709 if (_push_queue(target_uid, reqkey, REQUEST_TYPE_DISABLE_APP, "default",
711 g_dbus_method_invocation_return_value(invocation,
712 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
717 g_dbus_method_invocation_return_value(invocation,
718 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
729 static int __handle_request_enable_global_app_for_uid(uid_t uid,
730 GDBusMethodInvocation *invocation, GVariant *parameters)
732 uid_t target_uid = (uid_t)-1;
737 g_variant_get(parameters, "(u&s)", &target_uid, &appid);
738 if (target_uid == (uid_t)-1 || appid == NULL) {
739 g_dbus_method_invocation_return_value(invocation,
740 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
744 reqkey = __generate_reqkey(appid);
745 if (reqkey == NULL) {
746 g_dbus_method_invocation_return_value(invocation,
747 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
752 if (_push_queue(target_uid, reqkey,
753 REQUEST_TYPE_ENABLE_GLOBAL_APP_FOR_UID,
754 "default", appid, NULL)) {
755 g_dbus_method_invocation_return_value(invocation,
756 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
761 g_dbus_method_invocation_return_value(invocation,
762 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
773 static int __handle_request_disable_global_app_for_uid(uid_t uid,
774 GDBusMethodInvocation *invocation, GVariant *parameters)
776 uid_t target_uid = (uid_t)-1;
781 g_variant_get(parameters, "(u&s)", &target_uid, &appid);
782 if (target_uid == (uid_t)-1 || appid == NULL) {
783 g_dbus_method_invocation_return_value(invocation,
784 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
788 reqkey = __generate_reqkey(appid);
789 if (reqkey == NULL) {
790 g_dbus_method_invocation_return_value(invocation,
791 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
796 if (_push_queue(target_uid, reqkey,
797 REQUEST_TYPE_DISABLE_GLOBAL_APP_FOR_UID,
798 "default", appid, NULL)) {
799 g_dbus_method_invocation_return_value(invocation,
800 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
805 g_dbus_method_invocation_return_value(invocation,
806 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
817 static int __handle_request_getsize(uid_t uid,
818 GDBusMethodInvocation *invocation, GVariant *parameters)
820 uid_t target_uid = (uid_t)-1;
826 g_variant_get(parameters, "(u&si)", &target_uid, &pkgid, &get_type);
827 if (target_uid == (uid_t)-1 || pkgid == NULL || get_type == -1) {
828 g_dbus_method_invocation_return_value(invocation,
829 g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
833 reqkey = __generate_reqkey(pkgid);
834 if (reqkey == NULL) {
835 g_dbus_method_invocation_return_value(invocation,
836 g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
840 snprintf(buf, sizeof(buf), "%d", get_type);
841 if (_push_queue(target_uid, reqkey, REQUEST_TYPE_GETSIZE, "pkgtool",
843 g_dbus_method_invocation_return_value(invocation,
844 g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
849 g_dbus_method_invocation_return_value(invocation,
850 g_variant_new("(is)", PKGMGR_R_OK, reqkey));
856 static int __handle_request_cleardata(uid_t uid,
857 GDBusMethodInvocation *invocation, GVariant *parameters)
859 uid_t target_uid = (uid_t)-1;
860 char *pkgtype = NULL;
864 g_variant_get(parameters, "(u&s&s)", &target_uid, &pkgtype, &pkgid);
865 if (target_uid == (uid_t)-1 || pkgtype == NULL || pkgid == NULL) {
866 g_dbus_method_invocation_return_value(invocation,
867 g_variant_new("(i)", PKGMGR_R_ECOMM));
871 reqkey = __generate_reqkey(pkgid);
872 if (reqkey == NULL) {
873 g_dbus_method_invocation_return_value(invocation,
874 g_variant_new("(i)", PKGMGR_R_ENOMEM));
878 if (_push_queue(target_uid, reqkey, REQUEST_TYPE_CLEARDATA, pkgtype,
880 g_dbus_method_invocation_return_value(invocation,
881 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
886 g_dbus_method_invocation_return_value(invocation,
887 g_variant_new("(i)", PKGMGR_R_OK));
894 static int __handle_request_clearcache(uid_t uid,
895 GDBusMethodInvocation *invocation, GVariant *parameters)
897 uid_t target_uid = (uid_t)-1;
900 g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
901 if (target_uid == (uid_t)-1 || pkgid == NULL) {
902 g_dbus_method_invocation_return_value(invocation,
903 g_variant_new("(i)", PKGMGR_R_ECOMM));
907 if (_push_queue(target_uid, NULL, REQUEST_TYPE_CLEARCACHE,
908 "pkgtool", pkgid, NULL)) {
909 g_dbus_method_invocation_return_value(invocation,
910 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
914 g_dbus_method_invocation_return_value(invocation,
915 g_variant_new("(i)", PKGMGR_R_OK));
920 static int __handle_request_kill(uid_t uid,
921 GDBusMethodInvocation *invocation, GVariant *parameters)
923 uid_t target_uid = (uid_t)-1;
927 g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
928 if (target_uid == (uid_t)-1 || pkgid == NULL) {
929 g_dbus_method_invocation_return_value(invocation,
930 g_variant_new("(ii)", PKGMGR_R_ECOMM, 0));
934 reqkey = __generate_reqkey(pkgid);
935 if (reqkey == NULL) {
936 g_dbus_method_invocation_return_value(invocation,
937 g_variant_new("(ii)", PKGMGR_R_ENOMEM, 0));
941 if (_push_queue(target_uid, reqkey, REQUEST_TYPE_KILL,
942 "default", pkgid, NULL)) {
943 g_dbus_method_invocation_return_value(invocation,
944 g_variant_new("(ii)", PKGMGR_R_ESYSTEM, 0));
949 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
950 (gpointer)invocation))
951 ERR("reqkey already exists");
956 static int __handle_request_check(uid_t uid,
957 GDBusMethodInvocation *invocation, GVariant *parameters)
959 uid_t target_uid = (uid_t)-1;
963 g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
964 if (target_uid == (uid_t)-1 || pkgid == NULL) {
965 g_dbus_method_invocation_return_value(invocation,
966 g_variant_new("(ii)", PKGMGR_R_ECOMM, 0));
970 reqkey = __generate_reqkey(pkgid);
971 if (reqkey == NULL) {
972 g_dbus_method_invocation_return_value(invocation,
973 g_variant_new("(ii)", PKGMGR_R_ENOMEM, 0));
977 if (_push_queue(target_uid, reqkey, REQUEST_TYPE_CHECK,
978 "default", pkgid, NULL)) {
979 g_dbus_method_invocation_return_value(invocation,
980 g_variant_new("(ii)", PKGMGR_R_ESYSTEM, 0));
985 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
986 (gpointer)invocation))
987 ERR("reqkey already exists");
992 static int __handle_request_generate_license_request(uid_t uid,
993 GDBusMethodInvocation *invocation, GVariant *parameters)
996 char *resp_data = NULL;
998 g_variant_get(parameters, "(&s)", &resp_data);
999 if (resp_data == NULL) {
1000 g_dbus_method_invocation_return_value(invocation,
1001 g_variant_new("(iss)", PKGMGR_R_ECOMM, "", ""));
1005 reqkey = __generate_reqkey("drm");
1006 if (reqkey == NULL) {
1007 g_dbus_method_invocation_return_value(invocation,
1008 g_variant_new("(iss)", PKGMGR_R_ENOMEM, "",
1013 if (_push_queue(uid, reqkey,
1014 REQUEST_TYPE_GENERATE_LICENSE_REQUEST,
1015 "default", NULL, resp_data)) {
1016 g_dbus_method_invocation_return_value(invocation,
1017 g_variant_new("(iss)", PKGMGR_R_ESYSTEM, "",
1023 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1024 (gpointer)invocation))
1025 ERR("reqkey already exists");
1030 static int __handle_request_register_license(uid_t uid,
1031 GDBusMethodInvocation *invocation, GVariant *parameters)
1034 char *resp_data = NULL;
1036 g_variant_get(parameters, "(&s)", &resp_data);
1037 if (resp_data == NULL) {
1038 g_dbus_method_invocation_return_value(invocation,
1039 g_variant_new("(i)", PKGMGR_R_ECOMM));
1043 reqkey = __generate_reqkey("drm");
1044 if (reqkey == NULL) {
1045 g_dbus_method_invocation_return_value(invocation,
1046 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1050 if (_push_queue(uid, reqkey, REQUEST_TYPE_REGISTER_LICENSE,
1051 "default", NULL, resp_data)) {
1052 g_dbus_method_invocation_return_value(invocation,
1053 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1058 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1059 (gpointer)invocation))
1060 ERR("reqkey already exists");
1065 static int __handle_request_decrypt_package(uid_t uid,
1066 GDBusMethodInvocation *invocation, GVariant *parameters)
1069 char *drm_file_path = NULL;
1070 char *decrypted_file_path = NULL;
1072 g_variant_get(parameters, "(&s&s)", &drm_file_path,
1073 &decrypted_file_path);
1074 if (drm_file_path == NULL || decrypted_file_path == NULL) {
1075 g_dbus_method_invocation_return_value(invocation,
1076 g_variant_new("(i)", PKGMGR_R_ECOMM));
1080 reqkey = __generate_reqkey("drm");
1081 if (reqkey == NULL) {
1082 g_dbus_method_invocation_return_value(invocation,
1083 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1087 if (_push_queue(uid, reqkey, REQUEST_TYPE_DECRYPT_PACKAGE,
1088 "default", drm_file_path,
1089 decrypted_file_path)) {
1090 g_dbus_method_invocation_return_value(invocation,
1091 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1096 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1097 (gpointer)invocation))
1098 ERR("reqkey already exists");
1103 static int __update_app_splash_screen(uid_t uid,
1104 GDBusMethodInvocation *invocation, GVariant *parameters,
1107 uid_t target_uid = (uid_t)-1;
1111 g_variant_get(parameters, "(u&s)", &target_uid, &appid);
1112 if (target_uid == (uid_t)-1 || appid == NULL) {
1113 ERR("target_uid: %d, appid: %s", target_uid, appid);
1114 g_dbus_method_invocation_return_value(invocation,
1115 g_variant_new("(i)", PKGMGR_R_ECOMM));
1119 reqkey = __generate_reqkey(appid);
1120 if (reqkey == NULL) {
1121 ERR("Failed to generate request key");
1122 g_dbus_method_invocation_return_value(invocation,
1123 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1127 if (_push_queue(target_uid, reqkey, req_type, "default",
1129 ERR("Failed to push request");
1130 g_dbus_method_invocation_return_value(invocation,
1131 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1136 g_dbus_method_invocation_return_value(invocation,
1137 g_variant_new("(i)", PKGMGR_R_OK));
1145 static int __handle_request_enable_app_splash_screen(uid_t uid,
1146 GDBusMethodInvocation *invocation, GVariant *parameters)
1148 return __update_app_splash_screen(uid, invocation, parameters,
1149 REQUEST_TYPE_ENABLE_APP_SPLASH_SCREEN);
1152 static int __handle_request_disable_app_splash_screen(uid_t uid,
1153 GDBusMethodInvocation *invocation, GVariant *parameters)
1155 return __update_app_splash_screen(uid, invocation, parameters,
1156 REQUEST_TYPE_DISABLE_APP_SPLASH_SCREEN);
1159 static int __handle_request_set_restriction_mode(uid_t uid,
1160 GDBusMethodInvocation *invocation, GVariant *parameters)
1162 uid_t target_uid = (uid_t)-1;
1168 g_variant_get(parameters, "(usi)", &target_uid, &pkgid, &mode);
1169 if (target_uid == (uid_t)-1 || pkgid == NULL || mode < 0) {
1170 g_dbus_method_invocation_return_value(invocation,
1171 g_variant_new("(i)", PKGMGR_R_ECOMM));
1175 reqkey = __generate_reqkey("restriction");
1176 if (reqkey == NULL) {
1177 g_dbus_method_invocation_return_value(invocation,
1178 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1182 snprintf(buf, sizeof(buf), "%d", mode);
1183 if (_push_queue(target_uid, reqkey,
1184 REQUEST_TYPE_SET_RESTRICTION_MODE,
1185 "default", pkgid, buf)) {
1186 g_dbus_method_invocation_return_value(invocation,
1187 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1192 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1193 (gpointer)invocation))
1194 ERR("reqkey already exists");
1199 static int __handle_request_unset_restriction_mode(uid_t uid,
1200 GDBusMethodInvocation *invocation, GVariant *parameters)
1202 uid_t target_uid = (uid_t)-1;
1208 g_variant_get(parameters, "(usi)", &target_uid, &pkgid, &mode);
1209 if (target_uid == (uid_t)-1 || pkgid == NULL || mode < 0) {
1210 g_dbus_method_invocation_return_value(invocation,
1211 g_variant_new("(i)", PKGMGR_R_ECOMM));
1215 reqkey = __generate_reqkey("restriction");
1216 if (reqkey == NULL) {
1217 g_dbus_method_invocation_return_value(invocation,
1218 g_variant_new("(i)", PKGMGR_R_ENOMEM));
1222 snprintf(buf, sizeof(buf), "%d", mode);
1223 if (_push_queue(target_uid, reqkey,
1224 REQUEST_TYPE_UNSET_RESTRICTION_MODE,
1225 "default", pkgid, buf)) {
1226 g_dbus_method_invocation_return_value(invocation,
1227 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1232 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1233 (gpointer)invocation))
1234 ERR("reqkey already exists");
1239 static int __handle_request_get_restriction_mode(uid_t uid,
1240 GDBusMethodInvocation *invocation, GVariant *parameters)
1242 uid_t target_uid = (uid_t)-1;
1246 g_variant_get(parameters, "(us)", &target_uid, &pkgid);
1247 if (target_uid == (uid_t)-1 || pkgid == NULL) {
1248 g_dbus_method_invocation_return_value(invocation,
1249 g_variant_new("(i)", PKGMGR_R_ECOMM));
1253 reqkey = __generate_reqkey("restriction");
1254 if (reqkey == NULL) {
1255 g_dbus_method_invocation_return_value(invocation,
1256 g_variant_new("(ii)", -1, PKGMGR_R_ENOMEM));
1260 if (_push_queue(target_uid, reqkey,
1261 REQUEST_TYPE_GET_RESTRICTION_MODE,
1262 "default", pkgid, NULL)) {
1263 g_dbus_method_invocation_return_value(invocation,
1264 g_variant_new("(ii)", -1, PKGMGR_R_ESYSTEM));
1269 if (!g_hash_table_insert(req_table, (gpointer)reqkey,
1270 (gpointer)invocation))
1271 ERR("reqkey already exists");
1276 static uid_t __get_caller_uid(GDBusConnection *connection, const char *name)
1282 result = g_dbus_connection_call_sync(connection,
1283 "org.freedesktop.DBus", "/org/freedesktop/DBus",
1284 "org.freedesktop.DBus", "GetConnectionUnixUser",
1285 g_variant_new("(s)", name), NULL,
1286 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
1287 if (result == NULL) {
1288 ERR("failed to get caller uid: %s", err->message);
1293 g_variant_get(result, "(u)", &uid);
1298 static void __handle_method_call(GDBusConnection *connection,
1299 const gchar *sender, const gchar *object_path,
1300 const gchar *interface_name, const gchar *method_name,
1301 GVariant *parameters, GDBusMethodInvocation *invocation,
1307 uid = __get_caller_uid(connection,
1308 g_dbus_method_invocation_get_sender(invocation));
1309 if (uid == (uid_t)-1)
1312 if (__check_caller_permission(uid, invocation, parameters))
1315 if (g_strcmp0(method_name, "install") == 0)
1316 ret = __handle_request_install(uid, invocation, parameters);
1317 else if (g_strcmp0(method_name, "mount_install") == 0)
1318 ret = __handle_request_mount_install(uid, invocation,
1320 else if (g_strcmp0(method_name, "reinstall") == 0)
1321 ret = __handle_request_reinstall(uid, invocation, parameters);
1322 else if (g_strcmp0(method_name, "uninstall") == 0)
1323 ret = __handle_request_uninstall(uid, invocation, parameters);
1324 else if (g_strcmp0(method_name, "cleardata") == 0)
1325 ret = __handle_request_cleardata(uid, invocation, parameters);
1326 else if (g_strcmp0(method_name, "move") == 0)
1327 ret = __handle_request_move(uid, invocation, parameters);
1328 else if (g_strcmp0(method_name, "enable_pkgs") == 0)
1329 ret = __handle_request_enable_pkgs(uid, invocation, parameters);
1330 else if (g_strcmp0(method_name, "disable_pkgs") == 0)
1331 ret = __handle_request_disable_pkgs(uid, invocation, parameters);
1332 else if (g_strcmp0(method_name, "getsize") == 0)
1333 ret = __handle_request_getsize(uid, invocation, parameters);
1334 else if (g_strcmp0(method_name, "clearcache") == 0)
1335 ret = __handle_request_clearcache(uid, invocation, parameters);
1336 else if (g_strcmp0(method_name, "enable_app") == 0)
1337 ret = __handle_request_enable_app(uid, invocation, parameters);
1338 else if (g_strcmp0(method_name, "disable_app") == 0)
1339 ret = __handle_request_disable_app(uid, invocation, parameters);
1340 else if (g_strcmp0(method_name, "enable_global_app_for_uid") == 0)
1341 ret = __handle_request_enable_global_app_for_uid(uid,
1342 invocation, parameters);
1343 else if (g_strcmp0(method_name, "disable_global_app_for_uid") == 0)
1344 ret = __handle_request_disable_global_app_for_uid(uid,
1345 invocation, parameters);
1346 else if (g_strcmp0(method_name, "kill") == 0)
1347 ret = __handle_request_kill(uid, invocation, parameters);
1348 else if (g_strcmp0(method_name, "check") == 0)
1349 ret = __handle_request_check(uid, invocation, parameters);
1350 else if (g_strcmp0(method_name, "generate_license_request") == 0)
1351 ret = __handle_request_generate_license_request(uid, invocation,
1353 else if (g_strcmp0(method_name, "register_license") == 0)
1354 ret = __handle_request_register_license(uid, invocation,
1356 else if (g_strcmp0(method_name, "decrypt_package") == 0)
1357 ret = __handle_request_decrypt_package(uid, invocation,
1359 else if (g_strcmp0(method_name, "disable_app_splash_screen") == 0)
1360 ret = __handle_request_disable_app_splash_screen(uid,
1361 invocation, parameters);
1362 else if (g_strcmp0(method_name, "enable_app_splash_screen") == 0)
1363 ret = __handle_request_enable_app_splash_screen(uid,
1364 invocation, parameters);
1365 else if (g_strcmp0(method_name, "set_restriction_mode") == 0)
1366 ret = __handle_request_set_restriction_mode(uid, invocation,
1368 else if (g_strcmp0(method_name, "unset_restriction_mode") == 0)
1369 ret = __handle_request_unset_restriction_mode(uid, invocation,
1371 else if (g_strcmp0(method_name, "get_restriction_mode") == 0)
1372 ret = __handle_request_get_restriction_mode(uid, invocation,
1378 g_idle_add(queue_job, NULL);
1381 int _return_value_to_caller(const char *req_key, GVariant *result)
1383 GDBusMethodInvocation *invocation;
1385 invocation = (GDBusMethodInvocation *)g_hash_table_lookup(req_table,
1387 if (invocation == NULL) {
1388 ERR("no such request id");
1392 g_dbus_method_invocation_return_value(invocation, result);
1393 g_hash_table_remove(req_table, (gpointer)req_key);
1398 static const GDBusInterfaceVTable interface_vtable = {
1399 __handle_method_call,
1404 static void __on_bus_acquired(GDBusConnection *connection, const gchar *name,
1409 DBG("on bus acquired");
1411 reg_id = g_dbus_connection_register_object(connection,
1412 PKGMGR_DBUS_OBJECT_PATH,
1413 instropection_data->interfaces[0],
1414 &interface_vtable, NULL, NULL, &err);
1417 ERR("failed to register object: %s", err->message);
1422 static void __on_name_acquired(GDBusConnection *connection, const gchar *name,
1425 DBG("on name acquired: %s", name);
1428 static void __on_name_lost(GDBusConnection *connection, const gchar *name,
1431 DBG("on name lost: %s", name);
1434 int _init_request_handler(void)
1436 instropection_data = g_dbus_node_info_new_for_xml(instropection_xml,
1439 owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, PKGMGR_DBUS_SERVICE,
1440 G_BUS_NAME_OWNER_FLAGS_NONE, __on_bus_acquired,
1441 __on_name_acquired, __on_name_lost, NULL, NULL);
1443 req_table = g_hash_table_new_full(g_str_hash, g_str_equal,
1445 if (req_table == NULL)
1451 void _fini_request_handler(void)
1453 g_hash_table_destroy(req_table);
1454 g_bus_unown_name(owner_id);
1455 g_dbus_node_info_unref(instropection_data);