</listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>--lightweight=<replaceable>BOOLEAN</replaceable></option></term>
+
+ <listitem><para>Controls whether to activate the per-user service manager for the target user. By
+ default if the target user is <literal>root</literal> or a system user the per-user service manager
+ is not activated as effect of the <command>run0</command> invocation, otherwise it is.</para>
+
+ <para>This ultimately controls the <varname>$XDG_SESSION_CLASS</varname> variable
+ <citerefentry><refentrytitle>pam_systemd</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ respects.</para>
+
+ <xi:include href="version-info.xml" xpointer="v258"/>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><option>--machine=</option></term>
<member><citerefentry><refentrytitle>systemd-run</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
<member><citerefentry project='man-pages'><refentrytitle>sudo</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
<member><citerefentry><refentrytitle>machinectl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
+ <member><citerefentry><refentrytitle>pam_systemd</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
</simplelist></para>
</refsect1>
static char *arg_background = NULL;
static sd_json_format_flags_t arg_json_format_flags = SD_JSON_FORMAT_OFF;
static char *arg_shell_prompt_prefix = NULL;
+static int arg_lightweight = -1;
STATIC_DESTRUCTOR_REGISTER(arg_description, freep);
STATIC_DESTRUCTOR_REGISTER(arg_environment, strv_freep);
" --pty Request allocation of a pseudo TTY for stdio\n"
" --pipe Request direct pipe for stdio\n"
" --shell-prompt-prefix=PREFIX Set $SHELL_PROMPT_PREFIX\n"
+ " --lightweight=BOOLEAN Control whether to register a session with service manager\n"
+ " or without\n"
"\nSee the %s for details.\n",
program_invocation_short_name,
ansi_highlight(),
ARG_PTY,
ARG_PIPE,
ARG_SHELL_PROMPT_PREFIX,
+ ARG_LIGHTWEIGHT,
};
/* If invoked as "run0" binary, let's expose a more sudo-like interface. We add various extensions
{ "pty", no_argument, NULL, ARG_PTY },
{ "pipe", no_argument, NULL, ARG_PIPE },
{ "shell-prompt-prefix", required_argument, NULL, ARG_SHELL_PROMPT_PREFIX },
+ { "lightweight", required_argument, NULL, ARG_LIGHTWEIGHT },
{},
};
return r;
break;
+ case ARG_LIGHTWEIGHT:
+ r = parse_tristate_argument("--lightweight=", optarg, &arg_lightweight);
+ if (r < 0)
+ return r;
+ break;
+
case '?':
return -EINVAL;
if (IN_SET(arg_stdio, ARG_STDIO_NONE, ARG_STDIO_AUTO))
arg_stdio = isatty_safe(STDIN_FILENO) && isatty_safe(STDOUT_FILENO) && isatty_safe(STDERR_FILENO) ? ARG_STDIO_PTY : ARG_STDIO_DIRECT;
+ log_debug("Using %s stdio mode.", arg_stdio == ARG_STDIO_PTY ? "pty" : "direct");
+
arg_expand_environment = false;
arg_send_sighup = true;
return log_error_errno(r, "Failed to set $SHELL_PROMPT_PREFIX environment variable: %m");
}
+ /* When using run0 to acquire privileges temporarily, let's not pull in session manager by
+ * default. Note that pam_logind/systemd-logind doesn't distinguish between run0-style privilege
+ * escalation on a TTY and first class (getty-style) TTY logins (and thus gives root a per-session
+ * manager for interactive TTY sessions), hence let's override the logic explicitly here. We only do
+ * this for root though, under the assumption that if a regular user temporarily transitions into
+ * another regular user it's a better default that the full user environment is uniformly
+ * available. */
+ if (arg_lightweight < 0 && !strv_env_get(arg_environment, "XDG_SESSION_CLASS") && privileged_execution())
+ arg_lightweight = true;
+
+ if (arg_lightweight >= 0) {
+ const char *class =
+ arg_lightweight ? (arg_stdio == ARG_STDIO_PTY ? (privileged_execution() ? "user-early-light" : "user-light") : "background-light") :
+ (arg_stdio == ARG_STDIO_PTY ? (privileged_execution() ? "user-early" : "user") : "background");
+
+ log_debug("Setting XDG_SESSION_CLASS to '%s'.", class);
+
+ r = strv_env_assign(&arg_environment, "XDG_SESSION_CLASS", class);
+ if (r < 0)
+ return log_error_errno(r, "Failed to set $XDG_SESSION_CLASS environment variable: %m");
+ }
+
return 1;
}
TRANSIENTUNIT2="bgg$RANDOM.service"
TRANSIENTUNIT3="bggg$RANDOM.service"
TRANSIENTUNIT4="bgggg$RANDOM.service"
+ RUN0UNIT0="run0$RANDOM.service"
+ RUN0UNIT1="runn0$RANDOM.service"
+ RUN0UNIT2="runnn0$RANDOM.service"
+ RUN0UNIT3="runnnn0$RANDOM.service"
trap background_at_return RETURN
systemd-run -u "$TRANSIENTUNIT4" -p PAMName="$PAMSERVICE" -p "Environment=XDG_SESSION_TYPE=tty" -p Type=exec -p User=lightuser sleep infinity
loginctl | grep lightuser | grep -q user-light
systemctl stop "$TRANSIENTUNIT4"
+
+ # Now check that run0's session class control works
+ systemd-run --service-type=notify run0 -u lightuser --unit="$RUN0UNIT0" sleep infinity
+ loginctl | grep lightuser | grep -q "background-light "
+ systemctl stop "$RUN0UNIT0"
+
+ systemd-run --service-type=notify run0 -u lightuser --unit="$RUN0UNIT1" --lightweight=yes sleep infinity
+ loginctl | grep lightuser | grep -q "background-light "
+ systemctl stop "$RUN0UNIT1"
+
+ systemd-run --service-type=notify run0 -u lightuser --unit="$RUN0UNIT2" --lightweight=no sleep infinity
+ loginctl | grep lightuser | grep -q "background "
+ systemctl stop "$RUN0UNIT2"
+
+ systemd-run --service-type=notify run0 -u root --unit="$RUN0UNIT3" sleep infinity
+ loginctl | grep root | grep -q "background-light "
+ systemctl stop "$RUN0UNIT3"
}
testcase_varlink() {