}
-VfsCatalog::VfsCatalog(const std::string& host, const std::string& prefix, const std::string &allow, const std::string &deny) throw (DmException): Catalog(),
+
+VfsCatalog::VfsCatalog(const std::string& host, const std::string& prefix, const std::string &allow, const std::string &deny, const std::string allowWrite, const std::string denyWrite) throw (DmException): Catalog(),
hostName_(host), prefix_(prefix)
{
- regex_t regex;
- int ret;
- char buf[256];
-
- this->allowRegex = 0;
- if (!allow.empty()) {
-//fprintf(stderr, "allow regex: '%s'\n", allow.c_str());
- if ((ret = regcomp(®ex, allow.c_str(), REG_EXTENDED | REG_NOSUB)) != 0) {
- regerror(ret, ®ex, buf, sizeof buf);
- vfsThrow(EINVAL, "invalid regular expresion for 'Allow': %s", buf);
- }
- this->allowRegex = new regex_t(regex);
- }
- this->denyRegex = 0;
- if (!deny.empty()) {
-//fprintf(stderr, "deny regex: '%s'\n", deny.c_str());
- if ((ret = regcomp(®ex, deny.c_str(), REG_EXTENDED | REG_NOSUB)) != 0)
- vfsThrow(EINVAL, "invalid regular expresion for 'Deny': %s", buf);
- this->denyRegex = new regex_t(regex);
- }
+ this->allowRegex = vfsCompileRegex("Allow", allow);
+ this->denyRegex = vfsCompileRegex("Deny", deny);
+ this->allowWriteRegex = vfsCompileRegex("AllowWrite", allowWrite);
+ this->denyWriteRegex = vfsCompileRegex("DenyWrite", denyWrite);
if (prefix.empty()) this->prefix_ = "";
}
regfree(this->denyRegex);
delete this->denyRegex;
}
+ if (this->allowWriteRegex) {
+ regfree(this->allowWriteRegex);
+ delete this->allowWriteRegex;
+ }
+ if (this->denyWriteRegex) {
+ regfree(this->denyWriteRegex);
+ delete this->denyWriteRegex;
+ }
}
{
std::string subj = ctx->credentials.clientName;
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)
- this->allowCurrent = true;
-//fprintf(stderr, "'%s' %s allow regexp\n", subj.c_str(), ((ret == 0) ? "matches" : "not matches"));
- }
- 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");
- }
+
+ this->allowCurrent = vfsEvalRegex(this->allowRegex, this->denyRegex, subj.c_str());
+ this->allowWriteCurrent = vfsEvalRegex(this->allowWriteRegex, this->denyWriteRegex, subj.c_str());
}
void VfsCatalog::setMode(const std::string& path, mode_t mode) throw (DmException)
{
- ExtendedStat meta = this->extendedStat(path);
+ ExtendedStat meta;
+
+ if (!this->allowWriteCurrent)
+ vfsThrow(EACCES, "not enough permissions for '%s' to setting mode", clientName.c_str());
+
+ meta = this->extendedStat(path);
// User has to be the owner, or root
if (getUid(this->secCtx_) != meta.stat.st_uid &&
int VfsCatalog::checkPermissions(const SecurityContext *context, const Acl &acl, const struct stat &stat, mode_t mode) {
//fprintf(stderr, "VfsCatalog::checkPermissions(inode %lu, %04o)\n", stat.st_ino, mode);
- return this->allowCurrent ? 0 : 1;
+ if (this->allowCurrent) {
+ if ((mode & S_IWRITE) != 0) return this->allowWriteCurrent ? 0 : 1;
+ else return 0;
+ } else {
+ return 1;
+ }
}
return xattrs;
}
+
+
+
+regex_t *VfsCatalog::vfsCompileRegex(const char *name, const std::string value) throw (DmException) {
+ regex_t regex;
+ int ret;
+ char buf[256];
+
+ if (value.empty()) return 0;
+
+ //syslog(LOG_DEBUG, "%s: %s regex: '%s'\n", __func__, name, value.c_str());
+ if ((ret = regcomp(®ex, value.c_str(), REG_EXTENDED | REG_NOSUB)) != 0) {
+ regerror(ret, ®ex, buf, sizeof buf);
+ vfsThrow(EINVAL, "invalid regular expresion for '%s': %s", name, buf);
+ }
+
+ return new regex_t(regex);
+}
+
+
+
+bool VfsCatalog::vfsEvalRegex(regex_t *allowRegex, regex_t *denyRegex, const char *subj) {
+ bool allow = false;
+ int ret;
+
+ if (allowRegex) {
+ if ((ret = regexec(allowRegex, subj, 0, NULL, 0)) == 0)
+ allow = true;
+ //fprintf(stderr, "'%s' %s allow regexp\n", subj.c_str(), ((ret == 0) ? "matches" : "not matches"));
+ }
+ if (allow && denyRegex) {
+ if ((ret = regexec(denyRegex, subj, 0, NULL, 0)) == 0)
+ allow = false;
+ //fprintf(stderr, "'%s' %s deny regexp\n", subj.c_str(), (ret == 0) ? "matches" : "not matches");
+ }
+
+ return allow;
+}
public:
/// Constructor
/// @param retryLimit Limit of retrials.
- VfsCatalog(const std::string& host, const std::string& prefix, const std::string& allow, const std::string& deny) throw (DmException);
+ VfsCatalog(const std::string& host, const std::string& prefix, const std::string& allow, const std::string& deny, const std::string allowWrite, const std::string denyWrite) throw (DmException);
/// Destructor
~VfsCatalog();
ExtendedStat vfsExtendedStat(const std::string& name, const std::string& path, bool follow) throw (DmException);
PrivateDir* vfsOpenDir(const std::string& lpath, const std::string& path) throw (DmException);
Extensible vfsGetXattrs(const std::string& path, const std::string& lpath, bool follow) throw (DmException);
+ regex_t *vfsCompileRegex(const char *name, const std::string value) throw (DmException);
+ bool vfsEvalRegex(regex_t *allowRegex, regex_t *denyRegex, const char *subj);
StackInstance* si_;
const SecurityContext* secCtx_;
private:
int checkPermissions(const SecurityContext *context, const Acl &acl, const struct stat &stat, mode_t mode);
- regex_t *allowRegex, *denyRegex;
- bool allowCurrent;
+ regex_t *allowRegex, *denyRegex, *allowWriteRegex, *denyWriteRegex;
+ bool allowCurrent, allowWriteCurrent;
std::string clientName;
char xattrBuffer[1024], xattrValue[1024];