Skip to content

Commit 5f1dece

Browse files
Merge pull request ceph#51317 from rishabh-d-dave/mdscaps-combinations
mds: allow all types of mds capsq Reviewed-by: Venky Shankar <[email protected]>
2 parents 0c22b59 + bfacee1 commit 5f1dece

File tree

3 files changed

+94
-52
lines changed

3 files changed

+94
-52
lines changed

src/mds/MDSAuthCaps.cc

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ struct MDSCapParser : qi::grammar<Iterator, MDSAuthCaps()>
5454
using qi::_1;
5555
using qi::_2;
5656
using qi::_3;
57+
using qi::_4;
58+
using qi::_5;
5759
using qi::eps;
5860
using qi::lit;
5961

@@ -66,25 +68,13 @@ struct MDSCapParser : qi::grammar<Iterator, MDSAuthCaps()>
6668
network_str %= +char_("/.:a-fA-F0-9][");
6769
fs_name_str %= +char_("a-zA-Z0-9_.-");
6870

69-
// match := [path=<path>] [uid=<uid> [gids=<gid>[,<gid>...]]
70-
// TODO: allow fsname, and root_squash to be specified with uid, and gidlist
71-
path %= (spaces >> lit("path") >> lit('=') >> (quoted_path | unquoted_path));
72-
uid %= (spaces >> lit("uid") >> lit('=') >> uint_);
71+
path %= -(spaces >> lit("path") >> lit('=') >> (quoted_path | unquoted_path));
72+
uid %= -(spaces >> lit("uid") >> lit('=') >> uint_);
7373
uintlist %= (uint_ % lit(','));
7474
gidlist %= -(spaces >> lit("gids") >> lit('=') >> uintlist);
7575
fs_name %= -(spaces >> lit("fsname") >> lit('=') >> fs_name_str);
76-
root_squash %= (spaces >> lit("root_squash") >> attr(true));
77-
match = -(
78-
(fs_name >> path >> root_squash)[_val = phoenix::construct<MDSCapMatch>(_2, _1, _3)] |
79-
(uid >> gidlist)[_val = phoenix::construct<MDSCapMatch>(_1, _2)] |
80-
(path >> uid >> gidlist)[_val = phoenix::construct<MDSCapMatch>(_1, _2, _3)] |
81-
(fs_name >> path)[_val = phoenix::construct<MDSCapMatch>(_2, _1)] |
82-
(fs_name >> root_squash)[_val = phoenix::construct<MDSCapMatch>(string(), _1, _2)] |
83-
(path >> root_squash)[_val = phoenix::construct<MDSCapMatch>(_1, string(), _2)] |
84-
(path)[_val = phoenix::construct<MDSCapMatch>(_1)] |
85-
(root_squash)[_val = phoenix::construct<MDSCapMatch>(string(), string(), _1)] |
86-
(fs_name)[_val = phoenix::construct<MDSCapMatch>(string(),
87-
_1)]);
76+
root_squash %= -(spaces >> lit("root_squash") >> attr(true));
77+
match = (fs_name >> path >> root_squash >> uid >> gidlist)[_val = phoenix::construct<MDSCapMatch>(_1, _2, _3, _4, _5)];
8878

