summary refs log tree commit diff
path: root/src/dhcp/nm-dhcp-dhclient.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2018-10-20 01:30:31 +0200
committerMichael Biebl <biebl@debian.org>2018-10-20 01:30:31 +0200
commit6518e361171f64bcaaa4bf868139362ed95cc2e0 (patch)
treed2d5b53faf80646a40ec2c0c7f2a42b3959612f5 /src/dhcp/nm-dhcp-dhclient.c
parente126f3e804c35480c4f075777430419d6ece23da (diff)
New upstream version 1.14.2 upstream/1.14.2
Diffstat (limited to 'src/dhcp/nm-dhcp-dhclient.c')
-rw-r--r--src/dhcp/nm-dhcp-dhclient.c196
1 files changed, 126 insertions, 70 deletions
diff --git a/src/dhcp/nm-dhcp-dhclient.c b/src/dhcp/nm-dhcp-dhclient.c
index bf93c831..4a936178 100644
--- a/src/dhcp/nm-dhcp-dhclient.c
+++ b/src/dhcp/nm-dhcp-dhclient.c
@@ -41,6 +41,7 @@
 #include "nm-utils/nm-dedup-multi.h"
 
 #include "nm-utils.h"
+#include "nm-config.h"
 #include "nm-dhcp-dhclient-utils.h"
 #include "nm-dhcp-manager.h"
 #include "NetworkManagerUtils.h"
