]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
hostname: expose hardware serial through dbus
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sat, 22 Jan 2022 18:12:35 +0000 (03:12 +0900)
committerLuca Boccassi <luca.boccassi@gmail.com>
Mon, 24 Jan 2022 21:09:37 +0000 (21:09 +0000)
Closes #22119.

man/org.freedesktop.hostname1.xml
src/hostname/hostnamed.c
src/hostname/org.freedesktop.hostname1.policy

index 4f51cd5e806e831c332daed973b62df2db69d785..5e3bb7807dc9278e09da3655b221a3693a861505 100644 (file)
@@ -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"/>
index 8a9a180d635e61de8bde6f18f84581bf7226382d..4637ac8817838293f602f6f539d4292e51569414 100644 (file)
@@ -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),
index dacea0ff0acd762c2fb7cc66bd99ac586d82ee1e..a86cead53ed126cd55ccbe0e982033e22fb9b4d0 100644 (file)
                 </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>