diff options
| -rw-r--r-- | netfs/daemon/daemon.cpp | 37 | ||||
| -rw-r--r-- | netfs/daemon/daemon.h | 13 | ||||
| -rw-r--r-- | netfs/daemon/daemonVolume.cpp | 94 | ||||
| -rw-r--r-- | netfs/daemon/modeCheck.cpp | 38 | ||||
| -rw-r--r-- | 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 <Ice/Ice.h>  #include <IceBox/IceBox.h>  #include <daemonConfig.h> -#include <types.h>  #include <boost/filesystem/path.hpp>  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 <entCache.h> +#include <exceptions.h>  #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 <sys/stat.h> +#include <types.h> +#include <boost/filesystem/path.hpp>  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); | 
