Blob Blame History Raw
diff -up smartmontools-5.38/configure.in.lowcap smartmontools-5.38/configure.in
--- smartmontools-5.38/configure.in.lowcap	2009-10-05 15:33:00.231298546 +0200
+++ smartmontools-5.38/configure.in	2009-10-05 15:33:00.237483461 +0200
@@ -143,6 +143,40 @@ if test "$with_selinux" = "yes"; then
 	AC_DEFINE(WITH_SELINUX, [1], [Define to 1 if SELinux support is enabled])
 fi
 
+  AC_ARG_WITH(libcap-ng,
+    [  --with-libcap-ng=[auto/yes/no]  Add Libcap-ng support [default=auto]],,
+    with_libcap_ng=auto)
+
+# Check for Libcap-ng API
+#
+# libcap-ng detection
+
+if test x$with_libcap_ng = xno ; then
+    have_libcap_ng=no;
+else
+    # Start by checking for header file
+    AC_CHECK_HEADER(cap-ng.h, capng_headers=yes, capng_headers=no)
+
+    # See if we have libcap-ng library
+    AC_CHECK_LIB(cap-ng, capng_clear, CAPNG_LDADD=-lcap-ng,)
+
+    # Check results are usable
+    if test x$with_libcap_ng = xyes -a x$CAPNG_LDADD = x ; then
+       AC_MSG_ERROR(libcap-ng support was requested and the library was not found)
+    fi
+    if test x$CAPNG_LDADD != x -a $capng_headers = no ; then
+       AC_MSG_ERROR(libcap-ng libraries found but headers are missing)
+    fi
+fi
+AC_SUBST(CAPNG_LDADD)
+AC_MSG_CHECKING(whether to use libcap-ng)
+if test x$CAPNG_LDADD != x ; then
+    AC_DEFINE(HAVE_LIBCAP_NG,1,[libcap-ng support])
+    AC_MSG_RESULT(yes)
+else
+    AC_MSG_RESULT(no)
+fi
+
 if test "$prefix" = "NONE"; then
     dnl no prefix and no mandir, so use ${prefix}/share/man as default
     if test "$mandir" = '${prefix}/man'; then
diff -up smartmontools-5.38/Makefile.am.lowcap smartmontools-5.38/Makefile.am
--- smartmontools-5.38/Makefile.am.lowcap	2007-04-01 18:49:44.000000000 +0200
+++ smartmontools-5.38/Makefile.am	2009-10-05 15:33:00.238483296 +0200
@@ -35,7 +35,7 @@ smartd_SOURCES =  smartd.cpp      \
                   utility.cpp     \
                   utility.h
 
-smartd_LDADD = @os_deps@ @os_libs@
+smartd_LDADD = @os_deps@ @os_libs@ @CAPNG_LDADD@
 smartd_DEPENDENCIES = @os_deps@
 
 EXTRA_smartd_SOURCES = os_darwin.cpp    \
diff -up smartmontools-5.38/smartd.8.in.lowcap smartmontools-5.38/smartd.8.in
--- smartmontools-5.38/smartd.8.in.lowcap	2008-03-04 23:09:47.000000000 +0100
+++ smartmontools-5.38/smartd.8.in	2009-10-05 15:44:35.455113557 +0200
@@ -354,6 +354,12 @@ The default level is 1, so \'\-r ataioct
 equivalent.
 
 .TP
+.B \-C, \-\-capabilities
+Use possix \fBcapabilities(7)\fP (EXPERIMENTAL).
+
+Warning: Mail notification does not work when used.
+
+.TP
 .B \-\-service
 Cygwin and Windows only: Enables \fBsmartd\fP to run as a Windows service.
 
