From 33e68d9492c7cb2f34da007575f6de5e7b63711d Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 19 Jul 2015 20:15:12 +0100 Subject: Move TempPrivs into ModeCheck --- netfs/daemon/daemon.cpp | 37 ----------------- netfs/daemon/daemon.h | 13 ------ netfs/daemon/daemonVolume.cpp | 94 +++++++++++++++++++++---------------------- netfs/daemon/modeCheck.cpp | 38 +++++++++++++++++ netfs/daemon/modeCheck.h | 11 +++++ 5 files changed, 96 insertions(+), 97 deletions(-) diff --git a/netfs/daemon/daemon.cpp b/netfs/daemon/daemon.cpp index 59f3638..5f780d7 100644 --- a/netfs/daemon/daemon.cpp +++ b/netfs/daemon/daemon.cpp @@ -78,40 +78,3 @@ extern "C" { } } -TempPrivs::TempPrivs(const NetFS::ReqEnv & re, const boost::filesystem::path & r) : - myu(UserEntCache::instance.getEntry(re.user)->id), - myg(GroupEntCache::instance.getEntry(re.grp)->id), - root(r) -{ -} - -void -TempPrivs::AssertRead(const boost::filesystem::path & p) const -{ - if (p != root) { - AssertRead(p.parent_path()); - } - struct stat s; - if (::lstat(p.string().c_str(), &s) != 0) { - throw NetFS::SystemError(errno); - } - if (!ModeCheck::ReadableBy(s, myu, myg)) { - throw NetFS::SystemError(EACCES); - } -} - -void -TempPrivs::AssertWrite(const boost::filesystem::path & p) const -{ - if (p != root) { - AssertRead(p.parent_path()); - } - struct stat s; - if (::lstat(p.string().c_str(), &s) != 0) { - throw NetFS::SystemError(errno); - } - if (!ModeCheck::WritableBy(s, myu, myg)) { - throw NetFS::SystemError(EACCES); - } -} - diff --git a/netfs/daemon/daemon.h b/netfs/daemon/daemon.h index 1cf2d49..e4e79ae 100644 --- a/netfs/daemon/daemon.h +++ b/netfs/daemon/daemon.h @@ -4,7 +4,6 @@ #include #include #include -#include #include class NetFSDaemon : public IceBox::Service { @@ -28,17 +27,5 @@ class NetFSDaemon : public IceBox::Service { std::string hostname(); }; -class TempPrivs { - public: - TempPrivs(const NetFS::ReqEnv & re, const boost::filesystem::path &); - - void AssertRead(const boost::filesystem::path &) const; - void AssertWrite(const boost::filesystem::path &) const; - - const uid_t myu; - const gid_t myg; - const boost::filesystem::path & root; -}; - #endif diff --git a/netfs/daemon/daemonVolume.cpp b/netfs/daemon/daemonVolume.cpp index 40082cc..347dbe2 100644 --- a/netfs/daemon/daemonVolume.cpp +++ b/netfs/daemon/daemonVolume.cpp @@ -36,7 +36,7 @@ VolumeServer::disconnect(const Ice::Current & ice) Ice::Int VolumeServer::access(const NetFS::ReqEnv & re, const std::string & path, Ice::Int mode, const Ice::Current &) { - TempPrivs tp(re, root); + ModeCheck mc(re, root); struct stat s; boost::filesystem::path p(resolvePath(path)); if (::stat(p.string().c_str(), &s) != 0) { @@ -46,14 +46,14 @@ VolumeServer::access(const NetFS::ReqEnv & re, const std::string & path, Ice::In // stat succeeded, file must exist return 0; } - tp.AssertRead(p.parent_path()); - if (mode & R_OK && !ModeCheck::ReadableBy(s, tp.myu, tp.myg)) { + mc.AssertRead(p.parent_path()); + if (mode & R_OK && !ModeCheck::ReadableBy(s, mc.myu, mc.myg)) { return EACCES; } - if (mode & W_OK && !ModeCheck::WritableBy(s, tp.myu, tp.myg)) { + if (mode & W_OK && !ModeCheck::WritableBy(s, mc.myu, mc.myg)) { return EACCES; } - if (mode & X_OK && !ModeCheck::ExecutableBy(s, tp.myu, tp.myg)) { + if (mode & X_OK && !ModeCheck::ExecutableBy(s, mc.myu, mc.myg)) { return EACCES; } return 0; @@ -62,10 +62,10 @@ VolumeServer::access(const NetFS::ReqEnv & re, const std::string & path, Ice::In NetFS::Attr VolumeServer::getattr(const NetFS::ReqEnv & re, const std::string & path, const Ice::Current &) { - TempPrivs tp(re, root); + ModeCheck mc(re, root); struct stat s; boost::filesystem::path p(resolvePath(path)); - tp.AssertRead(p.parent_path()); + mc.AssertRead(p.parent_path()); if (::lstat(p.string().c_str(), &s) != 0) { throw NetFS::SystemError(errno); } @@ -77,10 +77,10 @@ VolumeServer::getattr(const NetFS::ReqEnv & re, const std::string & path, const void VolumeServer::mknod(const NetFS::ReqEnv & re, const std::string & path, Ice::Int mode, Ice::Int dev, const Ice::Current&) { - TempPrivs tp(re, root); + ModeCheck mc(re, root); errno = 0; boost::filesystem::path p(resolvePath(path)); - tp.AssertWrite(p.parent_path()); + mc.AssertWrite(p.parent_path()); if (::mknod(p.string().c_str(), mode, dev) != 0) { throw NetFS::SystemError(errno); } @@ -89,14 +89,14 @@ VolumeServer::mknod(const NetFS::ReqEnv & re, const std::string & path, Ice::Int void VolumeServer::symlink(const NetFS::ReqEnv & re, const std::string & path1, const std::string & path2, const Ice::Current &) { - TempPrivs tp(re, root); + ModeCheck mc(re, root); errno = 0; boost::filesystem::path p(resolvePath(path2)); - tp.AssertWrite(p.parent_path()); + mc.AssertWrite(p.parent_path()); if (::symlink(path1.c_str(), p.string().c_str()) != 0) { throw NetFS::SystemError(errno); } - if (::lchown(p.string().c_str(), tp.myu, tp.myg) != 0) { + if (::lchown(p.string().c_str(), mc.myu, mc.myg) != 0) { ::unlink(p.string().c_str()); throw NetFS::SystemError(errno); } @@ -105,14 +105,14 @@ VolumeServer::symlink(const NetFS::ReqEnv & re, const std::string & path1, const void VolumeServer::link(const NetFS::ReqEnv & re, const std::string & path1, const std::string & path2, const Ice::Current &) { - TempPrivs tp(re, root); + ModeCheck mc(re, root); errno = 0; boost::filesystem::path p1(resolvePath(path1)); boost::filesystem::path p2(resolvePath(path2)); if (::link(p1.string().c_str(), p2.string().c_str()) != 0) { throw NetFS::SystemError(errno); } - if (::chown(p2.string().c_str(), tp.myu, tp.myg) != 0) { + if (::chown(p2.string().c_str(), mc.myu, mc.myg) != 0) { ::unlink(p2.string().c_str()); throw NetFS::SystemError(errno); } @@ -121,17 +121,17 @@ VolumeServer::link(const NetFS::ReqEnv & re, const std::string & path1, const st void VolumeServer::rename(const NetFS::ReqEnv & re, const std::string & from, const std::string & to, const Ice::Current &) { - TempPrivs tp(re, root); + ModeCheck mc(re, root); errno = 0; boost::filesystem::path f(resolvePath(from)); boost::filesystem::path t(resolvePath(to)); - tp.AssertWrite(f.parent_path()); - tp.AssertWrite(f); + mc.AssertWrite(f.parent_path()); + mc.AssertWrite(f); if (boost::filesystem::is_directory(t)) { - tp.AssertWrite(t); + mc.AssertWrite(t); } else { - tp.AssertWrite(t.parent_path()); + mc.AssertWrite(t.parent_path()); } if (::rename(f.string().c_str(), t.string().c_str()) != 0) { throw NetFS::SystemError(errno); @@ -141,11 +141,11 @@ VolumeServer::rename(const NetFS::ReqEnv & re, const std::string & from, const s std::string VolumeServer::readlink(const NetFS::ReqEnv & re, const std::string & path, const Ice::Current &) { - TempPrivs tp(re, root); + ModeCheck mc(re, root); errno = 0; char buf[PATH_MAX]; boost::filesystem::path p(resolvePath(path)); - tp.AssertRead(p); + mc.AssertRead(p); ssize_t rc = ::readlink(p.string().c_str(), buf, PATH_MAX); if (rc == -1) { throw NetFS::SystemError(errno); @@ -156,10 +156,10 @@ VolumeServer::readlink(const NetFS::ReqEnv & re, const std::string & path, const void VolumeServer::chmod(const NetFS::ReqEnv & re, const std::string & path, Ice::Int mode, const Ice::Current &) { - TempPrivs tp(re, root); + ModeCheck mc(re, root); errno = 0; boost::filesystem::path p(resolvePath(path)); - tp.AssertWrite(p); + mc.AssertWrite(p); if (::chmod(p.string().c_str(), mode) != 0) { throw NetFS::SystemError(errno); } @@ -168,10 +168,10 @@ VolumeServer::chmod(const NetFS::ReqEnv & re, const std::string & path, Ice::Int void VolumeServer::chown(const NetFS::ReqEnv & re, const std::string & path, Ice::Int uid, Ice::Int gid, const Ice::Current &) { - TempPrivs tp(re, root); + ModeCheck mc(re, root); errno = 0; boost::filesystem::path p(resolvePath(path)); - tp.AssertWrite(p); + mc.AssertWrite(p); if (::lchown(p.string().c_str(), uid, gid) != 0) { throw NetFS::SystemError(errno); } @@ -181,7 +181,7 @@ void VolumeServer::utimens(const NetFS::ReqEnv & re, const std::string & path, Ice::Long s0, Ice::Long ns0, Ice::Long s1, Ice::Long ns1, const Ice::Current&) { - TempPrivs tp(re, root); + ModeCheck mc(re, root); errno = 0; struct timespec times[2]; times[0].tv_sec = s0; @@ -189,7 +189,7 @@ VolumeServer::utimens(const NetFS::ReqEnv & re, const std::string & path, times[1].tv_sec = s1; times[1].tv_nsec = ns1; boost::filesystem::path p(resolvePath(path)); - tp.AssertWrite(p); + mc.AssertWrite(p); if (::utimensat(0, p.string().c_str(), times, AT_SYMLINK_NOFOLLOW) != 0) { throw NetFS::SystemError(errno); } @@ -198,11 +198,11 @@ VolumeServer::utimens(const NetFS::ReqEnv & re, const std::string & path, NetFS::VFS VolumeServer::statfs(const NetFS::ReqEnv & re, const std::string & path, const Ice::Current&) { - TempPrivs tp(re, root); + ModeCheck mc(re, root); errno = 0; struct statvfs s; boost::filesystem::path p(resolvePath(path)); - tp.AssertRead(p); + mc.AssertRead(p); if (::statvfs(p.string().c_str(), &s) != 0) { throw NetFS::SystemError(errno); } @@ -214,10 +214,10 @@ VolumeServer::statfs(const NetFS::ReqEnv & re, const std::string & path, const I void VolumeServer::truncate(const NetFS::ReqEnv & re, const std::string & path, Ice::Long size, const Ice::Current&) { - TempPrivs tp(re, root); + ModeCheck mc(re, root); errno = 0; boost::filesystem::path p(resolvePath(path)); - tp.AssertWrite(p); + mc.AssertWrite(p); if (::truncate(p.string().c_str(), size) != 0) { throw NetFS::SystemError(errno); } @@ -226,11 +226,11 @@ VolumeServer::truncate(const NetFS::ReqEnv & re, const std::string & path, Ice:: void VolumeServer::unlink(const NetFS::ReqEnv & re, const std::string & path, const Ice::Current&) { - TempPrivs tp(re, root); + ModeCheck mc(re, root); errno = 0; boost::filesystem::path p(resolvePath(path)); - tp.AssertWrite(p); - tp.AssertWrite(p.parent_path()); + mc.AssertWrite(p); + mc.AssertWrite(p.parent_path()); if (::unlink(p.string().c_str()) != 0) { throw NetFS::SystemError(errno); } @@ -245,10 +245,10 @@ VolumeServer::openReadOnly(const NetFS::ReqEnv & re, const std::string & path, I NetFS::FilePrx VolumeServer::open(const NetFS::ReqEnv & re, const std::string & path, Ice::Int flags, const Ice::Current & ice) { - TempPrivs tp(re, root); + ModeCheck mc(re, root); errno = 0; boost::filesystem::path p(resolvePath(path)); - tp.AssertRead(p); + mc.AssertRead(p); if (flags & O_CREAT) { throw NetFS::SystemError(EINVAL); } @@ -262,15 +262,15 @@ VolumeServer::open(const NetFS::ReqEnv & re, const std::string & path, Ice::Int NetFS::FilePrx VolumeServer::create(const NetFS::ReqEnv & re, const std::string & path, Ice::Int flags, Ice::Int mode, const Ice::Current & ice) { - TempPrivs tp(re, root); + ModeCheck mc(re, root); errno = 0; boost::filesystem::path p(resolvePath(path)); - tp.AssertWrite(p.parent_path()); + mc.AssertWrite(p.parent_path()); int fd = ::open(p.string().c_str(), O_CREAT | flags, mode); if (fd == -1) { throw NetFS::SystemError(errno); } - if (fchown(fd, tp.myu, tp.myg) != 0) { + if (fchown(fd, mc.myu, mc.myg) != 0) { ::close(fd); ::unlink(p.string().c_str()); throw NetFS::SystemError(errno); @@ -281,10 +281,10 @@ VolumeServer::create(const NetFS::ReqEnv & re, const std::string & path, Ice::In NetFS::DirectoryPrx VolumeServer::opendir(const NetFS::ReqEnv & re, const std::string & path, const Ice::Current & ice) { - TempPrivs tp(re, root); + ModeCheck mc(re, root); errno = 0; boost::filesystem::path p(resolvePath(path)); - tp.AssertRead(p); + mc.AssertRead(p); DIR * od = ::opendir(p.string().c_str()); if (!od) { throw NetFS::SystemError(errno); @@ -295,14 +295,14 @@ VolumeServer::opendir(const NetFS::ReqEnv & re, const std::string & path, const void VolumeServer::mkdir(const NetFS::ReqEnv & re, const std::string & path, Ice::Int mode, const Ice::Current&) { - TempPrivs tp(re, root); + ModeCheck mc(re, root); errno = 0; boost::filesystem::path p(resolvePath(path)); - tp.AssertWrite(p.parent_path()); + mc.AssertWrite(p.parent_path()); if (::mkdir(p.string().c_str(), mode) != 0) { throw NetFS::SystemError(errno); } - if (::chown(p.string().c_str(), tp.myu, tp.myg) != 0) { + if (::chown(p.string().c_str(), mc.myu, mc.myg) != 0) { ::rmdir(p.string().c_str()); throw NetFS::SystemError(errno); } @@ -311,11 +311,11 @@ VolumeServer::mkdir(const NetFS::ReqEnv & re, const std::string & path, Ice::Int void VolumeServer::rmdir(const NetFS::ReqEnv & re, const std::string & path, const Ice::Current&) { - TempPrivs tp(re, root); + ModeCheck mc(re, root); errno = 0; boost::filesystem::path p(resolvePath(path)); - tp.AssertWrite(p); - tp.AssertWrite(p.parent_path()); + mc.AssertWrite(p); + mc.AssertWrite(p.parent_path()); if (::rmdir(p.string().c_str()) != 0) { throw NetFS::SystemError(errno); } diff --git a/netfs/daemon/modeCheck.cpp b/netfs/daemon/modeCheck.cpp index 637abe3..2a928a1 100644 --- a/netfs/daemon/modeCheck.cpp +++ b/netfs/daemon/modeCheck.cpp @@ -1,9 +1,47 @@ #include "modeCheck.h" #include +#include #define us UserEntCache::instance #define gs GroupEntCache::instance +ModeCheck::ModeCheck(const NetFS::ReqEnv & re, const boost::filesystem::path & r) : + myu(UserEntCache::instance.getEntry(re.user)->id), + myg(GroupEntCache::instance.getEntry(re.grp)->id), + root(r) +{ +} + +void +ModeCheck::AssertRead(const boost::filesystem::path & p) const +{ + if (p != root) { + AssertRead(p.parent_path()); + } + struct stat s; + if (::lstat(p.string().c_str(), &s) != 0) { + throw NetFS::SystemError(errno); + } + if (!ModeCheck::ReadableBy(s, myu, myg)) { + throw NetFS::SystemError(EACCES); + } +} + +void +ModeCheck::AssertWrite(const boost::filesystem::path & p) const +{ + if (p != root) { + AssertRead(p.parent_path()); + } + struct stat s; + if (::lstat(p.string().c_str(), &s) != 0) { + throw NetFS::SystemError(errno); + } + if (!ModeCheck::WritableBy(s, myu, myg)) { + throw NetFS::SystemError(EACCES); + } +} + bool ModeCheck::ReadableBy(const struct stat & s, uid_t u, gid_t g) { diff --git a/netfs/daemon/modeCheck.h b/netfs/daemon/modeCheck.h index b3377bd..fae30d8 100644 --- a/netfs/daemon/modeCheck.h +++ b/netfs/daemon/modeCheck.h @@ -2,9 +2,20 @@ #define NETFS_DAEMON_IOHELPERS #include +#include +#include class ModeCheck { public: + ModeCheck(const NetFS::ReqEnv & re, const boost::filesystem::path &); + + void AssertRead(const boost::filesystem::path &) const; + void AssertWrite(const boost::filesystem::path &) const; + + const uid_t myu; + const gid_t myg; + const boost::filesystem::path & root; + static bool ReadableBy(const struct stat &, uid_t u, gid_t g); static bool WritableBy(const struct stat &, uid_t u, gid_t g); static bool ExecutableBy(const struct stat &, uid_t u, gid_t g); -- cgit v1.2.3