*/
bool MDSAuthCaps::is_capable(const std::string &inode_path,
uid_t inode_uid, gid_t inode_gid, unsigned inode_mode,
- uid_t uid, unsigned mask) const
+ uid_t uid, gid_t gid, unsigned mask) const
{
if (cct)
ldout(cct, 10) << __func__ << " inode(path /" << inode_path
<< " owner " << inode_uid << ":" << inode_gid
<< " mode 0" << std::oct << inode_mode << std::dec
- << ") by uid " << uid << " mask " << mask << " cap: " << *this << dendl;
+ << ") by uid " << uid << " gid " << gid << " mask " << mask << " cap: " << *this << dendl;
for (std::vector<MDSCapGrant>::const_iterator i = grants.begin();
i != grants.end();
if (i->match.match(inode_path, uid) &&
i->spec.allows(mask & (MAY_READ|MAY_EXECUTE), mask & MAY_WRITE)) {
+
+ if ((mask & MAY_CREATE) &&
+ (inode_gid != gid)) {
+ continue;
+ }
+
// check unix permissions?
if (i->match.uid == MDSCapMatch::MDS_AUTH_UID_ANY) {
return true;
MAY_READ = 1,
MAY_WRITE = 2,
MAY_EXECUTE = 4,
+ MAY_CREATE = 8
};
class CephContext;
bool allow_all() const;
bool is_capable(const std::string &inode_path,
uid_t inode_uid, gid_t inode_gid, unsigned inode_mode,
- uid_t uid, unsigned mask) const;
+ uid_t uid, gid_t gid, unsigned mask) const;
friend std::ostream &operator<<(std::ostream &out, const MDSAuthCaps &cap);
};
Session *s = mdr->session;
uid_t uid = mdr->client_request->get_caller_uid();
+ gid_t gid = mdr->client_request->get_caller_gid();
// FIXME: behave with inodes in stray dir
// FIXME: behave with hard links
path = path.substr(1); // drop leading /
if (s->auth_caps.is_capable(path, in->inode.uid, in->inode.gid, in->inode.mode,
- uid, mask)) {
+ uid, gid, mask)) {
return true;
}
return;
// mkdir check access
- if (!check_access(mdr, diri, MAY_WRITE))
+ if (!check_access(mdr, diri, (MAY_WRITE | MAY_CREATE)))
return;
// new inode