From: Rishabh Dave Date: Fri, 9 Jun 2023 18:54:12 +0000 (+0530) Subject: MDSAuthCaps: print a special error message for wrong permissions X-Git-Tag: v18.2.4~68^2~2 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=9e3f16ab73b28d23036f3d375587f2671da60d43;p=ceph.git MDSAuthCaps: print a special error message for wrong permissions Permissions mentioned in MDS caps flags can either begin with "r" or "rw", or can be "*" and "all". But it can't start with or be just "w" or something else. This is confusing for some CephFS users since MON caps can be just "w". Command "ceph fs authorize" complains about this to the user. But other commands (specifically, "ceph auth add", "ceph auth caps", "ceph auth get-or-create" and "ceph auth get-or-create-key") don't. Make these commands too print a helpful message, the way "ceph fs authorize" command does. Fixes: https://tracker.ceph.com/issues/61666 Signed-off-by: Rishabh Dave (cherry picked from commit f163dd3ef1fd9f05f05fa50eda9993225770d524) Conflicts: src/mds/MDSAuthCaps.cc "std::string" was replace "string" in main but that's not the case in Reef. --- diff --git a/qa/tasks/cephfs/test_admin.py b/qa/tasks/cephfs/test_admin.py index 123d913026624..128b17c498ff2 100644 --- a/qa/tasks/cephfs/test_admin.py +++ b/qa/tasks/cephfs/test_admin.py @@ -1576,3 +1576,61 @@ class TestFsBalRankMask(CephFSTestCase): self.fs.set_bal_rank_mask(bal_rank_mask) except CommandFailedError as e: self.assertEqual(e.exitstatus, errno.EINVAL) + + +class TestPermErrMsg(CephFSTestCase): + + CLIENT_NAME = 'client.testuser' + FS1_NAME, FS2_NAME, FS3_NAME = 'abcd', 'efgh', 'ijkl' + + EXPECTED_ERRNO = 22 + EXPECTED_ERRMSG = ("Permission flags in MDS caps must start with 'r' or " + "'rw' or be '*' or 'all'") + + MONCAP = f'allow r fsname={FS1_NAME}' + OSDCAP = f'allow rw tag cephfs data={FS1_NAME}' + MDSCAPS = [ + 'allow w', + f'allow w fsname={FS1_NAME}', + + f'allow rw fsname={FS1_NAME}, allow w fsname={FS2_NAME}', + f'allow w fsname={FS1_NAME}, allow rw fsname={FS2_NAME}', + f'allow w fsname={FS1_NAME}, allow w fsname={FS2_NAME}', + + (f'allow rw fsname={FS1_NAME}, allow rw fsname={FS2_NAME}, allow ' + f'w fsname={FS3_NAME}'), + + # without space after comma + f'allow rw fsname={FS1_NAME},allow w fsname={FS2_NAME}', + + + 'allow wr', + f'allow wr fsname={FS1_NAME}', + + f'allow rw fsname={FS1_NAME}, allow wr fsname={FS2_NAME}', + f'allow wr fsname={FS1_NAME}, allow rw fsname={FS2_NAME}', + f'allow wr fsname={FS1_NAME}, allow wr fsname={FS2_NAME}', + + (f'allow rw fsname={FS1_NAME}, allow rw fsname={FS2_NAME}, allow ' + f'wr fsname={FS3_NAME}'), + + # without space after comma + f'allow rw fsname={FS1_NAME},allow wr fsname={FS2_NAME}'] + + def _negtestcmd(self, SUBCMD, MDSCAP): + return self.negtest_ceph_cmd( + args=(f'{SUBCMD} {self.CLIENT_NAME} ' + f'mon "{self.MONCAP}" osd "{self.OSDCAP}" mds "{MDSCAP}"'), + retval=self.EXPECTED_ERRNO, errmsgs=self.EXPECTED_ERRMSG) + + def test_auth_add(self): + for mdscap in self.MDSCAPS: + self._negtestcmd('auth add', mdscap) + + def test_auth_get_or_create(self): + for mdscap in self.MDSCAPS: + self._negtestcmd('auth get-or-create', mdscap) + + def test_auth_get_or_create_key(self): + for mdscap in self.MDSCAPS: + self._negtestcmd('auth get-or-create-key', mdscap) diff --git a/src/mds/MDSAuthCaps.cc b/src/mds/MDSAuthCaps.cc index 03b6413b15b6e..22383445e67a4 100644 --- a/src/mds/MDSAuthCaps.cc +++ b/src/mds/MDSAuthCaps.cc @@ -354,10 +354,15 @@ bool MDSAuthCaps::parse(string_view str, ostream *err) // Make sure no grants are kept after parsing failed! grants.clear(); - if (err) - *err << "mds capability parse failed, stopped at '" - << string(iter, end) - << "' of '" << str << "'"; + if (err) { + if (string(iter, end).find("allow") != string::npos) { + *err << "Permission flags in MDS caps must start with 'r' or " << + "'rw' or be '*' or 'all'"; + } else { + *err << "mds capability parse failed, stopped at '" + << string(iter, end) << "' of '" << str << "'"; + } + } return false; } }