ExtendedStat meta;
std::string lpath;
+ if (vfsCheckPermissions(path, S_IEXEC | S_IREAD))
+ vfsThrow(EACCES, "not enough permissions for '%s'", clientName.c_str());
+
meta = this->extendedStat(path);
if (checkPermissions(this->secCtx_, meta.acl, meta.stat, S_IEXEC | S_IREAD) != 0)
vfsThrow(EACCES, "not enough permissions for '%s' on '%s'", clientName.c_str(), meta.name.c_str());
char buffer[1024];
size_t len;
+ if (vfsCheckPermissions("", S_IREAD))
+ vfsThrow(EACCES, "not enough permissions for '%s'", clientName.c_str());
+
wrapCall(getcwd(buffer, sizeof(buffer)));
len = strlen(buffer);
ExtendedStat meta;
Extensible xattrs;
+ if (vfsCheckPermissions(path, S_IREAD))
+ vfsThrow(EACCES, "not enough permissions for '%s'", clientName.c_str());
+
meta = vfsExtendedStat(path, follow);
// not require working xattrs
ExtendedStat meta;
mode_t perm;
+ if (vfsCheckPermissions(path, S_IREAD))
+ vfsThrow(EACCES, "not enough permissions for '%s'", clientName.c_str());
+
try {
meta = this->extendedStat(path);
std::vector<Replica> VfsCatalog::getReplicas(const std::string& path) throw (DmException)
{
Replica replica;
- ExtendedStat xStat = this->extendedStat(path, true);
+ ExtendedStat xStat;
+ if (vfsCheckPermissions(path, S_IREAD))
+ vfsThrow(EACCES, "not enough permissions for '%s'", clientName.c_str());
+
+ xStat = this->extendedStat(path, true);
if (checkPermissions(this->secCtx_, xStat.acl, xStat.stat, S_IREAD) != 0)
vfsThrow(EACCES, "not enough permissions for '%s' to read '%s'", clientName.c_str(), path.c_str());
void VfsCatalog::symlink(const std::string& oldPath, const std::string& newPath) throw (DmException)
{
std::string parentPath, symName;
+ ExtendedStat parent;
- ExtendedStat parent = this->getParent(newPath, &parentPath, &symName);
+ if (vfsCheckPermissions(oldPath, S_IWRITE) ||
+ vfsCheckPermissions(newPath, S_IWRITE))
+ vfsThrow(EACCES, "not enough permissions for '%s'", clientName.c_str());
+ parent = this->getParent(newPath, &parentPath, &symName);
if (checkPermissions(this->secCtx_, parent.acl, parent.stat, S_IWRITE | S_IEXEC) != 0)
vfsThrow(EACCES, "not enough permissions for '%s' on '%s'", clientName.c_str(), parentPath.c_str());
std::string VfsCatalog::readLink(const std::string& path) throw (DmException)
{
- ExtendedStat meta = this->extendedStat(path, false);
+ ExtendedStat meta;
char *buf;
+ if (vfsCheckPermissions(path, S_IREAD))
+ vfsThrow(EACCES, "not enough permissions for '%s'", clientName.c_str());
+
+ meta = this->vfsExtendedStat(path, false);
if (checkPermissions(this->secCtx_, meta.acl, meta.stat, S_IREAD) != 0)
vfsThrow(EACCES, "not enough permissions for '%s' on '%s'", clientName.c_str(), path.c_str());
{
std::string parentPath, name;
+ if (vfsCheckPermissions(path, S_IWRITE))
+ vfsThrow(EACCES, "not enough permissions for '%s'", clientName.c_str());
+
ExtendedStat parent = this->getParent(path, &parentPath, &name);
if (checkPermissions(this->secCtx_, parent.acl, parent.stat, S_IEXEC) != 0)
int code = DMLITE_SUCCESS;
ExtendedStat file;
+ if (vfsCheckPermissions(path, S_IWRITE))
+ vfsThrow(EACCES, "not enough permissions for '%s'", clientName.c_str());
+
ExtendedStat parent = this->getParent(path, &parentPath, &name);
if (checkPermissions(this->secCtx_, parent.acl, parent.stat, S_IEXEC) != 0)
mode_t VfsCatalog::umask(mode_t mask) throw ()
{
+ if (vfsCheckPermissions("", S_IREAD))
+ vfsThrow(EACCES, "not enough permissions for '%s'", clientName.c_str());
+
return ::umask(mask);
}
{
ExtendedStat meta;
- if (!this->allowWriteCurrent)
- vfsThrow(EACCES, "not enough permissions for '%s' to setting mode", clientName.c_str());
+ if (vfsCheckPermissions(path, S_IWRITE))
+ vfsThrow(EACCES, "not enough permissions for '%s'", clientName.c_str());
- meta = this->extendedStat(path);
+ meta = this->vfsExtendedStat(path, true);
// User has to be the owner, or root
if (getUid(this->secCtx_) != meta.stat.st_uid &&
void VfsCatalog::setSize(const std::string& path, size_t newSize) throw (DmException)
{
- ExtendedStat file = this->extendedStat(path);
+ ExtendedStat file;
+ if (vfsCheckPermissions(path, S_IWRITE))
+ vfsThrow(EACCES, "not enough permissions for '%s'", clientName.c_str());
+
+ file = this->extendedStat(path);
if (S_ISDIR(file.stat.st_mode))
vfsThrow(EISDIR, "'%s' is directory, can not truncate", path.c_str());
if (getUid(this->secCtx_) != file.stat.st_uid &&
void VfsCatalog::utime(const std::string& path, const struct utimbuf* buf) throw (DmException)
{
- ExtendedStat meta = this->extendedStat(path);
+ ExtendedStat meta;
+ if (vfsCheckPermissions(path, S_IWRITE))
+ vfsThrow(EACCES, "not enough permissions for '%s'", clientName.c_str());
+
+ meta = this->extendedStat(path);
if (getUid(this->secCtx_) != meta.stat.st_uid &&
checkPermissions(this->secCtx_, meta.acl, meta.stat, S_IWRITE) != 0) {
vfsThrow(EACCES, "not enough permissions for '%s' to modify the time of '%s'", clientName.c_str(), path.c_str());
std::string key, value, oldvalue;
std::string lpath;
+ if (vfsCheckPermissions(path, S_IWRITE))
+ vfsThrow(EACCES, "not enough permissions for '%s'", clientName.c_str());
+
meta = this->extendedStat(path, true);
if (checkPermissions(this->secCtx_, meta.acl, meta.stat, S_IWRITE) != 0)
vfsThrow(EACCES, "not enough permissions for '%s' to change attributes on '%s'", clientName.c_str(), path.c_str());
ExtendedStat meta;
std::string lpath;
+ if (vfsCheckPermissions(path, S_IREAD))
+ vfsThrow(EACCES, "not enough permissions for '%s'", clientName.c_str());
+
meta = this->extendedStat(path);
if (checkPermissions(this->secCtx_, meta.acl, meta.stat, S_IREAD) != 0)
vfsThrow(EACCES, "not enough permissions for '%s' to read '%s'", clientName.c_str(), path.c_str());
{
std::string parentPath, name;
+ if (vfsCheckPermissions(path, S_IWRITE))
+ vfsThrow(EACCES, "not enough permissions for '%s'", clientName.c_str());
+
if (path.empty())
vfsThrow(EINVAL, "empty directory name");
{
std::string oldParentPath, newParentPath, oldName, newName;
+ if (vfsCheckPermissions(oldPath, S_IWRITE) ||
+ vfsCheckPermissions(newPath, S_IWRITE))
+ vfsThrow(EACCES, "not enough permissions for '%s'", clientName.c_str());
+
if (oldPath == "/" || newPath == "/")
vfsThrow(EINVAL, "not the source, neither the destination, can be '/'");
char *cwd = NULL, *rmd = NULL;
std::string parentPath, name;
+ if (vfsCheckPermissions(path, S_IWRITE))
+ vfsThrow(EACCES, "not enough permissions for '%s'", clientName.c_str());
+
if (path == "/")
vfsThrow(EINVAL, "can not remove '/'");
Replica replica;
struct stat fstat;
+ if (vfsCheckPermissions(rfn, S_IREAD))
+ vfsThrow(EACCES, "not enough permissions for '%s'", clientName.c_str());
+
wrapCall(stat(getLocalPath(rfn).c_str(), &fstat));
replica.atime = fstat.st_atime;
-int VfsCatalog::checkPermissions(const SecurityContext *context, const Acl &acl, const struct stat &stat, mode_t mode) {
-//fprintf(stderr, "VfsCatalog::checkPermissions(inode %lu, %04o)\n", stat.st_ino, mode);
+///
+/// Basic permissions check, to be called before stat().
+///
+int VfsCatalog::vfsCheckPermissions(const std::string& path, mode_t mode) {
+ int ret = 1;
+
if (this->allowCurrent) {
- if ((mode & S_IWRITE) != 0) return this->allowWriteCurrent ? 0 : 1;
+ if ((mode & S_IWRITE) != 0) ret = this->allowWriteCurrent ? 0 : 1;
else return 0;
- } else {
- return 1;
}
+
+ return ret;
}
+
+///
+/// override all permission checks - no file-level permissions in zero version
+///
+int VfsCatalog::checkPermissions(const SecurityContext *context, const Acl &acl, const struct stat &stat, mode_t mode) {
+ return 0;
+}
+
+
+
Extensible VfsCatalog::vfsGetXattrs(const std::string& path, const std::string& lpath, bool follow) throw (DmException) {
int len;
std::string attrValue;