Change to do zone provisioning not in dpm, but in libzone 36/72236/9
authorSungbae Yoo <sungbae.yoo@samsung.com>
Tue, 31 May 2016 08:21:39 +0000 (17:21 +0900)
committerSungbae Yoo <sungbae.yoo@samsung.com>
Thu, 2 Jun 2016 05:25:45 +0000 (14:25 +0900)
Change-Id: I8deb2f7370162ffdfeaf42ca19f23b2707ab1ba0
Signed-off-by: Sungbae Yoo <sungbae.yoo@samsung.com>
20 files changed:
common/auth/user.cpp
common/dbus/connection.cpp
common/dbus/error.h
common/dbus/variant.h
libs/dpm/context.h
libs/dpm/zone.cpp
libs/dpm/zone.h
libs/zone.cpp
policy/zone.hxx
policy/zone/zone.hxx [new file with mode: 0644]
server/app-bundle.cpp
server/app-bundle.h
server/mobile.cmake
server/zone.cpp
server/zone/zone.cpp [new file with mode: 0644]
zone/libs/CMakeLists.txt
zone/libs/zone.cpp [new file with mode: 0644]
zone/libs/zone/zone.cpp
zone/libs/zone/zone.h
zone/setup-wizard/src/util.c

index ce11f76..7559a31 100644 (file)
@@ -13,8 +13,6 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License
  */
-
-
 #include <regex>
 #include <memory>
 
