* See the License for the specific language governing permissions and
* limitations under the License
*/
-
-
#include <regex>
#include <memory>
::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
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;
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) {
#include <iostream>
#include <gio/gio.h>
-namespace dbus{
+namespace dbus {
class Error {
public:
#include <string>
#include <gio/gio.h>
-namespace dbus{
+namespace dbus {
class Variant {
public:
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;
/**
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)
else
*result = it->next()->c_str();
- return 0;
+ return DPM_ERROR_NONE;
}
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);
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;
}
*/
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
* @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
* @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.
* 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
* @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);
/**
* @}
}
}
-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;
}
}
class ZonePolicy {
public:
+ enum State {
+ Locked = 0x01,
+ Running = 0x02,
+ };
+
ZonePolicy(PolicyControlContext& ctxt);
~ZonePolicy();
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;
--- /dev/null
+/*
+ * 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__
{
::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());
+}
#ifndef __DPM_BUNDLE_H__
#define __DPM_BUNDLE_H__
-#include <bundle.h>
-
#include <string>
+#include <vector>
+
+#include <bundle.h>
#include "exception.h"
~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);
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;
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}
* 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)
{
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;
}
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;
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());
--- /dev/null
+/*
+ * 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
SET(PC_FILE "${PROJECT_NAME}.pc")
SET(SOURCES ${DPM_LIBS}/policy-client.cpp
+ zone.cpp
package-proxy.cpp
app-proxy.cpp
zone/zone.cpp
--- /dev/null
+/*
+ * 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
#include "error.h"
#include "debug.h"
+#include "array.h"
+
#include "policy-client.h"
+#include "zone/zone.hxx"
+
+using namespace DevicePolicyManager;
DevicePolicyContext& GetDevicePolicyContext(void* handle)
{
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;
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;
+}
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;
/**
* @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, void* user_data);
/**
* @brief Adds zone event callback.
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);
+
+/**
* @}
*/
int _send_zone_create_request(appdata_s *ad)
{
char *metadata = NULL;
+ int ret;
metadata = __get_zone_metadata();
if (metadata == NULL) {
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;
}