unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Karel Klic <kklic@redhat.com>
To: Glenn Morris <rgm@gnu.org>
Cc: emacs-devel@gnu.org
Subject: Re: [PATCH] SELinux support
Date: Mon, 22 Mar 2010 15:53:49 +0100	[thread overview]
Message-ID: <4BA7847D.6030906@redhat.com> (raw)
In-Reply-To: <o1wrx93u6u.fsf@fencepost.gnu.org>

[-- Attachment #1: Type: text/plain, Size: 715 bytes --]

Hi Glenn,

On 03/19/2010 03:46 AM, Glenn Morris wrote:
> Some comments:
>
> It would need some copyright paperwork before we could install it.
I'm sending the copyright assignment paper to the FSF today.
>
> With regards to RHEL apparently not providing a libselinux.pc
> file, maybe the configure.in stuff could be changed to use
> AC_CHECK_LIB instead of PKG_CHECK_MODULES? It seems that
> -lselinux is all that is needed (?).
Agreed. The emacs-1-* attached patch now uses AC_CHECK_LIB. -lselinux 
should suffice.
>
> It might be nice to extend copy-file to optionally preserve the
> context as well.
Agreed. The emacs-2-* attached patch now extends the copy-file function.

Thank you for the suggestions.

Karel

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: emacs-1-selinux-config.patch --]
[-- Type: text/x-patch; name="emacs-1-selinux-config.patch", Size: 4627 bytes --]

