From 1bdb327892cb0d81c10a6b927fc5088633f99088 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 15 Feb 2016 20:26:46 +0000 Subject: Test permissions behaviour, fix write permissions check (might need further work) --- netfs/daemon/daemonVolume.cpp | 2 +- netfs/daemon/modeCheck.cpp | 12 ++++++++++++ netfs/daemon/modeCheck.h | 1 + netfs/unittests/testCore.cpp | 30 ++++++++++++++++++++++++++++++ 4 files changed, 44 insertions(+), 1 deletion(-) diff --git a/netfs/daemon/daemonVolume.cpp b/netfs/daemon/daemonVolume.cpp index e4c65bd..5064b5b 100644 --- a/netfs/daemon/daemonVolume.cpp +++ b/netfs/daemon/daemonVolume.cpp @@ -161,7 +161,7 @@ VolumeServer::chmod(const NetFS::ReqEnv & re, const std::string & path, Ice::Int ModeCheck mc(re, root, userLookup, groupLookup); errno = 0; boost::filesystem::path p(resolvePath(path)); - mc.AssertWrite(p); + mc.AssertWritePerms(p); if (::chmod(p.c_str(), mode) != 0) { throw NetFS::SystemError(errno); } diff --git a/netfs/daemon/modeCheck.cpp b/netfs/daemon/modeCheck.cpp index dd1464c..df409bf 100644 --- a/netfs/daemon/modeCheck.cpp +++ b/netfs/daemon/modeCheck.cpp @@ -52,6 +52,18 @@ ModeCheck::AssertWrite(const boost::filesystem::path & p) const } } +void +ModeCheck::AssertWritePerms(const boost::filesystem::path & p) const +{ + if (p != root) { + AssertRead(p.parent_path()); + } + auto s = lstat(p); + if (s.st_uid != myu && !WritableBy(s, myu, myg)) { + throw NetFS::SystemError(EACCES); + } +} + struct stat ModeCheck::lstat(const boost::filesystem::path & p) { diff --git a/netfs/daemon/modeCheck.h b/netfs/daemon/modeCheck.h index 6c3ee2c..54a82e2 100644 --- a/netfs/daemon/modeCheck.h +++ b/netfs/daemon/modeCheck.h @@ -14,6 +14,7 @@ class ModeCheck { void AssertRead(const boost::filesystem::path &) const; void AssertWriteParent(const boost::filesystem::path &) const; void AssertWrite(const boost::filesystem::path &) const; + void AssertWritePerms(const boost::filesystem::path &) const; const uid_t myu; const gid_t myg; diff --git a/netfs/unittests/testCore.cpp b/netfs/unittests/testCore.cpp index 8a0d38b..fb41f65 100644 --- a/netfs/unittests/testCore.cpp +++ b/netfs/unittests/testCore.cpp @@ -251,6 +251,36 @@ BOOST_AUTO_TEST_CASE( symlinks ) BOOST_REQUIRE_EQUAL(fuse->unlink("/test3"), -ENOENT); } +BOOST_AUTO_TEST_CASE( access ) +{ + struct stat st; + memset(&st, 0, sizeof(st)); + BOOST_REQUIRE_EQUAL(fuse->access("/", F_OK), 0); + BOOST_REQUIRE_EQUAL(fuse->access("/missing", F_OK), -ENOENT); + BOOST_REQUIRE_EQUAL(fuse->mkdir("/dir", 0700), 0); + BOOST_REQUIRE_EQUAL(fuse->getattr("/dir", &st), 0); + BOOST_REQUIRE_EQUAL(st.st_mode, 0700 | S_IFDIR); + BOOST_REQUIRE_EQUAL(fuse->access("/dir", F_OK), 0); + BOOST_REQUIRE_EQUAL(fuse->access("/dir", R_OK), 0); + BOOST_REQUIRE_EQUAL(fuse->access("/dir", W_OK), 0); + BOOST_REQUIRE_EQUAL(fuse->access("/dir", X_OK), 0); + BOOST_REQUIRE_EQUAL(fuse->chmod("/dir", 0000), 0); + BOOST_REQUIRE_EQUAL(fuse->getattr("/dir", &st), 0); + BOOST_REQUIRE_EQUAL(st.st_mode, 0000 | S_IFDIR); + BOOST_REQUIRE_EQUAL(fuse->access("/dir", F_OK), 0); + BOOST_REQUIRE_EQUAL(fuse->access("/dir", R_OK), -EACCES); + BOOST_REQUIRE_EQUAL(fuse->access("/dir", W_OK), -EACCES); + BOOST_REQUIRE_EQUAL(fuse->access("/dir", X_OK), -EACCES); + BOOST_REQUIRE_EQUAL(fuse->chmod("/dir", 0500), 0); + BOOST_REQUIRE_EQUAL(fuse->getattr("/dir", &st), 0); + BOOST_REQUIRE_EQUAL(st.st_mode, 0500 | S_IFDIR); + BOOST_REQUIRE_EQUAL(fuse->rmdir("/dir"), -EACCES); + BOOST_REQUIRE_EQUAL(fuse->chmod("/dir", 0700), 0); + BOOST_REQUIRE_EQUAL(fuse->getattr("/dir", &st), 0); + BOOST_REQUIRE_EQUAL(st.st_mode, 0700 | S_IFDIR); + BOOST_REQUIRE_EQUAL(fuse->rmdir("/dir"), 0); +} + BOOST_AUTO_TEST_SUITE_END(); BOOST_AUTO_TEST_CASE( testNoAuthNoPass ) -- cgit v1.2.3