]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/hostname/hostnamed.c
tree-wide: use ASSERT_PTR more
[thirdparty/systemd.git] / src / hostname / hostnamed.c
index bcd244986198797cb90a24f7e81245236a021608..d59c783dbc49c35427627c45b6aa8b69475c9d7e 100644 (file)
@@ -43,7 +43,7 @@
 
 /* Properties we cache are indexed by an enum, to make invalidation easy and systematic (as we can iterate
  * through them all, and they are uniformly strings). */
-enum {
+typedef enum {
         /* Read from /etc/hostname */
         PROP_STATIC_HOSTNAME,
 
@@ -53,6 +53,8 @@ enum {
         PROP_CHASSIS,
         PROP_DEPLOYMENT,
         PROP_LOCATION,
+        PROP_HARDWARE_VENDOR,
+        PROP_HARDWARE_MODEL,
 
         /* Read from /etc/os-release (or /usr/lib/os-release) */
         PROP_OS_PRETTY_NAME,
@@ -60,7 +62,7 @@ enum {
         PROP_OS_HOME_URL,
         _PROP_MAX,
         _PROP_INVALID = -EINVAL,
-};
+} HostProperty;
 
 typedef struct Context {
         char *data[_PROP_MAX];
@@ -126,14 +128,18 @@ static void context_read_machine_info(Context *c) {
                       (UINT64_C(1) << PROP_ICON_NAME) |
                       (UINT64_C(1) << PROP_CHASSIS) |
                       (UINT64_C(1) << PROP_DEPLOYMENT) |
-                      (UINT64_C(1) << PROP_LOCATION));
+                      (UINT64_C(1) << PROP_LOCATION) |
+                      (UINT64_C(1) << PROP_HARDWARE_VENDOR) |
+                      (UINT64_C(1) << PROP_HARDWARE_MODEL));
 
         r = parse_env_file(NULL, "/etc/machine-info",
                            "PRETTY_HOSTNAME", &c->data[PROP_PRETTY_HOSTNAME],
                            "ICON_NAME", &c->data[PROP_ICON_NAME],
                            "CHASSIS", &c->data[PROP_CHASSIS],
                            "DEPLOYMENT", &c->data[PROP_DEPLOYMENT],
-                           "LOCATION", &c->data[PROP_LOCATION]);
+                           "LOCATION", &c->data[PROP_LOCATION],
+                           "HARDWARE_VENDOR", &c->data[PROP_HARDWARE_VENDOR],
+                           "HARDWARE_MODEL", &c->data[PROP_HARDWARE_MODEL]);
         if (r < 0 && r != -ENOENT)
                 log_warning_errno(r, "Failed to read /etc/machine-info, ignoring: %m");
 
@@ -166,6 +172,81 @@ static void context_read_os_release(Context *c) {
         c->etc_os_release_stat = current_stat;
 }
 
+static int get_dmi_data(const char *database_key, const char *regular_key, 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");
+
+        if (database_key)
+                (void) sd_device_get_property_value(device, database_key, &s);
+        if (!s && regular_key)
+                (void) sd_device_get_property_value(device, regular_key, &s);
+
+        if (!ret)
+                return !!s;
+
+        if (s) {
+                b = strdup(s);
+                if (!b)
+                        return -ENOMEM;
+        }
+
+        *ret = TAKE_PTR(b);
+        return !!s;
+}
+
+static int get_hardware_vendor(char **ret) {
+        return get_dmi_data("ID_VENDOR_FROM_DATABASE", "ID_VENDOR", ret);
+}
+
+static int get_hardware_model(char **ret) {
+        return get_dmi_data("ID_MODEL_FROM_DATABASE", "ID_MODEL", ret);
+}
+
+static int get_hardware_firmware_data(const char *sysattr, char **ret) {
+        _cleanup_(sd_device_unrefp) sd_device *device = NULL;
+        _cleanup_free_ char *b = NULL;
+        const char *s = NULL;
+        int r;
+
+        assert(sysattr);
+
+        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, sysattr, &s);
+        if (!isempty(s)) {
+                b = strdup(s);
+                if (!b)
+                        return -ENOMEM;
+        }
+
+        if (ret)
+                *ret = TAKE_PTR(b);
+
+        return !isempty(s);
+}
+
+static int get_hardware_serial(char **ret) {
+         int r;
+
+         r = get_hardware_firmware_data("product_serial", ret);
+         if (r <= 0)
+                return get_hardware_firmware_data("board_serial", ret);
+
+         return r;
+}
+
+static int get_firmware_version(char **ret) {
+         return get_hardware_firmware_data("bios_version", ret);
+}
+
 static const char* valid_chassis(const char *chassis) {
         assert(chassis);
 
@@ -191,9 +272,10 @@ static bool valid_deployment(const char *deployment) {
 
 static const char* fallback_chassis(void) {
         const char *chassis;
-        char *type;
+        _cleanup_free_ char *type = NULL;
+        Virtualization v;
         unsigned t;
-        int v, r;
+        int r;
 
         v = detect_virtualization();
         if (v < 0)
@@ -210,27 +292,28 @@ static const char* fallback_chassis(void) {
         }
 
         r = safe_atou(type, &t);
-        free(type);
         if (r < 0) {
-                log_debug_errno(r, "Failed to parse DMI chassis type, ignoring: %m");
+                log_debug_errno(r, "Failed to parse DMI chassis type \"%s\", ignoring: %m", type);
                 goto try_acpi;
         }
 
         /* We only list the really obvious cases here. The DMI data is unreliable enough, so let's not do any
-           additional guesswork on top of that.
-
-           See the SMBIOS Specification 3.0 section 7.4.1 for details about the values listed here:
-
-           https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.0.0.pdf
+         * additional guesswork on top of that.
+         *
+         * See the SMBIOS Specification 3.5.0 section 7.4.1 for details about the values listed here:
+         *
+         * https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.5.0.pdf
          */
 
         switch (t) {
 
-        case 0x3: /* Desktop */
-        case 0x4: /* Low Profile Desktop */
-        case 0x6: /* Mini Tower */
-        case 0x7: /* Tower */
-        case 0xD: /* All in one (i.e. PC built into monitor) */
+        case 0x03: /* Desktop */
+        case 0x04: /* Low Profile Desktop */
+        case 0x06: /* Mini Tower */
+        case 0x07: /* Tower */
+        case 0x0D: /* All in one (i.e. PC built into monitor) */
+        case 0x23: /* Mini PC */
+        case 0x24: /* Stick PC */
                 return "desktop";
 
         case 0x8: /* Portable */
@@ -254,11 +337,16 @@ static const char* fallback_chassis(void) {
         case 0x20: /* Detachable */
                 return "convertible";
 
+        case 0x21: /* IoT Gateway */
+        case 0x22: /* Embedded PC */
+                return "embedded";
+
         default:
                 log_debug("Unhandled DMI chassis type 0x%02x, ignoring.", t);
         }
 
 try_acpi:
+        type = mfree(type);
         r = read_one_line_file("/sys/firmware/acpi/pm_profile", &type);
         if (r < 0) {
                 log_debug_errno(r, "Failed read ACPI PM profile, ignoring: %m");
@@ -266,9 +354,8 @@ try_acpi:
         }
 
         r = safe_atou(type, &t);
-        free(type);
         if (r < 0) {
-                log_debug_errno(r, "Failed parse ACPI PM profile, ignoring: %m");
+                log_debug_errno(r, "Failed parse ACPI PM profile \"%s\", ignoring: %m", type);
                 goto try_devicetree;
         }
 
@@ -279,7 +366,7 @@ try_acpi:
          * http://www.acpi.info/DOWNLOADS/ACPIspec50.pdf
          */
 
-        switch(t) {
+        switch (t) {
 
         case 1: /* Desktop */
         case 3: /* Workstation */
@@ -302,7 +389,8 @@ try_acpi:
         }
 
 try_devicetree:
-        r = read_one_line_file("/sys/firmware/devicetree/base/chassis-type", &type);
+        type = mfree(type);
+        r = read_one_line_file("/proc/device-tree/chassis-type", &type);
         if (r < 0) {
                 log_debug_errno(r, "Failed to read device-tree chassis type, ignoring: %m");
                 return NULL;
@@ -314,22 +402,35 @@ try_devicetree:
          * https://github.com/devicetree-org/devicetree-specification/blob/master/source/chapter3-devicenodes.rst */
         chassis = valid_chassis(type);
         if (!chassis)
-                log_debug("Invalid device-tree chassis type '%s', ignoring.", type);
-
-        free(type);
-
+                log_debug("Invalid device-tree chassis type \"%s\", ignoring.", type);
         return chassis;
 }
 
-static char* context_fallback_icon_name(Context *c) {
-        const char *chassis;
+static char* context_get_chassis(Context *c) {
+        const char *fallback;
+        char *dmi;
 
         assert(c);
 
         if (!isempty(c->data[PROP_CHASSIS]))
-                return strjoin("computer-", c->data[PROP_CHASSIS]);
+                return strdup(c->data[PROP_CHASSIS]);
+
+        if (get_dmi_data("ID_CHASSIS", NULL, &dmi) > 0)
+                return dmi;
+
+        fallback = fallback_chassis();
+        if (fallback)
+                return strdup(fallback);
+
+        return NULL;
+}
+
+static char* context_fallback_icon_name(Context *c) {
+        _cleanup_free_ char *chassis = NULL;
+
+        assert(c);
 
-        chassis = fallback_chassis();
+        chassis = context_get_chassis(c);
         if (chassis)
                 return strjoin("computer-", chassis);
 
@@ -467,42 +568,40 @@ static int context_write_data_machine_info(Context *c) {
         return 0;
 }
 
-static int get_dmi_data(const char *database_key, const char *regular_key, char **ret) {
-        _cleanup_(sd_device_unrefp) sd_device *device = NULL;
-        _cleanup_free_ char *b = NULL;
-        const char *s = NULL;
-        int r;
+static int property_get_hardware_property(
+                sd_bus_message *reply,
+                Context *c,
+                HostProperty prop,
+                int (*getter)(char **)) {
 
-        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");
+        _cleanup_free_ char *from_dmi = NULL;
 
-        if (database_key)
-                (void) sd_device_get_property_value(device, database_key, &s);
-        if (!s && regular_key)
-                (void) sd_device_get_property_value(device, regular_key, &s);
+        assert(reply);
+        assert(c);
+        assert(IN_SET(prop, PROP_HARDWARE_VENDOR, PROP_HARDWARE_MODEL));
+        assert(getter);
 
-        if (s) {
-                b = strdup(s);
-                if (!b)
-                        return -ENOMEM;
-        }
+        context_read_machine_info(c);
 
-        if (ret)
-                *ret = TAKE_PTR(b);
+        if (isempty(c->data[prop]))
+                (void) getter(&from_dmi);
 
-        return !!s;
+        return sd_bus_message_append(reply, "s", from_dmi ?: c->data[prop]);
 }
 
-static int get_hardware_vendor(char **ret) {
-        return get_dmi_data("ID_VENDOR_FROM_DATABASE", "ID_VENDOR", ret);
-}
+static int property_get_hardware_vendor(
+                sd_bus *bus,
+                const char *path,
+                const char *interface,
+                const char *property,
+                sd_bus_message *reply,
+                void *userdata,
+                sd_bus_error *error) {
 
-static int get_hardware_model(char **ret) {
-        return get_dmi_data("ID_MODEL_FROM_DATABASE", "ID_MODEL", ret);
+        return property_get_hardware_property(reply, userdata, PROP_HARDWARE_VENDOR, get_hardware_vendor);
 }
 
-static int property_get_hardware_vendor(
+static int property_get_hardware_model(
                 sd_bus *bus,
                 const char *path,
                 const char *interface,
@@ -511,13 +610,10 @@ static int property_get_hardware_vendor(
                 void *userdata,
                 sd_bus_error *error) {
 
-        _cleanup_free_ char *vendor = NULL;
-
-        (void) get_hardware_vendor(&vendor);
-        return sd_bus_message_append(reply, "s", vendor);
+        return property_get_hardware_property(reply, userdata, PROP_HARDWARE_MODEL, get_hardware_model);
 }
 
-static int property_get_hardware_model(
+static int property_get_firmware_version(
                 sd_bus *bus,
                 const char *path,
                 const char *interface,
@@ -526,10 +622,11 @@ static int property_get_hardware_model(
                 void *userdata,
                 sd_bus_error *error) {
 
-        _cleanup_free_ char *model = NULL;
+        _cleanup_free_ char *firmware_version = NULL;
+
+        (void) get_firmware_version(&firmware_version);
 
-        (void) get_hardware_model(&model);
-        return sd_bus_message_append(reply, "s", model);
+        return sd_bus_message_append(reply, "s", firmware_version);
 }
 
 static int property_get_hostname(
@@ -566,8 +663,7 @@ static int property_get_static_hostname(
                 void *userdata,
                 sd_bus_error *error) {
 
-        Context *c = userdata;
-        assert(c);
+        Context *c = ASSERT_PTR(userdata);
 
         context_read_etc_hostname(c);
 
@@ -633,8 +729,7 @@ static int property_get_hostname_source(
                 void *userdata,
                 sd_bus_error *error) {
 
-        Context *c = userdata;
-        assert(c);
+        Context *c = ASSERT_PTR(userdata);
 
         context_read_etc_hostname(c);
         context_determine_hostname_source(c);
@@ -727,17 +822,14 @@ static int property_get_chassis(
                 void *userdata,
                 sd_bus_error *error) {
 
+        _cleanup_free_ char *chassis = NULL;
         Context *c = userdata;
-        const char *name;
 
         context_read_machine_info(c);
 
-        if (isempty(c->data[PROP_CHASSIS]))
-                name = fallback_chassis();
-        else
-                name = c->data[PROP_CHASSIS];
+        chassis = context_get_chassis(c);
 
-        return sd_bus_message_append(reply, "s", name);
+        return sd_bus_message_append(reply, "s", chassis);
 }
 
 static int property_get_uname_field(
@@ -757,12 +849,11 @@ static int property_get_uname_field(
 }
 
 static int method_set_hostname(sd_bus_message *m, void *userdata, sd_bus_error *error) {
-        Context *c = userdata;
+        Context *c = ASSERT_PTR(userdata);
         const char *name;
         int interactive, r;
 
         assert(m);
-        assert(c);
 
         r = sd_bus_message_read(m, "sb", &name, &interactive);
         if (r < 0)
@@ -804,13 +895,12 @@ static int method_set_hostname(sd_bus_message *m, void *userdata, sd_bus_error *
 }
 
 static int method_set_static_hostname(sd_bus_message *m, void *userdata, sd_bus_error *error) {
-        Context *c = userdata;
+        Context *c = ASSERT_PTR(userdata);
         const char *name;
         int interactive;
         int r;
 
         assert(m);
-        assert(c);
 
         r = sd_bus_message_read(m, "sb", &name, &interactive);
         if (r < 0)
@@ -974,12 +1064,11 @@ static int method_set_location(sd_bus_message *m, void *userdata, sd_bus_error *
 
 static int method_get_product_uuid(sd_bus_message *m, void *userdata, sd_bus_error *error) {
         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
-        Context *c = userdata;
+        Context *c = ASSERT_PTR(userdata);
         int interactive, r;
         sd_id128_t uuid;
 
         assert(m);
-        assert(c);
 
         r = sd_bus_message_read(m, "b", &interactive);
         if (r < 0)
@@ -1022,24 +1111,60 @@ 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 = ASSERT_PTR(userdata);
+        int r;
+
+        assert(m);
+
+        r = bus_verify_polkit_async(
+                        m,
+                        CAP_SYS_ADMIN,
+                        "org.freedesktop.hostname1.get-hardware-serial",
+                        NULL,
+                        false,
+                        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, *vendor = NULL, *model = NULL;
+        _cleanup_free_ char *hn = NULL, *dhn = NULL, *in = NULL, *text = NULL,
+                *chassis = NULL, *vendor = NULL, *model = NULL, *serial = NULL, *firmware_version = 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;
-        const char *chassis = NULL;
-        Context *c = userdata;
+        Context *c = ASSERT_PTR(userdata);
         bool privileged;
         struct utsname u;
         int r;
 
         assert(m);
-        assert(c);
 
         r = bus_verify_polkit_async(
                         m,
                         CAP_SYS_ADMIN,
-                        "org.freedesktop.hostname1.get-product-uuid",
+                        "org.freedesktop.hostname1.get-description",
                         NULL,
                         false,
                         UID_INVALID,
@@ -1074,16 +1199,21 @@ static int method_describe(sd_bus_message *m, void *userdata, sd_bus_error *erro
         if (isempty(c->data[PROP_ICON_NAME]))
                 in = context_fallback_icon_name(c);
 
-        if (isempty(c->data[PROP_CHASSIS]))
-                chassis = fallback_chassis();
+        chassis = context_get_chassis(c);
 
         assert_se(uname(&u) >= 0);
 
-        (void) get_hardware_vendor(&vendor);
-        (void) get_hardware_model(&model);
+        if (isempty(c->data[PROP_HARDWARE_VENDOR]))
+                (void) get_hardware_vendor(&vendor);
+        if (isempty(c->data[PROP_HARDWARE_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);
+        }
+        (void) get_firmware_version(&firmware_version);
 
         r = json_build(&v, JSON_BUILD_OBJECT(
                                        JSON_BUILD_PAIR("Hostname", JSON_BUILD_STRING(hn)),
@@ -1092,7 +1222,7 @@ static int method_describe(sd_bus_message *m, void *userdata, sd_bus_error *erro
                                        JSON_BUILD_PAIR("DefaultHostname", JSON_BUILD_STRING(dhn)),
                                        JSON_BUILD_PAIR("HostnameSource", JSON_BUILD_STRING(hostname_source_to_string(c->hostname_source))),
                                        JSON_BUILD_PAIR("IconName", JSON_BUILD_STRING(in ?: c->data[PROP_ICON_NAME])),
-                                       JSON_BUILD_PAIR("Chassis", JSON_BUILD_STRING(chassis ?: c->data[PROP_CHASSIS])),
+                                       JSON_BUILD_PAIR("Chassis", JSON_BUILD_STRING(chassis)),
                                        JSON_BUILD_PAIR("Deployment", JSON_BUILD_STRING(c->data[PROP_DEPLOYMENT])),
                                        JSON_BUILD_PAIR("Location", JSON_BUILD_STRING(c->data[PROP_LOCATION])),
                                        JSON_BUILD_PAIR("KernelName", JSON_BUILD_STRING(u.sysname)),
@@ -1101,8 +1231,10 @@ static int method_describe(sd_bus_message *m, void *userdata, sd_bus_error *erro
                                        JSON_BUILD_PAIR("OperatingSystemPrettyName", JSON_BUILD_STRING(c->data[PROP_OS_PRETTY_NAME])),
                                        JSON_BUILD_PAIR("OperatingSystemCPEName", JSON_BUILD_STRING(c->data[PROP_OS_CPE_NAME])),
                                        JSON_BUILD_PAIR("OperatingSystemHomeURL", JSON_BUILD_STRING(c->data[PROP_OS_HOME_URL])),
-                                       JSON_BUILD_PAIR("HardwareVendor", JSON_BUILD_STRING(vendor)),
-                                       JSON_BUILD_PAIR("HardwareModel", JSON_BUILD_STRING(model)),
+                                       JSON_BUILD_PAIR("HardwareVendor", JSON_BUILD_STRING(vendor ?: c->data[PROP_HARDWARE_VENDOR])),
+                                       JSON_BUILD_PAIR("HardwareModel", JSON_BUILD_STRING(model ?: c->data[PROP_HARDWARE_MODEL])),
+                                       JSON_BUILD_PAIR("HardwareSerial", JSON_BUILD_STRING(serial)),
+                                       JSON_BUILD_PAIR("FirmwareVersion", JSON_BUILD_STRING(firmware_version)),
                                        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)));
 
@@ -1143,63 +1275,53 @@ static const sd_bus_vtable hostname_vtable[] = {
         SD_BUS_PROPERTY("HomeURL", "s", property_get_os_release_field, offsetof(Context, data) + sizeof(char*) * PROP_OS_HOME_URL, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("HardwareVendor", "s", property_get_hardware_vendor, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("HardwareModel", "s", property_get_hardware_model, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("FirmwareVersion", "s", property_get_firmware_version, 0, SD_BUS_VTABLE_PROPERTY_CONST),
 
-        SD_BUS_METHOD_WITH_NAMES("SetHostname",
-                                 "sb",
-                                 SD_BUS_PARAM(hostname)
-                                 SD_BUS_PARAM(interactive),
-                                 NULL,,
-                                 method_set_hostname,
-                                 SD_BUS_VTABLE_UNPRIVILEGED),
-        SD_BUS_METHOD_WITH_NAMES("SetStaticHostname",
-                                 "sb",
-                                 SD_BUS_PARAM(hostname)
-                                 SD_BUS_PARAM(interactive),
-                                 NULL,,
-                                 method_set_static_hostname,
-                                 SD_BUS_VTABLE_UNPRIVILEGED),
-        SD_BUS_METHOD_WITH_NAMES("SetPrettyHostname",
-                                 "sb",
-                                 SD_BUS_PARAM(hostname)
-                                 SD_BUS_PARAM(interactive),
-                                 NULL,,
-                                 method_set_pretty_hostname,
-                                 SD_BUS_VTABLE_UNPRIVILEGED),
-        SD_BUS_METHOD_WITH_NAMES("SetIconName",
-                                 "sb",
-                                 SD_BUS_PARAM(icon)
-                                 SD_BUS_PARAM(interactive),
-                                 NULL,,
-                                 method_set_icon_name,
-                                 SD_BUS_VTABLE_UNPRIVILEGED),
-        SD_BUS_METHOD_WITH_NAMES("SetChassis",
-                                 "sb",
-                                 SD_BUS_PARAM(chassis)
-                                 SD_BUS_PARAM(interactive),
-                                 NULL,,
-                                 method_set_chassis,
-                                 SD_BUS_VTABLE_UNPRIVILEGED),
-        SD_BUS_METHOD_WITH_NAMES("SetDeployment",
-                                 "sb",
-                                 SD_BUS_PARAM(deployment)
-                                 SD_BUS_PARAM(interactive),
-                                 NULL,,
-                                 method_set_deployment,
-                                 SD_BUS_VTABLE_UNPRIVILEGED),
-        SD_BUS_METHOD_WITH_NAMES("SetLocation",
-                                 "sb",
-                                 SD_BUS_PARAM(location)
-                                 SD_BUS_PARAM(interactive),
-                                 NULL,,
-                                 method_set_location,
-                                 SD_BUS_VTABLE_UNPRIVILEGED),
-        SD_BUS_METHOD_WITH_NAMES("GetProductUUID",
-                                 "b",
-                                 SD_BUS_PARAM(interactive),
-                                 "ay",
-                                 SD_BUS_PARAM(uuid),
-                                 method_get_product_uuid,
-                                 SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD_WITH_ARGS("SetHostname",
+                                SD_BUS_ARGS("s", hostname, "b", interactive),
+                                SD_BUS_NO_RESULT,
+                                method_set_hostname,
+                                SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD_WITH_ARGS("SetStaticHostname",
+                                SD_BUS_ARGS("s", hostname, "b", interactive),
+                                SD_BUS_NO_RESULT,
+                                method_set_static_hostname,
+                                SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD_WITH_ARGS("SetPrettyHostname",
+                                SD_BUS_ARGS("s", hostname, "b", interactive),
+                                SD_BUS_NO_RESULT,
+                                method_set_pretty_hostname,
+                                SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD_WITH_ARGS("SetIconName",
+                                SD_BUS_ARGS("s", icon, "b", interactive),
+                                SD_BUS_NO_RESULT,
+                                method_set_icon_name,
+                                SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD_WITH_ARGS("SetChassis",
+                                SD_BUS_ARGS("s", chassis, "b", interactive),
+                                SD_BUS_NO_RESULT,
+                                method_set_chassis,
+                                SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD_WITH_ARGS("SetDeployment",
+                                SD_BUS_ARGS("s", deployment, "b", interactive),
+                                SD_BUS_NO_RESULT,
+                                method_set_deployment,
+                                SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD_WITH_ARGS("SetLocation",
+                                SD_BUS_ARGS("s", location, "b", interactive),
+                                SD_BUS_NO_RESULT,
+                                method_set_location,
+                                SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD_WITH_ARGS("GetProductUUID",
+                                SD_BUS_ARGS("b", interactive),
+                                SD_BUS_RESULT("ay", uuid),
+                                method_get_product_uuid,
+                                SD_BUS_VTABLE_UNPRIVILEGED),
+        SD_BUS_METHOD_WITH_ARGS("GetHardwareSerial",
+                                SD_BUS_NO_ARGS,
+                                SD_BUS_RESULT("s", serial),
+                                method_get_hardware_serial,
+                                SD_BUS_VTABLE_UNPRIVILEGED),
         SD_BUS_METHOD_WITH_ARGS("Describe",
                                 SD_BUS_NO_ARGS,
                                 SD_BUS_RESULT("s", json),