return _flock(f, operation, owner);
}
-int Client::opendir(const char *relpath, dir_result_t **dirpp)
+int Client::opendir(const char *relpath, dir_result_t **dirpp, const UserPerm& perms)
{
Mutex::Locker lock(client_lock);
tout(cct) << "opendir" << std::endl;
tout(cct) << relpath << std::endl;
filepath path(relpath);
InodeRef in;
- int r = path_walk(path, &in);
+ int r = path_walk(path, &in, perms, true);
if (r < 0)
return r;
if (cct->_conf->client_permissions) {
- int r = may_open(in.get(), O_RDONLY);
+ int r = may_open(in.get(), O_RDONLY, perms);
if (r < 0)
return r;
}
- r = _opendir(in.get(), dirpp);
+ r = _opendir(in.get(), dirpp, perms);
tout(cct) << (unsigned long)*dirpp << std::endl;
return r;
}
-int Client::_opendir(Inode *in, dir_result_t **dirpp, int uid, int gid)
+int Client::_opendir(Inode *in, dir_result_t **dirpp, const UserPerm& perms)
{
if (!in->is_dir())
return -ENOTDIR;
*dirpp = new dir_result_t(in);
opened_dirs.insert(*dirpp);
- (*dirpp)->owner_uid = uid;
- (*dirpp)->owner_gid = gid;
+ (*dirpp)->owner_uid = perms.uid();
+ (*dirpp)->owner_gid = perms.gid();
ldout(cct, 3) << "_opendir(" << in->ino << ") = " << 0 << " (" << *dirpp << ")" << dendl;
return 0;
}
req->dirp = dirp;
bufferlist dirbl;
+ // FIXME: is owner_uid safe, or can dirp get invoked with different perms?
int res = make_request(req, dirp->owner_uid, dirp->owner_gid, NULL, NULL, -1, &dirbl);
if (res == -EAGAIN) {
}
dir_result_t *d;
- int r = opendir(relpath, &d);
+ int r = opendir(relpath, &d, perms);
if (r < 0)
return r;
}
int Client::ll_opendir(Inode *in, int flags, dir_result_t** dirpp,
- int uid, int gid)
+ const UserPerm& perms)
{
Mutex::Locker lock(client_lock);
tout(cct) << vino.ino.val << std::endl;
if (!cct->_conf->fuse_default_permissions) {
- int r = may_open(in, flags, uid, gid);
+ int r = may_open(in, flags, perms);
if (r < 0)
return r;
}
- int r = _opendir(in, dirpp, uid, gid);
+ int r = _opendir(in, dirpp, perms);
tout(cct) << (unsigned long)*dirpp << std::endl;
ldout(cct, 3) << "ll_opendir " << vino << " = " << r << " (" << *dirpp << ")"
// some readdir helpers
typedef int (*add_dirent_cb_t)(void *p, struct dirent *de, struct stat *st, int stmask, off_t off);
- int _opendir(Inode *in, dir_result_t **dirpp, int uid=-1, int gid=-1);
+ int _opendir(Inode *in, dir_result_t **dirpp, const UserPerm& perms);
void _readdir_drop_dirp_buffer(dir_result_t *dirp);
bool _readdir_have_frag(dir_result_t *dirp);
void _readdir_next_frag(dir_result_t *dirp);
void getcwd(std::string& cwd);
// namespace ops
- int opendir(const char *name, dir_result_t **dirpp);
+ int opendir(const char *name, dir_result_t **dirpp, const UserPerm& perms);
int closedir(dir_result_t *dirp);
/**
int flags, int uid=-1, int gid=-1);
int ll_removexattr(Inode *in, const char *name, int uid=-1, int gid=-1);
int ll_listxattr(Inode *in, char *list, size_t size, int uid=-1, int gid=-1);
- int ll_opendir(Inode *in, int flags, dir_result_t **dirpp, int uid = -1, int gid = -1);
+ int ll_opendir(Inode *in, int flags, dir_result_t **dirpp,
+ const UserPerm& perms);
int ll_releasedir(dir_result_t* dirp);
int ll_fsyncdir(dir_result_t* dirp);
int ll_readlink(Inode *in, char *buf, size_t bufsize, int uid = -1, int gid = -1);
const char *a = t.get_string(buf, p);
int64_t b = t.get_int();
dir_result_t *dirp;
- client->opendir(a, &dirp);
+ client->opendir(a, &dirp, perms);
if (dirp) open_dirs[b] = dirp;
} else if (strcmp(op, "closedir") == 0) {
int64_t a = t.get_int();
dir_result_t *dirp;
if (ll_inos.count(i)) {
i1 = client->ll_get_inode(vinodeno_t(ll_inos[i],CEPH_NOSNAP));
- if (client->ll_opendir(i1, O_RDONLY, &dirp) == 0)
+ if (client->ll_opendir(i1, O_RDONLY, &dirp, perms) == 0)
ll_dirs[r] = dirp;
client->ll_put(i1);
}
Inode *in = cfuse->iget(ino);
void *dirp;
+ UserPerm perms(ctx->uid, ctx->gid);
+
int r = cfuse->client->ll_opendir(in, fi->flags, (dir_result_t **)&dirp,
- ctx->uid, ctx->gid);
+ perms);
if (r >= 0) {
fi->fh = (uint64_t)dirp;
fuse_reply_open(req, fi);
{
if (!cmount->is_mounted())
return -ENOTCONN;
- return cmount->get_client()->opendir(name, (dir_result_t **)dirpp);
+ UserPerm perms = cmount->get_client()->pick_my_perms();
+ return cmount->get_client()->opendir(name, (dir_result_t **)dirpp, perms);
}
extern "C" int ceph_closedir(struct ceph_mount_info *cmount, struct ceph_dir_result *dirp)
struct ceph_dir_result **dirpp,
int uid, int gid)
{
+ UserPerm perms(uid, gid);
return (cmount->get_client()->ll_opendir(in, O_RDONLY, (dir_result_t**) dirpp,
- uid, gid));
+ perms));
}
extern "C" int ceph_ll_releasedir(class ceph_mount_info *cmount,