APP2SD_APP_LAUNCH,
APP2SD_APP_TERMINATE,
APP2SD_MOVE_APP_TO_MMC,
- APP2SD_MOVE_APP_TO_PHONE
+ APP2SD_MOVE_APP_TO_PHONE,
+ APP2SD_MIGRATE_LEGACY
} app2sd_cmd;
/**
APP2EXT_ERROR_SAME_LOOPBACK_DEVICE_EXISTS,
APP2EXT_ERROR_PKGMGR_ERROR,
APP2EXT_ERROR_KILLAPP_ERROR,
+ APP2EXT_ERROR_NOENTRY,
#ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
APP2EXT_ERROR_SETUP_DMCRYPT_DEVICE,
APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE,
typedef int (*app2ext_client_force_clean)(const char *pkgid);
/**
- * This structure defines the app2ext interfaces. Plugins have to implement these functions
+ * @brief : This function type is for a function that is implemented by plugin
+ * and called before migration of legacy mount image.
+ *
+ * @param[in] pkgid application package name which is to be migrated
+ * @return 0 if success, error code(>0) if fail
+ */
+typedef int (*app2ext_client_usr_pre_migrate_legacy)(const char *pkgid,
+ uid_t uid);
+
+/**
+ * @brief : This function type is for a function that is implemented by plugin
+ * and called after migration of legacy mount image.
+ *
+ * @param[in] pkgid application package name which is to be migrated
+ * @return 0 if success, error code(>0) if fail
+ */
+typedef int (*app2ext_client_usr_post_migrate_legacy)(const char *pkgid,
+ uid_t uid);
+
+/**
+ * @brief : This function type is for a function that is implemented by plugin
+ * and called to migrate legacy mount image.
+ *
+ * @param[in] pkgid application package name which is to be migrated
+ * @return 0 if success, error code(>0) if fail
+ */
+typedef int (*app2ext_client_migrate_legacy_all)(void);
+
+/**
+ * @brief : This function type is for a function that is implemented by plugin
+ * and called to get the external image name.
+ *
+ * @param[in] pkgid application package name
+ * @param[in] uid target user id
+ * @return the name of external image
+ * @remark the name should be freed after the use.
+ */
+typedef char *(*app2ext_client_usr_getname_image)(const char *pkgid,
+ uid_t uid);
+
+/**
+ * This structure defines the app2ext interfaces.
+ * Plugins have to implement these functions
*/
typedef struct app2ext_interface_t {
/* for library function */
app2ext_client_disable_full_pkg client_disable_full_pkg;
app2ext_client_pre_move client_pre_move;
app2ext_client_post_move client_post_move;
+ app2ext_client_migrate_legacy_all client_migrate_legacy_all;
app2ext_client_usr_pre_install client_usr_pre_install;
app2ext_client_usr_post_install client_usr_post_install;
app2ext_client_usr_disable client_usr_disable;
app2ext_client_usr_pre_move client_usr_pre_move;
app2ext_client_usr_post_move client_usr_post_move;
+ app2ext_client_usr_getname_image client_usr_getname_image;
+ app2ext_client_usr_pre_migrate_legacy client_usr_pre_migrate_legacy;
+ app2ext_client_usr_post_migrate_legacy client_usr_post_migrate_legacy;
} app2ext_interface;
/**
API int app2ext_enable_all_external_pkgs(void);
API int app2ext_disable_all_external_pkgs(void);
+/**
+ * @brief : This API migrate all legacy entries which are located in external memory
+ * @return error < 0 if fail to migrate legacy
+ */
+API int app2ext_migrate_legacy_all(void);
+
+/**
+ * @brief : This API get the external image name
+ * @param[in] pkgid application package name
+ * @param[in] uid target user id
+ * @return the name of external image
+ * @remark the name should be freed after the use.
+ */
+API char *app2ext_usr_getname_image(const char *pkgid, uid_t uid);
+
#ifdef __cplusplus
}
#endif
Name: app2sd
Summary: Application installation on external memory
-Version: 0.5.43
+Version: 0.5.44
Release: 1
Group: Application Framework/Package Management
License: Apache-2.0
BuildRequires: pkgconfig(glib-2.0)
BuildRequires: pkgconfig(aul)
BuildRequires: pkgconfig(storage)
+BuildRequires: pkgconfig(pkgmgr)
BuildRequires: cmake
%if "%{?profile}" == "common"
# Required packages
-pkg_check_modules(app2sd_pkgs REQUIRED dlog pkgmgr-info gio-2.0 glib-2.0 db-util libtzplatform-config aul storage)
+pkg_check_modules(app2sd_pkgs REQUIRED dlog pkgmgr-info gio-2.0 glib-2.0 db-util libtzplatform-config aul storage pkgmgr)
pkg_check_modules(app2sd_libpkgs REQUIRED dlog pkgmgr-info gio-2.0 glib-2.0)
# Compiler flags
#define APP2EXT_SUCCESS 0
#define OWNER_ROOT 0
+#define APPFW_UID 301
#define REGULAR_USER 5000
#define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
#define EXTIMG_DIR "app2sd"
}
ret = pkgmgrinfo_pkginfo_get_installed_storage(info_handle, &storage);
if (ret < 0) {
- _E("failed to get installed storage for pkg(%s) of uid(%d), ret(%d)",
- pkgid, uid, ret);
+ _E("failed to get installed storage for pkg(%s) " \
+ "of uid(%d), ret(%d)", pkgid, uid, ret);
pkgmgrinfo_pkginfo_destroy_pkginfo(info_handle);
return APP2EXT_ERROR_PKGMGR_ERROR;
}
- if ((move_type == APP2EXT_MOVE_TO_EXT && storage == PMINFO_EXTERNAL_STORAGE)
- || (move_type == APP2EXT_MOVE_TO_PHONE && storage == PMINFO_INTERNAL_STORAGE)) {
+ if ((move_type == APP2EXT_MOVE_TO_EXT && storage ==
+ PMINFO_EXTERNAL_STORAGE)
+ || (move_type == APP2EXT_MOVE_TO_PHONE &&
+ storage == PMINFO_INTERNAL_STORAGE)) {
_E("PKG_EXISTS in [%d] STORAGE", storage);
pkgmgrinfo_pkginfo_destroy_pkginfo(info_handle);
return APP2EXT_ERROR_PKG_EXISTS;
return ret;
}
+int app2sd_client_usr_pre_migrate_legacy(const char *pkgid, uid_t uid)
+{
+ int ret = 0;
+ GVariant *param = NULL;
+
+ /* validate the function parameter recieved */
+ if (pkgid == NULL) {
+ _E("invalid function arguments");
+ return APP2EXT_ERROR_INVALID_ARGUMENTS;
+ }
+
+ param = g_variant_new("(si)", pkgid, uid);
+ ret = __app2sd_call_server_method("PreMigrateLegacy", param);
+
+ return ret;
+}
+
+int app2sd_client_usr_post_migrate_legacy(const char *pkgid, uid_t uid)
+{
+ int ret = 0;
+ GVariant *param = NULL;
+
+ /* validate the function parameter recieved */
+ if (pkgid == NULL) {
+ _E("invalid function arguments");
+ return APP2EXT_ERROR_INVALID_ARGUMENTS;
+ }
+
+ param = g_variant_new("(si)", pkgid, uid);
+ ret = __app2sd_call_server_method("PostMigrateLegacy", param);
+
+ return ret;
+}
+
+int app2sd_client_migrate_legacy_all()
+{
+ int ret = 0;
+
+ ret = __app2sd_call_server_method("MigrateLegacyAll", NULL);
+
+ return ret;
+}
+
+char *app2sd_client_usr_getname_image(const char *pkgid, uid_t uid)
+{
+ return _app2sd_get_encoded_name(pkgid, uid);
+}
+
void app2ext_on_load(app2ext_interface *interface)
{
/* Plug-in Binding.*/
interface->client_disable_full_pkg = app2sd_client_disable_full_pkg;
interface->client_pre_move = app2sd_client_pre_move_installed_app;
interface->client_post_move = app2sd_client_post_move_installed_app;
+ interface->client_migrate_legacy_all = app2sd_client_migrate_legacy_all;
interface->client_usr_pre_install = app2sd_client_usr_pre_app_install;
interface->client_usr_post_install = app2sd_client_usr_post_app_install;
interface->client_usr_disable = app2sd_client_usr_on_demand_setup_exit;
interface->client_usr_pre_move = app2sd_client_usr_pre_move_installed_app;
interface->client_usr_post_move = app2sd_client_usr_post_move_installed_app;
+ interface->client_usr_getname_image = app2sd_client_usr_getname_image;
+ interface->client_usr_pre_migrate_legacy = app2sd_client_usr_pre_migrate_legacy;
+ interface->client_usr_post_migrate_legacy = app2sd_client_usr_post_migrate_legacy;
}
* @param[in] pkgid application package id
* @pre Package must be installed and enabled
* and application must be running in SD card
- * @post application is disabked in SD card.
+ * @post application is disabled in SD card.
* @return 0 if success, error code(>0) if fail
* @remark None.
*/
int app2sd_client_force_clean(const char *pkgid);
/**
+ * @brief : This API does pre operation for the migration of legacy external
+ * image for the compatability with tizen 3.0 platform.
+ * @param[in] pkgid application package id
+ * @return 0 if success, error code(>0) if fail
+ * @remark None.
+ */
+int app2sd_client_usr_pre_migrate_legacy(const char *pkgid, uid_t uid);
+
+/**
+ * @brief : This API does post operation for the migration of legacy external
+ * image for the compatability with tizen 3.0 platform.
+ * @param[in] pkgid application package id
+ * @return 0 if success, error code(>0) if fail
+ * @remark None.
+ */
+int app2sd_client_usr_post_migrate_legacy(const char *pkgid, uid_t uid);
+
+/**
+ * @brief : This API migrate all the legacy mount image in sd card to be comapatible
+ * with tizen 3.0 platform.
+ * @param[in] pkgid application package id
+ * @return 0 if success, error code(>0) if fail
+ * @remark None.
+ */
+int app2sd_client_migrate_legacy_all(void);
+
+/**
+ * @brief : This API get the external image name.
+ * @param[in] pkgid application package id
+ * @param[in] uid target user id
+ * @return the name of external image
+ * @remark the name should be freed after the use.
+ */
+char *app2sd_client_usr_getname_image(const char *pkgid, uid_t uid);
+
+/**
* @brief : This is the plug-in load function.
* The plugin has to bind its functions to function pointers of storage handle
* @param[in/out] st_interface Specifies the storage interface.
*/
#include <pkgmgr-info.h>
+#include <package-manager.h>
#include <aul.h>
#include "app2sd_internals.h"
fp = fopen(loopback_device, "r+");
if (fp == NULL) {
- _E("app entry is not present in SD Card");
+ _E("app entry is not present in SD Card, (%s), errno(%d)",
+ loopback_device, errno);
return APP2EXT_ERROR_INVALID_PACKAGE;
}
fclose(fp);
ret = _app2sd_get_info_from_db(loopback_device,
&pkgid, &uid);
if (ret) {
- _E("failed to get info from db");
- break;;
+ _W("failed to get info from db, continue");
+ continue;
}
if (pkgid) {
_D("pkgid(%s), uid(%d)", pkgid, uid);
ret = app2sd_usr_on_demand_setup_init(pkgid, uid);
if (ret) {
_E("error(%d)", ret);
- break;
+ continue;
}
free(pkgid);
pkgid = NULL;
sync();
return ret;
}
+
+static int _app2sd_migrate_legacy_image(const char *pkgid, const char *passwd,
+ const char *mmc_path, uid_t uid)
+{
+ int ret = 0;
+ char *device_node = NULL;
+ char *encoded_id = NULL;
+ char new_image[FILENAME_MAX] = { 0, };
+ char legacy_image[FILENAME_MAX] = { 0, };
+ char application_path[FILENAME_MAX] = { 0, };
+ uid_t default_uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
+
+ if (_is_global(uid)) {
+ snprintf(application_path, sizeof(application_path), "%s/%s",
+ tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
+ } else {
+ tzplatform_set_user(uid);
+ snprintf(application_path, sizeof(application_path), "%s/%s",
+ tzplatform_getenv(TZ_USER_APP), pkgid);
+ tzplatform_reset_user();
+ }
+
+ /* make the information and insert to DB */
+ encoded_id = _app2sd_get_encoded_name(pkgid, uid);
+ if (encoded_id == NULL)
+ return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
+ snprintf(new_image, sizeof(new_image), "%s/%s",
+ mmc_path, encoded_id);
+ free(encoded_id);
+
+ snprintf(legacy_image, sizeof(legacy_image), "%s/%s",
+ mmc_path, pkgid);
+
+ ret = _app2sd_rename_dir(legacy_image, new_image);
+ if (ret) {
+ _E("unable to rename (%s)", legacy_image);
+ return APP2EXT_ERROR_ACCESS_FILE;
+ }
+
+ ret = pkgmgrinfo_pkginfo_set_usr_installed_storage(pkgid,
+ INSTALL_EXTERNAL, new_image, uid);
+ if (ret < 0) {
+ _E("fail to update installed location " \
+ "to db[%s, %d] of uid(%d), ret(%d)",
+ pkgid, INSTALL_EXTERNAL, uid, ret);
+ return APP2EXT_ERROR_PKGMGR_ERROR;
+ }
+
+ /* update app2sd db */
+ if (_is_global(uid)) {
+ ret = _app2sd_remove_info_from_db(pkgid, default_uid);
+ if (ret) {
+ _E("cannot remove info from db");
+ return APP2EXT_ERROR_SQLITE_REGISTRY;
+ }
+ }
+ ret = _app2sd_set_info_in_db(pkgid, passwd, new_image, uid);
+ if (ret) {
+ _E("unable to save info");
+ return APP2EXT_ERROR_SQLITE_REGISTRY;
+ }
+
+#ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
+ device_node =
+ _app2sd_find_associated_dmcrypt_device_node(pkgid, uid);
+ if (device_node) {
+ _E("device_node(%s_%d) already associated", pkgid, uid);
+ return APP2EXT_ERROR_ALREADY_MOUNTED;
+ }
+
+ ret = _app2sd_dmcrypt_open_device(pkgid, new_image, false,
+ uid, &device_node);
+ if (ret) {
+ _E("dmcrypt open device error(%d)", ret);
+ return APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE;
+ }
+#else
+ result = (char *)_app2sd_find_associated_device(new_image);
+ /* process the string */
+ if ((result != NULL) && strstr(result, "/dev") != NULL) {
+ _E("already associated");
+ free(result);
+ result = NULL;
+ return APP2EXT_ERROR_ALREADY_MOUNTED;
+ }
+
+ /* do loopback setup */
+ device_node = _app2sd_do_loopback_encryption_setup(pkgid,
+ new_image, uid);
+ if (device_node == NULL) {
+ _E("loopback encryption setup failed");
+ return APP2EXT_ERROR_DO_LOSETUP;
+ }
+#endif
+
+ /* do mounting */
+ ret = _app2sd_mount_app_content(application_path, pkgid,
+ device_node, MOUNT_TYPE_RW, NULL,
+ APP2SD_MIGRATE_LEGACY, uid);
+ if (ret) {
+ _E("mount failed");
+ if (device_node) {
+ free(device_node);
+ device_node = NULL;
+ }
+ return APP2EXT_ERROR_MOUNT_PATH;
+ }
+
+ if (device_node) {
+ free(device_node);
+ device_node = NULL;
+ }
+
+ sync();
+ return APP2EXT_SUCCESS;
+}
+
+int app2sd_pre_migrate_legacy(const char *pkgid, uid_t uid)
+{
+ int ret = APP2EXT_SUCCESS;
+ char *passwd = NULL;
+ char *sdpath = NULL;
+ char mmc_path[FILENAME_MAX] = { 0, };
+ char file_path[FILENAME_MAX] = { 0, };
+ uid_t default_uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
+
+ /* check whether MMC is present or not */
+ ret = _app2sd_check_mmc_status(&sdpath);
+ if (ret) {
+ _E("MMC not present OR Not ready (%d)", ret);
+ return APP2EXT_ERROR_MMC_STATUS;
+ }
+ snprintf(mmc_path, sizeof(mmc_path), "%s/%s", sdpath, EXTIMG_DIR);
+ free(sdpath);
+ snprintf(file_path, sizeof(file_path), "%s/%s", mmc_path, pkgid);
+
+ ret = _app2sd_initialize_db();
+ if (ret) {
+ _E("app2sd db initialize failed");
+ return APP2EXT_ERROR_SQLITE_REGISTRY;
+ }
+
+ /* In the upgrade script, the information
+ * of legacy image are filled with default user-id,
+ * pkgid(from old db), passwd(from old db) and
+ * empty filename in app2sd db. */
+ if (!_app2sd_get_filename_from_db(pkgid, default_uid)) {
+ passwd = _app2sd_get_password_from_db(pkgid, default_uid);
+ if (passwd) {
+ ret = _app2sd_migrate_legacy_image(pkgid, passwd,
+ mmc_path, uid);
+ free(passwd);
+ passwd = NULL;
+ } else {
+ _E("invalid package info");
+ return APP2EXT_ERROR_INVALID_PACKAGE;
+ }
+ } else {
+ _W("same pkg exists, remove legacy file (%s)", file_path);
+ ret = remove(file_path);
+ if (ret < 0)
+ _E("failed to remove, errno(%d)", errno);
+ return APP2EXT_ERROR_PKG_EXISTS;
+ }
+
+ return ret;
+}
+
+int app2sd_post_migrate_legacy(const char *pkgid, uid_t uid)
+{
+ int ret = APP2EXT_SUCCESS;
+ char *sdpath = NULL;
+ char *encoded_id = NULL;
+ char mmc_path[FILENAME_MAX] = { 0, };
+ char application_path[FILENAME_MAX] = { 0, };
+ char loopback_device[FILENAME_MAX] = { 0, };
+
+ /* check whether MMC is present or not */
+ ret = _app2sd_check_mmc_status(&sdpath);
+ if (ret) {
+ _E("MMC not present OR Not ready (%d)", ret);
+ return APP2EXT_ERROR_MMC_STATUS;
+ }
+ snprintf(mmc_path, sizeof(mmc_path), "%s/%s",
+ sdpath, EXTIMG_DIR);
+ free(sdpath);
+
+ if (_is_global(uid)) {
+ snprintf(application_path, sizeof(application_path), "%s/%s",
+ tzplatform_getenv(TZ_SYS_RW_APP), pkgid);
+ } else {
+ tzplatform_set_user(uid);
+ snprintf(application_path, sizeof(application_path), "%s/%s",
+ tzplatform_getenv(TZ_USER_APP), pkgid);
+ tzplatform_reset_user();
+ }
+
+ encoded_id = _app2sd_get_encoded_name(pkgid, uid);
+ if (encoded_id == NULL) {
+ return APP2EXT_ERROR_MEMORY_ALLOC_FAILED;
+ }
+ snprintf(loopback_device, sizeof(loopback_device), "%s/%s",
+ mmc_path, encoded_id);
+ free(encoded_id);
+
+ ret = __app2sd_finalize_device_setup(pkgid, loopback_device,
+ application_path, uid);
+ if (ret) {
+ _E("failed to finalize device setup");
+ return ret;
+ }
+
+ return APP2EXT_SUCCESS;
+}
+
+/* this function is called when sdcard is inserted */
+int app2sd_migrate_legacy_all(void)
+{
+ int ret = APP2EXT_SUCCESS;
+ int rc = 0;
+ char buf[FILENAME_MAX] = { 0, };
+ char app2sd_path[FILENAME_MAX] = { 0, };
+ char loopback_device[FILENAME_MAX] = { 0, };
+ char *sdpath = NULL;
+ DIR *dir = NULL;
+ struct dirent entry;
+ struct dirent *result = NULL;
+ uid_t default_uid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
+ pkgmgr_client *pc;
+
+ /* check whether MMC is present or not */
+ ret = _app2sd_check_mmc_status(&sdpath);
+ if (ret) {
+ _E("MMC not present OR Not ready (%d)", ret);
+ return APP2EXT_ERROR_MMC_STATUS;
+ }
+ snprintf(app2sd_path, sizeof(app2sd_path), "%s/%s",
+ sdpath, EXTIMG_DIR);
+ free(sdpath);
+
+ dir = opendir(app2sd_path);
+ if (!dir) {
+ strerror_r(errno, buf, sizeof(buf));
+ _E("failed to opendir (%s)", buf);
+ return APP2EXT_ERROR_OPEN_DIR;
+ }
+
+ pc = pkgmgr_client_new(PC_REQUEST);
+ if (pc == NULL) {
+ _E("failed to create pkgmgr client");
+ return APP2EXT_ERROR_PKGMGR_ERROR;
+ }
+
+ for (rc = readdir_r(dir, &entry, &result);
+ rc == 0 && result != NULL;
+ rc = readdir_r(dir, &entry, &result)) {
+ if (strcmp(entry.d_name, ".") == 0 ||
+ strcmp(entry.d_name, "..") == 0)
+ continue;
+ snprintf(loopback_device, sizeof(loopback_device), "%s/%s",
+ app2sd_path, entry.d_name);
+ /* check losetup image */
+ if (_app2sd_check_is_luks_device(loopback_device) == 0) {
+ /* call installer backend
+ * to change access-rule and broadcast this update */
+ ret = pkgmgr_client_usr_migrate_external_image(pc,
+ entry.d_name, default_uid);
+ if (ret < 0)
+ _E("failed to request migration, ret(%d)", ret);
+ }
+ }
+
+ pkgmgr_client_free(pc);
+ closedir(dir);
+
+ return ret;
+}
+
int app2sd_disable_full_pkg(void);
+int app2sd_pre_migrate_legacy(const char *pkgid, uid_t uid);
+
+int app2sd_post_migrate_legacy(const char *pkgid, uid_t uid);
+
+int app2sd_migrate_legacy_all(void);
+
#ifdef __cplusplus
}
#endif
return APP2EXT_ERROR_SQLITE_REGISTRY;
}
- snprintf(dmcrypt_open_cmd, BUF_SIZE, "/bin/echo '%s' | /sbin/cryptsetup -q luksOpen %s %s",
- passwd, loopback_device, dev_name);
+ if (_app2sd_check_is_luks_device(loopback_device) == 0) {
+ _W("legacy image format!");
+ snprintf(dmcrypt_open_cmd, sizeof(dmcrypt_open_cmd),
+ "/bin/echo '%s' | /sbin/cryptsetup " \
+ "-M plain -c aes-cbc-plain -h plain open %s %s",
+ passwd, loopback_device, dev_name);
+ } else {
+ snprintf(dmcrypt_open_cmd, sizeof(dmcrypt_open_cmd),
+ "/bin/echo '%s' | /sbin/cryptsetup -q luksOpen %s %s",
+ passwd, loopback_device, dev_name);
+ }
free(passwd);
ret = system(dmcrypt_open_cmd);
_D("device_node: (%s)", dev_node);
return dev_node;
}
+ _D("can not access dev_node(%s), errno(%d)", dev_node, errno);
free(dev_node);
dev_node = NULL;
/* this function is used to get password from db */
char *_app2sd_get_password_from_db(const char *pkgid, uid_t uid);
+/* this function is used to get filename from db */
+char *_app2sd_get_filename_from_db(const char *pkgid, uid_t uid);
+
/* this function removes info from db */
int _app2sd_remove_info_from_db(const char *pkgid, uid_t uid);
/* this function find associated dmcrypt device node */
char *_app2sd_find_associated_dmcrypt_device_node(const char *pkgid, uid_t uid);
+
+int _app2sd_check_is_luks_device(const char *device_path);
#endif
#endif
#include <dirent.h>
#include <time.h>
#include <db-util.h>
+#include <grp.h>
+#include <pwd.h>
#include "app2sd_internals.h"
#define MAX_QUERY_LEN 4096
#define PASSWORD_LENGTH 64
+#define BUFSIZE 4096
+
/*
########### Internal APIs ##################
*/
"(pkgid TEXT NOT NULL, password TEXT NOT NULL, " \
"filename TEXT NOT NULL, uid INTEGER, PRIMARY KEY(pkgid, uid))"
+static int _app2sd_db_change_perm(const char *db_file)
+{
+ char buf[BUFSIZE];
+ char pwuid_buf[1024];
+ char journal_file[BUFSIZE];
+ int fd;
+ char *files[3];
+ int ret, i;
+ uid_t uid = APPFW_UID;
+ struct passwd userinfo, *result = NULL;
+ files[0] = (char *)db_file;
+ files[1] = journal_file;
+ files[2] = NULL;
+
+ if (db_file == NULL)
+ return -1;
+
+ if (getuid() != OWNER_ROOT) {
+ _E("not allowed user");
+ return -1;
+ }
+
+ snprintf(journal_file, sizeof(journal_file), "%s%s", db_file, "-journal");
+
+ ret = getpwuid_r(uid, &userinfo, pwuid_buf, sizeof(pwuid_buf), &result);
+ if (ret != 0 || result == NULL) {
+ _E("user(%d) doesn't exist", uid);
+ return -1;
+ }
+
+ for (i = 0; files[i]; i++) {
+ fd = open(files[i], O_RDONLY);
+ if (fd == -1) {
+ if (strerror_r(errno, buf, sizeof(buf)))
+ strncpy(buf, "", BUFSIZE - 1);
+ _E("failed to open %s : %s", files[i], buf);
+ return -1;
+ }
+
+ ret = fchown(fd, uid, userinfo.pw_gid);
+ if (ret == -1) {
+ if (strerror_r(errno, buf, sizeof(buf)))
+ strncpy(buf, "", BUFSIZE - 1);
+ _E("failed to fchown %s %d.%d : %s", files[i], uid,
+ userinfo.pw_gid, buf);
+ close(fd);
+ return -1;
+ }
+
+ ret = fchmod(fd, 0644);
+ if (ret == -1) {
+ if (strerror_r(errno, buf, sizeof(buf)))
+ strncpy(buf, "", BUFSIZE - 1);
+ _E("failed to fchmod %s : %s", files[i], buf);
+ close(fd);
+ return -1;
+ }
+ close(fd);
+ }
+ return 0;
+}
+
int _app2sd_initialize_db()
{
char *error_message = NULL;
return -1;
}
+ if (_app2sd_db_change_perm(APP2SD_DB_FILE) < 0) {
+ _E("failed to change permissions");
+ return -1;
+ }
+
return 0;
}
sqlite3_stmt *stmt = NULL;
int ret = 0;
- query = sqlite3_mprintf("select * from app2sd_info " \
+ query = sqlite3_mprintf("select password from app2sd_info " \
"where pkgid=%Q and uid=%d", pkgid, uid);
if (query == NULL) {
_E("failed to make a query");
_W("no records found");
goto FINISH_OFF;
}
- passwd = malloc(PASSWORD_LENGTH + 1);
- if (passwd == NULL) {
+
+ passwd = strdup((const char *)sqlite3_column_text(stmt, 0));
+ if (!passwd) {
_E("memory allocation failed");
goto FINISH_OFF;
}
-
- strncpy(passwd, (const char *)sqlite3_column_text(stmt, 1),
- PASSWORD_LENGTH);
if (strlen(passwd) == 0) {
_E("data is empty");
goto FINISH_OFF;
return NULL;
}
+
+char *_app2sd_get_filename_from_db(const char *pkgid, uid_t uid)
+{
+ char *query = NULL;
+ char *filename = NULL;
+ sqlite3_stmt *stmt = NULL;
+ int ret = 0;
+
+ query = sqlite3_mprintf("select filename from app2sd_info " \
+ "where pkgid=%Q and uid=%d", pkgid, uid);
+ if (query == NULL) {
+ _E("failed to make a query");
+ return NULL;
+ }
+
+ ret = sqlite3_prepare_v2(app2sd_db, query, strlen(query), &stmt, NULL);
+ if (ret != SQLITE_OK) {
+ _E("prepare failed (%s)", sqlite3_errmsg(app2sd_db));
+ sqlite3_free(query);
+ return NULL;
+ }
+
+ ret = sqlite3_step(stmt);
+ if (ret != SQLITE_ROW || ret == SQLITE_DONE) {
+ _W("no records found");
+ goto FINISH_OFF;
+ }
+
+ filename = strdup((const char *)sqlite3_column_text(stmt, 0));
+ if (!filename) {
+ _E("memory allocation failed");
+ goto FINISH_OFF;
+ }
+ if (strlen(filename) == 0) {
+ _E("data is empty");
+ goto FINISH_OFF;
+ }
+ if (SQLITE_OK != sqlite3_finalize(stmt)) {
+ _E("error : sqlite3_finalize");
+ goto FINISH_OFF;
+ }
+ sqlite3_free(query);
+
+ return filename;
+
+FINISH_OFF:
+ if (filename)
+ free(filename);
+
+ sqlite3_finalize(stmt);
+ sqlite3_free(query);
+
+ return NULL;
+}
return ret;
} else {
_E("failed to open src(%s) dir, errno(%d)", errno);
- return APP2EXT_ERROR_MOVE;
+ return APP2EXT_ERROR_ACCESS_FILE;
}
}
} else {
if (errno == ENOENT) {
_E("dest(%s) not exist, failed!", dest);
- return APP2EXT_ERROR_MOVE;
+ return APP2EXT_ERROR_ACCESS_FILE;
} else {
_E("failed to open dest(%s) dir, errno(%d)", errno);
- return APP2EXT_ERROR_MOVE;
+ return APP2EXT_ERROR_ACCESS_FILE;
}
}
ret = _xsystem(argv_bin);
if (ret) {
_E("failed to copy dir, errno(%d)", errno);
- return APP2EXT_ERROR_MOVE;
+ return APP2EXT_ERROR_ACCESS_FILE;
}
return ret;
}
ret = _xsystem(argv_bin);
if (ret) {
_E("mv/rename fail");
- return APP2EXT_ERROR_MOVE;
+ return APP2EXT_ERROR_ACCESS_FILE;
}
return ret;
}
return ret_result;
}
+
+#ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
+int _app2sd_check_is_luks_device(const char *device_path)
+{
+ int ret = 0;
+ int result = 1; /* default: luks format */
+ const char *argv_bin[] = { "/sbin/cryptsetup", "isLuks", device_path };
+ ret = _xsystem(argv_bin);
+ if (ret < 0)
+ _E("there was errot to check isLuks");
+
+ if (ret == 1) /* legacy format */
+ result = 0;
+
+ _D("ret(%d), result(%d)", ret, result);
+ return result;
+}
+#endif
" <method name='DisableFullPkg'>"
" <arg type='i' name='result' direction='out'/>"
" </method>"
+" <method name='PreMigrateLegacy'>"
+" <arg type='s' name='pkgid' direction='in'/>"
+" <arg type='i' name='uid' direction='in'/>"
+" <arg type='i' name='result' direction='out'/>"
+" </method>"
+" <method name='PostMigrateLegacy'>"
+" <arg type='s' name='pkgid' direction='in'/>"
+" <arg type='i' name='uid' direction='in'/>"
+" <arg type='i' name='result' direction='out'/>"
+" </method>"
+" <method name='MigrateLegacyAll'>"
+" <arg type='i' name='result' direction='out'/>"
+" </method>"
" </interface>"
"</node>";
static int _app2sd_server_generate_directory_list(GVariantIter *iter, GList **list)
{
int result = APP2EXT_SUCCESS;
- GVariantIter *iter;
gchar *str = NULL;
int type;
- GList *list = NULL;
app2ext_dir_details *dir_detail = NULL;
while (g_variant_iter_loop(iter, "(si)", &str, &type)) {
}
dir_detail->type = type;
- list = g_list_append(list, dir_detail);
+ *list = g_list_append(*list, dir_detail);
}
}
g_dbus_method_invocation_return_value(invocation, param);
}
+static void _app2sd_server_pre_migrate_legacy(GDBusConnection *connection,
+ const gchar *sender, GVariant *parameters,
+ GDBusMethodInvocation *invocation, uid_t sender_uid)
+{
+ GVariant *param = NULL;
+ int result = APP2EXT_SUCCESS;
+ char *pkgid = NULL;
+ uid_t target_uid = -1;
+ int ret = 0;
+
+ g_variant_get(parameters, "(&si)", &pkgid, &target_uid);
+
+ _D("pkgid(%s), target_uid(%d), sender_uid(%d)",
+ pkgid, target_uid, sender_uid);
+
+ if (!_app2sd_server_check_permission(sender_uid, sender_uid)) {
+ _E("Not permitted user!");
+ _app2sd_server_return_method_error(invocation,
+ APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
+ return;
+ }
+
+ ret = app2sd_pre_migrate_legacy(pkgid, target_uid);
+ if (ret) {
+ _E("error(%d)", ret);
+ result = ret;
+ }
+
+ param = g_variant_new("(i)", result);
+ g_dbus_method_invocation_return_value(invocation, param);
+}
+
+static void _app2sd_server_post_migrate_legacy(GDBusConnection *connection,
+ const gchar *sender, GVariant *parameters,
+ GDBusMethodInvocation *invocation, uid_t sender_uid)
+{
+ GVariant *param = NULL;
+ int result = APP2EXT_SUCCESS;
+ char *pkgid = NULL;
+ uid_t target_uid = -1;
+ int ret = 0;
+
+ g_variant_get(parameters, "(&si)", &pkgid, &target_uid);
+
+ _D("pkgid(%s), target_uid(%d), sender_uid(%d)",
+ pkgid, target_uid, sender_uid);
+
+ if (!_app2sd_server_check_permission(sender_uid, sender_uid)) {
+ _E("Not permitted user!");
+ _app2sd_server_return_method_error(invocation,
+ APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
+ return;
+ }
+
+ ret = app2sd_post_migrate_legacy(pkgid, target_uid);
+ if (ret) {
+ _E("error(%d)", ret);
+ result = ret;
+ }
+
+ param = g_variant_new("(i)", result);
+ g_dbus_method_invocation_return_value(invocation, param);
+}
+
+static void _app2sd_server_migrate_legacy_all(GDBusConnection *connection,
+ const gchar *sender, GVariant *parameters,
+ GDBusMethodInvocation *invocation, uid_t sender_uid)
+{
+ GVariant *param = NULL;
+ int result = APP2EXT_SUCCESS;
+ int ret = 0;
+
+ _D("sender_uid(%d)", sender_uid);
+
+ if (!_app2sd_server_check_permission(sender_uid, sender_uid)) {
+ _E("Not permitted user!");
+ _app2sd_server_return_method_error(invocation,
+ APP2EXT_ERROR_OPERATION_NOT_PERMITTED);
+ return;
+ }
+
+ ret = app2sd_migrate_legacy_all();
+ if (ret) {
+ _E("error(%d)", ret);
+ result = ret;
+ }
+
+ param = g_variant_new("(i)", result);
+ g_dbus_method_invocation_return_value(invocation, param);
+}
+
static void handle_method_call(GDBusConnection *connection,
const gchar *sender, const gchar *object_path,
const gchar *interface_name, const gchar *method_name,
} else if (g_strcmp0(method_name, "DisableFullPkg") == 0) {
_app2sd_server_disable_full_pkg(connection, sender,
parameters, invocation, sender_uid);
+ } else if (g_strcmp0(method_name, "PreMigrateLegacy") == 0) {
+ _app2sd_server_pre_migrate_legacy(connection, sender,
+ parameters, invocation, sender_uid);
+ } else if (g_strcmp0(method_name, "PostMigrateLegacy") == 0) {
+ _app2sd_server_post_migrate_legacy(connection, sender,
+ parameters, invocation, sender_uid);
+ } else if (g_strcmp0(method_name, "MigrateLegacyAll") == 0) {
+ _app2sd_server_migrate_legacy_all(connection, sender,
+ parameters, invocation, sender_uid);
}
if (source_id)
return ret;
}
+
+int app2ext_migrate_legacy_all(void)
+{
+ app2ext_handle *handle = NULL;
+
+ handle = app2ext_init(APP2EXT_SD_CARD);
+ if (handle == NULL) {
+ _E("app2ext init failed");
+ return -1;
+ }
+
+ handle->interface.client_migrate_legacy_all();
+ app2ext_deinit(handle);
+
+ return 0;
+}
+
+char *app2ext_usr_getname_image(const char *pkgid, uid_t uid)
+{
+ app2ext_handle *handle = NULL;
+ char *image_name = NULL;
+
+ /* validate the function parameter received */
+ if (pkgid == NULL) {
+ _E("invalid func parameters");
+ return NULL;
+ }
+
+ handle = app2ext_init(APP2EXT_SD_CARD);
+ if (handle == NULL) {
+ _E("app2ext init failed");
+ return NULL;
+ }
+
+ image_name = handle->interface.client_usr_getname_image(pkgid, uid);
+ app2ext_deinit(handle);
+
+ return image_name;
+}
"APP2EXT_ERROR_OPERATION_NOT_PERMITTED",
"APP2EXT_ERROR_SAME_LOOPBACK_DEVICE_EXISTS",
"APP2EXT_ERROR_PKGMGR_ERROR",
+ "APP2EXT_ERROR_NOENTRY",
#ifdef TIZEN_FEATURE_APP2SD_DMCRYPT_ENCRYPTION
"APP2EXT_ERROR_SETUP_DMCRYPT_DEVICE",
"APP2EXT_ERROR_OPEN_DMCRYPT_DEVICE",
{
printf("\n");
printf("*************************************************\n");
- printf("app2sd test usage:\n");
- printf("pre-condition: /tmp/org.example.basicuiapplication-1.0.0-arm.tpk\n");
+ printf("App2sd test usage:\n");
+ printf("Pre-condition: /tmp/org.example.basicuiapplication-1.0.0-arm.tpk\n");
+ printf("All tests assume the target uid as default user.\n");
printf("\n");
printf("<INSTALL>\n");
- printf("1.(at target_user)$test_app2ext --pre-install\n");
- printf("2.(at target_user)$pkgcmd -it tpk {pkg-path}\n");
- printf("3.(at target_user)$test_app2ext --post-install\n");
+ printf("1.#test_app2ext --pre-install\n");
+ printf("2.#pkgcmd -it tpk {pkg-path}\n");
+ printf("3.#test_app2ext --post-install\n");
printf("------------------------------------------------\n");
printf("\n");
printf("<UPGRADE>\n");
- printf("1.(at target_user)$test_app2ext --pre-upgrade\n");
- printf("2.(at target_user)$pkgcmd -it tpk {pkg-path}\n");
- printf("3.(at target_user)$test_app2ext --post-upgrade\n");
+ printf("1.#test_app2ext --pre-upgrade\n");
+ printf("2.#pkgcmd -it tpk {pkg-path}\n");
+ printf("3.#test_app2ext --post-upgrade\n");
printf("------------------------------------------------\n");
printf("\n");
printf("<INSTALL>\n");
- printf("1.(at target_user)$test_app2ext --pre-uninstall\n");
- printf("2.(at target_user)$pkgcmd -un {pkg-id}\n");
- printf("3.(at target_user)$test_app2ext --post-uninstall\n");
+ printf("1.#test_app2ext --pre-uninstall\n");
+ printf("2.#pkgcmd -un {pkg-id}\n");
+ printf("3.#test_app2ext --post-uninstall\n");
printf("------------------------------------------------\n");
printf("\n");
printf("<MOVE PKG TEST>\n");
- printf("(at target_user)$test_app2ext --move-to-ext\n");
- printf("(at target_user)$test_app2ext --move-to-int\n");
+ printf("#test_app2ext --move-to-ext\n");
+ printf("#test_app2ext --move-to-int\n");
printf("------------------------------------------------\n");
printf("\n");
printf("<ENABLE(mount)/DISABLE(umount) TEST W/ Installed PKG>\n");
- printf("(at target_user)$test_app2ext --enable\n");
- printf("(at target_user)$test_app2ext --disable\n");
- printf("(at target_user)$test_app2ext --enable-full\n");
- printf("(at target_user)$test_app2ext --disable-full\n");
+ printf("#test_app2ext --enable\n");
+ printf("#test_app2ext --disable\n");
+ printf("#test_app2ext --enable-full\n");
+ printf("#test_app2ext --disable-full\n");
+ printf("------------------------------------------------\n");
+ printf("\n");
+ printf("<MIGRATION TRIGGER TEST>\n");
+ printf("Pre-condition: install test package and copy legacy image to app2sd.\n");
+ printf("#test_app2ext --migrate-all\n");
printf("------------------------------------------------\n");
printf("**************************************************\n");
printf("\n");
#define OPTVAL_DISABLE_APP 1009
#define OPTVAL_ENABLE_FULL 1010
#define OPTVAL_DISABLE_FULL 1011
-#define OPTVAL_USAGE 1012
+#define OPTVAL_MIGRATE_ALL 1012
+#define OPTVAL_USAGE 1013
/* Supported options */
const struct option long_opts[] = {
{ "disable", 0, NULL, OPTVAL_DISABLE_APP },
{ "enable-full", 0, NULL, OPTVAL_ENABLE_FULL },
{ "disable-full", 0, NULL, OPTVAL_DISABLE_FULL },
+ { "migrate-all", 0, NULL, OPTVAL_MIGRATE_ALL },
{ "help", 0, NULL, OPTVAL_USAGE },
{ "usage", 0, NULL, OPTVAL_USAGE },
{ 0, 0, 0, 0 } /* sentinel */
return ret;
}
+static int migrate_all()
+{
+ int ret = -1;
+
+ ret = handle->interface.client_migrate_legacy_all();
+ print_error_code(__func__, ret);
+
+ return ret;
+}
+
static int pre_app_uninstall()
{
int ret = -1;
uid_t uid = getuid();
/* check user */
- if (uid == GLOBAL_USER) {
- printf("test for global app\n");
- } else if (uid == OWNER_ROOT) {
- printf("for root user, a test isn't supproted yet\n");
+ if (uid != OWNER_ROOT) {
+ printf("only root user allowed\n");
return 0;
- } else {
- printf("test for user(%d) app\n", uid);
}
/* check sdcard info */
case OPTVAL_DISABLE_FULL:
fullpkg_disable();
break;
+ case OPTVAL_MIGRATE_ALL:
+ migrate_all();
+ break;
case OPTVAL_USAGE:
default:
usage();