From: Greg Farnum Date: Tue, 28 Jun 2016 23:30:00 +0000 (-0700) Subject: client: always pass UserPerms to opendir() and variants X-Git-Tag: v11.0.1~36^2~95 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=dbdf402eba50e3195cc30488d5c3f6b4ff78a92b;p=ceph.git client: always pass UserPerms to opendir() and variants Signed-off-by: Greg Farnum --- diff --git a/src/client/Client.cc b/src/client/Client.cc index 4472485d604a..e8fdf7f47315 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -6889,34 +6889,34 @@ int Client::flock(int fd, int operation, uint64_t owner) 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; } @@ -7100,6 +7100,7 @@ int Client::_readdir_get_frag(dir_result_t *dirp) 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) { @@ -7510,7 +7511,7 @@ int Client::getdir(const char *relpath, list& contents, } dir_result_t *d; - int r = opendir(relpath, &d); + int r = opendir(relpath, &d, perms); if (r < 0) return r; @@ -11249,7 +11250,7 @@ uint64_t Client::ll_get_internal_offset(Inode *in, uint64_t blockno) } int Client::ll_opendir(Inode *in, int flags, dir_result_t** dirpp, - int uid, int gid) + const UserPerm& perms) { Mutex::Locker lock(client_lock); @@ -11260,12 +11261,12 @@ int Client::ll_opendir(Inode *in, int flags, dir_result_t** dirpp, 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 << ")" diff --git a/src/client/Client.h b/src/client/Client.h index f76de8713cf3..085e087ba98c 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -737,7 +737,7 @@ private: // 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); @@ -976,7 +976,7 @@ public: 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); /** @@ -1136,7 +1136,8 @@ public: 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); diff --git a/src/client/SyntheticClient.cc b/src/client/SyntheticClient.cc index de744c54671b..a17f49e2ccfd 100644 --- a/src/client/SyntheticClient.cc +++ b/src/client/SyntheticClient.cc @@ -1140,7 +1140,7 @@ int SyntheticClient::play_trace(Trace& t, string& prefix, bool metadata_only) 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(); @@ -1354,7 +1354,7 @@ int SyntheticClient::play_trace(Trace& t, string& prefix, bool metadata_only) 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); } diff --git a/src/client/fuse_ll.cc b/src/client/fuse_ll.cc index de14029943d1..873ff59877e0 100644 --- a/src/client/fuse_ll.cc +++ b/src/client/fuse_ll.cc @@ -268,8 +268,10 @@ static void fuse_ll_opendir(fuse_req_t req, fuse_ino_t ino, 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); diff --git a/src/libcephfs.cc b/src/libcephfs.cc index 75653610fdea..daf9f0381dc2 100644 --- a/src/libcephfs.cc +++ b/src/libcephfs.cc @@ -467,7 +467,8 @@ extern "C" int ceph_opendir(struct ceph_mount_info *cmount, { 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) @@ -1558,8 +1559,9 @@ extern "C" int ceph_ll_opendir(class ceph_mount_info *cmount, 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,