From ce158e229f74a29373a7cb7985dfb16ef344b890 Mon Sep 17 00:00:00 2001 From: chrfranke <chrfranke@4ea69e1a-61f1-4043-bf83-b5c94c648137> Date: Wed, 3 Feb 2010 20:56:41 +0000 Subject: [PATCH] smartd: Add option '-C, --capabilities' if libcap-ng is available (ticket #45). git-svn-id: https://smartmontools.svn.sourceforge.net/svnroot/smartmontools/trunk@3057 4ea69e1a-61f1-4043-bf83-b5c94c648137 --- smartmontools/CHANGELOG | 9 ++++++ smartmontools/INSTALL | 2 ++ smartmontools/Makefile.am | 10 +++++- smartmontools/NEWS | 1 + smartmontools/configure.in | 23 ++++++++++++++ smartmontools/smartd.8.in | 8 +++++ smartmontools/smartd.cpp | 62 ++++++++++++++++++++++++++++++++++++-- 7 files changed, 111 insertions(+), 4 deletions(-) diff --git a/smartmontools/CHANGELOG b/smartmontools/CHANGELOG index e7fa04e1a..35059a8d1 100644 --- a/smartmontools/CHANGELOG +++ b/smartmontools/CHANGELOG @@ -43,6 +43,15 @@ NOTES FOR FUTURE RELEASES: see TODO file. <DEVELOPERS: ADDITIONS TO THE CHANGE LOG GO JUST BELOW HERE, PLEASE> + [CF] smartd: Add option '-C, --capabilities' if libcap-ng is available + (ticket #45). + Support is added if libcap-ng is found during build. This can + be overridden by configure option '--with-libcap-ng=[auto|yes|no]'. + + Based on Debian patch: + http://patch-tracker.debian.org/patch/series/view/smartmontools/5.39-3/62_lowcap.patch + Modified to fix regression (ticket #41, Debian bug 564876). + [CF] Bugfix release 5.39.1. [CF] Linux: Fix spin-up of SATA drive if '-n standby' is used diff --git a/smartmontools/INSTALL b/smartmontools/INSTALL index b97c5cdcf..ba220efae 100644 --- a/smartmontools/INSTALL +++ b/smartmontools/INSTALL @@ -669,6 +669,8 @@ OPTIONS DEFAULT AFFECTS --with-selinux <not set> Enables SELinux support. If smartmontools has to create the /dev/tw[ae] device nodes for 3ware/AMCC controllers, this option ensures that the nodes are created with correct SELinux file contexts. +--with-libcap-ng --with-libcap-ng=auto Enables/disables libcap-ng support. If enabled and libcap-ng is + available, option --capabilities is added to smartd. --enable-drivedb --disable-drivedb Enables default drive database file '${drivedbdir}/drivedb.h' --with-drivedbdir ${prefix}/share/smartmontools Directory for 'drivedb.h' (implies --enable-drivedb) --enable-savestates --disable-savestates Enables default smartd state files '${savestates}MODEL-SERIAL.ata.state' diff --git a/smartmontools/Makefile.am b/smartmontools/Makefile.am index 30aa1e32d..943a73bd9 100644 --- a/smartmontools/Makefile.am +++ b/smartmontools/Makefile.am @@ -46,7 +46,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 \ @@ -405,6 +405,12 @@ install-initdDATA : $(initd_DATA_install) uninstall-initdDATA: $(initd_DATA_uninstall) +if ENABLE_CAPABILITIES +MAN_CAPABILITIES = cat +else +MAN_CAPABILITIES = sed '/BEGIN ENABLE_CAPABILITIES/,/END ENABLE_CAPABILITIES/d' +endif + if ENABLE_DRIVEDB MAN_DRIVEDB = sed "s|/usr/local/share/smartmontools/drivedb\\.h|$(drivedbdir)/drivedb.h|g" else @@ -435,6 +441,7 @@ ${file}: $(srcdir)/${file}.in Makefile svnversion.h s|/usr/local/share/doc/smartmontools-5.1/|$(docsdir)/|g; \ s|/usr/local/etc/smartd\\.conf|$(sysconfdir)/smartd.conf|g; \ s|/usr/local/etc/smart_drivedb\\.h|$(sysconfdir)/smart_drivedb\\.h|g" ${.ALLSRC:M*.in} | \ + $(MAN_CAPABILITIES) | \ $(MAN_DRIVEDB) | \ $(MAN_SAVESTATES) | \ $(MAN_ATTRIBUTELOG) > $@ @@ -450,6 +457,7 @@ smart%: $(srcdir)/smart%.in Makefile svnversion.h sed "s|/usr/local/share/doc/smartmontools-5.1/|$(docsdir)/|g" | \ sed "s|/usr/local/etc/smartd\\.conf|$(sysconfdir)/smartd.conf|g" | \ sed "s|/usr/local/etc/smart_drivedb\\.h|$(sysconfdir)/smart_drivedb\\.h|g" | \ + $(MAN_CAPABILITIES) | \ $(MAN_DRIVEDB) | \ $(MAN_SAVESTATES) | \ $(MAN_ATTRIBUTELOG) > $@ diff --git a/smartmontools/NEWS b/smartmontools/NEWS index fd64f13f1..35fee538a 100644 --- a/smartmontools/NEWS +++ b/smartmontools/NEWS @@ -12,6 +12,7 @@ Summary: smartmontools release 5.40 - configure: New default value for '--with-docdir'. - Drive database is in a separate source file 'drivedb.h' which can be downloaded from SVN. +- smartd libcap-ng support, option '-C, --capabilities'. Date 2010-01-28 Summary: smartmontools release 5.39.1 diff --git a/smartmontools/configure.in b/smartmontools/configure.in index 5eba73810..41876cad0 100644 --- a/smartmontools/configure.in +++ b/smartmontools/configure.in @@ -233,6 +233,29 @@ 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, + [AC_HELP_STRING([--with-libcap-ng=[auto|yes|no]], [Add Libcap-ng support to smartd [auto]])], + [with_libcap_ng="$withval"], + [with_libcap_ng=auto]) + +use_libcap_ng=no +if test "$with_libcap_ng" != "no"; then + AC_CHECK_LIB(cap-ng, capng_clear, + [AC_DEFINE(HAVE_LIBCAP_NG, 1, [Define to 1 if you have the `cap-ng' library (-lcap-ng).]) + CAPNG_LDADD="-lcap-ng"; use_libcap_ng=yes]) + + if test "$use_libcap_ng" = "yes"; then + AC_CHECK_HEADER(cap-ng.h, [], [AC_MSG_ERROR([libcap-ng libraries found but headers are missing])]) + elif test "$with_libcap_ng" = "yes"; then + AC_MSG_ERROR([libcap-ng support was requested but the library was not found]) + fi +fi + +AC_MSG_CHECKING([whether to use libcap-ng]) +AC_SUBST(CAPNG_LDADD) +AM_CONDITIONAL(ENABLE_CAPABILITIES, [test "$use_libcap_ng" = "yes"]) +AC_MSG_RESULT([$use_libcap_ng]) + 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 --git a/smartmontools/smartd.8.in b/smartmontools/smartd.8.in index 619f45285..f56045947 100644 --- a/smartmontools/smartd.8.in +++ b/smartmontools/smartd.8.in @@ -174,6 +174,14 @@ input. This is useful for commands like: .fi to perform quick and simple checks without a configuration file. +.\" BEGIN ENABLE_CAPABILITIES +.TP +.B \-C, \-\-capabilities +Use \fBcapabilities(7)\fP (EXPERIMENTAL). + +Warning: Mail notification does not work when used. + +.\" END ENABLE_CAPABILITIES .TP .B \-d, \-\-debug Runs \fBsmartd\fP in "debug" mode. In this mode, it displays status diff --git a/smartmontools/smartd.cpp b/smartmontools/smartd.cpp index ddf431f12..e9c0b02d7 100644 --- a/smartmontools/smartd.cpp +++ b/smartmontools/smartd.cpp @@ -1,4 +1,4 @@ -/* + /* * Home page of code is: http://smartmontools.sourceforge.net * * Copyright (C) 2002-10 Bruce Allen <smartmontools-support@lists.sourceforge.net> @@ -77,6 +77,10 @@ extern "C" int __stdcall FreeConsole(void); #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" @@ -190,6 +194,11 @@ static int facility=LOG_DAEMON; static bool do_fork=true; #endif +#ifdef HAVE_LIBCAP_NG +// command-line: enable capabilities? +static bool enable_capabilities = false; +#endif + // used for control of printing, passing arguments to atacmds.c smartmonctrl *con=NULL; @@ -918,6 +927,14 @@ static void MailWarning(const dev_config & cfg, dev_state & state, int which, co 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) mail->firstsent=epoch; @@ -1464,6 +1481,11 @@ void Usage (void){ PrintOut(LOG_INFO,"\n"); PrintOut(LOG_INFO," -c NAME|-, --configfile=NAME|-\n"); PrintOut(LOG_INFO," Read configuration file NAME or stdin [default is %s]\n\n", configfile); +#ifdef HAVE_LIBCAP_NG + PrintOut(LOG_INFO," -C, --capabilities\n"); + PrintOut(LOG_INFO," Use capabilities (EXPERIMENTAL).\n" + " Warning: Mail notification does not work when used.\n\n"); +#endif PrintOut(LOG_INFO," -d, --debug\n"); PrintOut(LOG_INFO," Start smartd in debug mode\n\n"); PrintOut(LOG_INFO," -D, --showdirectives\n"); @@ -3707,7 +3729,11 @@ void ParseOpts(int argc, char **argv){ char *tailptr; long lchecktime; // Please update GetValidArgList() if you edit shortopts - const char *shortopts = "c:l:q:dDni:p:r:s:A:B:Vh?"; + static const char shortopts[] = "c:l:q:dDni:p:r:s:A:B:Vh?" +#ifdef HAVE_LIBCAP_NG + "C" +#endif + ; char *arg; // Please update GetValidArgList() if you edit longopts struct option longopts[] = { @@ -3733,6 +3759,9 @@ void ParseOpts(int argc, char **argv){ { "copyright", no_argument, 0, 'V' }, { "help", no_argument, 0, 'h' }, { "usage", no_argument, 0, 'h' }, +#ifdef HAVE_LIBCAP_NG + { "capabilities", no_argument, 0, 'C' }, +#endif { 0, 0, 0, 0 } }; @@ -3891,6 +3920,12 @@ void ParseOpts(int argc, char **argv){ PrintOut(LOG_INFO, "%s", format_version_info("smartd", true /*full*/).c_str()); EXIT(0); break; +#ifdef HAVE_LIBCAP_NG + case 'C': + // enable capabilities + enable_capabilities = true; + break; +#endif case 'h': // help: print summary of command-line options debugmode=1; @@ -4230,6 +4265,16 @@ int main_worker(int argc, char **argv) bool write_states_always = true; +#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 for (;;) { @@ -4323,7 +4368,18 @@ int main_worker(int argc, char **argv) PrintTestSchedule(configs, states, devices); return 0; } - + +#ifdef HAVE_LIBCAP_NG + if (enable_capabilities) { + for (unsigned i = 0; i < configs.size(); i++) { + if (!configs[i].emailaddress.empty() || !configs[i].emailcmdline.empty()) { + PrintOut(LOG_WARNING, "Mail can't be enabled together with --capabilities. All mail will be suppressed.\n"); + break; + } + } + } +#endif + // reset signal caughtsigHUP=0; -- GitLab