From: Yan, Zheng Date: Mon, 12 Oct 2015 09:22:27 +0000 (+0800) Subject: client: permission check for harklink X-Git-Tag: v10.0.3~48^2~3^2~7 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=e31f35ffd48ce3eafcd1a615e95c1207dc54e1ae;p=ceph.git client: permission check for harklink Signed-off-by: Yan, Zheng --- diff --git a/src/client/Client.cc b/src/client/Client.cc index 7ae066a53a4e..0ad9b327f10e 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -5026,6 +5026,39 @@ out: 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 */ @@ -10596,6 +10629,9 @@ int Client::ll_link(Inode *in, Inode *newparent, const char *newname, 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; diff --git a/src/client/Client.h b/src/client/Client.h index b630b7a165ac..7d3a60a36361 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -789,6 +789,7 @@ private: 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);