return r;
}
+int Client::may_hardlink(Inode *in, int uid, int gid)
+{
+ if (uid < 0)
+ uid = get_uid();
+ if (gid < 0)
+ gid = get_gid();
+ RequestUserGroups groups(this, uid, gid);
+
+ int r = _getattr(in, CEPH_STAT_CAP_MODE, uid, gid);
+ if (r < 0)
+ goto out;
+
+ if (uid == 0 || (uid_t)uid == in->uid) {
+ r = 0;
+ goto out;
+ }
+
+ r = -EPERM;
+ if (!S_ISREG(in->mode))
+ goto out;
+
+ if (in->mode & S_ISUID)
+ goto out;
+
+ if ((in->mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))
+ goto out;
+
+ r = inode_permission(in, uid, groups, MAY_READ | MAY_WRITE);
+out:
+ ldout(cct, 3) << __func__ << " " << in << " = " << r << dendl;
+ return r;
+}
+
vinodeno_t Client::_get_vino(Inode *in)
{
/* The caller must hold the client lock */
r = -EPERM;
goto out;
}
+ r = may_hardlink(in, uid, gid);
+ if (r < 0)
+ goto out;
r = may_create(newparent, uid, gid);
if (r < 0)
goto out;
int may_lookup(Inode *dir, int uid=-1, int gid=-1);
int may_create(Inode *dir, int uid=-1, int gid=-1);
int may_delete(Inode *dir, const char *name, int uid=-1, int gid=-1);
+ int may_hardlink(Inode *in, int uid=-1, int gid=-1);
int _getgrouplist(gid_t **sgids, int uid=-1, int gid=-1);
int check_data_pool_exist(string name, string value, const OSDMap *osdmap);