diff -up smartmontools-5.38/smartd.cpp.lowcap smartmontools-5.38/smartd.cpp
--- smartmontools-5.38/smartd.cpp.lowcap	2009-10-05 15:33:00.224483349 +0200
+++ smartmontools-5.38/smartd.cpp	2009-10-05 15:33:00.245483604 +0200
@@ -74,6 +74,10 @@ extern "C" int __stdcall FreeConsole(voi
 #include <io.h> // setmode()
 #endif // __CYGWIN__
 
+#ifdef HAVE_LIBCAP_NG
+#include <cap-ng.h>
+#endif //LIBCAP_NG
+
 // locally included files
 #include "int64.h"
 #include "atacmds.h"
@@ -179,6 +183,11 @@ static int facility=LOG_DAEMON;
 static bool do_fork=true;
 #endif
 
+#ifdef HAVE_LIBCAP_NG
+// enable possix capabilities
+static bool enable_capabilities=false;
+#endif
+
 // used for control of printing, passing arguments to atacmds.c
 smartmonctrl *con=NULL;
 
@@ -613,6 +622,15 @@ void MailWarning(cfgfile *cfg, int which
     if  (epoch<(mail->lastsent+days))
       return;
   }
+  
+#ifdef HAVE_LIBCAP_NG
+  if (enable_capabilities) {
+    PrintOut(LOG_ERR,"Sending a mail was supressed. "
+		     "Mails can't be send when capabilites are enabled\n");
+    return;
+  }
+
+#endif
 
   // record the time of this mail message, and the first mail message
   if (!mail->logged)
@@ -1239,6 +1257,11 @@ void Usage (void){
   PrintOut(LOG_INFO,"        Quit on one of: %s\n\n", GetValidArgList('q'));
   PrintOut(LOG_INFO,"  -r, --report=TYPE\n");
   PrintOut(LOG_INFO,"        Report transactions for one of: %s\n\n", GetValidArgList('r'));
+#ifdef HAVE_LIBCAP_NG
+  PrintOut(LOG_INFO,"  -C, --usecapabilities\n");
+  PrintOut(LOG_INFO,"        Use possix capabilities (EXPERIMENTAL).\n"
+		    "        Warning: Mail notification does not work when used.\n");
+#endif
 #ifdef _WIN32
   PrintOut(LOG_INFO,"  --service\n");
   PrintOut(LOG_INFO,"        Running as windows service (see man page), install with:\n");
@@ -1260,6 +1283,9 @@ void Usage (void){
   PrintOut(LOG_INFO,"  -p NAME    Write PID file NAME\n");
   PrintOut(LOG_INFO,"  -q WHEN    Quit on one of: %s\n", GetValidArgList('q'));
   PrintOut(LOG_INFO,"  -r TYPE    Report transactions for one of: %s\n", GetValidArgList('r'));
+#ifdef HAVE_LIBCAP_NG
+  PrintOut(LOG_INFO,"  -C         Use possix capabilities (EXPERIMENTAL)\n");
+#endif
   PrintOut(LOG_INFO,"  -V         Print License, Copyright, and version information\n");
 #endif
 }
@@ -3890,6 +3916,7 @@ void ParseOpts(int argc, char **argv){
     { "copyright",      no_argument,       0, 'V' },
     { "help",           no_argument,       0, 'h' },
     { "usage",          no_argument,       0, 'h' },
+    { "usecapabilities",no_argument,       0, 'C' },
     { 0,                0,                 0, 0   }
   };
 #endif
@@ -4030,6 +4057,12 @@ void ParseOpts(int argc, char **argv){
       PrintCopyleft();
       EXIT(0);
       break;
+#ifdef HAVE_LIBCAP_NG
+    case 'C':
+      //enable possix capabilities
+      enable_capabilities=1;
+      break;
+#endif
     case 'h':
       // help: print summary of command-line options
       debugmode=1;
@@ -4408,6 +4441,16 @@ static int smartd_main(int argc, char **
   
   // don't exit on bad checksums
   con->checksumfail=0;
+
+#ifdef HAVE_LIBCAP_NG
+  // Drop capabilities
+  if (enable_capabilities) {
+    capng_clear(CAPNG_SELECT_BOTH);
+    capng_updatev(CAPNG_ADD, (capng_type_t)(CAPNG_EFFECTIVE|CAPNG_PERMITTED),
+                CAP_SYS_ADMIN, CAP_MKNOD, CAP_SYS_RAWIO, -1);
+    capng_apply(CAPNG_SELECT_BOTH);
+  }
+#endif
   
   // the main loop of the code
   while (1){
@@ -4482,7 +4525,15 @@ static int smartd_main(int argc, char **
         PrintTestSchedule(ATAandSCSIdevlist);
         EXIT(0);
       }
-      
+#ifdef HAVE_LIBCAP_NG
+      for(int i=numdevata+numdevscsi; i>1; i--) {
+	  if (ATAandSCSIdevlist[i-1]->mailwarn) {
+	      PrintOut(LOG_WARNING,"Mail can't be enabled together with --usecapabilities. All mail will be suppressed.\n");
+	      break;
+	  }
+      }
+	
+#endif
       // reset signal
       caughtsigHUP=0;
     }