diff options
author | Sunmin Lee <sunm.lee@samsung.com> | 2017-02-09 15:40:43 +0900 |
---|---|---|
committer | Sunmin Lee <sunm.lee@samsung.com> | 2017-03-02 11:31:25 +0900 |
commit | b8666c3fa67525fc363da84422633420366f0061 (patch) | |
tree | 9e74d840eba8eb68c6da22ea99bbd9ffb68e7779 | |
parent | 46534c09b9135f63c4e0094d01d9a02a58b9b5f0 (diff) | |
download | session-utils-accepted/tizen_wearable.tar.gz session-utils-accepted/tizen_wearable.tar.bz2 session-utils-accepted/tizen_wearable.zip |
Initial session-utils repositorysubmit/tizen_unified/20170308.100409submit/tizen/20170303.002552accepted/tizen/wearable/20170303.005224accepted/tizen/unified/20170309.033720accepted/tizen/tv/20170303.005207accepted/tizen/mobile/20170303.005201accepted/tizen/ivi/20170303.005240accepted/tizen/common/20170303.090737accepted/tizen_wearableaccepted/tizen_tvaccepted/tizen_mobileaccepted/tizen_iviaccepted/tizen_common
Initial session-utils includes systemd-user-helper
from system-plugin package.
Change-Id: I196f6c54ee49ee3347ef42834d4d3d65be8bd79b
Signed-off-by: Sunmin Lee <sunm.lee@samsung.com>
-rw-r--r-- | LICENSE.Apache-2.0 | 204 | ||||
-rw-r--r-- | Makefile.am | 24 | ||||
-rwxr-xr-x | autogen.sh | 21 | ||||
-rw-r--r-- | configure.ac | 31 | ||||
-rw-r--r-- | packaging/session-utils.manifest | 8 | ||||
-rw-r--r-- | packaging/session-utils.spec | 49 | ||||
-rw-r--r-- | src/systemd-user-helper/systemd-user-helper.c | 457 |
7 files changed, 794 insertions, 0 deletions
diff --git a/LICENSE.Apache-2.0 b/LICENSE.Apache-2.0 new file mode 100644 index 0000000..8f17f50 --- /dev/null +++ b/LICENSE.Apache-2.0 @@ -0,0 +1,204 @@ +Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. +
diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..5c4ec1b --- /dev/null +++ b/Makefile.am @@ -0,0 +1,24 @@ +SUBDIRS = . + +AM_CPPFLAGS = \ + -include $(top_builddir)/config.h \ + -I $(top_srcdir)/src \ + -I $(top_srcdir)/src/shared \ + $(DEFAULT_CFLAGS) + +AM_CFLAGS = $(OUR_CFLAGS) +AM_LDFLAGS = $(OUR_LDFLAGS) + +bin_PROGRAMS = \ + systemd_user_helper + +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 diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..968bc8e --- /dev/null +++ b/autogen.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +set -e + +if [ -f .git/hooks/pre-commit.sample ] && [ ! -f .git/hooks/pre-commit ]; then + # This part is allowed to fail + cp -p .git/hooks/pre-commit.sample .git/hooks/pre-commit && \ + chmod +x .git/hooks/pre-commit && \ + echo "Activated pre-commit hook." || : +fi + +# README and INSTALL are required by automake, but may be deleted by +# clean up rules. to get automake to work, simply touch these here, +# they will be regenerated from their corresponding *.in files by +# ./configure anyway. +touch README INSTALL + +# Make sure m4 directory exist +mkdir -p m4 + +autoreconf --force --install --verbose || exit $? diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..23613fc --- /dev/null +++ b/configure.ac @@ -0,0 +1,31 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_PREREQ([2.68]) +AC_INIT(session-utils, 0.1, [BUG-REPORT-ADDRESS]) +AC_CONFIG_HEADERS([config.h]) + +AC_USE_SYSTEM_EXTENSIONS +AC_SYS_LARGEFILE +AC_PREFIX_DEFAULT([/usr]) +AM_INIT_AUTOMAKE([foreign]) + +# Checks for programs. +AC_PROG_MKDIR_P +AC_PROG_LN_S +AC_PROG_SED +AC_PROG_GREP +AC_PROG_AWK +#AC_PROG_INSTALL + +AC_PROG_CC +AM_PROG_CC_C_O + +AC_SUBST([OUR_CFLAGS], "$our_cflags") +dnl AC_SUBST([OUR_CPPFLAGS], "$OUR_CFLAGS -Wp,-D_FORTIFY_SOURCE=2") +AC_SUBST([OUR_LDFLAGS], "$our_ldflags") + +PKG_CHECK_MODULES(TZPLATFORMCONF, libtzplatform-config) + +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/packaging/session-utils.manifest b/packaging/session-utils.manifest new file mode 100644 index 0000000..90334b8 --- /dev/null +++ b/packaging/session-utils.manifest @@ -0,0 +1,8 @@ +<manifest> + <request> + <domain name="_"/> + </request> + <assign> + <filesystem path="/usr/bin/systemd_user_helper" label="_" exec_label="System::Privileged" /> + </assign> +</manifest> diff --git a/packaging/session-utils.spec b/packaging/session-utils.spec new file mode 100644 index 0000000..342acec --- /dev/null +++ b/packaging/session-utils.spec @@ -0,0 +1,49 @@ +Name: session-utils +Summary: System utils for supporting multi-user environment +Version: 0.1 +Release: 0 +Group: Base/Startup +License: Apache-2.0 +Source0: %{name}-%{version}.tar.bz2 +Source1: %{name}.manifest + +BuildRequires: pkgconfig(libtzplatform-config) + +%description +This package provides some utils for session control in multi-user environment. + +%prep +%setup -q + +%build +cp %{SOURCE1} . + +./autogen.sh +%reconfigure \ + --disable-static \ + --prefix=%{_prefix} \ + --disable-debug-mode \ + --disable-eng-mode + +%__make %{?jobs:-j%jobs} \ + CFLAGS+=-DLIBDIR=\\\"%{_libdir}\\\" + +%install +rm -rf %{buildroot} +%make_install + +%files +%license LICENSE.Apache-2.0 +%manifest session-utils.manifest +%caps(cap_sys_admin,cap_mac_admin,cap_mac_override,cap_dac_override,cap_setgid=ei) %{_bindir}/systemd_user_helper + +#TODO: when uninstalling, it should be restored to original file +%posttrans +cp -a /usr/lib/systemd/system/user\@.service /usr/lib/systemd/system/__user@.service +/usr/bin/sed -i -e 's/Type=\(.*\)/Type=forking/' /usr/lib/systemd/system/user\@.service +/usr/bin/sed -i -e 's/ExecStart=\(.*\)/ExecStart=\/usr\/bin\/systemd_user_helper start %i/' /usr/lib/systemd/system/user\@.service +/usr/bin/sed -i -e '/ExecStart=\(.*\)/ a ExecStop=\/usr\/bin\/systemd_user_helper stop %i' /usr/lib/systemd/system/user\@.service +/usr/bin/sed -i -e '/PIDFile=\(.*\)/d' /usr/lib/systemd/system/user\@.service +/usr/bin/sed -i -e '/XDG_RUNTIME_DIR/ a Environment=XDG_RUNTIME_EXT_DIR=/run/user_ext/%i' /usr/lib/systemd/system/user\@.service +echo 'PIDFile=/run/user/%i/.systemd.pid' >> /usr/lib/systemd/system/user\@.service +echo "d /run/user_ext 0755 root root -" >> /usr/lib/tmpfiles.d/systemd.conf 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..b65a7d9 --- /dev/null +++ b/src/systemd-user-helper/systemd-user-helper.c @@ -0,0 +1,457 @@ +/* + * 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. + * + */ + +/* + * @file systemd-user-helper.c + * @brief Systemd user launch helper for supporting Tizen specific feature + * + * Systemd user launch helper supports Tizen specific feature like directory + * compatibility and container. + */ + +#include <dlfcn.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <signal.h> +#include <errno.h> +#include <limits.h> +#include <sys/stat.h> + +#include <sched.h> +#include <sys/mount.h> + +#include <tzplatform_config.h> + +#include <sys/types.h> +#include <grp.h> +#include <string.h> + +#define ARRAY_SIZE(name) (sizeof(name)/sizeof(name[0])) +#define PIDFILE_PATH ".systemd.pid" + +// For compatibility, Using hard-coded path +#define LEGACY_CONTENTS_DIR "/opt/usr/media" +#define LEGACY_APPS_DIR "/opt/usr/apps" + +#define LAZYMOUNT_LIB LIBDIR"/liblazymount.so.0" +#define CONTAINER_LIB LIBDIR"/security/pam_krate.so" + +#define LOAD_SYMBOL(handle, sym, name) \ + do { \ + sym = dlsym(handle, name); \ + if (!sym) { \ + fprintf(stderr, "dlsym %s error\n", name); \ + dlclose(handle); \ + return -1; \ + } \ + } while (0); + +#define MOUNT_SIZE "10000k" +#define MAX_GRP_BUF_SIZE (1024 * 4) +#define GRP_NAME_SYSTEM_SHARE "system_share" + +static void *container_handle = NULL; + +static const char *systemd_arg[] = { + "/usr/lib/systemd/systemd", + "--user", + NULL +}; + +int mac_smack_use(void) { + static int cached_use = -1; + + if (cached_use < 0) + cached_use = access("/sys/fs/smackfs/", F_OK) >= 0; + + return cached_use; +} + +static int mount_user_ext(char *username) +{ + char *mount_point = NULL; + char *mount_option = NULL; + uid_t mnt_uid; + gid_t mnt_gid; + struct group *p_grp = NULL, grp_buf; + char buf[MAX_GRP_BUF_SIZE]; + int r; + + mnt_uid = atoi(username); + if(mnt_uid <= 0) + return -1; + + r = asprintf(&mount_point, "/run/user_ext/%s", username); + if (r < 0) { + fprintf(stderr, "Failed to set mount point for user_ext\n"); + return r; + } + + (void) mkdir(mount_point, 0750); + + r = getgrnam_r(GRP_NAME_SYSTEM_SHARE, &grp_buf, buf, sizeof(buf), &p_grp); + if( r == 0 && p_grp != NULL) + { + mnt_gid = p_grp->gr_gid; + } + else + { + free(mount_point); + return -2; + } + + if (mac_smack_use()) + r = asprintf(&mount_option, "mode=0750,smackfsroot=*,uid=%d,gid=%d,size=%s", mnt_uid, mnt_gid, MOUNT_SIZE); + else + r = asprintf(&mount_option, "mode=0750,uid=%d,gid=%d,size=%s", mnt_uid, mnt_gid, MOUNT_SIZE); + + if (r < 0) { + fprintf(stderr, "Failed to set mount option for user_ext\n"); + free(mount_point); + return r; + } + + r = mount("tmpfs", mount_point, "tmpfs", MS_NODEV|MS_NOSUID|MS_NOEXEC, mount_option); + free(mount_point); + free(mount_option); + + if (r < 0) { + fprintf(stderr, "Failed to mount user_ext\n"); + return r; + } + return 0; +} + +static int umount_user_ext(char *username) +{ + int r; + char *mount_point = NULL; + + r = asprintf(&mount_point, "/run/user_ext/%s", username); + if (r < 0) { + fprintf(stderr, "Failed to set mount point for user_ext\n"); + return r; + } + r = umount2(mount_point, MNT_DETACH); + if (r < 0) { + fprintf(stderr, "Failed to umount user_ext\n"); + free(mount_point); + return r; + } + r = rmdir(mount_point); + if (r < 0) { + fprintf(stderr, "Failed to rmdir user_ext\n"); + free(mount_point); + return r; + } + free(mount_point); + return 0; +} + +static int stop_process(char *username) +{ + int r; + + (void)umount_user_ext(username); + r = umount2(tzplatform_getenv(TZ_USER_CONTENT), MNT_DETACH); + if (r < 0) { + fprintf(stderr, "Warning : Failed to umount user content\n"); + } + + r = umount2(tzplatform_getenv(TZ_USER_APP), MNT_DETACH); + if (r < 0) { + fprintf(stderr, "Warning : Failed to umount application content\n"); + } + return 0; +} + +static int normal_user_preprocess(char *username) +{ + int r; + + r = unshare(CLONE_NEWNS); + if (r < 0) { + fprintf(stderr, "unshare failed\n"); + return r; + } + + r = mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL); + if (r < 0) { + fprintf(stderr, "Failed to change the propagation type of root to SLAVE\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 - %d\n", errno); + return r; + } + + r = mount(tzplatform_getenv(TZ_USER_APP), + LEGACY_APPS_DIR, NULL, MS_BIND, NULL); + if (r < 0) { + fprintf(stderr, "user app bind mount failed - %d\n", errno); + 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) { + fprintf(stderr, "cannot find lazymount module - No support lazymount\n"); + 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"); + dlclose(h); + return r; + } + + dlclose(h); + return 0; +} + +static int make_pid_file(int pid, char* user_id) +{ + FILE *fp; + char pidpath[PATH_MAX]; + int r = 0; + + snprintf(pidpath, PATH_MAX, "/run/user/%s/%s", user_id, PIDFILE_PATH); + + fp = fopen(pidpath, "w+"); + if (fp != NULL) { + fprintf(fp, "%d", pid); + fclose(fp); + } else + r = -1; + + return r; +} + +static int change_smack_for_user_session() +{ + FILE *fp; + int r = 0; + + fp = fopen("/proc/self/attr/current", "w"); + + if(fp == NULL) + { + r = -errno; + return r; + } + r = fputs("User", fp); + if(r == EOF) + { + fclose(fp); + r = -errno; + return r; + } + fclose(fp); + + return 0; +} + +int run_child(int argc, const char *argv[], char* user_id) +{ + pid_t pid; + int r = 0; + int i; + + if (!argv) + return -EINVAL; + + pid = fork(); + + if (pid < 0) { + fprintf(stderr, "failed to fork"); + r = -errno; + } else if (pid == 0) { + for (i = 0; i < _NSIG; ++i) + signal(i, SIG_DFL); + + r = execv(argv[0], (char **)argv); + /* NOT REACH */ + } else{ + make_pid_file(pid, user_id); + r = pid; + } + + return r; +} + +int main(int argc, char *argv[]) +{ + int r = 0; + int support_container = 0; + char *operation; + char *username; + + if (argc < 3) { + fprintf(stderr, "require user argument\n"); + return -1; + } + operation = argv[1]; + username = argv[2]; + + if (strcmp(operation,"stop") == 0) { + return stop_process(username); + } else if (strcmp(operation, "start") == 0) { + } else { + fprintf(stderr, "option is invalid(%s)\n", operation); + return -2; + } + + r = mount_user_ext(username); + if (r < 0) { + fprintf(stderr, "mount user_ext failed\n"); + return r; + } + r = change_smack_for_user_session(); + if(r != 0) + { + fprintf(stderr, "failed to change smack\n"); + return r; + } + + /* pre-processing */ + r = normal_user_preprocess(username); + 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(username); + if (r < 0) { + fprintf(stderr, "container preprocess failed\n"); + return r; + } + } + + r = run_child(ARRAY_SIZE(systemd_arg), systemd_arg, username); + if (r < 0) { + fprintf(stderr, "systemd user execution failed\n"); + return r; + } else{ + fprintf(stderr, "success = pid = %d\n", r); + } + + /* sync-style since there is no need to process other signal */ + wait_condition(); + + /* post-processing */ + r = normal_user_postprocess(username); + if (r < 0) { + fprintf(stderr, "normal user postprocess failed\n"); + return r; + } + + if (support_container) { + r = container_postprocess(username); + if (r < 0) { + fprintf(stderr, "container postprocess failed\n"); + return r; + } + } + + return 0; +} + + |