<term><option>-g</option></term>
<listitem><para>Switches to the specified user/group. If not specified defaults to
- <literal>root</literal>, unless <option>--area=</option> is used (see below), in which case this
- defaults to the invoking user.</para>
+ <literal>root</literal>, unless <option>--area=</option> or <option>--empower</option> are used (see
+ below), in which case this defaults to the invoking user.</para>
<xi:include href="version-info.xml" xpointer="v256"/>
</listitem>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>--empower</option></term>
+
+ <listitem><para>If specified, run0 will elevate the privileges of the selected user (using
+ <option>--user=</option>) or the current user if no user is explicitly selected. Currently this means
+ we give the user all available capabilities, but other privileges may be granted in the future as
+ well when using this option.</para>
+
+ <xi:include href="version-info.xml" xpointer="v259"/></listitem>
+ </varlistentry>
+
<varlistentry>
<term><option>--machine=</option></term>
#include "bus-util.h"
#include "bus-wait-for-jobs.h"
#include "calendarspec.h"
+#include "capability-util.h"
#include "capsule-util.h"
#include "chase.h"
#include "env-util.h"
static int arg_lightweight = -1;
static char *arg_area = NULL;
static bool arg_via_shell = false;
+static bool arg_empower = false;
STATIC_DESTRUCTOR_REGISTER(arg_description, freep);
STATIC_DESTRUCTOR_REGISTER(arg_environment, strv_freep);
" --lightweight=BOOLEAN Control whether to register a session with service manager\n"
" or without\n"
" --area=AREA Home area to log into\n"
+ " --empower Give privileges to selected or current user\n"
"\nSee the %s for details.\n",
program_invocation_short_name,
ansi_highlight(),
return 0;
}
+static bool become_root(void) {
+ return !arg_exec_user || STR_IN_SET(arg_exec_user, "root", "0");
+}
+
static bool privileged_execution(void) {
if (arg_runtime_scope != RUNTIME_SCOPE_SYSTEM)
return false;
- return !arg_exec_user || STR_IN_SET(arg_exec_user, "root", "0");
+ return become_root() || arg_empower;
}
static int add_timer_property(const char *name, const char *val) {
ARG_LIGHTWEIGHT,
ARG_AREA,
ARG_VIA_SHELL,
+ ARG_EMPOWER,
};
/* If invoked as "run0" binary, let's expose a more sudo-like interface. We add various extensions
{ "shell-prompt-prefix", required_argument, NULL, ARG_SHELL_PROMPT_PREFIX },
{ "lightweight", required_argument, NULL, ARG_LIGHTWEIGHT },
{ "area", required_argument, NULL, ARG_AREA },
+ { "empower", no_argument, NULL, ARG_EMPOWER },
{},
};
arg_via_shell = true;
break;
+ case ARG_EMPOWER:
+ arg_empower = true;
+ break;
+
case '?':
return -EINVAL;
assert_not_reached();
}
- if (!arg_exec_user && arg_area) {
+ if (!arg_exec_user && (arg_area || arg_empower)) {
/* If the user specifies --area= but not --user= then consider this an area switch request,
- * and default to logging into our own account */
+ * and default to logging into our own account.
+ *
+ * If the user specifies --empower but not --user= then consider this a request to empower
+ * the current user. */
+
arg_exec_user = getusername_malloc();
if (!arg_exec_user)
return log_oom();
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");
+ arg_lightweight ? (arg_stdio == ARG_STDIO_PTY ? (become_root() ? "user-early-light" : "user-light") : "background-light") :
+ (arg_stdio == ARG_STDIO_PTY ? (become_root() ? "user-early" : "user") : "background");
log_debug("Setting XDG_SESSION_CLASS to '%s'.", class);
return bus_log_create_error(r);
}
+ if (arg_empower) {
+ r = sd_bus_message_append(m, "(sv)", "AmbientCapabilities", "t", CAP_MASK_ALL);
+ if (r < 0)
+ return bus_log_create_error(r);
+ }
+
if (arg_nice_set) {
r = sd_bus_message_append(m, "(sv)", "Nice", "i", arg_nice);
if (r < 0)