void VfsCatalog::setMode(const std::string& path, mode_t mode) throw (DmException)
{
ExtendedStat meta;
- char buf[20];
if (vfsCheckPermissions(path, S_IWRITE))
vfsThrow(EACCES, "not enough permissions for '%s'", clientName.c_str());
// Clean up unwanted bits (keep type, read/write for owner, correct sticky bit)
mode &= ~S_IFMT;
mode |= (meta.stat.st_mode & S_IFMT);
+ if (!S_ISDIR(meta.stat.st_mode) && getUid(this->secCtx_) != 0)
+ mode &= ~S_ISVTX;
if (getUid(this->secCtx_) != 0 &&
!hasGroup(this->secCtx_->groups, meta.stat.st_gid))
mode &= ~S_ISGID;
- //
- // Set the mode on the filesystem
- //
- // But keep read/write for owner.
- // Filesystem mode couldn't be needed, but let's set it anyway.
- //
- wrapCall(chmod(getLocalPath(path).c_str(), mode | S_IRUSR | S_IWUSR));
+ // TODO: update ACL, setAcl().
- snprintf(buf, sizeof buf, "%04o", mode);
- vfsSetXattr(path, getLocalPath(path), VFS_XATTR "mode", buf, 0);
+ vfsSetMode(path, getLocalPath(path), mode);
}
return allow;
}
+
+
+
+void VfsCatalog::vfsSetMode(const std::string& path, const std::string& lpath, mode_t mode) throw (DmException) {
+ char buf[20];
+
+ //
+ // Set the mode on the filesystem
+ //
+ // But keep read/write for owner.
+ // Filesystem mode couldn't be needed, but let's set it anyway.
+ //
+ wrapCall(chmod(lpath.c_str(), mode | S_IRUSR | S_IWUSR), "could not set mode on '%s' on the filesystem", path.c_str());
+
+ snprintf(buf, sizeof buf, "%04o", mode);
+ vfsSetXattr(path, lpath, VFS_XATTR "mode", buf, 0);
+}
regex_t *vfsCompileRegex(const char *name, const std::string value) throw (DmException);
bool vfsEvalRegex(regex_t *allowRegex, regex_t *denyRegex, const char *subj);
int vfsCheckPermissions(const std::string& path, mode_t mode);
+ void vfsSetMode(const std::string& path, const std::string& lpath, mode_t mode) throw (DmException);
StackInstance* si_;
const SecurityContext* secCtx_;