remove CAP_MAC_OVERRIDE from app2sd-server
[platform/core/appfw/app2sd.git] / plugin / app2sd / src / app2sd_client_interface.c
1 /*
2  * app2ext
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Garima Shrivastava<garima.s@samsung.com>
7  *      Jyotsna Dhumale <jyotsna.a@samsung.com>
8  *      Venkatesha Sarpangala <sarpangala.v@samsung.com>
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  */
23
24 #include <stdio.h>
25 #include <errno.h>
26 #include <sys/types.h>
27 #include <sys/wait.h>
28 #include <gio/gio.h>
29
30 #include "app2sd_client_interface.h"
31 #include "app2ext_utils.h"
32
33 static int app2sd_gdbus_shared_connection(GDBusConnection **connection)
34 {
35         GError *error = NULL;
36
37 #if (GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION < 36)
38         g_type_init();
39 #endif
40
41         *connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
42         if (*connection == NULL) {
43                 if (error != NULL) {
44                         _E("app2sd error : failed to get "
45                                 "system dbus [%s]", error->message);
46                         g_error_free(error);
47                 }
48                 return APP2EXT_ERROR_DBUS_FAILED;
49         }
50
51         return APP2EXT_SUCCESS;
52 }
53
54 static int __app2sd_call_server_method(const gchar *method_name,
55                 GVariant *param)
56 {
57         int ret = APP2EXT_SUCCESS;
58         int result = 0;
59         GDBusConnection *conn = NULL;
60         GDBusProxy *proxy = NULL;
61         GError *error = NULL;
62         GVariant *value = NULL;
63
64         /* get gdbus connection */
65         ret = app2sd_gdbus_shared_connection(&conn);
66         if (ret) {
67                 _E("app2sd error : dbus connection error");
68                 return ret;
69         }
70
71         /* method call */
72         proxy = g_dbus_proxy_new_sync(conn,
73                 G_DBUS_PROXY_FLAGS_NONE, NULL,
74                 APP2SD_BUS_NAME, APP2SD_OBJECT_PATH, APP2SD_INTERFACE_NAME,
75                 NULL, &error);
76         if (proxy == NULL) {
77                 _E("failed to create new proxy, error(%s)", error->message);
78                 g_error_free(error);
79                 ret = APP2EXT_ERROR_DBUS_FAILED;
80                 goto out;
81         }
82
83         value = g_dbus_proxy_call_sync(proxy, method_name, param,
84                 G_DBUS_CALL_FLAGS_NONE, G_MAXINT, NULL, &error);
85         if (error != NULL) {
86                 _E("proxy call sync error(%s)", error->message);
87                 g_error_free(error);
88                 ret = APP2EXT_ERROR_DBUS_FAILED;
89                 goto out;
90         }
91
92         g_variant_get(value, "(i)", &result);
93         g_variant_unref(value);
94
95         _D("result(%d)", result);
96         if (result)
97                 ret = result;
98
99 out:
100         if (conn)
101                 g_object_unref(conn);
102
103         return ret;
104 }
105
106 static void __app2sd_create_dir_list_builder(gpointer data, gpointer user_data)
107 {
108         app2ext_dir_details *item = (app2ext_dir_details *)data;
109         GVariantBuilder *builder = (GVariantBuilder *)user_data;
110
111         g_variant_builder_add(builder, "(si)", item->name, item->type);
112 }
113
114 static int __app2sd_delete_temp_directories(const char *pkgid,
115                 app2sd_cmd cmd, uid_t uid)
116 {
117         int ret = 0;
118         char temp_path[FILENAME_MAX] = { 0, };
119
120         if (cmd != APP2SD_PRE_UPGRADE)
121                 return APP2EXT_SUCCESS;
122
123         if (_is_global(uid)) {
124                 snprintf(temp_path, FILENAME_MAX - 1, "%s/%s.new",
125                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
126         } else {
127                 tzplatform_set_user(uid);
128                 snprintf(temp_path, FILENAME_MAX - 1, "%s/%s.new",
129                         tzplatform_getenv(TZ_USER_APP), pkgid);
130                 tzplatform_reset_user();
131         }
132
133         /* this will delete all files under temp_path */
134         ret = _app2sd_delete_directory(temp_path);
135         if (ret) {
136                 _E("unable to delete (%s)", temp_path);
137                 return APP2EXT_ERROR_DELETE_DIRECTORY;
138         }
139
140         return APP2EXT_SUCCESS;
141 }
142
143 static int __app2sd_create_default_directories(const char *pkgid,
144                 app2sd_cmd cmd, uid_t uid)
145 {
146         int ret = 0;
147         mode_t mode = DIR_PERMS;
148         char application_path[FILENAME_MAX] = { 0, };
149         char application_mmc_path[FILENAME_MAX] = { 0, };
150         char temp_path[FILENAME_MAX] = { 0, };
151
152         if (_is_global(uid)) {
153                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
154                         tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
155         } else {
156                 tzplatform_set_user(uid);
157                 snprintf(application_path, FILENAME_MAX - 1, "%s/%s",
158                         tzplatform_getenv(TZ_USER_APP), pkgid);
159                 tzplatform_reset_user();
160         }
161
162         ret = mkdir(application_path, mode);
163         if (ret) {
164                 if (errno != EEXIST) {
165                         _E("create directory failed," \
166                                 " error no is (%d)", errno);
167                         return APP2EXT_ERROR_CREATE_DIRECTORY;
168                 }
169         }
170
171         snprintf(application_mmc_path, FILENAME_MAX - 1, "%s/.mmc",
172                 application_path);
173
174         ret = mkdir(application_mmc_path, mode);
175         if (ret) {
176                 if (errno != EEXIST) {
177                         _E("create directory failed," \
178                                 " error no is (%d)", errno);
179                         return APP2EXT_ERROR_CREATE_DIRECTORY;
180                 }
181         }
182
183         if (cmd == APP2SD_PRE_UPGRADE) {
184                 /* application_path for {pkgid}.new */
185                 snprintf(temp_path, FILENAME_MAX - 1, "%s.new",
186                         application_path);
187                 ret = mkdir(temp_path, mode);
188                 if (ret) {
189                         if (errno != EEXIST) {
190                                 _E("create directory failed," \
191                                         " error no is (%d)", errno);
192                                 return APP2EXT_ERROR_CREATE_DIRECTORY;
193                         }
194                 }
195                 /* application_mmc_path for {pkgid}.new */
196                 snprintf(application_mmc_path, FILENAME_MAX - 1, "%s/.mmc",
197                         temp_path);
198                 ret = mkdir(application_mmc_path, mode);
199                 if (ret) {
200                         if (errno != EEXIST) {
201                                 _E("create directory failed," \
202                                         " error no is (%d)", errno);
203                                 return APP2EXT_ERROR_CREATE_DIRECTORY;
204                         }
205                 }
206         }
207
208         return APP2EXT_SUCCESS;
209 }
210
211 int app2sd_client_usr_pre_app_install(const char *pkgid, GList *dir_list,
212                 int size, uid_t uid)
213 {
214         int ret = 0;
215         GVariantBuilder *builder = NULL;
216         GVariant *param = NULL;
217
218         /* validate the function parameter recieved */
219         if (pkgid == NULL || dir_list == NULL || size <= 0) {
220                 _E("invalid function arguments");
221                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
222         }
223
224         ret = __app2sd_create_default_directories(pkgid,
225                 APP2SD_PRE_INSTALL, uid);
226         if (ret)
227                 return ret;
228
229         builder = g_variant_builder_new(G_VARIANT_TYPE("a(si)"));
230         g_list_foreach(dir_list, __app2sd_create_dir_list_builder, builder);
231
232         param = g_variant_new("(sia(si)i)", pkgid, size, builder, uid);
233         ret = __app2sd_call_server_method("PreAppInstall", param);
234
235         if (builder)
236                 g_variant_builder_unref(builder);
237
238         return ret;
239 }
240 int app2sd_client_pre_app_install(const char *pkgid, GList *dir_list,
241                 int size)
242 {
243         int ret = 0;
244
245         ret = app2sd_client_usr_pre_app_install(pkgid,
246                 dir_list, size, getuid());
247
248         return ret;
249 }
250
251 int app2sd_client_usr_post_app_install(const char *pkgid,
252                 app2ext_status install_status, uid_t uid)
253 {
254         int ret = 0;
255         GVariant *param = NULL;
256
257         /* validate the function parameter recieved */
258         if (pkgid == NULL || install_status < APP2EXT_STATUS_FAILED
259                 || install_status > APP2EXT_STATUS_SUCCESS) {
260                 _E("invalid func parameters");
261                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
262         }
263
264         param = g_variant_new("(sii)", pkgid, install_status, uid);
265         ret = __app2sd_call_server_method("PostAppInstall", param);
266
267         return ret;
268 }
269 int app2sd_client_post_app_install(const char *pkgid,
270                 app2ext_status install_status)
271 {
272         int ret = 0;
273
274         ret = app2sd_client_usr_post_app_install(pkgid,
275                 install_status, getuid());
276
277         return ret;
278 }
279
280 int app2sd_client_usr_pre_app_upgrade(const char *pkgid, GList *dir_list,
281                 int size, uid_t uid)
282 {
283         int ret = 0;
284         GVariantBuilder *builder = NULL;
285         GVariant *param = NULL;
286
287         /* validate the function parameter recieved */
288         if (pkgid == NULL || dir_list == NULL || size <= 0) {
289                 _E("invalid function arguments");
290                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
291         }
292
293         ret = __app2sd_create_default_directories(pkgid,
294                 APP2SD_PRE_UPGRADE, uid);
295         if (ret)
296                 return ret;
297
298         builder = g_variant_builder_new(G_VARIANT_TYPE("a(si)"));
299         g_list_foreach(dir_list, __app2sd_create_dir_list_builder, builder);
300
301         param = g_variant_new("(sia(si)i)", pkgid, size, builder, uid);
302         ret = __app2sd_call_server_method("PreAppUpgrade", param);
303
304         if (builder)
305                 g_variant_builder_unref(builder);
306
307         ret = __app2sd_delete_temp_directories(pkgid,
308                 APP2SD_PRE_UPGRADE, uid);
309
310         return ret;
311 }
312 int app2sd_client_pre_app_upgrade(const char *pkgid, GList *dir_list,
313                 int size)
314 {
315         int ret = 0;
316
317         ret = app2sd_client_usr_pre_app_upgrade(pkgid,
318                 dir_list, size, getuid());
319
320         return ret;
321 }
322
323 int app2sd_client_usr_post_app_upgrade(const char *pkgid,
324                 app2ext_status install_status, uid_t uid)
325 {
326         int ret = 0;
327         GVariant *param = NULL;
328
329         /* validate the function parameter recieved */
330         if (pkgid == NULL || install_status < APP2EXT_STATUS_FAILED
331                 || install_status > APP2EXT_STATUS_SUCCESS) {
332                 _E("invalid func parameters");
333                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
334         }
335
336         param = g_variant_new("(sii)", pkgid, install_status, uid);
337         ret = __app2sd_call_server_method("PostAppUpgrade", param);
338
339         return ret;
340 }
341 int app2sd_client_post_app_upgrade(const char *pkgid,
342                 app2ext_status install_status)
343 {
344         int ret = 0;
345
346         ret = app2sd_client_usr_post_app_upgrade(pkgid,
347                 install_status, getuid());
348
349         return ret;
350 }
351
352 int app2sd_client_usr_pre_app_uninstall(const char *pkgid, uid_t uid)
353 {
354         int ret = 0;
355         GVariant *param = NULL;
356
357         /* validate the function parameter recieved */
358         if (pkgid == NULL) {
359                 _E("invalid func parameters");
360                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
361         }
362
363         param = g_variant_new("(si)", pkgid, uid);
364         ret = __app2sd_call_server_method("PreAppUninstall", param);
365
366         return ret;
367 }
368 int app2sd_client_pre_app_uninstall(const char *pkgid)
369 {
370         int ret = 0;
371
372         ret = app2sd_client_usr_pre_app_uninstall(pkgid,
373                 getuid());
374
375         return ret;
376 }
377
378 int app2sd_client_usr_post_app_uninstall(const char *pkgid, uid_t uid)
379 {
380         int ret = 0;
381         GVariant *param = NULL;
382
383         /* validate the function parameter recieved */
384         if (pkgid == NULL) {
385                 _E("invalid func parameters");
386                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
387         }
388
389         param = g_variant_new("(si)", pkgid, uid);
390         ret = __app2sd_call_server_method("PostAppUninstall", param);
391
392         return ret;
393 }
394 int app2sd_client_post_app_uninstall(const char *pkgid)
395 {
396         int ret = 0;
397
398         ret = app2sd_client_usr_post_app_uninstall(pkgid,
399                 getuid());
400
401         return ret;
402 }
403
404 int app2sd_client_usr_force_clean(const char *pkgid, uid_t uid)
405 {
406         int ret = 0;
407         GVariant *param = NULL;
408
409         /* validate the function parameter recieved */
410         if (pkgid == NULL) {
411                 _E("invalid func parameters");
412                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
413         }
414
415         param = g_variant_new("(si)", pkgid, uid);
416         ret = __app2sd_call_server_method("ForceClean", param);
417
418         return ret;
419 }
420 int app2sd_client_force_clean(const char *pkgid)
421 {
422         int ret = 0;
423
424         ret = app2sd_client_usr_force_clean(pkgid, getuid());
425
426         return ret;
427 }
428
429 int app2sd_client_enable_full_pkg(void)
430 {
431         int ret = 0;
432
433         ret = __app2sd_call_server_method("EnableFullPkg", NULL);
434
435         return ret;
436 }
437
438 int app2sd_client_disable_full_pkg(void)
439 {
440         int ret = 0;
441
442         ret = __app2sd_call_server_method("DisableFullPkg", NULL);
443
444         return ret;
445 }
446
447 int app2sd_client_usr_on_demand_setup_init(const char *pkgid, uid_t uid)
448 {
449         int ret = 0;
450         GVariant *param = NULL;
451
452         /* validate the function parameter recieved */
453         if (pkgid == NULL) {
454                 _E("invalid func parameters");
455                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
456         }
457
458         param = g_variant_new("(si)", pkgid, uid);
459         ret = __app2sd_call_server_method("OndemandSetupInit", param);
460
461         return ret;
462 }
463 int app2sd_client_on_demand_setup_init(const char *pkgid)
464 {
465         int ret = 0;
466
467         ret = app2sd_client_usr_on_demand_setup_init(pkgid,
468                 getuid());
469
470         return ret;
471 }
472
473 int app2sd_client_usr_on_demand_setup_exit(const char *pkgid, uid_t uid)
474 {
475         int ret = 0;
476         GVariant *param = NULL;
477
478         /* validate the function parameter recieved */
479         if (pkgid == NULL) {
480                 _E("invalid func parameters");
481                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
482         }
483
484         param = g_variant_new("(si)", pkgid, uid);
485         ret = __app2sd_call_server_method("OndemandSetupExit", param);
486
487         return ret;
488 }
489 int app2sd_client_on_demand_setup_exit(const char *pkgid)
490 {
491         int ret = 0;
492
493         ret = app2sd_client_usr_on_demand_setup_exit(pkgid,
494                 getuid());
495
496         return ret;
497 }
498
499 int app2sd_client_usr_pre_move_installed_app(const char *pkgid, GList *dir_list,
500                 app2ext_move_type move_type, uid_t uid)
501 {
502         int ret = 0;
503         GVariantBuilder *builder = NULL;
504         GVariant *param = NULL;
505         app2sd_cmd cmd = APP2SD_MOVE_APP_TO_PHONE;
506
507         /* validate the function parameter recieved */
508         if (pkgid == NULL || dir_list == NULL
509                 || move_type < APP2EXT_MOVE_TO_EXT
510                 || move_type > APP2EXT_MOVE_TO_PHONE) {
511                 _E("invalid function arguments");
512                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
513         }
514
515         if (move_type == APP2EXT_MOVE_TO_EXT)
516                 cmd = APP2SD_MOVE_APP_TO_MMC;
517
518         if (cmd == APP2SD_MOVE_APP_TO_MMC) {
519                 ret = __app2sd_create_default_directories(pkgid, cmd, uid);
520                 if (ret)
521                         return ret;
522         }
523
524         builder = g_variant_builder_new(G_VARIANT_TYPE("a(si)"));
525         g_list_foreach(dir_list, __app2sd_create_dir_list_builder, builder);
526
527         param = g_variant_new("(sia(si)i)", pkgid, move_type, builder, uid);
528         ret = __app2sd_call_server_method("PreMoveInstalledApp", param);
529
530         if (builder)
531                 g_variant_builder_unref(builder);
532
533         return ret;
534 }
535 int app2sd_client_pre_move_installed_app(const char *pkgid, GList *dir_list,
536                 app2ext_move_type move_type)
537 {
538         int ret = 0;
539
540         ret = app2sd_client_usr_pre_move_installed_app(pkgid,
541                 dir_list, move_type, getuid());
542
543         return ret;
544 }
545
546 int app2sd_client_usr_post_move_installed_app(const char *pkgid,
547                 app2ext_move_type move_type, uid_t uid)
548 {
549         int ret = 0;
550         GVariant *param = NULL;
551
552         /* validate the function parameter recieved */
553         if (pkgid == NULL || move_type < APP2EXT_MOVE_TO_EXT
554                 || move_type > APP2EXT_MOVE_TO_PHONE) {
555                 _E("invalid function arguments");
556                 return APP2EXT_ERROR_INVALID_ARGUMENTS;
557         }
558
559         param = g_variant_new("(sii)", pkgid, move_type, uid);
560         ret = __app2sd_call_server_method("PostMoveInstalledApp", param);
561
562         return ret;
563 }
564 int app2sd_client_post_move_installed_app(const char *pkgid,
565                 app2ext_move_type move_type)
566 {
567         int ret = 0;
568
569         ret = app2sd_client_usr_post_move_installed_app(pkgid,
570                 move_type, getuid());
571
572         return ret;
573 }
574
575 void app2ext_on_load(app2ext_interface *interface)
576 {
577         /* Plug-in Binding.*/
578         interface->client_pre_install = app2sd_client_pre_app_install;
579         interface->client_post_install = app2sd_client_post_app_install;
580         interface->client_pre_upgrade = app2sd_client_pre_app_upgrade;
581         interface->client_post_upgrade = app2sd_client_post_app_upgrade;
582         interface->client_pre_uninstall = app2sd_client_pre_app_uninstall;
583         interface->client_post_uninstall = app2sd_client_post_app_uninstall;
584         interface->client_force_clean = app2sd_client_force_clean;
585         interface->client_enable = app2sd_client_on_demand_setup_init;
586         interface->client_disable = app2sd_client_on_demand_setup_exit;
587         interface->client_enable_full_pkg = app2sd_client_enable_full_pkg;
588         interface->client_disable_full_pkg = app2sd_client_disable_full_pkg;
589         interface->client_pre_move = app2sd_client_pre_move_installed_app;
590         interface->client_post_move = app2sd_client_post_move_installed_app;
591
592         interface->client_usr_pre_install = app2sd_client_usr_pre_app_install;
593         interface->client_usr_post_install = app2sd_client_usr_post_app_install;
594         interface->client_usr_pre_upgrade = app2sd_client_usr_pre_app_upgrade;
595         interface->client_usr_post_upgrade = app2sd_client_usr_post_app_upgrade;
596         interface->client_usr_pre_uninstall = app2sd_client_usr_pre_app_uninstall;
597         interface->client_usr_post_uninstall = app2sd_client_usr_post_app_uninstall;
598         interface->client_usr_force_clean = app2sd_client_usr_force_clean;
599         interface->client_usr_enable = app2sd_client_usr_on_demand_setup_init;
600         interface->client_usr_disable = app2sd_client_usr_on_demand_setup_exit;
601         interface->client_usr_pre_move = app2sd_client_usr_pre_move_installed_app;
602         interface->client_usr_post_move = app2sd_client_usr_post_move_installed_app;
603 }