summary refs log tree commit diff
path: root/src/dhcp-manager
diff options
context:
space:
mode:
Diffstat (limited to 'src/dhcp-manager')
-rw-r--r--src/dhcp-manager/Makefile.in1
-rw-r--r--src/dhcp-manager/nm-dhcp-client.c2
-rw-r--r--src/dhcp-manager/nm-dhcp-dhclient-utils.c26
-rw-r--r--src/dhcp-manager/nm-dhcp-dhclient.c13
-rw-r--r--src/dhcp-manager/nm-dhcp-dhcpcd.c15
-rw-r--r--src/dhcp-manager/tests/Makefile.in1
-rw-r--r--src/dhcp-manager/tests/test-dhcp-dhclient.c41
7 files changed, 88 insertions, 11 deletions
diff --git a/src/dhcp-manager/Makefile.in b/src/dhcp-manager/Makefile.in
index 0f98c8c5..063489cb 100644
--- a/src/dhcp-manager/Makefile.in
+++ b/src/dhcp-manager/Makefile.in
@@ -317,6 +317,7 @@ NEWT_LIBS = @NEWT_LIBS@
 NM = @NM@
 NMEDIT = @NMEDIT@
 NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@
+NM_CONFIG_DEFAULT_DNS_RC_MANAGER = @NM_CONFIG_DEFAULT_DNS_RC_MANAGER@
 NM_CONFIG_DEFAULT_LOGGING_AUDIT_TEXT = @NM_CONFIG_DEFAULT_LOGGING_AUDIT_TEXT@
 NM_CONFIG_LOGGING_BACKEND_DEFAULT_TEXT = @NM_CONFIG_LOGGING_BACKEND_DEFAULT_TEXT@
 NM_MAJOR_VERSION = @NM_MAJOR_VERSION@
diff --git a/src/dhcp-manager/nm-dhcp-client.c b/src/dhcp-manager/nm-dhcp-client.c
index 9f4cdf3e..c1025817 100644
--- a/src/dhcp-manager/nm-dhcp-client.c
+++ b/src/dhcp-manager/nm-dhcp-client.c
@@ -884,7 +884,9 @@ dispose (GObject *object)
 
 	g_clear_pointer (&priv->iface, g_free);
 	g_clear_pointer (&priv->hostname, g_free);
+	g_clear_pointer (&priv->fqdn, g_free);
 	g_clear_pointer (&priv->uuid, g_free);
