From 78b2d513b638b5f6f4154a8334e5306d2e736607 Mon Sep 17 00:00:00 2001 From: Kunhoon Baik Date: Mon, 22 Aug 2016 22:54:16 +0900 Subject: System User Session Launch helper For supporting Tizen specific feature like directory compatibility and container, Tizen requires to handle namespaces. However, it could not be treated by PAM due to Lazy-mount feature. This launch helper solves the issues. This is first trial, if we find better solution, we will change to the solution. Change-Id: I0a6b27eb30f7904afde3a710a7fcb044ec172411 Signed-off-by: taeyoung --- Makefile.am | 14 +- configure.ac | 1 + packaging/system-plugin.spec | 23 ++- packaging/systemd-user-helper.manifest | 5 + src/systemd-user-helper/systemd-user-helper.c | 202 ++++++++++++++++++++++++++ 5 files changed, 242 insertions(+), 3 deletions(-) create mode 100644 packaging/systemd-user-helper.manifest create mode 100644 src/systemd-user-helper/systemd-user-helper.c diff --git a/Makefile.am b/Makefile.am index a651e89..03bd218 100644 --- a/Makefile.am +++ b/Makefile.am @@ -149,7 +149,8 @@ noinst_liblazymount_la_SOURCES = \ # ------------------------------------------------------------------------------ bin_PROGRAMS = \ - test_lazymount + test_lazymount \ + systemd_user_helper test_lazymount_SOURCES = \ src/liblazymount/test_lazymount.c @@ -174,6 +175,17 @@ BASIC_TARGET_WANTS += \ bin_SCRIPTS = \ scripts/mount-user.sh +systemd_user_helper_SOURCES = \ + src/systemd-user-helper/systemd-user-helper.c + +systemd_user_helper_CFLAGS = \ + $(AM_CFLAGS) \ + ${TZPLATFORMCONF_CFLAGS} + +systemd_user_helper_LDADD = \ + ${TZPLATFORMCONF_LIBS} \ + -ldl + # ------------------------------------------------------------------------------ substitutions = \ '|rootlibexecdir=$(rootlibexecdir)|' \ diff --git a/configure.ac b/configure.ac index 5f0e9de..280e5c1 100644 --- a/configure.ac +++ b/configure.ac @@ -117,6 +117,7 @@ AC_SUBST(M4_DEFINES) # ------------------------------------------------------------------------------ PKG_CHECK_MODULES(VCONF, vconf) +PKG_CHECK_MODULES(TZPLATFORMCONF, libtzplatform-config) # ------------------------------------------------------------------------------ AC_SUBST([LIBLAZYMOUNT_PC_REQUIRES], "") diff --git a/packaging/system-plugin.spec b/packaging/system-plugin.spec index dfb4c40..16998b3 100644 --- a/packaging/system-plugin.spec +++ b/packaging/system-plugin.spec @@ -10,11 +10,13 @@ License: Apache-2.0 Source0: %{name}-%{version}.tar.bz2 Source1: %{name}.manifest Source2: liblazymount.manifest +Source3: systemd-user-helper.manifest Requires(post): /usr/bin/systemctl Requires(post): /usr/bin/vconftool BuildRequires: pkgconfig(vconf) BuildRequires: pkgconfig(libsystemd) +BuildRequires: pkgconfig(libtzplatform-config) %description This package provides target specific system configuration files. @@ -67,7 +69,6 @@ License: Apache-2.0 Requires: vconf Requires: liblazymount = %{version} - %description -n liblazymount Library for lazy mount feature. It supports some interface functions. @@ -80,6 +81,13 @@ Requires: liblazymount = %{version} %description -n liblazymount-devel Development library for lazy mount feature.It supports some interface functions. +%package -n systemd-user-helper +Summary: Systemd user launch helper for supporting Tizen specific feature +License: Apache-2.0 + +%description -n systemd-user-helper +Systemd user launch helper supports Tizen specific feature like directory compatibility and container. + %package -n system-upgrade Summary: System upgrade available patch License: Apache-2.0 @@ -93,6 +101,7 @@ Systemd offline system update activation package %build cp %{SOURCE1} . cp %{SOURCE2} . +cp %{SOURCE3} . ./autogen.sh %reconfigure \ @@ -254,7 +263,6 @@ mv %{_sysconfdir}/fstab_initrd %{_sysconfdir}/fstab %{_unitdir}/lazy_mount.service %{_bindir}/mount-user.sh - %files -n liblazymount-devel %defattr(-,root,root,-) %manifest liblazymount.manifest @@ -271,3 +279,14 @@ mv %{_sysconfdir}/fstab_initrd %{_sysconfdir}/fstab %{_unitdir}/system-update.target.wants/init-update.service /system-update %{_prefix}/lib/udev/rules.d/99-sdb-switch.rules + +%files -n systemd-user-helper +%manifest systemd-user-helper.manifest +%caps(cap_sys_admin,cap_mac_admin,cap_setgid=ei) %{_bindir}/systemd_user_helper + +%posttrans -n systemd-user-helper +cp -a /usr/lib/systemd/system/user\@.service /usr/lib/systemd/system/__user@.service +/usr/bin/sed -i -e 's/Type=\(.*\)/Type=simple/' /usr/lib/systemd/system/user\@.service +/usr/bin/sed -i -e 's/ExecStart=\(.*\)/ExecStart=\/usr\/bin\/systemd_user_helper %i/' /usr/lib/systemd/system/user\@.service +/usr/bin/sed -i -e '/RemainAfterExit=\(.*\)/d' /usr/lib/systemd/system/user\@.service +echo 'RemainAfterExit=yes' >> /usr/lib/systemd/system/user\@.service diff --git a/packaging/systemd-user-helper.manifest b/packaging/systemd-user-helper.manifest new file mode 100644 index 0000000..2a0cec5 --- /dev/null +++ b/packaging/systemd-user-helper.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/src/systemd-user-helper/systemd-user-helper.c b/src/systemd-user-helper/systemd-user-helper.c new file mode 100644 index 0000000..7291792 --- /dev/null +++ b/src/systemd-user-helper/systemd-user-helper.c @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * 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 + +#define LEGACY_CONTENTS_DIR "/opt/usr/media" + +#define LAZYMOUNT_LIB "/usr/lib/liblazymount.so" +#define CONTAINER_LIB "/usr/lib/security/pam_krate.so" + +#define LOAD_SYMBOL(handle, sym, name) \ + do{ \ + sym = dlsym(handle, name); \ + if (!sym) { \ + fprintf(stderr, "dlsym %s error\n", name); \ + return -1; \ + } \ + } while (0); + +static void *container_handle = NULL; + +static int normal_user_preprocess(char *username) +{ + int r; + r = unshare(CLONE_NEWNS); + if (r < 0) { + fprintf(stderr,"unshare failed\n"); + return r; + } + return 0; +} + +static int normal_user_postprocess(char *username) +{ + int r; + r = mount(tzplatform_getenv(TZ_USER_CONTENT), + LEGACY_CONTENTS_DIR, NULL, MS_BIND, NULL); + if (r < 0) { + fprintf(stderr, "user content bind mount failed\n"); + return r; + } + return 0; +} + +static int container_open(void) +{ + if (container_handle) + return 0; + + container_handle = dlopen(CONTAINER_LIB, RTLD_LAZY); + if (!container_handle) { + fprintf(stderr, "container module dlopen error\n"); + return -1; + } + return 0; +} + +static int container_preprocess(char *username) +{ + int r; + int (*handle_preprocess)(char *); + + r = container_open(); + if (r < 0) + return r; + + LOAD_SYMBOL(container_handle, handle_preprocess, "container_preprocess"); + + r = handle_preprocess(username); + if (r < 0) { + fprintf(stderr, "container module preprocess error\n"); + return r; + } + + return 0; +} + +static int container_postprocess(char *username) +{ + int r; + int (*handle_postprocess)(char *); + + r = container_open(); + if (r < 0) + return r; + + LOAD_SYMBOL(container_handle, handle_postprocess, "container_postprocess"); + + r = handle_postprocess(username); + if (r < 0) { + fprintf(stderr, "container module postprocess error\n"); + return r; + } + + return 0; +} + +static int wait_condition(void) +{ + int r; + void *h; + + int (*wait_mount_user)(void); + + r = access(LAZYMOUNT_LIB,F_OK); + if (r < 0) + return 0; + + h = dlopen(LAZYMOUNT_LIB, RTLD_LAZY); + if (!h) { + fprintf(stderr, "lazymount module dlopen error\n"); + return -1; + } + + LOAD_SYMBOL(h, wait_mount_user, "wait_mount_user"); + + r = wait_mount_user(); + if (r < 0) { + fprintf(stderr, "wait_mout_user failed\n"); + return r; + } + return 0; +} + +int main(int argc, char *argv[]) +{ + int r = 0; + int support_container = 0; + + if (argc < 2) { + fprintf(stderr, "require user argument\n"); + return -1; + } + + /* pre-processing */ + r = normal_user_preprocess(argv[1]); + if (r < 0) { + fprintf(stderr, "normal user preprocess failed\n"); + return r; + } + + /* If container supports below funcs, below line should be enabled. */ + /* support_container = (access(CONTAINER_LIB, F_OK) == 0) ? 1 : 0; */ + if (support_container) { + r = container_preprocess(argv[1]); + if (r < 0) { + fprintf(stderr, "container preprocess failed\n"); + return r; + } + } + + /* TODO: fork & exec */ + r = system("/usr/lib/systemd/systemd --user &"); + if (r < 0) { + fprintf(stderr, "systemd user execution failed\n"); + return r; + } + + /* sync-style since there is no need to process other signal */ + wait_condition(); + + /* post-processing */ + r = normal_user_postprocess(argv[1]); + if (r < 0) { + fprintf(stderr, "normal user postprocess failed\n"); + return r; + } + + if (support_container) { + r = container_postprocess(argv[1]); + if (r < 0) { + fprintf(stderr, "container postprocess failed\n"); + return r; + } + } + + return 0; +} + + -- cgit v1.2.3