From dbf600d69b3cb2d24d63165da9cf5e801397fedf Mon Sep 17 00:00:00 2001 From: Sangyoon Jang Date: Fri, 22 Apr 2016 15:06:47 +0900 Subject: [PATCH 01/16] Implement restriction mode For setting restriction mode, pkgmgr-server will make a file at /run/user// This file contains current restriction mode. Since this directory is volitile, it will be deleted if the user session closed. Change-Id: Ic665cbefc40e1010d266d809def549ab36eb51eb Signed-off-by: Sangyoon Jang --- CMakeLists.txt | 9 ++- include/pkgmgr-server.h | 6 ++ org.tizen.pkgmgr.conf.in | 3 + packaging/pkgmgr-server.spec | 1 + src/pkgmgr-server.c | 50 ++++++++++++ src/request.c | 139 ++++++++++++++++++++++++++++++- src/restriction_mode.c | 189 +++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 395 insertions(+), 2 deletions(-) create mode 100644 src/restriction_mode.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 7d89a0b..917b6f3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,6 +12,7 @@ SET(LIBDIR ${LIB_INSTALL_DIR}) SET(INCLUDEDIR "\${prefix}/include") ADD_DEFINITIONS(-DDB_DIR="${DB_DIR}") +ADD_DEFINITIONS(-DRUN_DIR="${RUN_DIR}") ADD_DEFINITIONS(-DBACKEND_DIR="${BACKEND_DIR}") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden -g -Wall") @@ -20,7 +21,13 @@ INCLUDE_DIRECTORIES(include) INCLUDE(FindPkgConfig) SET(PKGMGR_SERVER "pkgmgr-server") -SET(SRCS src/pkgmgr-server.c src/request.c src/pm-queue.c src/db.c) +SET(SRCS + src/pkgmgr-server.c + src/request.c + src/pm-queue.c + src/db.c + src/restriction_mode.c + ) pkg_check_modules(SERVER_DEPS REQUIRED gio-2.0 diff --git a/include/pkgmgr-server.h b/include/pkgmgr-server.h index 602e0fa..5faf134 100644 --- a/include/pkgmgr-server.h +++ b/include/pkgmgr-server.h @@ -81,6 +81,9 @@ enum request_type { PKGMGR_REQUEST_TYPE_CHECK_BLACKLIST, PKGMGR_REQUEST_TYPE_ENABLE_APP_SPLASH_SCREEN, PKGMGR_REQUEST_TYPE_DISABLE_APP_SPLASH_SCREEN, + PKGMGR_REQUEST_TYPE_SET_RESTRICTION_MODE, + PKGMGR_REQUEST_TYPE_UNSET_RESTRICTION_MODE, + PKGMGR_REQUEST_TYPE_GET_RESTRICTION_MODE, }; typedef struct { @@ -110,5 +113,8 @@ void __fini_request_handler(void); int __add_blacklist(uid_t uid, const char *pkgid); int __remove_blacklist(uid_t uid, const char *pkgid); int __check_blacklist(uid_t uid, const char *pkgid, int *result); +int __set_restriction_mode(uid_t uid, int mode); +int __unset_restriction_mode(uid_t uid, int mode); +int __get_restriction_mode(uid_t uid, int *result); #endif/* _PKGMGR_SERVER_H_ */ diff --git a/org.tizen.pkgmgr.conf.in b/org.tizen.pkgmgr.conf.in index c3b0204..6aeb6f4 100644 --- a/org.tizen.pkgmgr.conf.in +++ b/org.tizen.pkgmgr.conf.in @@ -27,5 +27,8 @@ + + + diff --git a/packaging/pkgmgr-server.spec b/packaging/pkgmgr-server.spec index 7c9768d..5dd8633 100644 --- a/packaging/pkgmgr-server.spec +++ b/packaging/pkgmgr-server.spec @@ -38,6 +38,7 @@ Packager Manager server package for packaging cp %{SOURCE1001} . %define db_dir %{_localstatedir}/lib/package-manager +%define run_dir /run/user %define backend_dir %{_sysconfdir}/package-manager/backend %build diff --git a/src/pkgmgr-server.c b/src/pkgmgr-server.c index 78ed2b3..ada3f99 100644 --- a/src/pkgmgr-server.c +++ b/src/pkgmgr-server.c @@ -1348,6 +1348,47 @@ static int __process_update_app_splash_screen(pm_dbus_msg *item, int flag) return ret; } +static int __process_set_restriction_mode(pm_dbus_msg *item) +{ + int ret; + int mode; + + mode = atoi(item->args); + ret = __set_restriction_mode(item->uid, mode); + + __return_value_to_caller(item->req_id, + g_variant_new("(i)", ret)); + + return ret; +} + +static int __process_unset_restriction_mode(pm_dbus_msg *item) +{ + int ret; + int mode; + + mode = atoi(item->args); + ret = __unset_restriction_mode(item->uid, mode); + + __return_value_to_caller(item->req_id, + g_variant_new("(i)", ret)); + + return ret; +} + +static int __process_get_restriction_mode(pm_dbus_msg *item) +{ + int ret; + int result = -1; + + ret = __get_restriction_mode(item->uid, &result); + + __return_value_to_caller(item->req_id, + g_variant_new("(ii)", result, ret)); + + return ret; +} + gboolean queue_job(void *data) { pm_dbus_msg *item = NULL; @@ -1464,6 +1505,15 @@ gboolean queue_job(void *data) case PKGMGR_REQUEST_TYPE_DISABLE_APP_SPLASH_SCREEN: ret = __process_update_app_splash_screen(item, 0); break; + case PKGMGR_REQUEST_TYPE_SET_RESTRICTION_MODE: + ret = __process_set_restriction_mode(item); + break; + case PKGMGR_REQUEST_TYPE_UNSET_RESTRICTION_MODE: + ret = __process_unset_restriction_mode(item); + break; + case PKGMGR_REQUEST_TYPE_GET_RESTRICTION_MODE: + ret = __process_get_restriction_mode(item); + break; default: ret = -1; break; diff --git a/src/request.c b/src/request.c index daf4d12..e2c6871 100644 --- a/src/request.c +++ b/src/request.c @@ -159,6 +159,21 @@ static const char instropection_xml[] = " " " " " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " " " ""; static GDBusNodeInfo *instropection_data; @@ -1093,7 +1108,6 @@ static int __handle_request_check_blacklist(uid_t uid, return 0; } - static int __update_app_splash_screen(uid_t uid, GDBusMethodInvocation *invocation, GVariant *parameters, int req_type) @@ -1148,6 +1162,120 @@ static int __handle_request_disable_app_splash_screen(uid_t uid, PKGMGR_REQUEST_TYPE_DISABLE_APP_SPLASH_SCREEN); } +static int __handle_request_set_restriction_mode(uid_t uid, + GDBusMethodInvocation *invocation, GVariant *parameters) +{ + uid_t target_uid = (uid_t)-1; + char *reqkey; + int mode = -1; + char buf[4]; + + g_variant_get(parameters, "(ui)", &target_uid, &mode); + if (target_uid == (uid_t)-1 || mode < 0) { + g_dbus_method_invocation_return_value(invocation, + g_variant_new("(i)", PKGMGR_R_ECOMM)); + return -1; + } + + reqkey = __generate_reqkey("restriction"); + if (reqkey == NULL) { + g_dbus_method_invocation_return_value(invocation, + g_variant_new("(i)", PKGMGR_R_ENOMEM)); + return -1; + } + + snprintf(buf, sizeof(buf), "%d", mode); + if (_pm_queue_push(target_uid, reqkey, + PKGMGR_REQUEST_TYPE_SET_RESTRICTION_MODE, + "default", "", buf)) { + g_dbus_method_invocation_return_value(invocation, + g_variant_new("(i)", PKGMGR_R_ESYSTEM)); + free(reqkey); + return -1; + } + + if (!g_hash_table_insert(req_table, (gpointer)reqkey, + (gpointer)invocation)) + ERR("reqkey already exists"); + + return 0; +} + +static int __handle_request_unset_restriction_mode(uid_t uid, + GDBusMethodInvocation *invocation, GVariant *parameters) +{ + uid_t target_uid = (uid_t)-1; + char *reqkey; + int mode = -1; + char buf[4]; + + g_variant_get(parameters, "(ui)", &target_uid, &mode); + if (target_uid == (uid_t)-1 || mode < 0) { + g_dbus_method_invocation_return_value(invocation, + g_variant_new("(i)", PKGMGR_R_ECOMM)); + return -1; + } + + reqkey = __generate_reqkey("restriction"); + if (reqkey == NULL) { + g_dbus_method_invocation_return_value(invocation, + g_variant_new("(i)", PKGMGR_R_ENOMEM)); + return -1; + } + + snprintf(buf, sizeof(buf), "%d", mode); + if (_pm_queue_push(target_uid, reqkey, + PKGMGR_REQUEST_TYPE_UNSET_RESTRICTION_MODE, + "default", "", buf)) { + g_dbus_method_invocation_return_value(invocation, + g_variant_new("(i)", PKGMGR_R_ESYSTEM)); + free(reqkey); + return -1; + } + + if (!g_hash_table_insert(req_table, (gpointer)reqkey, + (gpointer)invocation)) + ERR("reqkey already exists"); + + return 0; +} + +static int __handle_request_get_restriction_mode(uid_t uid, + GDBusMethodInvocation *invocation, GVariant *parameters) +{ + uid_t target_uid = (uid_t)-1; + char *reqkey; + + g_variant_get(parameters, "(u)", &target_uid); + if (target_uid == (uid_t)-1) { + g_dbus_method_invocation_return_value(invocation, + g_variant_new("(i)", PKGMGR_R_ECOMM)); + return -1; + } + + reqkey = __generate_reqkey("restriction"); + if (reqkey == NULL) { + g_dbus_method_invocation_return_value(invocation, + g_variant_new("(ii)", -1, PKGMGR_R_ENOMEM)); + return -1; + } + + if (_pm_queue_push(target_uid, reqkey, + PKGMGR_REQUEST_TYPE_GET_RESTRICTION_MODE, + "default", "", "")) { + g_dbus_method_invocation_return_value(invocation, + g_variant_new("(ii)", -1, PKGMGR_R_ESYSTEM)); + free(reqkey); + return -1; + } + + if (!g_hash_table_insert(req_table, (gpointer)reqkey, + (gpointer)invocation)) + ERR("reqkey already exists"); + + return 0; +} + static uid_t __get_caller_uid(GDBusConnection *connection, const char *name) { GError *err = NULL; @@ -1243,6 +1371,15 @@ static void __handle_method_call(GDBusConnection *connection, else if (g_strcmp0(method_name, "enable_app_splash_screen") == 0) ret = __handle_request_enable_app_splash_screen(uid, invocation, parameters); + else if (g_strcmp0(method_name, "set_restriction_mode") == 0) + ret = __handle_request_set_restriction_mode(uid, invocation, + parameters); + else if (g_strcmp0(method_name, "unset_restriction_mode") == 0) + ret = __handle_request_unset_restriction_mode(uid, invocation, + parameters); + else if (g_strcmp0(method_name, "get_restriction_mode") == 0) + ret = __handle_request_get_restriction_mode(uid, invocation, + parameters); else ret = -1; diff --git a/src/restriction_mode.c b/src/restriction_mode.c new file mode 100644 index 0000000..50fe8d5 --- /dev/null +++ b/src/restriction_mode.c @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pkgmgr-server.h" + +#ifndef RUN_DIR +#define RUN_DIR "/run/user" +#endif + +#define RESTRICTION_CONF ".package_manager_restriction_mode" + +static char *_get_conf_file_path(uid_t uid) +{ + char buf[PATH_MAX]; + + snprintf(buf, sizeof(buf), "%s/%d/%s", RUN_DIR, uid, RESTRICTION_CONF); + + return strdup(buf); +} + +static int __set_mode(int cur, int mode) +{ + return cur | mode; +} + +static int __unset_mode(int cur, int mode) +{ + return cur & ~(mode); +} + +int __set_restriction_mode(uid_t uid, int mode) +{ + char *conf_path; + int fd; + int cur = 0; + ssize_t len; + + conf_path = _get_conf_file_path(uid); + if (conf_path == NULL) { + ERR("failed to get conf path"); + return -1; + } + + fd = open(conf_path, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); + if (fd < 0) { + ERR("failed to open conf file: %d", errno); + free(conf_path); + return -1; + } + + len = read(fd, &cur, sizeof(int)); + if (len < 0) { + ERR("failed to read conf file: %d", errno); + close(fd); + free(conf_path); + return -1; + } + + mode = __set_mode(cur, mode); + + lseek(fd, 0, SEEK_SET); + len = write(fd, &mode, sizeof(int)); + if (len < 0) { + ERR("failed to write conf file: %d", errno); + close(fd); + free(conf_path); + return -1; + } + + close(fd); + free(conf_path); + + return 0; +} + +int __unset_restriction_mode(uid_t uid, int mode) +{ + char *conf_path; + int fd; + int cur = 0; + ssize_t len; + + conf_path = _get_conf_file_path(uid); + if (conf_path == NULL) { + ERR("failed to get conf path"); + return -1; + } + + if (access(conf_path, F_OK) != 0) { + ERR("restriction mode is not set"); + free(conf_path); + return 0; + } + + fd = open(conf_path, O_RDWR, 0); + if (fd < 0) { + ERR("failed to open conf file: %s", errno); + free(conf_path); + return -1; + } + + len = read(fd, &cur, sizeof(int)); + if (len < 0) { + ERR("failed to read conf file: %d", errno); + close(fd); + free(conf_path); + return -1; + } + + mode = __unset_mode(cur, mode); + + lseek(fd, 0, SEEK_SET); + len = write(fd, &mode, sizeof(int)); + if (len < 0) { + ERR("failed to write conf file: %d", errno); + close(fd); + free(conf_path); + return -1; + } + + close(fd); + free(conf_path); + + return 0; +} + +int __get_restriction_mode(uid_t uid, int *result) +{ + char *conf_path; + int fd; + int cur; + ssize_t len; + + conf_path = _get_conf_file_path(uid); + if (conf_path == NULL) + return -1; + + if (access(conf_path, F_OK) != 0) { + free(conf_path); + *result = 0; + return 0; + } + + fd = open(conf_path, O_RDONLY, 0); + if (fd < 0) { + ERR("failed to open conf file: %s", errno); + free(conf_path); + return -1; + } + + len = read(fd, &cur, sizeof(int)); + if (len < 0) { + ERR("failed to read conf file: %d", errno); + close(fd); + free(conf_path); + return -1; + } + + *result = cur; + + close(fd); + free(conf_path); + + return 0; +} -- 2.7.4 From b06797764d79c49e5c2643ff877482fa9c792da4 Mon Sep 17 00:00:00 2001 From: Sangyoon Jang Date: Fri, 13 May 2016 18:41:52 +0900 Subject: [PATCH 02/16] Redesign restriction mode - Remove blacklist feature(merged to restriction mode) - Use gdbm to store mode - set/unset/get by pkgid Change-Id: I3da360eb5b20471c5249f8445b96560c7fead598 Signed-off-by: Sangyoon Jang --- CMakeLists.txt | 4 +- blacklist.sql | 8 -- include/pkgmgr-server.h | 12 +-- org.tizen.pkgmgr.conf.in | 8 +- packaging/pkgmgr-server.spec | 11 +-- src/db.c | 217 ----------------------------------------- src/pkgmgr-server.c | 56 +---------- src/request.c | 160 +++--------------------------- src/restriction_mode.c | 225 ++++++++++++++++++++++--------------------- 9 files changed, 146 insertions(+), 555 deletions(-) delete mode 100644 blacklist.sql delete mode 100644 src/db.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 917b6f3..9b8829e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,7 +25,6 @@ SET(SRCS src/pkgmgr-server.c src/request.c src/pm-queue.c - src/db.c src/restriction_mode.c ) @@ -36,7 +35,6 @@ pkg_check_modules(SERVER_DEPS REQUIRED pkgmgr-info libtzplatform-config drm-service-core-tizen - sqlite3 libgum pkgmgr pkgmgr-installer) @@ -46,7 +44,7 @@ ENDFOREACH(SERVER_FLAGS) ADD_EXECUTABLE(${PKGMGR_SERVER} ${SRCS}) TARGET_LINK_LIBRARIES(${PKGMGR_SERVER} pkgmgr_installer) -TARGET_LINK_LIBRARIES(${PKGMGR_SERVER} ${SERVER_DEPS_LDFLAGS}) +TARGET_LINK_LIBRARIES(${PKGMGR_SERVER} ${SERVER_DEPS_LDFLAGS} -lgdbm) CONFIGURE_FILE(org.tizen.pkgmgr.service.in org.tizen.pkgmgr.service @ONLY) CONFIGURE_FILE(org.tizen.pkgmgr.conf.in org.tizen.pkgmgr.conf @ONLY) diff --git a/blacklist.sql b/blacklist.sql deleted file mode 100644 index 0db3ddb..0000000 --- a/blacklist.sql +++ /dev/null @@ -1,8 +0,0 @@ -PRAGMA user_version = 30; /* Tizen 3.0 */ -PRAGMA journal_mode = WAL; - -CREATE TABLE blacklist ( - uid INTEGER NOT NULL, - pkgid TEXT NOT NULL, - UNIQUE (uid, pkgid) -); diff --git a/include/pkgmgr-server.h b/include/pkgmgr-server.h index 5faf134..8a49751 100644 --- a/include/pkgmgr-server.h +++ b/include/pkgmgr-server.h @@ -76,9 +76,6 @@ enum request_type { PKGMGR_REQUEST_TYPE_GENERATE_LICENSE_REQUEST, PKGMGR_REQUEST_TYPE_REGISTER_LICENSE, PKGMGR_REQUEST_TYPE_DECRYPT_PACKAGE, - PKGMGR_REQUEST_TYPE_ADD_BLACKLIST, - PKGMGR_REQUEST_TYPE_REMOVE_BLACKLIST, - PKGMGR_REQUEST_TYPE_CHECK_BLACKLIST, PKGMGR_REQUEST_TYPE_ENABLE_APP_SPLASH_SCREEN, PKGMGR_REQUEST_TYPE_DISABLE_APP_SPLASH_SCREEN, PKGMGR_REQUEST_TYPE_SET_RESTRICTION_MODE, @@ -110,11 +107,8 @@ gboolean queue_job(void *data); int __return_value_to_caller(const char *req_key, GVariant *result); int __init_request_handler(void); void __fini_request_handler(void); -int __add_blacklist(uid_t uid, const char *pkgid); -int __remove_blacklist(uid_t uid, const char *pkgid); -int __check_blacklist(uid_t uid, const char *pkgid, int *result); -int __set_restriction_mode(uid_t uid, int mode); -int __unset_restriction_mode(uid_t uid, int mode); -int __get_restriction_mode(uid_t uid, int *result); +int __restriction_mode_set(uid_t uid, const char *pkgid, int mode); +int __restriction_mode_unset(uid_t uid, const char *pkgid, int mode); +int __restriction_mode_get(uid_t uid, const char *pkgid, int *mode); #endif/* _PKGMGR_SERVER_H_ */ diff --git a/org.tizen.pkgmgr.conf.in b/org.tizen.pkgmgr.conf.in index 6aeb6f4..bee2a29 100644 --- a/org.tizen.pkgmgr.conf.in +++ b/org.tizen.pkgmgr.conf.in @@ -5,6 +5,9 @@ + + + @@ -27,8 +30,5 @@ - - - - + diff --git a/packaging/pkgmgr-server.spec b/packaging/pkgmgr-server.spec index 5dd8633..4ea86ec 100644 --- a/packaging/pkgmgr-server.spec +++ b/packaging/pkgmgr-server.spec @@ -24,8 +24,8 @@ BuildRequires: pkgconfig(libsmack) BuildRequires: pkgconfig(pkgmgr) BuildRequires: pkgconfig(pkgmgr-installer) BuildRequires: pkgconfig(drm-service-core-tizen) -BuildRequires: pkgconfig(sqlite3) BuildRequires: pkgconfig(libgum) +BuildRequires: gdbm-devel BuildRequires: pkgmgr-info-parser-devel BuildRequires: pkgmgr-info-parser BuildRequires: fdupes @@ -37,14 +37,11 @@ Packager Manager server package for packaging %setup -q cp %{SOURCE1001} . -%define db_dir %{_localstatedir}/lib/package-manager %define run_dir /run/user %define backend_dir %{_sysconfdir}/package-manager/backend %build -sqlite3 blacklist.db < ./blacklist.sql - -%cmake . -DDB_DIR=%{db_dir} -DBACKEND_DIR=%{backend_dir} +%cmake . -DRUN_DIR=%{run_dir} -DBACKEND_DIR=%{backend_dir} %__make %{?_smp_mflags} @@ -55,9 +52,6 @@ mkdir -p %{buildroot}/usr/share/license cp LICENSE %{buildroot}/usr/share/license/%{name} mkdir -p %{buildroot}%{_sysconfdir}/package-manager/server -mkdir -p %{buildroot}%{db_dir} -install -m 0600 blacklist.db %{buildroot}%{db_dir} - %fdupes %{buildroot} %post @@ -70,6 +64,5 @@ install -m 0600 blacklist.db %{buildroot}%{db_dir} %config %{_sysconfdir}/dbus-1/system.d/org.tizen.pkgmgr.conf %{_bindir}/pkgmgr-server %{_sysconfdir}/package-manager/server -%config(noreplace) %{db_dir}/blacklist.db %exclude %{_sysconfdir}/package-manager/server/queue_status /usr/share/license/%{name} diff --git a/src/db.c b/src/db.c deleted file mode 100644 index 68b8cdf..0000000 --- a/src/db.c +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include -#include -#include - -#include - -#include - -#include "pkgmgr-server.h" - -#ifndef DB_DIR -#define DB_DIR "/var/lib/package-manager" -#endif - -static const char *_get_db_path(void) -{ - return DB_DIR"/blacklist.db"; -} - -static sqlite3 *_open_db(void) -{ - int ret; - const char *path; - sqlite3 *db; - - path = _get_db_path(); - if (path == NULL) { - ERR("get db path error"); - return NULL; - } - - ret = sqlite3_open_v2(path, &db, SQLITE_OPEN_READWRITE, NULL); - if (ret != SQLITE_OK) { - ERR("open db error: %d", ret); - return NULL; - } - - return db; -} - -static int __add_blacklist_info(sqlite3 *db, uid_t uid, const char *pkgid) -{ - static const char query[] = - "INSERT INTO blacklist (uid, pkgid) VALUES(?, ?)"; - int ret; - sqlite3_stmt *stmt; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - ERR("prepare error: %s", sqlite3_errmsg(db)); - return -1; - } - - sqlite3_bind_int(stmt, 1, uid); - sqlite3_bind_text(stmt, 2, pkgid, -1, SQLITE_STATIC); - - ret = sqlite3_step(stmt); - sqlite3_finalize(stmt); - if (ret != SQLITE_DONE) { - ERR("step error: %s", sqlite3_errmsg(db)); - return -1; - } - - return 0; -} - -int __add_blacklist(uid_t uid, const char *pkgid) -{ - int ret; - sqlite3 *db; - - db = _open_db(); - if (db == NULL) - return PKGMGR_R_ERROR; - - ret = sqlite3_exec(db, "BEGIN EXCLUSIVE", NULL, NULL, NULL); - if (ret != SQLITE_OK) { - sqlite3_close_v2(db); - ERR("transaction failed"); - return PKGMGR_R_ERROR; - } - - if (__add_blacklist_info(db, uid, pkgid)) { - sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL); - sqlite3_close_v2(db); - return PKGMGR_R_ERROR; - } - - ret = sqlite3_exec(db, "COMMIT", NULL, NULL, NULL); - if (ret != SQLITE_OK) { - ERR("commit error: %s", sqlite3_errmsg(db)); - sqlite3_close_v2(db); - return PKGMGR_R_ERROR; - } - - sqlite3_close_v2(db); - - return PKGMGR_R_OK; -} - -static int __remove_blacklist_info(sqlite3 *db, uid_t uid, const char *pkgid) -{ - static const char query[] = - "DELETE FROM blacklist WHERE uid=? AND pkgid=?"; - int ret; - sqlite3_stmt *stmt; - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - ERR("prepare error: %s", sqlite3_errmsg(db)); - return -1; - } - - sqlite3_bind_int(stmt, 1, uid); - sqlite3_bind_text(stmt, 2, pkgid, -1, SQLITE_STATIC); - - ret = sqlite3_step(stmt); - sqlite3_finalize(stmt); - if (ret != SQLITE_DONE) { - ERR("step error: %s", sqlite3_errmsg(db)); - return -1; - } - - return 0; -} - -int __remove_blacklist(uid_t uid, const char *pkgid) -{ - int ret; - sqlite3 *db; - - db = _open_db(); - if (db == NULL) - return PKGMGR_R_ERROR; - - ret = sqlite3_exec(db, "BEGIN EXCLUSIVE", NULL, NULL, NULL); - if (ret != SQLITE_OK) { - sqlite3_close_v2(db); - ERR("transaction failed"); - return PKGMGR_R_ERROR; - } - - if (__remove_blacklist_info(db, uid, pkgid)) { - sqlite3_exec(db, "ROLLBACK", NULL, NULL, NULL); - sqlite3_close_v2(db); - return PKGMGR_R_ERROR; - } - - ret = sqlite3_exec(db, "COMMIT", NULL, NULL, NULL); - if (ret != SQLITE_OK) { - ERR("commit error: %s", sqlite3_errmsg(db)); - sqlite3_close_v2(db); - return PKGMGR_R_ERROR; - } - - sqlite3_close_v2(db); - - return PKGMGR_R_OK; -} - -int __check_blacklist(uid_t uid, const char *pkgid, int *result) -{ - static const char query[] = - "SELECT * FROM blacklist WHERE uid=? AND pkgid=?"; - int ret; - sqlite3 *db; - sqlite3_stmt *stmt; - - db = _open_db(); - if (db == NULL) { - *result = 0; - return PKGMGR_R_ERROR; - } - - ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); - if (ret != SQLITE_OK) { - ERR("prepare error: %s", sqlite3_errmsg(db)); - *result = 0; - sqlite3_close_v2(db); - return PKGMGR_R_ERROR; - } - - sqlite3_bind_int(stmt, 1, uid); - sqlite3_bind_text(stmt, 2, pkgid, -1, SQLITE_STATIC); - - ret = sqlite3_step(stmt); - sqlite3_finalize(stmt); - if (ret != SQLITE_ROW) { - if (ret != SQLITE_DONE) - ERR("step error: %s", sqlite3_errmsg(db)); - *result = 0; - sqlite3_close_v2(db); - return ret == SQLITE_DONE ? PKGMGR_R_OK : PKGMGR_R_ERROR; - } - - *result = 1; - sqlite3_close_v2(db); - - return PKGMGR_R_OK; -} diff --git a/src/pkgmgr-server.c b/src/pkgmgr-server.c index ada3f99..58f79f0 100644 --- a/src/pkgmgr-server.c +++ b/src/pkgmgr-server.c @@ -1276,43 +1276,6 @@ static int __process_decrypt_package(pm_dbus_msg *item) return 0; } -static int __process_add_blacklist(pm_dbus_msg *item) -{ - int ret; - - ret = __add_blacklist(item->uid, item->pkgid); - - __return_value_to_caller(item->req_id, - g_variant_new("(i)", ret)); - - return ret; -} - -static int __process_remove_blacklist(pm_dbus_msg *item) -{ - int ret; - - ret = __remove_blacklist(item->uid, item->pkgid); - - __return_value_to_caller(item->req_id, - g_variant_new("(i)", ret)); - - return ret; -} - -static int __process_check_blacklist(pm_dbus_msg *item) -{ - int ret; - int result = 0; - - ret = __check_blacklist(item->uid, item->pkgid, &result); - - __return_value_to_caller(item->req_id, - g_variant_new("(ii)", result, ret)); - - return ret; -} - static int __process_update_app_splash_screen(pm_dbus_msg *item, int flag) { int ret; @@ -1354,7 +1317,7 @@ static int __process_set_restriction_mode(pm_dbus_msg *item) int mode; mode = atoi(item->args); - ret = __set_restriction_mode(item->uid, mode); + ret = __restriction_mode_set(item->uid, item->pkgid, mode); __return_value_to_caller(item->req_id, g_variant_new("(i)", ret)); @@ -1368,7 +1331,7 @@ static int __process_unset_restriction_mode(pm_dbus_msg *item) int mode; mode = atoi(item->args); - ret = __unset_restriction_mode(item->uid, mode); + ret = __restriction_mode_unset(item->uid, item->pkgid, mode); __return_value_to_caller(item->req_id, g_variant_new("(i)", ret)); @@ -1379,12 +1342,12 @@ static int __process_unset_restriction_mode(pm_dbus_msg *item) static int __process_get_restriction_mode(pm_dbus_msg *item) { int ret; - int result = -1; + int mode = -1; - ret = __get_restriction_mode(item->uid, &result); + ret = __restriction_mode_get(item->uid, item->pkgid, &mode); __return_value_to_caller(item->req_id, - g_variant_new("(ii)", result, ret)); + g_variant_new("(ii)", mode, ret)); return ret; } @@ -1490,15 +1453,6 @@ gboolean queue_job(void *data) case PKGMGR_REQUEST_TYPE_DECRYPT_PACKAGE: ret = __process_decrypt_package(item); break; - case PKGMGR_REQUEST_TYPE_ADD_BLACKLIST: - ret = __process_add_blacklist(item); - break; - case PKGMGR_REQUEST_TYPE_REMOVE_BLACKLIST: - ret = __process_remove_blacklist(item); - break; - case PKGMGR_REQUEST_TYPE_CHECK_BLACKLIST: - ret = __process_check_blacklist(item); - break; case PKGMGR_REQUEST_TYPE_ENABLE_APP_SPLASH_SCREEN: ret = __process_update_app_splash_screen(item, 1); break; diff --git a/src/request.c b/src/request.c index e2c6871..ba99bf0 100644 --- a/src/request.c +++ b/src/request.c @@ -133,22 +133,6 @@ static const char instropection_xml[] = " " " " " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " " " " " " " @@ -161,16 +145,19 @@ static const char instropection_xml[] = " " " " " " + " " " " " " " " " " " " + " " " " " " " " " " " " + " " " " " " " " @@ -997,117 +984,6 @@ static int __handle_request_decrypt_package(uid_t uid, return 0; } -static int __handle_request_add_blacklist(uid_t uid, - GDBusMethodInvocation *invocation, GVariant *parameters) -{ - uid_t target_uid = (uid_t)-1; - char *reqkey; - char *pkgid = NULL; - - g_variant_get(parameters, "(u&s)", &target_uid, &pkgid); - if (target_uid == (uid_t)-1 || pkgid == NULL) { - g_dbus_method_invocation_return_value(invocation, - g_variant_new("(i)", PKGMGR_R_ECOMM)); - return -1; - } - - reqkey = __generate_reqkey("blacklist"); - if (reqkey == NULL) { - g_dbus_method_invocation_return_value(invocation, - g_variant_new("(i)", PKGMGR_R_ENOMEM)); - return -1; - } - - if (_pm_queue_push(target_uid, reqkey, - PKGMGR_REQUEST_TYPE_ADD_BLACKLIST, - "default", pkgid, "")) { - g_dbus_method_invocation_return_value(invocation, - g_variant_new("(i)", PKGMGR_R_ESYSTEM)); - free(reqkey); - return -1; - } - - if (!g_hash_table_insert(req_table, (gpointer)reqkey, - (gpointer)invocation)) - ERR("reqkey already exists"); - - return 0; -} - -static int __handle_request_remove_blacklist(uid_t uid, - GDBusMethodInvocation *invocation, GVariant *parameters) -{ - uid_t target_uid = (uid_t)-1; - char *reqkey; - char *pkgid = NULL; - - g_variant_get(parameters, "(u&s)", &target_uid, &pkgid); - if (target_uid == (uid_t)-1 || pkgid == NULL) { - g_dbus_method_invocation_return_value(invocation, - g_variant_new("(i)", PKGMGR_R_ECOMM)); - return -1; - } - - reqkey = __generate_reqkey("blacklist"); - if (reqkey == NULL) { - g_dbus_method_invocation_return_value(invocation, - g_variant_new("(i)", PKGMGR_R_ENOMEM)); - return -1; - } - - if (_pm_queue_push(target_uid, reqkey, - PKGMGR_REQUEST_TYPE_REMOVE_BLACKLIST, - "default", pkgid, "")) { - g_dbus_method_invocation_return_value(invocation, - g_variant_new("(i)", PKGMGR_R_ESYSTEM)); - free(reqkey); - return -1; - } - - if (!g_hash_table_insert(req_table, (gpointer)reqkey, - (gpointer)invocation)) - ERR("reqkey already exists"); - - return 0; -} - -static int __handle_request_check_blacklist(uid_t uid, - GDBusMethodInvocation *invocation, GVariant *parameters) -{ - uid_t target_uid = (uid_t)-1; - char *reqkey; - char *pkgid = NULL; - - g_variant_get(parameters, "(u&s)", &target_uid, &pkgid); - if (target_uid == (uid_t)-1 || pkgid == NULL) { - g_dbus_method_invocation_return_value(invocation, - g_variant_new("(ii)", PKGMGR_R_ECOMM, -1)); - return -1; - } - - reqkey = __generate_reqkey("blacklist"); - if (reqkey == NULL) { - g_dbus_method_invocation_return_value(invocation, - g_variant_new("(ii)", PKGMGR_R_ENOMEM, -1)); - return -1; - } - - if (_pm_queue_push(target_uid, reqkey, - PKGMGR_REQUEST_TYPE_CHECK_BLACKLIST, - "default", pkgid, "")) { - g_dbus_method_invocation_return_value(invocation, - g_variant_new("(ii)", PKGMGR_R_ESYSTEM, -1)); - free(reqkey); - return -1; - } - - if (!g_hash_table_insert(req_table, (gpointer)reqkey, - (gpointer)invocation)) - ERR("reqkey already exists"); - - return 0; -} - static int __update_app_splash_screen(uid_t uid, GDBusMethodInvocation *invocation, GVariant *parameters, int req_type) @@ -1166,12 +1042,13 @@ static int __handle_request_set_restriction_mode(uid_t uid, GDBusMethodInvocation *invocation, GVariant *parameters) { uid_t target_uid = (uid_t)-1; + char *pkgid = NULL; char *reqkey; int mode = -1; char buf[4]; - g_variant_get(parameters, "(ui)", &target_uid, &mode); - if (target_uid == (uid_t)-1 || mode < 0) { + g_variant_get(parameters, "(usi)", &target_uid, &pkgid, &mode); + if (target_uid == (uid_t)-1 || pkgid == NULL || mode < 0) { g_dbus_method_invocation_return_value(invocation, g_variant_new("(i)", PKGMGR_R_ECOMM)); return -1; @@ -1187,7 +1064,7 @@ static int __handle_request_set_restriction_mode(uid_t uid, snprintf(buf, sizeof(buf), "%d", mode); if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_SET_RESTRICTION_MODE, - "default", "", buf)) { + "default", pkgid, buf)) { g_dbus_method_invocation_return_value(invocation, g_variant_new("(i)", PKGMGR_R_ESYSTEM)); free(reqkey); @@ -1205,12 +1082,13 @@ static int __handle_request_unset_restriction_mode(uid_t uid, GDBusMethodInvocation *invocation, GVariant *parameters) { uid_t target_uid = (uid_t)-1; + char *pkgid = NULL; char *reqkey; int mode = -1; char buf[4]; - g_variant_get(parameters, "(ui)", &target_uid, &mode); - if (target_uid == (uid_t)-1 || mode < 0) { + g_variant_get(parameters, "(usi)", &target_uid, &pkgid, &mode); + if (target_uid == (uid_t)-1 || pkgid == NULL || mode < 0) { g_dbus_method_invocation_return_value(invocation, g_variant_new("(i)", PKGMGR_R_ECOMM)); return -1; @@ -1226,7 +1104,7 @@ static int __handle_request_unset_restriction_mode(uid_t uid, snprintf(buf, sizeof(buf), "%d", mode); if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_UNSET_RESTRICTION_MODE, - "default", "", buf)) { + "default", pkgid, buf)) { g_dbus_method_invocation_return_value(invocation, g_variant_new("(i)", PKGMGR_R_ESYSTEM)); free(reqkey); @@ -1244,10 +1122,11 @@ static int __handle_request_get_restriction_mode(uid_t uid, GDBusMethodInvocation *invocation, GVariant *parameters) { uid_t target_uid = (uid_t)-1; + char *pkgid = NULL; char *reqkey; - g_variant_get(parameters, "(u)", &target_uid); - if (target_uid == (uid_t)-1) { + g_variant_get(parameters, "(us)", &target_uid, &pkgid); + if (target_uid == (uid_t)-1 || pkgid == NULL) { g_dbus_method_invocation_return_value(invocation, g_variant_new("(i)", PKGMGR_R_ECOMM)); return -1; @@ -1262,7 +1141,7 @@ static int __handle_request_get_restriction_mode(uid_t uid, if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_GET_RESTRICTION_MODE, - "default", "", "")) { + "default", pkgid, "")) { g_dbus_method_invocation_return_value(invocation, g_variant_new("(ii)", -1, PKGMGR_R_ESYSTEM)); free(reqkey); @@ -1356,15 +1235,6 @@ static void __handle_method_call(GDBusConnection *connection, else if (g_strcmp0(method_name, "decrypt_package") == 0) ret = __handle_request_decrypt_package(uid, invocation, parameters); - else if (g_strcmp0(method_name, "add_blacklist") == 0) - ret = __handle_request_add_blacklist(uid, invocation, - parameters); - else if (g_strcmp0(method_name, "remove_blacklist") == 0) - ret = __handle_request_remove_blacklist(uid, invocation, - parameters); - else if (g_strcmp0(method_name, "check_blacklist") == 0) - ret = __handle_request_check_blacklist(uid, invocation, - parameters); else if (g_strcmp0(method_name, "disable_app_splash_screen") == 0) ret = __handle_request_disable_app_splash_screen(uid, invocation, parameters); diff --git a/src/restriction_mode.c b/src/restriction_mode.c index 50fe8d5..c7ee92c 100644 --- a/src/restriction_mode.c +++ b/src/restriction_mode.c @@ -1,43 +1,27 @@ -/* - * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - #include +#include #include #include -#include #include -#include #include -#include #include +#include + #include "pkgmgr-server.h" #ifndef RUN_DIR #define RUN_DIR "/run/user" #endif +#define RESTRICTION_DB ".package_manager_restriction_mode" +#define VAL_SIZE sizeof(int) +#define ALL_PKG "ALL_PKG" -#define RESTRICTION_CONF ".package_manager_restriction_mode" - -static char *_get_conf_file_path(uid_t uid) +static char *__get_dbpath(uid_t uid) { char buf[PATH_MAX]; - snprintf(buf, sizeof(buf), "%s/%d/%s", RUN_DIR, uid, RESTRICTION_CONF); + snprintf(buf, sizeof(buf), "%s/%d/%s", RUN_DIR, uid, RESTRICTION_DB); return strdup(buf); } @@ -52,138 +36,161 @@ static int __unset_mode(int cur, int mode) return cur & ~(mode); } -int __set_restriction_mode(uid_t uid, int mode) +static GDBM_FILE __open(const char *path, bool writable) { - char *conf_path; - int fd; - int cur = 0; - ssize_t len; + GDBM_FILE db; + + db = gdbm_open((char *)path, 0, writable ? GDBM_WRCREAT : GDBM_READER, + S_IRUSR | S_IWUSR, NULL); + if (db == NULL) + ERR("failed to open gdbm file(%s): %d", path, gdbm_errno); - conf_path = _get_conf_file_path(uid); - if (conf_path == NULL) { - ERR("failed to get conf path"); + return db; +} + +static void __close(GDBM_FILE dbf) +{ + gdbm_close(dbf); +} + +static int __set_value(GDBM_FILE dbf, const char *pkgid, int mode) +{ + datum key; + datum content; + char buf[VAL_SIZE]; + + key.dptr = (char *)pkgid; + key.dsize = strlen(pkgid) + 1; + + memcpy(buf, &mode, VAL_SIZE); + content.dptr = buf; + content.dsize = VAL_SIZE; + + if (gdbm_store(dbf, key, content, GDBM_REPLACE)) { + ERR("failed to store value"); return -1; } - fd = open(conf_path, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); - if (fd < 0) { - ERR("failed to open conf file: %d", errno); - free(conf_path); + return 0; +} + +static int __get_value(GDBM_FILE dbf, const char *pkgid, int *mode) +{ + datum key; + datum content; + + key.dptr = (char *)pkgid; + key.dsize = strlen(pkgid) + 1; + + content = gdbm_fetch(dbf, key); + if (content.dptr == NULL) { + DBG("no value for key(%s)", pkgid); return -1; } - len = read(fd, &cur, sizeof(int)); - if (len < 0) { - ERR("failed to read conf file: %d", errno); - close(fd); - free(conf_path); + if (content.dsize != VAL_SIZE) + ERR("content size is different"); + + memcpy(mode, content.dptr, VAL_SIZE); + free(content.dptr); + + return 0; +} + +int __restriction_mode_set(uid_t uid, const char *pkgid, int mode) +{ + GDBM_FILE dbf; + char *dbpath; + int cur = 0; + + if (pkgid == NULL || !strcmp(pkgid, "")) + pkgid = ALL_PKG; + + dbpath = __get_dbpath(uid); + if (dbpath == NULL) + return -1; + + dbf = __open(dbpath, true); + if (dbf == NULL) { + free(dbpath); return -1; } + __get_value(dbf, pkgid, &cur); mode = __set_mode(cur, mode); - lseek(fd, 0, SEEK_SET); - len = write(fd, &mode, sizeof(int)); - if (len < 0) { - ERR("failed to write conf file: %d", errno); - close(fd); - free(conf_path); + if (__set_value(dbf, pkgid, mode)) { + free(dbpath); return -1; } - close(fd); - free(conf_path); + __close(dbf); + free(dbpath); return 0; } -int __unset_restriction_mode(uid_t uid, int mode) +int __restriction_mode_unset(uid_t uid, const char *pkgid, int mode) { - char *conf_path; - int fd; + GDBM_FILE dbf; + char *dbpath; int cur = 0; - ssize_t len; - conf_path = _get_conf_file_path(uid); - if (conf_path == NULL) { - ERR("failed to get conf path"); - return -1; - } + if (pkgid == NULL || !strcmp(pkgid, "")) + pkgid = ALL_PKG; - if (access(conf_path, F_OK) != 0) { - ERR("restriction mode is not set"); - free(conf_path); - return 0; - } - - fd = open(conf_path, O_RDWR, 0); - if (fd < 0) { - ERR("failed to open conf file: %s", errno); - free(conf_path); + dbpath = __get_dbpath(uid); + if (dbpath == NULL) return -1; - } - len = read(fd, &cur, sizeof(int)); - if (len < 0) { - ERR("failed to read conf file: %d", errno); - close(fd); - free(conf_path); + dbf = __open(dbpath, true); + if (dbf == NULL) { + free(dbpath); return -1; } + __get_value(dbf, pkgid, &cur); mode = __unset_mode(cur, mode); - lseek(fd, 0, SEEK_SET); - len = write(fd, &mode, sizeof(int)); - if (len < 0) { - ERR("failed to write conf file: %d", errno); - close(fd); - free(conf_path); + if (__set_value(dbf, pkgid, mode)) { + free(dbpath); return -1; } - close(fd); - free(conf_path); + __close(dbf); + free(dbpath); return 0; } -int __get_restriction_mode(uid_t uid, int *result) +int __restriction_mode_get(uid_t uid, const char *pkgid, int *mode) { - char *conf_path; - int fd; - int cur; - ssize_t len; + GDBM_FILE dbf; + char *dbpath; - conf_path = _get_conf_file_path(uid); - if (conf_path == NULL) - return -1; - - if (access(conf_path, F_OK) != 0) { - free(conf_path); - *result = 0; - return 0; - } + if (pkgid == NULL || !strcmp(pkgid, "")) + pkgid = ALL_PKG; - fd = open(conf_path, O_RDONLY, 0); - if (fd < 0) { - ERR("failed to open conf file: %s", errno); - free(conf_path); + dbpath = __get_dbpath(uid); + if (dbpath == NULL) return -1; - } - len = read(fd, &cur, sizeof(int)); - if (len < 0) { - ERR("failed to read conf file: %d", errno); - close(fd); - free(conf_path); + dbf = __open(dbpath, false); + if (dbf == NULL) { + if (gdbm_errno == GDBM_FILE_OPEN_ERROR) { + *mode = 0; + return 0; + } + free(dbpath); return -1; } - *result = cur; + if (__get_value(dbf, pkgid, mode)) { + free(dbpath); + } - close(fd); - free(conf_path); + __close(dbf); + free(dbpath); return 0; } -- 2.7.4 From ce32097d814aa00e110ea4ac161c2a8337efd2c5 Mon Sep 17 00:00:00 2001 From: Sangyoon Jang Date: Thu, 19 May 2016 19:08:24 +0900 Subject: [PATCH 03/16] Fix checking caller permission Skip checking when caller is system user. Change-Id: I93bc80dd744805b9ccb4ab860426f38fd592dfd7 Signed-off-by: Sangyoon Jang --- src/request.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/request.c b/src/request.c index ba99bf0..e4dda11 100644 --- a/src/request.c +++ b/src/request.c @@ -217,6 +217,7 @@ static int __is_admin_user(uid_t uid) return 1; } +#define REGULAR_USER 5000 static int __check_caller_permission(uid_t uid, GDBusMethodInvocation *invocation, GVariant *parameters) { @@ -224,6 +225,9 @@ static int __check_caller_permission(uid_t uid, uid_t target_uid; int is_admin; + if (uid < REGULAR_USER) + return 0; + v = g_variant_get_child_value(parameters, 0); if (v == NULL) { g_dbus_method_invocation_return_error_literal(invocation, -- 2.7.4 From 4e4aa023d3d21d2cb690f514981b2a5932e1f9e0 Mon Sep 17 00:00:00 2001 From: jongmyeongko Date: Fri, 27 May 2016 19:43:53 +0900 Subject: [PATCH 04/16] fix clear data behavior Change-Id: I272de791ac3973e3ca9530f0dba1855aeda75474 Signed-off-by: jongmyeongko --- src/request.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/request.c b/src/request.c index e4dda11..58987d9 100644 --- a/src/request.c +++ b/src/request.c @@ -779,6 +779,7 @@ static int __handle_request_cleardata(uid_t uid, uid_t target_uid = (uid_t)-1; char *pkgtype = NULL; char *pkgid = NULL; + char *reqkey = NULL; g_variant_get(parameters, "(u&s&s)", &target_uid, &pkgtype, &pkgid); if (target_uid == (uid_t)-1 || pkgtype == NULL || pkgid == NULL) { @@ -787,7 +788,11 @@ static int __handle_request_cleardata(uid_t uid, return -1; } - if (_pm_queue_push(target_uid, "", PKGMGR_REQUEST_TYPE_CLEARDATA, "pkgtool", + reqkey = __generate_reqkey(pkgid); + if (reqkey == NULL) + return -1; + + if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_CLEARDATA, pkgtype, pkgid, "")) { g_dbus_method_invocation_return_value(invocation, g_variant_new("(i)", PKGMGR_R_ESYSTEM)); @@ -797,6 +802,8 @@ static int __handle_request_cleardata(uid_t uid, g_dbus_method_invocation_return_value(invocation, g_variant_new("(i)", PKGMGR_R_OK)); + free(reqkey); + return 0; } -- 2.7.4 From f63165aae9c188c75165942945fc12032df15217 Mon Sep 17 00:00:00 2001 From: Sangyoon Jang Date: Tue, 31 May 2016 16:26:32 +0900 Subject: [PATCH 05/16] Make pkg_type to lower case when queuing Change-Id: Ia063dd2d1f8d68352ca11f0db1518476b185536f Signed-off-by: Sangyoon Jang --- src/pm-queue.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/pm-queue.c b/src/pm-queue.c index 5131015..53aa25c 100644 --- a/src/pm-queue.c +++ b/src/pm-queue.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "pkgmgr-server.h" #include "pm-queue.h" @@ -258,18 +259,31 @@ int _pm_queue_init(void) return 0; } +static void __convert_to_lower_case(char *dst, const char *src) +{ + int i; + + for (i = 0; src[i] != '\0'; i++) + dst[i] = tolower(src[i]); + dst[i] = '\0'; +} + int _pm_queue_push(uid_t uid, const char *req_id, int req_type, const char *queue_type, const char *pkgid, const char *args) { pm_queue_data *data = NULL; pm_queue_data *cur = NULL; pm_queue_data *tmp = NULL; - int ret = 0; - ret = __is_pkg_supported(queue_type); + char type[MAX_PKG_NAME_LEN]; + int ret; + + __convert_to_lower_case(type, queue_type); + + ret = __is_pkg_supported(type); if (ret == 0) return -1; - cur = __get_head_from_pkgtype(queue_type); + cur = __get_head_from_pkgtype(type); tmp = cur; /* TODO: use glist */ @@ -282,7 +296,7 @@ int _pm_queue_push(uid_t uid, const char *req_id, int req_type, snprintf(data->msg->req_id, sizeof(data->msg->req_id), "%s", req_id); data->msg->req_type = req_type; data->msg->uid = uid; - snprintf(data->msg->pkg_type, sizeof(data->msg->pkg_type), "%s", queue_type); + snprintf(data->msg->pkg_type, sizeof(data->msg->pkg_type), "%s", type); snprintf(data->msg->pkgid, sizeof(data->msg->pkgid), "%s", pkgid); snprintf(data->msg->args, sizeof(data->msg->args), "%s", args); -- 2.7.4 From 6c44f638ca37cb7028851edea69d185ea3830767 Mon Sep 17 00:00:00 2001 From: jongmyeongko Date: Tue, 31 May 2016 17:11:04 +0900 Subject: [PATCH 06/16] set groups for the access of external storage. Change-Id: Id15871fc965d241616d06efce1990d67e723e814 Signed-off-by: jongmyeongko --- src/pkgmgr-server.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/pkgmgr-server.c b/src/pkgmgr-server.c index 58f79f0..dadac26 100644 --- a/src/pkgmgr-server.c +++ b/src/pkgmgr-server.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -53,6 +54,10 @@ #define OWNER_ROOT 0 #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER) +#define EXT_STORAGE_GROUP 10001 +#define EXT_STORAGE_APPDATA_GROUP 10002 +#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0])) + typedef struct { char **env; uid_t uid; @@ -631,12 +636,18 @@ int set_environement(user_ctx *ctx) int i = 0; int res = 0; char **env = NULL; + gid_t groups[] = {EXT_STORAGE_GROUP, EXT_STORAGE_APPDATA_GROUP}; + if (!ctx) return -1;; if (setgid(ctx->gid)) { ERR("setgid failed: %d", errno); return -1; } + if (setgroups(ARRAY_SIZE(groups), groups) < 0) { + ERR("setgroups failed: %d", errno); + return -1; + } if (setuid(ctx->uid)) { ERR("setuid failed: %d", errno); return -1; -- 2.7.4 From d91941074f60e1c9de528ab387c23a66c0d8114d Mon Sep 17 00:00:00 2001 From: jongmyeongko Date: Tue, 31 May 2016 11:13:04 +0900 Subject: [PATCH 07/16] Remove old recovery behavior. Instead, new operation is necessory. The app-installer makes recovery file. But, there is no trigger operation to do \ a recovery using this file, actually. So, we should implement this trigger operation in somewhere. Change-Id: If91207538c8447d0c968b9506cc161fba7d2f0b7 Signed-off-by: jongmyeongko --- CMakeLists.txt | 1 - include/pm-queue.h | 4 -- packaging/pkgmgr-server.spec | 1 - queue_status | 1 - src/pkgmgr-server.c | 140 ------------------------------------------- src/pm-queue.c | 18 ------ 6 files changed, 165 deletions(-) delete mode 100644 queue_status diff --git a/CMakeLists.txt b/CMakeLists.txt index 9b8829e..77121f2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,6 +50,5 @@ CONFIGURE_FILE(org.tizen.pkgmgr.service.in org.tizen.pkgmgr.service @ONLY) CONFIGURE_FILE(org.tizen.pkgmgr.conf.in org.tizen.pkgmgr.conf @ONLY) INSTALL(TARGETS ${PKGMGR_SERVER} DESTINATION bin) -INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/queue_status DESTINATION ${SYSCONF_INSTALL_DIR}/package-manager/server/) INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.tizen.pkgmgr.service DESTINATION ${PREFIX}/share/dbus-1/system-services/) INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.tizen.pkgmgr.conf DESTINATION ${SYSCONF_INSTALL_DIR}/dbus-1/system.d/) diff --git a/include/pm-queue.h b/include/pm-queue.h index 046edb9..eca0ce3 100644 --- a/include/pm-queue.h +++ b/include/pm-queue.h @@ -29,9 +29,6 @@ #include "pkgmgr-server.h" -#define STATUS_FILE "/etc/package-manager/server/queue_status" -/* #define STATUS_FILE "./queue_status" */ - typedef struct _pm_queue_data { pm_dbus_msg *msg; struct _pm_queue_data *next; @@ -54,7 +51,6 @@ pm_dbus_msg *_pm_queue_pop(int position); void _pm_queue_final(); void _pm_queue_delete(pm_dbus_msg *item); pm_queue_data *_add_node(); -void _save_queue_status(pm_dbus_msg *item, char *status); void _print_queue(int position); #endif /* _PM_QUEUE_H_ */ diff --git a/packaging/pkgmgr-server.spec b/packaging/pkgmgr-server.spec index 4ea86ec..54164b7 100644 --- a/packaging/pkgmgr-server.spec +++ b/packaging/pkgmgr-server.spec @@ -64,5 +64,4 @@ mkdir -p %{buildroot}%{_sysconfdir}/package-manager/server %config %{_sysconfdir}/dbus-1/system.d/org.tizen.pkgmgr.conf %{_bindir}/pkgmgr-server %{_sysconfdir}/package-manager/server -%exclude %{_sysconfdir}/package-manager/server/queue_status /usr/share/license/%{name} diff --git a/queue_status b/queue_status deleted file mode 100644 index 5baa80c..0000000 --- a/queue_status +++ /dev/null @@ -1 +0,0 @@ -This file is for creating required directory. diff --git a/src/pkgmgr-server.c b/src/pkgmgr-server.c index dadac26..12ac2db 100644 --- a/src/pkgmgr-server.c +++ b/src/pkgmgr-server.c @@ -123,90 +123,6 @@ static void __set_backend_free(int position) backend_busy = backend_busy & ~(1<uid, ptr->pkgid, ptr->pkgtype); if (WIFSIGNALED(info.status) || WEXITSTATUS(info.status)) { send_fail_signal(ptr->pkgid, ptr->pkgtype, ptr->args); DBG("backend[%s] exit with error", ptr->pkgtype); @@ -1396,27 +1311,22 @@ gboolean queue_job(void *data) switch (item->req_type) { case PKGMGR_REQUEST_TYPE_INSTALL: __set_backend_busy(x); - __set_recovery_mode(item->uid, item->pkgid, item->pkg_type); ret = __process_install(item); break; case PKGMGR_REQUEST_TYPE_MOUNT_INSTALL: __set_backend_busy(x); - __set_recovery_mode(item->uid, item->pkgid, item->pkg_type); ret = __process_mount_install(item); break; case PKGMGR_REQUEST_TYPE_REINSTALL: __set_backend_busy(x); - __set_recovery_mode(item->uid, item->pkgid, item->pkg_type); ret = __process_reinstall(item); break; case PKGMGR_REQUEST_TYPE_UNINSTALL: __set_backend_busy(x); - __set_recovery_mode(item->uid, item->pkgid, item->pkg_type); ret = __process_uninstall(item); break; case PKGMGR_REQUEST_TYPE_MOVE: __set_backend_busy(x); - __set_recovery_mode(item->uid, item->pkgid, item->pkg_type); ret = __process_move(item); break; case PKGMGR_REQUEST_TYPE_ENABLE_PKG: @@ -1565,60 +1475,10 @@ char *_get_backend_cmd(char *type) int main(int argc, char *argv[]) { - FILE *fp_status = NULL; - char buf[32] = { 0, }; - pid_t pid; - char *backend_cmd = NULL; - char *backend_name = NULL; int r; DBG("server start"); - if (argv[1] && (strcmp(argv[1], "init") == 0)) { - /* if current status is "processing", - execute related backend with '-r' option */ - if (!(fp_status = fopen(STATUS_FILE, "r"))) - return 0; /*if file is not exist, terminated. */ - /* if processing <-- unintended termination */ - if (fgets(buf, 32, fp_status) && - strcmp(buf, "processing") == 0) { - pid = fork(); - if (pid == 0) { /* child */ - if (fgets(buf, 32, fp_status)) - backend_cmd = _get_backend_cmd(buf); - if (!backend_cmd) { /* if NULL, */ - DBG("fail to get backend command"); - goto err; - } - backend_name = - strrchr(backend_cmd, '/'); - if (!backend_name) { - DBG("fail to get backend name"); - goto err; - } - - execl(backend_cmd, backend_name, "-r", - NULL); - if (backend_cmd) - free(backend_cmd); - fprintf(fp_status, " "); -err: - fclose(fp_status); - exit(13); - } else if (pid < 0) { /* error */ - DBG("fork fail"); - fclose(fp_status); - return 0; - } else { /* parent */ - - DBG("parent end\n"); - fprintf(fp_status, " "); - fclose(fp_status); - return 0; - } - } - } - r = _pm_queue_init(); if (r) { DBG("Queue Initialization Failed\n"); diff --git a/src/pm-queue.c b/src/pm-queue.c index 53aa25c..496fdbb 100644 --- a/src/pm-queue.c +++ b/src/pm-queue.c @@ -481,24 +481,6 @@ void _pm_queue_delete(pm_dbus_msg *item) } } -void _save_queue_status(pm_dbus_msg *item, char *status) -{ - FILE *fp_status = NULL; - - fp_status = fopen(STATUS_FILE, "w"); /* overwrite always */ - if (!fp_status) { - ERR("Can't open status file:%s", STATUS_FILE); - return; - } - - fprintf(fp_status, "%s\n", status); - fprintf(fp_status, "%s\n", item->pkg_type); - - fsync(fileno(fp_status)); - - fclose(fp_status); -} - void _print_queue(int position) { pm_queue_data *cur = NULL; -- 2.7.4 From 7f824c8bd1f8ecd721a9a8de303dd67bb6a2817e Mon Sep 17 00:00:00 2001 From: Junghyun Yeon Date: Thu, 9 Jun 2016 11:23:31 +0900 Subject: [PATCH 08/16] Change move function to return req_key for signal changed should be applied with slp-pkgmgr https://review.tizen.org/gerrit/#/c/73621/ Change-Id: I2972c3aef5168773aa3bf329566dbe313f717a6f Signed-off-by: Junghyun Yeon --- src/request.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/request.c b/src/request.c index 58987d9..c59a550 100644 --- a/src/request.c +++ b/src/request.c @@ -53,6 +53,7 @@ static const char instropection_xml[] = " " " " " " + " " " " " " " " @@ -495,7 +496,7 @@ static int __handle_request_move(uid_t uid, g_variant_get(parameters, "(u&s&si)", &target_uid, &pkgtype, &pkgid, &move_type); if (target_uid == (uid_t)-1 || pkgtype == NULL || pkgid == NULL) { g_dbus_method_invocation_return_value(invocation, - g_variant_new("(i)", PKGMGR_R_ECOMM)); + g_variant_new("(is)", PKGMGR_R_ECOMM, "")); return -1; } @@ -507,13 +508,13 @@ static int __handle_request_move(uid_t uid, if (_pm_queue_push(target_uid, reqkey, PKGMGR_REQUEST_TYPE_MOVE, pkgtype, pkgid, buf)) { g_dbus_method_invocation_return_value(invocation, - g_variant_new("(i)", PKGMGR_R_ESYSTEM)); + g_variant_new("(is)", PKGMGR_R_ESYSTEM, "")); free(reqkey); return -1; } g_dbus_method_invocation_return_value(invocation, - g_variant_new("(i)", PKGMGR_R_OK)); + g_variant_new("(is)", PKGMGR_R_OK, reqkey)); free(reqkey); return 0; -- 2.7.4 From d77188c33b3f99c8750b403080e88c9059843bc4 Mon Sep 17 00:00:00 2001 From: Sangyoon Jang Date: Thu, 9 Jun 2016 19:26:13 +0900 Subject: [PATCH 09/16] Remove unnecessary build dependency libsmack is not used. Change-Id: I664e9c7798f438868818d1a7f364e023f5c662da Signed-off-by: Sangyoon Jang --- packaging/pkgmgr-server.spec | 1 - 1 file changed, 1 deletion(-) diff --git a/packaging/pkgmgr-server.spec b/packaging/pkgmgr-server.spec index 54164b7..b1b6201 100644 --- a/packaging/pkgmgr-server.spec +++ b/packaging/pkgmgr-server.spec @@ -20,7 +20,6 @@ BuildRequires: pkgconfig(libtzplatform-config) BuildRequires: pkgconfig(security-manager) BuildRequires: pkgconfig(xdgmime) BuildRequires: pkgconfig(db-util) -BuildRequires: pkgconfig(libsmack) BuildRequires: pkgconfig(pkgmgr) BuildRequires: pkgconfig(pkgmgr-installer) BuildRequires: pkgconfig(drm-service-core-tizen) -- 2.7.4 From cc8e03e59bc3bcb438d2df08aacc888761f36be7 Mon Sep 17 00:00:00 2001 From: Sangyoon Jang Date: Fri, 10 Jun 2016 16:01:50 +0900 Subject: [PATCH 10/16] Remove a meaningless error log Change-Id: Iabe8d37b23a36b360ee261978b8cfcb80cc635c8 Signed-off-by: Sangyoon Jang --- src/pm-queue.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pm-queue.c b/src/pm-queue.c index 496fdbb..b644805 100644 --- a/src/pm-queue.c +++ b/src/pm-queue.c @@ -405,7 +405,6 @@ void _pm_queue_final() c = 0; while(c < num_of_backends) { if (!head[c]) { /* in case of head is NULL */ - ERR("queue is NULL"); c = c + 1; continue; } -- 2.7.4 From d4f61848465c8f6fb7d7b5230b334b3ccaec7ec2 Mon Sep 17 00:00:00 2001 From: Sangyoon Jang Date: Thu, 9 Jun 2016 19:16:44 +0900 Subject: [PATCH 11/16] Remove smack related capabilities Remove capabilities using systemd service. Change-Id: Ie8fc2a588744c62433455039f89eaf4a8c656bab Signed-off-by: Sangyoon Jang --- CMakeLists.txt | 2 ++ org.tizen.pkgmgr.service.in | 3 ++- package-manager.service.in | 7 +++++++ packaging/pkgmgr-server.spec | 3 ++- 4 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 package-manager.service.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 77121f2..5a14e57 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,7 +48,9 @@ TARGET_LINK_LIBRARIES(${PKGMGR_SERVER} ${SERVER_DEPS_LDFLAGS} -lgdbm) CONFIGURE_FILE(org.tizen.pkgmgr.service.in org.tizen.pkgmgr.service @ONLY) CONFIGURE_FILE(org.tizen.pkgmgr.conf.in org.tizen.pkgmgr.conf @ONLY) +CONFIGURE_FILE(package-manager.service.in package-manager.service @ONLY) INSTALL(TARGETS ${PKGMGR_SERVER} DESTINATION bin) INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.tizen.pkgmgr.service DESTINATION ${PREFIX}/share/dbus-1/system-services/) INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.tizen.pkgmgr.conf DESTINATION ${SYSCONF_INSTALL_DIR}/dbus-1/system.d/) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/package-manager.service DESTINATION ${UNITDIR}) diff --git a/org.tizen.pkgmgr.service.in b/org.tizen.pkgmgr.service.in index 38c9534..9252ca2 100644 --- a/org.tizen.pkgmgr.service.in +++ b/org.tizen.pkgmgr.service.in @@ -1,4 +1,5 @@ [D-BUS Service] User=root Name=org.tizen.pkgmgr -Exec=@PREFIX@/bin/pkgmgr-server +Exec=@PREFIX@/bin/false +SystemdService=package-manager.service diff --git a/package-manager.service.in b/package-manager.service.in new file mode 100644 index 0000000..79a03d4 --- /dev/null +++ b/package-manager.service.in @@ -0,0 +1,7 @@ +[Unit] +Description=Tizen Package Manager + +[Service] +ExecStart=@PREFIX@/bin/pkgmgr-server +CapabilityBoundingSet=~CAP_MAC_ADMIN +CapabilityBoundingSet=~CAP_MAC_OVERRIDE diff --git a/packaging/pkgmgr-server.spec b/packaging/pkgmgr-server.spec index b1b6201..7cd5191 100644 --- a/packaging/pkgmgr-server.spec +++ b/packaging/pkgmgr-server.spec @@ -40,7 +40,7 @@ cp %{SOURCE1001} . %define backend_dir %{_sysconfdir}/package-manager/backend %build -%cmake . -DRUN_DIR=%{run_dir} -DBACKEND_DIR=%{backend_dir} +%cmake . -DRUN_DIR=%{run_dir} -DBACKEND_DIR=%{backend_dir} -DUNITDIR=%{_unitdir} %__make %{?_smp_mflags} @@ -59,6 +59,7 @@ mkdir -p %{buildroot}%{_sysconfdir}/package-manager/server %files %manifest %{name}.manifest %defattr(-,root,root,-) +%{_unitdir}/package-manager.service %{_datadir}/dbus-1/system-services/org.tizen.pkgmgr.service %config %{_sysconfdir}/dbus-1/system.d/org.tizen.pkgmgr.conf %{_bindir}/pkgmgr-server -- 2.7.4 From ce682876298c0afe2fadd02e06da2aad9b7ce522 Mon Sep 17 00:00:00 2001 From: Sangyoon Jang Date: Mon, 13 Jun 2016 10:49:12 +0900 Subject: [PATCH 12/16] Fix double free Change-Id: I0e80906fe6289bebd0e44b5395b291a49da1dd2b Signed-off-by: Sangyoon Jang --- src/restriction_mode.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/restriction_mode.c b/src/restriction_mode.c index c7ee92c..c6648c5 100644 --- a/src/restriction_mode.c +++ b/src/restriction_mode.c @@ -185,9 +185,8 @@ int __restriction_mode_get(uid_t uid, const char *pkgid, int *mode) return -1; } - if (__get_value(dbf, pkgid, mode)) { - free(dbpath); - } + if (__get_value(dbf, pkgid, mode)) + *mode = 0; __close(dbf); free(dbpath); -- 2.7.4 From 93c209bab3b0f08c68f3f1c7dc6c6d63ba11e59a Mon Sep 17 00:00:00 2001 From: Junghyun Yeon Date: Mon, 13 Jun 2016 11:23:34 +0900 Subject: [PATCH 13/16] fix memory leak Change-Id: I6da3fbe7a0ec0965393f0d6c3fb0d6169e5ede43 Signed-off-by: Junghyun Yeon --- src/request.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/request.c b/src/request.c index c59a550..0e4d073 100644 --- a/src/request.c +++ b/src/request.c @@ -797,6 +797,7 @@ static int __handle_request_cleardata(uid_t uid, pkgid, "")) { g_dbus_method_invocation_return_value(invocation, g_variant_new("(i)", PKGMGR_R_ESYSTEM)); + free(reqkey); return -1; } -- 2.7.4 From 7216e7417179ff8a3f6643e1277a9f03b3ed7298 Mon Sep 17 00:00:00 2001 From: jongmyeongko Date: Fri, 10 Jun 2016 16:01:13 +0900 Subject: [PATCH 14/16] set label to prevent execution by non-system application. Change-Id: Ibb12282ca5d48435f70a332e40f650faa911832c Signed-off-by: jongmyeongko --- packaging/pkgmgr-server.manifest | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packaging/pkgmgr-server.manifest b/packaging/pkgmgr-server.manifest index a76fdba..46733b6 100644 --- a/packaging/pkgmgr-server.manifest +++ b/packaging/pkgmgr-server.manifest @@ -2,4 +2,7 @@ + + + -- 2.7.4 From ae0042b9855c391ac45d1e46eda59e11a3a39366 Mon Sep 17 00:00:00 2001 From: Sangyoon Jang Date: Wed, 15 Jun 2016 13:24:16 +0900 Subject: [PATCH 15/16] Fix restriction mode - Entire restriction mode -> store at run directory(volatile) - Package restriction mode -> store at package-manager db(non-volatile) Change-Id: Ibb764a1ecfcd843cdf039bc3f85efcfc3f920fd2 Signed-off-by: Sangyoon Jang --- CMakeLists.txt | 3 +- include/pkgmgr-server.h | 6 +- packaging/pkgmgr-server.manifest | 2 + packaging/pkgmgr-server.spec | 13 +- restriction.sql | 8 + src/pkgmgr-server.c | 6 +- src/restriction_mode.c | 331 +++++++++++++++++++++++++++------------ 7 files changed, 256 insertions(+), 113 deletions(-) create mode 100644 restriction.sql diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a14e57..ed35f4d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,6 +36,7 @@ pkg_check_modules(SERVER_DEPS REQUIRED libtzplatform-config drm-service-core-tizen libgum + sqlite3 pkgmgr pkgmgr-installer) FOREACH(SERVER_FLAGS ${SERVER_DEPS_CFLAGS}) @@ -44,7 +45,7 @@ ENDFOREACH(SERVER_FLAGS) ADD_EXECUTABLE(${PKGMGR_SERVER} ${SRCS}) TARGET_LINK_LIBRARIES(${PKGMGR_SERVER} pkgmgr_installer) -TARGET_LINK_LIBRARIES(${PKGMGR_SERVER} ${SERVER_DEPS_LDFLAGS} -lgdbm) +TARGET_LINK_LIBRARIES(${PKGMGR_SERVER} ${SERVER_DEPS_LDFLAGS}) CONFIGURE_FILE(org.tizen.pkgmgr.service.in org.tizen.pkgmgr.service @ONLY) CONFIGURE_FILE(org.tizen.pkgmgr.conf.in org.tizen.pkgmgr.conf @ONLY) diff --git a/include/pkgmgr-server.h b/include/pkgmgr-server.h index 8a49751..b30eb65 100644 --- a/include/pkgmgr-server.h +++ b/include/pkgmgr-server.h @@ -107,8 +107,8 @@ gboolean queue_job(void *data); int __return_value_to_caller(const char *req_key, GVariant *result); int __init_request_handler(void); void __fini_request_handler(void); -int __restriction_mode_set(uid_t uid, const char *pkgid, int mode); -int __restriction_mode_unset(uid_t uid, const char *pkgid, int mode); -int __restriction_mode_get(uid_t uid, const char *pkgid, int *mode); +int _restriction_mode_set(uid_t uid, const char *pkgid, int mode); +int _restriction_mode_unset(uid_t uid, const char *pkgid, int mode); +int _restriction_mode_get(uid_t uid, const char *pkgid, int *mode); #endif/* _PKGMGR_SERVER_H_ */ diff --git a/packaging/pkgmgr-server.manifest b/packaging/pkgmgr-server.manifest index 46733b6..fee7117 100644 --- a/packaging/pkgmgr-server.manifest +++ b/packaging/pkgmgr-server.manifest @@ -4,5 +4,7 @@ + + diff --git a/packaging/pkgmgr-server.spec b/packaging/pkgmgr-server.spec index 7cd5191..161059c 100644 --- a/packaging/pkgmgr-server.spec +++ b/packaging/pkgmgr-server.spec @@ -24,7 +24,7 @@ BuildRequires: pkgconfig(pkgmgr) BuildRequires: pkgconfig(pkgmgr-installer) BuildRequires: pkgconfig(drm-service-core-tizen) BuildRequires: pkgconfig(libgum) -BuildRequires: gdbm-devel +BuildRequires: pkgconfig(sqlite3) BuildRequires: pkgmgr-info-parser-devel BuildRequires: pkgmgr-info-parser BuildRequires: fdupes @@ -37,10 +37,16 @@ Packager Manager server package for packaging cp %{SOURCE1001} . %define run_dir /run/user +%define db_dir %{_localstatedir}/lib/package-manager %define backend_dir %{_sysconfdir}/package-manager/backend %build -%cmake . -DRUN_DIR=%{run_dir} -DBACKEND_DIR=%{backend_dir} -DUNITDIR=%{_unitdir} +sqlite3 restriction.db < ./restriction.sql + +%cmake . -DRUN_DIR=%{run_dir} \ + -DDB_DIR=%{db_dir} \ + -DBACKEND_DIR=%{backend_dir} \ + -DUNITDIR=%{_unitdir} %__make %{?_smp_mflags} @@ -50,6 +56,8 @@ cp %{SOURCE1001} . mkdir -p %{buildroot}/usr/share/license cp LICENSE %{buildroot}/usr/share/license/%{name} mkdir -p %{buildroot}%{_sysconfdir}/package-manager/server +mkdir -p %{buildroot}%{db_dir} +install -m 0600 restriction.db %{buildroot}%{db_dir} %fdupes %{buildroot} @@ -62,6 +70,7 @@ mkdir -p %{buildroot}%{_sysconfdir}/package-manager/server %{_unitdir}/package-manager.service %{_datadir}/dbus-1/system-services/org.tizen.pkgmgr.service %config %{_sysconfdir}/dbus-1/system.d/org.tizen.pkgmgr.conf +%config(noreplace) %{db_dir}/restriction.db %{_bindir}/pkgmgr-server %{_sysconfdir}/package-manager/server /usr/share/license/%{name} diff --git a/restriction.sql b/restriction.sql new file mode 100644 index 0000000..9fa3e8d --- /dev/null +++ b/restriction.sql @@ -0,0 +1,8 @@ +PRAGMA journal_mode = WAL; + +CREATE TABLE restriction ( + uid INTEGER NOT NULL, + pkgid TEXT NOT NULL, + mode INTEGER NOT NULL, + UNIQUE (uid, pkgid) +); diff --git a/src/pkgmgr-server.c b/src/pkgmgr-server.c index 12ac2db..91b19b1 100644 --- a/src/pkgmgr-server.c +++ b/src/pkgmgr-server.c @@ -1243,7 +1243,7 @@ static int __process_set_restriction_mode(pm_dbus_msg *item) int mode; mode = atoi(item->args); - ret = __restriction_mode_set(item->uid, item->pkgid, mode); + ret = _restriction_mode_set(item->uid, item->pkgid, mode); __return_value_to_caller(item->req_id, g_variant_new("(i)", ret)); @@ -1257,7 +1257,7 @@ static int __process_unset_restriction_mode(pm_dbus_msg *item) int mode; mode = atoi(item->args); - ret = __restriction_mode_unset(item->uid, item->pkgid, mode); + ret = _restriction_mode_unset(item->uid, item->pkgid, mode); __return_value_to_caller(item->req_id, g_variant_new("(i)", ret)); @@ -1270,7 +1270,7 @@ static int __process_get_restriction_mode(pm_dbus_msg *item) int ret; int mode = -1; - ret = __restriction_mode_get(item->uid, item->pkgid, &mode); + ret = _restriction_mode_get(item->uid, item->pkgid, &mode); __return_value_to_caller(item->req_id, g_variant_new("(ii)", mode, ret)); diff --git a/src/restriction_mode.c b/src/restriction_mode.c index c6648c5..376d4f9 100644 --- a/src/restriction_mode.c +++ b/src/restriction_mode.c @@ -1,30 +1,25 @@ #include -#include #include #include +#include #include +#include #include +#include #include -#include +#include #include "pkgmgr-server.h" #ifndef RUN_DIR #define RUN_DIR "/run/user" #endif -#define RESTRICTION_DB ".package_manager_restriction_mode" -#define VAL_SIZE sizeof(int) -#define ALL_PKG "ALL_PKG" - -static char *__get_dbpath(uid_t uid) -{ - char buf[PATH_MAX]; - - snprintf(buf, sizeof(buf), "%s/%d/%s", RUN_DIR, uid, RESTRICTION_DB); - - return strdup(buf); -} +#ifndef DB_DIR +#define DB_DIR "/var/lib/package-manager" +#endif +#define RESTRICTION_CONF ".package_manager_restriction_mode" +#define BUFSIZE 4096 static int __set_mode(int cur, int mode) { @@ -36,160 +31,288 @@ static int __unset_mode(int cur, int mode) return cur & ~(mode); } -static GDBM_FILE __open(const char *path, bool writable) +static char *__get_conf_file_path(uid_t uid) { - GDBM_FILE db; + char buf[PATH_MAX]; - db = gdbm_open((char *)path, 0, writable ? GDBM_WRCREAT : GDBM_READER, - S_IRUSR | S_IWUSR, NULL); - if (db == NULL) - ERR("failed to open gdbm file(%s): %d", path, gdbm_errno); + snprintf(buf, sizeof(buf), "%s/%d/%s", RUN_DIR, uid, RESTRICTION_CONF); - return db; + return strdup(buf); } -static void __close(GDBM_FILE dbf) +static int __set_restriction_mode(uid_t uid, int mode) { - gdbm_close(dbf); -} + char *conf_path; + int fd; + int cur = 0; + ssize_t len; -static int __set_value(GDBM_FILE dbf, const char *pkgid, int mode) -{ - datum key; - datum content; - char buf[VAL_SIZE]; + conf_path = __get_conf_file_path(uid); + if (conf_path == NULL) { + ERR("failed to get conf path"); + return -1; + } - key.dptr = (char *)pkgid; - key.dsize = strlen(pkgid) + 1; + fd = open(conf_path, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); + if (fd < 0) { + ERR("failed to open conf file: %d", errno); + free(conf_path); + return -1; + } - memcpy(buf, &mode, VAL_SIZE); - content.dptr = buf; - content.dsize = VAL_SIZE; + len = read(fd, &cur, sizeof(int)); + if (len < 0) { + ERR("failed to read conf file: %d", errno); + close(fd); + free(conf_path); + return -1; + } - if (gdbm_store(dbf, key, content, GDBM_REPLACE)) { - ERR("failed to store value"); + mode = __set_mode(cur, mode); + + lseek(fd, 0, SEEK_SET); + len = write(fd, &mode, sizeof(int)); + if (len < 0) { + ERR("failed to write conf file: %d", errno); + close(fd); + free(conf_path); return -1; } + close(fd); + free(conf_path); + return 0; } -static int __get_value(GDBM_FILE dbf, const char *pkgid, int *mode) +static int __unset_restriction_mode(uid_t uid, int mode) { - datum key; - datum content; + char *conf_path; + int fd; + int cur = 0; + ssize_t len; + + conf_path = __get_conf_file_path(uid); + if (conf_path == NULL) { + ERR("failed to get conf path"); + return -1; + } - key.dptr = (char *)pkgid; - key.dsize = strlen(pkgid) + 1; + if (access(conf_path, F_OK) != 0) { + free(conf_path); + return 0; + } - content = gdbm_fetch(dbf, key); - if (content.dptr == NULL) { - DBG("no value for key(%s)", pkgid); + fd = open(conf_path, O_RDWR, 0); + if (fd < 0) { + ERR("failed to open conf file: %s", errno); + free(conf_path); return -1; } - if (content.dsize != VAL_SIZE) - ERR("content size is different"); + len = read(fd, &cur, sizeof(int)); + if (len < 0) { + ERR("failed to read conf file: %d", errno); + close(fd); + free(conf_path); + return -1; + } - memcpy(mode, content.dptr, VAL_SIZE); - free(content.dptr); + mode = __unset_mode(cur, mode); + + lseek(fd, 0, SEEK_SET); + len = write(fd, &mode, sizeof(int)); + if (len < 0) { + ERR("failed to write conf file: %d", errno); + close(fd); + free(conf_path); + return -1; + } + + close(fd); + free(conf_path); return 0; } -int __restriction_mode_set(uid_t uid, const char *pkgid, int mode) +static int __get_restriction_mode(uid_t uid, int *mode) { - GDBM_FILE dbf; - char *dbpath; - int cur = 0; + char *conf_path; + int fd; + int cur; + ssize_t len; - if (pkgid == NULL || !strcmp(pkgid, "")) - pkgid = ALL_PKG; - - dbpath = __get_dbpath(uid); - if (dbpath == NULL) + conf_path = __get_conf_file_path(uid); + if (conf_path == NULL) return -1; - dbf = __open(dbpath, true); - if (dbf == NULL) { - free(dbpath); - return -1; + if (access(conf_path, F_OK) != 0) { + free(conf_path); + *mode = 0; + return 0; } - __get_value(dbf, pkgid, &cur); - mode = __set_mode(cur, mode); + fd = open(conf_path, O_RDONLY, 0); + if (fd < 0) { + ERR("failed to open conf file: %s", errno); + free(conf_path); + return -1; + } - if (__set_value(dbf, pkgid, mode)) { - free(dbpath); + len = read(fd, &cur, sizeof(int)); + if (len < 0) { + ERR("failed to read conf file: %d", errno); + close(fd); + free(conf_path); return -1; } - __close(dbf); - free(dbpath); + *mode = cur; + + close(fd); + free(conf_path); return 0; } -int __restriction_mode_unset(uid_t uid, const char *pkgid, int mode) +static const char *__get_db_path(void) { - GDBM_FILE dbf; - char *dbpath; - int cur = 0; + return DB_DIR"/restriction.db"; +} - if (pkgid == NULL || !strcmp(pkgid, "")) - pkgid = ALL_PKG; +static sqlite3 *__open_db(void) +{ + int ret; + const char *path; + sqlite3 *db; + + path = __get_db_path(); + if (path == NULL) { + ERR("get db path error"); + return NULL; + } + + ret = sqlite3_open_v2(path, &db, SQLITE_OPEN_READWRITE, NULL); + if (ret != SQLITE_OK) { + ERR("open db error: %d", ret); + return NULL; + } - dbpath = __get_dbpath(uid); - if (dbpath == NULL) + return db; +} + +enum { + TYPE_SET, + TYPE_UNSET, +}; + +static int __update_pkg_restriction_mode(uid_t uid, const char *pkgid, int mode, + int type) +{ + static const char query[] = + "INSERT OR REPLACE INTO restriction (uid, pkgid, mode) " + "VALUES(?, ?, (COALESCE(" + " (SELECT mode FROM restriction WHERE uid=? AND pkgid=?), 0) "; + int ret; + sqlite3 *db; + sqlite3_stmt *stmt; + char buf[BUFSIZE]; + + db = __open_db(); + if (db == NULL) return -1; - dbf = __open(dbpath, true); - if (dbf == NULL) { - free(dbpath); + snprintf(buf, sizeof(buf), "%s%s", query, + type == TYPE_SET ? "| ?))" : "& ~?))"); + + ret = sqlite3_prepare_v2(db, buf, strlen(buf), &stmt, NULL); + if (ret != SQLITE_OK) { + ERR("prepare error: %s", sqlite3_errmsg(db)); + sqlite3_close_v2(db); return -1; } - __get_value(dbf, pkgid, &cur); - mode = __unset_mode(cur, mode); - - if (__set_value(dbf, pkgid, mode)) { - free(dbpath); + sqlite3_bind_int(stmt, 1, uid); + sqlite3_bind_text(stmt, 2, pkgid, -1, SQLITE_STATIC); + sqlite3_bind_int(stmt, 3, uid); + sqlite3_bind_text(stmt, 4, pkgid, -1, SQLITE_STATIC); + sqlite3_bind_int(stmt, 5, mode); + + ret = sqlite3_step(stmt); + sqlite3_finalize(stmt); + if (ret != SQLITE_DONE) { + ERR("step error: %s", sqlite3_errmsg(db)); + sqlite3_close_v2(db); return -1; } - __close(dbf); - free(dbpath); + sqlite3_close_v2(db); return 0; } -int __restriction_mode_get(uid_t uid, const char *pkgid, int *mode) +static int __get_pkg_restriction_mode(uid_t uid, const char *pkgid, int *mode) { - GDBM_FILE dbf; - char *dbpath; - - if (pkgid == NULL || !strcmp(pkgid, "")) - pkgid = ALL_PKG; + static const char query[] = + "SELECT COALESCE( " + " (SELECT mode FROM restriction WHERE uid=? AND pkgid=?), 0)"; + int ret; + sqlite3 *db; + sqlite3_stmt *stmt; + + db = __open_db(); + if (db == NULL) { + return -1; + } - dbpath = __get_dbpath(uid); - if (dbpath == NULL) + ret = sqlite3_prepare_v2(db, query, strlen(query), &stmt, NULL); + if (ret != SQLITE_OK) { + ERR("prepare error: %s", sqlite3_errmsg(db)); + sqlite3_close_v2(db); return -1; + } - dbf = __open(dbpath, false); - if (dbf == NULL) { - if (gdbm_errno == GDBM_FILE_OPEN_ERROR) { - *mode = 0; - return 0; - } - free(dbpath); + sqlite3_bind_int(stmt, 1, uid); + sqlite3_bind_text(stmt, 2, pkgid, -1, SQLITE_STATIC); + + ret = sqlite3_step(stmt); + if (ret != SQLITE_ROW) { + ERR("step error: %s", sqlite3_errmsg(db)); + sqlite3_finalize(stmt); + sqlite3_close_v2(db); return -1; } - if (__get_value(dbf, pkgid, mode)) - *mode = 0; + *mode = sqlite3_column_int(stmt, 0); - __close(dbf); - free(dbpath); + sqlite3_finalize(stmt); + sqlite3_close_v2(db); return 0; } + +int _restriction_mode_set(uid_t uid, const char *pkgid, int mode) +{ + if (pkgid && strlen(pkgid)) + return __update_pkg_restriction_mode(uid, pkgid, mode, + TYPE_SET); + else + return __set_restriction_mode(uid, mode); +} + +int _restriction_mode_unset(uid_t uid, const char *pkgid, int mode) +{ + if (pkgid && strlen(pkgid)) + return __update_pkg_restriction_mode(uid, pkgid, mode, + TYPE_UNSET); + else + return __unset_restriction_mode(uid, mode); +} + +int _restriction_mode_get(uid_t uid, const char *pkgid, int *mode) +{ + if (pkgid && strlen(pkgid)) + return __get_pkg_restriction_mode(uid, pkgid, mode); + else + return __get_restriction_mode(uid, mode); +} -- 2.7.4 From ae5f88f32deb444e2a17792a53899661e45e75b6 Mon Sep 17 00:00:00 2001 From: Junghyun Yeon Date: Thu, 16 Jun 2016 16:26:02 +0900 Subject: [PATCH 16/16] Initialize stat Change-Id: Ia771840d933b0ee48d147c8f91d6753baa89973f Signed-off-by: Junghyun Yeon --- src/pm-queue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pm-queue.c b/src/pm-queue.c index b644805..1022332 100644 --- a/src/pm-queue.c +++ b/src/pm-queue.c @@ -144,7 +144,7 @@ int _pm_queue_init(void) /*Find the num of backends currently supported and initialize that many queues. It is dynamically determined.*/ struct dirent **namelist; - struct stat fileinfo; + struct stat fileinfo = {0}; queue_info_map *ptr = NULL; int n = 0; int c = 0; -- 2.7.4