Update makeDir() to set owner, mode and ACLs.
authorFrantišek Dvořák <valtri@civ.zcu.cz>
Sat, 19 Oct 2013 19:15:59 +0000 (21:15 +0200)
committerFrantišek Dvořák <valtri@civ.zcu.cz>
Sun, 23 Feb 2014 13:16:19 +0000 (14:16 +0100)
src/VfsNs.cpp
src/VfsNs.h

index 2f22360..e18af57 100644 (file)
@@ -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);
index 9d602c7..ede8792 100644 (file)
@@ -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);