summaryrefslogtreecommitdiff
path: root/src/hostname/hostnamed.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/hostname/hostnamed.c')
-rw-r--r--src/hostname/hostnamed.c122
1 files changed, 92 insertions, 30 deletions
diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c
index ee51002ece..7777450c35 100644
--- a/src/hostname/hostnamed.c
+++ b/src/hostname/hostnamed.c
@@ -6,15 +6,24 @@
#include <unistd.h>
#include "alloc-util.h"
+#include "bus-common-errors.h"
#include "bus-util.h"
#include "def.h"
+#include "env-file-label.h"
+#include "env-file.h"
#include "env-util.h"
#include "fileio-label.h"
+#include "fileio.h"
#include "hostname-util.h"
+#include "id128-util.h"
+#include "main-func.h"
+#include "missing_capability.h"
+#include "nscd-flush.h"
#include "os-util.h"
#include "parse-util.h"
#include "path-util.h"
#include "selinux-util.h"
+#include "signal-util.h"
#include "strv.h"
#include "user-util.h"
#include "util.h"
@@ -42,6 +51,8 @@ enum {
typedef struct Context {
char *data[_PROP_MAX];
Hashmap *polkit_registry;
+ sd_id128_t uuid;
+ bool has_uuid;
} Context;
static void context_reset(Context *c) {
@@ -53,7 +64,7 @@ static void context_reset(Context *c) {
c->data[p] = mfree(c->data[p]);
}
-static void context_free(Context *c) {
+static void context_clear(Context *c) {
assert(c);
context_reset(c);
@@ -84,13 +95,12 @@ static int context_read_data(Context *c) {
if (r < 0 && r != -ENOENT)
return r;
- r = parse_env_file(NULL, "/etc/machine-info", NEWLINE,
+ 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],
- NULL);
+ "LOCATION", &c->data[PROP_LOCATION]);
if (r < 0 && r != -ENOENT)
return r;
@@ -102,6 +112,15 @@ static int context_read_data(Context *c) {
if (r < 0 && r != -ENOENT)
return r;
+ r = id128_read("/sys/class/dmi/id/product_uuid", ID128_UUID, &c->uuid);
+ if (r < 0)
+ log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, r,
+ "Failed to read product UUID, ignoring: %m");
+ else if (sd_id128_is_null(c->uuid) || sd_id128_is_allf(c->uuid))
+ log_debug("DMI product UUID " SD_ID128_FORMAT_STR " is all 0x00 or all 0xFF, ignoring.", SD_ID128_FORMAT_VAL(c->uuid));
+ else
+ c->has_uuid = true;
+
return 0;
}
@@ -272,6 +291,8 @@ static int context_update_kernel_hostname(Context *c) {
if (sethostname_idempotent(hn) < 0)
return -errno;
+ (void) nscd_flush_cache(STRV_MAKE("hosts"));
+
return 0;
}
@@ -304,7 +325,7 @@ static int context_write_data_machine_info(Context *c) {
assert(c);
- r = load_env_file(NULL, "/etc/machine-info", NULL, &l);
+ r = load_env_file(NULL, "/etc/machine-info", &l);
if (r < 0 && r != -ENOENT)
return r;
@@ -597,6 +618,46 @@ static int method_set_location(sd_bus_message *m, void *userdata, sd_bus_error *
return set_machine_info(userdata, m, PROP_LOCATION, method_set_location, 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;
+ int interactive, r;
+
+ assert(m);
+ assert(c);
+
+ if (!c->has_uuid)
+ return sd_bus_error_set(error, BUS_ERROR_NO_PRODUCT_UUID, "Failed to read product UUID from /sys/class/dmi/id/product_uuid");
+
+ 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-product-uuid",
+ 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 = sd_bus_message_new_method_return(m, &reply);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_append_array(reply, 'y', &c->uuid, sizeof(c->uuid));
+ if (r < 0)
+ return r;
+
+ return sd_bus_send(NULL, reply, NULL);
+}
+
static const sd_bus_vtable hostname_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_PROPERTY("Hostname", "s", NULL, offsetof(Context, data) + sizeof(char*) * PROP_HOSTNAME, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
@@ -619,6 +680,7 @@ static const sd_bus_vtable hostname_vtable[] = {
SD_BUS_METHOD("SetChassis", "sb", NULL, method_set_chassis, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("SetDeployment", "sb", NULL, method_set_deployment, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("SetLocation", "sb", NULL, method_set_location, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("GetProductUUID", "b", "ay", method_get_product_uuid, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_VTABLE_END,
};
@@ -651,51 +713,51 @@ static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) {
return 0;
}
-int main(int argc, char *argv[]) {
- Context context = {};
+static int run(int argc, char *argv[]) {
+ _cleanup_(context_clear) Context context = {};
_cleanup_(sd_event_unrefp) sd_event *event = NULL;
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
int r;
- log_set_target(LOG_TARGET_AUTO);
- log_parse_environment();
- log_open();
+ log_setup_service();
umask(0022);
mac_selinux_init();
if (argc != 1) {
log_error("This program takes no arguments.");
- r = -EINVAL;
- goto finish;
+ return -EINVAL;
}
+ assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, -1) >= 0);
+
r = sd_event_default(&event);
- if (r < 0) {
- log_error_errno(r, "Failed to allocate event loop: %m");
- goto finish;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to allocate event loop: %m");
+
+ (void) sd_event_set_watchdog(event, true);
- sd_event_set_watchdog(event, true);
+ r = sd_event_add_signal(event, NULL, SIGINT, NULL, NULL);
+ if (r < 0)
+ return log_error_errno(r, "Failed to install SIGINT handler: %m");
+
+ r = sd_event_add_signal(event, NULL, SIGTERM, NULL, NULL);
+ if (r < 0)
+ return log_error_errno(r, "Failed to install SIGTERM handler: %m");
r = connect_bus(&context, event, &bus);
if (r < 0)
- goto finish;
+ return r;
r = context_read_data(&context);
- if (r < 0) {
- log_error_errno(r, "Failed to read hostname and machine information: %m");
- goto finish;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to read hostname and machine information: %m");
r = bus_event_loop_with_idle(event, bus, "org.freedesktop.hostname1", DEFAULT_EXIT_USEC, NULL, NULL);
- if (r < 0) {
- log_error_errno(r, "Failed to run event loop: %m");
- goto finish;
- }
-
-finish:
- context_free(&context);
+ if (r < 0)
+ return log_error_errno(r, "Failed to run event loop: %m");
- return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+ return 0;
}
+
+DEFINE_MAIN_FUNCTION(run);