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 |
+} |