Fix static analysis tool issue
[platform/core/appfw/app2sd.git] / plugin / app2sd / server / app2sd_server.c
1 /*
2  * app2sd-server
3  *
4  * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include <gio/gio.h>
21
22 #include "app2sd_internals.h"
23
24 #define APPFW_UID 301
25
26 int processing_busy_cnt;
27 guint source_id;
28
29 GMainLoop *app2sd_mainloop = NULL;
30
31 static void __free_dir_detail(gpointer data)
32 {
33         app2ext_dir_details *dir_detail = (app2ext_dir_details *)data;
34
35         if (dir_detail->name)
36                 free(dir_detail->name);
37         free(dir_detail);
38 }
39
40 gboolean __exit_app2sd_server(void *data)
41 {
42         if (processing_busy_cnt <= 0) {
43                 _D("exit app2sd_server");
44                 g_main_loop_quit(app2sd_mainloop);
45                 return FALSE;
46         }
47
48         _D("processing busy, count(%d)", processing_busy_cnt);
49         return TRUE;
50 }
51
52 static int __app2sd_get_sender_unixinfo(GDBusConnection *conn,
53                 const char *sender_name, const char *type)
54 {
55         GDBusMessage *msg = NULL;
56         GDBusMessage *reply = NULL;
57         GError *err = NULL;
58         GVariant *body;
59         int ret = -1;
60         unsigned int value;
61
62         msg = g_dbus_message_new_method_call("org.freedesktop.DBus",
63                 "/org/freedesktop/DBus", "org.freedesktop.DBus", type);
64         if (!msg) {
65                 _E("Can't allocate new method call");
66                 goto out;
67         }
68
69         g_dbus_message_set_body(msg, g_variant_new("(s)", sender_name));
70         reply = g_dbus_connection_send_message_with_reply_sync(conn, msg,
71                 G_DBUS_SEND_MESSAGE_FLAGS_NONE, -1, NULL, NULL, &err);
72
73         if (!reply) {
74                 if (err != NULL) {
75                         _E("Failed to get info [%s]", err->message);
76                         g_error_free(err);
77                 }
78                 goto out;
79         }
80
81         body = g_dbus_message_get_body(reply);
82         g_variant_get(body, "(u)", &value);
83         ret = (int)value;
84
85 out:
86         if (msg)
87                 g_object_unref(msg);
88         if (reply)
89                 g_object_unref(reply);
90
91         return ret;
92 }
93
94 /*
95 static int __app2sd_get_sender_pid(GDBusConnection *conn,
96                 const char *sender_name)
97 {
98         int pid = 0;
99
100         pid = __app2sd_get_sender_unixinfo(conn, sender_name,
101                 "GetConnectionUnixProcessID");
102         if (pid < 0) {
103                 _E("failed to get pid");
104                 pid = 0;
105         }
106
107         _D("sender_name(%s), pid(%d)", sender_name, pid);
108
109         return pid;
110 }
111 */
112
113 static int __app2sd_get_sender_uid(GDBusConnection *conn,
114                 const char *sender_name)
115 {
116         int uid = -1;
117
118         uid = __app2sd_get_sender_unixinfo(conn, sender_name,
119                 "GetConnectionUnixUser");
120         if (uid < 0)
121                 _E("failed to get uid");
122
123         _D("sender_name(%s), uid(%d)", sender_name, uid);
124
125         return uid;
126 }
127
128 static GDBusNodeInfo *introspection_data;
129 static const gchar introspection_xml[] =
130 "<node>"
131 "       <interface name='org.tizen.app2sd'>"
132 "               <method name='PreAppInstall'>"
133 "                       <arg type='s' name='pkgid' direction='in'/>"
134 "                       <arg type='i' name='size' direction='in'/>"
135 "                       <arg type='a(si)' name='dir_list' direction='in'/>"
136 "                       <arg type='i' name='uid' direction='in'/>"
137 "                       <arg type='i' name='result' direction='out'/>"
138 "               </method>"
139 "               <method name='PostAppInstall'>"
140 "                       <arg type='s' name='pkgid' direction='in'/>"
141 "                       <arg type='i' name='install_status' direction='in'/>"
142 "                       <arg type='i' name='uid' direction='in'/>"
143 "                       <arg type='i' name='result' direction='out'/>"
144 "               </method>"
145 "               <method name='PreAppUpgrade'>"
146 "                       <arg type='s' name='pkgid' direction='in'/>"
147 "                       <arg type='i' name='size' direction='in'/>"
148 "                       <arg type='a(si)' name='dir_list' direction='in'/>"
149 "                       <arg type='i' name='uid' direction='in'/>"
150 "                       <arg type='i' name='result' direction='out'/>"
151 "               </method>"
152 "               <method name='PostAppUpgrade'>"
153 "                       <arg type='s' name='pkgid' direction='in'/>"
154 "                       <arg type='i' name='install_status' direction='in'/>"
155 "                       <arg type='i' name='uid' direction='in'/>"
156 "                       <arg type='i' name='result' direction='out'/>"
157 "               </method>"
158 "               <method name='PreAppUninstall'>"
159 "                       <arg type='s' name='pkgid' direction='in'/>"
160 "                       <arg type='i' name='uid' direction='in'/>"
161 "                       <arg type='i' name='result' direction='out'/>"
162 "               </method>"
163 "               <method name='PostAppUninstall'>"
164 "                       <arg type='s' name='pkgid' direction='in'/>"
165 "                       <arg type='i' name='uid' direction='in'/>"
166 "                       <arg type='i' name='result' direction='out'/>"
167 "               </method>"
168 "               <method name='OndemandSetupInit'>"
169 "                       <arg type='s' name='pkgid' direction='in'/>"
170 "                       <arg type='i' name='uid' direction='in'/>"
171 "                       <arg type='i' name='result' direction='out'/>"
172 "               </method>"
173 "               <method name='OndemandSetupExit'>"
174 "                       <arg type='s' name='pkgid' direction='in'/>"
175 "                       <arg type='i' name='uid' direction='in'/>"
176 "                       <arg type='i' name='result' direction='out'/>"
177 "               </method>"
178 "               <method name='PreMoveInstalledApp'>"
179 "                       <arg type='s' name='pkgid' direction='in'/>"
180 "                       <arg type='i' name='move_type' direction='in'/>"
181 "                       <arg type='a(si)' name='dir_list' direction='in'/>"
182 "                       <arg type='i' name='uid' direction='in'/>"
183 "                       <arg type='i' name='result' direction='out'/>"
184 "               </method>"
185 "               <method name='PostMoveInstalledApp'>"
186 "                       <arg type='s' name='pkgid' direction='in'/>"
187 "                       <arg type='i' name='move_type' direction='in'/>"
188 "                       <arg type='i' name='uid' direction='in'/>"
189 "                       <arg type='i' name='result' direction='out'/>"
190 "               </method>"
191 "               <method name='ForceClean'>"
192 "                       <arg type='s' name='pkgid' direction='in'/>"
193 "                       <arg type='i' name='uid' direction='in'/>"
194 "                       <arg type='i' name='result' direction='out'/>"
195 "               </method>"
196 "               <method name='EnableFullPkg'>"
197 "                       <arg type='i' name='result' direction='out'/>"
198 "               </method>"
199 "               <method name='DisableFullPkg'>"
200 "                       <arg type='i' name='result' direction='out'/>"
201 "               </method>"
202 "       </interface>"
203 "</node>";
204
205 static bool _app2sd_server_check_permission(uid_t sender_uid, uid_t target_uid)
206 {
207         if (sender_uid != 0 && sender_uid != APPFW_UID && sender_uid != target_uid) {
208                 _E("Not permitted user!, uid(%d)", sender_uid);
209                 return false;
210         }
211
212         return true;
213 }
214
215 static void _app2sd_server_return_method_error(GDBusMethodInvocation *invocation, int result)
216 {
217         GVariant *param = NULL;
218
219         param = g_variant_new("(i)", result);
220         g_dbus_method_invocation_return_value(invocation, param);
221 }
222
223 static void _app2sd_server_pre_app_install(GDBusConnection *connection, const gchar *sender,
224         GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
225 {
226         GVariant *param = NULL;
227         int result = APP2EXT_SUCCESS;
228         int size;
229         char *pkgid = NULL;
230         GVariantIter *iter;
231         gchar *str = NULL;
232         int type;
233         int ret = 0;
234         uid_t target_uid = -1;
235         GList *dir_list = NULL;
236         GList *list = NULL;
237         app2ext_dir_details *dir_detail = NULL;
238
239         g_variant_get(parameters, "(&sia(si)i)", &pkgid, &size, &iter, &target_uid);
240
241         _D("pkgid(%s), size(%d),sender_uid(%d), target_uid(%d)",
242                 pkgid, size, sender_uid, target_uid);
243
244         if (!_app2sd_server_check_permission(sender_uid, target_uid)) {
245                 _E("Not permitted user!");
246                 g_variant_iter_free(iter);
247                 _app2sd_server_return_method_error(invocation,
248                         APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
249                 return;
250         }
251
252         while (g_variant_iter_loop(iter, "(si)", &str, &type)) {
253                 if (str) {
254                         _D("str(%s), type(%d)", str, type);
255
256                         /* generate dir_list */
257                         dir_detail = (app2ext_dir_details *)calloc(1, sizeof(app2ext_dir_details));
258                         if (dir_detail == NULL) {
259                                 _E("memory allocation failed");
260                                 result = APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
261                                 break;
262                         }
263
264                         dir_detail->name = strdup((char *)str);
265                         if (dir_detail->name == NULL) {
266                                 _E("out of memory");
267                                 free(dir_detail);
268                                 result = APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
269                                 break;
270                         }
271
272                         dir_detail->type = type;
273                         list = g_list_append(list, dir_detail);
274                 }
275         }
276         g_variant_iter_free(iter);
277
278         dir_list = g_list_first(list);
279         ret = app2sd_usr_pre_app_install(pkgid, dir_list, size, target_uid);
280         if (ret) {
281                 _E("error(%d)", ret);
282                 result = ret;
283         }
284         g_list_free_full(dir_list, __free_dir_detail);
285
286         param = g_variant_new("(i)", result);
287         g_dbus_method_invocation_return_value(invocation, param);
288 }
289
290 static void _app2sd_server_post_app_install(GDBusConnection *connection, const gchar *sender,
291         GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
292 {
293         GVariant *param = NULL;
294         int result = APP2EXT_SUCCESS;
295         char *pkgid = NULL;
296         int install_status = 0;
297         int target_uid = -1;
298         int ret = 0;
299
300         g_variant_get(parameters, "(&sii)", &pkgid, &install_status, &target_uid);
301
302         _D("pkgid(%s), install_status(%d), sender_uid(%d), target_uid(%d)",
303                 pkgid, install_status, sender_uid, target_uid);
304
305         if (!_app2sd_server_check_permission(sender_uid, target_uid)) {
306                 _E("Not permitted user!");
307                 _app2sd_server_return_method_error(invocation,
308                         APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
309                 return;
310         }
311
312         ret = app2sd_usr_post_app_install(pkgid, install_status, target_uid);
313         if (ret) {
314                 _E("error(%d)", ret);
315                 result = ret;
316         }
317
318         param = g_variant_new("(i)", result);
319         g_dbus_method_invocation_return_value(invocation, param);
320 }
321
322 static void _app2sd_server_pre_app_upgrade(GDBusConnection *connection, const gchar *sender,
323         GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
324 {
325         GVariant *param = NULL;
326         int result = APP2EXT_SUCCESS;
327         int size;
328         char *pkgid = NULL;
329         GVariantIter *iter;
330         gchar *str = NULL;
331         int type;
332         uid_t target_uid = -1;
333         int ret = 0;
334         GList *dir_list = NULL;
335         GList *list = NULL;
336         app2ext_dir_details *dir_detail = NULL;
337
338         g_variant_get(parameters, "(&sia(si)i)", &pkgid, &size, &iter, &target_uid);
339
340         _D("pkgid(%s), size(%d), sender_uid(%d), target_uid(%d)",
341                 pkgid, size, sender_uid, target_uid);
342
343         if (!_app2sd_server_check_permission(sender_uid, target_uid)) {
344                 _E("Not permitted user!");
345                 g_variant_iter_free(iter);
346                 _app2sd_server_return_method_error(invocation,
347                         APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
348                 return;
349         }
350
351         while (g_variant_iter_loop(iter, "(si)", &str, &type)) {
352                 if (str) {
353                         _D("str(%s), type(%d)", str, type);
354
355                         /* generate dir_list */
356                         dir_detail = (app2ext_dir_details *)calloc(1, sizeof(app2ext_dir_details));
357                         if (dir_detail == NULL) {
358                                 _E("memory allocation failed");
359                                 result = APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
360                                 break;
361                         }
362
363                         dir_detail->name = strdup((char *)str);
364                         if (dir_detail->name == NULL) {
365                                 _E("out of memory");
366                                 free(dir_detail);
367                                 result = APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
368                                 break;
369                         }
370
371                         dir_detail->type = type;
372                         list = g_list_append(list, dir_detail);
373                 }
374         }
375         g_variant_iter_free(iter);
376
377         dir_list = g_list_first(list);
378         ret = app2sd_usr_pre_app_upgrade(pkgid, dir_list, size, target_uid);
379         if (ret) {
380                 _E("error(%d)", ret);
381                 result = ret;
382         }
383         g_list_free_full(dir_list, __free_dir_detail);
384
385         param = g_variant_new("(i)", result);
386         g_dbus_method_invocation_return_value(invocation, param);
387 }
388
389 static void _app2sd_server_post_app_upgrade(GDBusConnection *connection, const gchar *sender,
390         GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
391 {
392         GVariant *param = NULL;
393         int result = APP2EXT_SUCCESS;
394         char *pkgid = NULL;
395         int install_status = 0;
396         uid_t target_uid = -1;
397         int ret = 0;
398
399         g_variant_get(parameters, "(&sii)", &pkgid, &install_status, &target_uid);
400
401         _D("pkgid(%s), install_status(%d), sender_uid(%d), target_uid(%d)",
402                 pkgid, install_status, sender_uid, target_uid);
403
404         if (!_app2sd_server_check_permission(sender_uid, target_uid)) {
405                 _E("Not permitted user!");
406                 _app2sd_server_return_method_error(invocation,
407                         APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
408                 return;
409         }
410
411         ret = app2sd_usr_post_app_upgrade(pkgid, install_status, target_uid);
412         if (ret) {
413                 _E("error(%d)", ret);
414                 result = ret;
415         }
416
417         param = g_variant_new("(i)", result);
418         g_dbus_method_invocation_return_value(invocation, param);
419 }
420
421 static void _app2sd_server_pre_app_uninstall(GDBusConnection *connection, const gchar *sender,
422         GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
423 {
424         GVariant *param = NULL;
425         int result = APP2EXT_SUCCESS;
426         char *pkgid = NULL;
427         uid_t target_uid = -1;
428         int ret = 0;
429
430         g_variant_get(parameters, "(&si)", &pkgid, &target_uid);
431
432         _D("pkgid(%s), sender_uid(%d), target_uid(%d)",
433                 pkgid, sender_uid, target_uid);
434
435         if (!_app2sd_server_check_permission(sender_uid, target_uid)) {
436                 _E("Not permitted user!");
437                 _app2sd_server_return_method_error(invocation,
438                         APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
439                 return;
440         }
441
442         ret = app2sd_usr_pre_app_uninstall(pkgid, target_uid);
443         if (ret) {
444                 _E("error(%d)", ret);
445                 result = ret;
446         }
447
448         param = g_variant_new("(i)", result);
449         g_dbus_method_invocation_return_value(invocation, param);
450 }
451
452 static void _app2sd_server_post_app_uninstall(GDBusConnection *connection, const gchar *sender,
453         GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
454 {
455         GVariant *param = NULL;
456         int result = APP2EXT_SUCCESS;
457         char *pkgid = NULL;
458         uid_t target_uid = -1;
459         int ret = 0;
460
461         g_variant_get(parameters, "(&si)", &pkgid, &target_uid);
462
463         _D("pkgid(%s), sender_uid(%d), target_uid(%d)",
464                 pkgid, sender_uid, target_uid);
465
466         if (!_app2sd_server_check_permission(sender_uid, target_uid)) {
467                 _E("Not permitted user!");
468                 _app2sd_server_return_method_error(invocation,
469                         APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
470                 return;
471         }
472
473         ret = app2sd_usr_post_app_uninstall(pkgid, target_uid);
474         if (ret) {
475                 _E("error(%d)", ret);
476                 result = ret;
477         }
478
479         param = g_variant_new("(i)", result);
480         g_dbus_method_invocation_return_value(invocation, param);
481 }
482
483 static void _app2sd_server_ondemand_setup_init(GDBusConnection *connection, const gchar *sender,
484         GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
485 {
486         GVariant *param = NULL;
487         int result = APP2EXT_SUCCESS;
488         char *pkgid = NULL;
489         uid_t target_uid = -1;
490         int ret = 0;
491
492         g_variant_get(parameters, "(&si)", &pkgid, &target_uid);
493
494         _D("pkgid(%s), sender_uid(%d), target_uid(%d)",
495                 pkgid, sender_uid, target_uid);
496
497         if (!_app2sd_server_check_permission(sender_uid, target_uid)) {
498                 _E("Not permitted user!");
499                 _app2sd_server_return_method_error(invocation,
500                         APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
501                 return;
502         }
503
504         ret = app2sd_usr_on_demand_setup_init(pkgid, target_uid);
505         if (ret) {
506                 _E("error(%d)", ret);
507                 result = ret;
508         }
509
510         param = g_variant_new("(i)", result);
511         g_dbus_method_invocation_return_value(invocation, param);
512 }
513
514 static void _app2sd_server_ondemand_setup_exit(GDBusConnection *connection, const gchar *sender,
515         GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
516 {
517         GVariant *param = NULL;
518         int result = APP2EXT_SUCCESS;
519         char *pkgid = NULL;
520         uid_t target_uid = -1;
521         int ret = 0;
522
523         g_variant_get(parameters, "(&si)", &pkgid, &target_uid);
524
525         _D("pkgid(%s), sender_uid(%d), target_uid(%d)",
526                 pkgid, sender_uid, target_uid);
527
528         if (!_app2sd_server_check_permission(sender_uid, target_uid)) {
529                 _E("Not permitted user!");
530                 _app2sd_server_return_method_error(invocation,
531                         APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
532                 return;
533         }
534
535         ret = app2sd_usr_on_demand_setup_exit(pkgid, target_uid);
536         if (ret) {
537                 _E("error(%d)", ret);
538                 result = ret;
539         }
540
541         param = g_variant_new("(i)", result);
542         g_dbus_method_invocation_return_value(invocation, param);
543 }
544
545 static void _app2sd_server_pre_move_installed_app(GDBusConnection *connection,
546         const gchar *sender, GVariant *parameters,
547         GDBusMethodInvocation *invocation, uid_t sender_uid)
548 {
549         GVariant *param = NULL;
550         int result = APP2EXT_SUCCESS;
551         int move_type;
552         char *pkgid = NULL;
553         GVariantIter *iter;
554         gchar *str = NULL;
555         int type;
556         int ret = 0;
557         uid_t target_uid = -1;
558         GList *dir_list = NULL;
559         GList *list = NULL;
560         app2ext_dir_details *dir_detail = NULL;
561
562         g_variant_get(parameters, "(&sia(si)i)", &pkgid, &move_type, &iter, &target_uid);
563
564         _D("pkgid(%s), move_type(%d),sender_uid(%d), target_uid(%d)",
565                 pkgid, move_type, sender_uid, target_uid);
566
567         if (!_app2sd_server_check_permission(sender_uid, target_uid)) {
568                 _E("Not permitted user!");
569                 g_variant_iter_free(iter);
570                 _app2sd_server_return_method_error(invocation,
571                         APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
572                 return;
573         }
574
575         while (g_variant_iter_loop(iter, "(si)", &str, &type)) {
576                 if (str) {
577                         _D("str(%s), type(%d)", str, type);
578
579                         /* generate dir_list */
580                         dir_detail = (app2ext_dir_details *)calloc(1, sizeof(app2ext_dir_details));
581                         if (dir_detail == NULL) {
582                                 _E("memory allocation failed");
583                                 result = APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
584                                 break;
585                         }
586
587                         dir_detail->name = strdup((char *)str);
588                         if (dir_detail->name == NULL) {
589                                 _E("out of memory");
590                                 free(dir_detail);
591                                 result = APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
592                                 break;
593                         }
594
595                         dir_detail->type = type;
596                         list = g_list_append(list, dir_detail);
597                 }
598         }
599         g_variant_iter_free(iter);
600
601         dir_list = g_list_first(list);
602         ret = app2sd_usr_pre_move_installed_app(pkgid, dir_list, move_type, target_uid);
603         if (ret) {
604                 _E("pre_move error(%d)", ret);
605                 result = ret;
606         }
607
608         g_list_free_full(list, __free_dir_detail);
609         param = g_variant_new("(i)", result);
610         g_dbus_method_invocation_return_value(invocation, param);
611 }
612
613 static void _app2sd_server_post_move_installed_app(GDBusConnection *connection,
614         const gchar *sender, GVariant *parameters,
615         GDBusMethodInvocation *invocation, uid_t sender_uid)
616 {
617         GVariant *param = NULL;
618         int result = APP2EXT_SUCCESS;
619         int move_type;
620         char *pkgid = NULL;
621         int ret = 0;
622         uid_t target_uid = -1;
623
624         g_variant_get(parameters, "(&sii)", &pkgid, &move_type, &target_uid);
625
626         _D("pkgid(%s), move_type(%d),sender_uid(%d), target_uid(%d)",
627                 pkgid, move_type, sender_uid, target_uid);
628
629         if (!_app2sd_server_check_permission(sender_uid, target_uid)) {
630                 _E("Not permitted user!");
631                 _app2sd_server_return_method_error(invocation,
632                         APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
633                 return;
634         }
635
636         ret = app2sd_usr_post_move_installed_app(pkgid, move_type, target_uid);
637         if (ret) {
638                 _E("post_move error(%d)", ret);
639                 result = ret;
640         }
641
642         param = g_variant_new("(i)", result);
643         g_dbus_method_invocation_return_value(invocation, param);
644 }
645
646 static void _app2sd_server_force_clean(GDBusConnection *connection, const gchar *sender,
647         GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
648 {
649         GVariant *param = NULL;
650         int result = APP2EXT_SUCCESS;
651         char *pkgid = NULL;
652         uid_t target_uid = -1;
653         int ret = 0;
654
655         g_variant_get(parameters, "(&si)", &pkgid, &target_uid);
656
657         _D("pkgid(%s), sender_uid(%d), target_uid(%d)",
658                 pkgid, sender_uid, target_uid);
659
660         if (!_app2sd_server_check_permission(sender_uid, target_uid)) {
661                 _E("Not permitted user!");
662                 _app2sd_server_return_method_error(invocation,
663                         APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
664                 return;
665         }
666
667         ret = app2sd_usr_force_clean(pkgid, target_uid);
668         if (ret) {
669                 _E("error(%d)", ret);
670                 result = ret;
671         }
672
673         param = g_variant_new("(i)", result);
674         g_dbus_method_invocation_return_value(invocation, param);
675 }
676
677 static void _app2sd_server_enable_full_pkg(GDBusConnection *connection, const gchar *sender,
678         GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
679 {
680         GVariant *param = NULL;
681         int result = APP2EXT_SUCCESS;
682         int ret = 0;
683
684         _D("sender_uid(%d)", sender_uid);
685
686         if (sender_uid >= REGULAR_USER) {
687                 _E("Not permitted user!");
688                 _app2sd_server_return_method_error(invocation,
689                         APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
690                 return;
691         }
692
693         ret = app2sd_enable_full_pkg();
694         if (ret) {
695                 _E("error(%d)", ret);
696                 result = ret;
697         }
698
699         param = g_variant_new("(i)", result);
700         g_dbus_method_invocation_return_value(invocation, param);
701 }
702
703 static void _app2sd_server_disable_full_pkg(GDBusConnection *connection, const gchar *sender,
704         GVariant *parameters, GDBusMethodInvocation *invocation, uid_t sender_uid)
705 {
706         GVariant *param = NULL;
707         int result = APP2EXT_SUCCESS;
708         int ret = 0;
709
710         _D("sender_uid(%d)", sender_uid);
711
712         if (sender_uid >= REGULAR_USER) {
713                 _E("Not permitted user!");
714                 _app2sd_server_return_method_error(invocation,
715                         APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
716                 return;
717         }
718
719         ret = app2sd_disable_full_pkg();
720         if (ret) {
721                 _E("error(%d)", ret);
722                 result = ret;
723         }
724
725         param = g_variant_new("(i)", result);
726         g_dbus_method_invocation_return_value(invocation, param);
727 }
728
729 static void handle_method_call(GDBusConnection *connection,
730         const gchar *sender, const gchar *object_path,
731         const gchar *interface_name, const gchar *method_name,
732         GVariant *parameters, GDBusMethodInvocation *invocation,
733         gpointer user_data)
734 {
735         uid_t sender_uid = -1;
736
737         processing_busy_cnt++;
738
739         sender_uid = (uid_t)__app2sd_get_sender_uid(connection, sender);
740
741         if (g_strcmp0(method_name, "PreAppInstall") == 0) {
742                 _app2sd_server_pre_app_install(connection, sender,
743                         parameters, invocation, sender_uid);
744         } else if (g_strcmp0(method_name, "PostAppInstall") == 0) {
745                 _app2sd_server_post_app_install(connection, sender,
746                         parameters, invocation, sender_uid);
747         } else if (g_strcmp0(method_name, "PreAppUpgrade") == 0) {
748                 _app2sd_server_pre_app_upgrade(connection, sender,
749                         parameters, invocation, sender_uid);
750         } else if (g_strcmp0(method_name, "PostAppUpgrade") == 0) {
751                 _app2sd_server_post_app_upgrade(connection, sender,
752                         parameters, invocation, sender_uid);
753         } else if (g_strcmp0(method_name, "PreAppUninstall") == 0) {
754                 _app2sd_server_pre_app_uninstall(connection, sender,
755                         parameters, invocation, sender_uid);
756         } else if (g_strcmp0(method_name, "PostAppUninstall") == 0) {
757                 _app2sd_server_post_app_uninstall(connection, sender,
758                         parameters, invocation, sender_uid);
759         } else if (g_strcmp0(method_name, "OndemandSetupInit") == 0) {
760                 _app2sd_server_ondemand_setup_init(connection, sender,
761                         parameters, invocation, sender_uid);
762         } else if (g_strcmp0(method_name, "OndemandSetupExit") == 0) {
763                 _app2sd_server_ondemand_setup_exit(connection, sender,
764                         parameters, invocation, sender_uid);
765         } else if (g_strcmp0(method_name, "PreMoveInstalledApp") == 0) {
766                 _app2sd_server_pre_move_installed_app(connection, sender,
767                         parameters, invocation, sender_uid);
768         } else if (g_strcmp0(method_name, "PostMoveInstalledApp") == 0) {
769                 _app2sd_server_post_move_installed_app(connection, sender,
770                         parameters, invocation, sender_uid);
771         } else if (g_strcmp0(method_name, "ForceClean") == 0) {
772                 _app2sd_server_force_clean(connection, sender,
773                         parameters, invocation, sender_uid);
774         } else if (g_strcmp0(method_name, "EnableFullPkg") == 0) {
775                 _app2sd_server_enable_full_pkg(connection, sender,
776                         parameters, invocation, sender_uid);
777         } else if (g_strcmp0(method_name, "DisableFullPkg") == 0) {
778                 _app2sd_server_disable_full_pkg(connection, sender,
779                         parameters, invocation, sender_uid);
780         }
781
782         if (source_id)
783                 g_source_remove(source_id);
784         source_id = g_timeout_add_seconds(5, __exit_app2sd_server, NULL);
785         processing_busy_cnt--;
786 }
787
788 static const GDBusInterfaceVTable interface_vtable = {
789         handle_method_call,
790         NULL,
791         NULL
792 };
793
794 static void __app2sd_on_bus_acquired(GDBusConnection *connection,
795                 const gchar *name, gpointer user_data)
796 {
797         _I("bus acquired(%s)", name);
798
799         guint reg_id = 0;
800         GError *error = NULL;
801
802         reg_id = g_dbus_connection_register_object(connection,
803                 APP2SD_OBJECT_PATH,
804                 introspection_data->interfaces[0],
805                 &interface_vtable,
806                 NULL, NULL, &error);
807         if (reg_id == 0) {
808                 _E("g_dbus_connection_register_object error(%s)", error->message);
809                 g_error_free(error);
810         }
811 }
812
813 static void __app2sd_on_name_acquired(GDBusConnection *connection,
814                 const gchar *name, gpointer user_data)
815 {
816         _I("name acquired(%s)", name);
817 }
818
819 static void __app2sd_on_name_lost(GDBusConnection *connection,
820                 const gchar *name, gpointer user_data)
821 {
822         _E("name lost(%s)", name);
823         g_main_loop_quit(app2sd_mainloop);
824 }
825
826 static int __app2sd_server_init()
827 {
828         GError *error = NULL;
829         guint owner_id = 0;
830
831         /* gdbus setup for method call */
832         introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, &error);
833         if (!introspection_data) {
834                 _E("g_dbus_node_info_new_for_xml error(%s)", error->message);
835                 g_error_free(error);
836                 return -1;
837         }
838
839         owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM,
840                 APP2SD_BUS_NAME,
841                 G_BUS_NAME_OWNER_FLAGS_NONE,
842                 __app2sd_on_bus_acquired,
843                 __app2sd_on_name_acquired,
844                 __app2sd_on_name_lost,
845                 NULL, NULL);
846         if (!owner_id) {
847                 _E("g_bus_own_name error");
848                 g_dbus_node_info_unref(introspection_data);
849                 return -1;
850         }
851
852         return 0;
853 }
854
855 static void __app2sd_finalize(void)
856 {
857         _D("app2sd finalize");
858
859         if (introspection_data)
860                 g_dbus_node_info_unref(introspection_data);
861
862         _D("app2sd finalize end");
863 }
864
865 int main(int argc, char *argv[])
866 {
867         int ret = 0;
868
869         _I("app2sd_server : start");
870
871         ret = __app2sd_server_init();
872         if (ret) {
873                 _E("app2sd_server init failed(%d)", ret);
874                 return -1;
875         }
876
877         app2sd_mainloop = g_main_loop_new(NULL, FALSE);
878         if (!app2sd_mainloop) {
879                 _E("g_main_loop_new failed");
880                 return -1;
881         }
882
883         g_main_loop_run(app2sd_mainloop);
884
885         __app2sd_finalize();
886
887         _I("app2sd_server : end");
888
889         return 0;
890 }