diff --git a/libnm-glib/Makefile.am b/libnm-glib/Makefile.am index 6462766b6e..66b72c5416 100644 --- a/libnm-glib/Makefile.am +++ b/libnm-glib/Makefile.am @@ -132,7 +132,7 @@ libnm_glib_la_LIBADD = \ $(GUDEV_LIBS) libnm_glib_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libnm-glib.ver \ - -version-info "6:0:4" + -version-info "6:1:4" noinst_PROGRAMS = libnm-glib-test diff --git a/libnm-glib/nm-ip6-config.c b/libnm-glib/nm-ip6-config.c index f7a2107520..1f2d13beff 100644 --- a/libnm-glib/nm-ip6-config.c +++ b/libnm-glib/nm-ip6-config.c @@ -92,7 +92,7 @@ demarshal_ip6_nameserver_array (NMObject *object, GParamSpec *pspec, GValue *val if (!_nm_ip6_address_array_demarshal (value, (GSList **) field)) return FALSE; - if (!strcmp (pspec->name, NM_IP6_CONFIG_NAMESERVERS)) + if (pspec && !strcmp (pspec->name, NM_IP6_CONFIG_NAMESERVERS)) _nm_object_queue_notify (object, NM_IP6_CONFIG_NAMESERVERS); return TRUE; @@ -188,6 +188,7 @@ const GSList * nm_ip6_config_get_nameservers (NMIP6Config *config) { NMIP6ConfigPrivate *priv; + GParamSpec *pspec; GValue value = {0,}; g_return_val_if_fail (NM_IS_IP6_CONFIG (config), NULL); @@ -203,7 +204,8 @@ nm_ip6_config_get_nameservers (NMIP6Config *config) return NULL; } - demarshal_ip6_nameserver_array (NM_OBJECT (config), NULL, &value, &priv->nameservers); + pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (G_OBJECT (config)), NM_IP6_CONFIG_NAMESERVERS); + demarshal_ip6_nameserver_array (NM_OBJECT (config), pspec, &value, &priv->nameservers); g_value_unset (&value); return priv->nameservers; diff --git a/libnm-glib/nm-types.c b/libnm-glib/nm-types.c index baceb86ba6..cf9e084c77 100644 --- a/libnm-glib/nm-types.c +++ b/libnm-glib/nm-types.c @@ -359,7 +359,7 @@ _nm_ip6_address_array_demarshal (GValue *value, GSList **dest) { GPtrArray *array; - if (!G_VALUE_HOLDS (value, DBUS_TYPE_G_UINT_ARRAY)) + if (!G_VALUE_HOLDS (value, DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UCHAR)) return FALSE; if (*dest) { @@ -373,12 +373,12 @@ _nm_ip6_address_array_demarshal (GValue *value, GSList **dest) int i; for (i = 0; i < array->len; i++) { - struct in6_addr *addr = g_ptr_array_index (array, i); - struct in6_addr *dup; + GByteArray *bytearray = (GByteArray *) g_ptr_array_index (array, i); + struct in6_addr *addr; - dup = g_malloc0 (sizeof (struct in6_addr)); - memcpy (dup, addr, sizeof (struct in6_addr)); - *dest = g_slist_append (*dest, dup); + addr = g_malloc0 (sizeof (struct in6_addr)); + memcpy (addr->s6_addr, bytearray->data, bytearray->len); + *dest = g_slist_append (*dest, addr); } } diff --git a/libnm-util/nm-setting-vpn.c b/libnm-util/nm-setting-vpn.c index cef8323432..53b609e2d8 100644 --- a/libnm-util/nm-setting-vpn.c +++ b/libnm-util/nm-setting-vpn.c @@ -248,6 +248,7 @@ static gboolean update_one_secret (NMSetting *setting, const char *key, GValue *value, GError **error) { NMSettingVPNPrivate *priv = NM_SETTING_VPN_GET_PRIVATE (setting); + char *str; g_return_val_if_fail (key != NULL, FALSE); g_return_val_if_fail (value != NULL, FALSE); @@ -259,8 +260,17 @@ update_one_secret (NMSetting *setting, const char *key, GValue *value, GError ** return FALSE; } - g_hash_table_insert (priv->secrets, g_strdup (key), g_value_dup_string (value)); - return FALSE; + str = g_value_dup_string (value); + if (!str || !strlen (str)) { + g_set_error (error, NM_SETTING_ERROR, + NM_SETTING_ERROR_PROPERTY_TYPE_MISMATCH, + "Secret %s was empty", key); + g_free (str); + return FALSE; + } + + g_hash_table_insert (priv->secrets, g_strdup (key), str); + return TRUE; } static void diff --git a/src/dhcp-manager/nm-dhcp-client.c b/src/dhcp-manager/nm-dhcp-client.c index 5cebaa84ee..1ed62ab9df 100644 --- a/src/dhcp-manager/nm-dhcp-client.c +++ b/src/dhcp-manager/nm-dhcp-client.c @@ -293,7 +293,8 @@ start_monitor (NMDHCPClient *self) gboolean nm_dhcp_client_start_ip4 (NMDHCPClient *self, NMSettingIP4Config *s_ip4, - guint8 *dhcp_anycast_addr) + guint8 *dhcp_anycast_addr, + const char *hostname) { NMDHCPClientPrivate *priv; @@ -308,7 +309,7 @@ nm_dhcp_client_start_ip4 (NMDHCPClient *self, nm_log_info (LOGD_DHCP, "Activation (%s) Beginning DHCPv4 transaction (timeout in %d seconds)", priv->iface, priv->timeout); - priv->pid = NM_DHCP_CLIENT_GET_CLASS (self)->ip4_start (self, s_ip4, dhcp_anycast_addr); + priv->pid = NM_DHCP_CLIENT_GET_CLASS (self)->ip4_start (self, s_ip4, dhcp_anycast_addr, hostname); if (priv->pid) start_monitor (self); @@ -319,6 +320,7 @@ gboolean nm_dhcp_client_start_ip6 (NMDHCPClient *self, NMSettingIP6Config *s_ip6, guint8 *dhcp_anycast_addr, + const char *hostname, gboolean info_only) { NMDHCPClientPrivate *priv; @@ -336,7 +338,7 @@ nm_dhcp_client_start_ip6 (NMDHCPClient *self, nm_log_info (LOGD_DHCP, "Activation (%s) Beginning DHCPv6 transaction (timeout in %d seconds)", priv->iface, priv->timeout); - priv->pid = NM_DHCP_CLIENT_GET_CLASS (self)->ip6_start (self, s_ip6, dhcp_anycast_addr, info_only); + priv->pid = NM_DHCP_CLIENT_GET_CLASS (self)->ip6_start (self, s_ip6, dhcp_anycast_addr, hostname, info_only); if (priv->pid > 0) start_monitor (self); diff --git a/src/dhcp-manager/nm-dhcp-client.h b/src/dhcp-manager/nm-dhcp-client.h index 92b2b8fe51..8c2d465310 100644 --- a/src/dhcp-manager/nm-dhcp-client.h +++ b/src/dhcp-manager/nm-dhcp-client.h @@ -87,11 +87,13 @@ typedef struct { GPid (*ip4_start) (NMDHCPClient *self, NMSettingIP4Config *s_ip4, - guint8 *anycast_addr); + guint8 *anycast_addr, + const char *hostname); GPid (*ip6_start) (NMDHCPClient *self, NMSettingIP6Config *s_ip6, guint8 *anycast_addr, + const char *hostname, gboolean info_only); void (*stop) (NMDHCPClient *self); @@ -114,11 +116,13 @@ const char *nm_dhcp_client_get_uuid (NMDHCPClient *self); gboolean nm_dhcp_client_start_ip4 (NMDHCPClient *self, NMSettingIP4Config *s_ip4, - guint8 *dhcp_anycast_addr); + guint8 *dhcp_anycast_addr, + const char *hostname); gboolean nm_dhcp_client_start_ip6 (NMDHCPClient *self, NMSettingIP6Config *s_ip6, guint8 *dhcp_anycast_addr, + const char *hostname, gboolean info_only); void nm_dhcp_client_stop (NMDHCPClient *self); diff --git a/src/dhcp-manager/nm-dhcp-dhclient.c b/src/dhcp-manager/nm-dhcp-dhclient.c index d7a6e32fb3..7529a57f13 100644 --- a/src/dhcp-manager/nm-dhcp-dhclient.c +++ b/src/dhcp-manager/nm-dhcp-dhclient.c @@ -312,6 +312,7 @@ merge_dhclient_config (const char *iface, const char *conf_file, NMSettingIP4Config *s_ip4, guint8 *anycast_addr, + const char *hostname, const char *orig_path, GError **error) { @@ -353,7 +354,7 @@ merge_dhclient_config (const char *iface, ignore = TRUE; if ( s_ip4 - && nm_setting_ip4_config_get_dhcp_hostname (s_ip4) + && hostname && !strncmp (*line, DHCP_HOSTNAME_TAG, strlen (DHCP_HOSTNAME_TAG))) ignore = TRUE; @@ -396,9 +397,8 @@ merge_dhclient_config (const char *iface, g_string_append_printf (new_contents, DHCP_CLIENT_ID_FORMAT "\n", tmp); } - tmp = nm_setting_ip4_config_get_dhcp_hostname (s_ip4); - if (tmp) - g_string_append_printf (new_contents, DHCP_HOSTNAME_FORMAT "\n", tmp); + if (hostname) + g_string_append_printf (new_contents, DHCP_HOSTNAME_FORMAT "\n", hostname); } if (anycast_addr) { @@ -427,7 +427,8 @@ merge_dhclient_config (const char *iface, static char * create_dhclient_config (const char *iface, NMSettingIP4Config *s_ip4, - guint8 *dhcp_anycast_addr) + guint8 *dhcp_anycast_addr, + const char *hostname) { char *orig = NULL, *tmp, *conf_file = NULL; GError *error = NULL; @@ -450,12 +451,24 @@ create_dhclient_config (const char *iface, return FALSE; } +#if !defined(TARGET_SUSE) && !defined(TARGET_DEBIAN) && !defined(TARGET_GENTOO) + /* Try /etc/dhcp/ too (rh #607759) */ + if (!g_file_test (orig, G_FILE_TEST_EXISTS)) { + g_free (orig); + orig = g_strdup_printf (SYSCONFDIR "/dhcp/dhclient-%s.conf", iface); + if (!orig) { + nm_log_warn (LOGD_DHCP, "(%s): not enough memory for dhclient options.", iface); + return FALSE; + } + } +#endif + tmp = g_strdup_printf ("nm-dhclient-%s.conf", iface); conf_file = g_build_filename ("/var", "run", tmp, NULL); g_free (tmp); error = NULL; - success = merge_dhclient_config (iface, conf_file, s_ip4, dhcp_anycast_addr, orig, &error); + success = merge_dhclient_config (iface, conf_file, s_ip4, dhcp_anycast_addr, hostname, orig, &error); if (!success) { nm_log_warn (LOGD_DHCP, "(%s): error creating dhclient configuration: %s", iface, error->message); @@ -568,14 +581,15 @@ dhclient_start (NMDHCPClient *client, static GPid real_ip4_start (NMDHCPClient *client, NMSettingIP4Config *s_ip4, - guint8 *dhcp_anycast_addr) + guint8 *dhcp_anycast_addr, + const char *hostname) { NMDHCPDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (client); const char *iface; iface = nm_dhcp_client_get_iface (client); - priv->conf_file = create_dhclient_config (iface, s_ip4, dhcp_anycast_addr); + priv->conf_file = create_dhclient_config (iface, s_ip4, dhcp_anycast_addr, hostname); if (!priv->conf_file) { nm_log_warn (LOGD_DHCP4, "(%s): error creating dhclient configuration file.", iface); return -1; @@ -588,6 +602,7 @@ static GPid real_ip6_start (NMDHCPClient *client, NMSettingIP6Config *s_ip6, guint8 *dhcp_anycast_addr, + const char *hostname, gboolean info_only) { return dhclient_start (client, "-6", info_only ? "-S" : "-N"); diff --git a/src/dhcp-manager/nm-dhcp-dhcpcd.c b/src/dhcp-manager/nm-dhcp-dhcpcd.c index 403431fcb4..c9fdc956e3 100644 --- a/src/dhcp-manager/nm-dhcp-dhcpcd.c +++ b/src/dhcp-manager/nm-dhcp-dhcpcd.c @@ -88,14 +88,15 @@ dhcpcd_child_setup (gpointer user_data G_GNUC_UNUSED) static GPid real_ip4_start (NMDHCPClient *client, NMSettingIP4Config *s_ip4, - guint8 *dhcp_anycast_addr) + guint8 *dhcp_anycast_addr, + const char *hostname) { NMDHCPDhcpcdPrivate *priv = NM_DHCP_DHCPCD_GET_PRIVATE (client); GPtrArray *argv = NULL; GPid pid = -1; GError *error = NULL; char *pid_contents = NULL, *binary_name, *cmd_str; - const char *iface, *uuid, *hostname; + const char *iface, *uuid; g_return_val_if_fail (priv->pid_file == NULL, -1); @@ -130,7 +131,6 @@ real_ip4_start (NMDHCPClient *client, g_ptr_array_add (argv, (gpointer) "-c"); /* Set script file */ g_ptr_array_add (argv, (gpointer) ACTION_SCRIPT_PATH ); - hostname = nm_setting_ip4_config_get_dhcp_hostname (s_ip4); if (hostname && strlen (hostname)) { g_ptr_array_add (argv, (gpointer) "-h"); /* Send hostname to DHCP server */ g_ptr_array_add (argv, (gpointer) hostname ); @@ -160,6 +160,7 @@ static GPid real_ip6_start (NMDHCPClient *client, NMSettingIP6Config *s_ip6, guint8 *dhcp_anycast_addr, + const char *hostname, gboolean info_only) { nm_log_warn (LOGD_DHCP6, "the dhcpcd backend does not support IPv6."); diff --git a/src/dhcp-manager/nm-dhcp-manager.c b/src/dhcp-manager/nm-dhcp-manager.c index 7b110fb232..bde874fb7b 100644 --- a/src/dhcp-manager/nm-dhcp-manager.c +++ b/src/dhcp-manager/nm-dhcp-manager.c @@ -407,6 +407,7 @@ client_start (NMDHCPManager *self, NMSettingIP6Config *s_ip6, guint32 timeout, guint8 *dhcp_anycast_addr, + const char *hostname, gboolean info_only) { NMDHCPManagerPrivate *priv; @@ -438,9 +439,9 @@ client_start (NMDHCPManager *self, add_client (self, client); if (ipv6) - success = nm_dhcp_client_start_ip6 (client, s_ip6, dhcp_anycast_addr, info_only); + success = nm_dhcp_client_start_ip6 (client, s_ip6, dhcp_anycast_addr, hostname, info_only); else - success = nm_dhcp_client_start_ip4 (client, s_ip4, dhcp_anycast_addr); + success = nm_dhcp_client_start_ip4 (client, s_ip4, dhcp_anycast_addr, hostname); if (!success) { remove_client (self, client); @@ -462,6 +463,7 @@ nm_dhcp_manager_start_ip4 (NMDHCPManager *self, { NMDHCPManagerPrivate *priv; NMDHCPClient *client = NULL; + const char *hostname = NULL; g_return_val_if_fail (self, NULL); g_return_val_if_fail (NM_IS_DHCP_MANAGER (self), NULL); @@ -476,27 +478,26 @@ nm_dhcp_manager_start_ip4 (NMDHCPManager *self, g_return_val_if_fail (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, NULL); } - if ( nm_setting_ip4_config_get_dhcp_send_hostname (s_ip4) - && (nm_setting_ip4_config_get_dhcp_hostname (s_ip4) == NULL) - && priv->hostname_provider != NULL) { + /* If we're asked to send the hostname to DHCP server, and the hostname + * isn't specified, and a hostname provider is registered: use that + */ + if (nm_setting_ip4_config_get_dhcp_send_hostname (s_ip4)) { + hostname = nm_setting_ip4_config_get_dhcp_hostname (s_ip4); - s_ip4 = NM_SETTING_IP4_CONFIG (nm_setting_duplicate (NM_SETTING (s_ip4))); - - /* We're asked to send the hostname to DHCP server, the hostname - * isn't specified, and a hostname provider is registered: use that + /* If we're supposed to send the hostname to the DHCP server but + * the user didn't specify one, use the persistent hostname. */ - g_object_set (G_OBJECT (s_ip4), - NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME, - nm_hostname_provider_get_hostname (priv->hostname_provider), - NULL); - } else - g_object_ref (s_ip4); + if (!hostname && priv->hostname_provider) { + hostname = nm_hostname_provider_get_hostname (priv->hostname_provider); + if ( hostname + && (!strcmp (hostname, "localhost.localdomain") || + !strcmp (hostname, "localhost6.localdomain6"))) + hostname = NULL; + } + } } - client = client_start (self, iface, uuid, FALSE, s_ip4, NULL, timeout, dhcp_anycast_addr, FALSE); - - if (s_ip4) - g_object_unref (s_ip4); + client = client_start (self, iface, uuid, FALSE, s_ip4, NULL, timeout, dhcp_anycast_addr, hostname, FALSE); return client; } @@ -511,7 +512,7 @@ nm_dhcp_manager_start_ip6 (NMDHCPManager *self, guint8 *dhcp_anycast_addr, gboolean info_only) { - return client_start (self, iface, uuid, TRUE, NULL, s_ip6, timeout, dhcp_anycast_addr, info_only); + return client_start (self, iface, uuid, TRUE, NULL, s_ip6, timeout, dhcp_anycast_addr, NULL, info_only); } static void diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c index 2fea38f331..4c6c5c6273 100644 --- a/src/nm-ip6-config.c +++ b/src/nm-ip6-config.c @@ -654,6 +654,27 @@ finalize (GObject *object) G_OBJECT_CLASS (nm_ip6_config_parent_class)->finalize (object); } +static void +nameservers_to_gvalue (GArray *array, GValue *value) +{ + GPtrArray *dns; + guint i = 0; + + dns = g_ptr_array_new (); + + while (array && (i < array->len)) { + struct in6_addr *addr; + GByteArray *bytearray; + addr = &g_array_index (array, struct in6_addr, i++); + + bytearray = g_byte_array_sized_new (16); + g_byte_array_append (bytearray, (guint8 *) addr->s6_addr, 16); + g_ptr_array_add (dns, bytearray); + } + + g_value_take_boxed (value, dns); +} + static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) @@ -665,7 +686,7 @@ get_property (GObject *object, guint prop_id, nm_utils_ip6_addresses_to_gvalue (priv->addresses, value); break; case PROP_NAMESERVERS: - g_value_set_boxed (value, priv->nameservers); + nameservers_to_gvalue (priv->nameservers, value); break; case PROP_DOMAINS: g_value_set_boxed (value, priv->domains); diff --git a/test/nm-tool.c b/test/nm-tool.c index 9a1a0ba61b..700e1c430d 100644 --- a/test/nm-tool.c +++ b/test/nm-tool.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -210,6 +211,28 @@ ip4_address_as_string (guint32 ip) } } +static gchar * +ip6_address_as_string (const struct in6_addr *ip) +{ + char buf[INET6_ADDRSTRLEN]; + + memset (&buf, '\0', sizeof (buf)); + + if (inet_ntop (AF_INET6, ip, buf, INET6_ADDRSTRLEN)) { + return g_strdup (buf); + } else { + int j; + GString *ip6_str = g_string_new (NULL); + g_string_append_printf (ip6_str, "%02X", ip->s6_addr[0]); + for (j = 1; j < 16; j++) + g_string_append_printf (ip6_str, " %02X", ip->s6_addr[j]); + nm_warning ("%s: error converting IP6 address %s", + __func__, ip6_str->str); + g_string_free (ip6_str, TRUE); + return NULL; + } +} + static const char * get_dev_state_string (NMDeviceState state) { @@ -399,38 +422,69 @@ detail_device (gpointer data, gpointer user_data) /* IP Setup info */ if (state == NM_DEVICE_STATE_ACTIVATED) { - NMIP4Config *cfg = nm_device_get_ip4_config (device); + NMIP4Config *cfg4 = nm_device_get_ip4_config (device); + NMIP6Config *cfg6 = nm_device_get_ip6_config (device); GSList *iter; - printf ("\n IPv4 Settings:\n"); + if (cfg4) { + printf ("\n IPv4 Settings:\n"); - for (iter = (GSList *) nm_ip4_config_get_addresses (cfg); iter; iter = g_slist_next (iter)) { - NMIP4Address *addr = (NMIP4Address *) iter->data; - guint32 prefix = nm_ip4_address_get_prefix (addr); - char *tmp2; + for (iter = (GSList *) nm_ip4_config_get_addresses (cfg4); iter; iter = g_slist_next (iter)) { + NMIP4Address *addr = (NMIP4Address *) iter->data; + guint32 prefix = nm_ip4_address_get_prefix (addr); + char *tmp2; - tmp = ip4_address_as_string (nm_ip4_address_get_address (addr)); - print_string (" Address", tmp); - g_free (tmp); + tmp = ip4_address_as_string (nm_ip4_address_get_address (addr)); + print_string (" Address", tmp); + g_free (tmp); - tmp2 = ip4_address_as_string (nm_utils_ip4_prefix_to_netmask (prefix)); - tmp = g_strdup_printf ("%d (%s)", prefix, tmp2); - g_free (tmp2); - print_string (" Prefix", tmp); - g_free (tmp); + tmp2 = ip4_address_as_string (nm_utils_ip4_prefix_to_netmask (prefix)); + tmp = g_strdup_printf ("%d (%s)", prefix, tmp2); + g_free (tmp2); + print_string (" Prefix", tmp); + g_free (tmp); - tmp = ip4_address_as_string (nm_ip4_address_get_gateway (addr)); - print_string (" Gateway", tmp); - g_free (tmp); - printf ("\n"); + tmp = ip4_address_as_string (nm_ip4_address_get_gateway (addr)); + print_string (" Gateway", tmp); + g_free (tmp); + printf ("\n"); + } + + array = nm_ip4_config_get_nameservers (cfg4); + if (array) { + int i; + + for (i = 0; i < array->len; i++) { + tmp = ip4_address_as_string (g_array_index (array, guint32, i)); + print_string (" DNS", tmp); + g_free (tmp); + } + } } - array = nm_ip4_config_get_nameservers (cfg); - if (array) { - int i; + if (cfg6) { + printf ("\n IPv6 Settings:\n"); - for (i = 0; i < array->len; i++) { - tmp = ip4_address_as_string (g_array_index (array, guint32, i)); + for (iter = (GSList *) nm_ip6_config_get_addresses (cfg6); iter; iter = g_slist_next (iter)) { + NMIP6Address *addr = (NMIP6Address *) iter->data; + guint32 prefix = nm_ip6_address_get_prefix (addr); + + tmp = ip6_address_as_string (nm_ip6_address_get_address (addr)); + print_string (" Address", tmp); + g_free (tmp); + + tmp = g_strdup_printf ("%d", prefix); + print_string (" Prefix", tmp); + g_free (tmp); + + tmp = ip6_address_as_string (nm_ip6_address_get_gateway (addr)); + print_string (" Gateway", tmp); + g_free (tmp); + printf ("\n"); + } + + for (iter = (GSList *) nm_ip6_config_get_nameservers (cfg6); iter; iter = g_slist_next (iter)) { + tmp = ip6_address_as_string (iter->data); print_string (" DNS", tmp); g_free (tmp); }