summary refs log tree commit diff
path: root/src/nm-hostname-manager.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nm-hostname-manager.c')
-rw-r--r--src/nm-hostname-manager.c47
1 files changed, 32 insertions, 15 deletions
diff --git a/src/nm-hostname-manager.c b/src/nm-hostname-manager.c
index f44e169e..86beffdf 100644
--- a/src/nm-hostname-manager.c
+++ b/src/nm-hostname-manager.c
@@ -11,6 +11,7 @@
 
 #if HAVE_SELINUX
 #include <selinux/selinux.h>
+#include <selinux/label.h>
 #endif
 
 #include "nm-libnm-core-intern/nm-common-macros.h"
@@ -345,8 +346,8 @@ nm_hostname_manager_write_hostname (NMHostnameManager *self, const char *hostnam
 	gs_unref_variant GVariant *var = NULL;
 	struct stat file_stat;
 #if HAVE_SELINUX
-	security_context_t se_ctx_prev = NULL, se_ctx = NULL;
-	mode_t st_mode = 0;
+	gboolean fcon_was_set = FALSE;
+	char *fcon_prev = NULL;
 #endif
 
 	g_return_val_if_fail (NM_IS_HOSTNAME_MANAGER (self), FALSE);
@@ -376,16 +377,6 @@ nm_hostname_manager_write_hostname (NMHostnameManager *self, const char *hostnam
 	    && (link_path = nm_utils_read_link_absolute (file, NULL)))
 		file = link_path;
 
-#if HAVE_SELINUX
-	/* Get default context for hostname file and set it for fscreate */
-	if (stat (file, &file_stat) == 0)
-		st_mode = file_stat.st_mode;
-	matchpathcon (file, st_mode, &se_ctx);
-	matchpathcon_fini ();
-	getfscreatecon (&se_ctx_prev);
-	setfscreatecon (se_ctx);
-#endif
-
 #if defined (HOSTNAME_PERSIST_GENTOO)
 	hostname_eol = g_strdup_printf ("#Generated by NetworkManager\n"
 	                                "hostname=\"%s\"\n", hostname);
@@ -393,13 +384,39 @@ nm_hostname_manager_write_hostname (NMHostnameManager *self, const char *hostnam
 	hostname_eol = g_strdup_printf ("%s\n", hostname);
 #endif
 
+#if HAVE_SELINUX
+	/* Get default context for hostname file and set it for fscreate */
+	{
+		struct selabel_handle *handle;
+
+		handle = selabel_open (SELABEL_CTX_FILE, NULL, 0);
+		if (handle) {
+			mode_t st_mode = 0;
+			char *fcon = NULL;
+
+			if (stat (file, &file_stat) == 0)
+				st_mode = file_stat.st_mode;
+
+			if (   (selabel_lookup (handle, &fcon, file, st_mode) == 0)
+			    && (getfscreatecon (&fcon_prev) == 0)) {
+				setfscreatecon (fcon);
+				fcon_was_set = TRUE;
+			}
+
+			selabel_close (handle);
+			freecon (fcon);
+		}
+	}
+#endif
+
 	ret = g_file_set_contents (file, hostname_eol, -1, &error);
 
 #if HAVE_SELINUX
 	/* Restore previous context and cleanup */
-	setfscreatecon (se_ctx_prev);
-	freecon (se_ctx);
-	freecon (se_ctx_prev);
+	if (fcon_was_set)
+		setfscreatecon (fcon_prev);
+	if (fcon_prev)
+		freecon (fcon_prev);
 #endif
 
 	g_free (hostname_eol);