]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
client: always pass UserPerms to opendir() and variants
authorGreg Farnum <gfarnum@redhat.com>
Tue, 28 Jun 2016 23:30:00 +0000 (16:30 -0700)
committerGreg Farnum <gfarnum@redhat.com>
Wed, 31 Aug 2016 21:33:33 +0000 (14:33 -0700)
Signed-off-by: Greg Farnum <gfarnum@redhat.com>
src/client/Client.cc
src/client/Client.h
src/client/SyntheticClient.cc
src/client/fuse_ll.cc
src/libcephfs.cc

index 4472485d604a3e9fd38cfe558257b8ffebeb6fb9..e8fdf7f473153d964b0aa8327c1442d2eb087cf7 100644 (file)
@@ -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<string>& 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 << ")"
index f76de8713cf3e91ef49051e311402e8097f9f74c..085e087ba98cb4f2081cd64e4bfd91492ad007b2 100644 (file)
@@ -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);
index de744c54671bce26ff1c003e15fe271ca741b67d..a17f49e2ccfd676678ad83e3baff60fb40f95013 100644 (file)
@@ -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);
       }
index de14029943d1be19ef636098396533e8d720dea9..873ff59877e071a371800456e5632a68bf802664 100644 (file)
@@ -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);
index 75653610fdea4e27a47a96008c555675b73be31b..daf9f0381dc2acc874a9ca8c94baa82c4fe702b2 100644 (file)
@@ -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,