Add krate-mount service 94/188994/4 accepted/tizen/unified/20180918.062935 submit/tizen/20180917.094422
authorSungbae Yoo <sungbae.yoo@samsung.com>
Wed, 12 Sep 2018 08:28:02 +0000 (17:28 +0900)
committerSungbae Yoo <sungbae.yoo@samsung.com>
Mon, 17 Sep 2018 06:18:44 +0000 (15:18 +0900)
which does mount after wait-mount.service in each namespace of krate.
and also this requires krate-mount to have cap_sysadmin

Change-Id: I6d0729d617d2d7aa610ec1a2e832688d50797ff2
Signed-off-by: Sungbae Yoo <sungbae.yoo@samsung.com>
module/CMakeLists.txt
module/krate-builder.cpp
module/krate-builder.h
module/krate-mount.cpp [new file with mode: 0644]
module/krate.cpp
module/systemd/krate-mount.service.in [new file with mode: 0644]
packaging/krate.spec

index fa353f9..0fd43f6 100644 (file)
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-FILE(GLOB PAM_SRCS     krate.cpp
-                                       krate-builder.cpp
+SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,noexecstack")
+
+FILE(GLOB BUILDER_SRCS krate-builder.cpp)
+
+PKG_CHECK_MODULES(BUILDER_DEPS REQUIRED
+                                                               klay
+                                                               libxml-2.0
 )
 
-SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,noexecstack")
+FILE(GLOB PAM_SRCS     krate.cpp)
 
 SET(PAM_NAME pam_${PROJECT_NAME})
+ADD_LIBRARY(${PAM_NAME} MODULE ${PAM_SRCS} ${BUILDER_SRCS})
 
-ADD_LIBRARY(${PAM_NAME} MODULE ${PAM_SRCS})
 SET_TARGET_PROPERTIES(${PAM_NAME} PROPERTIES  PREFIX ""
        COMPILE_DEFINITIONS PID_FILE_PATH="${RUN_INSTALL_DIR}/krate"
        COMPILE_FLAGS "-fvisibility=hidden"
@@ -35,12 +40,19 @@ MARK_AS_ADVANCED(PAM_INCLUDE_DIR PAM_LIBRARY)
 INCLUDE(FindPackageHandleStandardArgs)
 FIND_PACKAGE_HANDLE_STANDARD_ARGS(PAM DEFAULT_MSG PAM_LIBRARY PAM_INCLUDE_DIR)
 
-PKG_CHECK_MODULES(PAM_DEPS     REQUIRED
-                                                       klay
-                                                       libxml-2.0
-)
+INCLUDE_DIRECTORIES(${PAM_INCLUDE_DIR} ${BUILDER_DEPS_INCLUDE_DIRS})
+
+TARGET_LINK_LIBRARIES(${PAM_NAME}      ${PAM_LIBRARY} ${BUILDER_DEPS_LIBRARIES})
+
+FILE(GLOB MOUNT_SRCS   krate-mount.cpp)
+
+SET(MOUNT_NAME ${PROJECT_NAME}-mount)
+ADD_EXECUTABLE(${MOUNT_NAME}   ${MOUNT_SRCS} ${BUILDER_SRCS})
+
+TARGET_LINK_LIBRARIES(${MOUNT_NAME}    ${MOUNT_SRC} ${BUILDER_DEPS_LIBRARIES})
 
-INCLUDE_DIRECTORIES(${PAM_INCLUDE_DIR} ${PAM_DEPS_INCLUDE_DIRS})
-TARGET_LINK_LIBRARIES(${PAM_NAME} ${PAM_LIBRARY} ${PAM_DEPS_LIBRARIES} pthread)
+CONFIGURE_FILE(systemd/${MOUNT_NAME}.service.in systemd/${MOUNT_NAME}.service)
 
 INSTALL(TARGETS ${PAM_NAME} DESTINATION ${LIB_INSTALL_DIR}/security)
+INSTALL(TARGETS ${MOUNT_NAME} DESTINATION ${BIN_DIR})
+INSTALL(FILES systemd/${MOUNT_NAME}.service DESTINATION ${SYSTEMD_USER_UNIT_DIR})
index 07fee11..3e13cc7 100644 (file)
 #include "krate-builder.h"
 
 #include <klay/exception.h>
+#include <klay/namespace.h>
 #include <klay/filesystem.h>
 
-KrateBuilder::KrateBuilder(const runtime::User& user, const std::string& manifestPath) :
-       name(user.getName()), uid(user.getUid()), gid(user.getGid())
+#define CGROUP_SUBSYSTEM "krate"
+
+KrateBuilder::KrateBuilder(const runtime::User& user) :
+       user(user)
 {
-       runtime::File data(manifestPath);
+       runtime::File data(getManifestPath());
        if (data.exists()) {
-               manifest.reset(xml::Parser::parseFile(manifestPath));
+               manifest.reset(xml::Parser::parseFile(data.getPath()));
        }
 }
 
@@ -37,6 +40,11 @@ KrateBuilder::~KrateBuilder()
 {
 }
 
+std::string KrateBuilder::getManifestPath()
+{
+       return "/home/" + user.getName() + "/.config/krate/krate.xml";
+}
+
 void KrateBuilder::bindFilesystemNode(const std::string& source, const std::string& target,
                                                                         const std::string& type, const std::string& options,
                                                                         bool create)
@@ -44,7 +52,7 @@ void KrateBuilder::bindFilesystemNode(const std::string& source, const std::stri
        if (create) {
                runtime::File dir(target);
                if (!dir.exists()) {
-                       dir.makeDirectory(true, uid, gid);
+                       dir.makeDirectory(true, user.getUid(), user.getGid());
                }
        }
 
@@ -61,10 +69,41 @@ void KrateBuilder::mountOwnFilesystem()
                }
        }
 
-       bindFilesystemNode("/home/" + name,
-                                          "/home/" + name + "/.krate/" + name,
+       bindFilesystemNode("/home/" + user.getName(),
+                                          "/home/" + user.getName() + "/.krate/" + user.getName(),
                                           "none", "rw,bind");
 
-       bindFilesystemNode("/home/" + name + "/.krate", "/home",
+       bindFilesystemNode("/home/" + user.getName() + "/.krate", "/home",
                                           "none", "rw,rbind");
 }
+
+void KrateBuilder::enterKrate()
+{
+       std::string path = CGROUP_SUBSYSTEM "/" + user.getName();
+       pid_t pid = 0;
+
+       if (runtime::Cgroup::exist(CGROUP_SUBSYSTEM, path)) {
+               auto pids = runtime::Cgroup::getProcessList(CGROUP_SUBSYSTEM, path);
+               if (pids.size() > 0) {
+                       pid  = pids[0];
+               }
+       } else {
+               runtime::Cgroup::create(CGROUP_SUBSYSTEM, path);
+       }
+
+       if (pid == 0) {
+               runtime::Cgroup::addProcess(CGROUP_SUBSYSTEM, path, ::getpid());
+               runtime::Namespace::unshare(CLONE_NEWNS | CLONE_NEWIPC);
+       } else {
+               runtime::Namespace::attach(pid);
+       }
+}
+
+void KrateBuilder::exitKrate()
+{
+       std::string path =  CGROUP_SUBSYSTEM "/" + user.getName();
+       auto pids = runtime::Cgroup::getProcessList(CGROUP_SUBSYSTEM, path);
+       if (pids.size() <= 1) {
+               runtime::Cgroup::destroy(CGROUP_SUBSYSTEM, path);
+       }
+}
index 7947c6b..1563c3e 100644 (file)
 #include <vector>
 #include <memory>
 
+#include <klay/cgroup.h>
 #include <klay/xml/parser.h>
 #include <klay/xml/document.h>
 #include <klay/auth/user.h>
 
 class KrateBuilder final {
 public:
-       KrateBuilder(const runtime::User& user, const std::string& manifestPath);
+       KrateBuilder(const runtime::User& user);
        virtual ~KrateBuilder();
 
        void mountOwnFilesystem();
 
-protected:
+       void enterKrate();
+       void exitKrate();
+
+private:
+       runtime::User user;
+       std::unique_ptr<xml::Document> manifest;
+
+       std::string getManifestPath();
        void bindFilesystemNode(const std::string& source, const std::string& target,
                                                        const std::string& type, const std::string& options,
                                                        bool create = true);
-private:
-       std::string name;
-       uid_t uid;
-       gid_t gid;
-       std::unique_ptr<xml::Document> manifest;
 };
 
 #endif //!__KRATE_BUILDER_H__
diff --git a/module/krate-mount.cpp b/module/krate-mount.cpp
new file mode 100644 (file)
index 0000000..7595c0a
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+
+#include <string>
+#include <iostream>
+
+#include "krate-builder.h"
+
+int main(int argc, char *argv[])
+{
+       try {
+               runtime::User user;
+               KrateBuilder builder(user);
+               builder.mountOwnFilesystem();
+       } catch (std::exception &e) {
+               std::cerr << e.what() << std::endl;
+       }
+
+       return EXIT_SUCCESS;
+}
index dda52c8..8c9a320 100644 (file)
 
 #include "krate-builder.h"
 
-#include <klay/cgroup.h>
-#include <klay/namespace.h>
 #include <klay/exception.h>
 #include <klay/filesystem.h>
-#include <klay/xml/parser.h>
-#include <klay/xml/document.h>
-
-#define CGROUP_SUBSYSTEM "krate"
 
 #define KRATE_UID_MIN 6000
 #define KRATE_UID_MAX 6999
 
-#define LAZYMOUNT_EXTERN extern
-#define LAZYMOUNT_LIB "/usr/lib/liblazymount.so.0"
+namespace {
 
-std::string buildKrateManifestPath(const std::string& name)
-{
-       return "/home/" + name + "/.config/krate/krate.xml";
+static std::string getFlagFilePath(runtime::User &user) {
+       return "/run/user/" + std::to_string(user.getUid()) + "/.container";
 }
 
+} // namespace
+
 std::string getKrateName(pam_handle_t* handle)
 {
        const void* retItem;
@@ -57,37 +51,18 @@ std::string getKrateName(pam_handle_t* handle)
        return static_cast<const char*>(retItem);
 }
 
-void enterKrate(const std::string& name)
-{
-       std::string path = CGROUP_SUBSYSTEM "/" + name;
-       pid_t pid = 0;
-
-       if (runtime::Cgroup::exist(CGROUP_SUBSYSTEM, path)) {
-               auto pids = runtime::Cgroup::getProcessList(CGROUP_SUBSYSTEM, path);
-               if (pids.size() > 0) {
-                       pid  = pids[0];
-               }
-       } else {
-               runtime::Cgroup::create(CGROUP_SUBSYSTEM, path);
-       }
-
-       if (pid == 0) {
-               runtime::Cgroup::addProcess(CGROUP_SUBSYSTEM, path, ::getpid());
-               runtime::Namespace::unshare(CLONE_NEWNS | CLONE_NEWIPC);
-       } else {
-               runtime::Namespace::attach(pid);
-       }
-}
-
 extern "C" {
 PAM_EXTERN  __attribute__((visibility("default")))
 int pam_sm_open_session(pam_handle_t* pamh, int flags, int argc, const char* argv[])
 {
        try {
                runtime::User user(getKrateName(pamh));
-               enterKrate(user.getName());
+
+               KrateBuilder builder(user);
+               builder.enterKrate();
+
                if (user.getUid() >= KRATE_UID_MIN && user.getUid() <= KRATE_UID_MAX ) {
-                       runtime::File flag("/run/user/" + std::to_string(user.getUid()) + "/.container");
+                       runtime::File flag(getFlagFilePath(user));
                        if (!flag.exists())
                                flag.create(0644);
                }
@@ -103,16 +78,14 @@ PAM_EXTERN  __attribute__((visibility("default")))
 int pam_sm_close_session(pam_handle_t* pamh, int flags, int argc, const char* argv[])
 {
        try {
-               std::string name = getKrateName(pamh);
-               auto pids = runtime::Cgroup::getProcessList(CGROUP_SUBSYSTEM, name);
-               if (pids.size() <= 1) {
-                       std::string path = CGROUP_SUBSYSTEM "/" + name;
-                       runtime::Cgroup::destroy(CGROUP_SUBSYSTEM, path);
-                       runtime::User user(name);
-                       runtime::File flag("/run/user/" + std::to_string(user.getUid()) + "/.container");
-                       if (flag.exists())
-                               flag.remove(false);
-               }
+               runtime::User user(getKrateName(pamh));
+
+               KrateBuilder builder(user);
+               builder.exitKrate();
+
+               runtime::File flag(getFlagFilePath(user));
+               if (flag.exists())
+                       flag.remove(false);
        } catch (runtime::Exception& e) {
                ::pam_syslog(pamh, LOG_ERR, "%s", e.what());
                return PAM_SESSION_ERR;
diff --git a/module/systemd/krate-mount.service.in b/module/systemd/krate-mount.service.in
new file mode 100644 (file)
index 0000000..e13a194
--- /dev/null
@@ -0,0 +1,11 @@
+[Unit]
+Description=@PROJECT_NAME@ mount manager for UID %U
+DefaultDependencies=no
+Wants=wait-mount@opt-usr.service
+After=wait-mount@opt-usr.service
+Before=session-bind.service basic.target
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=@BIN_DIR@/@PROJECT_NAME@-mount
index 0ac2d13..a22e09a 100644 (file)
@@ -35,9 +35,12 @@ krates.
 %manifest krate.manifest
 %defattr(644,root,root,755)
 %attr(755,root,root) %{_bindir}/krated
+%attr(755,root,root) %{_bindir}/krate-mount
 %attr(700,root,root) %{_sbindir}/krate-volume-manager
 %{_unitdir}/krate.service
 %{_unitdir}/multi-user.target.wants/krate.service
+%{_unitdir_user}/krate-mount.service
+%{_unitdir_user}/basic.target.wants/krate-mount.service
 %attr(644,root,root) %{TZ_SYS_RO_ICONS}/krate/default_icon.png
 %attr(644,root,root) %{TZ_SYS_RO_ICONS}/krate/shortcut_icon.png
 %attr(644,root,root) %{TZ_SYS_RO_ICONS}/krate/indicator_icon.png
@@ -61,6 +64,7 @@ krates.
          -DBIN_DIR=%{TZ_SYS_BIN} \
          -DHOME_DIR=%{TZ_SYS_HOME} \
          -DSYSTEMD_UNIT_DIR=%{_unitdir} \
+         -DSYSTEMD_USER_UNIT_DIR=%{_unitdir_user} \
          -DPAMD_DIR=/etc/pam.d \
          -DICON_DIR="%{TZ_SYS_RO_ICONS}/krate" \
 
@@ -68,8 +72,11 @@ make %{?jobs:-j%jobs}
 
 %install
 %make_install
+mkdir -p %{buildroot}/%{_unitdir_user}/basic.target.wants
+ln -s ../krate-mount.service %{buildroot}/%{_unitdir_user}/basic.target.wants/.
+
 mkdir -p %{buildroot}/%{_unitdir}/multi-user.target.wants
-ln -s ../krate.service %{buildroot}/%{_unitdir}/multi-user.target.wants/krate.service
+ln -s ../krate.service %{buildroot}/%{_unitdir}/multi-user.target.wants/.
 
 %post
 echo "session  required pam_krate.so" >> /etc/pam.d/systemd-user