More verbose permission error messages.
authorFrantišek Dvořák <valtri@civ.zcu.cz>
Tue, 15 Oct 2013 11:16:54 +0000 (13:16 +0200)
committerFrantišek Dvořák <valtri@civ.zcu.cz>
Tue, 15 Oct 2013 11:16:54 +0000 (13:16 +0200)
src/VfsNs.cpp
src/VfsNs.h

index 08bc0a8..7308c8b 100644 (file)
@@ -92,6 +92,7 @@ void VfsCatalog::setSecurityContext(const SecurityContext* ctx) throw (DmExcepti
   secCtx_ = ctx;
   int ret;
 
+  this->clientName = subj;
   this->allowCurrent = false;
   if (this->allowRegex) {
     if ((ret = regexec(this->allowRegex, subj.c_str(), 0, NULL, 0)) == 0)
@@ -101,7 +102,7 @@ void VfsCatalog::setSecurityContext(const SecurityContext* ctx) throw (DmExcepti
   if (this->allowCurrent && this->denyRegex) {
     if ((ret = regexec(this->denyRegex, subj.c_str(), 0, NULL, 0)) == 0)
       this->allowCurrent = false;
-//fprintf(stderr, "'%s' %s deny regexp\n", subj.c_str(), ret == 0 ? "matches" : "not matches");
+//fprintf(stderr, "'%s' %s deny regexp\n", subj.c_str(), (ret == 0) ? "matches" : "not matches");
   }
 }
 
@@ -167,7 +168,7 @@ ExtendedStat VfsCatalog::extendedStat(const std::string& path, bool follow) thro
     meta = vfsExtendedStat(components[i], dir, true);
 
     if (checkPermissions(this->secCtx_, meta.acl, meta.stat, S_IEXEC) != 0)
-      vfsThrow(EACCES, "not enough permissions to list '%s'", meta.name.c_str());
+      vfsThrow(EACCES, "not enough permissions for '%s' to list '%s'", clientName.c_str(), meta.name.c_str());
   }
 
   meta = vfsExtendedStat(components.back(), path, follow);
@@ -258,7 +259,7 @@ std::vector<Replica> VfsCatalog::getReplicas(const std::string& path) throw (DmE
   ExtendedStat xStat = this->extendedStat(path, true);
 
   if (checkPermissions(this->secCtx_, xStat.acl, xStat.stat, S_IREAD) != 0)
-    vfsThrow(EACCES, "not enough permissions to read '%s'", path.c_str());
+    vfsThrow(EACCES, "not enough permissions for '%s' to read '%s'", clientName.c_str(), path.c_str());
 
   if (S_ISDIR(xStat.stat.st_mode))
     vfsThrow(EISDIR, "directories do not have replicas");
@@ -292,7 +293,7 @@ void VfsCatalog::symlink(const std::string& oldPath, const std::string& newPath)
   ExtendedStat parent = this->getParent(newPath, &parentPath, &symName);
 
   if (checkPermissions(this->secCtx_, parent.acl, parent.stat, S_IWRITE | S_IEXEC) != 0)
-    vfsThrow(EACCES, "not enough permissions on '%s'", parentPath.c_str());
+    vfsThrow(EACCES, "not enough permissions for '%s' on '%s'", clientName.c_str(), parentPath.c_str());
 
   wrapCall(::symlink(oldPath.c_str(), newPath.c_str()));
 }
@@ -305,7 +306,7 @@ std::string VfsCatalog::readLink(const std::string& path) throw (DmException)
   ExtendedStat meta = this->extendedStat(path, false);
 
   if (checkPermissions(this->secCtx_, meta.acl, meta.stat, S_IREAD) != 0)
-    vfsThrow(EACCES, "not enough permissions on '%s'", path.c_str());
+    vfsThrow(EACCES, "not enough permissions for '%s' on '%s'", clientName.c_str(), path.c_str());
 
   memset(buf, 0, sizeof(buf));
   wrapCall(readlink(path.c_str(), buf, sizeof(buf) - 1));
@@ -321,16 +322,16 @@ void VfsCatalog::unlink(const std::string& path) throw (DmException)
   ExtendedStat parent = this->getParent(path, &parentPath, &name);
 
   if (checkPermissions(this->secCtx_, parent.acl, parent.stat, S_IEXEC) != 0)
-    vfsThrow(EACCES, "not enough permissions on '%s' to list", parentPath.c_str());
+    vfsThrow(EACCES, "not enough permissions for '%s' on '%s' to list", clientName.c_str(), parentPath.c_str());
   if (checkPermissions(this->secCtx_, parent.acl, parent.stat, S_IWRITE) != 0)
-    vfsThrow(EACCES, "not enough permissions on '%s' to unlink '%s'", parentPath.c_str(), path.c_str());
+    vfsThrow(EACCES, "not enough permissions for '%s' on '%s' to unlink '%s'", clientName.c_str(), parentPath.c_str(), path.c_str());
 
   // Sticky bit set ==> only directory or file owner can delete
   if ((parent.stat.st_mode & S_ISVTX) == S_ISVTX) {
     ExtendedStat file = this->extendedStat(path);
     if (getUid(this->secCtx_) != file.stat.st_uid &&
         getUid(this->secCtx_) != parent.stat.st_uid) {
-      vfsThrow(EACCES, "not enough permissions to unlink '%s' (sticky bit set)", path.c_str());
+      vfsThrow(EACCES, "not enough permissions for '%s' to unlink '%s' (sticky bit set)", clientName.c_str(), path.c_str());
     }
   }
 
@@ -349,9 +350,9 @@ void VfsCatalog::create(const std::string& path, mode_t mode) throw (DmException
   ExtendedStat parent = this->getParent(path, &parentPath, &name);
 
   if (checkPermissions(this->secCtx_, parent.acl, parent.stat, S_IEXEC) != 0)
-    vfsThrow(EACCES, "not enough permissions on '%s' to list", parentPath.c_str());
+    vfsThrow(EACCES, "not enough permissions for '%s' on '%s' to list", clientName.c_str(), parentPath.c_str());
   if (checkPermissions(this->secCtx_, parent.acl, parent.stat, S_IWRITE) != 0)
-    vfsThrow(EACCES, "need write access on '%s' to create '%s'", parentPath.c_str(), path.c_str());
+    vfsThrow(EACCES, "need write access for '%s' on '%s' to create '%s'", clientName.c_str(), parentPath.c_str(), path.c_str());
 
   try {
     file = this->extendedStat(path);
@@ -385,7 +386,7 @@ void VfsCatalog::create(const std::string& path, mode_t mode) throw (DmException
       vfsThrow(EISDIR, "'%s' is directory, can not truncate", path.c_str());
     if (getUid(this->secCtx_) != file.stat.st_uid &&
        checkPermissions(this->secCtx_, file.acl, file.stat, S_IWRITE) != 0) {
-      vfsThrow(EACCES, "not enough permissions to truncate '%s'", path.c_str());
+      vfsThrow(EACCES, "not enough permissions for '%s' to truncate '%s'", clientName.c_str(), path.c_str());
     }
     wrapCall(truncate(path.c_str(), 0));
   }
@@ -409,7 +410,7 @@ void VfsCatalog::setMode(const std::string& path, mode_t mode) throw (DmExceptio
   // User has to be the owner, or root
   if (getUid(this->secCtx_) != meta.stat.st_uid &&
       getUid(this->secCtx_) != 0) {
-    vfsThrow(EACCES, "only the owner or root can set the mode of '%s'", path.c_str());
+    vfsThrow(EACCES, "'%s' neither owner nor root, setting the mode of '%s' rejected", clientName.c_str(), path.c_str());
   }
   // Clean up unwanted bits
   mode &= ~S_IFMT;
@@ -438,7 +439,7 @@ void VfsCatalog::setSize(const std::string& path, size_t newSize) throw (DmExcep
     vfsThrow(EISDIR, "'%s' is directory, can not truncate", path.c_str());
   if (getUid(this->secCtx_) != file.stat.st_uid &&
      checkPermissions(this->secCtx_, file.acl, file.stat, S_IWRITE) != 0) {
-    vfsThrow(EACCES, "not enough permissions to truncate '%s'", path.c_str());
+    vfsThrow(EACCES, "not enough permissions for '%s' to truncate '%s'", clientName.c_str(), path.c_str());
   }
   wrapCall(truncate(path.c_str(), newSize));
 }
@@ -467,7 +468,7 @@ void VfsCatalog::utime(const std::string& path, const struct utimbuf* buf) throw
 
   if (getUid(this->secCtx_) != meta.stat.st_uid &&
       checkPermissions(this->secCtx_, meta.acl, meta.stat, S_IWRITE) != 0) {
-    vfsThrow(EACCES, "not enough permissions to modify the time of '%s'", path.c_str());
+    vfsThrow(EACCES, "not enough permissions for '%s' to modify the time of '%s'", clientName.c_str(), path.c_str());
   }
 
   wrapCall(::utime(path.c_str(), buf));
@@ -517,7 +518,7 @@ Directory* VfsCatalog::openDir(const std::string& path) throw (DmException)
   try {
     meta = this->extendedStat(path);
     if (checkPermissions(this->secCtx_, meta.acl, meta.stat, S_IREAD) != 0)
-      vfsThrow(EACCES, "not enough permissions to read '%s'", path.c_str());
+      vfsThrow(EACCES, "not enough permissions for '%s' to read '%s'", clientName.c_str(), path.c_str());
 
     privateDir->path = path;
     privateDir->dir  = opendir(path.c_str());
@@ -592,9 +593,9 @@ void VfsCatalog::makeDir(const std::string& path, mode_t mode) throw (DmExceptio
   ExtendedStat parent = this->getParent(path, &parentPath, &name);
 
   if (checkPermissions(this->secCtx_, parent.acl, parent.stat, S_IEXEC) != 0)
-    vfsThrow(EACCES, "not enough permissions on '%s' to list", parentPath.c_str());
+    vfsThrow(EACCES, "not enough permissions for '%s' on '%s' to list", clientName.c_str(), parentPath.c_str());
   if (checkPermissions(this->secCtx_, parent.acl, parent.stat, S_IWRITE) != 0)
-    vfsThrow(EACCES, "need write access on '%s' to create directory '%s'", parentPath.c_str(), name.c_str());
+    vfsThrow(EACCES, "need write access for '%s' on '%s' to create directory '%s'", clientName.c_str(), parentPath.c_str(), name.c_str());
 
   // Clean up unwanted bits
   mode &= ~S_IFMT;
@@ -615,9 +616,9 @@ void VfsCatalog::rename(const std::string& oldPath, const std::string& newPath)
   ExtendedStat oldParent = this->getParent(oldPath, &oldParentPath, &oldName);
   ExtendedStat newParent = this->getParent(newPath, &oldParentPath, &newName);
   if (checkPermissions(this->secCtx_, oldParent.acl, oldParent.stat, S_IWRITE) != 0)
-    vfsThrow(EACCES, "Not enough permissions on origin '%s'", oldPath.c_str());
+    vfsThrow(EACCES, "Not enough permissions for '%s' on origin '%s'", clientName.c_str(), oldPath.c_str());
   if (checkPermissions(this->secCtx_, newParent.acl, newParent.stat, S_IWRITE) != 0)
-    vfsThrow(EACCES, "Not enough permissions on destination '%s'", newPath.c_str());
+    vfsThrow(EACCES, "Not enough permissions for '%s' on destination '%s'", clientName.c_str(), newPath.c_str());
 
   // Check sticky
   if (oldParent.stat.st_mode & S_ISVTX) {
@@ -625,7 +626,7 @@ void VfsCatalog::rename(const std::string& oldPath, const std::string& newPath)
     if (getUid(this->secCtx_) != oldParent.stat.st_uid &&
         getUid(this->secCtx_) != old.stat.st_uid &&
         checkPermissions(this->secCtx_, old.acl, old.stat, S_IWRITE) != 0)
-       vfsThrow(EACCES, "not enough permissions (sticky bit set on parent '%s')", oldParentPath.c_str());
+       vfsThrow(EACCES, "not enough permissions for '%s' (sticky bit set on parent '%s')", clientName.c_str(), oldParentPath.c_str());
   }
 
   // XXX: test-rename should probably accept both ENOTEMPTY and EEXIST instead
@@ -655,11 +656,11 @@ void VfsCatalog::removeDir(const std::string& path) throw (DmException)
     if (getUid(this->secCtx_) != entry.stat.st_uid &&
         getUid(this->secCtx_) != parent.stat.st_uid &&
         checkPermissions(this->secCtx_, entry.acl, entry.stat, S_IWRITE) != 0)
-      vfsThrow(EACCES, "not enough permissions to remove '%s' (sticky bit set)", path.c_str());
+      vfsThrow(EACCES, "not enough permissions for '%s' to remove '%s' (sticky bit set)", clientName.c_str(), path.c_str());
   } else {
     // No sticky bit
     if (checkPermissions(this->secCtx_, parent.acl, parent.stat, S_IWRITE) != 0)
-      vfsThrow(EACCES, "not enough permissions to remove '%s'", path.c_str());
+      vfsThrow(EACCES, "not enough permissions for '%s' to remove '%s'", clientName.c_str(), path.c_str());
   }
 
   // check if we are not removing current working directory
index 2ab57d4..3d8c72b 100644 (file)
@@ -112,6 +112,7 @@ namespace dmlite {
 
     regex_t *allowRegex, *denyRegex;
     bool allowCurrent;
+    std::string clientName;
   };
 
 };