1666bb9
diff -up sm5.mine/configure.in.selinux sm5.mine/configure.in
1666bb9
--- sm5.mine/configure.in.selinux	2008-04-01 09:01:02.000000000 +0200
1666bb9
+++ sm5.mine/configure.in	2008-03-28 11:06:05.000000000 +0100
1666bb9
@@ -136,6 +136,16 @@ AC_ARG_ENABLE(sample,[AC_HELP_STRING([--
1666bb9
 AC_SUBST(smartd_suffix)
1666bb9
 AM_CONDITIONAL(SMARTD_SUFFIX, test $smartd_suffix)
1666bb9
 
1666bb9
+AC_ARG_WITH(selinux,[AC_HELP_STRING([--with-selinux],[Enables SELinux support])],
1666bb9
+	[
1666bb9
+		AC_CHECK_HEADERS([selinux/selinux.h], [], [echo "*** Error: Missing SELinux header files";exit 1])
1666bb9
+		AC_CHECK_LIB(selinux, matchpathcon, [with_selinux=yes], [echo "*** Error: Missing or incorrect SELinux library files"; exit 1],)
1666bb9
+	],[])
1666bb9
+AC_SUBST(with_selinux)
1666bb9
+if test "$with_selinux" = "yes"; then
1666bb9
+	AC_DEFINE(WITH_SELINUX, [1], [Define to 1 if SELinux support is enabled])
1666bb9
+fi
1666bb9
+
1666bb9
 if test "$prefix" = "NONE"; then
1666bb9
     dnl no prefix and no mandir, so use ${prefix}/share/man as default
1666bb9
     if test "$mandir" = '${prefix}/man'; then
1666bb9
@@ -151,7 +161,11 @@ dnl if OS not recognized, then use the o
1666bb9
 case "${host}" in
1666bb9
 	*-*-linux*)
1666bb9
 		AC_SUBST([os_deps], ['os_linux.o cciss.o']) 
1666bb9
-		AC_SUBST([os_libs], ['']) ;;
1666bb9
+		if test "$with_selinux" = "yes"; then
1666bb9
+			AC_SUBST([os_libs], ['-lselinux'])
1666bb9
+		else
1666bb9
+			AC_SUBST([os_libs], [''])
1666bb9
+		fi;;
1666bb9
 	*-*-freebsd*|*-*-dragonfly*|*-*-kfreebsd*-gnu*)
1666bb9
 		AC_SUBST([os_deps], ['os_freebsd.o cciss.o']) 
1666bb9
 		AC_SUBST([os_libs], ['-lcam']);;
1666bb9
diff -up sm5.mine/os_linux.cpp.selinux sm5.mine/os_linux.cpp
1666bb9
--- sm5.mine/os_linux.cpp.selinux	2008-04-01 09:01:14.000000000 +0200
1666bb9
+++ sm5.mine/os_linux.cpp	2008-04-01 12:28:04.000000000 +0200
1666bb9
@@ -60,6 +60,9 @@
1666bb9
 #ifndef makedev // old versions of types.h do not include sysmacros.h
1666bb9
 #include <sys/sysmacros.h>
1666bb9
 #endif
1666bb9
+#ifdef WITH_SELINUX
1666bb9
+#include <selinux/selinux.h>
1666bb9
+#endif
1666bb9
 
1666bb9
 #include "int64.h"
1666bb9
 #include "atacmds.h"
1666bb9
@@ -105,6 +108,14 @@ int setup_3ware_nodes(const char *nodena
1666bb9
   char             nodestring[NODE_STRING_LENGTH];
1666bb9
   struct stat      stat_buf;
1666bb9
   FILE             *file;
1666bb9
+  int              retval = 0;
1666bb9
+#ifdef WITH_SELINUX
1666bb9
+  security_context_t orig_context = NULL;
1666bb9
+  security_context_t node_context = NULL;
1666bb9
+  int                selinux_enabled  = is_selinux_enabled();
1666bb9
+  int                selinux_enforced = security_getenforce();
1666bb9
+#endif
1666bb9
+
1666bb9
 
1666bb9
   /* First try to open up /proc/devices */
1666bb9
   if (!(file = fopen("/proc/devices", "r"))) {
1666bb9
@@ -129,18 +140,50 @@ int setup_3ware_nodes(const char *nodena
1666bb9
     pout("No major number for /dev/%s listed in /proc/devices. Is the %s driver loaded?\n", nodename, driver_name);
1666bb9
     return 2;
1666bb9
   }
1666bb9
-
1666bb9
+#ifdef WITH_SELINUX
1666bb9
+  /* Prepare a database of contexts for files in /dev
1666bb9
+   * and save the current context */
1666bb9
+  if (selinux_enabled) {
1666bb9
+    if (matchpathcon_init_prefix(NULL, "/dev") < 0)
1666bb9
+      pout("Error initializing contexts database for /dev");
1666bb9
+    if (getfscreatecon(&orig_context) < 0) {
1666bb9
+      pout("Error retrieving original SELinux fscreate context");
1666bb9
+      if (selinux_enforced)
1666bb9
+        matchpathcon_fini();
1666bb9
+        return 6;
1666bb9
+      }
1666bb9
+  }
1666bb9
+#endif
1666bb9
   /* Now check if nodes are correct */
1666bb9
   for (index=0; index<16; index++) {
1666bb9
     sprintf(nodestring, "/dev/%s%d", nodename, index);
1666bb9
-
1666bb9
+#ifdef WITH_SELINUX
1666bb9
+    /* Get context of the node and set it as the default */
1666bb9
+    if (selinux_enabled) {
1666bb9
+      if (matchpathcon(nodestring, S_IRUSR | S_IWUSR, &node_context) < 0) {
1666bb9
+        pout("Could not retreive context for %s", nodestring);
1666bb9
+        if (selinux_enforced) {
1666bb9
+          retval = 6;
1666bb9
+          break;
1666bb9
+        }
1666bb9
+      }
1666bb9
+      if (setfscreatecon(node_context) < 0) {
1666bb9
+        pout ("Error setting default fscreate context");
1666bb9
+        if (selinux_enforced) {
1666bb9
+          retval = 6;
1666bb9
+          break;
1666bb9
+        }
1666bb9
+      }
1666bb9
+    }
1666bb9
+#endif
1666bb9
     /* Try to stat the node */
1666bb9
     if ((stat(nodestring, &stat_buf))) {
1666bb9
       /* Create a new node if it doesn't exist */
1666bb9
       if (mknod(nodestring, S_IFCHR|0600, makedev(tw_major, index))) {
1666bb9
         pout("problem creating 3ware device nodes %s", nodestring);
1666bb9
         syserror("mknod");
1666bb9
-        return 3;
1666bb9
+        retval = 3;
1666bb9
+        break;
1666bb9
       }
1666bb9
     }
1666bb9
 
1666bb9
@@ -153,18 +196,41 @@ int setup_3ware_nodes(const char *nodena
1666bb9
       if (unlink(nodestring)) {
1666bb9
         pout("problem unlinking stale 3ware device node %s", nodestring);
1666bb9
         syserror("unlink");
1666bb9
-        return 4;
1666bb9
+        retval = 4;
1666bb9
+        break;
1666bb9
       }
1666bb9
 
1666bb9
       /* Make a new node */
1666bb9
       if (mknod(nodestring, S_IFCHR|0600, makedev(tw_major, index))) {
1666bb9
         pout("problem creating 3ware device nodes %s", nodestring);
1666bb9
         syserror("mknod");
1666bb9
-        return 5;
1666bb9
+        retval = 5;
1666bb9
+        break;
1666bb9
       }
1666bb9
     }
1666bb9
+#ifdef WITH_SELINUX
1666bb9
+    if (selinux_enabled && node_context) {
1666bb9
+      freecon(node_context);
1666bb9
+      node_context = NULL;
1666bb9
+    }
1666bb9
+#endif
1666bb9
   }
1666bb9
-  return 0;
1666bb9
+
1666bb9
+#ifdef WITH_SELINUX
1666bb9
+  if (selinux_enabled) {
1666bb9
+    if(setfscreatecon(orig_context) < 0) {
1666bb9
+      pout("Error re-setting original fscreate context");
1666bb9
+      if (selinux_enforced)
1666bb9
+        retval = 6;
1666bb9
+    }
1666bb9
+    if(orig_context)
1666bb9
+      freecon(orig_context);
1666bb9
+    if(node_context)
1666bb9
+      freecon(node_context);
1666bb9
+    matchpathcon_fini();
1666bb9
+  }
1666bb9
+#endif
1666bb9
+  return retval;
1666bb9
 }
1666bb9
 
1666bb9
 static char prev_scsi_dev[128];