示例#1
0
/* Nautilus loves to use access(2) to test everything about a file,
 * such as whether it's executable.  Therefore treat this a lot like
 * mount_local_getattr.
 */
static int
mount_local_access (const char *path, int mask)
{
  struct stat statbuf;
  int r;
  struct fuse_context *fuse;
  int ok = 1;
  DECL_G ();
  DEBUG_CALL ("%s, %d", path, mask);

  if (g->ml_read_only && (mask & W_OK))
    return -EROFS;

  r = mount_local_getattr (path, &statbuf);
  if (r < 0 || mask == F_OK) {
    debug (g, "%s: mount_local_getattr returned r = %d", path, r);
    return r;
  }

  fuse = fuse_get_context ();

  /* Root user should be able to access everything, so only bother
   * with these fine-grained tests for non-root.  (RHBZ#1106548).
   */
  if (fuse->uid != 0) {
    if (mask & R_OK)
      ok = ok &&
        (  fuse->uid == statbuf.st_uid ? statbuf.st_mode & S_IRUSR
           : fuse->gid == statbuf.st_gid ? statbuf.st_mode & S_IRGRP
           : statbuf.st_mode & S_IROTH);
    if (mask & W_OK)
      ok = ok &&
        (  fuse->uid == statbuf.st_uid ? statbuf.st_mode & S_IWUSR
           : fuse->gid == statbuf.st_gid ? statbuf.st_mode & S_IWGRP
           : statbuf.st_mode & S_IWOTH);
    if (mask & X_OK)
      ok = ok &&
        (  fuse->uid == statbuf.st_uid ? statbuf.st_mode & S_IXUSR
           : fuse->gid == statbuf.st_gid ? statbuf.st_mode & S_IXGRP
           : statbuf.st_mode & S_IXOTH);
  }

  debug (g, "%s: "
         "testing access mask%s%s%s%s: "
         "caller UID:GID = %ju:%ju, "
         "file UID:GID = %ju:%ju, "
         "file mode = %o, "
         "result = %s",
         path,
         mask & R_OK ? " R_OK" : "",
         mask & W_OK ? " W_OK" : "",
         mask & X_OK ? " X_OK" : "",
         mask == 0 ? " 0" : "",
         (uintmax_t) fuse->uid, (uintmax_t) fuse->gid,
         (uintmax_t) statbuf.st_uid, (uintmax_t) statbuf.st_gid,
         statbuf.st_mode,
         ok ? "OK" : "EACCESS");

  return ok ? 0 : -EACCES;
}
示例#2
0
文件: fuse.c 项目: msmhrt/libguestfs
/* Nautilus loves to use access(2) to test everything about a file,
 * such as whether it's executable.  Therefore treat this a lot like
 * mount_local_getattr.
 */
static int
mount_local_access (const char *path, int mask)
{
  DECL_G ();
  DEBUG_CALL ("%s, %d", path, mask);

  struct stat statbuf;
  int r;

  if (g->ml_read_only && (mask & W_OK))
    return -EROFS;

  r = mount_local_getattr (path, &statbuf);
  if (r < 0 || mask == F_OK)
    return r;

  struct fuse_context *fuse = fuse_get_context ();
  int ok = 1;

  if (mask & R_OK)
    ok = ok &&
      (  fuse->uid == statbuf.st_uid ? statbuf.st_mode & S_IRUSR
       : fuse->gid == statbuf.st_gid ? statbuf.st_mode & S_IRGRP
       : statbuf.st_mode & S_IROTH);
  if (mask & W_OK)
    ok = ok &&
      (  fuse->uid == statbuf.st_uid ? statbuf.st_mode & S_IWUSR
       : fuse->gid == statbuf.st_gid ? statbuf.st_mode & S_IWGRP
       : statbuf.st_mode & S_IWOTH);
  if (mask & X_OK)
    ok = ok &&
      (  fuse->uid == statbuf.st_uid ? statbuf.st_mode & S_IXUSR
       : fuse->gid == statbuf.st_gid ? statbuf.st_mode & S_IXGRP
       : statbuf.st_mode & S_IXOTH);

  return ok ? 0 : -EACCES;
}