+	g_clear_pointer (&priv->client_id, g_bytes_unref);
 
 	if (priv->hwaddr) {
 		g_byte_array_free (priv->hwaddr, TRUE);
diff --git a/src/dhcp-manager/nm-dhcp-dhclient-utils.c b/src/dhcp-manager/nm-dhcp-dhclient-utils.c
index bf2df1e0..008f8af2 100644
--- a/src/dhcp-manager/nm-dhcp-dhclient-utils.c
+++ b/src/dhcp-manager/nm-dhcp-dhclient-utils.c
@@ -36,8 +36,9 @@
 #define HOSTNAME4_TAG    "send host-name"
 #define HOSTNAME4_FORMAT HOSTNAME4_TAG " \"%s\"; # added by NetworkManager"
 
-#define FQDN_TAG    "send fqdn.fqdn"
-#define FQDN_FORMAT FQDN_TAG " \"%s\"; # added by NetworkManager"
+#define FQDN_TAG_PREFIX  "send fqdn."
+#define FQDN_TAG         FQDN_TAG_PREFIX "fqdn"
+#define FQDN_FORMAT      FQDN_TAG " \"%s\"; # added by NetworkManager"
 
 #define ALSOREQ_TAG "also request "
 
@@ -205,13 +206,14 @@ nm_dhcp_dhclient_create_config (const char *interface,
                                 GBytes **out_new_client_id)
 {
 	GString *new_contents;
-	GPtrArray *alsoreq;
+	GPtrArray *alsoreq, *fqdn_opts;
 	int i;
 
 	g_return_val_if_fail (!anycast_addr || nm_utils_hwaddr_valid (anycast_addr, ETH_ALEN), NULL);
 
 	new_contents = g_string_new (_("# Created by NetworkManager\n"));
 	alsoreq = g_ptr_array_sized_new (5);
+	fqdn_opts = g_ptr_array_sized_new (5);
 
 	if (orig_contents) {
 		char **lines, **line;
@@ -244,6 +246,14 @@ nm_dhcp_dhclient_create_config (const char *interface,
 					continue;
 			}
 
+			/* To let user's FQDN options (except "fqdn.fqdn") override the
+			 * default ones set by NM, add them later
+			 */
+			if (!strncmp (p, FQDN_TAG_PREFIX, NM_STRLEN (FQDN_TAG_PREFIX))) {
+				g_ptr_array_add (fqdn_opts, g_strdup (p + NM_STRLEN (FQDN_TAG_PREFIX)));
+				continue;
+			}
+
 			/* Ignore 'script' since we pass our own */
 			if (g_str_has_prefix (p, "script "))
 				continue;
@@ -320,6 +330,16 @@ nm_dhcp_dhclient_create_config (const char *interface,
 	}
 	g_ptr_array_free (alsoreq, TRUE);
 
+	for (i = 0; i < fqdn_opts->len; i++) {
+		char *t = g_ptr_array_index (fqdn_opts, i);
+
+		if (i == 0)
+			g_string_append_printf (new_contents, "\n# FQDN options from %s\n", orig_path);
+		g_string_append_printf (new_contents, FQDN_TAG_PREFIX "%s\n", t);
+		g_free (t);
+	}
+	g_ptr_array_free (fqdn_opts, TRUE);
+
 	g_string_append_c (new_contents, '\n');
 
 	if (anycast_addr) {
diff --git a/src/dhcp-manager/nm-dhcp-dhclient.c b/src/dhcp-manager/nm-dhcp-dhclient.c
index 4b6d301b..b35921ec 100644
--- a/src/dhcp-manager/nm-dhcp-dhclient.c
+++ b/src/dhcp-manager/nm-dhcp-dhclient.c
@@ -52,6 +52,7 @@ typedef struct {
 	const char *def_leasefile;
 	char *lease_file;
 	char *pid_file;
+	NMDhcpListener *dhcp_listener;
 } NMDhcpDhclientPrivate;
 
 static const char *
@@ -622,7 +623,8 @@ nm_dhcp_dhclient_init (NMDhcpDhclient *self)
 	if (!priv->def_leasefile)
 		priv->def_leasefile = SYSCONFDIR "/dhclient6.leases";
 
-	g_signal_connect (nm_dhcp_listener_get (),
+	priv->dhcp_listener = g_object_ref (nm_dhcp_listener_get ());
+	g_signal_connect (priv->dhcp_listener,
 	                  NM_DHCP_LISTENER_EVENT,
 	                  G_CALLBACK (nm_dhcp_client_handle_event),
 	                  self);
@@ -633,9 +635,12 @@ dispose (GObject *object)
 {
 	NMDhcpDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (object);
 
-	g_signal_handlers_disconnect_by_func (nm_dhcp_listener_get (),
-	                                      G_CALLBACK (nm_dhcp_client_handle_event),
-	                                      NM_DHCP_DHCLIENT (object));
+	if (priv->dhcp_listener) {
+		g_signal_handlers_disconnect_by_func (priv->dhcp_listener,
+		                                      G_CALLBACK (nm_dhcp_client_handle_event),
+		                                      NM_DHCP_DHCLIENT (object));
+		g_clear_object (&priv->dhcp_listener);
+	}
 
 	g_free (priv->pid_file);
 	g_free (priv->conf_file);
diff --git a/src/dhcp-manager/nm-dhcp-dhcpcd.c b/src/dhcp-manager/nm-dhcp-dhcpcd.c
index 8bbb6e4c..17ec993a 100644
--- a/src/dhcp-manager/nm-dhcp-dhcpcd.c
+++ b/src/dhcp-manager/nm-dhcp-dhcpcd.c
@@ -44,6 +44,7 @@ G_DEFINE_TYPE (NMDhcpDhcpcd, nm_dhcp_dhcpcd, NM_TYPE_DHCP_CLIENT)
 
 typedef struct {
 	char *pid_file;
+	NMDhcpListener *dhcp_listener;
 } NMDhcpDhcpcdPrivate;
 
 static const char *
@@ -191,7 +192,10 @@ stop (NMDhcpClient *client, gboolean release, const GByteArray *duid)
 static void
 nm_dhcp_dhcpcd_init (NMDhcpDhcpcd *self)
 {
-	g_signal_connect (nm_dhcp_listener_get (),
+	NMDhcpDhcpcdPrivate *priv = NM_DHCP_DHCPCD_GET_PRIVATE (self);
+
+	priv->dhcp_listener = g_object_ref (nm_dhcp_listener_get ());
+	g_signal_connect (priv->dhcp_listener,
 	                  NM_DHCP_LISTENER_EVENT,
 	                  G_CALLBACK (nm_dhcp_client_handle_event),
 	                  self);
@@ -202,9 +206,12 @@ dispose (GObject *object)
 {
 	NMDhcpDhcpcdPrivate *priv = NM_DHCP_DHCPCD_GET_PRIVATE (object);
 
-	g_signal_handlers_disconnect_by_func (nm_dhcp_listener_get (),
-	                                      G_CALLBACK (nm_dhcp_client_handle_event),
-	                                      NM_DHCP_DHCPCD (object));
+	if (priv->dhcp_listener) {
+		g_signal_handlers_disconnect_by_func (priv->dhcp_listener,
+		                                      G_CALLBACK (nm_dhcp_client_handle_event),
+		                                      NM_DHCP_DHCPCD (object));
+		g_clear_object (&priv->dhcp_listener);
+	}
 
 	g_free (priv->pid_file);
 
diff --git a/src/dhcp-manager/tests/Makefile.in b/src/dhcp-manager/tests/Makefile.in
index 1a072c73..2528b3c5 100644
--- a/src/dhcp-manager/tests/Makefile.in
+++ b/src/dhcp-manager/tests/Makefile.in
@@ -527,6 +527,7 @@ NEWT_LIBS = @NEWT_LIBS@
 NM = @NM@
 NMEDIT = @NMEDIT@
 NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT = @NM_CONFIG_DEFAULT_AUTH_POLKIT_TEXT@
+NM_CONFIG_DEFAULT_DNS_RC_MANAGER = @NM_CONFIG_DEFAULT_DNS_RC_MANAGER@
 NM_CONFIG_DEFAULT_LOGGING_AUDIT_TEXT = @NM_CONFIG_DEFAULT_LOGGING_AUDIT_TEXT@
 NM_CONFIG_LOGGING_BACKEND_DEFAULT_TEXT = @NM_CONFIG_LOGGING_BACKEND_DEFAULT_TEXT@
 NM_MAJOR_VERSION = @NM_MAJOR_VERSION@
diff --git a/src/dhcp-manager/tests/test-dhcp-dhclient.c b/src/dhcp-manager/tests/test-dhcp-dhclient.c
index 0561d43c..046dd7e2 100644
--- a/src/dhcp-manager/tests/test-dhcp-dhclient.c
+++ b/src/dhcp-manager/tests/test-dhcp-dhclient.c
@@ -334,6 +334,46 @@ test_fqdn (void)
 	             NULL);
 }
 
+static const char *fqdn_options_override_orig = \
+	"\n"
+	"send fqdn.fqdn \"foobar.com\"\n"    /* NM must ignore this ... */
+	"send fqdn.encoded off;\n"           /* ... and honor these */
+	"send fqdn.server-update off;\n";
+
+static const char *fqdn_options_override_expected = \
+	"# Created by NetworkManager\n"
+	"# Merged from /path/to/dhclient.conf\n"
+	"\n"
+	"send fqdn.fqdn \"example2.com\"; # added by NetworkManager\n"
+	"send fqdn.encoded on;\n"
+	"send fqdn.server-update on;\n"
+	"\n"
+	"option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n"
+	"option ms-classless-static-routes code 249 = array of unsigned integer 8;\n"
+	"option wpad code 252 = string;\n"
+	"\n"
+	"also request rfc3442-classless-static-routes;\n"
+	"also request ms-classless-static-routes;\n"
+	"also request static-routes;\n"
+	"also request wpad;\n"
+	"also request ntp-servers;\n"
+	"\n"
+	"# FQDN options from /path/to/dhclient.conf\n"
+	"send fqdn.encoded off;\n"
+	"send fqdn.server-update off;\n\n";
+
+static void
+test_fqdn_options_override (void)
+{
+	test_config (fqdn_options_override_orig,
+	             fqdn_options_override_expected,
+	             FALSE, NULL,
+	             "example2.com", NULL,
+	             NULL,
+	             "eth0",
+	             NULL);
+}
+
 /*******************************************/
 
 static const char *override_hostname_orig = \
@@ -804,6 +844,7 @@ main (int argc, char **argv)
 	g_test_add_func ("/dhcp/dhclient/existing-hex-client-id", test_existing_hex_client_id);
 	g_test_add_func ("/dhcp/dhclient/existing-ascii-client-id", test_existing_ascii_client_id);
 	g_test_add_func ("/dhcp/dhclient/fqdn", test_fqdn);
+	g_test_add_func ("/dhcp/dhclient/fqdn_options_override", test_fqdn_options_override);
 	g_test_add_func ("/dhcp/dhclient/override_hostname", test_override_hostname);
 	g_test_add_func ("/dhcp/dhclient/override_hostname6", test_override_hostname6);
 	g_test_add_func ("/dhcp/dhclient/nonfqdn_hostname6", test_nonfqdn_hostname6);