From 646e34045a174e90228e20ec40e2fb386ce083d0 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Franti=C5=A1ek=20Dvo=C5=99=C3=A1k?= Date: Mon, 9 Dec 2013 00:22:18 +0100 Subject: [PATCH] Look at replica status too in accessReplica(), catch EACCES in access(). --- src/VfsNs.cpp | 51 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/src/VfsNs.cpp b/src/VfsNs.cpp index 0f439c3..f7d5d1d 100644 --- a/src/VfsNs.cpp +++ b/src/VfsNs.cpp @@ -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) -- 1.8.2.3