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>
# 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"
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})
#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()));
}
}
{
}
+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)
if (create) {
runtime::File dir(target);
if (!dir.exists()) {
- dir.makeDirectory(true, uid, gid);
+ dir.makeDirectory(true, user.getUid(), user.getGid());
}
}
}
}
- 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);
+ }
+}
#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__
--- /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 <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;
+}
#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;
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);
}
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;
--- /dev/null
+[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
%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
-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" \
%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