]> git.ipfire.org Git - thirdparty/snapper.git/commitdiff
Snapper: sync selinux contexts on all snapper metadata
authorOndrej Kozina <okozina@redhat.com>
Mon, 11 Apr 2016 15:21:49 +0000 (17:21 +0200)
committerOndrej Kozina <okozina@redhat.com>
Mon, 11 Apr 2016 15:21:49 +0000 (17:21 +0200)
snapper/Snapper.cc
snapper/Snapper.h

index b29edf7e0c3bbcb4cc1f830522d0ca26a4e2f298..b2e0eff002f1bcf0ede2abcbcc3f7519483813eb 100644 (file)
 #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 @@ namespace snapper
 
 
     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,8 @@ namespace snapper
 
        filesystem = Filesystem::create(*config_info, root_prefix);
 
+       syncSelinuxContexts();
+
        bool sync_acl;
        if (config_info->getValue(KEY_SYNC_ACL, sync_acl) && sync_acl == true)
            syncAcl();
@@ -762,6 +779,76 @@ namespace snapper
     }
 
 
+    void
+    Snapper::syncSelinuxContexts() const
+    {
+#ifdef ENABLE_SELINUX
+       try
+       {
+           SDir subvol_dir = openSubvolumeDir();
+           SDir infos_dir(subvol_dir, ".snapshots");
+
+           if (infos_dir.restorecon(selabel_handle))
+           {
+               syncSelinuxContextsInInfosDir();
+           }
+           else
+           {
+               SnapperContexts scons;
+
+               if (infos_dir.fsetfilecon(scons.subvolume_context()))
+                   syncSelinuxContextsInInfosDir();
+           }
+       }
+       catch (const SelinuxException& e)
+       {
+           SN_CAUGHT(e);
+           // fall through intentional
+       }
+#endif
+    }
+
+
+    void
+    Snapper::syncSelinuxContextsInInfosDir() 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);
+
+           SFile snapshot_dir(info_dir, "snapshot");
+           snapshot_dir.restorecon(selabel_handle); // this usually fails w/ btrfs backend (it's RO)
+
+           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 +947,12 @@ namespace snapper
 #ifndef ENABLE_BTRFS_QUOTA
            "no-"
 #endif
-           "btrfs-quota"
+           "btrfs-quota,"
+
+#ifndef ENABLE_SELINUX
+           "no-"
+#endif
+           "selinux"
 
            ;
     }
index e3ace78fe6b7be47d0c04f76803ce79fc2c54ed2..d5dc4df98fdc56d709385fa5e3737ae0bb2b8d49 100644 (file)
@@ -39,6 +39,7 @@ namespace snapper
 
     class Filesystem;
     class SDir;
+    class SelinuxLabelHandle;
 
 
     class ConfigInfo : public SysconfigFile
@@ -176,6 +177,10 @@ namespace snapper
 
        void syncAcl(const vector<uid_t>& uids, const vector<gid_t>& gids) const;
 
+       void syncSelinuxContexts() const;
+       void syncSelinuxContextsInInfosDir() const;
+       void syncInfoDir(SDir& dir) const;
+
        ConfigInfo* config_info;
 
        Filesystem* filesystem;
@@ -184,6 +189,8 @@ namespace snapper
 
        Snapshots snapshots;
 
+       SelinuxLabelHandle* selabel_handle;
+
     };
 
 }