8979
// capspec = * | r[w][f][p][s]
9080
capspec = spaces >> (

src/mds/MDSAuthCaps.h

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -101,30 +101,17 @@ struct MDSCapSpec {
101101
struct MDSCapMatch {
102102
static const int64_t MDS_AUTH_UID_ANY = -1;
103103

104-
MDSCapMatch() : uid(MDS_AUTH_UID_ANY), fs_name(std::string()) {}
104+
MDSCapMatch() {}
105105

106-
MDSCapMatch(int64_t uid_, std::vector<gid_t>& gids_) :
107-
uid(uid_), gids(gids_), fs_name(std::string()) {}
106+
MDSCapMatch(const std::string& fsname_, const std::string& path_,
107+
bool root_squash_, int64_t uid_=MDS_AUTH_UID_ANY,
108+
const std::vector<gid_t>& gids_={}) {
109+
fs_name = std::move(fsname_);
110+
path = std::move(path_);
111+
root_squash = root_squash_;
112+
uid = (uid_ == 0) ? -1 : uid_;
113+
gids = gids_;
108114

109-
explicit MDSCapMatch(const std::string &path_)
110-
: uid(MDS_AUTH_UID_ANY), path(path_), fs_name(std::string()) {
111-
normalize_path();
112-
}
113-
114-
explicit MDSCapMatch(std::string path, std::string fs_name) :
115-
uid(MDS_AUTH_UID_ANY), path(std::move(path)), fs_name(std::move(fs_name))
116-
{
117-
normalize_path();
118-
}
119-
120-
explicit MDSCapMatch(std::string path, std::string fs_name, bool root_squash_) :
121-
uid(MDS_AUTH_UID_ANY), path(std::move(path)), fs_name(std::move(fs_name)), root_squash(root_squash_)
122-
{
123-
normalize_path();
124-
}
125-
126-
MDSCapMatch(const std::string& path_, int64_t uid_, std::vector<gid_t>& gids_)
127-
: uid(uid_), gids(gids_), path(path_), fs_name(std::string()) {
128115
normalize_path();
129116
}
130117

@@ -149,7 +136,8 @@ struct MDSCapMatch {
149136
*/
150137
bool match_path(std::string_view target_path) const;
151138

152-
int64_t uid; // Require UID to be equal to this, if !=MDS_AUTH_UID_ANY
139+
// Require UID to be equal to this, if !=MDS_AUTH_UID_ANY
140+
int64_t uid = MDS_AUTH_UID_ANY;
153141
std::vector<gid_t> gids; // Use these GIDs
154142
std::string path; // Require path to be child of this (may be "" or "/" for any)
155143
std::string fs_name;

src/test/mds/TestMDSAuthCaps.cc

Lines changed: 77 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,14 @@ using namespace std;
2323

2424
entity_addr_t addr;
2525

26-
const char *parse_good[] = {
26+
string fsnamecap = "fsname=a";
27+
string pathcap = "path=/dir1";
28+
string rscap = "root_squash";
29+
string uidcap = "uid=1000";
30+
string gidscap = "gids=1000,1001,1002";
31+
32+
33+
vector<string> parse_good = {
2734
"allow rw uid=1 gids=1",
2835
"allow * path=\"/foo\"",
2936
"allow * path=/foo",
@@ -34,8 +41,6 @@ const char *parse_good[] = {
3441
"allow *",
3542
"allow r",
3643
"allow rw",
37-
"allow rw uid=1 gids=1,2,3",
38-
"allow rw path=/foo uid=1 gids=1,2,3",
3944
"allow r, allow rw path=/foo",
4045
"allow r, allow * uid=1",
4146
"allow r ,allow * uid=1",
@@ -45,23 +50,82 @@ const char *parse_good[] = {
4550
"allow r uid=1 gids=1,2,3, allow * uid=2",
4651
"allow r network 1.2.3.4/8",
4752
"allow rw path=/foo uid=1 gids=1,2,3 network 2.3.4.5/16",
48-
"allow r root_squash",
49-
"allow rw path=/foo root_squash",
50-
"allow rw fsname=a root_squash",
51-
"allow rw fsname=a path=/foo root_squash",
52-
"allow rw fsname=a root_squash, allow rwp fsname=a path=/volumes",
53-
0
53+
54+
// Following are all types of MDS caps, or in other words, all
55+
// (mathematical) combinations of fsnamecap, pathcap, rscap, uidcap, and
56+
// gidscaps.
57+
"allow rw " + fsnamecap,
58+
"allow rw " + pathcap,
59+
"allow rw " + rscap,
60+
"allow rw " + uidcap,
61+
"allow rw " + gidscap,
62+
63+
"allow rw " + fsnamecap + " " + pathcap,
64+
"allow rw " + fsnamecap + " " + rscap,
65+
"allow rw " + fsnamecap + " " + uidcap,
66+
"allow rw " + fsnamecap + " " + gidscap,
67+
"allow rw " + pathcap + " " + rscap,
68+
"allow rw " + pathcap + " " + uidcap,
69+
"allow rw " + pathcap + " " + gidscap,
70+
"allow rw " + rscap + " " + uidcap,
71+
"allow rw " + rscap + " " + gidscap,
72+
"allow rw " + uidcap + " " + gidscap,
73+
74+
"allow rw " + fsnamecap + " " + pathcap + " " + rscap,
75+
"allow rw " + fsnamecap + " " + pathcap + " " + uidcap,
76+
"allow rw " + fsnamecap + " " + pathcap + " " + gidscap,
77+
"allow rw " + fsnamecap + " " + rscap + " " + uidcap,
78+
"allow rw " + fsnamecap + " " + rscap + " " + gidscap,
79+
"allow rw " + fsnamecap + " " + uidcap + " " + gidscap,
80+
"allow rw " + pathcap + " " + rscap + " " + uidcap,
81+
"allow rw " + pathcap + " " + rscap + " " + gidscap,
82+
"allow rw " + pathcap + " " + uidcap + " " + gidscap,
83+
"allow rw " + rscap + " " + uidcap + " " + gidscap,
84+
85+
"allow rw " + fsnamecap + " " + pathcap + " " + rscap + " " + uidcap,
86+
"allow rw " + fsnamecap + " " + pathcap + " " + rscap + " " + gidscap,
87+
"allow rw " + fsnamecap + " " + pathcap + " " + uidcap + " " + gidscap,
88+
"allow rw " + fsnamecap + " " + rscap + " " + uidcap + " " + gidscap,
89+
"allow rw " + pathcap + " " + rscap + " " + uidcap + " " + gidscap,
90+
91+
"allow rw " + fsnamecap + " " + pathcap + " " + rscap + " " + uidcap +
92+
" " + gidscap
5493
};
5594

5695
TEST(MDSAuthCaps, ParseGood) {
57-
for (int i=0; parse_good[i]; i++) {
58-
string str = parse_good[i];
96+
for (auto str : parse_good) {
5997
MDSAuthCaps cap;
6098
std::cout << "Testing good input: '" << str << "'" << std::endl;
6199
ASSERT_TRUE(cap.parse(str, &cout));
62100
}
63101
}
64102

103+
TEST(MDSAuthCaps, ParseDumpReparseCaps) {
104+
for (auto str : parse_good) {
105+
MDSAuthCaps cap1;
106+
ASSERT_TRUE(cap1.parse(str, &cout));
107+
108+
std::cout << "Testing by parsing caps, dumping to string, reparsing "
109+
"string and then redumping and checking strings from "
110+
"first and second dumps: '" << str << "'" << std::endl;
111+
// Convert cap object to string, reparse and check if converting again
112+
// gives same string as before.
113+
MDSAuthCaps cap2;
114+
std::ostringstream cap1_ostream;
115+
cap1_ostream << cap1;
116+
string cap1_str = cap1_ostream.str();
117+
// Removing "MDSAuthCaps[" from cap1_str
118+
cap1_str.replace(0, 12, "");
119+
// Removing "]" from cap1_str
120+
cap1_str.replace(cap1_str.length() - 1, 1, "");
121+
ASSERT_TRUE(cap2.parse(cap1_str, &cout));
122+
123+
std::ostringstream cap2_ostream;
124+
cap2_ostream << cap2;
125+
ASSERT_TRUE(cap1_ostream.str().compare(cap2_ostream.str()) == 0);
126+
}
127+
}
128+
65129
const char *parse_bad[] = {
66130
"allow r poolfoo",
67131
"allow r w",
@@ -85,8 +149,6 @@ const char *parse_bad[] = {
85149
"allow namespace=foo",
86150
"allow rwx auid 123 namespace asdf",
87151
"allow wwx pool ''",
88-
"allow rw gids=1",
89-
"allow rw gids=1,2,3",
90152
"allow rw uid=123 gids=asdf",
91153
"allow rw uid=123 gids=1,2,asdf",
92154
0
@@ -98,6 +160,8 @@ TEST(MDSAuthCaps, ParseBad) {
98160
MDSAuthCaps cap;
99161
std::cout << "Testing bad input: '" << str << "'" << std::endl;
100162
ASSERT_FALSE(cap.parse(str, &cout));
163+
// error message from parse() doesn't have newline char at the end of it
164+
std::cout << std::endl;
101165
}
102166
}
103167

0 commit comments

Comments
 (0)