Change policy storage to database 68/102068/2 accepted/tizen/3.0/common/20161206.125317 accepted/tizen/3.0/ivi/20161205.234436 accepted/tizen/3.0/mobile/20161205.234253 accepted/tizen/3.0/tv/20161205.234342 accepted/tizen/3.0/wearable/20161205.234408 submit/tizen_3.0/20161205.022357 submit/tizen_3.0/20161205.022817
authorJaemin Ryu <jm77.ryu@samsung.com>
Thu, 1 Dec 2016 02:03:26 +0000 (11:03 +0900)
committerJaemin Ryu <jm77.ryu@samsung.com>
Mon, 5 Dec 2016 02:01:19 +0000 (11:01 +0900)
Change-Id: Id0806d24321582acd954ecf7eed82d1829798692
Signed-off-by: Jaemin Ryu <jm77.ryu@samsung.com>
18 files changed:
server/CMakeLists.txt
server/administration.cpp
server/bluetooth.cpp
server/client-manager.cpp [deleted file]
server/client-manager.h
server/location.cpp
server/password.cpp
server/policy-builder.h
server/policy-manager.cpp
server/policy-manager.h
server/policy-storage.h [deleted file]
server/policy.cpp [deleted file]
server/policy.h [deleted file]
server/restriction.cpp
server/security.cpp
server/server.cpp
server/server.h
server/wifi.cpp

