int Client::may_setattr(Inode *in, struct stat *st, int mask, const UserPerm& perms)
{
- RequestUserGroups groups(this, perms.uid(), perms.gid());
+ RequestUserGroups groups(perms.uid(), perms.gid());
+ init_groups(&groups);
int r = _getattr_for_perm(in, perms);
if (r < 0)
}
}
+void Client::init_groups(RequestUserGroups *groups)
+{
+ gid_t *sgids;
+ int count = _getgrouplist(&sgids, groups->get_uid(), groups->get_gid());
+ groups->init_gids(sgids, count);
+}
+
bool Client::RequestUserGroups::is_in(gid_t id)
{
+ assert(sgid_count >= 0);
if (id == gid)
return true;
- if (sgid_count < 0)
- init();
for (int i = 0; i < sgid_count; ++i) {
if (id == sgids[i])
return true;
int Client::RequestUserGroups::get_gids(const gid_t **out)
{
- if (sgid_count < 0)
- init();
+ assert(sgid_count >= 0);
if (sgid_count > 0) {
*out = sgids;
return sgid_count;
};
class RequestUserGroups : public UserGroups {
- Client *client;
uid_t uid;
gid_t gid;
int sgid_count;
gid_t *sgids;
- void init() {
- sgid_count = client->_getgrouplist(&sgids, uid, gid);
- }
public:
- RequestUserGroups(Client *c, uid_t u, gid_t g) :
- client(c), uid(u), gid(g), sgid_count(-1), sgids(NULL) {}
+ RequestUserGroups(uid_t u, gid_t g) :
+ uid(u), gid(g), sgid_count(-1), sgids(NULL) {}
~RequestUserGroups() {
free(sgids);
}
+ bool is_init() { return sgid_count < 0; }
+ void init_gids(gid_t *_sgids, int count) {
+ sgids = _sgids;
+ sgid_count = count;
+ }
+ uid_t get_uid() { return uid; }
gid_t get_gid() { return gid; }
bool is_in(gid_t id);
int get_gids(const gid_t **out);
};
+ friend class RequestUserGroups;
+ void init_groups(RequestUserGroups *groups);
int inode_permission(Inode *in, uid_t uid, UserGroups& groups, unsigned want);
int xattr_permission(Inode *in, const char *name, unsigned want,
int may_hardlink(Inode *in, const UserPerm& perms);
int inode_permission(Inode *in, const UserPerm& perms, unsigned want) {
- RequestUserGroups groups(this, perms.uid(), perms.gid());
+ RequestUserGroups groups(perms.uid(), perms.gid());
+ init_groups(&groups);
return inode_permission(in, perms.uid(), groups, want);
}
int xattr_permission(Inode *in, const char *name, unsigned want, int uid=-1, int gid=-1) {