@@ -115,7 +113,7 @@ User User::create(const std::string& name, const std::string& group_name,
 
     ::getpwnam_r(name.c_str(), &tmppwd, buf.get(), bufsize, &result);
     if (result != NULL) {
-        return User(name);
+        throw runtime::Exception("User " + name + "already exists");
     }
 
     //prepare passwd structure
index dddb99d..f609260 100644 (file)
@@ -28,13 +28,13 @@ namespace {
 
 const std::string DBUS_SYSTEM_BUS_ADDRESS = "unix:path=/var/run/dbus/system_bus_socket";
 
-void defaultCallback (GDBusConnection *connection,
-                      const gchar *sender_name,
-                      const gchar *object_path,
-                      const gchar *interface_name,
-                      const gchar *signal_name,
-                      GVariant *parameters,
-                      gpointer user_data) {
+void defaultCallback(GDBusConnection* connection,
+                     const gchar *sender_name,
+                     const gchar *object_path,
+                     const gchar *interface_name,
+                     const gchar *signal_name,
+                     GVariant *parameters,
+                     gpointer user_data) {
     Connection::signalCallback* func = reinterpret_cast<Connection::signalCallback*> (user_data);
     (*func)(Variant(parameters));
     delete func;
@@ -46,9 +46,8 @@ Connection::Connection(const std::string& address) :
      connection(nullptr)
 {
     Error error;
-    const GDBusConnectionFlags flags = static_cast<GDBusConnectionFlags>(
-        G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION
-    );
+    const GDBusConnectionFlags flags = static_cast<GDBusConnectionFlags>
+        (G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION);
 
     connection = g_dbus_connection_new_for_address_sync(address.c_str(), flags, NULL, NULL, &error);
     if (error) {
index f2fa38b..e6c7a1e 100644 (file)
@@ -20,7 +20,7 @@
 #include <iostream>
 #include <gio/gio.h>
 
-namespace dbus{
+namespace dbus {
 
 class Error {
 public:
index 3695751..360efcf 100644 (file)
@@ -20,7 +20,7 @@
 #include <string>
 #include <gio/gio.h>
 
-namespace dbus{
+namespace dbus {
 
 class Variant {
 public:
index e0048fe..9a4b01b 100644 (file)
@@ -85,7 +85,8 @@ typedef enum {
     DPM_ERROR_NOT_SUPPORTED        = TIZEN_ERROR_NOT_SUPPORTED,        /**< Operation is not supported */
     DPM_ERROR_NO_SUCH_FILE         = TIZEN_ERROR_NO_SUCH_FILE,         /**< No such file or directory */
     DPM_ERROR_FILE_EXISTS          = TIZEN_ERROR_FILE_EXISTS,          /**< File exists */
-    DPM_ERROR_OUT_OF_MEMORY        = TIZEN_ERROR_OUT_OF_MEMORY         /**< Out of memory */
+    DPM_ERROR_OUT_OF_MEMORY        = TIZEN_ERROR_OUT_OF_MEMORY,        /**< Out of memory */
+    DPM_ERROR_NO_DATA              = TIZEN_ERROR_NO_DATA               /**< No Data */
 } dpm_error_type_e;
 
 /**
index 101eebb..3236ae2 100644 (file)
@@ -55,16 +55,33 @@ int dpm_zone_destroy(dpm_zone_policy_h handle, const char* name)
     return zone.removeZone(name);
 }
 
+int dpm_zone_get_state(dpm_zone_policy_h handle, const char* name, dpm_zone_state_e *state)
+{
+    RET_ON_FAILURE(handle, DPM_ERROR_INVALID_PARAMETER);
+    RET_ON_FAILURE(name, DPM_ERROR_INVALID_PARAMETER);
+
+    DevicePolicyContext &client = GetDevicePolicyContext(handle);
+    ZonePolicy zone = client.createPolicyInterface<ZonePolicy>();
+
+    int result = zone.getZoneState(name);
+    if (result <0) {
+        return DPM_ERROR_NO_DATA;
+    }
+
+    *state = (dpm_zone_state_e)result;
+    return DPM_ERROR_NONE;
+}
+
 typedef runtime::Array<std::string> dpm_zone_iterator;
 
-dpm_zone_iterator_h dpm_zone_create_iterator(dpm_zone_policy_h handle)
+dpm_zone_iterator_h dpm_zone_create_iterator(dpm_zone_policy_h handle, dpm_zone_state_e state)
 {
     RET_ON_FAILURE(handle, NULL);
 
     DevicePolicyContext &client = GetDevicePolicyContext(handle);
     ZonePolicy zone = client.createPolicyInterface<ZonePolicy>();
 
-    return reinterpret_cast<dpm_zone_iterator_h>(new dpm_zone_iterator(zone.getZoneList()));
+    return reinterpret_cast<dpm_zone_iterator_h>(new dpm_zone_iterator(zone.getZoneList(state)));
 }
 
 int dpm_zone_iterator_next(dpm_zone_iterator_h iter, const char** result)
@@ -79,7 +96,7 @@ int dpm_zone_iterator_next(dpm_zone_iterator_h iter, const char** result)
     else
         *result = it->next()->c_str();
 
-    return 0;
+    return DPM_ERROR_NONE;
 }
 
 int dpm_zone_destroy_iterator(dpm_zone_iterator_h iter)
@@ -88,10 +105,10 @@ int dpm_zone_destroy_iterator(dpm_zone_iterator_h iter)
 
     delete reinterpret_cast<dpm_zone_iterator*>(iter);
 
-    return 0;
+    return DPM_ERROR_NONE;
 }
 
-int dpm_zone_foreach_name(dpm_zone_policy_h handle,
+int dpm_zone_foreach_name(dpm_zone_policy_h handle, dpm_zone_state_e state,
                           dpm_zone_foreach_cb callback, void* user_data)
 {
     RET_ON_FAILURE(handle, DPM_ERROR_INVALID_PARAMETER);
@@ -99,23 +116,11 @@ int dpm_zone_foreach_name(dpm_zone_policy_h handle,
 
     DevicePolicyContext &client = GetDevicePolicyContext(handle);
     ZonePolicy zone = client.createPolicyInterface<ZonePolicy>();
-    std::vector<std::string> list = zone.getZoneList();
+    std::vector<std::string> list = zone.getZoneList(state);
     for (std::vector<std::string>::iterator it = list.begin();
          it != list.end(); it++) {
         callback((*it).c_str(), user_data);
     }
 
-    return 0;
-}
-
-int dpm_zone_get_state(dpm_zone_policy_h handle, const char* name, dpm_zone_state_e *state)
-{
-    RET_ON_FAILURE(handle, DPM_ERROR_INVALID_PARAMETER);
-    RET_ON_FAILURE(name, DPM_ERROR_INVALID_PARAMETER);
-
-    //ZonePolicy& zone = GetPolicyInterface<ZonePolicy>(handle);
-
-    /* TODO : should implement */
-
-    return DPM_ERROR_INVALID_PARAMETER;
+    return DPM_ERROR_NONE;
 }
index 17146d3..aabd556 100644 (file)
@@ -124,6 +124,37 @@ DPM_API int dpm_zone_create(dpm_zone_policy_h handle, const char* name, const ch
  */
 DPM_API int dpm_zone_destroy(dpm_zone_policy_h handle, const char* name);
 
+/*
+ * @brief       Enumeration for zone state
+ * @since_tizen 3.0
+ */
+typedef enum {
+    DPM_ZONE_STATE_LOCKED       = 0x01,  /**< Zone has been defined, but it can not start. */
+    DPM_ZONE_STATE_RUNNING      = 0x02, /**< Zone has been started. */
+    DPM_ZONE_STATE_ALL          = 0xff  /**< This presents all of the state  */
+} dpm_zone_state_e;
+
+/**
+ * @brief       Gets the zone state.
+ * @details     This API can be used to get the state of the zone. The zone can
+ *              have one of the three states(running, locked).
+ * @since_tizen 3.0
+ * @param[in]   handle The zone policy handle
+ * @param[in]   name The zone name
+ * @param[out]  state The zone state
+ * @return      #DPM_ERROR_NONE on success, otherwise a negative value
+ * @retval      #DPM_ERROR_NONE Successful
+ * @retval      #DPM_ERROR_NO_DATA No such zone to get state
+ * @retval      #DPM_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval      #DPM_ERROR_TIMED_OUT Time out
+ * @pre         The handle must be created by dpm_context_acquire_zone_policy().
+ * @see         dpm_context_acquire_zone_policy()
+ * @see         dpm_context_release_zone_policy()
+ * @see         dpm_zone_create()
+ * @see         dpm_zone_destroy()
+ */
+DPM_API int dpm_zone_get_state(dpm_zone_policy_h handle, const char* name, dpm_zone_state_e *state);
+
 /**
  * @brief       The zone list iterator handle
  * @since_tizen 3.0
@@ -138,6 +169,7 @@ typedef void* dpm_zone_iterator_h;
  * @details     The zone list iterator can be used to get all defined zones.
  * @since_tizen 3.0
  * @param[in]   handle The zone policy handle
+ * @param[in]   state a combination of the zone state to look
  * @return      A zone list iterator on success, otherwise
  *              null value
  * @remark      The specific error code can be obtained by using the
@@ -156,7 +188,7 @@ typedef void* dpm_zone_iterator_h;
  * @see         dpm_zone_destroy_iterator()
  * @see         get_last_result()
  */
-DPM_API dpm_zone_iterator_h dpm_zone_create_iterator(dpm_zone_policy_h handle);
+DPM_API dpm_zone_iterator_h dpm_zone_create_iterator(dpm_zone_policy_h handle, dpm_zone_state_e state);
 
 /**
  * @brief       Fetches a zone name and forwards the iterator.
@@ -207,6 +239,7 @@ typedef void(*dpm_zone_foreach_cb)(const char* name, void *user_data);
  *              with traversing the created zones list.
  * @since_tizen 3.0
  * @param[in]   handle The zone policy handle
+ * @param[in]   state a combination of the zone state to look
  * @param[in]   callback The iteration callback function
  * @param[in]   user_data The user data passed to the callback function
  * @return      #DPM_ERROR_NONE on success, otherwise a negative value
@@ -220,38 +253,9 @@ typedef void(*dpm_zone_foreach_cb)(const char* name, void *user_data);
  * @see         dpm_zone_destroy()
  */
 DPM_API int dpm_zone_foreach_name(dpm_zone_policy_h handle,
+                                  dpm_zone_state_e state,
                                   dpm_zone_foreach_cb callback, void* user_data);
 
-/*
- * @brief       Enumeration for zone state
- * @since_tizen 3.0
- */
-typedef enum {
-    DPM_ZONE_STATE_DEFINED      = 0x01, /**< ZonePolicy has been defined, but it is not running. */
-    DPM_ZONE_STATE_RUNNING      = 0x02, /**< ZonePolicy has been started. */
-    DPM_ZONE_STATE_LOCKED       = 0x03  /**< ZonePolicy has been defined, but it can not start. */
-} dpm_zone_state_e;
-
-/**
- * @brief       Gets the zone state.
- * @details     This API can be used to get the state of the zone. The zone can
- *              have one of the three states(defined, running, locked).
- * @since_tizen 3.0
- * @param[in]   handle The zone policy handle
- * @param[in]   name The zone name
- * @param[out]  state The zone state
- * @return      #DPM_ERROR_NONE on success, otherwise a negative value
- * @retval      #DPM_ERROR_NONE Successful
- * @retval      #DPM_ERROR_NO_DATA No such zone to get state
- * @retval      #DPM_ERROR_INVALID_PARAMETER Invalid parameter
- * @retval      #DPM_ERROR_TIMED_OUT Time out
- * @pre         The handle must be created by dpm_context_acquire_zone_policy().
- * @see         dpm_context_acquire_zone_policy()
- * @see         dpm_context_release_zone_policy()
- * @see         dpm_zone_create()
- * @see         dpm_zone_destroy()
- */
-DPM_API int dpm_zone_get_state(dpm_zone_policy_h handle, const char* name, dpm_zone_state_e *state);
 
 /**
  * @}
index 7204122..0306f87 100644 (file)
@@ -63,22 +63,22 @@ int ZonePolicy::unlockZone(const std::string& name)
     }
 }
 
-std::vector<std::string> ZonePolicy::getZoneList()
+int ZonePolicy::getZoneState(const std::string& name)
 {
-    std::vector<std::string> empty;
     try {
-        return context->methodCall<std::vector<std::string>>("ZonePolicy::getZoneList");
+        return context->methodCall<int>("ZonePolicy::getZoneState", name);
     } catch (runtime::Exception& e) {
-        return empty;
+        return -1;
     }
 }
 
-int ZonePolicy::getZoneState(const std::string& name)
+std::vector<std::string> ZonePolicy::getZoneList(int state)
 {
+    std::vector<std::string> empty;
     try {
-        return context->methodCall<int>("ZonePolicy::getZoneState", name);
+        return context->methodCall<std::vector<std::string>>("ZonePolicy::getZoneList", state);
     } catch (runtime::Exception& e) {
-        return -1;
+        return empty;
     }
 }
 
index 9c05eed..947c835 100644 (file)
@@ -24,6 +24,11 @@ namespace DevicePolicyManager {
 
 class ZonePolicy {
 public:
+    enum State {
+        Locked      = 0x01,
+        Running     = 0x02,
+    };
+
     ZonePolicy(PolicyControlContext& ctxt);
     ~ZonePolicy();
 
@@ -32,9 +37,9 @@ public:
     int lockZone(const std::string& name);
     int unlockZone(const std::string& name);
 
-    std::vector<std::string> getZoneList(void);
     int getZoneState(const std::string& name);
 
+    std::vector<std::string> getZoneList(int state);
 
 private:
     PolicyControlContext& context;
diff --git a/policy/zone/zone.hxx b/policy/zone/zone.hxx
new file mode 100644 (file)
index 0000000..7b314b1
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ *  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 __ZONE_MANAGER__
+#define __ZONE_MANAGER__
+
+#include "data-type.h"
+#include "policy-context.hxx"
+
+namespace DevicePolicyManager {
+
+class ZoneManager {
+public:
+    enum State {
+        Locked      = 0x01,
+        Running     = 0x02,
+    };
+
+    ZoneManager(PolicyControlContext& ctxt);
+    ~ZoneManager();
+
+    int createZone(const std::string& name, const std::string& manifest);
+    int removeZone(const std::string& name);
+    int lockZone(const std::string& name);
+    int unlockZone(const std::string& name);
+
+    int getZoneState(const std::string& name);
+
+    std::vector<std::string> getZoneList(int state);
+
+private:
+    PolicyControlContext& context;
+};
+
+} // namespace DevicePolicyManager
+#endif // __ZONE_MANAGER__
index cec3c37..779573e 100644 (file)
@@ -38,3 +38,15 @@ void Bundle::addInternal(const std::string& key, const std::string& value)
 {
     ::bundle_add_str(handle, key.c_str(), value.c_str());
 }
+
+void Bundle::addArrayInternal(const std::string& key, const std::vector<std::string>& array)
+{
+    std::unique_ptr<const char*[]> arrayptr(new const char*[array.size()]);
+
+    int index = 0;
+    for (const std::string& data : array) {
+        arrayptr.get()[index++] = data.c_str();
+    }
+
+    ::bundle_add_str_array(handle, key.c_str(), arrayptr.get(), array.size());
+}
index 4b23974..da2ab70 100644 (file)
 #ifndef __DPM_BUNDLE_H__
 #define __DPM_BUNDLE_H__
 
-#include <bundle.h>
-
 #include <string>
+#include <vector>
+
+#include <bundle.h>
 
 #include "exception.h"
 
@@ -29,6 +30,12 @@ public:
     ~Bundle();
 
     template<typename T>
+    void add(const std::string& key, const std::vector<T>& value)
+    {
+        addArrayInternal(key, value);
+    }
+
+    template<typename T>
     void add(const std::string& key, const T& value)
     {
         addInternal(key, value);
@@ -41,6 +48,7 @@ public:
 
 private:
     void addInternal(const std::string& key, const std::string& value);
+    void addArrayInternal(const std::string& key, const std::vector<std::string>& array);
 
 private:
     bundle* handle;
index 885d4d6..f2045ff 100644 (file)
@@ -19,8 +19,9 @@ SET(POLICY      ${POLICY}
                 location.cpp
                 password.cpp
                 zone.cpp
-                               zone/app-proxy.cpp
-                               zone/package-proxy.cpp
+                zone/zone.cpp
+                zone/app-proxy.cpp
+                zone/package-proxy.cpp
 )
 
 SET(DEPENDENCY  ${DEPENDENCY}
index a146197..2ea5ecf 100644 (file)
@@ -13,7 +13,9 @@
  *  See the License for the specific language governing permissions and
  *  limitations under the License
  */
+#include <regex>
 #include <algorithm>
+
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/inotify.h>
 #include <tzplatform_config.h>
 
 #include "zone.hxx"
+#include "zone/zone.hxx"
 
 #include "error.h"
-#include "smack.h"
-#include "process.h"
-#include "packman.h"
 #include "launchpad.h"
 #include "filesystem.h"
 #include "auth/user.h"
-#include "auth/group.h"
-#include "xml/parser.h"
-#include "xml/document.h"
 #include "audit/logger.h"
-#include "dbus/connection.h"
 
-#define ZONE_UID_MIN       60001
-#define ZONE_UID_MAX       65000
+#define NAME_PATTERN "^[A-Za-z_][A-Za-z0-9_.-]*"
 
 namespace DevicePolicyManager {
 
 namespace {
 
-const std::vector<std::string> defaultGroups = {
-    "audio",
-    "video",
-    "display",
-    "log"
-};
-
-const std::vector<std::string> defaultAppDirs = {
-    "cache",
-    "data",
-    "shared"
-};
-
-const std::vector<std::string> unitsToMask = {
-    "starter.service",
-    "scim.service"
-};
-
-const std::string ZONE_MANIFEST_DIR = CONF_PATH "/zone/";
-const std::string ZONE_PROVISION_DIR = "/tmp/zone/provision/";
-
-const std::string HOME_SMACKLABEL = "User::Home";
-const std::string SHARED_SMACKLABEL = "User::App::Shared";
-const std::string APP_SMACKLABEL = "User::Pkg::";
-
-const std::string ZONE_GROUP = "users";
-
-template <typename... Args>
-inline void execute(const std::string& path, Args&&... args)
-{
-    std::vector<std::string> argsVector = { args... };
-    runtime::Process proc(path, argsVector);
-    proc.execute();
-}
-
-void waitForSetupWizard(const std::string& watch)
-{
-    int fd = ::inotify_init();
-    if (fd < 0) {
-        throw runtime::Exception("Failed to initialize inotify");
-    }
-
-    std::string createfile;
-    char inotifyBuf[sizeof (struct inotify_event) + PATH_MAX + 1];
-    struct inotify_event *event = reinterpret_cast<struct inotify_event *>((void*)inotifyBuf);
-    int wd = ::inotify_add_watch(fd, watch.c_str(), IN_CREATE);
-
-    while (createfile != ".completed") {
-        int ret = ::read(fd, inotifyBuf, sizeof(inotifyBuf));
-        if (ret < 0) {
-            throw runtime::Exception("Failed to get inotify");
-        }
-        createfile = event->name;
-    }
-
-    ::inotify_rm_watch(fd, wd);
-    ::close(fd);
+namespace {
+std::regex zoneNamePattern(NAME_PATTERN);
 }
 
-std::string prepareDirectories(const runtime::User& user)
-{
-    //create zone home directories
-    const struct {
-        enum tzplatform_variable dir;
-        const std::string& smack;
-    } dirs[] = {
-        {TZ_USER_HOME, HOME_SMACKLABEL},
-        {TZ_USER_CACHE, SHARED_SMACKLABEL},
-        {TZ_USER_APPROOT, HOME_SMACKLABEL},
-        {TZ_USER_DB, HOME_SMACKLABEL},
-        {TZ_USER_PACKAGES, HOME_SMACKLABEL},
-        {TZ_USER_ICONS, HOME_SMACKLABEL},
-        {TZ_USER_CONFIG, SHARED_SMACKLABEL},
-        {TZ_USER_DATA, HOME_SMACKLABEL},
-        {TZ_USER_SHARE, SHARED_SMACKLABEL},
-        {TZ_USER_ETC, HOME_SMACKLABEL},
-        {TZ_USER_LIVE, HOME_SMACKLABEL},
-        {TZ_USER_UG, HOME_SMACKLABEL},
-        {TZ_USER_APP, HOME_SMACKLABEL},
-        {TZ_USER_CONTENT, SHARED_SMACKLABEL},
-        {TZ_USER_CAMERA, SHARED_SMACKLABEL},
-        {TZ_USER_VIDEOS, SHARED_SMACKLABEL},
-        {TZ_USER_IMAGES, SHARED_SMACKLABEL},
-        {TZ_USER_SOUNDS, SHARED_SMACKLABEL},
-        {TZ_USER_MUSIC, SHARED_SMACKLABEL},
-        {TZ_USER_GAMES, SHARED_SMACKLABEL},
-        {TZ_USER_DOCUMENTS, SHARED_SMACKLABEL},
-        {TZ_USER_OTHERS, SHARED_SMACKLABEL},
-        {TZ_USER_DOWNLOADS, SHARED_SMACKLABEL},
-        {TZ_SYS_HOME, ""},
-    };
-
-    ::umask(0022);
-
-    ::tzplatform_set_user(user.getUid());
-
-    std::string pivot(::tzplatform_getenv(TZ_USER_HOME));
-
-    try {
-        for (int i = 0; dirs[i].dir != TZ_SYS_HOME; i++) {
-            runtime::File dir(::tzplatform_getenv(dirs[i].dir));
-            dir.makeDirectory(false, user.getUid(), user.getGid());
-            runtime::Smack::setAccess(dir, dirs[i].smack);
-            runtime::Smack::setTransmute(dir, true);
-        }
-    } catch (runtime::Exception& e) {
-        ::tzplatform_reset_user();
-        throw runtime::Exception(e.what());
+bool isAllowedName(const std::string& name) {
+    if (!std::regex_match(name, zoneNamePattern)) {
+        return false;
     }
 
-    ::tzplatform_reset_user();
-
-    return pivot;
-}
-
-void deployPackages(const runtime::User& user)
-{
+    bool exists = false;
     try {
-        //initialize package db
-        execute("/usr/bin/pkg_initdb", "pkg_initdb",
-                "--uid", std::to_string(user.getUid()));
-
-        PackageManager& packageManager = PackageManager::instance();
-        std::vector<std::string> pkgList = packageManager.getPackageList(user.getUid());
-
-        ::umask(0022);
-
-        ::tzplatform_set_user(user.getUid());
-        for (const std::string& pkgid : pkgList) {
-            std::string appbase = std::string(::tzplatform_getenv(TZ_USER_APP)) + "/" + pkgid;
-            runtime::File dir(appbase);
-            dir.makeDirectory(false, user.getUid(), user.getGid());
-            runtime::Smack::setAccess(dir, APP_SMACKLABEL + pkgid);
-            runtime::Smack::setTransmute(dir, true);
-
-            for (const std::string& subdir : defaultAppDirs) {
-                runtime::File insideDir(appbase + "/" + subdir);
-                insideDir.makeDirectory(false, user.getUid(), user.getGid());
-            }
-        }
-        ::tzplatform_reset_user();
-    } catch (runtime::Exception& e) {
-        ::tzplatform_reset_user();
-        throw runtime::Exception(e.what());
-    }
-}
-
-void maskUserServices(const std::string& pivot, const runtime::User& user)
-{
-    runtime::File unitbase(pivot + "/.config/systemd/user");
-    unitbase.makeDirectory(true);
-    unitbase.chmod(S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
-
-    for (const std::string& unit : unitsToMask) {
-        std::string target = unitbase.getPath() + "/" + unit;
-        if (::symlink("/dev/null", target.c_str()) == -1) {
-            throw runtime::Exception(runtime::GetSystemErrorMessage());
-        }
-    }
-}
-
-void setZoneState(uid_t id, int state)
-{
-    dbus::Connection& systemDBus = dbus::Connection::getSystem();
-    systemDBus.methodcall("org.freedesktop.login1",
-                          "/org/freedesktop/login1",
-                          "org.freedesktop.login1.Manager",
-                          "SetUserLinger",
-                          -1, "", "(ubb)", id, state, 1);
-}
-
-void startZoneProvisioningThread(PolicyControlContext& context, const std::string& name, const std::string& watch)
-{
-    auto provisioningWorker = [name, watch, &context]() {
-        std::unique_ptr<xml::Document> manifest;
-
-        mode_t omask = ::umask(0);
-        try {
-            waitForSetupWizard(watch);
-
-            //create zone user
-            runtime::User user = runtime::User::create(name, ZONE_GROUP, ZONE_UID_MIN, ZONE_UID_MAX);
-            for (const std::string& grp : defaultGroups) {
-                runtime::Group group(grp);
-                group.addMember(name);
-            }
-
-            std::string pivot = prepareDirectories(user);
-            maskUserServices(pivot, user);
-            deployPackages(user);
-
-            //initialize security-manager
-            execute("/usr/bin/security-manager-cmd",
-                    "security-manager-cmd", "--manage-users=add",
-                    "--uid=" + std::to_string(user.getUid()),
-                    "--usertype=normal");
-
-            //change group to system_share
-            runtime::Group systemShareGroup("system_share");
-            ::tzplatform_set_user(user.getUid());
-            runtime::File appRootDir(::tzplatform_getenv(TZ_USER_APPROOT));
-            runtime::File dbDir(::tzplatform_getenv(TZ_USER_DB));
-            ::tzplatform_reset_user();
-            appRootDir.chown(user.getUid(), systemShareGroup.getGid());
-            appRootDir.chmod(0750);
-
-            dbDir.chown(user.getUid(), systemShareGroup.getGid());
-            dbDir.chmod(0770);
-
-            manifest.reset(xml::Parser::parseFile(watch + "/manifest.xml"));
-            ::umask(0077);
-            manifest->write(ZONE_MANIFEST_DIR + name + ".xml", "UTF-8", true);
-
-            //TODO: write container owner info
-
-            //unlock the user
-            setZoneState(user.getUid(), 1);
-
-            context.notify("ZonePolicy::created", name, std::string());
-        } catch (runtime::Exception& e) {
-            ERROR(e.what());
-            context.notify("ZonePolicy::removed", name, std::string());
-        }
-
-        ::umask(omask);
-    };
-
-    std::thread asyncWork(provisioningWorker);
-    asyncWork.detach();
-}
-
-const std::string convertPathForOwner(const std::string& path, const runtime::User& user, const runtime::User& owner)
-{
-    ::tzplatform_set_user(owner.getUid());
-    std::string ownerHome(::tzplatform_getenv(TZ_USER_HOME));
-    ::tzplatform_reset_user();
-    ownerHome += "/.zone";
-
-    ::tzplatform_set_user(user.getUid());
-    std::string userHome(::tzplatform_getenv(TZ_USER_HOME));
-    ::tzplatform_reset_user();
-
-    std::string userHomeForOwner(ownerHome + "/" + user.getName());
-
-    std::string convertedPath(path);
-
-    if (convertedPath.compare(0, userHome.size(), userHome) == 0) {
-        convertedPath.replace(0, userHome.size(), userHomeForOwner);
-    }
-
-    return convertedPath;
-}
+        runtime::User user(name);
+        exists = true;
+    } catch (runtime::Exception& e) {}
 
-void prepareFileForOwner(const std::string path, const runtime::User& pkgUser, const runtime::User& owner)
-{
-    std::string pathLink = convertPathForOwner(path, pkgUser, owner);
-
-    if (path != pathLink) {
-        runtime::File linkFile(pathLink);
-        linkFile.makeBaseDirectory(pkgUser.getUid(), pkgUser.getGid());
-        if (linkFile.exists()) {
-            linkFile.remove();
-        }
-
-        int ret = ::link(path.c_str(), pathLink.c_str());
-        if (ret != 0) {
-            //TODO: copy the icon instead of linking
-            throw runtime::Exception("Failed to link from " + path +
-                                     " to " + pathLink);
-        }
-    }
+    return !exists;
 }
 
-int packageEventHandler(uid_t target_uid, int req_id,
-                        const char *pkg_type, const char *pkgid,
-                        const char *key, const char *val,
-                        const void *pmsg, void *data)
-{
-    static std::string type;
-    std::string keystr = key;
-
-    if (target_uid == tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)) {
-        return 0;
-    }
-
-    std::transform(keystr.begin(), keystr.end(), keystr.begin(), ::tolower);
-    if (keystr == "start") {
-        type = val;
-        std::transform(type.begin(), type.end(), type.begin(), ::tolower);
-        return 0;
-    } else if (keystr != "end" && keystr != "ok") {
-        return 0;
-    }
-
-    try {
-        runtime::User owner("owner"), pkgUser(target_uid);
-
-        if (type == "install" || type == "update") {
-            PackageInfo info(pkgid, pkgUser.getUid());
-            std::string icon = info.getIcon();
-            prepareFileForOwner(icon, pkgUser, owner);
-
-            for (const std::string &appid : info.getAppList()) {
-                ApplicationInfo info(appid, pkgUser.getUid());
-                std::string icon = info.getIcon();
-                prepareFileForOwner(icon, pkgUser, owner);
-            }
-        } else {
-            ::tzplatform_set_user(pkgUser.getUid());
-            std::string pkgPath(::tzplatform_getenv(TZ_USER_APP));
-            pkgPath = pkgPath + "/" + pkgid;
-            ::tzplatform_reset_user();
-
-            runtime::File pkgDirForOwner(convertPathForOwner(pkgPath, pkgUser, owner));
-            pkgDirForOwner.remove(true);
-        }
-    } catch (runtime::Exception &e) {
-        ERROR(e.what());
-    }
-
-    return 0;
 }
 
-} // namespace
-
 ZonePolicy::ZonePolicy(PolicyControlContext& ctx)
     : context(ctx)
 {
@@ -374,50 +64,40 @@ ZonePolicy::ZonePolicy(PolicyControlContext& ctx)
     context.registerParametricMethod(this, (int)(ZonePolicy::removeZone)(std::string));
     context.registerParametricMethod(this, (int)(ZonePolicy::lockZone)(std::string));
     context.registerParametricMethod(this, (int)(ZonePolicy::unlockZone)(std::string));
-    context.registerNonparametricMethod(this, (std::vector<std::string>)(ZonePolicy::getZoneList)());
     context.registerParametricMethod(this, (int)(ZonePolicy::getZoneState)(std::string));
+    context.registerParametricMethod(this, (std::vector<std::string>)(ZonePolicy::getZoneList)(int));
 
     context.createNotification("ZonePolicy::created");
     context.createNotification("ZonePolicy::removed");
-
-    PackageManager& packageManager = PackageManager::instance();
-    packageManager.setEventCallback(packageEventHandler, this);
 }
 
 ZonePolicy::~ZonePolicy()
 {
-    PackageManager& packageManager = PackageManager::instance();
-    packageManager.unsetEventCallback();
 }
 
+
 int ZonePolicy::createZone(const std::string& name, const std::string& setupWizAppid)
 {
-    std::string provisionDirPath(ZONE_PROVISION_DIR + name);
-    runtime::File provisionDir(provisionDirPath);
-
-    try {
-        if (provisionDir.exists()) {
-            provisionDir.remove(true);
-        }
+    if (!std::regex_match(name, zoneNamePattern)) {
+        return -1;
+    }
 
-        //create a directory for zone setup
-        provisionDir.makeDirectory(true);
-        runtime::Smack::setAccess(provisionDir, APP_SMACKLABEL + setupWizAppid);
+    if (!isAllowedName(name)) {
+        return -1;
+    }
 
+    try {
+        std::vector<std::string> data = {"app-id", "org.tizen.zone-setup-wizard",
+                                         "mode", "create",
+                                         "zone", name};
         Bundle bundle;
-        bundle.add("zone", name);
-        bundle.add("provisionDir", provisionDirPath);
+        bundle.add("id", "zone-create");
+        bundle.add("user-data", data);
 
         Launchpad launchpad(context.getPeerUid());
-        launchpad.launch(setupWizAppid, bundle);
-
-        startZoneProvisioningThread(context, name, provisionDirPath);
+        launchpad.launch("org.tizen.dpm-syspopup", bundle);
     } catch (runtime::Exception& e) {
         ERROR(e.what());
-
-        if (provisionDir.exists()) {
-            provisionDir.remove(true);
-        }
         return -1;
     }
 
@@ -426,48 +106,20 @@ int ZonePolicy::createZone(const std::string& name, const std::string& setupWizA
 
 int ZonePolicy::removeZone(const std::string& name)
 {
-    if (lockZone(name) != 0) {
+    if (getZoneState(name) < 0) {
         return -1;
     }
 
-    auto remove = [name, this] {
-        runtime::File manifest(ZONE_MANIFEST_DIR + name + ".xml");
-
-        try {
-            runtime::User user(name);
-
-            //remove notification for ckm-tool
-            execute("/usr/bin/ckm_tool",
-                    "ckm_tool", "-d", std::to_string(user.getUid()));
-
-            //initialize security-manager
-            execute("/usr/bin/security-manager-cmd",
-                    "security-manager-cmd",
-                    "--manage-users=remove",
-                    "--uid=" + std::to_string(user.getUid()));
-
-            //remove zone user
-            user.remove();
-            manifest.remove();
-
-            context.notify("ZonePolicy::removed", name, std::string());
-        } catch (runtime::Exception& e) {
-            ERROR(e.what());
-            return;
-        }
-    };
-
-    std::thread asyncWork(remove);
-    asyncWork.detach();
-
-    return 0;
-}
-
-int ZonePolicy::lockZone(const std::string& name)
-{
     try {
-        runtime::User user(name);
-        setZoneState(user.getUid(), 0);
+        std::vector<std::string> data = {"app-id", "org.tizen.zone-setup-wizard",
+                                         "mode", "remove",
+                                         "zone", name};
+        Bundle bundle;
+        bundle.add("id", "zone-remove");
+        bundle.add("user-data", data);
+
+        Launchpad launchpad(context.getPeerUid());
+        launchpad.launch("org.tizen.dpm-syspopup", bundle);
     } catch (runtime::Exception& e) {
         ERROR(e.what());
         return -1;
@@ -476,27 +128,27 @@ int ZonePolicy::lockZone(const std::string& name)
     return 0;
 }
 
-int ZonePolicy::unlockZone(const std::string& name)
-{
-    try {
-        runtime::User user(name);
-        setZoneState(user.getUid(), 1);
-    } catch (runtime::Exception& e) {
-        ERROR(e.what());
-        return -1;
-    }
+/* [TBD] remove dependency with zoneManager like this */
+extern ZoneManager zoneManager;
 
-    return 0;
+int ZonePolicy::lockZone(const std::string& name)
+{
+    return zoneManager.lockZone(name);
 }
 
-std::vector<std::string> ZonePolicy::getZoneList()
+int ZonePolicy::unlockZone(const std::string& name)
 {
-    return std::vector<std::string>();
+    return zoneManager.unlockZone(name);
 }
 
 int ZonePolicy::getZoneState(const std::string& name)
 {
-    return 0;
+    return zoneManager.getZoneState(name);
+}
+
+std::vector<std::string> ZonePolicy::getZoneList(int state)
+{
+    return zoneManager.getZoneList(state);
 }
 
 ZonePolicy zonePolicy(Server::instance());
diff --git a/server/zone/zone.cpp b/server/zone/zone.cpp
new file mode 100644 (file)
index 0000000..98e0035
--- /dev/null
@@ -0,0 +1,491 @@
+/*
+ *  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 <algorithm>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/inotify.h>
+
+#include <tzplatform_config.h>
+
+#include "zone/zone.hxx"
+
+#include "error.h"
+#include "smack.h"
+#include "process.h"
+#include "packman.h"
+#include "launchpad.h"
+#include "filesystem.h"
+#include "auth/user.h"
+#include "auth/group.h"
+#include "xml/parser.h"
+#include "xml/document.h"
+#include "audit/logger.h"
+#include "dbus/connection.h"
+
+#define ZONE_UID_MIN       60001
+#define ZONE_UID_MAX       65000
+
+namespace DevicePolicyManager {
+
+namespace {
+
+const std::vector<std::string> defaultGroups = {
+    "audio",
+    "video",
+    "display",
+    "log"
+};
+
+const std::vector<std::string> defaultAppDirs = {
+    "cache",
+    "data",
+    "shared"
+};
+
+const std::vector<std::string> unitsToMask = {
+    "starter.service",
+    "scim.service"
+};
+
+const std::string ZONE_MANIFEST_DIR = CONF_PATH "/zone/";
+
+const std::string HOME_SMACKLABEL = "User::Home";
+const std::string SHARED_SMACKLABEL = "User::App::Shared";
+const std::string APP_SMACKLABEL = "User::Pkg::";
+
+const std::string ZONE_GROUP = "users";
+
+template <typename... Args>
+inline void execute(const std::string& path, Args&&... args)
+{
+    std::vector<std::string> argsVector = { args... };
+    runtime::Process proc(path, argsVector);
+    proc.execute();
+}
+
+inline std::string prepareDirectories(const runtime::User& user)
+{
+    //create zone home directories
+    const struct {
+        enum tzplatform_variable dir;
+        const std::string& smack;
+    } dirs[] = {
+        {TZ_USER_HOME, HOME_SMACKLABEL},
+        {TZ_USER_CACHE, SHARED_SMACKLABEL},
+        {TZ_USER_APPROOT, HOME_SMACKLABEL},
+        {TZ_USER_DB, HOME_SMACKLABEL},
+        {TZ_USER_PACKAGES, HOME_SMACKLABEL},
+        {TZ_USER_ICONS, HOME_SMACKLABEL},
+        {TZ_USER_CONFIG, SHARED_SMACKLABEL},
+        {TZ_USER_DATA, HOME_SMACKLABEL},
+        {TZ_USER_SHARE, SHARED_SMACKLABEL},
+        {TZ_USER_ETC, HOME_SMACKLABEL},
+        {TZ_USER_LIVE, HOME_SMACKLABEL},
+        {TZ_USER_UG, HOME_SMACKLABEL},
+        {TZ_USER_APP, HOME_SMACKLABEL},
+        {TZ_USER_CONTENT, SHARED_SMACKLABEL},
+        {TZ_USER_CAMERA, SHARED_SMACKLABEL},
+        {TZ_USER_VIDEOS, SHARED_SMACKLABEL},
+        {TZ_USER_IMAGES, SHARED_SMACKLABEL},
+        {TZ_USER_SOUNDS, SHARED_SMACKLABEL},
+        {TZ_USER_MUSIC, SHARED_SMACKLABEL},
+        {TZ_USER_GAMES, SHARED_SMACKLABEL},
+        {TZ_USER_DOCUMENTS, SHARED_SMACKLABEL},
+        {TZ_USER_OTHERS, SHARED_SMACKLABEL},
+        {TZ_USER_DOWNLOADS, SHARED_SMACKLABEL},
+        {TZ_SYS_HOME, ""},
+    };
+
+    ::umask(0022);
+
+    ::tzplatform_set_user(user.getUid());
+
+    std::string pivot(::tzplatform_getenv(TZ_USER_HOME));
+
+    try {
+        for (int i = 0; dirs[i].dir != TZ_SYS_HOME; i++) {
+            runtime::File dir(::tzplatform_getenv(dirs[i].dir));
+            dir.makeDirectory(false, user.getUid(), user.getGid());
+            runtime::Smack::setAccess(dir, dirs[i].smack);
+            runtime::Smack::setTransmute(dir, true);
+        }
+    } catch (runtime::Exception& e) {
+        ::tzplatform_reset_user();
+        throw runtime::Exception(e.what());
+    }
+
+    ::tzplatform_reset_user();
+
+    return pivot;
+}
+
+inline void deployPackages(const runtime::User& user)
+{
+    try {
+        //initialize package db
+        execute("/usr/bin/pkg_initdb", "pkg_initdb",
+                "--uid", std::to_string(user.getUid()));
+
+        PackageManager& packageManager = PackageManager::instance();
+        std::vector<std::string> pkgList = packageManager.getPackageList(user.getUid());
+
+        ::umask(0022);
+
+        ::tzplatform_set_user(user.getUid());
+        for (const std::string& pkgid : pkgList) {
+            std::string appbase = std::string(::tzplatform_getenv(TZ_USER_APP)) + "/" + pkgid;
+            runtime::File dir(appbase);
+            dir.makeDirectory(false, user.getUid(), user.getGid());
+            runtime::Smack::setAccess(dir, APP_SMACKLABEL + pkgid);
+            runtime::Smack::setTransmute(dir, true);
+
+            for (const std::string& subdir : defaultAppDirs) {
+                runtime::File insideDir(appbase + "/" + subdir);
+                insideDir.makeDirectory(false, user.getUid(), user.getGid());
+            }
+        }
+        ::tzplatform_reset_user();
+    } catch (runtime::Exception& e) {
+        ::tzplatform_reset_user();
+        throw runtime::Exception(e.what());
+    }
+}
+
+inline void maskUserServices(const std::string& pivot, const runtime::User& user)
+{
+    runtime::File unitbase(pivot + "/.config/systemd/user");
+    unitbase.makeDirectory(true);
+    unitbase.chmod(S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
+
+    for (const std::string& unit : unitsToMask) {
+        std::string target = unitbase.getPath() + "/" + unit;
+        if (::symlink("/dev/null", target.c_str()) == -1) {
+            throw runtime::Exception(runtime::GetSystemErrorMessage());
+        }
+    }
+}
+
+inline void setZoneState(uid_t id, int state)
+{
+    dbus::Connection& systemDBus = dbus::Connection::getSystem();
+    systemDBus.methodcall("org.freedesktop.login1",
+                          "/org/freedesktop/login1",
+                          "org.freedesktop.login1.Manager",
+                          "SetUserLinger",
+                          -1, "", "(ubb)", id, state, 1);
+}
+
+inline const std::string convertPathForOwner(const std::string& path, const runtime::User& user, const runtime::User& owner)
+{
+    ::tzplatform_set_user(owner.getUid());
+    std::string ownerHome(::tzplatform_getenv(TZ_USER_HOME));
+    ::tzplatform_reset_user();
+    ownerHome += "/.zone";
+
+    ::tzplatform_set_user(user.getUid());
+    std::string userHome(::tzplatform_getenv(TZ_USER_HOME));
+    ::tzplatform_reset_user();
+
+    std::string userHomeForOwner(ownerHome + "/" + user.getName());
+
+    std::string convertedPath(path);
+
+    if (convertedPath.compare(0, userHome.size(), userHome) == 0) {
+        convertedPath.replace(0, userHome.size(), userHomeForOwner);
+    }
+
+    return convertedPath;
+}
+
+inline void prepareFileForOwner(const std::string path, const runtime::User& pkgUser, const runtime::User& owner)
+{
+    std::string pathLink = convertPathForOwner(path, pkgUser, owner);
+
+    if (path != pathLink) {
+        runtime::File linkFile(pathLink);
+        linkFile.makeBaseDirectory(pkgUser.getUid(), pkgUser.getGid());
+        if (linkFile.exists()) {
+            linkFile.remove();
+        }
+
+        int ret = ::link(path.c_str(), pathLink.c_str());
+        if (ret != 0) {
+            //TODO: copy the icon instead of linking
+            throw runtime::Exception("Failed to link from " + path +
+                                     " to " + pathLink);
+        }
+    }
+}
+
+int packageEventHandler(uid_t target_uid, int req_id,
+                        const char *pkg_type, const char *pkgid,
+                        const char *key, const char *val,
+                        const void *pmsg, void *data)
+{
+    static std::string type;
+    std::string keystr = key;
+
+    if (target_uid == tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)) {
+        return 0;
+    }
+
+    std::transform(keystr.begin(), keystr.end(), keystr.begin(), ::tolower);
+    if (keystr == "start") {
+        type = val;
+        std::transform(type.begin(), type.end(), type.begin(), ::tolower);
+        return 0;
+    } else if (keystr != "end" && keystr != "ok") {
+        return 0;
+    }
+
+    try {
+        runtime::User owner("owner"), pkgUser(target_uid);
+
+        if (type == "install" || type == "update") {
+            PackageInfo info(pkgid, pkgUser.getUid());
+            std::string icon = info.getIcon();
+            prepareFileForOwner(icon, pkgUser, owner);
+
+            for (const std::string &appid : info.getAppList()) {
+                ApplicationInfo info(appid, pkgUser.getUid());
+                std::string icon = info.getIcon();
+                prepareFileForOwner(icon, pkgUser, owner);
+            }
+        } else {
+            ::tzplatform_set_user(pkgUser.getUid());
+            std::string pkgPath(::tzplatform_getenv(TZ_USER_APP));
+            pkgPath = pkgPath + "/" + pkgid;
+            ::tzplatform_reset_user();
+
+            runtime::File pkgDirForOwner(convertPathForOwner(pkgPath, pkgUser, owner));
+            pkgDirForOwner.remove(true);
+        }
+    } catch (runtime::Exception &e) {
+        ERROR(e.what());
+    }
+
+    return 0;
+}
+
+} // namespace
+
+ZoneManager::ZoneManager(PolicyControlContext& ctx)
+    : context(ctx)
+{
+    context.registerParametricMethod(this, (int)(ZoneManager::createZone)(std::string, std::string));
+    context.registerParametricMethod(this, (int)(ZoneManager::removeZone)(std::string));
+    context.registerParametricMethod(this, (int)(ZoneManager::lockZone)(std::string));
+    context.registerParametricMethod(this, (int)(ZoneManager::unlockZone)(std::string));
+    context.registerParametricMethod(this, (int)(ZoneManager::getZoneState)(std::string));
+    context.registerParametricMethod(this, (std::vector<std::string>)(ZoneManager::getZoneList)(int));
+
+    context.createNotification("ZoneManager::created");
+    context.createNotification("ZoneManager::removed");
+
+    PackageManager& packageManager = PackageManager::instance();
+    packageManager.setEventCallback(packageEventHandler, this);
+}
+
+ZoneManager::~ZoneManager()
+{
+    PackageManager& packageManager = PackageManager::instance();
+    packageManager.unsetEventCallback();
+}
+
+int ZoneManager::createZone(const std::string& name, const std::string& manifest)
+{
+    auto provisioningWorker = [name, manifest, this]() {
+        std::unique_ptr<xml::Document> manifestFile;
+
+        mode_t omask = ::umask(0);
+        try {
+            //create zone user
+            runtime::User user = runtime::User::create(name,
+                                        ZONE_GROUP, ZONE_UID_MIN, ZONE_UID_MAX);
+            for (const std::string& grp : defaultGroups) {
+                runtime::Group group(grp);
+                group.addMember(name);
+            }
+
+            std::string pivot = prepareDirectories(user);
+            maskUserServices(pivot, user);
+            deployPackages(user);
+
+            //initialize security-manager
+            execute("/usr/bin/security-manager-cmd",
+                    "security-manager-cmd", "--manage-users=add",
+                    "--uid=" + std::to_string(user.getUid()),
+                    "--usertype=normal");
+
+            //change group to system_share
+            runtime::Group systemShareGroup("system_share");
+            ::tzplatform_set_user(user.getUid());
+            runtime::File appRootDir(::tzplatform_getenv(TZ_USER_APPROOT));
+            runtime::File dbDir(::tzplatform_getenv(TZ_USER_DB));
+            ::tzplatform_reset_user();
+
+            appRootDir.chown(user.getUid(), systemShareGroup.getGid());
+            appRootDir.chmod(0750);
+            dbDir.chown(user.getUid(), systemShareGroup.getGid());
+            dbDir.chmod(0770);
+
+            manifestFile.reset(xml::Parser::parseString(manifest));
+            ::umask(0077);
+            manifestFile->write(ZONE_MANIFEST_DIR + name + ".xml", "UTF-8", true);
+
+            //TODO: write container owner info
+
+            //unlock the user
+            setZoneState(user.getUid(), 1);
+
+            context.notify("ZoneManager::created", name, std::string());
+        } catch (runtime::Exception& e) {
+            ERROR(e.what());
+            context.notify("ZoneManager::removed", name, std::string());
+        }
+
+        ::umask(omask);
+    };
+
+    std::thread asyncWork(provisioningWorker);
+    asyncWork.detach();
+
+    return 0;
+}
+
+int ZoneManager::removeZone(const std::string& name)
+{
+    if (lockZone(name) != 0) {
+        return -1;
+    }
+
+    try {
+        runtime::File manifest(ZONE_MANIFEST_DIR + name + ".xml");
+        manifest.remove();
+    }  catch (runtime::Exception& e) {
+        return -1;
+    }
+
+    auto remove = [name, this] {
+        try {
+            runtime::User user(name);
+
+            //remove notification for ckm-tool
+            execute("/usr/bin/ckm_tool",
+                    "ckm_tool", "-d", std::to_string(user.getUid()));
+
+            //initialize security-manager
+            execute("/usr/bin/security-manager-cmd",
+                    "security-manager-cmd",
+                    "--manage-users=remove",
+                    "--uid=" + std::to_string(user.getUid()));
+
+            //remove zone user
+            user.remove();
+
+            context.notify("ZoneManager::removed", name, std::string());
+        } catch (runtime::Exception& e) {
+            ERROR(e.what());
+            return;
+        }
+    };
+
+    std::thread asyncWork(remove);
+    asyncWork.detach();
+
+    return 0;
+}
+
+int ZoneManager::lockZone(const std::string& name)
+{
+    try {
+        runtime::User user(name);
+        setZoneState(user.getUid(), 0);
+    } catch (runtime::Exception& e) {
+        ERROR(e.what());
+        return -1;
+    }
+
+    return 0;
+}
+
+int ZoneManager::unlockZone(const std::string& name)
+{
+    try {
+        runtime::User user(name);
+        setZoneState(user.getUid(), 1);
+    } catch (runtime::Exception& e) {
+        ERROR(e.what());
+        return -1;
+    }
+
+    return 0;
+}
+
+int ZoneManager::getZoneState(const std::string& name)
+{
+    runtime::File manifest(ZONE_MANIFEST_DIR + name + ".xml");
+    if (!manifest.exists()) {
+        return -1;
+    }
+
+    try {
+        runtime::User user(name);
+        dbus::Connection& systemDBus = dbus::Connection::getSystem();
+        const dbus::Variant& var = systemDBus.methodcall
+                                           ("org.freedesktop.login1",
+                                            "/org/freedesktop/login1",
+                                            "org.freedesktop.login1.Manager",
+                                            "GetUser",
+                                            -1, "(o)", "(u)", user.getUid());
+        if (var) {
+            return ZoneManager::State::Running;
+        } else {
+            return ZoneManager::State::Locked;
+        }
+    } catch (runtime::Exception& e) {
+        ERROR(e.what());
+        return -1;
+    }
+
+    return 0;
+}
+
+std::vector<std::string> ZoneManager::getZoneList(int state)
+{
+    std::vector<std::string> list;
+    try {
+        runtime::Path manifestDir(ZONE_MANIFEST_DIR);
+        runtime::DirectoryIterator iter(manifestDir), end;
+
+        while (iter != end) {
+            const std::string& path = iter->getPath();
+            size_t namePos = path.rfind('/') + 1;
+            size_t extPos = path.rfind(".xml");
+            const std::string& name(path.substr(namePos, extPos - namePos));
+            if (getZoneState(name) & state) {
+                list.push_back(name);
+            }
+            ++iter;
+        }
+    } catch (runtime::Exception& e) {}
+
+    return list;
+}
+
+ZoneManager zoneManager(Server::instance());
+
+} // namespace DevicePolicyManager
index d8697f4..7956bd3 100755 (executable)
@@ -21,6 +21,7 @@ SET(LIB_SOVERSION "0")
 SET(PC_FILE "${PROJECT_NAME}.pc")
 
 SET(SOURCES ${DPM_LIBS}/policy-client.cpp
+                       zone.cpp
                        package-proxy.cpp
                        app-proxy.cpp
                        zone/zone.cpp
diff --git a/zone/libs/zone.cpp b/zone/libs/zone.cpp
new file mode 100644 (file)
index 0000000..2cb762d
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ *  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 "zone/zone.hxx"
+
+namespace DevicePolicyManager {
+
+ZoneManager::ZoneManager(PolicyControlContext& ctx)
+    : context(ctx)
+{
+}
+
+ZoneManager::~ZoneManager()
+{
+}
+
+int ZoneManager::createZone(const std::string& name, const std::string& setupWizAppid)
+{
+    try {
+        return context->methodCall<int>("ZoneManager::createZone", name, setupWizAppid);
+    } catch (runtime::Exception& e) {
+        return -1;
+    }
+}
+
+int ZoneManager::removeZone(const std::string& name)
+{
+    try {
+        return context->methodCall<int>("ZoneManager::removeZone", name);
+    } catch (runtime::Exception& e) {
+        return -1;
+    }
+}
+
+int ZoneManager::lockZone(const std::string& name)
+{
+    try {
+        return context->methodCall<int>("ZoneManager::lockZone", name);
+    } catch (runtime::Exception& e) {
+        return -1;
+    }
+}
+
+int ZoneManager::unlockZone(const std::string& name)
+{
+    try {
+        return context->methodCall<int>("ZoneManager::unlockZone", name);
+    } catch (runtime::Exception& e) {
+        return -1;
+    }
+}
+
+int ZoneManager::getZoneState(const std::string& name)
+{
+    try {
+        return context->methodCall<int>("ZoneManager::getZoneState", name);
+    } catch (runtime::Exception& e) {
+        return -1;
+    }
+}
+
+std::vector<std::string> ZoneManager::getZoneList(int state)
+{
+    std::vector<std::string> empty;
+    try {
+        return context->methodCall<std::vector<std::string>>("ZoneManager::getZoneList", state);
+    } catch (runtime::Exception& e) {
+        return empty;
+    }
+}
+
+} // namespace DevicePolicyManager
index ace6c7f..97a6eda 100644 (file)
 
 #include "error.h"
 #include "debug.h"
+#include "array.h"
+
 #include "policy-client.h"
+#include "zone/zone.hxx"
+
+using namespace DevicePolicyManager;
 
 DevicePolicyContext& GetDevicePolicyContext(void* handle)
 {
@@ -59,7 +64,7 @@ int zone_manager_add_event_cb(zone_manager_h handle, const char* event, zone_eve
     RET_ON_FAILURE(callback, ZONE_ERROR_INVALID_PARAMETER);
 
     DevicePolicyContext &context = GetDevicePolicyContext(handle);
-    int ret = context.subscribeSignal(std::string("ZonePolicy::") + event,
+    int ret = context.subscribeSignal(std::string("ZoneManager::") + event,
                                       callback, user_data);
     if (ret < 0)
         return ZONE_ERROR_INVALID_PARAMETER;
@@ -80,3 +85,94 @@ int zone_manager_remove_event_cb(zone_manager_h handle, int callback_id)
 
     return ZONE_ERROR_NONE;
 }
+
+int zone_manager_create_zone(zone_manager_h handle, const char* name, const char* manifest)
+{
+    RET_ON_FAILURE(handle, ZONE_ERROR_INVALID_PARAMETER);
+    RET_ON_FAILURE(name, ZONE_ERROR_INVALID_PARAMETER);
+    RET_ON_FAILURE(manifest, ZONE_ERROR_INVALID_PARAMETER);
+
+    DevicePolicyContext &client = GetDevicePolicyContext(handle);
+    ZoneManager zone = client.createPolicyInterface<ZoneManager>();
+    return zone.createZone(name, manifest);
+}
+
+int zone_manager_destroy_zone(zone_manager_h handle, const char* name)
+{
+    RET_ON_FAILURE(handle, ZONE_ERROR_INVALID_PARAMETER);
+    RET_ON_FAILURE(name, ZONE_ERROR_INVALID_PARAMETER);
+
+    DevicePolicyContext &client = GetDevicePolicyContext(handle);
+    ZoneManager zone = client.createPolicyInterface<ZoneManager>();
+    return zone.removeZone(name);
+}
+
+int zone_manager_get_zone_state(zone_manager_h handle, const char* name, zone_state_e *state)
+{
+    RET_ON_FAILURE(handle, ZONE_ERROR_INVALID_PARAMETER);
+    RET_ON_FAILURE(name, ZONE_ERROR_INVALID_PARAMETER);
+
+    DevicePolicyContext &client = GetDevicePolicyContext(handle);
+    ZoneManager zone = client.createPolicyInterface<ZoneManager>();
+
+    int result = zone.getZoneState(name);
+    if (result <0) {
+        return ZONE_ERROR_NO_DATA;
+    }
+
+    *state = (zone_state_e)result;
+    return ZONE_ERROR_NONE;
+}
+
+typedef runtime::Array<std::string> zone_iterator;
+
+zone_iterator_h zone_manager_create_iterator(zone_manager_h handle, zone_state_e state)
+{
+    RET_ON_FAILURE(handle, NULL);
+
+    DevicePolicyContext &client = GetDevicePolicyContext(handle);
+    ZoneManager zone = client.createPolicyInterface<ZoneManager>();
+
+    return reinterpret_cast<zone_iterator_h>(new zone_iterator(zone.getZoneList(state)));
+}
+
+int zone_iterator_next(zone_iterator_h iter, const char** result)
+{
+    RET_ON_FAILURE(iter, ZONE_ERROR_INVALID_PARAMETER);
+    RET_ON_FAILURE(result, ZONE_ERROR_INVALID_PARAMETER);
+
+    zone_iterator* it = reinterpret_cast<zone_iterator*>(iter);
+
+    if (it->isEnd())
+        *result = NULL;
+    else
+        *result = it->next()->c_str();
+
+    return ZONE_ERROR_NONE;
+}
+
+int zone_manager_destroy_iterator(zone_iterator_h iter)
+{
+    RET_ON_FAILURE(iter, ZONE_ERROR_INVALID_PARAMETER);
+
+    delete reinterpret_cast<zone_iterator*>(iter);
+
+    return ZONE_ERROR_NONE;
+}
+
+int zone_manager_foreach_name(zone_manager_h handle, zone_state_e state,
+                          zone_manager_foreach_cb callback, void* user_data)
+{
+    RET_ON_FAILURE(handle, ZONE_ERROR_INVALID_PARAMETER);
+    RET_ON_FAILURE(callback, ZONE_ERROR_INVALID_PARAMETER);
+
+    DevicePolicyContext &client = GetDevicePolicyContext(handle);
+    ZoneManager zone = client.createPolicyInterface<ZoneManager>();
+    std::vector<std::string> list = zone.getZoneList(state);
+    for (std::vector<std::string>::iterator it = list.begin();
+         it != list.end(); it++) {
+        callback((*it).c_str(), user_data);
+    }
+
+    return ZONE_ERROR_NONE;
+}
index e4b13fc..bde0220 100644 (file)
@@ -58,7 +58,8 @@ typedef enum {
     ZONE_ERROR_NOT_SUPPORTED        = TIZEN_ERROR_NOT_SUPPORTED,        /**< Operation is not supported */
     ZONE_ERROR_NO_SUCH_FILE         = TIZEN_ERROR_NO_SUCH_FILE,         /**< No such file or directory */
     ZONE_ERROR_FILE_EXISTS          = TIZEN_ERROR_FILE_EXISTS,          /**< File exists */
-    ZONE_ERROR_OUT_OF_MEMORY        = TIZEN_ERROR_OUT_OF_MEMORY         /**< Out of memory */
+    ZONE_ERROR_OUT_OF_MEMORY        = TIZEN_ERROR_OUT_OF_MEMORY,        /**< Out of memory */
+    ZONE_ERROR_NO_DATA              = TIZEN_ERROR_NO_DATA               /**< No Data */
 } zone_error_type_e;
 
 /**
@@ -116,7 +117,7 @@ ZONE_API int zone_manager_destroy(zone_manager_h handle);
  * @see         zone_manager_add_event_cb()
  * @see         zone_manager_remove_event_cb()
  */
-typedef void(*zone_event_cb)(const char* name, const char* object, void *user_data);
+typedef void(*zone_event_cb)(const char* name, const char* object, voiduser_data);
 
 /**
  * @brief       Adds zone event callback.
@@ -161,6 +162,186 @@ ZONE_API int zone_manager_add_event_cb(zone_manager_h handle,
 ZONE_API int zone_manager_remove_event_cb(zone_manager_h handle, int id);
 
 /**
+ * @brief       Creates a new zone.
+ * @details     This API creates a container. All file system objects neeeded
+ *              will be also created. manifest XML passed by parameter will be
+ *              used when the zone is running.
+ * @since_tizen 3.0
+ * @param[in]   handle The zone manager handle
+ * @param[in]   name The zone name to be created
+ * @param[in]   manifest The manifest XML to be used when the zone is runned.
+ * @return      #ZONE_ERROR_NONE on success, otherwise a negative value
+ * @retval      #ZONE_ERROR_NONE Successful
+ * @retval      #ZONE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval      #ZONE_ERROR_TIMED_OUT Time out
+ * @retval      #ZONE_ERROR_PERMISSION_DENIED The application does not have
+ *              the privilege to call this API
+ * @pre         The handle must be created by zone_manager_create().
+ * @see         zone_manager_create()
+ * @see         zone_manager_destroy()
+ * @see         zone_manager_destroy_zone()
+ * @see         zone_manager_create_zone_iterator()
+ */
+ZONE_API int zone_manager_create_zone(zone_manager_h handle, const char* name, const char* manifest);
+
+/**
+ * @brief       Removes existing zone.
+ * @details     This removes zone. All file system objects created for the zone
+ *              will be also erased.
+ * @since_tizen 3.0
+ * @param[in]   handle The zone manager handle
+ * @param[in]   name The zone name to be removed
+ * @return      #ZONE_ERROR_NONE on success, otherwise a negative value
+ * @retval      #ZONE_ERROR_NONE Successful
+ * @retval      #ZONE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval      #ZONE_ERROR_TIMED_OUT Time out
+ * @retval      #ZONE_ERROR_PERMISSION_DENIED The application does not have
+ *              the privilege to call this API or the caller is not the owner
+ *              of the zone
+ * @pre         The handle must be created by zone_manager_create().
+ * @pre         The zone corresponding to the given name must be
+ *              created before use of this API.
+ * @see         zone_manager_create()
+ * @see         zone_manager_destroy()
+ * @see         zone_manager_create_zone()
+ * @see         zone_manager_create_zone_iterator()
+ */
+ZONE_API int zone_manager_destroy_zone(zone_manager_h handle, const char* name);
+
+/*
+ * @brief       Enumeration for zone state
+ * @since_tizen 3.0
+ */
+typedef enum {
+    ZONE_STATE_LOCKED       = 0x01,  /**< Zone has been defined, but it can not start. */
+    ZONE_STATE_RUNNING      = 0x02, /**< Zone has been started. */
+    ZONE_STATE_ALL          = 0xff  /**< This presents all of the state  */
+} zone_state_e;
+
+/**
+ * @brief       Gets the zone state.
+ * @details     This API can be used to get the state of the zone. The zone can
+ *              have one of the three states(running, locked).
+ * @since_tizen 3.0
+ * @param[in]   handle The zone policy handle
+ * @param[in]   name The zone name
+ * @param[out]  state The zone state
+ * @return      #ZONE_ERROR_NONE on success, otherwise a negative value
+ * @retval      #ZONE_ERROR_NONE Successful
+ * @retval      #ZONE_ERROR_NO_DATA No such zone to get state
+ * @retval      #ZONE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval      #ZONE_ERROR_TIMED_OUT Time out
+ * @pre         The handle must be created by zone_manager_create().
+ * @see         zone_manager_create()
+ * @see         zone_manager_destroy()
+ * @see         zone_manager_create_zone()
+ * @see         zone_manager_destroy_zone()
+ */
+ZONE_API int zone_manager_get_zone_state(zone_manager_h handle, const char* name, zone_state_e* state);
+
+/**
+ * @brief       The zone list iterator handle
+ * @since_tizen 3.0
+ * @see         zone_manager_create_zone_terator()
+ * @see         zone_iterator_next()
+ * @see         zone_iterator_destroy()
+ */
+typedef void* zone_iterator_h;
+
+/**
+ * @brief       Creates a zone list iterator.
+ * @details     The zone list iterator can be used to get all defined zones.
+ * @since_tizen 3.0
+ * @param[in]   handle The zone policy handle
+ * @param[in]   state a combination of the zone state to look
+ * @return      A zone list iterator on success, otherwise
+ *              null value
+ * @remark      The specific error code can be obtained by using the
+ *              get_last_result() method. Error codes are described in
+ *              exception section.
+ * @exception   #ZONE_ERROR_NONE No error
+ * @exception   #ZONE_ERROR_OUT_OF_MEMORY Out of memory
+ * @exception   #ZONE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @exception   #ZONE_ERROR_TIMED_OUT Time out
+ * @pre         The handle must be created by zone_manager_create().
+ * @see         zone_manager_create()
+ * @see         zone_manager_destroy()
+ * @see         zone_manager_create_zone()
+ * @see         zone_manager_destroy_zone()
+ * @see         zone_iterator_next()
+ * @see         zone_interator_destroy()
+ * @see         get_last_result()
+ */
+ZONE_API zone_iterator_h zone_manager_create_zone_iterator(zone_manager_h handle, zone_state_e state);
+
+/**
+ * @brief       Fetches a zone name and forwards the iterator.
+ * @details     This API returns zone name indicated by the iterator, and then
+ *              the iterator is moved to the next position. If the iterator reaches
+ *              the end of the list, null value will be returned.
+ * @since_tizen 3.0
+ * @param[in]   iter The iterator to be controlled
+ * @param[out]  zone_name The zone name got from the iterator
+ * @return      #ZONE_ERROR_NONE on success, otherwise a negative value
+ * @retval      #ZONE_ERROR_NONE Successful
+ * @retval      #ZONE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval      #ZONE_ERROR_TIMED_OUT Time out
+ * @pre         The iter must be created by zone_manager_create_iterator().
+ * @see         zone_manager_create_zone_iterator()
+ * @see         zone_interator_destroy()
+ */
+ZONE_API int zone_iterator_next(zone_iterator_h iter, const char** zone_name);
+
+/**
+ * @brief       Frees the zone iterator.
+ * @details     This API frees the zone iterator. This API must be called
+ *              if the iterator no longer used.
+ * @since_tizen 3.0
+ * @param[in]   iter The iterator to be removed
+ * @return      #ZONE_ERROR_NONE on success, otherwise a negative value
+ * @retval      #ZONE_ERROR_NONE Successful
+ * @retval      #ZONE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval      #ZONE_ERROR_TIMED_OUT Time out
+ * @pre         The iter must be created by zone_manager_create_iterator()
+ * @see         zone_manager_create_zone_iterator()
+ * @see         zone_iterator_next()
+ */
+ZONE_API int zone_iterator_destroy(zone_iterator_h iter);
+
+/**
+ * @brief       Called to get all the name of created zones.
+ * @since_tizen 3.0
+ * @param[in]   name The zone name
+ * @param[in]   user_data The user data passed from zone_manager_foreach_name
+ * @see         zone_manager_foreach_name()
+ */
+typedef void(*zone_manager_foreach_cb)(const char* name, void* user_data);
+
+/**
+ * @brief       Retrieves all the name of created zones
+ * @details     This API calls zone_manager_foreach_cb() once for each zone name
+ *              with traversing the created zones list.
+ * @since_tizen 3.0
+ * @param[in]   handle The zone policy handle
+ * @param[in]   state a combination of the zone state to look
+ * @param[in]   callback The iteration callback function
+ * @param[in]   user_data The user data passed to the callback function
+ * @return      #ZONE_ERROR_NONE on success, otherwise a negative value
+ * @retval      #ZONE_ERROR_NONE Successful
+ * @retval      #ZONE_ERROR_TIMED_OUT Time out
+ * @retval      #ZONE_ERROR_INVALID_PARAMETER Invalid parameter
+ * @pre         The handle must be created by zone_manager_create().
+ * @see         zone_manager_create()
+ * @see         zone_manager_destroy()
+ * @see         zone_manager_create_zone()
+ * @see         zone_manager_destroy_zone()
+ */
+ZONE_API int zone_manager_foreach_name(zone_manager_h handle,
+                                       zone_state_e state,
+                                       zone_manager_foreach_cb callback,
+                                       void* user_data);
+
+/**
  * @}
  */
 
index 2c845a7..a30112f 100644 (file)
@@ -83,6 +83,7 @@ static char *__get_zone_metadata(void)
 int _send_zone_create_request(appdata_s *ad)
 {
        char *metadata = NULL;
+        int ret;
 
        metadata = __get_zone_metadata();
        if (metadata == NULL) {
@@ -90,14 +91,22 @@ int _send_zone_create_request(appdata_s *ad)
                return -1;
        }
 
-       /* [TBD] */
+       ret = zone_manager_create_zone(ad->zone_manager, ad->zone_name, metadata);
+       if (ret != ZONE_ERROR_NONE) {
+               return -1;
+       }
 
        return 0;
 }
 
 int _send_zone_remove_request(appdata_s *ad)
 {
-       /* [TBD] */
+       int ret;
+
+       ret = zone_manager_destroy_zone(ad->zone_manager, ad->zone_name);
+       if (ret != ZONE_ERROR_NONE) {
+               return -1;
+       }
 
        return 0;
 }