System User Session Launch helper 34/84834/4
authorKunhoon Baik <knhoon.baik@samsung.com>
Mon, 22 Aug 2016 13:54:16 +0000 (22:54 +0900)
committertaeyoung <ty317.kim@samsung.com>
Wed, 24 Aug 2016 01:44:56 +0000 (10:44 +0900)
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 <ty317.kim@samsung.com>
Makefile.am
configure.ac
packaging/system-plugin.spec
packaging/systemd-user-helper.manifest [new file with mode: 0644]
src/systemd-user-helper/systemd-user-helper.c [new file with mode: 0644]

index a651e89..03bd218 100644 (file)
@@ -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)|' \
index 5f0e9de..280e5c1 100644 (file)
@@ -117,6 +117,7 @@ AC_SUBST(M4_DEFINES)
 
 # ------------------------------------------------------------------------------
 PKG_CHECK_MODULES(VCONF, vconf)
+PKG_CHECK_MODULES(TZPLATFORMCONF, libtzplatform-config)
 
 # ------------------------------------------------------------------------------
 AC_SUBST([LIBLAZYMOUNT_PC_REQUIRES], "")
index dfb4c40..16998b3 100644 (file)
@@ -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 (file)
index 0000000..2a0cec5
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+  <request>
+    <domain name="_"/>
+  </request>
+</manifest>
diff --git a/src/systemd-user-helper/systemd-user-helper.c b/src/systemd-user-helper/systemd-user-helper.c
new file mode 100644 (file)
index 0000000..7291792
--- /dev/null
@@ -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 <dlfcn.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <sched.h>
+#include <sys/mount.h>
+
+#include <tzplatform_config.h>
+
+#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;
+}
+
+