From 19b8e712d8fc59c8fabe2607400874a65dcc0030 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 5 Jan 2024 16:34:33 +0100 Subject: [PATCH] hostnamed: expose local AF_VSOCK CID among other host info This is a host identifier of major relevance, since it is how you connect to this system if it is a VM, hence expose this nicely. --- man/org.freedesktop.hostname1.xml | 24 ++++++++++++++++++------ src/hostname/hostnamectl.c | 15 ++++++++++++++- src/hostname/hostnamed.c | 27 +++++++++++++++++++++++++-- units/systemd-hostnamed.service.in | 2 +- 4 files changed, 58 insertions(+), 10 deletions(-) diff --git a/man/org.freedesktop.hostname1.xml b/man/org.freedesktop.hostname1.xml index 577e64dcd7..61d9831ca6 100644 --- a/man/org.freedesktop.hostname1.xml +++ b/man/org.freedesktop.hostname1.xml @@ -99,6 +99,8 @@ node /org/freedesktop/hostname1 { readonly ay MachineID = [...]; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly ay BootID = [...]; + @org.freedesktop.DBus.Property.EmitsChangedSignal("const") + readonly u VSockCID = ...; }; interface org.freedesktop.DBus.Peer { ... }; interface org.freedesktop.DBus.Introspectable { ... }; @@ -120,10 +122,6 @@ node /org/freedesktop/hostname1 { - - - - @@ -196,6 +194,8 @@ node /org/freedesktop/hostname1 { + + Whenever the hostname or other metadata is changed via the daemon, @@ -287,6 +287,18 @@ node /org/freedesktop/hostname1 { purpose of those properties is to allow remote clients to access this information over D-Bus. Local clients can access the information directly. + MachineID expose the 128bit machine ID, see + machine-id5 for + details. + + BootID expose the 128bit boot ID, as per + /proc/sys/kernel/random/boot_id. + + VSockCID exposes the system's local AF_VSOCK CID (Context + Identifier, i.e. address) for the system, if one is available in the virtual machine environment. Set to + UINT32_MAX otherwise. See vsock7 for + details. + Methods @@ -440,8 +452,8 @@ node /org/freedesktop/hostname1 { OperatingSystemSupportEnd, FirmwareVendor, and FirmwareDate were added in version 253. - MachineID, and - BootID were added in version 256. + MachineID, BootID and + VSockCID were added in version 256. diff --git a/src/hostname/hostnamectl.c b/src/hostname/hostnamectl.c index 14fc160909..4b92ac2b23 100644 --- a/src/hostname/hostnamectl.c +++ b/src/hostname/hostnamectl.c @@ -24,6 +24,7 @@ #include "main-func.h" #include "parse-argument.h" #include "pretty-print.h" +#include "socket-util.h" #include "spawn-polkit-agent.h" #include "terminal-util.h" #include "verbs.h" @@ -58,6 +59,7 @@ typedef struct StatusInfo { usec_t firmware_date; sd_id128_t machine_id; sd_id128_t boot_id; + uint32_t vsock_cid; } StatusInfo; static const char* chassis_string_to_glyph(const char *chassis) { @@ -191,6 +193,14 @@ static int print_status_info(StatusInfo *i) { return table_log_add_error(r); } + if (i->vsock_cid != VMADDR_CID_ANY) { + r = table_add_many(table, + TABLE_FIELD, "AF_VSOCK CID", + TABLE_UINT32, i->vsock_cid); + if (r < 0) + return table_log_add_error(r); + } + if (!isempty(i->virtualization)) { r = table_add_many(table, TABLE_FIELD, "Virtualization", @@ -332,7 +342,9 @@ static int get_one_name(sd_bus *bus, const char* attr, char **ret) { } static int show_all_names(sd_bus *bus) { - StatusInfo info = {}; + StatusInfo info = { + .vsock_cid = VMADDR_CID_ANY, + }; static const struct bus_properties_map hostname_map[] = { { "Hostname", "s", NULL, offsetof(StatusInfo, hostname) }, @@ -354,6 +366,7 @@ static int show_all_names(sd_bus *bus) { { "FirmwareDate", "t", NULL, offsetof(StatusInfo, firmware_date) }, { "MachineID", "ay", bus_map_id128, offsetof(StatusInfo, machine_id) }, { "BootID", "ay", bus_map_id128, offsetof(StatusInfo, boot_id) }, + { "VSockCID", "u", NULL, offsetof(StatusInfo, vsock_cid) }, {} }, manager_map[] = { { "Virtualization", "s", NULL, offsetof(StatusInfo, virtualization) }, diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c index f0e643822a..d629a07d0f 100644 --- a/src/hostname/hostnamed.c +++ b/src/hostname/hostnamed.c @@ -6,6 +6,8 @@ #include #include +#include "sd-device.h" + #include "alloc-util.h" #include "bus-common-errors.h" #include "bus-get-properties.h" @@ -28,10 +30,10 @@ #include "os-util.h" #include "parse-util.h" #include "path-util.h" -#include "sd-device.h" #include "selinux-util.h" #include "service-util.h" #include "signal-util.h" +#include "socket-util.h" #include "stat-util.h" #include "string-table.h" #include "strv.h" @@ -1033,6 +1035,22 @@ static int property_get_boot_id( return bus_property_get_id128(bus, path, interface, property, reply, &id, error); } +static int property_get_vsock_cid( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) { + + unsigned local_cid = VMADDR_CID_ANY; + + (void) vsock_get_local_cid(&local_cid); + + return sd_bus_message_append(reply, "u", (uint32_t) local_cid); +} + static int method_set_hostname(sd_bus_message *m, void *userdata, sd_bus_error *error) { Context *c = ASSERT_PTR(userdata); const char *name; @@ -1333,6 +1351,7 @@ static int method_describe(sd_bus_message *m, void *userdata, sd_bus_error *erro _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; _cleanup_(json_variant_unrefp) JsonVariant *v = NULL; sd_id128_t machine_id, boot_id, product_uuid = SD_ID128_NULL; + unsigned local_cid = VMADDR_CID_ANY; Context *c = ASSERT_PTR(userdata); bool privileged; struct utsname u; @@ -1404,6 +1423,8 @@ static int method_describe(sd_bus_message *m, void *userdata, sd_bus_error *erro if (r < 0) return log_error_errno(r, "Failed to get boot ID: %m"); + (void) vsock_get_local_cid(&local_cid); + r = json_build(&v, JSON_BUILD_OBJECT( JSON_BUILD_PAIR("Hostname", JSON_BUILD_STRING(hn)), JSON_BUILD_PAIR("StaticHostname", JSON_BUILD_STRING(c->data[PROP_STATIC_HOSTNAME])), @@ -1430,7 +1451,8 @@ static int method_describe(sd_bus_message *m, void *userdata, sd_bus_error *erro JSON_BUILD_PAIR_ID128("MachineID", machine_id), JSON_BUILD_PAIR_ID128("BootID", boot_id), JSON_BUILD_PAIR_CONDITION(!sd_id128_is_null(product_uuid), "ProductUUID", JSON_BUILD_ID128(product_uuid)), - JSON_BUILD_PAIR_CONDITION(sd_id128_is_null(product_uuid), "ProductUUID", JSON_BUILD_NULL))); + JSON_BUILD_PAIR_CONDITION(sd_id128_is_null(product_uuid), "ProductUUID", JSON_BUILD_NULL), + JSON_BUILD_PAIR_CONDITION(local_cid != VMADDR_CID_ANY, "VSockCID", JSON_BUILD_UNSIGNED(local_cid)))); if (r < 0) return log_error_errno(r, "Failed to build JSON data: %m"); @@ -1475,6 +1497,7 @@ static const sd_bus_vtable hostname_vtable[] = { SD_BUS_PROPERTY("FirmwareDate", "t", property_get_firmware_date, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("MachineID", "ay", property_get_machine_id, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("BootID", "ay", property_get_boot_id, 0, SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("VSockCID", "u", property_get_vsock_cid, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_METHOD_WITH_ARGS("SetHostname", SD_BUS_ARGS("s", hostname, "b", interactive), diff --git a/units/systemd-hostnamed.service.in b/units/systemd-hostnamed.service.in index 31b45e0fa8..1cc15dd7cf 100644 --- a/units/systemd-hostnamed.service.in +++ b/units/systemd-hostnamed.service.in @@ -22,7 +22,7 @@ IPAddressDeny=any LockPersonality=yes MemoryDenyWriteExecute=yes NoNewPrivileges=yes -PrivateDevices=yes +DeviceAllow=/dev/vsock r PrivateNetwork=yes PrivateTmp=yes ProtectProc=invisible