wrapCall(f = fopen(lpath.c_str(), "w"));
wrapCall(fclose(f));
vfsSetOwner(path, lpath, getUid(this->secCtx_), egid, true);
- vfsSetMode(path, lpath, mode);
+ vfsSetMode(path, lpath, mode, false);
if (!newAcl.empty())
vfsSetAcl(path, lpath, newAcl);
} else {
lpath = getLocalPath(path);
- vfsSetMode(path, lpath, mode);
+ vfsSetMode(path, lpath, mode, S_ISDIR(meta.stat.st_mode));
if (!meta.acl.empty())
vfsSetAcl(path, lpath, meta.acl);
}
lpath = getLocalPath(path);
- vfsSetMode(path, lpath, meta.stat.st_mode);
+ vfsSetMode(path, lpath, meta.stat.st_mode, S_ISDIR(meta.stat.st_mode));
vfsSetAcl(path, lpath, aclCopy);
}
void VfsCatalog::makeDir(const std::string& path, mode_t mode) throw (DmException)
{
std::string lpath, parentPath, name;
- char buf[20];
+ gid_t egid;
+ Acl newAcl;
if (vfsCheckPermissions(path, S_IWRITE))
vfsThrow(EACCES, "not enough permissions for '%s'", clientName.c_str());
lpath = getLocalPath(path);
- // Clean up unwanted bits
- mode &= ~S_IFMT;
- mode |= S_IFDIR;
- // TODO: S_ISGID
- // TODO: inherit default ACL
+ // Clean up unwanted bits, set bits
+ mode = (mode & ~S_IFMT) | S_IFDIR;
+
+ // Effective gid
+ if (parent.stat.st_mode & S_ISGID) {
+ egid = parent.stat.st_gid;
+ mode |= S_ISGID;
+ }
+ else {
+ egid = getGid(this->secCtx_);
+ }
+
+ // Generate inherited ACL's if there are defaults
+ if (parent.acl.has(AclEntry::kDefault | AclEntry::kUserObj) != -1)
+ newAcl = Acl(parent.acl, getUid(this->secCtx_), egid, mode, &mode);
// Keep read/write for owner in the mode
- wrapCall(mkdir(lpath.c_str(), mode | S_IRUSR | S_IWUSR));
+ wrapCall(mkdir(lpath.c_str(), mode | S_IRUSR | S_IWUSR | S_IXUSR));
- snprintf(buf, sizeof buf, "%04o", mode);
- vfsSetXattr(path, lpath, VFS_XATTR "mode", buf, 0);
+ vfsSetMode(path, lpath, mode, true);
+ vfsSetOwner(path, lpath, getUid(this->secCtx_), egid, true);
+ if (!newAcl.empty())
+ vfsSetAcl(path, lpath, newAcl);
}
-void VfsCatalog::vfsSetMode(const std::string& path, const std::string& lpath, mode_t mode) throw (DmException) {
+void VfsCatalog::vfsSetMode(const std::string& path, const std::string& lpath, mode_t mode, bool dir) throw (DmException) {
char buf[20];
//
// 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());
+ wrapCall(chmod(lpath.c_str(), mode | S_IRUSR | S_IWUSR | (dir ? S_IXUSR : 0)), "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);
+ void vfsSetMode(const std::string& path, const std::string& lpath, mode_t mode, bool dir) throw (DmException);
void vfsSetOwner(const std::string& path, const std::string& lpath, uid_t newUid, gid_t newGid, bool followSymLink) throw (DmException);
void vfsSetOwner(const std::string& path, const std::string& lpath, const ExtendedStat& meta, uid_t newUid, gid_t newGid, bool followSymLink) throw (DmException);
void vfsSetAcl(const std::string& path, const std::string& lpath, Acl acl) throw (DmException);