summaryrefslogtreecommitdiff
path: root/netfs/daemon/daemonVolume.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'netfs/daemon/daemonVolume.cpp')
-rw-r--r--netfs/daemon/daemonVolume.cpp50
1 files changed, 34 insertions, 16 deletions
diff --git a/netfs/daemon/daemonVolume.cpp b/netfs/daemon/daemonVolume.cpp
index a84c2e1..2d67272 100644
--- a/netfs/daemon/daemonVolume.cpp
+++ b/netfs/daemon/daemonVolume.cpp
@@ -48,7 +48,7 @@ VolumeServer::access(const NetFS::ReqEnv & re, const std::string & path, Ice::In
// stat succeeded, file must exist
return 0;
}
- mc.AssertRead(p.parent_path());
+ mc.AssertReadParent(p);
if (mode & R_OK && !mc.ReadableBy(s, mc.myu, mc.myg)) {
return EACCES;
}
@@ -67,7 +67,7 @@ VolumeServer::getattr(const NetFS::ReqEnv & re, const std::string & path, const
ModeCheck mc(re, root, userLookup, groupLookup);
struct stat s;
boost::filesystem::path p(resolvePath(path));
- mc.AssertRead(p.parent_path());
+ mc.AssertReadParent(p);
if (::lstat(p.c_str(), &s) != 0) {
throw NetFS::SystemError(errno);
}
@@ -82,7 +82,7 @@ VolumeServer::mknod(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.parent_path());
+ mc.AssertWriteParent(p);
if (::mknod(p.c_str(), mode, dev) != 0) {
throw NetFS::SystemError(errno);
}
@@ -94,7 +94,7 @@ VolumeServer::symlink(const NetFS::ReqEnv & re, const std::string & path1, const
ModeCheck mc(re, root, userLookup, groupLookup);
errno = 0;
boost::filesystem::path p(resolvePath(path2));
- mc.AssertWrite(p.parent_path());
+ mc.AssertWriteParent(p);
if (::symlink(path1.c_str(), p.c_str()) != 0) {
throw NetFS::SystemError(errno);
}
@@ -127,13 +127,13 @@ VolumeServer::rename(const NetFS::ReqEnv & re, const std::string & from, const s
errno = 0;
boost::filesystem::path f(resolvePath(from));
boost::filesystem::path t(resolvePath(to));
- mc.AssertWrite(f.parent_path());
+ mc.AssertWriteParent(f);
mc.AssertWrite(f);
if (boost::filesystem::is_directory(t)) {
mc.AssertWrite(t);
}
else {
- mc.AssertWrite(t.parent_path());
+ mc.AssertWriteParent(t);
}
if (::rename(f.c_str(), t.c_str()) != 0) {
throw NetFS::SystemError(errno);
@@ -232,7 +232,7 @@ VolumeServer::unlink(const NetFS::ReqEnv & re, const std::string & path, const I
errno = 0;
boost::filesystem::path p(resolvePath(path));
mc.AssertWrite(p);
- mc.AssertWrite(p.parent_path());
+ mc.AssertWriteParent(p);
if (::unlink(p.c_str()) != 0) {
throw NetFS::SystemError(errno);
}
@@ -261,7 +261,7 @@ VolumeServer::create(const NetFS::ReqEnv & re, const std::string & path, Ice::In
ModeCheck mc(re, root, userLookup, groupLookup);
errno = 0;
boost::filesystem::path p(resolvePath(path));
- mc.AssertWrite(p.parent_path());
+ mc.AssertWriteParent(p);
int fd = ::open(p.c_str(), O_CREAT | flags, mode);
if (fd == -1) {
throw NetFS::SystemError(errno);
@@ -294,7 +294,7 @@ VolumeServer::mkdir(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.parent_path());
+ mc.AssertWriteParent(p);
if (::mkdir(p.c_str(), mode) != 0) {
throw NetFS::SystemError(errno);
}
@@ -311,20 +311,38 @@ VolumeServer::rmdir(const NetFS::ReqEnv & re, const std::string & path, const Ic
errno = 0;
boost::filesystem::path p(resolvePath(path));
mc.AssertWrite(p);
- mc.AssertWrite(p.parent_path());
+ mc.AssertWriteParent(p);
if (::rmdir(p.c_str()) != 0) {
throw NetFS::SystemError(errno);
}
}
boost::filesystem::path
-VolumeServer::resolvePath(const std::string & path) const
+normalizedAppend(boost::filesystem::path out, const boost::filesystem::path & in)
{
- Lock(lock);
- auto p((root / path).normalize());
- if (!boost::algorithm::starts_with(p.string(), root.string())) {
- throw NetFS::SystemError(EPERM);
+ unsigned int depth = 0;
+ for(auto e : in) {
+ if (e.empty() || e == "." || e == "/") {
+ continue;
+ }
+ else if (e == "..") {
+ if (depth == 0) {
+ throw NetFS::SystemError(EPERM);
+ }
+ out.remove_leaf();
+ depth -= 1;
+ }
+ else {
+ out /= e;
+ depth += 1;
+ }
}
- return p;
+ return out;
+}
+
+boost::filesystem::path
+VolumeServer::resolvePath(const std::string & path) const
+{
+ return normalizedAppend(root, path);
}