index 9a40a48..57cf478 100644 (file)
@@ -21,11 +21,8 @@ SET(FOUNDATION               main.cpp
                                        app-bundle.cpp
                                        launchpad.cpp
                                        packman.cpp
-                                       policy.cpp
                                        policy-builder.cpp
-                                       policy-storage.cpp
                                        policy-manager.cpp
-                                       client-manager.cpp
 )
 
 SET(POLICY                     administration.cpp
index 7f09d25..ba72bf1 100644 (file)
 
 #include "administration.hxx"
 
+namespace {
+const std::string repository = "/opt/dbspace/.dpm.db";
+}
+
 namespace DevicePolicyManager {
 
 AdministrationPolicy::AdministrationPolicy(PolicyControlContext& ctx) :
@@ -35,22 +39,26 @@ AdministrationPolicy::~AdministrationPolicy()
 
 int AdministrationPolicy::registerPolicyClient(const std::string& name, uid_t uid)
 {
+       int ret = -1;
        try {
-               return context.enroll(name, uid);
+               ret = context.getPolicyManager().prepareStorage(name, uid);
        } catch (runtime::Exception& e) {
-               ERROR("Failed to register policy client");
-               return -1;
+               ERROR("Failed to register admin client");
        }
+
+       return ret == 0 ? 0 : -1;
 }
 
 int AdministrationPolicy::deregisterPolicyClient(const std::string& name, uid_t uid)
 {
+       int ret = -1;
        try {
-               return context.disenroll(name, uid);
+               ret = context.getPolicyManager().removeStorage(name, uid);
        } catch (runtime::Exception& e) {
                ERROR("Failed to deregister policy client");
-               return -1;
        }
+
+       return ret == 0 ? 0 : -1;
 }
 
 DEFINE_POLICY(AdministrationPolicy);
index 8baa8e3..58cbcae 100644 (file)
@@ -92,23 +92,23 @@ void bluetoothAdapterStateChangedCallback(int result, bt_adapter_state_e state,
        BluetoothPolicyContext *bluetooth = (BluetoothPolicyContext *)user_data;
        PolicyControlContext &context = *bluetooth->context;
 
-       int ret = __setModeChangeState(context.getPolicy("bluetooth"));
+       int ret = __setModeChangeState(context.getPolicy<int>("bluetooth"));
        if (POLICY_ENFORCING_FAILED(ret)) {
        }
 
-       ret = __setDesktopConnectivityState(context.getPolicy("bluetooth-desktop-connectivity"));
+       ret = __setDesktopConnectivityState(context.getPolicy<int>("bluetooth-desktop-connectivity"));
        if (POLICY_ENFORCING_FAILED(ret)) {
        }
 
-       ret = __setPairingState(context.getPolicy("bluetooth-pairing"));
+       ret = __setPairingState(context.getPolicy<int>("bluetooth-pairing"));
        if (POLICY_ENFORCING_FAILED(ret)) {
        }
 
-       ret = __setDeviceRestriction(context.getPolicy("bluetooth-device-restriction"));
+       ret = __setDeviceRestriction(context.getPolicy<int>("bluetooth-device-restriction"));
        if (POLICY_ENFORCING_FAILED(ret)) {
        }
 
-       ret = __setUuidRestriction(context.getPolicy("bluetooth-uuid-restriction"));
+       ret = __setUuidRestriction(context.getPolicy<int>("bluetooth-uuid-restriction"));
        if (POLICY_ENFORCING_FAILED(ret)) {
        }
 }
@@ -177,7 +177,7 @@ int BluetoothPolicy::setModeChangeState(const bool enable)
 
 bool BluetoothPolicy::getModeChangeState()
 {
-       return context.getPolicy("bluetooth");
+       return context.getPolicy<int>("bluetooth");
 }
 
 int BluetoothPolicy::setDesktopConnectivityState(const bool enable)
@@ -195,7 +195,7 @@ int BluetoothPolicy::setDesktopConnectivityState(const bool enable)
 
 bool BluetoothPolicy::getDesktopConnectivityState()
 {
-       return context.getPolicy("bluetooth-desktop-connectivity");
+       return context.getPolicy<int>("bluetooth-desktop-connectivity");
 }
 
 int BluetoothPolicy::setPairingState(const bool enable)
@@ -213,7 +213,7 @@ int BluetoothPolicy::setPairingState(const bool enable)
 
 bool BluetoothPolicy::getPairingState()
 {
-       return context.getPolicy("bluetooth-pairing");
+       return context.getPolicy<int>("bluetooth-pairing");
 }
 
 
@@ -252,7 +252,7 @@ int BluetoothPolicy::setTetheringState(bool enable)
 
 bool BluetoothPolicy::getTetheringState()
 {
-       return context.getPolicy("bluetooth-tethering");
+       return context.getPolicy<int>("bluetooth-tethering");
 }
 
 int BluetoothPolicy::removeDeviceFromBlacklist(const std::string& mac)
@@ -280,7 +280,7 @@ int BluetoothPolicy::setDeviceRestriction(const bool enable)
 
 bool BluetoothPolicy::isDeviceRestricted()
 {
-       return context.getPolicy("bluetooth-device-restriction");
+       return context.getPolicy<int>("bluetooth-device-restriction");
 }
 
 int BluetoothPolicy::addUuidToBlacklist(const std::string& uuid)
@@ -318,7 +318,7 @@ int BluetoothPolicy::setUuidRestriction(const bool enable)
 
 bool BluetoothPolicy::isUuidRestricted()
 {
-       return context.getPolicy("bluetooth-uuid-restriction");
+       return context.getPolicy<int>("bluetooth-uuid-restriction");
 }
 
 DEFINE_POLICY(BluetoothPolicy);
diff --git a/server/client-manager.cpp b/server/client-manager.cpp
deleted file mode 100644 (file)
index 46f2813..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- *  Copyright (c) 2015 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 <string>
-#include <climits>
-
-#include <klay/exception.h>
-
-#include "client-manager.h"
-
-DeviceAdministrator::DeviceAdministrator(const std::string& pkgname, uid_t puid, const std::string& pk) :
-       name(pkgname), uid(puid), key(pk)
-{
-}
-
-DeviceAdministrator::~DeviceAdministrator()
-{
-}
-
-DeviceAdministratorManager::DeviceAdministratorManager(const std::string& path) :
-       repository(path + "/.dpm.db")
-{
-       prepareRepository();
-}
-
-DeviceAdministrator DeviceAdministratorManager::enroll(const std::string& name, uid_t uid)
-{
-       database::Connection connection(repository, database::Connection::ReadWrite);
-
-       std::string selectQuery = "SELECT * FROM ADMIN WHERE PKG = ? AND UID = ?";
-       database::Statement stmt0(connection, selectQuery);
-       stmt0.bind(1, name);
-       stmt0.bind(2, static_cast<int>(uid));
-       if (stmt0.step()) {
-               throw runtime::Exception("Client already registered");
-       }
-
-       std::string key = generateKey();
-
-       std::string insertQuery = "INSERT INTO ADMIN (PKG, UID, KEY, REMOVABLE) VALUES (?, ?, ?, ?)";
-       database::Statement stmt(connection, insertQuery);
-       stmt.bind(1, name);
-       stmt.bind(2, static_cast<int>(uid));
-       stmt.bind(3, key);
-       stmt.bind(4, true);
-       if (!stmt.exec()) {
-               throw runtime::Exception("Failed to insert client data");
-       }
-
-       return DeviceAdministrator(name, uid, key);
-}
-
-void DeviceAdministratorManager::disenroll(const std::string& name, uid_t uid)
-{
-       database::Connection connection(repository, database::Connection::ReadWrite);
-
-       std::string query = "DELETE FROM ADMIN WHERE PKG = ? AND UID = ?";
-       database::Statement stmt(connection, query);
-       stmt.bind(1, name);
-       stmt.bind(2, static_cast<int>(uid));
-       if (!stmt.exec()) {
-               throw runtime::Exception("Failed to delete client data");
-       }
-}
-
-std::string DeviceAdministratorManager::generateKey()
-{
-       std::string key = "TestKey";
-       return key;
-}
-
-void DeviceAdministratorManager::prepareRepository()
-{
-       database::Connection connection(repository, database::Connection::ReadWrite |
-                                                                                               database::Connection::Create);
-
-       std::string query = "CREATE TABLE IF NOT EXISTS ADMIN ("    \
-                                               "ID INTEGER PRIMARY KEY AUTOINCREMENT, " \
-                                               "PKG TEXT, "                             \
-                                               "UID INTEGER, "                          \
-                                               "KEY TEXT, "                             \
-                                               "REMOVABLE INTEGER)";
-
-       connection.exec(query);
-
-       database::Statement stmt(connection, "SELECT * FROM ADMIN");
-       while (stmt.step()) {
-               std::string name = stmt.getColumn(1).getText();
-               uid_t uid = static_cast<uid_t>(stmt.getColumn(2).getInt());
-               std::string key = stmt.getColumn(3).getText();
-
-               deviceAdministratorList.push_back(DeviceAdministrator(name, uid, key));
-       }
-}
index 098a2b6..aed5369 100644 (file)
 
 #ifndef __DPM_CLIENT_MANAGER_H__
 #define __DPM_CLIENT_MANAGER_H__
-#include <unistd.h>
 #include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <limits.h>
+
+#include <aul.h>
 
 #include <string>
 #include <vector>
 
-#include <klay/db/column.h>
-#include <klay/db/statement.h>
-#include <klay/db/connection.h>
+#include <klay/exception.h>
 
 class DeviceAdministrator {
 public:
        DeviceAdministrator(const DeviceAdministrator&) = delete;
        DeviceAdministrator(DeviceAdministrator&&) = default;
-       DeviceAdministrator(const std::string& name, uid_t uid, const std::string& key);
+       DeviceAdministrator(const std::string& pkgid, uid_t user, const std::string& pk) :
+               name(pkgid), uid(user), key(pk)
+       {
+       }
 
-       ~DeviceAdministrator();
+       DeviceAdministrator(pid_t pid, uid_t user)
+       {
+               char pkgid[PATH_MAX];
+
+               if (aul_app_get_pkgid_bypid_for_uid(pid, pkgid, PATH_MAX, uid) != 0) {
+                       int fd = ::open(std::string("/proc/" + std::to_string(pid) + "/cmdline").c_str(), O_RDONLY);
+                       if (fd == -1) {
+                               throw runtime::Exception("Unknown PID");
+                       }
+
+                       ssize_t ret, bytes = 0;
+                       do {
+                               ret = ::read(fd, &pkgid[bytes], PATH_MAX);
+                               if (ret != -1) {
+                                       bytes += ret;
+                               }
+                       } while ((ret == -1) && (errno == EINTR));
+
+                       if (ret == -1) {
+                               throw runtime::Exception("Failed to get admin info");
+                       }
+
+                       pkgid[bytes] = '\0';
+               }
+
+               name = pkgid;
+               uid = user;
+       }
+
+       ~DeviceAdministrator()
+       {
+       }
 
        DeviceAdministrator& operator=(DeviceAdministrator&&) = default;
        DeviceAdministrator& operator=(const DeviceAdministrator&) = delete;
@@ -58,34 +95,4 @@ private:
        std::string key;
 };
 
-class DeviceAdministratorManager {
-public:
-       typedef std::vector<DeviceAdministrator> DeviceAdministratorList;
-
-       DeviceAdministratorManager(const std::string& path);
-       DeviceAdministratorManager(const DeviceAdministratorManager&) = delete;
-       DeviceAdministratorManager& operator=(const DeviceAdministratorManager&) = delete;
-
-       DeviceAdministrator enroll(const std::string& name, uid_t uid);
-       void disenroll(const std::string& name, uid_t uid);
-
-       DeviceAdministratorList::iterator begin()
-       {
-               return deviceAdministratorList.begin();
-       }
-
-       DeviceAdministratorList::iterator end()
-       {
-               return deviceAdministratorList.end();
-       }
-
-private:
-       void prepareRepository();
-       std::string generateKey();
-
-private:
-       std::string repository;
-       DeviceAdministratorList deviceAdministratorList;
-};
-
 #endif //__DPM_CLIENT_MANAGER_H__
index ae16bd3..224ad83 100644 (file)
@@ -51,7 +51,7 @@ int LocationPolicy::setLocationState(int enable)
 
 int LocationPolicy::getLocationState()
 {
-       return context.getPolicy("location");
+       return context.getPolicy<int>("location");
 }
 
 DEFINE_POLICY(LocationPolicy);
index ddd257a..5545b24 100644 (file)
@@ -42,12 +42,12 @@ int PasswordStatus = 0;
 
 inline int getPasswordPolicy(PolicyControlContext &ctx, const std::string &name)
 {
-       return ctx.getPolicy(name, ctx.getPeerUid());
+       return ctx.getPolicy<int>(name, ctx.getPeerUid());
 }
 
 inline bool setPasswordPolicy(PolicyControlContext &ctx, const std::string &name, int value)
 {
-       return ctx.setPolicy(name, value, "password", name);
+       return ctx.setPolicy<int>(name, value, "password", name);
 }
 
 inline PasswordManager::QualityType getPasswordQualityType(int quality)
@@ -476,7 +476,7 @@ std::vector<std::string> PasswordPolicy::getForbiddenStrings()
 int PasswordPolicy::setRecovery(int enable)
 {
        try {
-               SetPolicyEnabled(context, "password-recovery", enable);
+               setPasswordPolicy(context, "password-recovery", enable);
        } catch (runtime::Exception &e) {
                ERROR("Failed to set recovery");
                return -1;
index 1b500f4..53943ab 100644 (file)
@@ -39,14 +39,14 @@ struct PolicyBuilder {
        std::unique_ptr<T> instance;
 };
 
-inline bool SetPolicyAllowed(PolicyControlContext& context, const std::string& name, bool allow)
+inline bool SetPolicyAllowed(PolicyControlContext& context, const std::string& name, int allow)
 {
-       return context.setPolicy(name, allow, name, allow ? "allowed" : "disallowed");
+       return context.setPolicy<int>(name, allow, name, allow ? "allowed" : "disallowed");
 }
 
-inline bool SetPolicyEnabled(PolicyControlContext& context, const std::string& name, bool enable)
+inline bool SetPolicyEnabled(PolicyControlContext& context, const std::string& name, int enable)
 {
-       return context.setPolicy(name, enable, name, enable ? "enabled" : "disabled");
+       return context.setPolicy<int>(name, enable, name, enable ? "enabled" : "disabled");
 }
 
 inline void PolicyBuild(PolicyControlContext& context)
index d67cbbe..6c7082d 100644 (file)
 #include <unistd.h>
 #include <sys/stat.h>
 #include <sys/types.h>
-#include <climits>
-
-#include "policy-manager.h"
 
-#include "exception.h"
-#include "filesystem.h"
-#include "audit/logger.h"
-
-#define POLICY_SCOPE_GLOBAL    0
-#define POLICY_SCOPE_USER      1
+#include <climits>
+#include <string>
+#include <unordered_map>
+#include <iostream>
 
-#define DEFINE_USER_POLICY(_n_, _v_, _c_)      \
-{ _n_, ManagedPolicy(POLICY_SCOPE_USER, _v_, _c_) }
+#include <klay/exception.h>
+#include <klay/filesystem.h>
+#include <klay/audit/logger.h>
 
-#define DEFINE_GLOBAL_POLICY(_n_, _v_, _c_)    \
-{ _n_, ManagedPolicy(POLICY_SCOPE_GLOBAL, _v_, _c_) }
+#include "client-manager.h"
+#include "policy-manager.h"
 
 namespace {
 
-struct ManagedPolicy {
-       ManagedPolicy(int sc, int val, PolicyManager::PolicyComparator pred) :
-               scope(sc), value(val), compare(pred)
-       {
-       }
-
-       int scope;
-       int value;
-       PolicyManager::PolicyComparator compare;
-};
+const std::string schema = \
+       "CREATE TABLE IF NOT EXISTS admin ("                                  \
+       "    id        INTEGER PRIMARY KEY AUTOINCREMENT, "                   \
+       "    pkg       TEXT NOT NULL, "                                       \
+       "    uid       INTEGER, "                                             \
+       "    key       TEXT, "                                                \
+       "    removable INTEGER"                                               \
+       ");"                                                                  \
+       "CREATE TABLE IF NOT EXISTS managed_policy ("                         \
+       "    id        INTEGER PRIMARY KEY AUTOINCREMENT, "                   \
+       "    aid       INTEGER,"                                              \
+       "    pid       INTEGER,"                                              \
+       "    value     INTEGER"                                               \
+       ");"                                                                  \
+       "CREATE TABLE IF NOT EXISTS policy_definition ("                      \
+    "    id        INTEGER PRIMARY KEY, "                                 \
+       "    scope     INTEGER, "                                             \
+       "    name      TEXT NOT NULL, "                                       \
+       "    ivalue    INTEGER"                                               \
+       ");"                                                                  \
+       "CREATE TRIGGER IF NOT EXISTS prepare_storage AFTER INSERT ON admin " \
+       "FOR EACH ROW "                                                       \
+       "BEGIN "                                                              \
+       "INSERT INTO managed_policy(aid, pid, value) "                        \
+       "SELECT NEW.ID, policy_definition.id, policy_definition.ivalue "      \
+       "FROM policy_definition; "                                            \
+       "END;"                                                                \
+       "CREATE TRIGGER IF NOT EXISTS remove_storage AFTER DELETE ON admin "  \
+       "FOR EACH ROW "                                                       \
+       "BEGIN "                                                              \
+       "DELETE FROM managed_policy WHERE managed_policy.aid = OLD.ID; "      \
+       "END;";
 
 bool StateComparator(int v1, int v2)
 {
@@ -59,7 +77,7 @@ bool RestrictionComparator(int v1, int v2)
 
 bool MinimizeIntegerComparator(int v1, int v2)
 {
-       return v2 < v1 ? true : false;
+       return v2 < v2 ? true : false;
 }
 
 bool MaximizeIntegerComparator(int v1, int v2)
@@ -67,330 +85,142 @@ bool MaximizeIntegerComparator(int v1, int v2)
        return v1 < v2 ? true : false;
 }
 
-std::unordered_map<std::string, ManagedPolicy> managedPolicyMap = {
-       DEFINE_GLOBAL_POLICY("password-history", 0, MaximizeIntegerComparator),
-       DEFINE_GLOBAL_POLICY("password-minimum-length", 0, MaximizeIntegerComparator),
-       DEFINE_GLOBAL_POLICY("password-minimum-complexity", 0, MaximizeIntegerComparator),
-       DEFINE_GLOBAL_POLICY("password-inactivity-timeout", INT_MAX, MinimizeIntegerComparator),
-       DEFINE_GLOBAL_POLICY("password-expired", INT_MAX, MinimizeIntegerComparator),
-       DEFINE_GLOBAL_POLICY("password-maximum-failure-count", INT_MAX, MinimizeIntegerComparator),
-       DEFINE_GLOBAL_POLICY("password-numeric-sequences-length", INT_MAX, MinimizeIntegerComparator),
-       DEFINE_GLOBAL_POLICY("password-maximum-character-occurrences", INT_MAX, MinimizeIntegerComparator),
-       DEFINE_GLOBAL_POLICY("password-quality", 0, MaximizeIntegerComparator),
-       DEFINE_GLOBAL_POLICY("password-recovery", 0, RestrictionComparator),
-       DEFINE_GLOBAL_POLICY("bluetooth", 1, StateComparator),
-       DEFINE_GLOBAL_POLICY("bluetooth-tethering", 1, StateComparator),
-       DEFINE_GLOBAL_POLICY("bluetooth-desktop-connectivity", 1, StateComparator),
-       DEFINE_GLOBAL_POLICY("bluetooth-pairing", 1, StateComparator),
-       DEFINE_GLOBAL_POLICY("bluetooth-uuid-restriction", 0, RestrictionComparator),
-       DEFINE_GLOBAL_POLICY("bluetooth-device-restriction", 0, RestrictionComparator),
-       DEFINE_GLOBAL_POLICY("browser", 1, StateComparator),
-       DEFINE_GLOBAL_POLICY("camera", 1, StateComparator),
-       DEFINE_GLOBAL_POLICY("clipboard", 1, StateComparator),
-       DEFINE_GLOBAL_POLICY("external-storage", 1, StateComparator),
-       DEFINE_GLOBAL_POLICY("location", 1, StateComparator),
-       DEFINE_GLOBAL_POLICY("messaging", 1, StateComparator),
-       DEFINE_GLOBAL_POLICY("microphone", 1, StateComparator),
-       DEFINE_GLOBAL_POLICY("popimap-email", 1, StateComparator),
-       DEFINE_GLOBAL_POLICY("usb-debugging", 1, StateComparator),
-       DEFINE_GLOBAL_POLICY("usb-tethering", 1, StateComparator),
-       DEFINE_GLOBAL_POLICY("wifi", 1, StateComparator),
-       DEFINE_GLOBAL_POLICY("wifi-hotspot", 1, StateComparator),
-       DEFINE_GLOBAL_POLICY("wifi-profile-change", 1, StateComparator),
-       DEFINE_GLOBAL_POLICY("wifi-ssid-restriction", 0, RestrictionComparator)
-};
-
-} // namespace
-
-PolicyManager::PolicyManager(const std::string& base, const std::string& path) :
-       store(base), location(path)
-{
-       runtime::File policyDirectory(location);
-
-       if (policyDirectory.exists()) {
-               policyDirectory.remove(true);
-       }
-
-       policyDirectory.makeDirectory(true);
-
-       runtime::File policyStore(store);
-       if (!policyStore.exists()) {
-               policyStore.makeDirectory(true);
-       }
-}
-
-PolicyManager::~PolicyManager()
-{
-}
-
-int PolicyManager::getEffectivePolicy(const std::string& path)
+bool PatternComparator(const std::string& v1, const std::string& v2)
 {
-       int value;
-       runtime::File file(path);
-
-       file.open(O_RDONLY);
-       file.read(&value, sizeof(value));
-       file.close();
-
-       return value;
+       return false;
 }
 
-void PolicyManager::setEffectivePolicy(const std::string& path, int value)
-{
-       runtime::File file(path);
-
-       file.open(O_WRONLY | O_TRUNC);
-       file.write(&value, sizeof(value));
-       file.close();
-}
+} // namespace
 
-void PolicyManager::createEffectivePolicy(const std::string& path, int value)
-{
-       runtime::File file(path);
+#define USER_POLICY(_n_, _v_, _c_)     \
+{ _n_, ManagedPolicy(_n_, 1, _v_, _c_) }
+
+#define GLOBAL_POLICY(_n_, _v_, _c_) \
+{ _n_, ManagedPolicy(_n_, 0, _v_, _c_) }
+
+std::unordered_map<std::string, ManagedPolicy> PolicyManager::managedPolicyMap = {
+USER_POLICY("password-history",                       int(0),          MaximizeIntegerComparator),
+USER_POLICY("password-minimum-length",                int(0),          MaximizeIntegerComparator),
+USER_POLICY("password-minimum-complexity",            int(0),          MaximizeIntegerComparator),
+USER_POLICY("password-inactivity-timeout",            int(INT_MAX),    MinimizeIntegerComparator),
+USER_POLICY("password-expired",                       int(INT_MAX),    MinimizeIntegerComparator),
+USER_POLICY("password-maximum-failure-count",         int(INT_MAX),    MinimizeIntegerComparator),
+USER_POLICY("password-numeric-sequences-length",      int(INT_MAX),    MinimizeIntegerComparator),
+USER_POLICY("password-maximum-character-occurrences", int(INT_MAX),    MinimizeIntegerComparator),
+USER_POLICY("password-quality",                       int(0),          MaximizeIntegerComparator),
+USER_POLICY("password-recovery",                      int(0),          RestrictionComparator),
+USER_POLICY("password-pattern",                       std::string(""), PatternComparator),
+USER_POLICY("browser",                                int(1),          StateComparator),
+USER_POLICY("clipboard",                              int(1),          StateComparator),
+GLOBAL_POLICY("bluetooth",                              int(1),          StateComparator),
+GLOBAL_POLICY("bluetooth-tethering",                    int(1),          StateComparator),
+GLOBAL_POLICY("bluetooth-desktop-connectivity",         int(1),          StateComparator),
+GLOBAL_POLICY("bluetooth-pairing",                      int(1),          StateComparator),
+GLOBAL_POLICY("bluetooth-uuid-restriction",             int(0),          RestrictionComparator),
+GLOBAL_POLICY("bluetooth-device-restriction",           int(0),          RestrictionComparator),
+GLOBAL_POLICY("camera",                                 int(1),          StateComparator),
+GLOBAL_POLICY("external-storage",                       int(1),          StateComparator),
+GLOBAL_POLICY("location",                               int(1),          StateComparator),
+GLOBAL_POLICY("messaging",                              int(1),          StateComparator),
+GLOBAL_POLICY("microphone",                             int(1),          StateComparator),
+GLOBAL_POLICY("popimap-email",                          int(1),          StateComparator),
+GLOBAL_POLICY("usb-debugging",                          int(1),          StateComparator),
+GLOBAL_POLICY("usb-tethering",                          int(1),          StateComparator),
+GLOBAL_POLICY("wifi",                                   int(1),          StateComparator),
+GLOBAL_POLICY("wifi-hotspot",                           int(1),          StateComparator),
+GLOBAL_POLICY("wifi-profile-change",                    int(1),          StateComparator),
+GLOBAL_POLICY("wifi-ssid-restriction",                  int(0),          RestrictionComparator)
+};
 
-       file.create(0644);
-       file.write(&value, sizeof(value));
-       file.close();
-}
+std::atomic<unsigned int> ManagedPolicy::IVariantStorage::sequencer(1);
 
-void PolicyManager::prepareGlobalPolicy()
+PolicyManager::PolicyManager(const std::string& path) :
+       connection(path, database::Connection::ReadWrite | database::Connection::Create)
 {
-       for (auto it = managedPolicyMap.begin(); it != managedPolicyMap.end(); ++it) {
-               const ManagedPolicy& policy = it->second;
-               if (policy.scope == POLICY_SCOPE_GLOBAL) {
-                       std::string path = buildLocation(it->first);
-                       createEffectivePolicy(path, policy.value);
-               }
-       }
+       initializeStorage();
 }
 
-void PolicyManager::removeGlobalPolicy()
+PolicyManager::~PolicyManager()
 {
-       runtime::File dir(location);
-       if (dir.exists()) {
-               dir.remove(true);
-       }
 }
 
-void PolicyManager::removeUserPolicy(uid_t uid)
+std::vector<uid_t> PolicyManager::getManagedDomainList()
 {
-       runtime::File dir(location + "/" + std::to_string(uid));
-       if (dir.exists()) {
-               dir.remove(true);
+       std::vector<uid_t> managedDomains;
+       std::string query0 = "SELECT DISTINCT uid FROM admin;";
+       database::Statement stmt0(connection, query0);
+       while (stmt0.step()) {
+               managedDomains.push_back(stmt0.getColumn(0).getInt());
        }
-}
 
-void PolicyManager::prepareUserPolicy(uid_t user)
-{
-       runtime::File dir(location + "/" + std::to_string(user));
-       if (!dir.exists()) {
-               dir.makeDirectory(true);
-               for (auto it = managedPolicyMap.begin(); it != managedPolicyMap.end(); ++it) {
-                       const ManagedPolicy& policy = it->second;
-                       if (policy.scope == POLICY_SCOPE_USER) {
-                               std::string path = buildLocation(user, it->first);
-                               createEffectivePolicy(path, policy.value);
-                       }
-               }
-       }
+       return managedDomains;
 }
 
-void PolicyManager::populateStorage(const std::string& name, uid_t uid, bool create)
+void PolicyManager::initializeStorage()
 {
-       std::unique_ptr<PolicyStorage> storage(new PolicyStorage(store, name, uid, create));
-       for (auto it = storage->begin(); it != storage->end(); ++it) {
-               if (managedPolicyMap.count(it->first)) {
-                       const ManagedPolicy& policy = managedPolicyMap.at(it->first);
-                       std::string path = (policy.scope == POLICY_SCOPE_USER)
-                                                        ? buildLocation(uid, it->first)
-                                                        : buildLocation(it->first);
-                       try {
-                               int value = getEffectivePolicy(path);
-                               int local = it->second.getContent();
-
-                               if (policy.compare(value, local)) {
-                                       setEffectivePolicy(path, local);
-                               }
-                       } catch (runtime::Exception& e) {
-                               ERROR(e.what());
-                       }
+       connection.exec(schema);
+       std::string query = "SELECT id FROM policy_definition;";
+       database::Statement stmt(connection, query);
+       if (stmt.step() == false) {
+               for (auto &it : managedPolicyMap) {
+                       ManagedPolicy &policy = it.second;
+                       policy.declare(connection);
                }
        }
-
-       storageList.emplace_back(std::move(storage));
 }
 
-void PolicyManager::removeStorage(const std::string& name, uid_t uid)
+void PolicyManager::apply()
 {
-       std::vector<std::unique_ptr<PolicyStorage>>::iterator iter = storageList.begin();
-       while (iter != storageList.end()) {
-               if ((*iter)->isAssociated(name, uid)) {
-                       (*iter)->remove();
-                       storageList.erase(iter);
-                       break;
-               }
-               ++iter;
-       }
-
-       std::unordered_map<std::string, ManagedPolicy>::iterator it = managedPolicyMap.begin();
-       while (it != managedPolicyMap.end()) {
-               ManagedPolicy& policy = it->second;
-               int strictness = policy.value;
-               if (policy.scope == POLICY_SCOPE_USER) {
-                       strictness = getStrictUserPolicy(it->first, uid, strictness, policy.compare);
-               } else {
-                       strictness = getStrictGlobalPolicy(it->first, strictness, policy.compare);
-               }
-
-               std::string path = (policy.scope == POLICY_SCOPE_USER)
-                                                ? buildLocation(uid, it->first)
-                                                : buildLocation(it->first);
-
-               setEffectivePolicy(path, strictness);
-               ++it;
-       }
-}
+       std::vector<uid_t> managedDomains = getManagedDomainList();
 
-void PolicyManager::cleanup()
-{
-       runtime::File policyDirectory(location);
-       if (policyDirectory.exists()) {
-               policyDirectory.remove(true);
+       for (auto &it : managedPolicyMap) {
+               ManagedPolicy &policy = it.second;
+               policy.apply(connection, managedDomains);
        }
 }
 
-int PolicyManager::getGlobalPolicy(const std::string& name)
+int PolicyManager::prepareStorage(const std::string& admin, uid_t uid)
 {
-       if (managedPolicyMap.count(name) == 0) {
+       std::string selectQuery = "SELECT * FROM admin WHERE pkg = ? AND uid = ?";
+       database::Statement stmt0(connection, selectQuery);
+       stmt0.bind(1, admin);
+       stmt0.bind(2, static_cast<int>(uid));
+       if (stmt0.step()) {
+               ERROR("Admin client already registered");
                return -1;
        }
 
-       return getEffectivePolicy(buildLocation(name));
-}
+       std::string key = "Not supported";
 
-int PolicyManager::getUserPolicy(const std::string& name, uid_t uid)
-{
-       if (managedPolicyMap.count(name) == 0) {
+       std::string insertQuery = "INSERT INTO admin (pkg, uid, key, removable) VALUES (?, ?, ?, ?)";
+       database::Statement stmt(connection, insertQuery);
+       stmt.bind(1, admin);
+       stmt.bind(2, static_cast<int>(uid));
+       stmt.bind(3, key);
+       stmt.bind(4, true);
+       if (!stmt.exec()) {
+               ERROR("I/O failure");
                return -1;
        }
-       return getEffectivePolicy(buildLocation(uid, name));
-}
-
-int PolicyManager::getStrictGlobalPolicy(const std::string& name, int pivot,
-                                                                                PolicyManager::PolicyComparator& pred)
-{
-       int strictness = pivot;
-       std::vector<std::unique_ptr<PolicyStorage>>::iterator iter = storageList.begin();
-       while (iter != storageList.end()) {
-               int value = (*iter)->getPolicy(name);
-               if (pred(strictness, value)) {
-                       strictness = value;
-               }
-               ++iter;
-       }
-
-       return strictness;
-}
-
-int PolicyManager::getStrictUserPolicy(const std::string& name, uid_t uid, int pivot,
-                                                                          PolicyManager::PolicyComparator& pred)
-{
-       int strictness = pivot;
-       std::vector<std::unique_ptr<PolicyStorage>>::iterator iter = storageList.begin();
-       while (iter != storageList.end()) {
-               if ((*iter)->isAssociated(uid)) {
-                       int value = (*iter)->getPolicy(name);
-                       if (pred(strictness, value)) {
-                               strictness = value;
-                       }
-               }
-               ++iter;
-       }
-
-       return strictness;
-}
-
-bool PolicyManager::updateClientStorage(const std::string& pkgid, uid_t uid,
-                                                                               const std::string& name, int value)
-{
-       std::vector<std::unique_ptr<PolicyStorage>>::iterator iter = storageList.begin();
-       while (iter != storageList.end()) {
-               if ((*iter)->isAssociated(pkgid, uid)) {
-                       (*iter)->setPolicy(name, value);
-                       return true;
-               }
-               ++iter;
-       }
-
-       ERROR("Unknown client: " + pkgid);
-       return false;
-}
-
-bool PolicyManager::setUserPolicy(const std::string& pkgid, uid_t uid,
-                                                                 const std::string& name, int value,
-                                                                 PolicyManager::PolicyComparator& pred)
-{
-       updateClientStorage(pkgid, uid, name, value);
-
-       std::string path = buildLocation(uid, name);
-       int current = getEffectivePolicy(path);
-       if (current != value) {
-               if (pred(current, value)) {
-                       setEffectivePolicy(path, value);
-                       return true;
-               }
-
-               int strictness = getStrictUserPolicy(name, uid, value, pred);
-               if (current != strictness) {
-                       setEffectivePolicy(path, strictness);
-                       return true;
-               }
-       }
-
-       return false;
-}
-
-bool PolicyManager::setGlobalPolicy(const std::string& pkgid, uid_t uid,
-                                                                       const std::string& name, int value,
-                                                                       PolicyManager::PolicyComparator& pred)
-{
-       updateClientStorage(pkgid, uid, name, value);
-
-       std::string path = buildLocation(name);
-       int current = getEffectivePolicy(path);
-       if (current != value) {
-               if (pred(current, value)) {
-                       setEffectivePolicy(path, value);
-                       return true;
-               }
-
-               int strictness = getStrictGlobalPolicy(name, value, pred);
-               if (current != strictness) {
-                       setEffectivePolicy(path, strictness);
-                       return true;
-               }
-       }
 
-       return false;
+       return 0;
 }
 
-bool PolicyManager::setPolicy(const std::string& pkgid, uid_t uid,
-                                                         const std::string& name, int value)
+int PolicyManager::removeStorage(const std::string& admin, uid_t domain)
 {
-       if (managedPolicyMap.count(name) == 0) {
-               ERROR("Unknown policy: " + name);
-               return false;
+       std::string query = "DELETE FROM admin WHERE pkg = ? AND uid = ?";
+       database::Statement stmt(connection, query);
+       stmt.bind(1, admin);
+       stmt.bind(2, static_cast<int>(domain));
+       if (!stmt.exec()) {
+               ERROR("Unknown device admin client: " + admin);
+               return -1;
        }
 
-       ManagedPolicy& policy = managedPolicyMap.at(name);
-       PolicyComparator& pred = policy.compare;
-
-       bool ret;
-       if (policy.scope == POLICY_SCOPE_USER) {
-               ret = setUserPolicy(pkgid, uid, name, value, pred);
-       } else {
-               ret = setGlobalPolicy(pkgid, uid, name, value, pred);
+       for (auto &it : managedPolicyMap) {
+               ManagedPolicy &policy = it.second;
+               policy.apply(connection, std::vector<uid_t>({domain}));
        }
 
-       return ret;
+       return 0;
 }
index f95a7f7..6e652ee 100644 (file)
 #include <string>
 #include <vector>
 #include <unordered_map>
+#include <memory>
+#include <atomic>
+#include <mutex>
 
-#include "policy.h"
-#include "policy-storage.h"
+#include <klay/db/connection.h>
+#include <klay/db/statement.h>
+#include <klay/db/column.h>
+#include <klay/audit/logger.h>
+
+#include "client-manager.h"
+
+template<typename DataType>
+struct PolicyComparator {
+       typedef std::function<bool(DataType&, DataType&)> type;
+};
+
+typedef database::Connection DataSource;
+
+struct ManagedPolicy {
+       ManagedPolicy()
+       {
+       }
+
+       ~ManagedPolicy()
+       {
+               if (storage != nullptr) {
+                       delete storage;
+               }
+       }
+
+       ManagedPolicy(const ManagedPolicy& rhs) :
+               scope(rhs.scope), storage(rhs.storage->clone())
+       {
+       }
+
+       ManagedPolicy(ManagedPolicy&& rhs) :
+               scope(rhs.scope), storage(rhs.storage)
+       {
+               rhs.storage = nullptr;
+       }
+
+       template<typename DataType>
+       ManagedPolicy(const std::string& name, int sc, const DataType& value) :
+               scope(sc)
+       {
+               storage = new VariantStorage<DataType>(name, sc, value);
+       }
+
+       template<typename DataType>
+       ManagedPolicy(const std::string& name, int sc, const DataType& value,
+                                 const typename PolicyComparator<DataType>::type& pred) :
+               scope(sc)
+       {
+               storage = new VariantStorage<DataType>(name, sc, value, pred);
+       }
+
+       template<typename DataType>
+       bool set(DataSource& datasource, const std::string& admin, uid_t domain, DataType& value)
+       {
+               std::lock_guard<std::recursive_mutex> lock(updateLock);
+               return static_cast<VariantStorage<DataType> *>(storage)->set(datasource, admin, domain, value);
+       }
+
+       template<typename DataType>
+       DataType get(DataSource& datasource, uid_t domain)
+       {
+               std::lock_guard<std::recursive_mutex> lock(updateLock);
+               return static_cast<VariantStorage<DataType> *>(storage)->get(datasource, domain);
+       }
+
+       void declare(DataSource& datasource)
+       {
+               std::lock_guard<std::recursive_mutex> lock(updateLock);
+               return storage->declare(datasource);
+       }
+
+       bool enforce(DataSource& datasource, uid_t domain = 0)
+       {
+               std::lock_guard<std::recursive_mutex> lock(updateLock);
+               return storage->enforce(datasource, domain);
+       }
+
+       void apply(DataSource& datasource, const std::vector<uid_t>& domainList)
+       {
+               if (scope) {
+                       for (auto domain : domainList) {
+                               enforce(datasource, domain);
+                       }
+               } else {
+                       enforce(datasource);
+               }
+       }
 
-class PolicyManager {
 public:
-       typedef std::function<bool(int, int)> PolicyComparator;
+       class IVariantStorage {
+       public:
+               virtual ~IVariantStorage() {}
+               virtual IVariantStorage* clone() const = 0;
+               virtual void declare(DataSource& source) = 0;
+               virtual bool enforce(DataSource& source, uid_t domain = 0) = 0;
+
+       private:
+               static std::atomic<unsigned int> sequencer;
+       };
+
+       template<typename DataType>
+       struct VariantStorage : public IVariantStorage {
+               VariantStorage( const std::string& rname, int sc, const DataType& value) :
+                       name(rname), scope(sc), reference(value)
+               {
+                       bool defaultComparator = [value](decltype(value)& v1, decltype(value)& v2) {
+                               return v1 < v2 ? false : true;
+                       };
+
+                       comparator = std::move(defaultComparator);
+                       id = sequencer++;
+               }
+
+               VariantStorage(const std::string& rname, int sc, const DataType& value,
+                                          const typename PolicyComparator<DataType>::type& pred) :
+                       name(rname), scope(sc), reference(value), comparator(pred)
+               {
+                       id = sequencer++;
+               }
+
+               ~VariantStorage()
+               {
+               }
+
+               IVariantStorage* clone() const
+               {
+                       return new VariantStorage<DataType>(*this);
+               }
+
+               DataType get(DataSource& datasource, uid_t domain)
+               {
+                       if (current.count(domain)) {
+                               return current[domain];
+                       }
 
-       PolicyManager(const std::string& base, const std::string& path);
+                       return reference;
+               }
+
+               bool compare(DataType& v1, DataType& v2)
+               {
+                       return comparator(v1, v2);
+               }
+
+               bool insert(uid_t domain, DataType& value)
+               {
+                       int count = current.count(domain);
+                       if ((count == 0) || (current[domain] != value)) {
+                               current[domain] = value;
+                               return true;
+                       }
+
+                       return false;
+               }
+
+               bool set(DataSource& datasource, const std::string& admin, uid_t domain, DataType& value)
+               {
+                       std::string selectQuery = "SELECT id FROM admin WHERE pkg = ? AND uid = ?";
+                       database::Statement stmt0(datasource, selectQuery);
+                       stmt0.bind(1, admin);
+                       stmt0.bind(2, static_cast<int>(domain));
+                       if (!stmt0.step()) {
+                               throw runtime::Exception("Unknown device admin client: " + admin);
+                       }
+
+                       int aid = stmt0.getColumn(0).getInt();
+
+                       std::string updateQuery = "UPDATE managed_policy SET value = ? WHERE pid = ? AND aid = ?";
+                       database::Statement stmt(datasource, updateQuery);
+                       stmt.bind(1, value);
+                       stmt.bind(2, id);
+                       stmt.bind(3, aid);
+                       if (!stmt.exec()) {
+                               throw runtime::Exception("Failed to update policy");
+                       }
+
+                       uid_t target = scope == 0 ? 0 : domain;
+                       return enforce(datasource, target);
+               }
+
+               void declare(DataSource& datasource)
+               {
+                       std::string query = "INSERT INTO policy_definition(id, scope, name, ivalue) VALUES (?, ?, ?, ?)";
+                       database::Statement stmt(datasource, query);
+                       stmt.bind(1, id);
+                       stmt.bind(2, scope);
+                       stmt.bind(3, name);
+                       stmt.bind(4, reference);
+
+                       if (!stmt.exec()) {
+                               throw runtime::Exception("Failed to insert");
+                       }
+               }
+
+               bool enforce(DataSource& datasource, uid_t domain)
+               {
+                       int count = 0;
+                       DataType strictness = reference;
+                       std::string query = "SELECT managed_policy.value, policy_definition.name FROM managed_policy " \
+                                                               "INNER JOIN policy_definition ON managed_policy.pid = policy_definition.id " \
+                                                               "INNER JOIN admin ON managed_policy.aid = admin.id " \
+                                                               "WHERE managed_policy.pid = ? AND policy_definition.scope = ? ";
+
+                       if (domain != 0) {
+                               query += "AND admin.uid = ? ";
+                       }
+
+                       database::Statement stmt(datasource, query);
+                       stmt.bind(1, id);
+                       stmt.bind(2, scope);
+                       if (domain != 0) {
+                               stmt.bind(3, static_cast<int>(domain));
+                       }
+                       while (stmt.step()) {
+                               DataType value(stmt.getColumn(0));
+                               if (comparator(strictness, value)) {
+                                       strictness = value;
+                               }
+                               count++;
+                       }
+
+                       if (!count) {
+                               return remove(domain);
+                       }
+
+                       return insert(domain, strictness);
+               }
+
+               bool remove(uid_t domain)
+               {
+                       if (current.count(domain)) {
+                               current.erase(domain);
+                               return true;
+                       }
+
+                       return false;
+               }
+
+               int id;
+               std::string name;
+               int scope;
+               DataType reference;
+               std::unordered_map<uid_t, DataType> current;
+
+               typename PolicyComparator<DataType>::type comparator;
+       };
+
+       int scope;
+       std::recursive_mutex updateLock;
+       IVariantStorage* storage;
+};
+
+class PolicyManager {
+public:
+       PolicyManager(const std::string& base);
        ~PolicyManager();
 
        PolicyManager(const PolicyManager&) = delete;
        PolicyManager& operator=(const PolicyManager&) = delete;
 
-       void prepareGlobalPolicy();
-       void removeGlobalPolicy();
-       void prepareUserPolicy(uid_t user);
-       void removeUserPolicy(uid_t user);
+       void apply();
 
-       void populateStorage(const std::string& name, uid_t uid, bool create);
-       void removeStorage(const std::string& name, uid_t uid);
-       bool setGlobalPolicy(const std::string& pkgid, uid_t uid, const std::string& name, int value, PolicyComparator& pred);
-       bool setUserPolicy(const std::string& pkgid, uid_t uid, const std::string& name, int value, PolicyComparator& pred);
-       bool setPolicy(const std::string& client, uid_t uid, const std::string& name, int value);
-       int getGlobalPolicy(const std::string& name);
-       int getUserPolicy(const std::string& name, uid_t uid);
+       int prepareStorage(const std::string& admin, uid_t uid);
+       int removeStorage(const std::string& admin, uid_t uid);
+
+       template<typename DataType>
+       bool setGlobalPolicy(const DeviceAdministrator& admin, const std::string& policyName, DataType& value);
+
+       template<typename DataType>
+       bool setUserPolicy(const DeviceAdministrator& admin, const std::string& policyName, DataType& value);
+
+       template<typename DataType>
+       bool setPolicy(const DeviceAdministrator& admin, const std::string& policyName, DataType& value);
+
+       template<typename DataType>
+       DataType getGlobalPolicy(const std::string& policyName);
+
+       template<typename DataType>
+       DataType getUserPolicy(const std::string& policyName, uid_t uid);
 
 private:
-       std::string buildLocation(uid_t uid, const std::string& name)
-       {
-               return location + "/" + std::to_string(uid) + "/" + name;
+       void initializeStorage();
+       std::vector<uid_t> getManagedDomainList();
+
+private:
+       database::Connection connection;
+       static std::unordered_map<std::string, ManagedPolicy> managedPolicyMap;
+};
+
+template<typename DataType>
+DataType PolicyManager::getGlobalPolicy(const std::string& name)
+{
+       if (!managedPolicyMap.count(name)) {
+               throw runtime::Exception("Unknown policy: " + name);
        }
 
-       std::string buildLocation(const std::string& name)
-       {
-               return location + "/" + name;
+       ManagedPolicy& policy = managedPolicyMap[name];
+       return policy.get<DataType>(connection, 0);
+}
+
+template<typename DataType>
+DataType PolicyManager::getUserPolicy(const std::string& name, uid_t domain)
+{
+       if (!managedPolicyMap.count(name)) {
+               throw runtime::Exception("Unknown policy: " + name);
        }
 
-       bool updateClientStorage(const std::string& pkgid, uid_t uid, const std::string& name, int value);
-       int getStrictGlobalPolicy(const std::string& name, int pivot, PolicyComparator& pred);
-       int getStrictUserPolicy(const std::string& name, uid_t uid, int pivot, PolicyComparator& pred);
-       void createEffectivePolicy(const std::string& path, int value);
-       void setEffectivePolicy(const std::string& path, int value);
-       int getEffectivePolicy(const std::string& path);
-       void cleanup();
+       ManagedPolicy& policy = managedPolicyMap.at(name);
+       return policy.get<DataType>(connection, domain);
+}
 
-private:
-       std::string store;
-       std::string location;
-       std::vector<std::unique_ptr<PolicyStorage>> storageList;
-};
+template<typename DataType>
+bool PolicyManager::setUserPolicy(const DeviceAdministrator& admin,
+                                                                 const std::string& policyName, DataType& value)
+{
+       if (!managedPolicyMap.count(policyName)) {
+               throw runtime::Exception("Unknown policy: " + policyName);
+       }
+
+       ManagedPolicy& policy = managedPolicyMap.at(policyName);
+       return policy.set<DataType>(connection, admin.getName(), admin.getUid(), value);
+}
+
+template<typename DataType>
+bool PolicyManager::setGlobalPolicy(const DeviceAdministrator& admin,
+                                                                       const std::string& policyName, DataType& value)
+{
+       if (!managedPolicyMap.count(policyName)) {
+               throw runtime::Exception("Unknown policy: " + policyName);
+       }
+
+       ManagedPolicy& policy = managedPolicyMap.at(policyName);
+       return policy.set<DataType>(connection, admin.getName(), admin.getUid(), value);
+}
+
+template<typename DataType>
+bool PolicyManager::setPolicy(const DeviceAdministrator& admin, const std::string& policyName, DataType& value)
+{
+       if (!managedPolicyMap.count(policyName)) {
+               throw runtime::Exception("Unknown policy: " + policyName);
+       }
+
+       ManagedPolicy& policy = managedPolicyMap.at(policyName);
+       return policy.set<DataType>(connection, admin.getName(), admin.getUid(), value);
+}
 
 #endif //__DPM_POLICY_MANAGER_H__
diff --git a/server/policy-storage.h b/server/policy-storage.h
deleted file mode 100644 (file)
index a1a52d7..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- *  Copyright (c) 2015 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
- */
-
-#ifndef __DPM_POLICY_STORAGE_H__
-#define __DPM_POLICY_STORAGE_H__
-
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <memory>
-#include <string>
-#include <unordered_map>
-
-#include "policy.h"
-
-#include <klay/xml/document.h>
-
-class PolicyStorage {
-public:
-       typedef std::unordered_map<std::string, Policy>::iterator PolicyIterator;
-
-       PolicyStorage(const std::string& storage, const std::string& pkgid, uid_t uid, bool create = true);
-       ~PolicyStorage();
-
-       PolicyStorage(const PolicyStorage&) = delete;
-       PolicyStorage& operator=(const PolicyStorage&) = delete;
-
-       void setPolicy(const std::string& name, int value);
-       int getPolicy(const std::string& name);
-
-       bool isAssociated(uid_t uid) const
-       {
-               return (uid == user);
-       }
-
-       bool isAssociated(const std::string& pkgid, uid_t uid) const
-       {
-               return ((pkgid == owner) && (uid == user));
-       }
-
-       PolicyIterator begin()
-       {
-               return policyMap.begin();
-       }
-
-       PolicyIterator end()
-       {
-               return policyMap.end();
-       }
-
-       void flush();
-
-       void remove();
-
-private:
-       uid_t user;
-       std::string owner;
-       std::string location;
-       std::unique_ptr<xml::Document> data;
-       std::unordered_map<std::string, Policy> policyMap;
-};
-
-#endif //__DPM_POLICY_STORAGE_H__
diff --git a/server/policy.cpp b/server/policy.cpp
deleted file mode 100644 (file)
index 84f90a5..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Copyright (c) 2015 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 "policy.h"
-
-Policy::Policy(xml::Node&& node) :
-       data(std::move(node))
-{
-       updateLock.reset(new std::mutex());
-       std::string state = data.getContent();
-       value = std::stoi(state);
-}
diff --git a/server/policy.h b/server/policy.h
deleted file mode 100644 (file)
index 278d07a..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- *  Copyright (c) 2015 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
- */
-
-#ifndef __DPM_POLICY_H__
-#define __DPM_POLICY_H__
-
-#include <string>
-#include <mutex>
-#include <memory>
-
-#include <klay/xml/node.h>
-
-class Policy {
-public:
-       Policy() = delete;
-       Policy(xml::Node&& node);
-
-       int getContent() const
-       {
-               return value;
-       }
-
-       void setContent(int content)
-       {
-               updateLock->lock();
-               value = content;
-               data.setContent(std::to_string(content));
-               updateLock->unlock();
-       }
-
-private:
-       int value;
-       xml::Node data;
-       std::unique_ptr<std::mutex> updateLock;
-};
-
-#endif //__DPM_POLICY_H__
index ed481c2..f80313d 100644 (file)
@@ -101,7 +101,7 @@ int RestrictionPolicy::setCameraState(int enable)
 
 int RestrictionPolicy::getCameraState()
 {
-       return context.getPolicy("camera");
+       return context.getPolicy<int>("camera");
 }
 
 int RestrictionPolicy::setMicrophoneState(int enable)
@@ -134,7 +134,7 @@ int RestrictionPolicy::setMicrophoneState(int enable)
 
 int RestrictionPolicy::getMicrophoneState()
 {
-       return context.getPolicy("microphone");
+       return context.getPolicy<int>("microphone");
 }
 
 int RestrictionPolicy::setClipboardState(int enable)
@@ -150,7 +150,7 @@ int RestrictionPolicy::setClipboardState(int enable)
 
 int RestrictionPolicy::getClipboardState()
 {
-       return context.getPolicy("clipboard");
+       return context.getPolicy<int>("clipboard");
 }
 
 int RestrictionPolicy::setUsbDebuggingState(int enable)
@@ -166,7 +166,7 @@ int RestrictionPolicy::setUsbDebuggingState(int enable)
 
 int RestrictionPolicy::getUsbDebuggingState()
 {
-       return context.getPolicy("usb-debugging");
+       return context.getPolicy<int>("usb-debugging");
 }
 
 int RestrictionPolicy::setUsbTetheringState(bool enable)
@@ -193,7 +193,7 @@ int RestrictionPolicy::setUsbTetheringState(bool enable)
 
 bool RestrictionPolicy::getUsbTetheringState()
 {
-       return context.getPolicy("usb-tethering");
+       return context.getPolicy<int>("usb-tethering");
 }
 
 int RestrictionPolicy::setExternalStorageState(int enable)
@@ -224,7 +224,7 @@ int RestrictionPolicy::setExternalStorageState(int enable)
 
 int RestrictionPolicy::getExternalStorageState()
 {
-       return context.getPolicy("external-storage");
+       return context.getPolicy<int>("external-storage");
 }
 
 int RestrictionPolicy::setPopImapEmailState(int enable)
@@ -240,7 +240,7 @@ int RestrictionPolicy::setPopImapEmailState(int enable)
 
 int RestrictionPolicy::getPopImapEmailState()
 {
-       return context.getPolicy("popimap-email");
+       return context.getPolicy<int>("popimap-email");
 }
 
 int RestrictionPolicy::setMessagingState(const std::string& sim_id, int enable)
@@ -256,7 +256,7 @@ int RestrictionPolicy::setMessagingState(const std::string& sim_id, int enable)
 
 int RestrictionPolicy::getMessagingState(const std::string& sim_id)
 {
-       return context.getPolicy("messaging");
+       return context.getPolicy<int>("messaging");
 }
 
 int RestrictionPolicy::setBrowserState(int enable)
@@ -272,7 +272,7 @@ int RestrictionPolicy::setBrowserState(int enable)
 
 int RestrictionPolicy::getBrowserState()
 {
-       return context.getPolicy("browser");
+       return context.getPolicy<int>("browser");
 }
 
 DEFINE_POLICY(RestrictionPolicy);
index 25a3b23..61dbb51 100755 (executable)
@@ -69,7 +69,7 @@ int SecurityPolicy::lockoutScreen()
 
 int SecurityPolicy::setInternalStorageEncryption(bool encrypt)
 {
-       int policy = context.getPolicy("internal-storage-encryption");
+       int policy = context.getPolicy<int>("internal-storage-encryption");
        if ((encrypt == true) && (policy == true)) {
                return 0;
        } else if ((encrypt == false) && (policy == false)) {
@@ -97,7 +97,7 @@ int SecurityPolicy::setInternalStorageEncryption(bool encrypt)
 
 int SecurityPolicy::isInternalStorageEncrypted()
 {
-       int policy = context.getPolicy("internal-storage-encryption");
+       int policy = context.getPolicy<int>("internal-storage-encryption");
        if (policy == true) {
                return true;
        }
@@ -107,7 +107,7 @@ int SecurityPolicy::isInternalStorageEncrypted()
 
 int SecurityPolicy::setExternalStorageEncryption(bool encrypt)
 {
-       int policy = context.getPolicy("external-storage-encryption");
+       int policy = context.getPolicy<int>("external-storage-encryption");
        if ((encrypt == true) && (policy == true)) {
                return 0;
        } else if ((encrypt == false) && (policy == false)) {
@@ -135,7 +135,7 @@ int SecurityPolicy::setExternalStorageEncryption(bool encrypt)
 
 int SecurityPolicy::isExternalStorageEncrypted()
 {
-       int policy = context.getPolicy("external-storage-encryption");
+       int policy = context.getPolicy<int>("external-storage-encryption");
        if (policy == true) {
                return true;
        }
index eb42a98..a4d3a2b 100644 (file)
  *  limitations under the License
  */
 
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <unistd.h>
-
 #include <functional>
 
-#include <aul.h>
 #include <cynara-client.h>
 #include <cynara-session.h>
 
 #include "server.h"
 #include "policy-builder.h"
-#include "client-manager.h"
 
 #include "exception.h"
 #include "filesystem.h"
@@ -38,44 +31,13 @@ using namespace std::placeholders;
 namespace {
 
 const std::string POLICY_MANAGER_ADDRESS = "/tmp/.device-policy-manager.sock";
-const std::string POLICY_ACCESS_POINT_PATH = "/var/run/dpm";
-const std::string POLICY_STORAGE_PATH = "/opt/etc/dpm/policy";
-const std::string DEVICE_ADMIN_REPOSITORY = DB_PATH;
-
-std::string GetPackageId(uid_t uid, pid_t pid)
-{
-       char pkgid[PATH_MAX];
-
-       if (aul_app_get_pkgid_bypid_for_uid(pid, pkgid, PATH_MAX, uid) != 0) {
-               int fd = ::open(std::string("/proc/" + std::to_string(pid) + "/cmdline").c_str(), O_RDONLY);
-               if (fd == -1) {
-                       throw runtime::Exception("Unknown PID");
-               }
-
-               ssize_t ret, bytes = 0;
-               do {
-                       ret = ::read(fd, &pkgid[bytes], PATH_MAX);
-                       if (ret != -1) {
-                               bytes += ret;
-                       }
-               } while ((ret == -1) && (errno == EINTR));
-
-               if (ret == -1) {
-                       throw runtime::Exception("Failed to get admin info");
-               }
-
-               pkgid[bytes] = '\0';
-       }
-
-       return pkgid;
-}
+const std::string POLICY_STORAGE_PATH = "/opt/dbspace/.dpm.db";
 
 } // namespace
 
 Server::Server()
 {
-       policyManager.reset(new PolicyManager(POLICY_STORAGE_PATH, POLICY_ACCESS_POINT_PATH));
-       adminManager.reset(new DeviceAdministratorManager(DEVICE_ADMIN_REPOSITORY));
+       policyManager.reset(new PolicyManager(POLICY_STORAGE_PATH));
        service.reset(new rmi::Service(POLICY_MANAGER_ADDRESS));
 
        service->setPrivilegeChecker(std::bind(&Server::checkPeerPrivilege, this, _1, _2));
@@ -90,28 +52,10 @@ Server::~Server()
 
 void Server::run()
 {
-       policyManager->prepareGlobalPolicy();
-
-       int index = 0;
-       uid_t uids[32];
-       DeviceAdministratorManager::DeviceAdministratorList::iterator iter = adminManager->begin();
-       while (iter != adminManager->end()) {
-               int i = 0;
-               const DeviceAdministrator& admin = *iter;
-               uid_t uid = admin.getUid();
-               while ((i < index) && (uids[i] != uid)) i++;
-
-               if (i == index) {
-                       uids[index++] = uid;
-                       policyManager->prepareUserPolicy(uid);
-               }
-
-               policyManager->populateStorage(admin.getName(), admin.getUid(), true);
-               ++iter;
-       }
-
        PolicyBuild(*this);
 
+       policyManager->apply();
+
        ::umask(0);
        service->start(true);
 }
@@ -131,20 +75,6 @@ int Server::unregisterNotificationSubscriber(const std::string& name, int id)
        return service->unsubscribeNotification(name, id);
 }
 
-bool Server::setPolicy(const std::string& name, int value, const std::string& event, const std::string& info)
-{
-       uid_t uid = getPeerUid();
-       std::string pkgid = GetPackageId(uid, getPeerPid());
-       if (policyManager->setPolicy(pkgid, uid, name, value)) {
-               if (event.empty() == false) {
-                       service->notify(event, info);
-               }
-               return true;
-       }
-
-       return false;
-}
-
 bool Server::checkPeerPrivilege(const rmi::Credentials& cred, const std::string& privilege)
 {
        cynara *p_cynara;
@@ -171,19 +101,3 @@ bool Server::checkPeerPrivilege(const rmi::Credentials& cred, const std::string&
        return true;
 }
 
-int Server::enroll(const std::string& name, uid_t uid)
-{
-       adminManager->enroll(name, uid);
-       policyManager->prepareUserPolicy(uid);
-       policyManager->populateStorage(name, uid, true);
-
-       return 0;
-}
-
-int Server::disenroll(const std::string& name, uid_t uid)
-{
-       adminManager->disenroll(name, uid);
-       policyManager->removeStorage(name, uid);
-
-       return 0;
-}
index eb8357f..9d8d5f5 100644 (file)
@@ -27,8 +27,6 @@
 #include <klay/file-descriptor.h>
 #include <klay/rmi/service.h>
 
-typedef std::function<bool(const std::string&, const std::string&)> PolicyComparator;
-
 class Server {
 public:
        Server();
@@ -77,26 +75,27 @@ public:
                }
        }
 
-       bool setPolicy(const std::string& name, int value, const std::string& event, const std::string& info);
+       template<typename DataType>
+       bool setPolicy(const std::string& name, DataType& value, const std::string& event, const std::string& info);
 
-       bool setPolicy(const std::string& name, int value, const std::string& info)
+       template<typename DataType>
+       bool setPolicy(const std::string& name, DataType& value, const std::string& info)
        {
-               return setPolicy(name, value, name, info);
+               return setPolicy<DataType>(name, value, name, info);
        }
 
-       int getPolicy(const std::string& name, uid_t uid)
+       template<typename DataType>
+       DataType getPolicy(const std::string& name, uid_t uid)
        {
-               return policyManager->getGlobalPolicy(name);
+               return policyManager->getUserPolicy<DataType>(name, uid);
        }
 
-       int getPolicy(const std::string& name)
+       template<typename DataType>
+       DataType getPolicy(const std::string& name)
        {
-               return policyManager->getGlobalPolicy(name);
+               return policyManager->getGlobalPolicy<DataType>(name);
        }
 
-       int enroll(const std::string& pkgid, uid_t user);
-       int disenroll(const std::string& pkgid, uid_t user);
-
        PolicyManager& getPolicyManager()
        {
                return *policyManager;
@@ -113,9 +112,20 @@ private:
        std::string location;
 
        std::unique_ptr<PolicyManager> policyManager;
-       std::unique_ptr<DeviceAdministratorManager> adminManager;
        std::unique_ptr<rmi::Service> service;
-       std::unordered_map<std::string, PolicyComparator> policyComparators;
 };
 
+template<typename DataType>
+bool Server::setPolicy(const std::string& name, DataType& value, const std::string& event, const std::string& info)
+{
+       DeviceAdministrator admin(getPeerPid(), getPeerUid());
+       if (policyManager->setPolicy<DataType>(admin, name, value)) {
+               if (event.empty() == false) {
+                       service->notify(event, info);
+               }
+               return true;
+       }
+
+       return false;
+}
 #endif //__DPM_SERVER_H__
index 286e6a1..ad32357 100644 (file)
@@ -147,7 +147,7 @@ int WifiPolicy::setState(bool enable)
 
 bool WifiPolicy::getState()
 {
-       return context.getPolicy("wifi");
+       return context.getPolicy<int>("wifi");
 }
 
 int WifiPolicy::setHotspotState(bool enable)
@@ -175,7 +175,7 @@ int WifiPolicy::setHotspotState(bool enable)
 
 bool WifiPolicy::getHotspotState()
 {
-       return context.getPolicy("wifi-hotspot");
+       return context.getPolicy<int>("wifi-hotspot");
 }
 
 int WifiPolicy::setProfileChangeRestriction(bool enable)
@@ -201,7 +201,7 @@ int WifiPolicy::setProfileChangeRestriction(bool enable)
 
 bool WifiPolicy::isProfileChangeRestricted(void)
 {
-       return context.getPolicy("wifi-profile-change");
+       return context.getPolicy<int>("wifi-profile-change");
 }
 
 int WifiPolicy::setNetworkAccessRestriction(bool enable)
@@ -223,14 +223,14 @@ int WifiPolicy::setNetworkAccessRestriction(bool enable)
 
 bool WifiPolicy::isNetworkAccessRestricted(void)
 {
-       return context.getPolicy("wifi-ssid-restriction");
+       return context.getPolicy<int>("wifi-ssid-restriction");
 }
 
 int WifiPolicy::addSsidToBlocklist(const std::string& ssid)
 {
        try {
                blockSsidList.insert(ssid);
-               if (context.getPolicy("wifi-ssid-restriction")) {
+               if (context.getPolicy<int>("wifi-ssid-restriction")) {
                        applyBlocklistToConnectedAP();
                }
        } catch (runtime::Exception& e) {