Hello community, here is the log from the commit of package snapper for openSUSE:Factory checked in at 2016-08-10 19:54:07 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/snapper (Old) and /work/SRC/openSUSE:Factory/.snapper.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "snapper" Changes: -------- --- /work/SRC/openSUSE:Factory/snapper/snapper.changes 2016-05-03 09:33:07.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.snapper.new/snapper.changes 2016-08-10 19:54:08.000000000 +0200 @@ -1,0 +2,7 @@ +Tue Aug 02 09:46:52 CEST 2016 - aschn...@suse.com + +- merged SELinux support from Red Hat (disabled at compile-time + per default) (gh#openSUSE/snapper#239) +- version 0.3.3 + +------------------------------------------------------------------- Old: ---- snapper-0.3.2.tar.bz2 New: ---- snapper-0.3.3.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ snapper.spec ++++++ --- /var/tmp/diff_new_pack.4MenAl/_old 2016-08-10 19:54:09.000000000 +0200 +++ /var/tmp/diff_new_pack.4MenAl/_new 2016-08-10 19:54:09.000000000 +0200 @@ -17,7 +17,7 @@ Name: snapper -Version: 0.3.2 +Version: 0.3.3 Release: 0 BuildRoot: %{_tmppath}/%{name}-%{version}-build Source: snapper-%{version}.tar.bz2 ++++++ snapper-0.3.2.tar.bz2 -> snapper-0.3.3.tar.bz2 ++++++ ++++ 1726 lines of diff (skipped) ++++ retrying with extended exclude list diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/snapper-0.3.2/VERSION new/snapper-0.3.3/VERSION --- old/snapper-0.3.2/VERSION 2016-04-19 11:27:11.000000000 +0200 +++ new/snapper-0.3.3/VERSION 2016-08-02 13:30:41.000000000 +0200 @@ -1 +1 @@ -0.3.2 +0.3.3 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/snapper-0.3.2/config.h.in new/snapper-0.3.3/config.h.in --- old/snapper-0.3.2/config.h.in 2016-04-19 14:03:12.000000000 +0200 +++ new/snapper-0.3.3/config.h.in 2016-08-02 13:35:20.000000000 +0200 @@ -27,6 +27,9 @@ /* Enable rollback support */ #undef ENABLE_ROLLBACK +/* Enable SELinux support */ +#undef ENABLE_SELINUX + /* Enable extended attributes support */ #undef ENABLE_XATTRS @@ -42,6 +45,9 @@ /* Define to 1 if you have the `btrfs' library (-lbtrfs). */ #undef HAVE_LIBBTRFS +/* Define to 1 if you have the `selinux' library (-lselinux). */ +#undef HAVE_LIBSELINUX + /* Define to 1 if you have the <memory.h> header file. */ #undef HAVE_MEMORY_H diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/snapper-0.3.2/configure.ac new/snapper-0.3.3/configure.ac --- old/snapper-0.3.2/configure.ac 2016-03-30 17:52:15.000000000 +0200 +++ new/snapper-0.3.3/configure.ac 2016-08-02 13:30:41.000000000 +0200 @@ -134,6 +134,16 @@ [with_pam=$enableval],[with_pam=yes]) AM_CONDITIONAL(HAVE_PAM, [test "x$with_pam" = "xyes"]) +AC_ARG_ENABLE([selinux], AC_HELP_STRING([--enable-selinux],[Enable support for SELinux LSM]), + [with_selinux=$enableval],[with_selinux=no]) +AM_CONDITIONAL(ENABLE_SELINUX, [test "x$enable_selinux" = "xyes"]) + +if test "x$with_selinux" = "xyes"; then + AC_DEFINE(ENABLE_SELINUX, 1, [Enable SELinux support]) + AC_CHECK_HEADER(selinux/selinux.h,[],[AC_MSG_ERROR([Cannot find libselinux headers. Please install libselinux-devel])]) + AC_CHECK_LIB(selinux, selinux_snapperd_contexts_path, [], [AC_MSG_ERROR([selinux library does not provide selinux_snapperd_contexts_path symbol])]) +fi + PKG_CHECK_MODULES(DBUS, dbus-1) AC_CHECK_HEADER(acl/libacl.h,[],[AC_MSG_ERROR([Cannout find libacl headers. Please install libacl-devel])]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/snapper-0.3.2/examples/c++-lib/Makefile.am new/snapper-0.3.3/examples/c++-lib/Makefile.am --- old/snapper-0.3.2/examples/c++-lib/Makefile.am 2016-01-18 11:03:24.000000000 +0100 +++ new/snapper-0.3.3/examples/c++-lib/Makefile.am 2016-08-02 13:30:41.000000000 +0200 @@ -5,6 +5,7 @@ AM_CPPFLAGS = -I$(top_srcdir) LDADD = ../../snapper/libsnapper.la +AM_LDFLAGS = -lboost_system noinst_PROGRAMS = List ListAll Create CmpDirs CreateNumber CreateTimeline diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/snapper-0.3.2/po/ar.po new/snapper-0.3.3/po/ar.po --- old/snapper-0.3.2/po/ar.po 2016-01-18 11:03:24.000000000 +0100 +++ new/snapper-0.3.3/po/ar.po 2016-05-17 11:37:12.000000000 +0200 @@ -7,15 +7,17 @@ "Project-Id-Version: @PACKAGE@\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-10-09 16:24+0200\n" -"PO-Revision-Date: 2014-09-04 09:00+0300\n" -"Last-Translator: malhargan <malh...@gmail.com>\n" -"Language-Team: openSUSE\n" +"PO-Revision-Date: 2016-04-28 04:47+0000\n" +"Last-Translator: mohammad alhargan <malh...@gmail.com>\n" +"Language-Team: Arabic <http://l10n.opensuse.org/projects/snapper/master/ar/>" +"\n" "Language: ar\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n" -"X-Generator: Virtaal 0.7.1\n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " +"&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n" +"X-Generator: Weblate 2.5\n" #: ../client/snapper.cc:457 msgid "\t--all-configs, -a\t\tList snapshots from all accessible configs." @@ -480,12 +482,12 @@ msgstr "فشل حذف اللقطة." #: ../client/commands.cc:274 -#, fuzzy, c-format +#, c-format msgid "Deleting snapshot from %s:" msgid_plural "Deleting snapshots from %s:" -msgstr[0] "حذف اللقطة من %s:" -msgstr[1] "حذف اللقطات من %s:" -msgstr[2] "حذف اللقطات من %s:" +msgstr[0] "حذف اللقطة من %s 1:" +msgstr[1] "حذف اللقطات من %s 2:" +msgstr[2] "حذف لقطتان من %s:" msgstr[3] "حذف اللقطات من %s:" msgstr[4] "حذف اللقطات من %s:" msgstr[5] "حذف اللقطات من %s:" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/snapper-0.3.2/po/ca.po new/snapper-0.3.3/po/ca.po --- old/snapper-0.3.2/po/ca.po 2016-01-18 11:03:24.000000000 +0100 +++ new/snapper-0.3.3/po/ca.po 2016-07-01 11:43:31.000000000 +0200 @@ -3,16 +3,16 @@ "Project-Id-Version: @PACKAGE@\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-10-09 16:24+0200\n" -"PO-Revision-Date: 2015-10-15 16:11+0200\n" +"PO-Revision-Date: 2016-06-04 11:53+0000\n" "Last-Translator: David Medina <medi...@gmail.com>\n" -"Language-Team: Catalan <http://10n.opensuse.org/projects/snapper/master/ca/>" -"\n" +"Language-Team: Catalan " +"<https://l10n.opensuse.org/projects/snapper/master/ca/>\n" "Language: ca\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 2.3\n" +"X-Generator: Weblate 2.6\n" #: ../client/snapper.cc:457 msgid "\t--all-configs, -a\t\tList snapshots from all accessible configs." @@ -30,7 +30,7 @@ #: ../client/snapper.cc:700 msgid "\t--command <command>\tRun command and create pre and post snapshots." -msgstr "\t--command <command>\tExecuta l'ordre i crea pre i post instantànies." +msgstr "\t--command <command>\tExecuta l'ordre i crea instantànies pre i post." #: ../client/snapper.cc:1583 msgid "\t--config, -c <name>\t\tSet name of config to use." @@ -608,7 +608,7 @@ #: ../client/snapper.cc:778 msgid "Missing or invalid pre-number." -msgstr "Pre-number inexistent o no vàlid." +msgstr "Número Pre inexistent o no vàlid." #: ../client/snapper.cc:1713 msgid "No command provided." @@ -630,7 +630,7 @@ #: ../client/snapper.cc:630 msgid "Post Date" -msgstr "Post Data" +msgstr "Data Post" #: ../client/snapper.cc:532 ../client/snapper.cc:627 msgid "Pre #" @@ -638,7 +638,7 @@ #: ../client/snapper.cc:629 msgid "Pre Date" -msgstr "Pre Data" +msgstr "Data Pre" #: ../client/misc.cc:89 ../client/snapper.cc:1051 ../client/snapper.cc:1824 msgid "See 'man snapper' for further instructions." diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/snapper-0.3.2/po/es.po new/snapper-0.3.3/po/es.po --- old/snapper-0.3.2/po/es.po 2016-01-18 11:03:24.000000000 +0100 +++ new/snapper-0.3.3/po/es.po 2016-05-17 11:37:12.000000000 +0200 @@ -4,15 +4,16 @@ "Project-Id-Version: snapper\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-10-09 16:24+0200\n" -"PO-Revision-Date: 2013-10-03 09:30-0300\n" -"Last-Translator: Sergio Gabriel Teves <gabr...@opensuse.org>\n" -"Language-Team: Spanish <opensuse-translation...@opensuse.org>\n" +"PO-Revision-Date: 2016-04-20 14:30+0000\n" +"Last-Translator: Victor hck <correo...@gmail.com>\n" +"Language-Team: Spanish <http://l10n.opensuse.org/projects/snapper/master/es/>" +"\n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 1.5.5\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 2.5\n" #: ../client/snapper.cc:457 msgid "\t--all-configs, -a\t\tList snapshots from all accessible configs." @@ -138,7 +139,7 @@ #: ../client/snapper.cc:1586 msgid "\t--version\t\t\tPrint version and exit." -msgstr "\t--version\t\t\tMuestra la versión y sale" +msgstr "\t--version\t\t\tMuestra la versión y sale." #: ../client/snapper.cc:1409 msgid "\tsnapper cleanup <cleanup-algorithm>" @@ -215,11 +216,11 @@ #: ../client/snapper.cc:693 msgid " Options for 'create' command:" -msgstr " Opciones para el comando 'create'." +msgstr " Opciones para el comando 'create':" #: ../client/snapper.cc:273 msgid " Options for 'create-config' command:" -msgstr " Opciones para el comando 'create-config'." +msgstr " Opciones para el comando 'create-config':" #: ../client/snapper.cc:883 msgid " Options for 'delete' command:" @@ -227,27 +228,27 @@ #: ../client/snapper.cc:1091 msgid " Options for 'diff' command:" -msgstr " Opciones para el comando 'diff'." +msgstr " Opciones para el comando 'diff':" #: ../client/snapper.cc:455 msgid " Options for 'list' command:" -msgstr " Opciones para el comando 'list'." +msgstr " Opciones para el comando 'list':" #: ../client/snapper.cc:830 msgid " Options for 'modify' command:" -msgstr " Opciones para el comando 'modify'." +msgstr " Opciones para el comando 'modify':" #: ../client/snapper.cc:1300 msgid " Options for 'rollback' command:" -msgstr " Opciones para el comando 'rollback'." +msgstr " Opciones para el comando 'rollback':" #: ../client/snapper.cc:1029 msgid " Options for 'status' command:" -msgstr " Opciones para el comando 'status'." +msgstr " Opciones para el comando 'status':" #: ../client/snapper.cc:1154 msgid " Options for 'undochange' command:" -msgstr " Opciones para el comando 'undochange'." +msgstr " Opciones para el comando 'undochange':" #: ../client/snapper.cc:1408 msgid " Cleanup snapshots:" @@ -559,7 +560,7 @@ #: ../client/snapper.cc:1781 ../client/errors.cc:49 msgid "Invalid configdata." -msgstr "Información de configuración no válida" +msgstr "Información de configuración no válida." # SLE12 #: ../client/snapper.cc:1805 ../client/errors.cc:82 @@ -618,7 +619,7 @@ #: ../client/snapper.cc:784 msgid "Missing command argument." -msgstr "Falta un argumento del comando. " +msgstr "Falta un argumento del comando." #: ../client/misc.cc:88 msgid "Missing delimiter '..' between snapshot numbers." @@ -630,7 +631,7 @@ #: ../client/snapper.cc:1713 msgid "No command provided." -msgstr "Ningún comando especificado" +msgstr "Ningún comando especificado." #: ../client/errors.cc:43 msgid "No permissions." diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/snapper-0.3.2/server/Makefile.am new/snapper-0.3.3/server/Makefile.am --- old/snapper-0.3.2/server/Makefile.am 2016-01-18 11:03:24.000000000 +0100 +++ new/snapper-0.3.3/server/Makefile.am 2016-08-02 13:30:41.000000000 +0200 @@ -14,4 +14,4 @@ Types.cc Types.h snapperd_LDADD = ../snapper/libsnapper.la ../dbus/libdbus.la -lrt - +snapperd_LDFLAGS = -lboost_system -lboost_thread diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/snapper-0.3.2/snapper/Btrfs.cc new/snapper-0.3.3/snapper/Btrfs.cc --- old/snapper-0.3.2/snapper/Btrfs.cc 2016-04-06 17:02:12.000000000 +0200 +++ new/snapper-0.3.3/snapper/Btrfs.cc 2016-08-02 13:30:41.000000000 +0200 @@ -58,6 +58,9 @@ #ifdef ENABLE_ROLLBACK #include "snapper/MntTable.h" #endif +#ifdef ENABLE_SELINUX +#include "snapper/Selinux.h" +#endif namespace snapper @@ -133,6 +136,19 @@ } SFile x(subvolume_dir, ".snapshots"); +#ifdef ENABLE_SELINUX + try + { + SnapperContexts scontexts; + + x.fsetfilecon(scontexts.subvolume_context()); + } + catch (const SelinuxException& e) + { + SN_CAUGHT(e); + // fall through intentional + } +#endif struct stat stat; if (x.stat(&stat, 0) == 0) x.chmod(stat.st_mode & ~0027, 0); @@ -1398,6 +1414,33 @@ #ifdef ENABLE_ROLLBACK + bool + Btrfs::isDefault(unsigned int num) const + { + bool ret = false; + + try + { + SDir subvolume_dir = openSubvolumeDir(); + subvolid_t id = get_default_id(subvolume_dir.fd()); + if (num == 0) + { + ret = get_id(subvolume_dir.fd()) == id; + } + else + { + ret = get_id(openSnapshotDir(num).fd()) == id; + } + } + catch (const runtime_error& e) + { + SN_THROW(IOErrorException(string("get default failed, ") + e.what())); + } + + return ret; + } + + void Btrfs::setDefault(unsigned int num) const { @@ -1424,13 +1467,50 @@ } } + + bool + Btrfs::isActive(unsigned int num) const + { + bool ret = false; + + try + { + if (num == 0) + SN_THROW(IllegalSnapshotException()); + + SDir snapshot_dir = openSnapshotDir(num); + SDir subvolume_dir = openSubvolumeDir(); + ret = get_id(snapshot_dir.fd()) == get_id(subvolume_dir.fd()); + } + catch (const runtime_error& e) + { + SN_THROW(IOErrorException(string("get active failed, ") + e.what())); + } + + return ret; + } + #else + bool + Btrfs::isDefault(unsigned int num) const + { + throw std::logic_error("not implemented"); + } + + void Btrfs::setDefault(unsigned int num) const { throw std::logic_error("not implemented"); } + + + bool + Btrfs::isActive(unsigned int num) const + { + throw std::logic_error("not implemented"); + } #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/snapper-0.3.2/snapper/Btrfs.h new/snapper-0.3.3/snapper/Btrfs.h --- old/snapper-0.3.2/snapper/Btrfs.h 2016-03-30 17:52:15.000000000 +0200 +++ new/snapper-0.3.3/snapper/Btrfs.h 2016-08-02 13:30:41.000000000 +0200 @@ -75,8 +75,11 @@ virtual void cmpDirs(const SDir& dir1, const SDir& dir2, cmpdirs_cb_t cb) const; + virtual bool isDefault(unsigned int num) const; virtual void setDefault(unsigned int num) const; + virtual bool isActive(unsigned int num) const; + virtual void sync() const; virtual qgroup_t getQGroup() const { return qgroup; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/snapper-0.3.2/snapper/BtrfsUtils.cc new/snapper-0.3.3/snapper/BtrfsUtils.cc --- old/snapper-0.3.2/snapper/BtrfsUtils.cc 2016-04-08 10:12:17.000000000 +0200 +++ new/snapper-0.3.3/snapper/BtrfsUtils.cc 2016-08-02 13:30:41.000000000 +0200 @@ -333,8 +333,6 @@ } } -#endif - qgroup_t calc_qgroup(uint64_t level, subvolid_t id) @@ -390,8 +388,6 @@ } -#ifdef ENABLE_BTRFS_QUOTA - void qgroup_create(int fd, qgroup_t qgroup) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/snapper-0.3.2/snapper/FileUtils.cc new/snapper-0.3.3/snapper/FileUtils.cc --- old/snapper-0.3.2/snapper/FileUtils.cc 2016-03-30 17:52:15.000000000 +0200 +++ new/snapper-0.3.3/snapper/FileUtils.cc 2016-08-02 13:30:41.000000000 +0200 @@ -34,12 +34,18 @@ #include <errno.h> #include <stdlib.h> #include <assert.h> +#ifdef ENABLE_SELINUX +#include <selinux/selinux.h> +#endif #include <algorithm> #include "snapper/FileUtils.h" #include "snapper/AppUtil.h" #include "snapper/Log.h" #include "snapper/Exception.h" +#ifdef ENABLE_SELINUX +#include "snapper/Selinux.h" +#endif namespace snapper @@ -567,6 +573,171 @@ } + bool + SDir::fsetfilecon(const string& name, char* con) const + { + assert(name.find('/') == string::npos); + assert(name != ".."); + + bool retval = true; + +#ifdef ENABLE_SELINUX + if (_is_selinux_enabled()) + { + char *src_con = NULL; + + int fd = ::openat(dirfd, name.c_str(), O_RDONLY | O_NOFOLLOW | O_NOATIME + | O_NONBLOCK | O_CLOEXEC); + if (fd < 0) + { + // symlink, detached dev node? + if (errno != ELOOP && errno != ENXIO && errno != EWOULDBLOCK) + { + y2err("open failed errno: " << errno << " (" << stringerror(errno) << ")"); + return false; + } + + boost::lock_guard<boost::mutex> lock(cwd_mutex); + + if (fchdir(dirfd) < 0) + { + y2err("fchdir failed errno: " << errno << " (" << stringerror(errno) << ")"); + return false; + } + + if (lgetfilecon(name.c_str(), &src_con) < 0 || selinux_file_context_cmp(src_con, con)) + { + y2deb("setting new SELinux context on " << fullname() << "/" << name); + if (lsetfilecon(name.c_str(), con)) + { + y2err("lsetfilecon on " << fullname() << "/" << name << " failed errno: " << errno << " (" << stringerror(errno) << ")"); + retval = false; + } + } + + chdir("/"); + + } + else + { + if (fgetfilecon(fd, &src_con) < 0 || selinux_file_context_cmp(src_con, con)) + { + y2deb("setting new SELinux context on " << fullname() << "/" << name); + if (::fsetfilecon(fd, con)) + { + y2err("fsetfilecon on " << fullname() << "/" << name << " failed errno: " << errno << " (" << stringerror(errno) << ")"); + retval = false; + } + } + + ::close(fd); + } + + freecon(src_con); + } +#endif + return retval; + } + + + bool + SDir::restorecon(const string& name, SelinuxLabelHandle* sh) const + { + assert(name.find('/') == string::npos); + assert(name != ".."); + + bool retval = true; +#ifdef ENABLE_SELINUX + if (_is_selinux_enabled()) + { + assert(sh); + + struct stat buf; + if (stat(name, &buf, AT_SYMLINK_NOFOLLOW)) + { + y2err("Failed to stat " << fullname() << "/" << name); + return false; + } + + char* con = sh->selabel_lookup(fullname() + "/" + name, buf.st_mode); + if (con) + { + retval = fsetfilecon(name, con); + } + else + { + retval = false; + } + + freecon(con); + } +#endif + return retval; + } + + + bool + SDir::fsetfilecon(char* con) const + { + bool retval = true; + +#ifdef ENABLE_SELINUX + if (_is_selinux_enabled()) + { + char* src_con = NULL; + + if (fgetfilecon(fd(), &src_con) < 0 || selinux_file_context_cmp(src_con, con)) + { + y2deb("setting new SELinux context on " << fullname()); + if (::fsetfilecon(fd(), con)) + { + y2err("fsetfilecon on " << fullname() << " failed errno: " << errno << " (" << stringerror(errno) << ")"); + retval = false; + } + } + + freecon(src_con); + } +#endif + return retval; + } + + + bool + SDir::restorecon(SelinuxLabelHandle* sh) const + { + bool retval = true; +#ifdef ENABLE_SELINUX + if (_is_selinux_enabled()) + { + assert(sh); + + struct stat buf; + + if (stat(&buf)) + { + y2err("Failed to stat " << fullname()); + return false; + } + + char* con = sh->selabel_lookup(fullname(), buf.st_mode); + if (con) + { + retval = fsetfilecon(con); + } + else + { + y2war("can't get proper label for path:" << fullname()); + retval = false; + } + + freecon(con); + } +#endif + return retval; + } + + SFile::SFile(const SDir& dir, const string& name) : dir(dir), name(name) { @@ -631,6 +802,19 @@ } + void + SFile::fsetfilecon(char* con) const + { + dir.fsetfilecon(name, con); + } + + void + SFile::restorecon(SelinuxLabelHandle* sh) const + { + dir.restorecon(name, sh); + } + + TmpDir::TmpDir(SDir& base_dir, const string& name_template) : base_dir(base_dir), name(name_template) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/snapper-0.3.2/snapper/FileUtils.h new/snapper-0.3.3/snapper/FileUtils.h --- old/snapper-0.3.2/snapper/FileUtils.h 2016-01-18 11:03:24.000000000 +0100 +++ new/snapper-0.3.3/snapper/FileUtils.h 2016-08-02 13:30:41.000000000 +0200 @@ -42,6 +42,7 @@ XA_SUPPORTED }; + class SelinuxLabelHandle; /* * The member functions of SDir and SFile are secure (avoid race @@ -101,6 +102,11 @@ const string& mount_data) const; bool umount(const string& mount_point) const; + bool fsetfilecon(const string& name, char* con) const; + bool fsetfilecon(char* con) const; + bool restorecon(SelinuxLabelHandle* sh) const; + bool restorecon(const string& name, SelinuxLabelHandle* sh) const; + private: XaAttrsStatus xastatus; @@ -134,6 +140,9 @@ ssize_t listxattr(char* list, size_t size) const; ssize_t getxattr(const char* name, void* value, size_t size) const; + void fsetfilecon(char* con) const; + void restorecon(SelinuxLabelHandle* sh) const; + private: const SDir& dir; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/snapper-0.3.2/snapper/Filesystem.cc new/snapper-0.3.3/snapper/Filesystem.cc --- old/snapper-0.3.2/snapper/Filesystem.cc 2016-03-30 17:52:15.000000000 +0200 +++ new/snapper-0.3.3/snapper/Filesystem.cc 2016-08-02 13:30:41.000000000 +0200 @@ -170,11 +170,25 @@ } + bool + Filesystem::isDefault(unsigned int num) const + { + throw std::logic_error("not implemented"); + } + + void Filesystem::setDefault(unsigned int num) const { throw std::logic_error("not implemented"); } + + + bool + Filesystem::isActive(unsigned int num) const + { + throw std::logic_error("not implemented"); + } void diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/snapper-0.3.2/snapper/Filesystem.h new/snapper-0.3.3/snapper/Filesystem.h --- old/snapper-0.3.2/snapper/Filesystem.h 2016-03-30 17:52:15.000000000 +0200 +++ new/snapper-0.3.3/snapper/Filesystem.h 2016-08-02 13:30:41.000000000 +0200 @@ -82,8 +82,11 @@ virtual void cmpDirs(const SDir& dir1, const SDir& dir2, cmpdirs_cb_t cb) const; + virtual bool isDefault(unsigned int num) const; virtual void setDefault(unsigned int num) const; + virtual bool isActive(unsigned int num) const; + virtual void sync() const; protected: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/snapper-0.3.2/snapper/Lvm.cc new/snapper-0.3.3/snapper/Lvm.cc --- old/snapper-0.3.2/snapper/Lvm.cc 2016-03-30 17:52:15.000000000 +0200 +++ new/snapper-0.3.3/snapper/Lvm.cc 2016-08-02 13:30:41.000000000 +0200 @@ -41,6 +41,9 @@ #include "snapper/SnapperDefines.h" #include "snapper/Regex.h" #include "snapper/LvmCache.h" +#ifdef ENABLE_SELINUX +#include "snapper/Selinux.h" +#endif namespace snapper @@ -60,7 +63,7 @@ Lvm::Lvm(const string& subvolume, const string& root_prefix, const string& mount_type) : Filesystem(subvolume, root_prefix), mount_type(mount_type), caps(LvmCapabilities::get_lvm_capabilities()), - cache(LvmCache::get_lvm_cache()) + cache(LvmCache::get_lvm_cache()), sh(NULL) { if (access(LVCREATEBIN, X_OK) != 0) { @@ -98,20 +101,87 @@ mount_options.push_back("nouuid"); mount_options.push_back("norecovery"); } + +#ifdef ENABLE_SELINUX + try + { + sh = SelinuxLabelHandle::get_selinux_handle(); + } + catch (const SelinuxException& e) + { + SN_RETHROW(e); + } +#endif + + } + + + void + Lvm::createLvmConfig(const SDir& subvolume_dir, int mode) const + { + int r1 = subvolume_dir.mkdir(".snapshots", mode); + if (r1 != 0 && errno != EEXIST) + { + y2err("mkdir failed errno:" << errno << " (" << strerror(errno) << ")"); + SN_THROW(CreateConfigFailedException("mkdir failed")); + } } void Lvm::createConfig() const { + int mode = 0750; SDir subvolume_dir = openSubvolumeDir(); - int r1 = subvolume_dir.mkdir(".snapshots", 0750); - if (r1 != 0 && errno != EEXIST) +#ifdef ENABLE_SELINUX + if (_is_selinux_enabled()) { - y2err("mkdir failed errno:" << errno << " (" << strerror(errno) << ")"); - throw CreateConfigFailedException("mkdir failed"); + assert(sh); + + char* con = NULL; + + try + { + string path(subvolume_dir.fullname() + "/.snapshots"); + + con = sh->selabel_lookup(path, mode); + if (con) + { + // race free mkdir with correct Selinux context preset + DefaultSelinuxFileContext defcon(con); + createLvmConfig(subvolume_dir, mode); + } + else + { + y2deb("Selinux policy does not define context for path: " << path); + + // race free mkdir with correct Selinux context preset even in case + // Selinux policy does not define context for the path + SnapperContexts scontexts; + DefaultSelinuxFileContext defcon(scontexts.subvolume_context()); + + createLvmConfig(subvolume_dir, mode); + } + + freecon(con); + + return; + } + catch (const SelinuxException& e) + { + SN_CAUGHT(e); + freecon(con); + // fall through intentional + } + catch (const CreateConfigFailedException& e) + { + freecon(con); + SN_RETHROW(e); + } } +#endif + createLvmConfig(subvolume_dir, mode); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/snapper-0.3.2/snapper/Lvm.h new/snapper-0.3.3/snapper/Lvm.h --- old/snapper-0.3.2/snapper/Lvm.h 2016-03-30 17:52:15.000000000 +0200 +++ new/snapper-0.3.3/snapper/Lvm.h 2016-08-02 13:30:41.000000000 +0200 @@ -74,6 +74,7 @@ bool time_support; }; + class SelinuxLabelHandle; class Lvm : public Filesystem { @@ -114,11 +115,13 @@ const string mount_type; const LvmCapabilities* caps; LvmCache* cache; + SelinuxLabelHandle* sh; bool detectThinVolumeNames(const MtabData& mtab_data); void activateSnapshot(const string& vg_name, const string& lv_name) const; void deactivateSnapshot(const string& vg_name, const string& lv_name) const; bool detectInactiveSnapshot(const string& vg_name, const string& lv_name) const; + void createLvmConfig(const SDir& subvolume_dir, int mode) const; string getDevice(unsigned int num) const; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/snapper-0.3.2/snapper/Makefile.am new/snapper-0.3.3/snapper/Makefile.am --- old/snapper-0.3.2/snapper/Makefile.am 2016-01-18 11:03:24.000000000 +0100 +++ new/snapper-0.3.3/snapper/Makefile.am 2016-08-02 13:30:41.000000000 +0200 @@ -56,6 +56,11 @@ MntTable.cc MntTable.h endif +if ENABLE_SELINUX +libsnapper_la_SOURCES += \ + Selinux.cc Selinux.h +endif + libsnapper_la_LDFLAGS = -version-info @LIBVERSION_INFO@ libsnapper_la_LIBADD = -lboost_thread -lboost_system -lxml2 -lacl -lz -lm if ENABLE_ROLLBACK diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/snapper-0.3.2/snapper/Selinux.cc new/snapper-0.3.3/snapper/Selinux.cc --- old/snapper-0.3.2/snapper/Selinux.cc 1970-01-01 01:00:00.000000000 +0100 +++ new/snapper-0.3.3/snapper/Selinux.cc 2016-08-02 13:30:41.000000000 +0200 @@ -0,0 +1,156 @@ +/* + * Copyright (c) [2016] Red Hat, Inc. + * + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, contact Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, you may + * find current contact information at www.novell.com. + */ + +#include <cerrno> +#include <map> + +#include <boost/algorithm/string.hpp> + +#include "snapper/AppUtil.h" +#include "snapper/AsciiFile.h" +#include "snapper/Log.h" +#include "snapper/Selinux.h" + +namespace snapper +{ + + SnapperContexts::SnapperContexts() + : subvolume_ctx(NULL) + { + std::map<string,string> snapperd_contexts; + + try + { + AsciiFileReader asciifile(selinux_snapperd_contexts_path()); + + string line; + while (asciifile.getline(line)) + { + // commented line + if (line[0] == '#') + continue; + + // do not parse lines w/o '=' symbol + string::size_type pos = line.find('='); + if (pos == string::npos) + continue; + + if (!snapperd_contexts.insert(make_pair(boost::trim_copy(line.substr(0, pos)), boost::trim_copy(line.substr(pos + 1)))).second) + { + SN_THROW(SelinuxException("Duplicate key in contexts file")); + } + } + } + catch (const FileNotFoundException& e) + { + SN_CAUGHT(e); + SN_THROW(SelinuxException("Failed to parse contexts file")); + } + + std::map<string,string>::const_iterator cit = snapperd_contexts.find(selinux_snapperd_data); + if (cit == snapperd_contexts.end()) + { + SN_THROW(SelinuxException("Snapperd data context not found")); + } + + subvolume_ctx = context_new(cit->second.c_str()); + if (!subvolume_ctx) + { + SN_THROW(SelinuxException()); + } + } + + + DefaultSelinuxFileContext::DefaultSelinuxFileContext(char* context) + { + if (setfscreatecon(context) < 0) + { + SN_THROW(SelinuxException(string("setfscreatecon(") + context + ") failed")); + } + } + + + DefaultSelinuxFileContext::~DefaultSelinuxFileContext() + { + if (setfscreatecon(NULL)) + y2err("Failed to reset default file system objects context"); + } + + + SelinuxLabelHandle::SelinuxLabelHandle() + : handle(selabel_open(SELABEL_CTX_FILE, NULL, 0)) + { + if (!handle) + { + SN_THROW(SelinuxException("Failed to open SELinux labeling handle: " + stringerror(errno))); + } + } + + + char* + SelinuxLabelHandle::selabel_lookup(const string& path, int mode) + { + char *con; + + if (!::selabel_lookup(handle, &con, path.c_str(), mode)) + { + y2deb("found label for path " << path << ": " << con); + return con; + } + else + { + if (errno == ENOENT) + y2deb("Selinux context not defined for path " << path); + + return NULL; + } + } + + + bool + _is_selinux_enabled() + { + static bool selinux_enabled, selinux_checked = false; + + if (!selinux_checked) + { + selinux_enabled = (is_selinux_enabled() == 1); // may return -1 on error + selinux_checked = true; + y2mil("Selinux support " << (selinux_enabled ? "en" : "dis") << "abled"); + } + + return selinux_enabled; + } + + + SelinuxLabelHandle* + SelinuxLabelHandle::get_selinux_handle() + { + if (_is_selinux_enabled()) + { + static SelinuxLabelHandle handle; + return &handle; + } + + return NULL; + } + +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/snapper-0.3.2/snapper/Selinux.h new/snapper-0.3.3/snapper/Selinux.h --- old/snapper-0.3.2/snapper/Selinux.h 1970-01-01 01:00:00.000000000 +0100 +++ new/snapper-0.3.3/snapper/Selinux.h 2016-08-02 13:30:41.000000000 +0200 @@ -0,0 +1,84 @@ +/* + * Copyright (c) [2016] Red Hat, Inc. + * + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, contact Novell, Inc. + * + * To contact Novell about this file by physical or electronic mail, you may + * find current contact information at www.novell.com. + */ + + +#ifndef SNAPPER_SELINUX_H +#define SNAPPER_SELINUX_H + +#include <string> +#include <selinux/context.h> +#include <selinux/label.h> +#include <selinux/selinux.h> + +#include <boost/noncopyable.hpp> + +#include "snapper/Exception.h" + + +namespace snapper { + + struct SelinuxException : public Exception + { + explicit SelinuxException() : Exception("SELinux error") {} + explicit SelinuxException(const std::string& msg) : Exception(msg) {} + }; + + using std::string; + + const static string selinux_snapperd_data = "snapperd_data"; + + bool _is_selinux_enabled(); + + class SnapperContexts + { + public: + char* subvolume_context() const { return context_str(subvolume_ctx); } + SnapperContexts(); + ~SnapperContexts() { context_free(subvolume_ctx); } + private: + context_t subvolume_ctx; + }; + + class DefaultSelinuxFileContext : private boost::noncopyable + { + public: + DefaultSelinuxFileContext(char* context); + ~DefaultSelinuxFileContext(); + }; + + + class SelinuxLabelHandle : public boost::noncopyable + { + public: + static SelinuxLabelHandle* get_selinux_handle(); + + char* selabel_lookup(const string& path, int mode); + + ~SelinuxLabelHandle() { selabel_close(handle); } + private: + SelinuxLabelHandle(); + + struct selabel_handle* handle; + }; + +} + +#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/snapper-0.3.2/snapper/Snapper.cc new/snapper-0.3.3/snapper/Snapper.cc --- old/snapper-0.3.2/snapper/Snapper.cc 2016-04-06 17:02:12.000000000 +0200 +++ new/snapper-0.3.3/snapper/Snapper.cc 2016-08-02 13:30:41.000000000 +0200 @@ -48,6 +48,10 @@ #include "snapper/Hooks.h" #include "snapper/Btrfs.h" #include "snapper/BtrfsUtils.h" +#ifdef ENABLE_SELINUX +#include "snapper/Selinux.h" +#include "snapper/Regex.h" +#endif namespace snapper @@ -82,12 +86,23 @@ Snapper::Snapper(const string& config_name, const string& root_prefix, bool disable_filters) - : config_info(NULL), filesystem(NULL), snapshots(this) + : config_info(NULL), filesystem(NULL), snapshots(this), selabel_handle(NULL) { y2mil("Snapper constructor"); y2mil("libsnapper version " VERSION); y2mil("config_name:" << config_name << " disable_filters:" << disable_filters); +#ifdef ENABLE_SELINUX + try + { + selabel_handle = SelinuxLabelHandle::get_selinux_handle(); + } + catch (const SelinuxException& e) + { + SN_RETHROW(e); + } +#endif + try { config_info = new ConfigInfo(config_name, root_prefix); @@ -99,6 +114,9 @@ filesystem = Filesystem::create(*config_info, root_prefix); + // With btrfs backend, it's useless try syncing snapshot RO subvolumes + syncSelinuxContexts(filesystem->fstype() == "btrfs"); + bool sync_acl; if (config_info->getValue(KEY_SYNC_ACL, sync_acl) && sync_acl == true) syncAcl(); @@ -762,6 +780,79 @@ } + void + Snapper::syncSelinuxContexts(bool skip_snapshot_dir) const + { +#ifdef ENABLE_SELINUX + try + { + SDir subvol_dir = openSubvolumeDir(); + SDir infos_dir(subvol_dir, ".snapshots"); + + if (infos_dir.restorecon(selabel_handle)) + { + syncSelinuxContextsInInfosDir(skip_snapshot_dir); + } + else + { + SnapperContexts scons; + + if (infos_dir.fsetfilecon(scons.subvolume_context())) + syncSelinuxContextsInInfosDir(skip_snapshot_dir); + } + } + catch (const SelinuxException& e) + { + SN_CAUGHT(e); + // fall through intentional + } +#endif + } + + + void + Snapper::syncSelinuxContextsInInfosDir(bool skip_snapshot_dir) const + { +#ifdef ENABLE_SELINUX + Regex rx("^[0-9]+$"); + Regex rx_filelist("^filelist-[0-9]+.txt$"); + + y2deb("Syncing Selinux contexts in infos dir"); + + SDir infos_dir = openInfosDir(); + + vector<string> infos = infos_dir.entries(); + for (vector<string>::const_iterator it1 = infos.begin(); it1 != infos.end(); ++it1) + { + if (!rx.match(*it1)) + continue; + + SDir info_dir(infos_dir, *it1); + info_dir.restorecon(selabel_handle); + + SFile info(info_dir, "info.xml"); + info.restorecon(selabel_handle); + + if (!skip_snapshot_dir) + { + SFile snapshot_dir(info_dir, "snapshot"); + snapshot_dir.restorecon(selabel_handle); + } + + vector<string> info_content = info_dir.entries(); + for (vector<string>::const_iterator it2 = info_content.begin(); it2 != info_content.end(); ++it2) + { + if (!rx_filelist.match(*it2)) + continue; + + SFile fl(info_dir, *it2); + fl.restorecon(selabel_handle); + } + } +#endif + } + + static bool is_subpath(const string& a, const string& b) { @@ -860,7 +951,12 @@ #ifndef ENABLE_BTRFS_QUOTA "no-" #endif - "btrfs-quota" + "btrfs-quota," + +#ifndef ENABLE_SELINUX + "no-" +#endif + "selinux" ; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/snapper-0.3.2/snapper/Snapper.h new/snapper-0.3.3/snapper/Snapper.h --- old/snapper-0.3.2/snapper/Snapper.h 2016-03-31 17:47:10.000000000 +0200 +++ new/snapper-0.3.3/snapper/Snapper.h 2016-08-02 13:30:41.000000000 +0200 @@ -39,6 +39,7 @@ class Filesystem; class SDir; + class SelinuxLabelHandle; class ConfigInfo : public SysconfigFile @@ -176,6 +177,10 @@ void syncAcl(const vector<uid_t>& uids, const vector<gid_t>& gids) const; + void syncSelinuxContexts(bool skip_snapshot_dir) const; + void syncSelinuxContextsInInfosDir(bool skip_snapshot_dir) const; + void syncInfoDir(SDir& dir) const; + ConfigInfo* config_info; Filesystem* filesystem; @@ -184,6 +189,8 @@ Snapshots snapshots; + SelinuxLabelHandle* selabel_handle; + }; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/snapper-0.3.2/snapper/Snapshot.cc new/snapper-0.3.3/snapper/Snapshot.cc --- old/snapper-0.3.2/snapper/Snapshot.cc 2016-03-30 17:52:15.000000000 +0200 +++ new/snapper-0.3.3/snapper/Snapshot.cc 2016-08-02 13:30:41.000000000 +0200 @@ -133,6 +133,27 @@ } + bool + Snapshot::isDefault() const + { + return snapper->getFilesystem()->isDefault(num); + } + + + void + Snapshot::setDefault() const + { + return snapper->getFilesystem()->setDefault(num); + } + + + bool + Snapshot::isActive() const + { + return !isCurrent() && snapper->getFilesystem()->isActive(num); + } + + void Snapshots::read() { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/snapper-0.3.2/snapper/Snapshot.h new/snapper-0.3.3/snapper/Snapshot.h --- old/snapper-0.3.2/snapper/Snapshot.h 2016-01-18 11:03:24.000000000 +0100 +++ new/snapper-0.3.3/snapper/Snapshot.h 2016-08-02 13:30:41.000000000 +0200 @@ -1,5 +1,6 @@ /* * Copyright (c) [2011-2015] Novell, Inc. + * Copyright (c) 2016 SUSE LLC * * All Rights Reserved. * @@ -104,6 +105,21 @@ bool isReadOnly() const; + /** + * Determine iff snapshot is default (will be activated on next boot time). + */ + bool isDefault() const; + + /** + * Change default snapshot (will be activated on next boot time). + */ + void setDefault() const; + + /** + * Determine iff snapshot is active (activated on last boot time). + */ + bool isActive() const; + void mountFilesystemSnapshot(bool user_request) const; void umountFilesystemSnapshot(bool user_request) const; void handleUmountFilesystemSnapshot() const; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/snapper-0.3.2/test-driver new/snapper-0.3.3/test-driver --- old/snapper-0.3.2/test-driver 2016-04-19 14:03:13.000000000 +0200 +++ new/snapper-0.3.3/test-driver 2016-08-02 13:35:21.000000000 +0200 @@ -56,21 +56,26 @@ expect_failure=no color_tests=no enable_hard_errors=yes -while test $# -gt 0; do - case $1 in +while test $# -gt 1; do + arg=${1%=*} + val=${1#*=} + if [ $arg == $val ]; then + val=$2 + shift + fi + case $arg in --help) print_usage; exit $?;; --version) echo "test-driver $scriptversion"; exit $?;; - --test-name) test_name=$2; shift;; - --log-file) log_file=$2; shift;; - --trs-file) trs_file=$2; shift;; - --color-tests) color_tests=$2; shift;; - --expect-failure) expect_failure=$2; shift;; - --enable-hard-errors) enable_hard_errors=$2; shift;; - --) shift; break;; + --test-name) test_name=$val;; + --log-file) log_file=$val;; + --trs-file) trs_file=$val;; + --color-tests) color_tests=$val;; + --expect-failure) expect_failure=$val;; + --enable-hard-errors) enable_hard_errors=$val;; + --) break;; -*) usage_error "invalid option: '$1'";; - *) break;; esac - shift + [[ $arg != $val ]] && shift done missing_opts= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/snapper-0.3.2/testsuite/Makefile.am new/snapper-0.3.3/testsuite/Makefile.am --- old/snapper-0.3.2/testsuite/Makefile.am 2016-03-29 18:02:14.000000000 +0200 +++ new/snapper-0.3.3/testsuite/Makefile.am 2016-08-02 13:30:41.000000000 +0200 @@ -7,7 +7,11 @@ LDADD = ../snapper/libsnapper.la ../dbus/libdbus.la -lboost_unit_test_framework check_PROGRAMS = sysconfig-get1.test dirname1.test basename1.test \ - equal-date.test dbus-escape.test cmp-lt.test qgroup1.test + equal-date.test dbus-escape.test cmp-lt.test + +if ENABLE_BTRFS_QUOTA +check_PROGRAMS += qgroup1.test +endif TESTS = $(check_PROGRAMS) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/snapper-0.3.2/testsuite-cmp/Makefile.am new/snapper-0.3.3/testsuite-cmp/Makefile.am --- old/snapper-0.3.2/testsuite-cmp/Makefile.am 2016-01-18 11:03:24.000000000 +0100 +++ new/snapper-0.3.3/testsuite-cmp/Makefile.am 2016-08-02 13:30:41.000000000 +0200 @@ -3,6 +3,7 @@ # AM_CPPFLAGS = -I$(top_srcdir) +AM_LDFLAGS = -lboost_system LDADD = ../snapper/libsnapper.la