Look at replica status too in accessReplica(), catch EACCES in access().
authorFrantišek Dvořák <valtri@civ.zcu.cz>
Sun, 8 Dec 2013 23:22:18 +0000 (00:22 +0100)
committerFrantišek Dvořák <valtri@civ.zcu.cz>
Mon, 9 Dec 2013 21:42:10 +0000 (22:42 +0100)
src/VfsNs.cpp

index 0f439c3..f7d5d1d 100644 (file)
@@ -477,28 +477,33 @@ bool VfsCatalog::access(const std::string& path, int mode) throw (DmException)
   ExtendedStat meta;
   mode_t perm;
 
-  if (vfsCheckPermissions(path, S_IREAD))
-    vfsThrow(EACCES, "not enough permissions for '%s'", clientName.c_str());
-
   try {
+    if (vfsCheckPermissions(path, S_IREAD))
+      vfsThrow(EACCES, "not enough permissions for '%s'", clientName.c_str());
+
     meta = this->vfsExtendedStat(path);
 
     perm = 0;
     if (mode & R_OK) perm  = S_IREAD;
     if (mode & W_OK) perm |= S_IWRITE;
     if (mode & X_OK) perm |= S_IEXEC;
+
+    if (checkPermissions(this->secCtx_, meta.acl, meta.stat, perm) != 0) return false;
   } catch (DmException& e) {
-    if (e.code() == ENOENT) {
-      // throw exeption up only if there was not requested test for existence (F_OK)
-      if (mode & F_OK) return false;
-      else throw DmException(DMLITE_NO_SUCH_REPLICA, e.what());
-    } else {
-      throw;
+    switch (e.code()) {
+      case ENOENT:
+        // throw exeption up only if there was not requested test for existence (F_OK)
+        if (mode & F_OK) return false;
+        else throw DmException(DMLITE_NO_SUCH_REPLICA, e.what());
+        break;
+      case EACCES:
+        return false;
+        break;
+      default:
+        throw;
     }
   }
 
-  if (checkPermissions(this->secCtx_, meta.acl, meta.stat, perm) != 0) return false;
-
   if (::access(getLocalPath(path).c_str(), mode) == -1) {
     if (errno == ENOENT) {
       // stat() performed OK, but access() failed with ENOENT
@@ -511,12 +516,28 @@ bool VfsCatalog::access(const std::string& path, int mode) throw (DmException)
 }
 
 
-bool VfsCatalog::accessReplica(const std::string& replica, int mode) throw (DmException)
+bool VfsCatalog::accessReplica(const std::string& rfn, int mode) throw (DmException)
 {
   std::string path;
+  Replica replica;
+  bool metaAllowed, replicaAllowed;
+
+  try {
+    replica = this->getReplicaByRFN(rfn);
+    if (mode & W_OK) {
+      replicaAllowed = (replica.status == Replica::kBeingPopulated);
+    } else {
+      replicaAllowed = true;
+    }
+
+    path = vfsPathByRFN(rfn);
+    metaAllowed = this->access(path, mode);
 
-  path = vfsPathByRFN(replica);
-  return this->access(path, mode);
+    return metaAllowed && replicaAllowed;
+  } catch (DmException& e) {
+    if (e.code() != EACCES) throw;
+    return false;
+  }
 }
 
 
@@ -1532,7 +1553,7 @@ Replica VfsCatalog::getReplicaByRFN(const std::string& rfn) throw (DmException)
 
   return replica;
 }
-        
+
 
 
 void VfsCatalog::updateReplica(const Replica& replica) throw (DmException)