Stefan Schuermans commited on 2020-08-23 12:37:57
Showing 17 changed files, with 195 additions and 8 deletions.
| ... | ... |
@@ -10,9 +10,6 @@ |
| 10 | 10 |
/// configuration file |
| 11 | 11 |
class Config {
|
| 12 | 12 |
public: |
| 13 |
- /// map of trees |
|
| 14 |
- typedef std::map<boost::filesystem::path, Tree> TreeMap; |
|
| 15 |
- |
|
| 16 | 13 |
/** |
| 17 | 14 |
* @brief parse configuration file |
| 18 | 15 |
* @param[in] configFileName name of configuation file |
| ... | ... |
@@ -23,6 +20,11 @@ public: |
| 23 | 20 |
/// return trees |
| 24 | 21 |
TreeMap const & getTrees() const; |
| 25 | 22 |
|
| 23 |
+ /** |
|
| 24 |
+ * @brief set owners and permissions of files in trees |
|
| 25 |
+ */ |
|
| 26 |
+ void setPermissions() const; |
|
| 27 |
+ |
|
| 26 | 28 |
protected: |
| 27 | 29 |
TreeMap trees; |
| 28 | 30 |
}; |
| ... | ... |
@@ -1,6 +1,7 @@ |
| 1 | 1 |
#ifndef PERMISSIONS_H |
| 2 | 2 |
#define PERMISSIONS_H |
| 3 | 3 |
|
| 4 |
+#include <boost/filesystem.hpp> |
|
| 4 | 5 |
#include <cstdint> |
| 5 | 6 |
#include <string> |
| 6 | 7 |
|
| ... | ... |
@@ -23,6 +24,16 @@ public: |
| 23 | 24 |
*/ |
| 24 | 25 |
void parseParams(std::string const ¶mStr); |
| 25 | 26 |
|
| 27 |
+ /** |
|
| 28 |
+ * @brief apply paermissions to file or directory |
|
| 29 |
+ * @param[in] path path to file or directory |
|
| 30 |
+ */ |
|
| 31 |
+ void apply(boost::filesystem::path const &path) const; |
|
| 32 |
+ |
|
| 33 |
+protected: |
|
| 34 |
+ /// convert flags into boost filesystem permissions |
|
| 35 |
+ static boost::filesystem::perms flags2perms(Flags flags); |
|
| 36 |
+ |
|
| 26 | 37 |
protected: |
| 27 | 38 |
Flags set = 0; ///< permissions to set |
| 28 | 39 |
Flags setCond = 0; ///< permissions to set conditionally on usrexec/dir |
| ... | ... |
@@ -6,8 +6,12 @@ |
| 6 | 6 |
#include <permissioner/User.h> |
| 7 | 7 |
|
| 8 | 8 |
#include <boost/filesystem.hpp> |
| 9 |
+#include <map> |
|
| 9 | 10 |
#include <string> |
| 10 | 11 |
|
| 12 |
+/// map of trees |
|
| 13 |
+typedef std::map<boost::filesystem::path, class Tree> TreeMap; |
|
| 14 |
+ |
|
| 11 | 15 |
/// directory tree configuration |
| 12 | 16 |
class Tree {
|
| 13 | 17 |
public: |
| ... | ... |
@@ -30,6 +34,27 @@ public: |
| 30 | 34 |
/// get root path |
| 31 | 35 |
boost::filesystem::path const & getRoot() const; |
| 32 | 36 |
|
| 37 |
+ /** |
|
| 38 |
+ * @brief set owners and permissions of files in tree |
|
| 39 |
+ * @param[in] exclude map of other trees that shall be excluded |
|
| 40 |
+ */ |
|
| 41 |
+ void setPermissions(TreeMap const &exclude) const; |
|
| 42 |
+ |
|
| 43 |
+protected: |
|
| 44 |
+ /** |
|
| 45 |
+ * @brief set owners and permissions of files in path and subtrees |
|
| 46 |
+ * @param[in] path path to top of directory tree for which to set owner/perms |
|
| 47 |
+ * @param[in] exclude map of other trees that shall be excluded |
|
| 48 |
+ */ |
|
| 49 |
+ void setPermissionsInternal(boost::filesystem::path const &path, |
|
| 50 |
+ TreeMap const &exclude) const; |
|
| 51 |
+ |
|
| 52 |
+ /** |
|
| 53 |
+ * @brief set owners and permissions of one file or directory |
|
| 54 |
+ * @param[in] path path to file or directory |
|
| 55 |
+ */ |
|
| 56 |
+ void setPermissionsOne(boost::filesystem::path const &path) const; |
|
| 57 |
+ |
|
| 33 | 58 |
protected: |
| 34 | 59 |
User user; |
| 35 | 60 |
Group group; |
| ... | ... |
@@ -43,6 +43,13 @@ void Config::parseFile(std::string const &configFileName) {
|
| 43 | 43 |
} |
| 44 | 44 |
} |
| 45 | 45 |
|
| 46 |
-Config::TreeMap const & Config::getTrees() const {
|
|
| 46 |
+TreeMap const & Config::getTrees() const {
|
|
| 47 | 47 |
return trees; |
| 48 | 48 |
} |
| 49 |
+ |
|
| 50 |
+void Config::setPermissions() const {
|
|
| 51 |
+ for (auto const & path_tree : trees) {
|
|
| 52 |
+ Tree const & tree = path_tree.second; |
|
| 53 |
+ tree.setPermissions(trees); // exclude all other trees |
|
| 54 |
+ } |
|
| 55 |
+} |
| ... | ... |
@@ -1,5 +1,6 @@ |
| 1 | 1 |
#include <permissioner/Permissions.h> |
| 2 | 2 |
|
| 3 |
+#include <boost/filesystem.hpp> |
|
| 3 | 4 |
#include <sstream> |
| 4 | 5 |
#include <stdexcept> |
| 5 | 6 |
#include <string> |
| ... | ... |
@@ -77,3 +78,45 @@ void Permissions::parseParams(std::string const ¶mStr) {
|
| 77 | 78 |
} |
| 78 | 79 |
} |
| 79 | 80 |
} |
| 81 |
+ |
|
| 82 |
+void Permissions::apply(boost::filesystem::path const &path) const {
|
|
| 83 |
+ // only process regular files and directories (especially no symlinks) |
|
| 84 |
+ if (! boost::filesystem::is_regular_file(path) && |
|
| 85 |
+ ! boost::filesystem::is_directory(path)) {
|
|
| 86 |
+ return; |
|
| 87 |
+ } |
|
| 88 |
+ |
|
| 89 |
+ // get permissions |
|
| 90 |
+ boost::filesystem::file_status st = boost::filesystem::status(path); |
|
| 91 |
+ boost::filesystem::perms perms = st.permissions(); |
|
| 92 |
+ |
|
| 93 |
+ // compute updated permissions |
|
| 94 |
+ Flags doSet = set, doClear = clear; |
|
| 95 |
+ if (perms & boost::filesystem::perms::owner_exe) {
|
|
| 96 |
+ doSet |= setCond; |
|
| 97 |
+ doClear |= clearCond; |
|
| 98 |
+ } |
|
| 99 |
+ perms &= boost::filesystem::perms::all_all ^ flags2perms(doClear); |
|
| 100 |
+ perms |= flags2perms(doSet); |
|
| 101 |
+ |
|
| 102 |
+ // set new permissions if they changed |
|
| 103 |
+ if (perms != st.permissions()) {
|
|
| 104 |
+ boost::filesystem::permissions(path, perms); |
|
| 105 |
+ } |
|
| 106 |
+} |
|
| 107 |
+ |
|
| 108 |
+boost::filesystem::perms Permissions::flags2perms(Flags flags) {
|
|
| 109 |
+ using fsp = boost::filesystem::perms; |
|
| 110 |
+ fsp perms = fsp::no_perms; |
|
| 111 |
+ if (flags & (flagUser * flagRead)) { perms |= fsp::owner_read; }
|
|
| 112 |
+ if (flags & (flagUser * flagWrite)) { perms |= fsp::owner_write; }
|
|
| 113 |
+ if (flags & (flagUser * flagExecute)) { perms |= fsp::owner_exe; }
|
|
| 114 |
+ if (flags & (flagGroup * flagRead)) { perms |= fsp::group_read; }
|
|
| 115 |
+ if (flags & (flagGroup * flagWrite)) { perms |= fsp::group_write; }
|
|
| 116 |
+ if (flags & (flagGroup * flagExecute)) { perms |= fsp::group_exe; }
|
|
| 117 |
+ if (flags & (flagOther * flagRead)) { perms |= fsp::others_read; }
|
|
| 118 |
+ if (flags & (flagOther * flagWrite)) { perms |= fsp::others_write; }
|
|
| 119 |
+ if (flags & (flagOther * flagExecute)) { perms |= fsp::others_exe; }
|
|
| 120 |
+ return perms; |
|
| 121 |
+} |
|
| 122 |
+ |
| ... | ... |
@@ -9,6 +9,7 @@ |
| 9 | 9 |
#include <sstream> |
| 10 | 10 |
#include <stdexcept> |
| 11 | 11 |
#include <string> |
| 12 |
+#include <unistd.h> |
|
| 12 | 13 |
#include <vector> |
| 13 | 14 |
|
| 14 | 15 |
void Tree::parseParams(std::string const ¶mStr) {
|
| ... | ... |
@@ -25,6 +26,7 @@ void Tree::parseParams(std::string const ¶mStr) {
|
| 25 | 26 |
msg << "<root> field missing in \"" << paramStr << "\""; |
| 26 | 27 |
throw std::runtime_error(msg.str()); |
| 27 | 28 |
} |
| 29 |
+ rootStr = paramStr.substr(pos); |
|
| 28 | 30 |
|
| 29 | 31 |
try {
|
| 30 | 32 |
user.parseUserName(userStr); |
| ... | ... |
@@ -78,3 +80,42 @@ Permissions const & Tree::getPermissions() const {
|
| 78 | 80 |
boost::filesystem::path const & Tree::getRoot() const {
|
| 79 | 81 |
return root; |
| 80 | 82 |
} |
| 83 |
+ |
|
| 84 |
+void Tree::setPermissions(TreeMap const &exclude) const {
|
|
| 85 |
+ setPermissionsInternal(root, exclude); |
|
| 86 |
+} |
|
| 87 |
+ |
|
| 88 |
+void Tree::setPermissionsInternal(boost::filesystem::path const &path, |
|
| 89 |
+ TreeMap const &exclude) const {
|
|
| 90 |
+ try {
|
|
| 91 |
+ if (boost::filesystem::is_regular_file(path)) {
|
|
| 92 |
+ setPermissionsOne(path); |
|
| 93 |
+ } else if (boost::filesystem::is_directory(path)) {
|
|
| 94 |
+ setPermissionsOne(path); |
|
| 95 |
+ for (boost::filesystem::directory_entry entry : |
|
| 96 |
+ boost::filesystem::directory_iterator(path)) {
|
|
| 97 |
+ if (exclude.find(entry) != exclude.end()) {
|
|
| 98 |
+ continue; // other tree -> skip here |
|
| 99 |
+ } |
|
| 100 |
+ setPermissionsInternal(entry, exclude); // recurse |
|
| 101 |
+ } |
|
| 102 |
+ } |
|
| 103 |
+ } catch (boost::filesystem::filesystem_error const & e) {
|
|
| 104 |
+ // ignore filesystem errors for now, as this runs in a daemon in background |
|
| 105 |
+ (void)e; |
|
| 106 |
+ } |
|
| 107 |
+} |
|
| 108 |
+ |
|
| 109 |
+void Tree::setPermissionsOne(boost::filesystem::path const &path) const {
|
|
| 110 |
+ // change permissions |
|
| 111 |
+ try {
|
|
| 112 |
+ permissions.apply(path); |
|
| 113 |
+ } catch (boost::filesystem::filesystem_error const & e) {
|
|
| 114 |
+ // ignore filesystem errors for now, as this runs in a daemon in background |
|
| 115 |
+ (void)e; |
|
| 116 |
+ } |
|
| 117 |
+ |
|
| 118 |
+ // change owner/group |
|
| 119 |
+ lchown(path.string().c_str(), user.getUid(), group.getGid()); |
|
| 120 |
+ // ignore error for now, as this runs in a daemon in background |
|
| 121 |
+} |
| ... | ... |
@@ -0,0 +1,27 @@ |
| 1 |
+#include <permissioner/Config.h> |
|
| 2 |
+ |
|
| 3 |
+#include <cstdlib> |
|
| 4 |
+#include <iostream> // DEBUG |
|
| 5 |
+#include <unistd.h> |
|
| 6 |
+#include <sys/stat.h> |
|
| 7 |
+ |
|
| 8 |
+// mock version of lchown, to see if right files get right owners |
|
| 9 |
+extern "C" int lchown(const char *pathname, uid_t owner, gid_t group) {
|
|
| 10 |
+ std::cout << "DEBUG lchown " << pathname << " owner " << owner |
|
| 11 |
+ << " group " << group << std::endl; |
|
| 12 |
+ return 0; |
|
| 13 |
+} |
|
| 14 |
+ |
|
| 15 |
+// mock version fo chmod, to see if right files get right permissions |
|
| 16 |
+extern "C" int chmod(const char *pathname, mode_t mode) {
|
|
| 17 |
+ std::cout << "DEBUG chmod " << pathname << " mode " << mode << std::endl; |
|
| 18 |
+ return 0; |
|
| 19 |
+} |
|
| 20 |
+ |
|
| 21 |
+int main(int argc, char const **argv) {
|
|
| 22 |
+ (void)argc; |
|
| 23 |
+ Config config; |
|
| 24 |
+ config.parseFile(argv[1]); |
|
| 25 |
+ config.setPermissions(); |
|
| 26 |
+ return EXIT_SUCCESS; |
|
| 27 |
+} |