diff options
-rw-r--r-- | init.d/bootmisc.in | 6 | ||||
-rw-r--r-- | init.d/meson.build | 5 | ||||
-rw-r--r-- | init.d/user.in | 48 | ||||
-rw-r--r-- | sh/meson.build | 1 | ||||
-rw-r--r-- | sh/user-init.sh.in | 28 | ||||
-rw-r--r-- | src/meson.build | 1 | ||||
-rw-r--r-- | src/user_init/meson.build | 5 | ||||
-rw-r--r-- | src/user_init/user_init.c | 23 |
8 files changed, 113 insertions, 4 deletions
diff --git a/init.d/bootmisc.in b/init.d/bootmisc.in index 233dfc55..fdcd20bb 100644 --- a/init.d/bootmisc.in +++ b/init.d/bootmisc.in @@ -169,10 +169,12 @@ start() # Satisfy Linux FHS extra=/var/lib/misc if [ ! -d /run ]; then - extra="/var/run $extra" + extra="/var/run /var/run/user $extra" + elif [ ! -d /run/user ]; then + extra="/run/user $extra" fi else - extra=/var/run + extra="/var/run /var/run/user" fi for x in /var/log /tmp $extra; do if ! [ -d $x ]; then diff --git a/init.d/meson.build b/init.d/meson.build index ab4b27f4..63f9c166 100644 --- a/init.d/meson.build +++ b/init.d/meson.build @@ -10,12 +10,13 @@ init_common = [ 'netmount.in', 'osclock.in', 'root.in', + 'runsvdir.in', + 's6-svscan.in', 'savecache.in', 'swap.in', 'swclock.in', 'sysctl.in', - 'runsvdir.in', - 's6-svscan.in', + 'user.in', ] if get_option('newnet') diff --git a/init.d/user.in b/init.d/user.in new file mode 100644 index 00000000..5e2420c7 --- /dev/null +++ b/init.d/user.in @@ -0,0 +1,48 @@ +#!@SBINDIR@/openrc-run +# Copyright (c) 2017 The OpenRC Authors. +# See the Authors file at the top-level directory of this distribution and +# https://github.com/OpenRC/openrc/blob/HEAD/AUTHORS +# +# This file is part of OpenRC. It is subject to the license terms in +# the LICENSE file found in the top-level directory of this +# distribution and at https://github.com/OpenRC/openrc/blob/HEAD/LICENSE +# This file may not be copied, modified, propagated, or distributed +# except according to the terms contained in the LICENSE file. + +description="starts an openrc session for an user" +user="${RC_SVCNAME#*.}" + +extra_started_commands="runtime_directory" + +runtime_directory() { + service_get_value xdg_runtime_dir +} + +start_pre() { + if [ "$user" = "$RC_SVCNAME" ]; then + eerror "${RC_SVCNAME} cannot be started directly. You must create" + eerror "symbolic links to it for the users you want to start" + return 1 + fi + + if [ -z "$XDG_RUNTIME_DIR" ]; then + export XDG_RUNTIME_DIR="/run/user/$(id -u $user)" + checkpath -d -o "$user:$user" "$XDG_RUNTIME_DIR" || return 1 + fi + + service_set_value xdg_runtime_dir "$XDG_RUNTIME_DIR" +} + +start() { + ebegin "Starting user session for $user" + user_init $user start + eend $? + return 0 +} + +stop() { + ebegin "Stopping user session for $user" + user_init $user stop + eend $? + return 0 +} diff --git a/sh/meson.build b/sh/meson.build index e8849d40..bbc95c25 100644 --- a/sh/meson.build +++ b/sh/meson.build @@ -28,6 +28,7 @@ sh_config = [ scripts_config = [ 'gendepends.sh.in', 'openrc-run.sh.in', + 'user-init.sh.in', ] if os == 'Linux' diff --git a/sh/user-init.sh.in b/sh/user-init.sh.in new file mode 100644 index 00000000..eaedc631 --- /dev/null +++ b/sh/user-init.sh.in @@ -0,0 +1,28 @@ +#!@SHELL@ + +sourcex() +{ + if [ "$1" = "-e" ]; then + shift + [ -e "$1" ] || return 1 + fi + if ! . "$1"; then + eerror "$RC_SVCNAME: error loading $1" + exit 1 + fi +} + +_sysconf="${XDG_CONFIG_HOME:-${HOME}/.config}/openrc" + +sourcex -e "@SYSCONFDIR@/rc.conf" +sourcex -e "$_sysconf/rc.conf" + +case $1 in + start) _runlevel="${rc_user_runlevel:-default}";; + stop) _runlevel="${rc_user_shutdown_runlevel:-none}";; + *) exit 1 +esac + +mkdir -p "$_sysconf/runlevels/$_runlevel" + +openrc --user "$_runlevel" diff --git a/src/meson.build b/src/meson.build index 76f6d8a1..cee6cb6c 100644 --- a/src/meson.build +++ b/src/meson.build @@ -34,3 +34,4 @@ subdir('start-stop-daemon') subdir('supervise-daemon') subdir('swclock') subdir('value') +subdir('user_init') diff --git a/src/user_init/meson.build b/src/user_init/meson.build new file mode 100644 index 00000000..838805fb --- /dev/null +++ b/src/user_init/meson.build @@ -0,0 +1,5 @@ +executable('user_init', ['user_init.c'], + include_directories: [incdir, einfo_incdir, rc_incdir], + link_with: [libeinfo, librc], + install: true, + install_dir: rc_bindir) diff --git a/src/user_init/user_init.c b/src/user_init/user_init.c new file mode 100644 index 00000000..1f79ec90 --- /dev/null +++ b/src/user_init/user_init.c @@ -0,0 +1,23 @@ +#include <sys/types.h> +#include <pwd.h> +#include <grp.h> +#include <unistd.h> +#include <stdlib.h> + +#include "rc.h" + +#define USERINIT RC_LIBEXECDIR "/sh/user-init.sh" + +int main(int argc, char **argv) { + struct passwd *user; + if (argc < 3) + return 1; + + user = getpwnam(argv[1]); + if (!user || initgroups(user->pw_name, user->pw_gid) == -1 + || setgid(user->pw_gid) == -1 + || setuid(user->pw_uid) == -1) + return 1; + + execl(user->pw_shell, "-", "-c", USERINIT, argv[2], NULL); +} |