From: Sungbae Yoo Date: Fri, 1 Jul 2016 09:39:27 +0000 (+0900) Subject: Change user-creation to use gumd X-Git-Tag: accepted/tizen/common/20160706.142558~7 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=cbd33f67c59be82329eb9300fe2b59808267d794;p=platform%2Fcore%2Fsecurity%2Fdevice-policy-manager.git Change user-creation to use gumd Change-Id: I3c5c994ecf61adba1e8c5406199fb01385a66270 Signed-off-by: Sungbae Yoo --- diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index a727335..f5d4a29 100755 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -17,7 +17,6 @@ PROJECT(dpm-common) SET (COMMON_SOURCES ${DPM_COMMON}/error.cpp - ${DPM_COMMON}/smack.cpp ${DPM_COMMON}/process.cpp ${DPM_COMMON}/eventfd.cpp ${DPM_COMMON}/mainloop.cpp @@ -42,7 +41,6 @@ SET (COMMON_SOURCES ${DPM_COMMON}/error.cpp ${DPM_COMMON}/db/connection.cpp ${DPM_COMMON}/auth/user.cpp ${DPM_COMMON}/auth/group.cpp - ${DPM_COMMON}/auth/shadow.cpp ${DPM_COMMON}/dbus/error.cpp ${DPM_COMMON}/dbus/variant.cpp ${DPM_COMMON}/dbus/connection.cpp @@ -54,7 +52,6 @@ ADD_LIBRARY(${PROJECT_NAME} STATIC ${COMMON_SOURCES}) PKG_CHECK_MODULES(COMMON_DEPS REQUIRED libxml-2.0 sqlite3 - libsmack gio-2.0 ) diff --git a/common/auth/group.cpp b/common/auth/group.cpp index 0a2644f..7bb8497 100644 --- a/common/auth/group.cpp +++ b/common/auth/group.cpp @@ -28,12 +28,6 @@ #include "shadow.h" #include "exception.h" -#define GROUP_DIR_PATH "/etc/" -#define GROUP_FILE_NAME "group" -#define GSHADOW_FILE_NAME "gshadow" - -#define NAME_PATTERN "^[A-Za-z_][A-Za-z0-9_.-]*" - namespace runtime { Group::Group(const Group& group) : @@ -86,150 +80,4 @@ Group::Group() : { } - -static std::regex groupNamePattern(NAME_PATTERN); - -Group Group::create(const std::string& name, const gid_t min, const gid_t max) -{ - struct group group, tmpgrp, *result; - struct sgrp sgrp; - int bufsize; - - bufsize = sysconf(_SC_GETGR_R_SIZE_MAX); - if (bufsize == -1) - bufsize = 16384; - - std::unique_ptr buf(new char[bufsize]); - ::getgrnam_r(name.c_str(), &tmpgrp, buf.get(), bufsize, &result); - if (result != NULL) { - return Group(name); - } - - if (!std::regex_match(name, groupNamePattern)) { - throw runtime::Exception("Invalid group name : " + name); - } - - //prepare group structure - std::unique_ptr - gr_name(::strdup(name.c_str()), ::free), - gr_passwd(::strdup("x"), ::free); - - group.gr_name = gr_name.get(); - group.gr_passwd = gr_passwd.get(); - group.gr_mem = NULL; - - //prepare gshadow structure - std::unique_ptr - sg_namp(::strdup(name.c_str()), ::free), - sg_passwd(::strdup("!"), ::free); - - sgrp.sg_namp = sg_namp.get(); - sgrp.sg_passwd = sg_passwd.get(); - sgrp.sg_adm = NULL; - sgrp.sg_mem = NULL; - - //prepare gid - get free gid - for (group.gr_gid = min; group.gr_gid <= max; group.gr_gid++) { - ::getgrgid_r(group.gr_gid, &tmpgrp, buf.get(), bufsize, &result); - if (result == NULL) { - break; - } - } - - if (group.gr_gid > max) { - throw runtime::Exception("Too many groups"); - } - - Shadow::putGroup(GROUP_DIR_PATH GROUP_FILE_NAME, group); - Shadow::putGshadow(GROUP_DIR_PATH GSHADOW_FILE_NAME, sgrp); - - return Group(name); -} - -void Group::remove() -{ - if (gid == INVALID_GID) { - throw runtime::Exception("Group is already removed"); - } - - Shadow::foreachGroup(GROUP_DIR_PATH GROUP_FILE_NAME, - [this](const struct group & grp) -> bool { - return grp.gr_gid != gid; - }); - Shadow::foreachGshadow(GROUP_DIR_PATH GSHADOW_FILE_NAME, - [this](const struct sgrp & sgrp) -> bool { - return sgrp.sg_namp != name; - }); - - name = ""; - gid = INVALID_GID; -} - -void Group::addMember(const std::string& name) -{ - char ** members = NULL; - std::unique_ptr - member(::strdup(name.c_str()), ::free); - - Shadow::foreachGroup(GROUP_DIR_PATH GROUP_FILE_NAME, - [&member, &members, this](struct group & grp) -> bool { - if (grp.gr_gid == gid) { - int len = 0; - - if (grp.gr_mem) - for (len = 0; grp.gr_mem[len]; len++); - - if (members) - delete [] members; - - members = new char * [len + 22]; - - for (int i = 0; i < len; i++) - members[i] = grp.gr_mem[i]; - members[len] = member.get(); - members[len + 1] = NULL; - - grp.gr_mem = members; - } - return true; - }); - - if (members) - delete [] members; -} - -void Group::removeMember(const std::string& name) -{ - char ** members = NULL; - - Shadow::foreachGroup(GROUP_DIR_PATH GROUP_FILE_NAME, - [&name, &members, this](struct group & grp) -> bool { - if (grp.gr_gid == gid) { - int len = 0; - - if (grp.gr_mem) - for (; grp.gr_mem[len]; len++); - - if (members) - delete [] members; - - members = new char * [len + 1]; - - for (int i = 0; i <= len; i++) - members[i] = NULL; - - for (int i = 0, j = 0; i < len; i++) { - if (grp.gr_mem[i] != name) - members[j++] = grp.gr_mem[i]; - } - - grp.gr_mem = members; - } - return true; - }); - - if (members) - delete [] members; -} - } // namespace Shadow diff --git a/common/auth/group.h b/common/auth/group.h index 1862c53..544dbca 100644 --- a/common/auth/group.h +++ b/common/auth/group.h @@ -44,12 +44,6 @@ public: return gid; } - static Group create(const std::string& name, const gid_t min = 100, const gid_t max = 65000); - void remove(); - - void addMember(const std::string& name); - void removeMember(const std::string& name); - private: std::string name; gid_t gid; diff --git a/common/auth/shadow.cpp b/common/auth/shadow.cpp deleted file mode 100644 index 66745e8..0000000 --- a/common/auth/shadow.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -#include -#include -#include - -#include -#include -#include - -#include "smack.h" -#include "shadow.h" -#include "exception.h" -#include "filesystem.h" -#include "audit/logger.h" - -namespace runtime { - -//PwdFileLock -class PwdFileLock final { -public: - PwdFileLock(); - ~PwdFileLock(); - -private: - std::unique_lock lock; - static std::mutex mutex; -}; - -std::mutex PwdFileLock::mutex; - -PwdFileLock::PwdFileLock() : - lock(mutex) -{ - if (::seteuid(0) != 0) { - throw runtime::Exception("failed to change euid"); - } - - if (::lckpwdf() != 0) { - throw runtime::Exception("shadow file lock error"); - } -} - -PwdFileLock::~PwdFileLock() -{ - if (::ulckpwdf() != 0) { - throw runtime::Exception("shadow file unlock error"); - } - - if (::seteuid(getuid()) != 0) { - throw runtime::Exception("failed to change euid"); - } -} - -//Shadow -template -void Shadow::put(const std::string& filename, const pwdStruct& pwd, - std::function put) -{ - PwdFileLock pwdLock; - - std::unique_ptr fp_pwd - (::fopen(filename.c_str(), "a"), &::fclose); - - if (fp_pwd.get() == NULL) { - throw runtime::Exception("shadow file open error"); - } - - if (put(&pwd, fp_pwd.get())) { - throw runtime::Exception("shadow file write error"); - } - - fp_pwd.reset(); -} - -template -void Shadow::foreach(const std::string& filename, - std::function put, - std::function get, - std::function check) -{ - std::string tmpfilename = filename + ".tmp"; - pwdStruct* ppwd; - mode_t old_mask; - struct stat st; - - old_mask = ::umask(0777); - - std::unique_ptr fp_tmp_pwd( - ::fopen(tmpfilename.c_str(), "w"), - [](FILE * fp) { - if (fp == NULL) { - return; - } - ::fclose(fp); - }); - - ::umask(old_mask); - - if (fp_tmp_pwd.get() == NULL) { - throw runtime::Exception("Tmp file for shadow create error"); - } - - if (::stat(filename.c_str(), &st) != 0) { - throw runtime::Exception("shadow file information get error"); - } - - PwdFileLock pwdLock; - - std::unique_ptr fp_pwd( - ::fopen(filename.c_str(), "r"), - [](FILE * fp) { - if (fp == NULL) { - return; - } - ::fclose(fp); - }); - - if (fp_pwd.get() == NULL) { - throw runtime::Exception("shadow file open error"); - } - - for (ppwd = get(fp_pwd.get()); ppwd != NULL; ppwd = get(fp_pwd.get())) - if (check(*ppwd)) - if (put(ppwd, fp_tmp_pwd.get()) != 0) { - throw runtime::Exception("Tmp file for shadow write error"); - } - - fp_pwd.reset(); - - ::fflush(fp_tmp_pwd.get()); - - if (::chown(tmpfilename.c_str(), 0, 0) != 0) { - throw runtime::Exception("Shadow file chown error"); - } - - if (::chmod(tmpfilename.c_str(), st.st_mode) != 0) { - throw runtime::Exception("Shadow file chmod error"); - } - - runtime::File tmpfile(tmpfilename); - runtime::Smack::setAccess(tmpfile, "_"); - - if (::rename(tmpfilename.c_str(), filename.c_str()) != 0) { - throw runtime::Exception("shadow file update error"); - } -} - - -void Shadow::putPasswd(const std::string& filename, const struct passwd& ent) -{ - put(filename, ent, putpwent); -} - -void Shadow::putShadow(const std::string& filename, const struct spwd& ent) -{ - put(filename, ent, putspent); -} - -void Shadow::putGroup(const std::string& filename, const struct group& ent) -{ - put(filename, ent, putgrent); -} - -void Shadow::putGshadow(const std::string& filename, const struct sgrp& ent) -{ - put(filename, ent, putsgent); -} - - -void Shadow::foreachPasswd(const std::string& filename, std::function check) -{ - foreach(filename, putpwent, fgetpwent, check); -} - -void Shadow::foreachShadow(const std::string& filename, std::function check) -{ - foreach(filename, putspent, fgetspent, check); -} - -void Shadow::foreachGroup(const std::string& filename, std::function check) -{ - foreach(filename, putgrent, fgetgrent, check); -} - -void Shadow::foreachGshadow(const std::string& filename, std::function check) -{ - foreach(filename, putsgent, fgetsgent, check); -} - -} // namespace runtime diff --git a/common/auth/shadow.h b/common/auth/shadow.h deleted file mode 100644 index d3c0863..0000000 --- a/common/auth/shadow.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -#ifndef __RUNTIME_SHADOW_H__ -#define __RUNTIME_SHADOW_H__ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -namespace runtime { - -class Shadow final { -public: - Shadow() = delete; - Shadow(Shadow&&) = delete; - Shadow(const Shadow&) = delete; - - Shadow& operator=(const Shadow&) = delete; - Shadow& operator=(Shadow &&) = delete; - - static void putPasswd(const std::string& filename, const struct passwd& ent); - static void putShadow(const std::string& filename, const struct spwd& ent); - static void putGroup(const std::string& filename, const struct group& ent); - static void putGshadow(const std::string& filename, const struct sgrp& ent); - - static void foreachPasswd(const std::string& filename, std::function check); - static void foreachShadow(const std::string& filename, std::function check); - static void foreachGroup(const std::string& filename, std::function check); - static void foreachGshadow(const std::string& filename, std::function check); - -private: - template - static void put(const std::string& filename, const pwdStruct& pwd, - std::function put); - - template - static void foreach(const std::string& filename, - std::function put, - std::function get, - std::function check); -}; - -} // namespace runtime - -#endif //__RUNTIME_SHADOW_H__ diff --git a/common/auth/user.cpp b/common/auth/user.cpp index 7559a31..c1a8e01 100644 --- a/common/auth/user.cpp +++ b/common/auth/user.cpp @@ -28,15 +28,6 @@ #include "filesystem.h" #include "exception.h" -#define PASSWD_DIR_PATH "/etc/" -#define PASSWD_FILE_NAME "passwd" -#define SHADOW_FILE_NAME "shadow" - -#define HOMEDIR_PATH "/home" -#define SHELL_PATH "/bin/bash" - -#define NAME_PATTERN "^[A-Za-z_][A-Za-z0-9_.-]*" - namespace runtime { User::User(const User& user) : @@ -90,119 +81,4 @@ User::User() : { } - -static std::regex userNamePattern(NAME_PATTERN); - -User User::create(const std::string& name, const std::string& group_name, - const uid_t min, const uid_t max) -{ - runtime::File home(HOMEDIR_PATH "/" + name); - struct passwd pwd, tmppwd, *result; - struct spwd spwd; - int bufsize; - - if (!std::regex_match(name, userNamePattern)) { - throw runtime::Exception("Invalid user name : " + name); - } - - bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); - if (bufsize == -1) - bufsize = 16384; - - std::unique_ptr buf(new char[bufsize]); - - ::getpwnam_r(name.c_str(), &tmppwd, buf.get(), bufsize, &result); - if (result != NULL) { - throw runtime::Exception("User " + name + "already exists"); - } - - //prepare passwd structure - std::unique_ptr - pw_name(::strdup(name.c_str()), ::free), - pw_passwd(::strdup("x"), ::free), - pw_gecos(::strdup(""), ::free), - pw_dir(::strdup(home.getPath().c_str()), ::free), - pw_shell(::strdup(SHELL_PATH), ::free); - - pwd.pw_name = pw_name.get(); - pwd.pw_passwd = pw_passwd.get(); - pwd.pw_gecos = pw_gecos.get(); - pwd.pw_dir = pw_dir.get(); - pwd.pw_shell = pw_shell.get(); - - //prepare passwd structure - std::unique_ptr - sp_namp(::strdup(name.c_str()), ::free), - sp_pwdp(::strdup("!"), ::free); - spwd.sp_namp = sp_namp.get(); - spwd.sp_pwdp = sp_pwdp.get(); - spwd.sp_lstchg = (long) time((time_t*) 0) / (24 * 60 * 60); - spwd.sp_min = 0; - spwd.sp_max = 99999; - spwd.sp_warn = 7; - spwd.sp_inact = -1; - spwd.sp_expire = -1; - spwd.sp_flag = -1; - - - //get free uid - for (pwd.pw_uid = min; pwd.pw_uid <= max; pwd.pw_uid++) { - ::getpwuid_r(pwd.pw_uid, &tmppwd, buf.get(), bufsize, &result); - if (result == NULL) { - break; - } - } - - if (pwd.pw_uid > max) { - throw runtime::Exception("Too many users"); - } - - pwd.pw_gid = Group::create(group_name).getGid(); - - Shadow::putPasswd(PASSWD_DIR_PATH PASSWD_FILE_NAME, pwd); - Shadow::putShadow(PASSWD_DIR_PATH SHADOW_FILE_NAME, spwd); - - try { - home.remove(true); - } catch (runtime::Exception& e) {} - - return User(name); -} - -void User::remove() -{ - runtime::File home(HOMEDIR_PATH "/" + name); - - if (uid == INVALID_UID) { - throw runtime::Exception("User is already removed"); - } - - Shadow::foreachPasswd(PASSWD_DIR_PATH PASSWD_FILE_NAME, - [this](const struct passwd & pwd) -> bool { - return pwd.pw_uid != uid; - }); - Shadow::foreachShadow(PASSWD_DIR_PATH SHADOW_FILE_NAME, - [this](const struct spwd & spwd) -> bool { - return spwd.sp_namp != name; - }); - - try { - home.remove(true); - } catch (runtime::Exception& e) {} - - int ngroups = 0; - getgrouplist(name.c_str(), gid, NULL, &ngroups); - - std::unique_ptr groups(new gid_t[ngroups]); - getgrouplist(name.c_str(), gid, groups.get(), &ngroups); - - for (int i = 0; i < ngroups; i++) { - Group grp(groups.get()[i]); - grp.removeMember(name); - } - - name = ""; - uid = INVALID_UID; -} - } // namespace runtime diff --git a/common/auth/user.h b/common/auth/user.h index 4fcb623..09e12ba 100644 --- a/common/auth/user.h +++ b/common/auth/user.h @@ -49,10 +49,6 @@ public: return gid; } - static User create(const std::string& name, const std::string& group, - const uid_t min = 5000, const uid_t max = 65000); - void remove(); - private: std::string name; uid_t uid; diff --git a/common/filesystem.cpp b/common/filesystem.cpp index 748f30f..51a4841 100755 --- a/common/filesystem.cpp +++ b/common/filesystem.cpp @@ -30,7 +30,6 @@ #include #include "filesystem.h" -#include "smack.h" #include "error.h" #include "exception.h" @@ -390,10 +389,6 @@ File File::copyTo(const std::string& destDir) iter->copyTo(destFile.getPath()); ++iter; } - - try { - Smack::setTransmute(destFile, Smack::getTransmute(*this)); - } catch (runtime::Exception &e) {} } else { open(O_RDONLY); destFile.open(O_WRONLY | O_CREAT, getMode()); @@ -402,18 +397,6 @@ File File::copyTo(const std::string& destDir) close(); } - try { - Smack::setAccess(destFile, Smack::getAccess(*this)); - } catch (runtime::Exception &e) {} - - try { - Smack::setExecute(destFile, Smack::getExecute(*this)); - } catch (runtime::Exception &e) {} - - try { - Smack::setMmap(destFile, Smack::getMmap(*this)); - } catch (runtime::Exception &e) {} - return destFile; } diff --git a/common/smack.cpp b/common/smack.cpp deleted file mode 100644 index b2c2871..0000000 --- a/common/smack.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -#include -#include -#include - -#include "smack.h" -#include "exception.h" - -namespace runtime { - -void Smack::setAccess(File& file, const std::string& label) -{ - set(file, XATTR_NAME_SMACK, label); -} - -void Smack::setExecute(File& file, const std::string& label) -{ - set(file, XATTR_NAME_SMACKEXEC, label); -} - -void Smack::setMmap(File& file, const std::string& label) -{ - set(file, XATTR_NAME_SMACKMMAP, label); -} - -void Smack::setTransmute(File& file, const bool enable) -{ - const char* enable_value; - - if (enable) { - enable_value = "TRUE"; - } else { - enable_value = "FALSE"; - } - - set(file, XATTR_NAME_SMACKTRANSMUTE, enable_value); -} - -std::string Smack::getAccess(File& file) -{ - return get(file, XATTR_NAME_SMACK); -} - -std::string Smack::getExecute(File& file) -{ - return get(file, XATTR_NAME_SMACKEXEC); -} - -std::string Smack::getMmap(File& file) -{ - return get(file, XATTR_NAME_SMACKMMAP); -} - -bool Smack::getTransmute(File& file) -{ - std::string label; - label = get(file, XATTR_NAME_SMACKTRANSMUTE); - - if (label == "TRUE") { - return true; - } - return false; -} - -void Smack::set(File& file, const char* xattr, const std::string& label) -{ - if (::smack_set_label_for_path(file.getPath().c_str(), - xattr, 0, label.c_str()) != 0) { - throw runtime::Exception("Smack setting error"); - } -} - -std::string Smack::get(File& file, const char* xattr) -{ - char* plabel; - std::string label; - if (::smack_new_label_from_path(file.getPath().c_str(), - xattr, 0, &plabel) < 0) { - throw runtime::Exception("Getting smack label error"); - } - - label = plabel; - free(plabel); - - return label; -} - -} // namespace runtime diff --git a/common/smack.h b/common/smack.h deleted file mode 100644 index 9f13648..0000000 --- a/common/smack.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -#ifndef __RUNTIME_SMACK_H__ -#define __RUNTIME_SMACK_H__ - -#include - -#include "filesystem.h" - -namespace runtime { - -class Smack final { -public: - Smack() = delete; - Smack(const Smack&) = delete; - Smack(Smack&&) = delete; - - Smack& operator=(const Smack&) = delete; - Smack& operator=(Smack&&) = delete; - - static void setAccess(File& file, const std::string& label); - static void setExecute(File& file, const std::string& label); - static void setMmap(File& file, const std::string& label); - static void setTransmute(File& file, const bool enable); - - static std::string getAccess(File& file); - static std::string getExecute(File& file); - static std::string getMmap(File& file); - static bool getTransmute(File& file); - - -private: - static void set(File& file, const char* xattr, const std::string& label); - static std::string get(File& file, const char* xattr); -}; - -} // namespace runtime -#endif //__RUNTIME_SMACK_H__ diff --git a/packaging/device-policy-manager.spec b/packaging/device-policy-manager.spec index 5017373..ef885db 100755 --- a/packaging/device-policy-manager.spec +++ b/packaging/device-policy-manager.spec @@ -23,7 +23,6 @@ BuildRequires: pkgconfig(vconf) BuildRequires: pkgconfig(vconf-internal-keys) BuildRequires: pkgconfig(bluetooth-api) BuildRequires: pkgconfig(capi-network-bluetooth) -BuildRequires: pkgconfig(libsmack) BuildRequires: pkgconfig(libtzplatform-config) BuildRequires: pkgconfig(security-privilege-manager) BuildRequires: pkgconfig(capi-base-common) @@ -34,6 +33,7 @@ BuildRequires: pkgconfig(capi-network-bluetooth) BuildRequires: pkgconfig(capi-system-system-settings) BuildRequires: pkgconfig(notification) BuildRequires: pkgconfig(key-manager) +BuildRequires: pkgconfig(libgum) %if "%{profile}" != "tv" BuildRequires: pkgconfig(capi-location-manager) diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index 85661d1..d4d2df3 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -53,6 +53,7 @@ SET(DEPENDENCY glib-2.0 capi-network-connection capi-network-bluetooth notification + libgum ) INCLUDE("${TIZEN_PROFILE_NAME}.cmake") diff --git a/server/zone/zone.cpp b/server/zone/zone.cpp index 4c50481..8dc6410 100644 --- a/server/zone/zone.cpp +++ b/server/zone/zone.cpp @@ -18,6 +18,8 @@ #include #include +#include +#include #include #include #include @@ -26,23 +28,16 @@ #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 DEFAULT_SHELL "/bin/bash" - #define ZONE_DELEGATOR_APP "org.tizen.keyguard" #define NOTIFICATION_SUB_ICON_PATH DATA_PATH "/zone_noti_list_sub_icon.png" @@ -72,32 +67,17 @@ const std::string ZONE_DEFAULT_OWNER = "owner"; const std::string ZONE_GROUP = "users"; std::vector createdZoneList; +static std::atomic isZoneForeground(false); + std::unordered_map notiProxyCallbackMap; std::unordered_map notiHandleMap; -template -inline void execute(const std::string& path, Args&&... args) -{ - std::vector argsVector = { args... }; - runtime::Process proc(path, argsVector); - proc.execute(); -} - -inline std::string prepareDirectories(const runtime::User& user) +inline void maskUserServices(const runtime::User& user) { ::tzplatform_set_user(user.getUid()); std::string pivot(::tzplatform_getenv(TZ_USER_HOME)); ::tzplatform_reset_user(); - //copy skel files to home directory - runtime::File skel(ZONE_SKEL_PATH); - skel.copyTo(pivot).chown(user.getUid(), user.getGid(), true); - - return pivot; -} - -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); @@ -110,43 +90,6 @@ inline void maskUserServices(const std::string& pivot, const runtime::User& user } } -inline void executeHookScripts(const runtime::User& user, const std::string& path, const std::string& pivot) -{ - std::vector scripts; - char currentDirectory[PATH_MAX]; - - try { - runtime::DirectoryIterator iter(path), end; - - while (iter != end) { - scripts.push_back(iter->getPath()); - ++iter; - } - } catch (runtime::Exception& e) {} - - if (getcwd(currentDirectory, PATH_MAX) == NULL) { - snprintf(currentDirectory, PATH_MAX, "/"); - } - - ::tzplatform_set_user(user.getUid()); - if (chdir(::tzplatform_getenv(TZ_SYS_HOME)) != 0) { - throw runtime::Exception(runtime::GetSystemErrorMessage()); - } - ::tzplatform_reset_user(); - - std::sort(scripts.begin(), scripts.end()); - - for (const std::string& script : scripts) { - execute(DEFAULT_SHELL, script, script, user.getName(), - std::to_string(user.getUid()), - std::to_string(user.getGid()), pivot, "normal"); - } - - if (chdir(currentDirectory) != 0) { - throw runtime::Exception(runtime::GetSystemErrorMessage()); - } -} - inline void setZoneState(uid_t id, int state) { dbus::Connection& systemDBus = dbus::Connection::getSystem(); @@ -281,7 +224,6 @@ void zoneProcessCallback(GDBusConnection *connection, GVariant *params, gpointer userData) { static runtime::User owner(ZONE_DEFAULT_OWNER); - static std::atomic isNotiShown(false); int pid, status; notification_h noti = reinterpret_cast(userData); @@ -298,16 +240,16 @@ void zoneProcessCallback(GDBusConnection *connection, return; } - if ((st.st_uid >= ZONE_UID_MIN) && (st.st_uid < ZONE_UID_MAX)) { - if (!isNotiShown) { + if (owner.getUid() != st.st_uid) { + if (!isZoneForeground) { notification_set_text(noti, NT_CONTENT, NT_APPINFO, NULL, NT_NONE); notification_post_for_uid(noti, owner.getUid()); - isNotiShown = true; + isZoneForeground = true; } } else { - if (isNotiShown) { + if (isZoneForeground) { notification_delete_for_uid(noti, owner.getUid()); - isNotiShown = false; + isZoneForeground = false; } } } @@ -577,23 +519,26 @@ int ZoneManager::createZone(const std::string& name, const std::string& manifest auto provisioningWorker = [name, manifest, this]() { std::unique_ptr 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); + //create zone user by gumd + GumUser *guser = gum_user_create_sync(FALSE); + g_object_set(G_OBJECT(guser), "username", name.c_str(), + "usertype", GUM_USERTYPE_SECURITY, NULL); + gboolean ret = gum_user_add_sync(guser); + g_object_unref(guser); + + if (!ret) { + throw runtime::Exception("Failed to remove user (" + name + ") by gumd"); } - std::string pivot = prepareDirectories(user); - maskUserServices(pivot, user); - executeHookScripts(user, ZONE_CREATE_HOOK_PATH, pivot); + runtime::User user(name); + + maskUserServices(user); manifestFile.reset(xml::Parser::parseString(manifest)); - ::umask(0077); + mode_t omask = ::umask(0077); manifestFile->write(ZONE_MANIFEST_DIR + name + ".xml", "UTF-8", true); + ::umask(omask); //TODO: write container owner info @@ -612,7 +557,6 @@ int ZoneManager::createZone(const std::string& name, const std::string& manifest context.notify("ZoneManager::removed", name, std::string()); } - ::umask(omask); }; std::thread asyncWork(provisioningWorker); @@ -638,14 +582,14 @@ int ZoneManager::removeZone(const std::string& name) try { runtime::User user(name); - ::tzplatform_set_user(user.getUid()); - std::string pivot(::tzplatform_getenv(TZ_USER_HOME)); - ::tzplatform_reset_user(); - - executeHookScripts(user, ZONE_REMOVE_HOOK_PATH, pivot); - //remove zone user - user.remove(); + GumUser *guser = gum_user_get_sync(user.getUid(), FALSE); + gboolean ret = gum_user_delete_sync(guser, TRUE); + g_object_unref(guser); + + if (!ret) { + throw runtime::Exception("Failed to remove user (" + name + ") by gumd"); + } for (std::vector::iterator it = createdZoneList.begin(); it != createdZoneList.end(); it++) { @@ -693,8 +637,8 @@ int ZoneManager::unlockZone(const std::string& name) int ZoneManager::getZoneState(const std::string& name) { - runtime::File manifest(ZONE_MANIFEST_DIR + name + ".xml"); - if (!manifest.exists()) { + auto it = std::find(createdZoneList.begin(), createdZoneList.end(), name); + if (it == createdZoneList.end()) { return 0; } diff --git a/tests/unit/shadow.cpp b/tests/unit/shadow.cpp index ea893b6..41932d3 100644 --- a/tests/unit/shadow.cpp +++ b/tests/unit/shadow.cpp @@ -35,39 +35,6 @@ TESTCASE(GetGroupTest) } } -TESTCASE(CreateGroupTest) -{ - try { - runtime::Group group = runtime::Group::create("testgroup"); - } catch (runtime::Exception& e) { - TEST_FAIL(e.what()); - } - - try { - runtime::Group group("testgroup"); - } catch (runtime::Exception& e) { - TEST_FAIL(e.what()); - } -} - -TESTCASE(RemoveGroupTest) -{ - try { - runtime::Group group("testgroup"); - group.remove(); - } catch (runtime::Exception& e) { - TEST_FAIL(e.what()); - } - - try { - runtime::Group group("testgroup"); - } catch (runtime::Exception& e) { - return; - } - - TEST_FAIL("Failed to remove group"); -} - TESTCASE(GetUserTest) { try { @@ -76,61 +43,3 @@ TESTCASE(GetUserTest) TEST_FAIL(e.what()); } } - -TESTCASE(CreateUserTest) -{ - try { - runtime::User user = runtime::User::create("testuser", "testgroup"); - } catch (runtime::Exception& e) { - TEST_FAIL(e.what()); - } - try { - runtime::User user("testuser"); - } catch (runtime::Exception& e) { - TEST_FAIL(e.what()); - } -} - -TESTCASE(AddMemberGroupTest) -{ - try { - runtime::Group group("users"); - group.addMember("test"); - group.addMember("testuser"); - } catch (runtime::Exception& e) { - TEST_FAIL(e.what()); - } -} -TESTCASE(RemoveMemberGroupTest) -{ - try { - runtime::Group group("users"); - group.removeMember("test"); - group.removeMember("noexist"); - } catch (runtime::Exception& e) { - TEST_FAIL(e.what()); - } -} - -TESTCASE(RemoveUserTest) -{ - try { - runtime::User user("testuser"); - user.remove(); - } catch (runtime::Exception& e) { - TEST_FAIL(e.what()); - } - - try { - runtime::Group group("testgroup"); - group.remove(); - } catch (runtime::Exception& e) {} - - try { - runtime::User user("testuser"); - } catch (runtime::Exception& e) { - return; - } - - TEST_FAIL("Failed to remove user"); -}