diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-01-22 19:12:35 +0100 |
---|---|---|
committer | Luca Boccassi <luca.boccassi@gmail.com> | 2022-01-24 22:09:37 +0100 |
commit | 9697662915e47a4797b05003cb1970fe2b01e530 (patch) | |
tree | 62cfef6e12b0052fc87562a6834685b867efd012 | |
parent | NEWS: update (diff) | |
download | systemd-9697662915e47a4797b05003cb1970fe2b01e530.tar.xz systemd-9697662915e47a4797b05003cb1970fe2b01e530.zip |
hostname: expose hardware serial through dbus
Closes #22119.
-rw-r--r-- | man/org.freedesktop.hostname1.xml | 6 | ||||
-rw-r--r-- | src/hostname/hostnamed.c | 89 | ||||
-rw-r--r-- | src/hostname/org.freedesktop.hostname1.policy | 20 |
3 files changed, 111 insertions, 4 deletions
diff --git a/man/org.freedesktop.hostname1.xml b/man/org.freedesktop.hostname1.xml index 4f51cd5e80..5e3bb7807d 100644 --- a/man/org.freedesktop.hostname1.xml +++ b/man/org.freedesktop.hostname1.xml @@ -58,6 +58,8 @@ node /org/freedesktop/hostname1 { in b interactive); GetProductUUID(in b interactive, out ay uuid); + GetHardwareSerial(in b interactive, + out s serial); Describe(out s json); properties: readonly s Hostname = '...'; @@ -93,6 +95,8 @@ node /org/freedesktop/hostname1 { }; </programlisting> + <!--method GetHardwareSerial is not documented!--> + <!--property HardwareVendor is not documented!--> <!--property HardwareModel is not documented!--> @@ -119,6 +123,8 @@ node /org/freedesktop/hostname1 { <variablelist class="dbus-method" generated="True" extra-ref="GetProductUUID()"/> + <variablelist class="dbus-method" generated="True" extra-ref="GetHardwareSerial()"/> + <variablelist class="dbus-method" generated="True" extra-ref="Describe()"/> <variablelist class="dbus-property" generated="True" extra-ref="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 @@ </defaults> </action> + <action id="org.freedesktop.hostname1.get-hardware-serial"> + <description gettext-domain="systemd">Get hardware serial number</description> + <message gettext-domain="systemd">Authentication is required to get hardware serial number.</message> + <defaults> + <allow_any>auth_admin_keep</allow_any> + <allow_inactive>auth_admin_keep</allow_inactive> + <allow_active>auth_admin_keep</allow_active> + </defaults> + </action> + + <action id="org.freedesktop.hostname1.get-description"> + <description gettext-domain="systemd">Get system description</description> + <message gettext-domain="systemd">Authentication is required to get system description.</message> + <defaults> + <allow_any>auth_admin_keep</allow_any> + <allow_inactive>auth_admin_keep</allow_inactive> + <allow_active>auth_admin_keep</allow_active> + </defaults> + </action> + </policyconfig> |