Implement restriction mode 38/66938/6
authorSangyoon Jang <s89.jang@samsung.com>
Fri, 22 Apr 2016 06:06:47 +0000 (15:06 +0900)
committerSangyoon Jang <s89.jang@samsung.com>
Wed, 4 May 2016 09:50:28 +0000 (02:50 -0700)
For setting restriction mode, pkgmgr-server will make a file at
/run/user/<uid>/

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 <s89.jang@samsung.com>
CMakeLists.txt
include/pkgmgr-server.h
org.tizen.pkgmgr.conf.in
packaging/pkgmgr-server.spec
src/pkgmgr-server.c
src/request.c
src/restriction_mode.c [new file with mode: 0644]

index 7d89a0b..917b6f3 100644 (file)
@@ -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
index 602e0fa..5faf134 100644 (file)
@@ -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_ */
index c3b0204..6aeb6f4 100644 (file)
@@ -27,5 +27,8 @@
                <check send_destination="org.tizen.pkgmgr" send_interface="org.tizen.pkgmgr" send_member="check_blacklist" privilege="http://tizen.org/privilege/packagemanager.admin"/>
                <check send_destination="org.tizen.pkgmgr" send_interface="org.tizen.pkgmgr" send_member="enable_app_splash_screen" privilege="http://tizen.org/privilege/packagemanager.admin"/>
                <check send_destination="org.tizen.pkgmgr" send_interface="org.tizen.pkgmgr" send_member="disable_app_splash_screen" privilege="http://tizen.org/privilege/packagemanager.admin"/>
+               <check send_destination="org.tizen.pkgmgr" send_interface="org.tizen.pkgmgr" send_member="set_restriction_mode" privilege="http://tizen.org/privilege/packagemanager.admin"/>
+               <check send_destination="org.tizen.pkgmgr" send_interface="org.tizen.pkgmgr" send_member="unset_restriction_mode" privilege="http://tizen.org/privilege/packagemanager.admin"/>
+               <check send_destination="org.tizen.pkgmgr" send_interface="org.tizen.pkgmgr" send_member="get_restriction_mode" privilege="http://tizen.org/privilege/packagemanager.admin"/>
         </policy>
 </busconfig>
index 7c9768d..5dd8633 100644 (file)
@@ -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
index 78ed2b3..ada3f99 100644 (file)
@@ -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;
index daf4d12..e2c6871 100644 (file)
@@ -159,6 +159,21 @@ static const char instropection_xml[] =
        "      <arg type='s' name='appid' direction='in'/>"
        "      <arg type='i' name='ret' direction='out'/>"
        "    </method>"
+       "    <method name='set_restriction_mode'>"
+       "      <arg type='u' name='uid' direction='in'/>"
+       "      <arg type='i' name='mode' direction='in'/>"
+       "      <arg type='i' name='ret' direction='out'/>"
+       "    </method>"
+       "    <method name='unset_restriction_mode'>"
+       "      <arg type='u' name='uid' direction='in'/>"
+       "      <arg type='i' name='mode' direction='in'/>"
+       "      <arg type='i' name='ret' direction='out'/>"
+       "    </method>"
+       "    <method name='get_restriction_mode'>"
+       "      <arg type='u' name='uid' direction='in'/>"
+       "      <arg type='i' name='result' direction='out'/>"
+       "      <arg type='i' name='ret' direction='out'/>"
+       "    </method>"
        "  </interface>"
        "</node>";
 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 (file)
index 0000000..50fe8d5
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <linux/limits.h>
+
+#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;
+}