@@ -120,8 +121,20 @@ get_dhclient_leasefile (int addr_family,
                         const char *uuid,
                         char **out_preferred_path)
 {
+	char *rundir_path;
 	char *path;
 
+	/* First, see if the lease file is in /run */
+	rundir_path = g_strdup_printf (NMRUNDIR "/dhclient%s-%s-%s.lease",
+	                               _addr_family_to_path_part (addr_family),
+	                               uuid,
+	                               iface);
+
+	if (g_file_test (rundir_path, G_FILE_TEST_EXISTS)) {
+		NM_SET_OUT (out_preferred_path, g_strdup (rundir_path));
+		return rundir_path;
+	}
+
 	/* /var/lib/NetworkManager is the preferred leasefile path */
 	path = g_strdup_printf (NMSTATEDIR "/dhclient%s-%s-%s.lease",
 	                        _addr_family_to_path_part (addr_family),
@@ -133,6 +146,12 @@ get_dhclient_leasefile (int addr_family,
 		return path;
 	}
 
+	if (nm_config_get_configure_and_quit (nm_config_get ()) == NM_CONFIG_CONFIGURE_AND_QUIT_INITRD) {
+		g_free (path);
+		path = rundir_path;
+	} else {
+		g_free (rundir_path);
+	}
 	NM_SET_OUT (out_preferred_path, g_steal_pointer (&path));
 
 	/* If the leasefile we're looking for doesn't exist yet in the new location
@@ -174,13 +193,14 @@ merge_dhclient_config (NMDhcpDhclient *self,
                        GBytes **out_new_client_id,
                        GError **error)
 {
-	char *orig = NULL, *new;
-	gboolean success = FALSE;
+	gs_free char *orig = NULL;
+	gs_free char *new = NULL;
 
-	g_return_val_if_fail (iface != NULL, FALSE);
-	g_return_val_if_fail (conf_file != NULL, FALSE);
+	g_return_val_if_fail (iface, FALSE);
+	g_return_val_if_fail (conf_file, FALSE);
 
-	if (orig_path && g_file_test (orig_path, G_FILE_TEST_EXISTS)) {
+	if (   orig_path
+	    && g_file_test (orig_path, G_FILE_TEST_EXISTS)) {
 		GError *read_error = NULL;
 
 		if (!g_file_get_contents (orig_path, &orig, NULL, &read_error)) {
@@ -190,14 +210,22 @@ merge_dhclient_config (NMDhcpDhclient *self,
 		}
 	}
 
-	new = nm_dhcp_dhclient_create_config (iface, addr_family, client_id, anycast_addr, hostname, timeout,
-	                                      use_fqdn, orig_path, orig, out_new_client_id);
+	new = nm_dhcp_dhclient_create_config (iface,
+	                                      addr_family,
+	                                      client_id,
+	                                      anycast_addr,
+	                                      hostname,
+	                                      timeout,
+	                                      use_fqdn,
+	                                      orig_path,
+	                                      orig,
+	                                      out_new_client_id);
 	g_assert (new);
-	success = g_file_set_contents (conf_file, new, -1, error);
-	g_free (new);
-	g_free (orig);
 
-	return success;
+	return g_file_set_contents (conf_file,
+	                            new,
+	                            -1,
+	                            error);
 }
 
 static char *
@@ -282,13 +310,14 @@ create_dhclient_config (NMDhcpDhclient *self,
                         gboolean use_fqdn,
                         GBytes **out_new_client_id)
 {
-	char *orig = NULL, *new = NULL;
+	gs_free char *orig = NULL;
+	char *new = NULL;
 	GError *error = NULL;
-	gboolean success = FALSE;
 
 	g_return_val_if_fail (iface != NULL, NULL);
 
 	new = g_strdup_printf (NMSTATEDIR "/dhclient%s-%s.conf", _addr_family_to_path_part (addr_family), iface);
+
 	_LOGD ("creating composite dhclient config %s", new);
 
 	orig = find_existing_config (self, addr_family, iface, uuid);
@@ -297,15 +326,12 @@ create_dhclient_config (NMDhcpDhclient *self,
 	else
 		_LOGD ("no existing dhclient configuration to merge");
 
-	error = NULL;
-	success = merge_dhclient_config (self, addr_family, iface, new, client_id, dhcp_anycast_addr,
-	                                 hostname, timeout, use_fqdn, orig, out_new_client_id, &error);
-	if (!success) {
+	if (!merge_dhclient_config (self, addr_family, iface, new, client_id, dhcp_anycast_addr,
+	                            hostname, timeout, use_fqdn, orig, out_new_client_id, &error)) {
 		_LOGW ("error creating dhclient configuration: %s", error->message);
-		g_error_free (error);
+		g_clear_error (&error);
 	}
 
-	g_free (orig);
 	return new;
 }
 
@@ -315,13 +341,14 @@ dhclient_start (NMDhcpClient *client,
                 GBytes *duid,
                 gboolean release,
                 pid_t *out_pid,
-                int prefixes)
+                int prefixes,
+                GError **error)
 {
 	NMDhcpDhclient *self = NM_DHCP_DHCLIENT (client);
 	NMDhcpDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (self);
 	gs_unref_ptrarray GPtrArray *argv = NULL;
 	pid_t pid;
-	GError *error = NULL;
+	gs_free_error GError *local = NULL;
 	const char *iface;
 	const char *uuid;
 	const char *system_bus_address;
@@ -339,7 +366,7 @@ dhclient_start (NMDhcpClient *client,
 
 	dhclient_path = nm_dhcp_dhclient_get_path ();
 	if (!dhclient_path) {
-		_LOGW ("dhclient could not be found");
+		nm_utils_error_set_literal (error, NM_UTILS_ERROR_UNKNOWN, "dhclient binary not found");
 		return FALSE;
 	}
 
@@ -371,11 +398,7 @@ dhclient_start (NMDhcpClient *client,
 		gs_unref_object GFile *dst = g_file_new_for_path (preferred_leasefile_path);
 
 		/* Try to copy the existing leasefile to the preferred location */
-		if (g_file_copy (src, dst, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, &error)) {
-			/* Success; use the preferred leasefile path */
-			g_free (priv->lease_file);
-			priv->lease_file = g_file_get_path (dst);
-		} else {
+		if (!g_file_copy (src, dst, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, &local)) {
 			gs_free char *s_path = NULL;
 			gs_free char *d_path = NULL;
 
@@ -383,8 +406,12 @@ dhclient_start (NMDhcpClient *client,
 			_LOGW ("failed to copy leasefile %s to %s: %s",
 			       (s_path = g_file_get_path (src)),
 			       (d_path = g_file_get_path (dst)),
-			       error->message);
-			g_clear_error (&error);
+			       local->message);
+			g_clear_error (&local);
+		} else {
+			/* Success; use the preferred leasefile path */
+			g_free (priv->lease_file);
+			priv->lease_file = g_file_get_path (dst);
 		}
 	}
 
@@ -393,9 +420,12 @@ dhclient_start (NMDhcpClient *client,
 		gs_free char *escaped = NULL;
 
 		escaped = nm_dhcp_dhclient_escape_duid (duid);
-		if (!nm_dhcp_dhclient_save_duid (priv->lease_file, escaped, &error)) {
-			_LOGW ("failed to save DUID to %s: %s", priv->lease_file, error->message);
-			g_clear_error (&error);
+		if (!nm_dhcp_dhclient_save_duid (priv->lease_file, escaped, &local)) {
+			nm_utils_error_set (error,
+			                    NM_UTILS_ERROR_UNKNOWN,
+			                    "failed to save DUID to '%s': %s",
+			                    priv->lease_file,
+			                    local->message);
 			return FALSE;
 		}
 	}
@@ -451,13 +481,15 @@ dhclient_start (NMDhcpClient *client,
 	g_ptr_array_add (argv, NULL);
 
 	_LOGD ("running: %s",
-	       (cmd_str = g_strjoinv (" ", (gchar **) argv->pdata)));
+	       (cmd_str = g_strjoinv (" ", (char **) argv->pdata)));
 
 	if (!g_spawn_async (NULL, (char **) argv->pdata, NULL,
 	                    G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL,
-	                    nm_utils_setpgid, NULL, &pid, &error)) {
-		_LOGW ("dhclient failed to start: '%s'", error->message);
-		g_error_free (error);
+	                    nm_utils_setpgid, NULL, &pid, &local)) {
+		nm_utils_error_set (error,
+		                    NM_UTILS_ERROR_UNKNOWN,
+		                    "dhclient failed to start: %s",
+		                    local->message);
 		return FALSE;
 	}
 
@@ -473,36 +505,46 @@ dhclient_start (NMDhcpClient *client,
 }
 
 static gboolean
-ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last_ip4_address)
+ip4_start (NMDhcpClient *client,
+           const char *dhcp_anycast_addr,
+           const char *last_ip4_address,
+           GError **error)
 {
 	NMDhcpDhclient *self = NM_DHCP_DHCLIENT (client);
 	NMDhcpDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (self);
 	GBytes *client_id;
 	gs_unref_bytes GBytes *new_client_id = NULL;
-	const char *iface, *uuid, *hostname;
-	guint32 timeout;
-	gboolean success = FALSE;
-	gboolean use_fqdn;
 
-	iface = nm_dhcp_client_get_iface (client);
-	uuid = nm_dhcp_client_get_uuid (client);
 	client_id = nm_dhcp_client_get_client_id (client);
-	hostname = nm_dhcp_client_get_hostname (client);
-	timeout = nm_dhcp_client_get_timeout (client);
-	use_fqdn = nm_dhcp_client_get_use_fqdn (client);
 
-	priv->conf_file = create_dhclient_config (self, AF_INET, iface, uuid, client_id, dhcp_anycast_addr,
-	                                          hostname, timeout, use_fqdn, &new_client_id);
-	if (priv->conf_file) {
-		if (new_client_id) {
-			nm_assert (!client_id);
-			nm_dhcp_client_set_client_id (client, new_client_id);
-		}
-		success = dhclient_start (client, NULL, NULL, FALSE, NULL, 0);
-	} else
-		_LOGW ("error creating dhclient configuration file");
+	priv->conf_file = create_dhclient_config (self,
+	                                          AF_INET,
+	                                          nm_dhcp_client_get_iface (client),
+	                                          nm_dhcp_client_get_uuid (client),
+	                                          client_id,
+	                                          dhcp_anycast_addr,
+	                                          nm_dhcp_client_get_hostname (client),
+	                                          nm_dhcp_client_get_timeout (client),
+	                                          nm_dhcp_client_get_use_fqdn (client),
+	                                          &new_client_id);
+	if (!priv->conf_file) {
+		nm_utils_error_set_literal (error,
+		                            NM_UTILS_ERROR_UNKNOWN,
+		                            "error creating dhclient configuration file");
+		return FALSE;
+	}
 
-	return success;
+	if (new_client_id) {
+		nm_assert (!client_id);
+		nm_dhcp_client_set_client_id (client, new_client_id);
+	}
+	return dhclient_start (client,
+	                       NULL,
+	                       NULL,
+	                       FALSE,
+	                       NULL,
+	                       0,
+	                       error);
 }
 
 static gboolean
@@ -511,22 +553,26 @@ ip6_start (NMDhcpClient *client,
            const struct in6_addr *ll_addr,
            NMSettingIP6ConfigPrivacy privacy,
            GBytes *duid,
-           guint needed_prefixes)
+           guint needed_prefixes,
+           GError **error)
 {
 	NMDhcpDhclient *self = NM_DHCP_DHCLIENT (client);
 	NMDhcpDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (self);
-	const char *iface, *uuid, *hostname;
-	guint32 timeout;
-
-	iface = nm_dhcp_client_get_iface (client);
-	uuid = nm_dhcp_client_get_uuid (client);
-	hostname = nm_dhcp_client_get_hostname (client);
-	timeout = nm_dhcp_client_get_timeout (client);
 
-	priv->conf_file = create_dhclient_config (self, AF_INET6, iface, uuid, NULL, dhcp_anycast_addr,
-	                                          hostname, timeout, TRUE, NULL);
+	priv->conf_file = create_dhclient_config (self,
+	                                          AF_INET6,
+	                                          nm_dhcp_client_get_iface (client),
+	                                          nm_dhcp_client_get_uuid (client),
+	                                          NULL,
+	                                          dhcp_anycast_addr,
+	                                          nm_dhcp_client_get_hostname (client),
+	                                          nm_dhcp_client_get_timeout (client),
+	                                          TRUE,
+	                                          NULL);
 	if (!priv->conf_file) {
-		_LOGW ("error creating dhclient configuration file");
+		nm_utils_error_set_literal (error,
+		                            NM_UTILS_ERROR_UNKNOWN,
+		                            "error creating dhclient configuration file");
 		return FALSE;
 	}
 
@@ -534,7 +580,11 @@ ip6_start (NMDhcpClient *client,
 	                       nm_dhcp_client_get_info_only (NM_DHCP_CLIENT (self))
 	                         ? "-S"
 	                         : "-N",
-	                       duid, FALSE, NULL, needed_prefixes);
+	                       duid,
+	                       FALSE,
+	                       NULL,
+	                       needed_prefixes,
+	                       error);
 }
 
 static void
@@ -560,7 +610,13 @@ stop (NMDhcpClient *client, gboolean release, GBytes *duid)
 	if (release) {
 		pid_t rpid = -1;
 
-		if (dhclient_start (client, NULL, duid, TRUE, &rpid, 0)) {
+		if (dhclient_start (client,
+		                    NULL,
+		                    duid,
+		                    TRUE,
+		                    &rpid,
+		                    0,
+		                    NULL)) {
 			/* Wait a few seconds for the release to happen */
 			nm_dhcp_client_stop_pid (rpid, nm_dhcp_client_get_iface (client));
 		}