From 5d3d376023351cc2ef2a885fb14ac4c2a244c6aa Mon Sep 17 00:00:00 2001 From: =?utf8?q?Franti=C5=A1ek=20Dvo=C5=99=C3=A1k?= Date: Sat, 19 Oct 2013 21:15:59 +0200 Subject: [PATCH] Update makeDir() to set owner, mode and ACLs. --- src/VfsNs.cpp | 41 +++++++++++++++++++++++++++-------------- src/VfsNs.h | 2 +- 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/src/VfsNs.cpp b/src/VfsNs.cpp index 2f22360..e18af57 100644 --- a/src/VfsNs.cpp +++ b/src/VfsNs.cpp @@ -586,7 +586,7 @@ void VfsCatalog::create(const std::string& path, mode_t mode) throw (DmException 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 { @@ -661,7 +661,7 @@ void VfsCatalog::setMode(const std::string& path, mode_t mode) throw (DmExceptio 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); } @@ -853,7 +853,7 @@ void VfsCatalog::setAcl(const std::string& path, const Acl& acl) throw (DmExcept 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); } @@ -1108,7 +1108,8 @@ ExtendedStat* VfsCatalog::readDirx(Directory* dir) throw (DmException) 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()); @@ -1125,17 +1126,29 @@ void VfsCatalog::makeDir(const std::string& path, mode_t mode) throw (DmExceptio 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); } @@ -1500,7 +1513,7 @@ bool VfsCatalog::vfsEvalRegex(regex_t *allowRegex, regex_t *denyRegex, const cha -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]; // @@ -1509,7 +1522,7 @@ void VfsCatalog::vfsSetMode(const std::string& path, const std::string& lpath, m // 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); diff --git a/src/VfsNs.h b/src/VfsNs.h index 9d602c7..ede8792 100644 --- a/src/VfsNs.h +++ b/src/VfsNs.h @@ -118,7 +118,7 @@ namespace dmlite { 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); -- 1.8.2.3