diff -U0 emacs-bzr-cur/ChangeLog.selinux-config emacs-bzr-cur/ChangeLog
--- emacs-bzr-cur/ChangeLog.selinux-config	2010-03-22 11:14:54.197886373 +0100
+++ emacs-bzr-cur/ChangeLog	2010-03-22 11:17:27.282886847 +0100
@@ -0,0 +1,5 @@
+2010-02-23  Karel Klíč  <kklic@redhat.com>
+
+	* configure.in: New option: --with(out)-selinux. 
+	Set HAVE_LIBSELINUX if we find libselinux.
+
diff -up emacs-bzr-cur/configure.in.selinux-config emacs-bzr-cur/configure.in
--- emacs-bzr-cur/configure.in.selinux-config	2010-03-22 11:14:54.435886553 +0100
+++ emacs-bzr-cur/configure.in	2010-03-22 11:27:57.131766948 +0100
@@ -161,6 +161,7 @@ OPTION_DEFAULT_OFF([ns],[use nextstep (C
 OPTION_DEFAULT_ON([gpm],[don't use -lgpm for mouse support on a GNU/Linux console])
 OPTION_DEFAULT_ON([dbus],[don't compile with D-Bus support])
 OPTION_DEFAULT_ON([gconf],[don't compile with GConf support])
+OPTION_DEFAULT_ON([selinux],[don't compile with SELinux support])
 
 ## For the times when you want to build Emacs but don't have
 ## a suitable makeinfo, and can live without the manuals.
@@ -1738,6 +1739,17 @@ if test "${HAVE_X11}" = "yes" && test "$
    fi
 fi
 
+dnl SELinux is available for GNU/Linux only.
+HAVE_LIBSELINUX=no
+if test "${with_selinux}" = "yes"; then
+   AC_CHECK_LIB([selinux], [lgetfilecon], HAVE_LIBSELINUX=yes, HAVE_LIBSELINUX=no)
+   if test "$HAVE_LIBSELINUX" = yes; then
+      AC_DEFINE(HAVE_LIBSELINUX, 1, [Define to 1 if using SELinux.])
+      LIBSELINUX_LIBS=-lselinux
+      AC_SUBST(LIBSELINUX_LIBS)
+   fi
+fi
+
 dnl Do not put whitespace before the #include statements below.
 dnl Older compilers (eg sunos4 cc) choke on it.
 HAVE_XAW3D=no
@@ -3090,6 +3102,7 @@ echo "  Does Emacs use -lrsvg-2?        
 echo "  Does Emacs use -lgpm?                                   ${HAVE_GPM}"
 echo "  Does Emacs use -ldbus?                                  ${HAVE_DBUS}"
 echo "  Does Emacs use -lgconf?                                 ${HAVE_GCONF}"
+echo "  Does Emacs use -lselinux?                               ${HAVE_LIBSELINUX}"
 
 echo "  Does Emacs use -lfreetype?                              ${HAVE_FREETYPE}"
 echo "  Does Emacs use -lm17n-flt?                              ${HAVE_M17N_FLT}"
diff -U0 emacs-bzr-cur/src/ChangeLog.selinux-config emacs-bzr-cur/src/ChangeLog
--- emacs-bzr-cur/src/ChangeLog.selinux-config	2010-03-22 11:14:54.186886485 +0100
+++ emacs-bzr-cur/src/ChangeLog	2010-03-22 14:01:43.595886038 +0100
@@ -0,0 +1,4 @@
+2010-03-22  Karel Klíč  <kklic@redhat.com>
+
+	* Makefile.in: Added libselinux LIBS.
+
diff -up emacs-bzr-cur/src/Makefile.in.selinux-config emacs-bzr-cur/src/Makefile.in
--- emacs-bzr-cur/src/Makefile.in.selinux-config	2010-03-22 11:14:55.288761407 +0100
+++ emacs-bzr-cur/src/Makefile.in	2010-03-22 11:28:30.212886766 +0100
@@ -254,6 +254,10 @@ GCONF_CFLAGS = @GCONF_CFLAGS@
 GCONF_LIBS = @GCONF_LIBS@
 #endif
 
+#ifdef HAVE_LIBSELINUX
+LIBSELINUX_LIBS = @LIBSELINUX_LIBS@
+#endif
+
 /* DO NOT use -R.  There is a special hack described in lastfile.c
    which is used instead.  Some initialized data areas are modified
    at initial startup, then labeled as part of the text area when
@@ -267,7 +271,7 @@ GCONF_LIBS = @GCONF_LIBS@
 
 /* C_SWITCH_X_SITE must come before C_SWITCH_X_MACHINE and C_SWITCH_X_SYSTEM
    since it may have -I options that should override those two.  */
-ALL_CFLAGS=-Demacs -DHAVE_CONFIG_H $(MYCPPFLAGS) -I. -I${srcdir} C_SWITCH_MACHINE C_SWITCH_SYSTEM C_SWITCH_X_SITE C_SWITCH_X_MACHINE C_SWITCH_X_SYSTEM C_SWITCH_SYSTEM_TEMACS ${CFLAGS_SOUND} ${RSVG_CFLAGS} ${DBUS_CFLAGS} ${GCONF_CFLAGS} ${CFLAGS} @FREETYPE_CFLAGS@ @FONTCONFIG_CFLAGS@ @LIBOTF_CFLAGS@ @M17N_FLT_CFLAGS@ ${DEPFLAGS}
+ALL_CFLAGS=-Demacs -DHAVE_CONFIG_H $(MYCPPFLAGS) -I. -I${srcdir} C_SWITCH_MACHINE C_SWITCH_SYSTEM C_SWITCH_X_SITE C_SWITCH_X_MACHINE C_SWITCH_X_SYSTEM C_SWITCH_SYSTEM_TEMACS ${CFLAGS_SOUND} ${RSVG_CFLAGS} ${DBUS_CFLAGS} ${GCONF_CFLAGS} ${LIBSELINUX_CFLAGS} ${CFLAGS} @FREETYPE_CFLAGS@ @FONTCONFIG_CFLAGS@ @LIBOTF_CFLAGS@ @M17N_FLT_CFLAGS@ ${DEPFLAGS}
 ALL_OBJC_CFLAGS=$(ALL_CFLAGS) @GNU_OBJC_CFLAGS@
 
 .SUFFIXES: .m
@@ -850,7 +854,7 @@ SOME_MACHINE_LISP = ../lisp/mouse.elc \
 
 LIBES = $(LOADLIBES) $(LIBS) $(LIBX) $(LIBSOUND) $(RSVG_LIBS) $(DBUS_LIBS) \
    @LIBGPM@ @LIBRESOLV@ LIBS_SYSTEM LIBS_MACHINE LIBS_TERMCAP \
-   LIBS_DEBUG $(GETLOADAVG_LIBS) ${GCONF_LIBS} \
+   LIBS_DEBUG $(GETLOADAVG_LIBS) ${GCONF_LIBS} ${LIBSELINUX_LIBS} \
    @FREETYPE_LIBS@ @FONTCONFIG_LIBS@ @LIBOTF_LIBS@ @M17N_FLT_LIBS@ \
    $(GNULIB_VAR) LIB_MATH LIB_STANDARD $(GNULIB_VAR)
 

[-- Attachment #3: emacs-2-selinux-context-fun.patch --]
[-- Type: text/x-patch, Size: 12012 bytes --]

diff -U0 emacs-bzr/src/ChangeLog.selinux-context-fun emacs-bzr/src/ChangeLog
--- emacs-bzr/src/ChangeLog.selinux-context-fun	2010-03-22 14:30:57.235887665 +0100
+++ emacs-bzr/src/ChangeLog	2010-03-22 15:05:20.936885923 +0100
@@ -2,0 +3,8 @@
+	* eval.c, lisp.h (call7): New function.
+
+	* fileio.c (Ffile_selinux_context): New function.
+	(Fset_file_selinux_context): New function.
+	(Fcopy_file): New parameter preserve-selinux-context.
+	(Frename_file): Preserve selinux context when renaming
+	by copy-file.
+
diff -up emacs-bzr/src/eval.c.selinux-context-fun emacs-bzr/src/eval.c
--- emacs-bzr/src/eval.c.selinux-context-fun	2010-03-22 14:41:29.485760685 +0100
+++ emacs-bzr/src/eval.c	2010-03-22 14:57:18.547767559 +0100
@@ -2930,6 +2930,33 @@ call6 (fn, arg1, arg2, arg3, arg4, arg5,
 #endif /* not NO_ARG_ARRAY */
 }
 
+/* Call function fn with 7 arguments arg1, arg2, arg3, arg4, arg5, arg6, arg7 */
+/* ARGSUSED */
+Lisp_Object
+call7 (fn, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+     Lisp_Object fn, arg1, arg2, arg3, arg4, arg5, arg6, arg7;
+{
+  struct gcpro gcpro1;
+#ifdef NO_ARG_ARRAY
+  Lisp_Object args[8];
+  args[0] = fn;
+  args[1] = arg1;
+  args[2] = arg2;
+  args[3] = arg3;
+  args[4] = arg4;
+  args[5] = arg5;
+  args[6] = arg6;
+  args[7] = arg7;
+  GCPRO1 (args[0]);
+  gcpro1.nvars = 8;
+  RETURN_UNGCPRO (Ffuncall (8, args));
+#else /* not NO_ARG_ARRAY */
+  GCPRO1 (fn);
+  gcpro1.nvars = 8;
+  RETURN_UNGCPRO (Ffuncall (8, &fn));
+#endif /* not NO_ARG_ARRAY */
+}
+
 /* The caller should GCPRO all the elements of ARGS.  */
 
 DEFUN ("funcall", Ffuncall, Sfuncall, 1, MANY, 0,
diff -up emacs-bzr/src/fileio.c.selinux-context-fun emacs-bzr/src/fileio.c
--- emacs-bzr/src/fileio.c.selinux-context-fun	2010-03-22 14:23:18.370761463 +0100
+++ emacs-bzr/src/fileio.c	2010-03-22 15:51:00.238886093 +0100
@@ -59,6 +59,11 @@ extern int errno;
 #endif
 #endif
 
+#ifdef HAVE_LIBSELINUX
+#include <selinux/selinux.h>
+#include <selinux/context.h>
+#endif
+
 #include "lisp.h"
 #include "intervals.h"
 #include "buffer.h"
@@ -339,6 +344,8 @@ Lisp_Object Qfile_accessible_directory_p
 Lisp_Object Qfile_modes;
 Lisp_Object Qset_file_modes;
 Lisp_Object Qset_file_times;
+Lisp_Object Qfile_selinux_context;
+Lisp_Object Qset_file_selinux_context;
 Lisp_Object Qfile_newer_than_file_p;
 Lisp_Object Qinsert_file_contents;
 Lisp_Object Qwrite_region;
@@ -1902,7 +1909,7 @@ barf_or_query_if_file_exists (absname, q
   return;
 }
 
-DEFUN ("copy-file", Fcopy_file, Scopy_file, 2, 5,
+DEFUN ("copy-file", Fcopy_file, Scopy_file, 2, 6,
        "fCopy file: \nGCopy %s to file: \np\nP",
        doc: /* Copy FILE to NEWNAME.  Both args must be strings.
 If NEWNAME names a directory, copy FILE there.
@@ -1924,10 +1931,13 @@ last-modified time as the old one.  (Thi
 A prefix arg makes KEEP-TIME non-nil.
 
 If PRESERVE-UID-GID is non-nil, we try to transfer the
-uid and gid of FILE to NEWNAME.  */)
-  (file, newname, ok_if_already_exists, keep_time, preserve_uid_gid)
+uid and gid of FILE to NEWNAME.
+
+If PRESERVE-SELINUX-CONTEXT is non-nil and SELinux is enabled 
+on the system, we copy the SELinux context of FILE to NEWNAME.  */)
+     (file, newname, ok_if_already_exists, keep_time, preserve_uid_gid, preserve_selinux_context)
      Lisp_Object file, newname, ok_if_already_exists, keep_time;
-     Lisp_Object preserve_uid_gid;
+     Lisp_Object preserve_uid_gid, preserve_selinux_context;
 {
   int ifd, ofd, n;
   char buf[16 * 1024];
@@ -1937,6 +1947,10 @@ uid and gid of FILE to NEWNAME.  */)
   int count = SPECPDL_INDEX ();
   int input_file_statable_p;
   Lisp_Object encoded_file, encoded_newname;
+#if HAVE_LIBSELINUX
+  security_context_t con;
+  int fail, conlength = 0;
+#endif
 
   encoded_file = encoded_newname = Qnil;
   GCPRO4 (file, newname, encoded_file, encoded_newname);
@@ -1957,8 +1971,9 @@ uid and gid of FILE to NEWNAME.  */)
   if (NILP (handler))
     handler = Ffind_file_name_handler (newname, Qcopy_file);
   if (!NILP (handler))
-    RETURN_UNGCPRO (call6 (handler, Qcopy_file, file, newname,
-			   ok_if_already_exists, keep_time, preserve_uid_gid));
+    RETURN_UNGCPRO (call7 (handler, Qcopy_file, file, newname,
+			   ok_if_already_exists, keep_time, preserve_uid_gid,
+			   preserve_selinux_context));
 
   encoded_file = ENCODE_FILE (file);
   encoded_newname = ENCODE_FILE (newname);
@@ -2012,6 +2027,15 @@ uid and gid of FILE to NEWNAME.  */)
      copyable by us. */
   input_file_statable_p = (fstat (ifd, &st) >= 0);
 
+#if HAVE_LIBSELINUX
+  if (!NILP (preserve_selinux_context) && is_selinux_enabled ())
+    {
+      conlength = fgetfilecon (ifd, &con);
+      if (conlength == -1)
+	report_file_error ("Doing fgetfilecon", Fcons (file, Qnil));
+    }
+#endif
+
 #if !defined (MSDOS) || __DJGPP__ > 1
   if (out_st.st_mode != 0
       && st.st_dev == out_st.st_dev && st.st_ino == out_st.st_ino)
@@ -2071,6 +2095,18 @@ uid and gid of FILE to NEWNAME.  */)
     }
 #endif	/* not MSDOS */
 
+#if HAVE_LIBSELINUX
+  if (conlength > 0)
+    {
+      /* Set the modified context back to the file. */
+      fail = fsetfilecon (ofd, con);
+      if (fail)
+	report_file_error ("Doing fsetfilecon", Fcons (newname, Qnil));
+
+      freecon (con);
+    }
+#endif
+
   /* Closing the output clobbers the file times on some systems.  */
   if (emacs_close (ofd) < 0)
     report_file_error ("I/O error", Fcons (newname, Qnil));
@@ -2297,7 +2333,7 @@ This is what happens in interactive use 
 	       have copy-file prompt again.  */
 	    Fcopy_file (file, newname,
 			NILP (ok_if_already_exists) ? Qnil : Qt,
-			Qt, Qt);
+			Qt, Qt, Qt);
 
 	  count = SPECPDL_INDEX ();
 	  specbind (Qdelete_by_moving_to_trash, Qnil);
@@ -2863,6 +2899,136 @@ See `file-symlink-p' to distinguish syml
 #endif
 }
 \f
+DEFUN ("file-selinux-context", Ffile_selinux_context,
+       Sfile_selinux_context, 1, 1, 0,
+       doc: /* Return SELinux context of file named FILENAME,
+as a list ("user", "role", "type", "range"). Return (nil, nil, nil, nil)
+if file does not exist, is not accessible, or SELinux is disabled */)
+     (filename)
+     Lisp_Object filename;
+{
+  Lisp_Object absname;
+  Lisp_Object values[4];
+  Lisp_Object handler;
+#if HAVE_LIBSELINUX
+  security_context_t con;
+  int conlength;
+  context_t context;
+#endif
+
+  absname = expand_and_dir_to_file (filename, current_buffer->directory);
+
+  /* If the file name has special constructs in it,
+     call the corresponding file handler.  */
+  handler = Ffind_file_name_handler (absname, Qfile_selinux_context);
+  if (!NILP (handler))
+    return call2 (handler, Qfile_selinux_context, absname);
+
+  absname = ENCODE_FILE (absname);
+
+  values[0] = Qnil;
+  values[1] = Qnil;
+  values[2] = Qnil;
+  values[3] = Qnil;
+#if HAVE_LIBSELINUX
+  if (is_selinux_enabled ())
+    {
+      conlength = lgetfilecon (SDATA (absname), &con);
+      if (conlength > 0)
+	{
+	  context = context_new (con);
+	  values[0] = build_string (context_user_get (context));
+	  values[1] = build_string (context_role_get (context));
+	  values[2] = build_string (context_type_get (context));
+	  values[3] = build_string (context_range_get (context));
+	  context_free (context);
+	}
+      if (con)
+	freecon (con);
+    }
+#endif
+
+  return Flist (sizeof(values) / sizeof(values[0]), values);
+}
+\f
+DEFUN ("set-file-selinux-context", Fset_file_selinux_context,
+       Sset_file_selinux_context, 2, 2, 0,
+       doc: /* Set SELinux context of file named FILENAME to CONTEXT
+as a list ("user", "role", "type", "range"). Has no effect if SELinux
+is disabled. */)
+     (filename, context)
+     Lisp_Object filename, context;
+{
+  Lisp_Object absname, encoded_absname;
+  Lisp_Object handler;
+  Lisp_Object user = CAR_SAFE (context);
+  Lisp_Object role = CAR_SAFE (CDR_SAFE (context));
+  Lisp_Object type = CAR_SAFE (CDR_SAFE (CDR_SAFE (context)));
+  Lisp_Object range = CAR_SAFE (CDR_SAFE (CDR_SAFE (CDR_SAFE (context))));
+#if HAVE_LIBSELINUX
+  security_context_t con;
+  int fail, conlength;
+  context_t parsed_con;
+#endif
+
+  absname = Fexpand_file_name (filename, current_buffer->directory);
+
+  /* If the file name has special constructs in it,
+     call the corresponding file handler.  */
+  handler = Ffind_file_name_handler (absname, Qset_file_selinux_context);
+  if (!NILP (handler))
+    return call3 (handler, Qset_file_selinux_context, absname, context);
+
+  encoded_absname = ENCODE_FILE (absname);
+
+#if HAVE_LIBSELINUX
+  if (is_selinux_enabled ())
+    {
+      /* Get current file context. */
+      conlength = lgetfilecon (SDATA (encoded_absname), &con);
+      if (conlength > 0)
+	{
+	  parsed_con = context_new (con);
+	  /* Change the parts defined in the parameter.*/
+	  if (STRINGP (user))
+	    {
+	      if (context_user_set (parsed_con, SDATA (user)))
+		error ("Doing context_user_set");
+	    }
+	  if (STRINGP (role))
+	    {
+	      if (context_role_set (parsed_con, SDATA (role)))
+		error ("Doing context_role_set");
+	    }
+	  if (STRINGP (type))
+	    {
+	      if (context_type_set (parsed_con, SDATA (type)))
+		error ("Doing context_type_set");
+	    }
+	  if (STRINGP (range))
+	    {
+	      if (context_range_set (parsed_con, SDATA (range)))
+		error ("Doing context_range_set");
+	    }
+
+	  /* Set the modified context back to the file. */
+	  fail = lsetfilecon (SDATA (encoded_absname), context_str (parsed_con));
+	  if (fail)
+	    report_file_error ("Doing lsetfilecon", Fcons (absname, Qnil));
+
+	  context_free (parsed_con);
+	}
+      else
+	report_file_error("Doing lgetfilecon", Fcons (absname, Qnil));
+
+      if (con)
+	freecon (con);
+    }
+#endif
+
+  return Qnil;
+}
+\f
 DEFUN ("file-modes", Ffile_modes, Sfile_modes, 1, 1, 0,
        doc: /* Return mode bits of file named FILENAME, as an integer.
 Return nil, if file does not exist or is not accessible.  */)
@@ -5515,6 +5681,8 @@ syms_of_fileio ()
   Qfile_modes = intern_c_string ("file-modes");
   Qset_file_modes = intern_c_string ("set-file-modes");
   Qset_file_times = intern_c_string ("set-file-times");
+  Qfile_selinux_context = intern_c_string("file-selinux-context");
+  Qset_file_selinux_context = intern_c_string("set-file-selinux-context");
   Qfile_newer_than_file_p = intern_c_string ("file-newer-than-file-p");
   Qinsert_file_contents = intern_c_string ("insert-file-contents");
   Qwrite_region = intern_c_string ("write-region");
@@ -5550,6 +5718,8 @@ syms_of_fileio ()
   staticpro (&Qfile_modes);
   staticpro (&Qset_file_modes);
   staticpro (&Qset_file_times);
+  staticpro (&Qfile_selinux_context);
+  staticpro (&Qset_file_selinux_context);
   staticpro (&Qfile_newer_than_file_p);
   staticpro (&Qinsert_file_contents);
   staticpro (&Qwrite_region);
@@ -5783,6 +5953,8 @@ When non-nil, the function `move-file-to
   defsubr (&Sfile_modes);
   defsubr (&Sset_file_modes);
   defsubr (&Sset_file_times);
+  defsubr (&Sfile_selinux_context);
+  defsubr (&Sset_file_selinux_context);
   defsubr (&Sset_default_file_modes);
   defsubr (&Sdefault_file_modes);
   defsubr (&Sfile_newer_than_file_p);
diff -up emacs-bzr/src/lisp.h.selinux-context-fun emacs-bzr/src/lisp.h
--- emacs-bzr/src/lisp.h.selinux-context-fun	2010-03-22 14:43:16.637768779 +0100
+++ emacs-bzr/src/lisp.h	2010-03-22 14:39:25.416761387 +0100
@@ -2855,6 +2855,7 @@ extern Lisp_Object call3 P_ ((Lisp_Objec
 extern Lisp_Object call4 P_ ((Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object));
 extern Lisp_Object call5 P_ ((Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object));
 extern Lisp_Object call6 P_ ((Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object));
+extern Lisp_Object call7 P_ ((Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object));
 EXFUN (Fdo_auto_save, 2);
 extern Lisp_Object apply_lambda P_ ((Lisp_Object, Lisp_Object, int));
 extern Lisp_Object internal_catch P_ ((Lisp_Object, Lisp_Object (*) (Lisp_Object), Lisp_Object));

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: emacs-3-selinux-backups-on-save.patch --]
[-- Type: text/x-patch; name="emacs-3-selinux-backups-on-save.patch", Size: 7132 bytes --]

diff -U0 emacs-23.1.92/lisp/ChangeLog.selinux-backups-on-save emacs-23.1.92/lisp/ChangeLog
--- emacs-23.1.92/lisp/ChangeLog.selinux-backups-on-save	2010-02-24 11:22:02.961149752 +0100
+++ emacs-23.1.92/lisp/ChangeLog	2010-02-24 11:34:23.555149599 +0100
@@ -0,0 +1,9 @@
+2010-02-24  Karel Klíč  <kklic@redhat.com>
+
+	* files.el (backup-buffer): Handle SELinux context, and return it
+	if a backup was made by renaming.
+	(backup-buffer-copy): Set SELinux context to the target file.
+	(basic-save-buffer): Set SELinux context of the newly written file.
+	(basic-save-buffer-1): Mention it also returns SELinux context.
+	(basic-save-buffer-2): Set SELinux context of the newly created file.
+
diff -up emacs-23.1.92/lisp/files.el.selinux-backups-on-save emacs-23.1.92/lisp/files.el
--- emacs-23.1.92/lisp/files.el.selinux-backups-on-save	2010-01-27 04:35:37.000000000 +0100
+++ emacs-23.1.92/lisp/files.el	2010-02-23 16:35:56.598149543 +0100
@@ -3616,10 +3616,13 @@ variable `make-backup-files'.  If it's d
 no longer accessible under its old name.
 
 The value is non-nil after a backup was made by renaming.
-It has the form (MODES . BACKUPNAME).
+It has the form (MODES SELINUXCONTEXT BACKUPNAME).
 MODES is the result of `file-modes' on the original
 file; this means that the caller, after saving the buffer, should change
 the modes of the new file to agree with the old modes.
+SELINUXCONTEXT is the result of `file-selinux-context' on the original 
+file; this means that the caller, after saving the buffer, should change
+the SELinux context of the new file to agree with the old context.
 BACKUPNAME is the backup file name, which is the old file renamed."
   (if (and make-backup-files (not backup-inhibited)
 	   (not buffer-backed-up)
@@ -3647,7 +3650,8 @@ BACKUPNAME is the backup file name, whic
 			    (or delete-old-versions
 				(y-or-n-p (format "Delete excess backup versions of %s? "
 						  real-file-name)))))
-		      (modes (file-modes buffer-file-name)))
+		      (modes (file-modes buffer-file-name))
+		      (context (file-selinux-context buffer-file-name)))
 		  ;; Actually write the back up file.
 		  (condition-case ()
 		      (if (or file-precious-flag
@@ -3667,10 +3671,10 @@ BACKUPNAME is the backup file name, whic
 						   (<= (nth 2 attr) backup-by-copying-when-privileged-mismatch)))
 					  (or (nth 9 attr)
 					      (not (file-ownership-preserved-p real-file-name)))))))
-			  (backup-buffer-copy real-file-name backupname modes)
+			  (backup-buffer-copy real-file-name backupname modes context)
 			;; rename-file should delete old backup.
 			(rename-file real-file-name backupname t)
-			(setq setmodes (cons modes backupname)))
+			(setq setmodes (list modes context backupname)))
 		    (file-error
 		     ;; If trouble writing the backup, write it in ~.
 		     (setq backupname (expand-file-name
@@ -3679,7 +3683,7 @@ BACKUPNAME is the backup file name, whic
 		     (message "Cannot write backup file; backing up in %s"
 			      backupname)
 		     (sleep-for 1)
-		     (backup-buffer-copy real-file-name backupname modes)))
+		     (backup-buffer-copy real-file-name backupname modes context)))
 		  (setq buffer-backed-up t)
 		  ;; Now delete the old versions, if desired.
 		  (if delete-old-versions
@@ -3691,7 +3695,7 @@ BACKUPNAME is the backup file name, whic
 		  setmodes)
 	    (file-error nil))))))
 
-(defun backup-buffer-copy (from-name to-name modes)
+(defun backup-buffer-copy (from-name to-name modes context)
   (let ((umask (default-file-modes)))
     (unwind-protect
 	(progn
@@ -3718,7 +3722,9 @@ BACKUPNAME is the backup file name, whic
       ;; Reset the umask.
       (set-default-file-modes umask)))
   (and modes
-       (set-file-modes to-name (logand modes #o1777))))
+       (set-file-modes to-name (logand modes #o1777)))
+  (and context
+       (set-file-selinux-context to-name context)))
 
 (defun file-name-sans-versions (name &optional keep-backup-version)
   "Return file NAME sans backup versions or strings.
@@ -4248,7 +4254,9 @@ Before and after saving the buffer, this
 		  (nthcdr 10 (file-attributes buffer-file-name)))
 	    (if setmodes
 		(condition-case ()
-		    (set-file-modes buffer-file-name (car setmodes))
+		    (progn
+		      (set-file-modes buffer-file-name (car setmodes))
+		      (set-file-selinux-context buffer-file-name (nth 1 setmodes)))
 		  (error nil))))
 	  ;; If the auto-save file was recent before this command,
 	  ;; delete it now.
@@ -4261,7 +4269,7 @@ Before and after saving the buffer, this
 ;; This does the "real job" of writing a buffer into its visited file
 ;; and making a backup file.  This is what is normally done
 ;; but inhibited if one of write-file-functions returns non-nil.
-;; It returns a value (MODES . BACKUPNAME), like backup-buffer.
+;; It returns a value (MODES SELINUXCONTEXT BACKUPNAME), like backup-buffer.
 (defun basic-save-buffer-1 ()
   (prog1
       (if save-buffer-coding-system
@@ -4273,7 +4281,7 @@ Before and after saving the buffer, this
       (setq buffer-file-coding-system-explicit
 	    (cons last-coding-system-used nil)))))
 
-;; This returns a value (MODES . BACKUPNAME), like backup-buffer.
+;; This returns a value (MODES SELINUXCONTEXT BACKUPNAME), like backup-buffer.
 (defun basic-save-buffer-2 ()
   (let (tempsetmodes setmodes)
     (if (not (file-writable-p buffer-file-name))
@@ -4344,8 +4352,9 @@ Before and after saving the buffer, this
 	    ;; Since we have created an entirely new file,
 	    ;; make sure it gets the right permission bits set.
 	    (setq setmodes (or setmodes
- 			       (cons (or (file-modes buffer-file-name)
+ 			       (list (or (file-modes buffer-file-name)
 					 (logand ?\666 umask))
+				     (file-selinux-context buffer-file-name)
 				     buffer-file-name)))
 	    ;; We succeeded in writing the temp file,
 	    ;; so rename it.
@@ -4356,8 +4365,11 @@ Before and after saving the buffer, this
 	;; (setmodes is set) because that says we're superseding.
 	(cond ((and tempsetmodes (not setmodes))
 	       ;; Change the mode back, after writing.
-	       (setq setmodes (cons (file-modes buffer-file-name) buffer-file-name))
-	       (set-file-modes buffer-file-name (logior (car setmodes) 128))))
+	       (setq setmodes (list (file-modes buffer-file-name) 
+				    (file-selinux-context buffer-file-name) 
+				    buffer-file-name))
+	       (set-file-modes buffer-file-name (logior (car setmodes) 128))
+	       (set-file-selinux-context buffer-file-name (nth 1 setmodes)))))
 	(let (success)
 	  (unwind-protect
 	      (progn
@@ -4371,8 +4383,8 @@ Before and after saving the buffer, this
 	    ;; the backup by renaming, undo the backing-up.
 	    (and setmodes (not success)
 		 (progn
-		   (rename-file (cdr setmodes) buffer-file-name t)
-		   (setq buffer-backed-up nil)))))))
+		   (rename-file (nth 2 setmodes) buffer-file-name t)
+		   (setq buffer-backed-up nil))))))
     setmodes))
 
 (defun diff-buffer-with-file (&optional buffer)

  reply	other threads:[~2010-03-22 14:53 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-03-02 19:36 [PATCH] SELinux support Karel Klic
2010-03-17  2:18 ` Glenn Morris
2010-03-18  0:10   ` Glenn Morris
2010-03-18 13:33     ` Karel Klic
2010-03-19  2:46       ` Glenn Morris
2010-03-22 14:53         ` Karel Klic [this message]
2010-03-22 16:01           ` Tom Tromey
2010-03-22 18:13             ` Glenn Morris
2010-03-29 13:53         ` Karel Klic
2010-03-29 19:00           ` Glenn Morris
2010-04-21  3:55           ` Glenn Morris
2010-04-23 14:23           ` Michael Albinus
2010-04-30  6:43             ` Karel Klic

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4BA7847D.6030906@redhat.com \
    --to=kklic@redhat.com \
    --cc=emacs-devel@gnu.org \
    --cc=rgm@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).