readonly s SSHPrivateKeyPath = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
readonly s State = '...';
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
+ readonly u UID = ...;
};
interface org.freedesktop.DBus.Peer { ... };
interface org.freedesktop.DBus.Introspectable { ... };
<variablelist class="dbus-property" generated="True" extra-ref="State"/>
+ <variablelist class="dbus-property" generated="True" extra-ref="UID"/>
+
<!--End of Autogenerated section-->
<refsect2>
<para><varname>Subgroup</varname> contains the sub-control-group path this machine's processes reside
in, relative to the specified unit's control group.</para>
+
+ <para><varname>UID</varname> contains the numeric UNIX UID of the user who registered the machine.</para>
</refsect2>
</refsect1>
<function>CopyToWithFlags()</function> were added in version 252.</para>
<para><function>GetSSHInfo()</function>, <varname>VSockCID</varname>, <varname>SSHAddress</varname>,
and <varname>SSHPrivateKeyPath</varname> were added in version 256.</para>
- <para><varname>LeaderPIDFDId</varname> and <varname>Subgroup</varname> were added in version 258.</para>
+ <para><varname>LeaderPIDFDId</varname>, <varname>Subgroup</varname>, and <varname>UID</varname> were
+ added in version 258.</para>
</refsect2>
</refsect1>
NULL
};
- r = bus_verify_polkit_async(
+ r = bus_verify_polkit_async_full(
message,
"org.freedesktop.machine1.manage-machines",
details,
+ m->uid,
+ /* flags= */ 0,
&m->manager->polkit_registry,
error);
if (r < 0)
NULL
};
- r = bus_verify_polkit_async(
+ r = bus_verify_polkit_async_full(
message,
"org.freedesktop.machine1.manage-machines",
details,
+ m->uid,
+ /* flags= */ 0,
&m->manager->polkit_registry,
error);
if (r < 0)
NULL
};
- r = bus_verify_polkit_async(
+ r = bus_verify_polkit_async_full(
message,
"org.freedesktop.machine1.manage-machines",
details,
+ m->uid,
+ /* flags= */ 0,
&m->manager->polkit_registry,
error);
if (r < 0)
NULL
};
- r = bus_verify_polkit_async(
+ r = bus_verify_polkit_async_full(
message,
m->class == MACHINE_HOST ? "org.freedesktop.machine1.host-open-pty" : "org.freedesktop.machine1.open-pty",
details,
+ m->uid,
+ /* flags= */ 0,
&m->manager->polkit_registry,
error);
if (r < 0)
NULL
};
- r = bus_verify_polkit_async(
+ r = bus_verify_polkit_async_full(
message,
m->class == MACHINE_HOST ? "org.freedesktop.machine1.host-login" : "org.freedesktop.machine1.login",
details,
+ m->uid,
+ /* flags= */ 0,
&m->manager->polkit_registry,
error);
if (r < 0)
NULL
};
- r = bus_verify_polkit_async(
+ r = bus_verify_polkit_async_full(
message,
m->class == MACHINE_HOST ? "org.freedesktop.machine1.host-shell" : "org.freedesktop.machine1.shell",
details,
+ m->uid,
+ /* flags= */ 0,
&m->manager->polkit_registry,
error);
if (r < 0)
NULL
};
+ /* NB: For now not opened up to owner of machine without auth */
r = bus_verify_polkit_async(
message,
"org.freedesktop.machine1.manage-machines",
NULL
};
+ /* NB: For now not opened up to owner of machine without auth */
r = bus_verify_polkit_async(
message,
"org.freedesktop.machine1.manage-machines",
NULL
};
+ /* NB: For now not opened up to owner of machine without auth */
r = bus_verify_polkit_async(
message,
"org.freedesktop.machine1.manage-machines",
SD_BUS_PROPERTY("SSHAddress", "s", NULL, offsetof(Machine, ssh_address), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("SSHPrivateKeyPath", "s", NULL, offsetof(Machine, ssh_private_key_path), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("State", "s", property_get_state, 0, 0),
+ SD_BUS_PROPERTY("UID", "u", bus_property_get_uid, offsetof(Machine, uid), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_METHOD("Terminate",
NULL,
return r;
}
+ r = sd_varlink_get_peer_uid(link, &machine->uid);
+ if (r < 0)
+ return r;
+
r = machine_link(manager, machine);
if (r == -EEXIST)
return sd_varlink_error(link, VARLINK_ERROR_MACHINE_EXISTS, NULL);
Manager *manager = ASSERT_PTR(machine->manager);
int r;
- r = varlink_verify_polkit_async(
+ r = varlink_verify_polkit_async_full(
link,
manager->bus,
"org.freedesktop.machine1.manage-machines",
(const char**) STRV_MAKE("name", machine->name,
"verb", "unregister"),
+ machine->uid,
+ /* flags= */ 0,
&manager->polkit_registry);
if (r <= 0)
return r;
Manager *manager = ASSERT_PTR(machine->manager);
int r;
- r = varlink_verify_polkit_async(
+ r = varlink_verify_polkit_async_full(
link,
manager->bus,
"org.freedesktop.machine1.manage-machines",
(const char**) STRV_MAKE("name", machine->name,
"verb", "terminate"),
+ machine->uid,
+ /* flags= */ 0,
&manager->polkit_registry);
if (r <= 0)
return r;
return sd_varlink_error_invalid_parameter_name(link, "whom");
}
- r = varlink_verify_polkit_async(
+ r = varlink_verify_polkit_async_full(
link,
manager->bus,
"org.freedesktop.machine1.manage-machines",
(const char**) STRV_MAKE("name", machine->name,
"verb", "kill"),
+ machine->uid,
+ /* flags= */ 0,
&manager->polkit_registry);
if (r <= 0)
return r;
return r;
polkit_details = machine_open_polkit_details(p.mode, machine->name, user, path, command_line);
- r = varlink_verify_polkit_async(
+ r = varlink_verify_polkit_async_full(
link,
manager->bus,
machine_open_polkit_action(p.mode, machine->class),
(const char**) polkit_details,
+ machine->uid,
+ /* flags= */ 0,
&manager->polkit_registry);
if (r <= 0)
return r;
if (machine->class != MACHINE_CONTAINER)
return sd_varlink_error(link, VARLINK_ERROR_MACHINE_NOT_SUPPORTED, NULL);
+ /* NB: For now not opened up to owner of machine without auth */
r = varlink_verify_polkit_async(
link,
manager->bus,
if (machine->class != MACHINE_CONTAINER)
return sd_varlink_error(link, VARLINK_ERROR_MACHINE_NOT_SUPPORTED, NULL);
+ /* NB: For now not opened up to owner of machine without auth */
r = varlink_verify_polkit_async(
link,
manager->bus,
Manager *manager = ASSERT_PTR(machine->manager);
int r;
+ /* NB: For now not opened up to owner of machine without auth */
r = varlink_verify_polkit_async(
link,
manager->bus,
fprintf(f,
"# This is private data. Do not parse.\n"
- "NAME=%s\n",
- m->name);
+ "NAME=%s\n"
+ "UID=" UID_FMT "\n",
+ m->name,
+ m->uid);
/* We continue to call this "SCOPE=" because it is internal only, and we want to stay compatible with old files */
env_file_fputs_assignment(f, "SCOPE=", m->unit);
int machine_load(Machine *m) {
_cleanup_free_ char *name = NULL, *realtime = NULL, *monotonic = NULL, *id = NULL, *leader = NULL, *leader_pidfdid = NULL,
- *class = NULL, *netif = NULL, *vsock_cid = NULL;
+ *class = NULL, *netif = NULL, *vsock_cid = NULL, *uid = NULL;
int r;
assert(m);
"NETIF", &netif,
"VSOCK_CID", &vsock_cid,
"SSH_ADDRESS", &m->ssh_address,
- "SSH_PRIVATE_KEY_PATH", &m->ssh_private_key_path);
+ "SSH_PRIVATE_KEY_PATH", &m->ssh_private_key_path,
+ "UID", &uid);
if (r == -ENOENT)
return 0;
if (r < 0)
log_warning_errno(r, "Failed to parse AF_VSOCK CID, ignoring: %s", vsock_cid);
}
+ r = parse_uid(uid, &m->uid);
+ if (r < 0)
+ log_warning_errno(r, "Failed to parse owning UID, ignoring: %s", uid);
+
return r;
}
if (r < 0)
return r;
- r = sd_bus_message_append(m, "(sv)(sv)(sv)(sv)",
- "Delegate", "b", 1,
- "CollectMode", "s", "inactive-or-failed",
- "AddRef", "b", 1,
- "TasksMax", "t", UINT64_C(16384));
+ r = sd_bus_message_append(
+ m, "(sv)(sv)(sv)(sv)",
+ "Delegate", "b", 1,
+ "CollectMode", "s", "inactive-or-failed",
+ "AddRef", "b", 1,
+ "TasksMax", "t", UINT64_C(16384));
if (r < 0)
return r;
+ if (machine->uid != 0) {
+ _cleanup_free_ char *u = NULL;
+
+ if (asprintf(&u, UID_FMT, machine->uid) < 0)
+ return -ENOMEM;
+
+ r = sd_bus_message_append(
+ m, "(sv)",
+ "User", "s", u);
+ if (r < 0)
+ return r;
+ }
+
if (more_properties) {
r = sd_bus_message_copy(m, more_properties, true);
if (r < 0)
char *name;
sd_id128_t id;
+ uid_t uid;
+
MachineClass class;
char *state_file;
struct dual_timestamp timestamp;
int *netif;
size_t n_netif;
+ uid_t uid;
} MachineStatusInfo;
static void machine_status_info_clear(MachineStatusInfo *info) {
} else if (i->class)
printf("\t Class: %s\n", i->class);
+ if (i->uid != 0)
+ printf("\t UID: " UID_FMT "\n", i->uid);
+
if (i->root_directory)
printf("\t Root: %s\n", i->root_directory);
{ "TimestampMonotonic", "t", NULL, offsetof(MachineStatusInfo, timestamp.monotonic) },
{ "Id", "ay", bus_map_id128, offsetof(MachineStatusInfo, id) },
{ "NetworkInterfaces", "ai", map_netif, 0 },
+ { "UID", "u", NULL, offsetof(MachineStatusInfo, uid) },
{}
};
if (hashmap_get(manager->machines, name))
return sd_bus_error_setf(error, BUS_ERROR_MACHINE_EXISTS, "Machine '%s' already exists", name);
+ _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
+ r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
+ if (r < 0)
+ return r;
+
+ uid_t uid;
+ r = sd_bus_creds_get_euid(creds, &uid);
+ if (r < 0)
+ return r;
+
const char *details[] = {
"name", name,
"class", machine_class_to_string(c),
m->leader = TAKE_PIDREF(pidref);
m->class = c;
m->id = id;
+ m->uid = uid;
if (!isempty(service)) {
m->service = strdup(service);
JSON_BUILD_PAIR_STRING_NON_EMPTY("sshPrivateKeyPath", m->ssh_private_key_path),
JSON_BUILD_PAIR_VARIANT_NON_NULL("addresses", addr_array),
JSON_BUILD_PAIR_STRV_ENV_PAIR_NON_EMPTY("OSRelease", os_release),
- JSON_BUILD_PAIR_UNSIGNED_NOT_EQUAL("UIDShift", shift, UID_INVALID));
+ JSON_BUILD_PAIR_UNSIGNED_NOT_EQUAL("UIDShift", shift, UID_INVALID),
+ SD_JSON_BUILD_PAIR_UNSIGNED("UID", m->uid));
if (r < 0)
return r;
SD_VARLINK_FIELD_COMMENT("Return the base UID/GID of the machine"),
SD_VARLINK_DEFINE_OUTPUT(UIDShift, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("Subcgroup path of the machine, relative to the unit's cgroup path"),
- SD_VARLINK_DEFINE_OUTPUT(Subgroup, SD_VARLINK_STRING, SD_VARLINK_NULLABLE));
+ SD_VARLINK_DEFINE_OUTPUT(Subgroup, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
+ SD_VARLINK_FIELD_COMMENT("Numeric UNIX UID of the user who registered the machine"),
+ SD_VARLINK_DEFINE_OUTPUT(UID, SD_VARLINK_INT, SD_VARLINK_NULLABLE));
static SD_VARLINK_DEFINE_ENUM_TYPE(
MachineOpenMode,