aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnna (navi) Figueiredo Gomes <navi@vlhl.dev>2024-07-12 00:51:12 +0200
committerAnna (navi) Figueiredo Gomes <navi@vlhl.dev>2024-07-19 20:40:28 +0200
commitfd961d2ea0eea2cc60f4af1aca6b6e7711d43995 (patch)
treefc53ad7bf4d46a3b72e151b79e8433ff4d565514
parentc34fcd63f05044f9034b26c52f19c91e04668da7 (diff)
openrc-user: init script for users
adds a new multiplexed script for starting user sessions. it also sets up XDG_RUNTIME_DIR. Signed-off-by: Anna (navi) Figueiredo Gomes <navi@vlhl.dev>
-rw-r--r--init.d/bootmisc.in6
-rw-r--r--init.d/meson.build5
-rw-r--r--init.d/user.in48
-rw-r--r--sh/meson.build1
-rw-r--r--sh/user-init.sh.in28
-rw-r--r--src/meson.build1
-rw-r--r--src/user_init/meson.build5
-rw-r--r--src/user_init/user_init.c23
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);
+}