hostnamed.c revision 89f134406af6a4b4c7493f624a89dcd654b48e81
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering This file is part of systemd.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Copyright 2011 Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is free software; you can redistribute it and/or modify it
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering under the terms of the GNU General Public License as published by
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering the Free Software Foundation; either version 2 of the License, or
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering (at your option) any later version.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is distributed in the hope that it will be useful, but
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering General Public License for more details.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering You should have received a copy of the GNU General Public License
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen " <interface name=\"org.freedesktop.hostname1\">\n" \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " <property name=\"Hostname\" type=\"s\" access=\"read\"/>\n" \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " <property name=\"StaticHostname\" type=\"s\" access=\"read\"/>\n" \
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering " <property name=\"PrettyHostname\" type=\"s\" access=\"read\"/>\n" \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " <property name=\"IconName\" type=\"s\" access=\"read\"/>\n" \
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering " <method name=\"SetHostname\">\n" \
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering " <arg name=\"name\" type=\"s\" direction=\"in\"/>\n" \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " <arg name=\"user_interaction\" type=\"b\" direction=\"in\"/>\n" \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " </method>\n" \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " <method name=\"SetStaticHostname\">\n" \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " <arg name=\"name\" type=\"s\" direction=\"in\"/>\n" \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " <arg name=\"user_interaction\" type=\"b\" direction=\"in\"/>\n" \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " </method>\n" \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " <method name=\"SetPrettyHostname\">\n" \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " <arg name=\"name\" type=\"s\" direction=\"in\"/>\n" \
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering " <arg name=\"user_interaction\" type=\"b\" direction=\"in\"/>\n" \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " </method>\n" \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " <method name=\"SetIconName\">\n" \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " <arg name=\"name\" type=\"s\" direction=\"in\"/>\n" \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " <arg name=\"user_interaction\" type=\"b\" direction=\"in\"/>\n" \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " </method>\n" \
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " </interface>\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersenconst char hostname_interface[] _introspect_("hostname1") = INTERFACE;
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poetteringstatic void free_data(void) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering for (p = 0; p < _PROP_MAX; p++) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersenstatic int read_data(void) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering data[PROP_HOSTNAME] = gethostname_malloc();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = read_one_line_file("/etc/hostname", &data[PROP_STATIC_HOSTNAME]);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0 && r != -ENOENT)
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen r = parse_env_file("/etc/machine-info", NEWLINE,
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering "PRETTY_HOSTNAME", &data[PROP_PRETTY_HOSTNAME],
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (r < 0 && r != -ENOENT)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poetteringstatic bool check_nss(void) {
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if ((dl = dlopen("libnss_myhostname.so.2", RTLD_LAZY))) {
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poetteringstatic const char* fallback_icon_name(void) {
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering#if defined(__i386__) || defined(__x86_64__)
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering return "computer-vm";
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering#if defined(__i386__) || defined(__x86_64__)
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering r = read_one_line_file("/sys/class/dmi/id/chassis_type", &type);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering /* We only list the really obvious cases here. The DMI data is
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering unreliable enough, so let's not do any additional guesswork
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering on top of that.
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering See the SMBIOS Specification 2.7.1 section 7.4.1 for
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering details about the values listed here:
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering http://www.dmtf.org/sites/default/files/standards/documents/DSP0134_2.7.1.pdf
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers return "computer-desktop";
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen return "computer-laptop";
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return "computer-server";
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int write_data_static_hostname(void) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (isempty(data[PROP_STATIC_HOSTNAME])) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return write_one_line_file_atomic("/etc/hostname", data[PROP_STATIC_HOSTNAME]);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int write_data_other(void) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering static const char * const name[_PROP_MAX] = {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering [PROP_PRETTY_HOSTNAME] = "PRETTY_HOSTNAME",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = load_env_file("/etc/machine-info", &l);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0 && r != -ENOENT)
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers char *t, **u;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers if (asprintf(&t, "%s=%s", name[p], strempty(data[p])) < 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = write_env_file("/etc/machine-info", l);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int bus_hostname_append_icon_name(DBusMessageIter *i, const char *property, void *userdata) {
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers const char *name;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen return bus_property_append_string(i, property, (void*) name);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sieversstatic const BusProperty bus_hostname_properties[] = {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "Hostname", bus_property_append_string, "s", sizeof(data[0])*PROP_HOSTNAME, true },
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering { "StaticHostname", bus_property_append_string, "s", sizeof(data[0])*PROP_STATIC_HOSTNAME, true },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "PrettyHostname", bus_property_append_string, "s", sizeof(data[0])*PROP_PRETTY_HOSTNAME, true },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "IconName", bus_hostname_append_icon_name, "s", sizeof(data[0])*PROP_ICON_NAME, true },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "org.freedesktop.hostname1", bus_hostname_properties, data },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic DBusHandlerResult hostname_message_handler(
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (dbus_message_is_method_call(message, "org.freedesktop.hostname1", "SetHostname")) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen return bus_send_error_reply(connection, message, &error, -EINVAL);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen return bus_send_error_reply(connection, message, NULL, -EINVAL);
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering if (!streq_ptr(name, data[PROP_HOSTNAME])) {
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers r = verify_polkit(connection, message, "org.freedesktop.hostname1.set-hostname", interactive, NULL, &error);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers return bus_send_error_reply(connection, message, &error, r);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Failed to set host name: %s", strerror(-r));
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return bus_send_error_reply(connection, message, NULL, r);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_info("Changed host name to '%s'", strempty(data[PROP_HOSTNAME]));
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen "Hostname\0");
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen } else if (dbus_message_is_method_call(message, "org.freedesktop.hostname1", "SetStaticHostname")) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return bus_send_error_reply(connection, message, &error, -EINVAL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!streq_ptr(name, data[PROP_STATIC_HOSTNAME])) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = verify_polkit(connection, message, "org.freedesktop.hostname1.set-static-hostname", interactive, NULL, &error);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return bus_send_error_reply(connection, message, &error, r);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen return bus_send_error_reply(connection, message, NULL, -EINVAL);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering log_error("Failed to write static host name: %s", strerror(-r));
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return bus_send_error_reply(connection, message, NULL, r);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering log_info("Changed static host name to '%s'", strempty(data[PROP_STATIC_HOSTNAME]));
34a6778fb9d1065f3fbb8e2243b9f0f25d1d18f1Zbigniew Jędrzejewski-Szmek changed = bus_properties_changed_new(
34a6778fb9d1065f3fbb8e2243b9f0f25d1d18f1Zbigniew Jędrzejewski-Szmek "StaticHostname\0");
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering } else if (dbus_message_is_method_call(message, "org.freedesktop.hostname1", "SetPrettyHostname") ||
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering dbus_message_is_method_call(message, "org.freedesktop.hostname1", "SetIconName")) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return bus_send_error_reply(connection, message, &error, -EINVAL);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering k = streq(dbus_message_get_member(message), "SetPrettyHostname") ? PROP_PRETTY_HOSTNAME : PROP_ICON_NAME;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering /* Since the pretty hostname should always be
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering * changed at the same time as the static one,
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering * use the same policy action for both... */
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering r = verify_polkit(connection, message, k == PROP_PRETTY_HOSTNAME ?
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering "org.freedesktop.hostname1.set-static-hostname" :
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering "org.freedesktop.hostname1.set-machine-info", interactive, NULL, &error);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return bus_send_error_reply(connection, message, &error, r);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering log_error("Failed to write machine info: %s", strerror(-r));
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return bus_send_error_reply(connection, message, NULL, r);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering log_info("Changed %s to '%s'", k == PROP_PRETTY_HOSTNAME ? "pretty host name" : "icon name", strempty(data[k]));
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering k == PROP_PRETTY_HOSTNAME ? "PrettyHostname\0" : "IconName\0");
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return bus_default_message_handler(connection, message, INTROSPECTION, INTERFACES_LIST, bps);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (!(reply = dbus_message_new_method_return(message)))
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (!dbus_connection_send(connection, reply, NULL))
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (!dbus_connection_send(connection, changed, NULL))
04d39279245834494baccfdb9349db8bf80abd13Lennart Poetteringstatic int connect_bus(DBusConnection **_bus) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering static const DBusObjectPathVTable hostname_vtable = {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering .message_function = hostname_message_handler
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering bus = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering log_error("Failed to get system D-Bus connection: %s", bus_error_message(&error));
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering dbus_connection_set_exit_on_disconnect(bus, FALSE);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (!dbus_connection_register_object_path(bus, "/org/freedesktop/hostname1", &hostname_vtable, NULL) ||
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering !dbus_connection_add_filter(bus, bus_exit_idle_filter, &remain_until, NULL)) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering r = dbus_bus_request_name(bus, "org.freedesktop.hostname1", DBUS_NAME_FLAG_DO_NOT_QUEUE, &error);
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering log_error("Failed to register name on bus: %s", bus_error_message(&error));
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (r != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (argc == 2 && streq(argv[1], "--introspect")) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering fputs(DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering log_error("This program takes no arguments.");
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering log_warning("Warning: nss-myhostname is not installed. Changing the local hostname might make it unresolveable. Please install nss-myhostname!");
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering log_error("Failed to read hostname data: %s", strerror(-r));
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering remain_until = now(CLOCK_MONOTONIC) + DEFAULT_EXIT_USEC;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (!dbus_connection_read_write_dispatch(bus, exiting ? -1 : (int) (DEFAULT_EXIT_USEC/USEC_PER_MSEC)))
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (!exiting && remain_until < now(CLOCK_MONOTONIC)) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering bus_async_unregister_and_exit(bus, "org.freedesktop.hostname1");