From 9697662915e47a4797b05003cb1970fe2b01e530 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 23 Jan 2022 03:12:35 +0900 Subject: hostname: expose hardware serial through dbus Closes #22119. --- src/hostname/hostnamed.c | 89 +++++++++++++++++++++++++-- src/hostname/org.freedesktop.hostname1.policy | 20 ++++++ 2 files changed, 105 insertions(+), 4 deletions(-) (limited to 'src/hostname') diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c index 8a9a180d63..4637ac8817 100644 --- a/src/hostname/hostnamed.c +++ b/src/hostname/hostnamed.c @@ -205,6 +205,33 @@ static int get_hardware_model(char **ret) { return get_dmi_data("ID_MODEL_FROM_DATABASE", "ID_MODEL", ret); } +static int get_hardware_serial(char **ret) { + _cleanup_(sd_device_unrefp) sd_device *device = NULL; + _cleanup_free_ char *b = NULL; + const char *s = NULL; + int r; + + r = sd_device_new_from_syspath(&device, "/sys/class/dmi/id"); + if (r < 0) + return log_debug_errno(r, "Failed to open /sys/class/dmi/id device, ignoring: %m"); + + (void) sd_device_get_sysattr_value(device, "product_serial", &s); + if (isempty(s)) + /* Fallback to board serial */ + (void) sd_device_get_sysattr_value(device, "board_serial", &s); + + if (!isempty(s)) { + b = strdup(s); + if (!b) + return -ENOMEM; + } + + if (ret) + *ret = TAKE_PTR(b); + + return !isempty(s); +} + static const char* valid_chassis(const char *chassis) { assert(chassis); @@ -1051,8 +1078,51 @@ static int method_get_product_uuid(sd_bus_message *m, void *userdata, sd_bus_err return sd_bus_send(NULL, reply, NULL); } +static int method_get_hardware_serial(sd_bus_message *m, void *userdata, sd_bus_error *error) { + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; + _cleanup_free_ char *serial = NULL; + Context *c = userdata; + int interactive, r; + + assert(m); + assert(c); + + r = sd_bus_message_read(m, "b", &interactive); + if (r < 0) + return r; + + r = bus_verify_polkit_async( + m, + CAP_SYS_ADMIN, + "org.freedesktop.hostname1.get-hardware-serial", + NULL, + interactive, + UID_INVALID, + &c->polkit_registry, + error); + if (r < 0) + return r; + if (r == 0) + return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ + + r = get_hardware_serial(&serial); + if (r < 0) + return r; + + r = sd_bus_message_new_method_return(m, &reply); + if (r < 0) + return r; + + r = sd_bus_message_append(reply, "s", serial); + if (r < 0) + return r; + + return sd_bus_send(NULL, reply, NULL); +} + static int method_describe(sd_bus_message *m, void *userdata, sd_bus_error *error) { - _cleanup_free_ char *hn = NULL, *dhn = NULL, *in = NULL, *text = NULL, *chassis = NULL, *vendor = NULL, *model = NULL; + _cleanup_free_ char *hn = NULL, *dhn = NULL, *in = NULL, *text = NULL, + *chassis = NULL, *vendor = NULL, *model = NULL, *serial = NULL; _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; _cleanup_(json_variant_unrefp) JsonVariant *v = NULL; sd_id128_t product_uuid = SD_ID128_NULL; @@ -1067,7 +1137,7 @@ static int method_describe(sd_bus_message *m, void *userdata, sd_bus_error *erro r = bus_verify_polkit_async( m, CAP_SYS_ADMIN, - "org.freedesktop.hostname1.get-product-uuid", + "org.freedesktop.hostname1.get-description", NULL, false, UID_INVALID, @@ -1111,8 +1181,11 @@ static int method_describe(sd_bus_message *m, void *userdata, sd_bus_error *erro if (isempty(c->data[PROP_MODEL])) (void) get_hardware_model(&model); - if (privileged) /* The product UUID is only available to privileged clients */ - id128_get_product(&product_uuid); + if (privileged) { + /* The product UUID and hardware serial is only available to privileged clients */ + (void) id128_get_product(&product_uuid); + (void) get_hardware_serial(&serial); + } r = json_build(&v, JSON_BUILD_OBJECT( JSON_BUILD_PAIR("Hostname", JSON_BUILD_STRING(hn)), @@ -1132,6 +1205,7 @@ static int method_describe(sd_bus_message *m, void *userdata, sd_bus_error *erro JSON_BUILD_PAIR("OperatingSystemHomeURL", JSON_BUILD_STRING(c->data[PROP_OS_HOME_URL])), JSON_BUILD_PAIR("HardwareVendor", JSON_BUILD_STRING(vendor ?: c->data[PROP_VENDOR])), JSON_BUILD_PAIR("HardwareModel", JSON_BUILD_STRING(model ?: c->data[PROP_MODEL])), + JSON_BUILD_PAIR("HardwareSerial", JSON_BUILD_STRING(serial)), 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))); @@ -1229,6 +1303,13 @@ static const sd_bus_vtable hostname_vtable[] = { SD_BUS_PARAM(uuid), method_get_product_uuid, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD_WITH_NAMES("GetHardwareSerial", + "b", + SD_BUS_PARAM(interactive), + "s", + SD_BUS_PARAM(serial), + method_get_hardware_serial, + SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD_WITH_ARGS("Describe", SD_BUS_NO_ARGS, SD_BUS_RESULT("s", json), diff --git a/src/hostname/org.freedesktop.hostname1.policy b/src/hostname/org.freedesktop.hostname1.policy index dacea0ff0a..a86cead53e 100644 --- a/src/hostname/org.freedesktop.hostname1.policy +++ b/src/hostname/org.freedesktop.hostname1.policy @@ -57,4 +57,24 @@ + + Get hardware serial number + Authentication is required to get hardware serial number. + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + + + + Get system description + Authentication is required to get system description. + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + + -- cgit v1.2.1