示例#1
0
文件: fs.cpp 项目: 8l/vdev
// for creating, opening, or stating files, verify that the caller is permitted according to our ACLs 
// return 0 on success 
// return -EPERM if denied 
// return other -errno on error 
static int vdevfs_access_check( struct vdevfs* vdev, struct fskit_fuse_state* fs_state, char const* method_name, char const* path ) {
   
   int rc = 0;
   pid_t pid = 0;
   uid_t uid = 0;
   gid_t gid = 0;
   struct stat sb;
   struct pstat ps;
   
   memset( &sb, 0, sizeof(struct stat) );
   sb.st_mode = 0777;
   
   memset( &ps, 0, sizeof(struct pstat) );
   
   // stat the calling process
   pid = fskit_fuse_get_pid();
   uid = fskit_fuse_get_uid( fs_state );
   gid = fskit_fuse_get_gid( fs_state );
   
   vdev_debug("%s('%s') from user %d group %d task %d\n", method_name, path, uid, gid, pid );
   
   // see who's asking 
   rc = pstat( pid, &ps, 0 );
   if( rc != 0 ) {
      
      vdev_error("pstat(%d) rc = %d\n", pid, rc );
      return -EIO;
   }
   
   // apply the ACLs on the stat buffer
   rc = vdev_acl_apply_all( vdev->config, vdev->acls, vdev->num_acls, path, &ps, uid, gid, &sb );
   if( rc < 0 ) {
      
      vdev_error("vdev_acl_apply_all(%s, uid=%d, gid=%d, pid=%d) rc = %d\n", path, uid, gid, pid, rc );
      return -EIO;
   }
   
   // omit entirely?
   if( rc == 0 || (sb.st_mode & 0777) == 0 ) {
      
      // filter
      vdev_debug("DENY '%s'\n", path );
      return -EPERM;
   }
   else {
      
      // accept!
      return 0;
   }
}
示例#2
0
int fskit_fuse_listxattr(const char *path, char *list, size_t size) {

   struct fskit_fuse_state* state = fskit_fuse_get_state();
   if( (state->callbacks & FSKIT_FUSE_LISTXATTR) == 0 ) {
      return -ENOSYS;
   }

   fskit_debug("listxattr(%s, %p, %zu)\n", path, list, size );

   uid_t uid = fskit_fuse_get_uid( state );
   gid_t gid = fskit_fuse_get_gid( state );

   int rc = fskit_listxattr( state->core, path, uid, gid, list, size );

   fskit_debug("listxattr(%s, %p, %zu) rc = %d\n", path, list, size, rc );
   return rc;
}
示例#3
0
int fskit_fuse_setxattr(const char *path, const char *name, const char *value, size_t size, int flags) {

   struct fskit_fuse_state* state = fskit_fuse_get_state();
   if( (state->callbacks & FSKIT_FUSE_SETXATTR) == 0 ) {
      return -ENOSYS;
   }

   fskit_debug("setxattr(%s, %s, %p, %zu, %X)\n", path, name, value, size, flags );

   uid_t uid = fskit_fuse_get_uid( state );
   gid_t gid = fskit_fuse_get_gid( state );

   int rc = fskit_setxattr( state->core, path, uid, gid, name, value, size, flags );

   fskit_debug("setxattr(%s, %s, %p, %zu, %X) rc = %d\n", path, name, value, size, flags, rc );
   return rc;
}
示例#4
0
int fskit_fuse_removexattr(const char *path, const char *name) {

   struct fskit_fuse_state* state = fskit_fuse_get_state();
   if( (state->callbacks & FSKIT_FUSE_REMOVEXATTR) == 0 ) {
      return -ENOSYS;
   }

   fskit_debug("removexattr(%s, %s)\n", path, name );

   uid_t uid = fskit_fuse_get_uid( state );
   gid_t gid = fskit_fuse_get_gid( state );

   int rc = fskit_removexattr( state->core, path, uid, gid, name );

   fskit_debug("removexattr(%s, %s) rc = %d\n", path, name, rc );
   return rc;
}
示例#5
0
int fskit_fuse_statfs(const char *path, struct statvfs *statv) {

   struct fskit_fuse_state* state = fskit_fuse_get_state();
   if( (state->callbacks & FSKIT_FUSE_STATFS) == 0 ) {
      return -ENOSYS;
   }

   fskit_debug("statfs(%s, %p)\n", path, statv );

   uid_t uid = fskit_fuse_get_uid( state );
   gid_t gid = fskit_fuse_get_gid( state );

   int rc = fskit_statvfs( state->core, path, uid, gid, statv );

   fskit_debug("statfs(%s, %p) rc = %d\n", path, statv, rc );

   return rc;
}
示例#6
0
int fskit_fuse_utime(const char *path, struct utimbuf *ubuf) {

   struct fskit_fuse_state* state = fskit_fuse_get_state();
   if( (state->callbacks & FSKIT_FUSE_UTIME) == 0 ) {
      return -ENOSYS;
   }

   fskit_debug("utime(%s, %ld.%ld)\n", path, ubuf->actime, ubuf->modtime );

   uid_t uid = fskit_fuse_get_uid( state );
   gid_t gid = fskit_fuse_get_gid( state );

   int rc = fskit_utime( state->core, path, uid, gid, ubuf );

   fskit_debug("utime(%s, %ld.%ld) rc = %d\n", path, ubuf->actime, ubuf->modtime, rc );

   return rc;
}
示例#7
0
int fskit_fuse_truncate(const char *path, off_t newsize) {

   struct fskit_fuse_state* state = fskit_fuse_get_state();
   if( (state->callbacks & FSKIT_FUSE_TRUNCATE) == 0 ) {
      return -ENOSYS;
   }

   fskit_debug("truncate(%s, %jd)\n", path, newsize );

   uid_t uid = fskit_fuse_get_uid( state );
   gid_t gid = fskit_fuse_get_gid( state );

   int rc = fskit_trunc( state->core, path, uid, gid, newsize );

   fskit_debug("truncate(%s, %jd) rc = %d\n", path, newsize, rc );

   return rc;
}
示例#8
0
int fskit_fuse_chmod(const char *path, mode_t mode) {

   struct fskit_fuse_state* state = fskit_fuse_get_state();
   if( (state->callbacks & FSKIT_FUSE_CHMOD) == 0 ) {
      return -ENOSYS;
   }

   fskit_debug("chmod(%s, %o)\n", path, mode );

   uid_t uid = fskit_fuse_get_uid( state );
   gid_t gid = fskit_fuse_get_gid( state );

   int rc = fskit_chmod( state->core, path, uid, gid, mode );

   fskit_debug("chmod(%s, %o) rc = %d\n", path, mode, rc );

   return rc;
}
示例#9
0
int fskit_fuse_link(const char *path, const char *newpath) {

   struct fskit_fuse_state* state = fskit_fuse_get_state();
   if( (state->callbacks & FSKIT_FUSE_LINK) == 0 ) {
      return -ENOSYS;
   }

   fskit_debug("link(%s, %s)\n", path, newpath );

   uid_t uid = fskit_fuse_get_uid( state );
   gid_t gid = fskit_fuse_get_gid( state );

   int rc = fskit_link( state->core, path, newpath, uid, gid );

   fskit_debug("link(%s, %s) rc = %d\n", path, newpath, rc );

   return 0;
}
示例#10
0
int fskit_fuse_symlink(const char *target, const char *linkpath) {

   struct fskit_fuse_state* state = fskit_fuse_get_state();
   if( (state->callbacks & FSKIT_FUSE_SYMLINK) == 0 ) {
      return -ENOSYS;
   }

   fskit_debug("symlink(%s, %s)\n", target, linkpath );

   int rc = 0;
   uid_t uid = fskit_fuse_get_uid( state );
   gid_t gid = fskit_fuse_get_gid( state );

   rc = fskit_symlink( state->core, target, linkpath, uid, gid );

   fskit_debug("symlink(%s, %s) rc = %d\n", target, linkpath, rc );
   return rc;
}
示例#11
0
int fskit_fuse_rmdir(const char *path) {

   struct fskit_fuse_state* state = fskit_fuse_get_state();
   if( (state->callbacks & FSKIT_FUSE_RMDIR) == 0 ) {
      return -ENOSYS;
   }

   fskit_debug("rmdir(%s)\n", path );

   uid_t uid = fskit_fuse_get_uid( state );
   gid_t gid = fskit_fuse_get_gid( state );

   int rc = fskit_rmdir( state->core, path, uid, gid );

   fskit_debug("rmdir(%s) rc = %d\n", path, rc );

   return rc;
}
示例#12
0
int fskit_fuse_mknod(const char *path, mode_t mode, dev_t dev) {

   struct fskit_fuse_state* state = fskit_fuse_get_state();
   if( (state->callbacks & FSKIT_FUSE_MKNOD) == 0 ) {
      return -ENOSYS;
   }

   fskit_debug("mknod(%s, %o, %d, %d)\n", path, mode, major(dev), minor(dev) );

   uid_t uid = fskit_fuse_get_uid( state );
   gid_t gid = fskit_fuse_get_gid( state );

   int rc = fskit_mknod( state->core, path, mode, dev, uid, gid );

   fskit_debug("mknod(%s, %o, %d, %d) rc = %d\n", path, mode, major(dev), minor(dev), rc );

   return rc;
}
示例#13
0
int fskit_fuse_access(const char *path, int mask) {

   struct fskit_fuse_state* state = fskit_fuse_get_state();
   if( (state->callbacks & FSKIT_FUSE_ACCESS) == 0 ) {
      return -ENOSYS;
   }

   fskit_debug("access(%s, %X)\n", path, mask );

   uid_t uid = fskit_fuse_get_uid( state );
   gid_t gid = fskit_fuse_get_gid( state );

   int rc = fskit_access( state->core, path, uid, gid, mask );

   fskit_debug("access(%s, %X) rc = %d\n", path, mask, rc );

   return rc;
}
示例#14
0
int fskit_fuse_getattr(const char *path, struct stat *statbuf) {

   struct fskit_fuse_state* state = fskit_fuse_get_state();
   if( (state->callbacks & FSKIT_FUSE_GETATTR) == 0 ) {
      return -ENOSYS;
   }

   uid_t uid = fskit_fuse_get_uid( state );
   gid_t gid = fskit_fuse_get_gid( state );

   fskit_debug("getattr(%s, %p, %d, %d)\n", path, statbuf, uid, gid );

   int rc = fskit_stat( state->core, path, uid, gid, statbuf );

   fskit_debug("getattr(%s, %p, %d, %d) rc = %d\n", path, statbuf, uid, gid, rc );

   return rc;
}
示例#15
0
int fskit_fuse_chown(const char *path, uid_t new_uid, gid_t new_gid) {

   struct fskit_fuse_state* state = fskit_fuse_get_state();
   if( (state->callbacks & FSKIT_FUSE_CHOWN) == 0 ) {
      return -ENOSYS;
   }

   fskit_debug("chown(%s, %d, %d)\n", path, new_uid, new_gid );

   uid_t uid = fskit_fuse_get_uid( state );
   gid_t gid = fskit_fuse_get_gid( state );

   int rc = fskit_chown( state->core, path, uid, gid, new_uid, new_gid );

   fskit_debug("chown(%s, %d, %d) rc = %d\n", path, new_uid, new_gid, rc );

   return rc;
}
示例#16
0
int fskit_fuse_create(const char *path, mode_t mode, struct fuse_file_info *fi) {

   struct fskit_fuse_state* state = fskit_fuse_get_state();
   if( (state->callbacks & FSKIT_FUSE_CREATE) == 0 ) {
      return -ENOSYS;
   }

   fskit_debug("create(%s, %o, %p)\n", path, mode, fi );

   uid_t uid = fskit_fuse_get_uid( state );
   gid_t gid = fskit_fuse_get_gid( state );
   struct fskit_fuse_file_info* ffi = NULL;
   int rc = 0;

   struct fskit_file_handle* fh = fskit_create( state->core, path, uid, gid, mode, &rc );

   if( rc != 0 ) {

      fskit_debug("create(%s, %o, %p) rc = %d\n", path, mode, fi, rc );

      return rc;
   }

   ffi = fskit_fuse_make_file_handle( fh );
   if( ffi == NULL ) {

      fskit_close( state->core, fh );

      fskit_debug("create(%s, %o, %p) rc = %d\n", path, mode, fi, -ENOMEM );

      return -ENOMEM;
   }

   fi->fh = (uintptr_t)ffi;

   // NOTE: fskit_read() and fskit_write() return a negative error code on error,
   // so set direct_io to allow this error code to be propagated.
   fi->direct_io = 1;

   fskit_debug("create(%s, %o, %p) rc = %d\n", path, mode, fi, rc );

   return rc;
}
示例#17
0
int fskit_fuse_readlink(const char *path, char *link, size_t size) {

   struct fskit_fuse_state* state = fskit_fuse_get_state();
   if( (state->callbacks & FSKIT_FUSE_READLINK) == 0 ) {
      return -ENOSYS;
   }

   fskit_debug("readlink(%s, %zu)\n", path, size );

   ssize_t rc = 0;
   uid_t uid = fskit_fuse_get_uid( state );
   gid_t gid = fskit_fuse_get_gid( state );

   rc = fskit_readlink( state->core, path, uid, gid, link, size );

   if( rc >= 0 ) {
      rc = 0;
   }

   fskit_debug("readlink(%s, %zu) rc = %zd\n", path, size, rc );

   return (int)rc;
}
示例#18
0
int fskit_fuse_opendir(const char *path, struct fuse_file_info *fi) {

   struct fskit_fuse_state* state = fskit_fuse_get_state();
   if( (state->callbacks & FSKIT_FUSE_OPENDIR) == 0 ) {
      return -ENOSYS;
   }

   fskit_debug("opendir(%s, %p)\n", path, fi );

   uid_t uid = fskit_fuse_get_uid( state );
   gid_t gid = fskit_fuse_get_gid( state );
   struct fskit_fuse_file_info* ffi = NULL;
   int rc = 0;

   struct fskit_dir_handle* dh = fskit_opendir( state->core, path, uid, gid, &rc );

   if( rc != 0 ) {

      fskit_debug("opendir(%s, %p) rc = %d\n", path, fi, rc );
      return rc;
   }

   ffi = fskit_fuse_make_dir_handle( dh );

   if( ffi == NULL ) {
      fskit_closedir( state->core, dh );

      fskit_debug("opendir(%s, %p) rc = %d\n", path, fi, -ENOMEM );
      return -ENOMEM;
   }

   fi->fh = (uintptr_t)ffi;

   fskit_debug("opendir(%s, %p) rc = %d\n", path, fi, 0 );
   return 0;
}
示例#19
0
文件: fs.cpp 项目: 8l/vdev
// readdir: equivocate about which devices exist, depending on who's asking
// omit entries if the ACLs forbid them
int vdevfs_readdir( struct fskit_core* core, struct fskit_match_group* grp, struct fskit_entry* fent, struct fskit_dir_entry** dirents, size_t num_dirents ) {
   
   int rc = 0;
   struct fskit_entry* child = NULL;
   
   // entries to omit in the listing
   vector<int> omitted_idx;
   
   pid_t pid = 0;
   uid_t uid = 0;
   gid_t gid = 0;
   
   struct vdevfs* vdev = (struct vdevfs*)fskit_core_get_user_data( core );
   struct fskit_fuse_state* fs_state = fskit_fuse_get_state();
   
   struct stat sb;
   struct pstat ps;
   char* child_path = NULL;
   
   pid = fskit_fuse_get_pid();
   uid = fskit_fuse_get_uid( fs_state );
   gid = fskit_fuse_get_gid( fs_state );
   
   vdev_debug("vdevfs_readdir(%s, %zu) from user %d group %d task %d\n", grp->path, num_dirents, uid, gid, pid );
   
   // see who's asking
   rc = pstat( pid, &ps, 0 );
   if( rc != 0 ) { 
      
      vdev_error("pstat(%d) rc = %d\n", pid, rc );
      return -EIO;
   }
   
   for( unsigned int i = 0; i < num_dirents; i++ ) {
      
      // skip . and ..
      if( strcmp(dirents[i]->name, ".") == 0 || strcmp(dirents[i]->name, "..") == 0 ) {
         continue;
      }
      
      // find the associated fskit_entry
      child = fskit_dir_find_by_name( fent, dirents[i]->name );
      
      if( child == NULL ) {
         // strange, shouldn't happen...
         continue;
      }
      
      fskit_entry_rlock( child );
      
      // construct a stat buffer from what we actually need 
      memset( &sb, 0, sizeof(struct stat) );
      
      sb.st_uid = child->owner;
      sb.st_gid = child->group;
      sb.st_mode = fskit_fullmode( child->type, child->mode );
      
      child_path = fskit_fullpath( grp->path, child->name, NULL );
      if( child_path == NULL ) {
         
         // can't continue; OOM
         fskit_entry_unlock( child );
         rc = -ENOMEM;
         break;
      }
      
      // filter it 
      rc = vdev_acl_apply_all( vdev->config, vdev->acls, vdev->num_acls, child_path, &ps, uid, gid, &sb );
      if( rc < 0 ) {
         
         vdev_error("vdev_acl_apply_all('%s', uid=%d, gid=%d, pid=%d) rc = %d\n", child_path, uid, gid, pid, rc );
         rc = -EIO;
      }
      else if( rc == 0 || (sb.st_mode & 0777) == 0 ) {
         
         // omit this one 
         vdev_debug("Filter '%s'\n", child->name );
         omitted_idx.push_back( i );
         
         rc = 0;
      }
      else {
         
         // success; matched
         rc = 0;
      }
      
      fskit_entry_unlock( child );
      
      free( child_path );
      
      // error?
      if( rc != 0 ) {
         break;
      }
   }
   
   // skip ACL'ed entries
   for( unsigned int i = 0; i < omitted_idx.size(); i++ ) {
      
      fskit_readdir_omit( dirents, omitted_idx[i] );
   }
   
   return rc;
}