hostnamed.c revision ebe5d6d0d05d1f17c96315c42f8d9bcf5e13ba9d
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek This file is part of systemd.
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek Copyright 2011 Lennart Poettering
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek systemd is free software; you can redistribute it and/or modify it
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek under the terms of the GNU Lesser General Public License as published by
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek the Free Software Foundation; either version 2.1 of the License, or
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek (at your option) any later version.
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek systemd is distributed in the hope that it will be useful, but
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek WITHOUT ANY WARRANTY; without even the implied warranty of
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek Lesser General Public License for more details.
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek You should have received a copy of the GNU Lesser General Public License
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek along with systemd; If not, see <http://www.gnu.org/licenses/>.
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek " <interface name=\"org.freedesktop.hostname1\">\n" \
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek " <property name=\"Hostname\" type=\"s\" access=\"read\"/>\n" \
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek " <property name=\"StaticHostname\" type=\"s\" access=\"read\"/>\n" \
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek " <property name=\"PrettyHostname\" type=\"s\" access=\"read\"/>\n" \
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek " <property name=\"IconName\" type=\"s\" access=\"read\"/>\n" \
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek " <property name=\"Chassis\" type=\"s\" access=\"read\"/>\n" \
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek " <method name=\"SetHostname\">\n" \
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek " <arg name=\"name\" type=\"s\" direction=\"in\"/>\n" \
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek " <arg name=\"user_interaction\" type=\"b\" direction=\"in\"/>\n" \
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek " </method>\n" \
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek " <method name=\"SetStaticHostname\">\n" \
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek " <arg name=\"name\" type=\"s\" direction=\"in\"/>\n" \
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek " <arg name=\"user_interaction\" type=\"b\" direction=\"in\"/>\n" \
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek " </method>\n" \
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek " <method name=\"SetPrettyHostname\">\n" \
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek " <arg name=\"name\" type=\"s\" direction=\"in\"/>\n" \
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek " <arg name=\"user_interaction\" type=\"b\" direction=\"in\"/>\n" \
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek " </method>\n" \
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek " <method name=\"SetIconName\">\n" \
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek " <arg name=\"name\" type=\"s\" direction=\"in\"/>\n" \
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek " <arg name=\"user_interaction\" type=\"b\" direction=\"in\"/>\n" \
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek " </method>\n" \
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek " <method name=\"SetChassis\">\n" \
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek " <arg name=\"name\" type=\"s\" direction=\"in\"/>\n" \
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek " <arg name=\"user_interaction\" type=\"b\" direction=\"in\"/>\n" \
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek " </method>\n" \
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek " </interface>\n"
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE \
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekconst char hostname_interface[] _introspect_("hostname1") = INTERFACE;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekstatic void free_data(void) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek for (p = 0; p < _PROP_MAX; p++) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekstatic int read_data(void) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek data[PROP_HOSTNAME] = gethostname_malloc();
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek r = read_one_line_file("/etc/hostname", &data[PROP_STATIC_HOSTNAME]);
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek if (r < 0 && r != -ENOENT)
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek r = parse_env_file("/etc/machine-info", NEWLINE,
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek "PRETTY_HOSTNAME", &data[PROP_PRETTY_HOSTNAME],
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek "ICON_NAME", &data[PROP_ICON_NAME],
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek if (r < 0 && r != -ENOENT)
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekstatic bool check_nss(void) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek dl = dlopen("libnss_myhostname.so.2", RTLD_LAZY);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekstatic bool valid_chassis(const char *chassis) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekstatic bool pretty_string_is_safe(const char *p) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek for (t = p; *t; t++) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekstatic const char* fallback_chassis(void) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek v = detect_virtualization(NULL);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (v == VIRTUALIZATION_CONTAINER)
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return "container";
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek r = read_one_line_file("/sys/firmware/acpi/pm_profile", &type);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek /* We only list the really obvious cases here as the ACPI data
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek * is not really super reliable.
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek * See the ACPI 5.0 Spec Section 5.2.9.1 for details:
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek * http://www.acpi.info/DOWNLOADS/ACPIspec50.pdf
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return "desktop";
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return "laptop";
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return "server";
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return "tablet";
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek r = read_one_line_file("/sys/class/dmi/id/chassis_type", &type);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek /* We only list the really obvious cases here. The DMI data is
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek unreliable enough, so let's not do any additional guesswork
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek See the SMBIOS Specification 2.7.1 section 7.4.1 for
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek details about the values listed here:
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek http://www.dmtf.org/sites/default/files/standards/documents/DSP0134_2.7.1.pdf
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return "desktop";
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return "laptop";
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return "handset";
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return "server";
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekstatic char* fallback_icon_name(void) {
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek if (!isempty(data[PROP_CHASSIS]))
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek return strappend("computer-", data[PROP_CHASSIS]);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return strappend("computer-", chassis);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekstatic int write_data_hostname(void) {
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek if (isempty(data[PROP_HOSTNAME]))
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (sethostname(hn, strlen(hn)) < 0)
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekstatic int write_data_static_hostname(void) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (isempty(data[PROP_STATIC_HOSTNAME])) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (unlink("/etc/hostname") < 0)
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return errno == ENOENT ? 0 : -errno;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return write_one_line_file_atomic_label("/etc/hostname", data[PROP_STATIC_HOSTNAME]);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekstatic int write_data_other(void) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek static const char * const name[_PROP_MAX] = {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek [PROP_PRETTY_HOSTNAME] = "PRETTY_HOSTNAME",
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek r = load_env_file("/etc/machine-info", &l);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (r < 0 && r != -ENOENT)
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek for (p = 2; p < _PROP_MAX; p++) {
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek if (asprintf(&t, "%s=%s", name[p], strempty(data[p])) < 0) {
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek if (unlink("/etc/machine-info") < 0)
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek return errno == ENOENT ? 0 : -errno;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek r = write_env_file_label("/etc/machine-info", l);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekstatic int bus_hostname_append_icon_name(DBusMessageIter *i, const char *property, void *userdata) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (isempty(data[PROP_ICON_NAME]))
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek name = n = fallback_icon_name();
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek return bus_property_append_string(i, property, (void*) name);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekstatic int bus_hostname_append_chassis(DBusMessageIter *i, const char *property, void *userdata) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (isempty(data[PROP_CHASSIS]))
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return bus_property_append_string(i, property, (void*) name);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekstatic const BusProperty bus_hostname_properties[] = {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek { "Hostname", bus_property_append_string, "s", sizeof(data[0])*PROP_HOSTNAME, true },
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek { "StaticHostname", bus_property_append_string, "s", sizeof(data[0])*PROP_STATIC_HOSTNAME, true },
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek { "PrettyHostname", bus_property_append_string, "s", sizeof(data[0])*PROP_PRETTY_HOSTNAME, true },
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek { "IconName", bus_hostname_append_icon_name, "s", sizeof(data[0])*PROP_ICON_NAME, true },
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek { "Chassis", bus_hostname_append_chassis, "s", sizeof(data[0])*PROP_CHASSIS, true },
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekstatic const BusBoundProperties bps[] = {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek { "org.freedesktop.hostname1", bus_hostname_properties, data },
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekstatic DBusHandlerResult hostname_message_handler(
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek DBusMessage *reply = NULL, *changed = NULL;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (dbus_message_is_method_call(message, "org.freedesktop.hostname1", "SetHostname")) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek DBUS_TYPE_BOOLEAN, &interactive,
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return bus_send_error_reply(connection, message, &error, -EINVAL);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek name = data[PROP_STATIC_HOSTNAME];
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return bus_send_error_reply(connection, message, NULL, -EINVAL);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (!streq_ptr(name, data[PROP_HOSTNAME])) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek r = verify_polkit(connection, message, "org.freedesktop.hostname1.set-hostname", interactive, NULL, &error);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return bus_send_error_reply(connection, message, &error, r);
r = write_data_hostname();
"/org/freedesktop/hostname1",
"org.freedesktop.hostname1",
if (!changed)
goto oom;
} else if (dbus_message_is_method_call(message, "org.freedesktop.hostname1", "SetStaticHostname")) {
const char *name;
if (!dbus_message_get_args(
&error,
r = verify_polkit(connection, message, "org.freedesktop.hostname1.set-static-hostname", interactive, NULL, &error);
goto oom;
r = write_data_static_hostname();
"/org/freedesktop/hostname1",
"org.freedesktop.hostname1",
if (!changed)
goto oom;
} else if (dbus_message_is_method_call(message, "org.freedesktop.hostname1", "SetPrettyHostname") ||
const char *name;
if (!dbus_message_get_args(
&error,
"org.freedesktop.hostname1.set-static-hostname" :
goto oom;
data[k] = h;
r = write_data_other();
"/org/freedesktop/hostname1",
"org.freedesktop.hostname1",
if (!changed)
goto oom;
if (!reply)
goto oom;
goto oom;
if (changed) {
goto oom;
return DBUS_HANDLER_RESULT_HANDLED;
oom:
if (reply)
if (changed)
return DBUS_HANDLER_RESULT_NEED_MEMORY;
if (!bus) {
r = -ECONNREFUSED;
goto fail;
if (!dbus_connection_register_object_path(bus, "/org/freedesktop/hostname1", &hostname_vtable, NULL) ||
r = log_oom();
goto fail;
r = -EEXIST;
goto fail;
if (r != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
r = -EEXIST;
goto fail;
if (_bus)
fail:
bool exiting = false;
log_open();
r = -EINVAL;
goto finish;
if (!check_nss())
log_warning("Warning: nss-myhostname is not installed. Changing the local hostname might make it unresolveable. Please install nss-myhostname!");
r = read_data();
goto finish;
goto finish;
if (!dbus_connection_read_write_dispatch(bus, exiting ? -1 : (int) (DEFAULT_EXIT_USEC/USEC_PER_MSEC)))
exiting = true;
free_data();
if (bus) {