diff options
author | Miklos Szeredi <miklos@szeredi.hu> | 2001-12-20 15:38:05 +0000 |
---|---|---|
committer | Miklos Szeredi <miklos@szeredi.hu> | 2001-12-20 15:38:05 +0000 |
commit | fe25def3344095825738deba119e1400b8e2315f (patch) | |
tree | a277304923d54e0495558c1e4e6720c2c114d78d /kernel/dir.c | |
parent | 2e50d4376f3124a87d5723ae66c09fa71c7ecf88 (diff) | |
download | libfuse-fe25def3344095825738deba119e1400b8e2315f.tar.gz |
permission checking implemented
Diffstat (limited to 'kernel/dir.c')
-rw-r--r-- | kernel/dir.c | 68 |
1 files changed, 52 insertions, 16 deletions
diff --git a/kernel/dir.c b/kernel/dir.c index a3f1485..7068d37 100644 --- a/kernel/dir.c +++ b/kernel/dir.c @@ -315,29 +315,14 @@ static int fuse_link(struct dentry *entry, struct inode *newdir, return out.h.error; } -static int fuse_permission(struct inode *inode, int mask) -{ - struct fuse_conn *fc = INO_FC(inode); - - /* (too) simple protection */ - if(current->fsuid == fc->uid) - return 0; - else - return -EACCES; -} -static int fuse_revalidate(struct dentry *entry) +int fuse_getattr(struct inode *inode) { - struct inode *inode = entry->d_inode; struct fuse_conn *fc = INO_FC(inode); struct fuse_in in = FUSE_IN_INIT; struct fuse_out out = FUSE_OUT_INIT; struct fuse_getattr_out arg; - if(inode->i_ino != FUSE_ROOT_INO && - time_before_eq(jiffies, entry->d_time + FUSE_REVALIDATE_TIME)) - return 0; - in.h.opcode = FUSE_GETATTR; in.h.ino = inode->i_ino; out.numargs = 1; @@ -351,6 +336,57 @@ static int fuse_revalidate(struct dentry *entry) return out.h.error; } +static int fuse_revalidate(struct dentry *entry) +{ + struct inode *inode = entry->d_inode; + struct fuse_conn *fc = INO_FC(inode); + + if(inode->i_ino == FUSE_ROOT_INO) { + if(!(fc->flags & FUSE_ALLOW_OTHER) + && current->fsuid != fc->uid) + return -EACCES; + } + else if(time_before_eq(jiffies, entry->d_time + FUSE_REVALIDATE_TIME)) + return 0; + + return fuse_getattr(inode); +} + +static int fuse_permission(struct inode *inode, int mask) +{ + struct fuse_conn *fc = INO_FC(inode); + + if(!(fc->flags & FUSE_ALLOW_OTHER) && current->fsuid != fc->uid) + return -EACCES; + else if(fc->flags & FUSE_DEFAULT_PERMISSIONS) { + int err = vfs_permission(inode, mask); + + /* If permission is denied, try to refresh file + attributes. This is also needed, because the root + node will at first have no permissions */ + + if(err == -EACCES) { + err = fuse_getattr(inode); + if(!err) + err = vfs_permission(inode, mask); + } + + /* FIXME: Need some mechanism to revoke permissions: + currently if the filesystem suddenly changes the + file mode, we will not be informed abot that, and + continue to allow access to the file/directory. + + This is actually not so grave, since the user can + simply keep access to the file/directory anyway by + keeping it open... */ + + return err; + } + else + return 0; +} + + static int parse_dirfile(char *buf, size_t nbytes, struct file *file, void *dstbuf, filldir_t filldir) { |