diff options
author | David Howells <dhowells@redhat.com> | 2007-04-26 18:57:07 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2007-04-26 18:57:07 -0400 |
commit | 00d3b7a4533e367b0dc2812a706db8f9f071c27f (patch) | |
tree | f0b1ae0266267cb2c54cb11aa61ad0758ce9c0f5 /fs/afs/inode.c | |
parent | 436058a49e0fb91c74454dbee9cfee6fb53b4336 (diff) |
[AFS]: Add security support.
Add security support to the AFS filesystem. Kerberos IV tickets are added as
RxRPC keys are added to the session keyring with the klog program. open() and
other VFS operations then find this ticket with request_key() and either use
it immediately (eg: mkdir, unlink) or attach it to a file descriptor (open).
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'fs/afs/inode.c')
-rw-r--r-- | fs/afs/inode.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/fs/afs/inode.c b/fs/afs/inode.c index 18863315211f..227336228299 100644 --- a/fs/afs/inode.c +++ b/fs/afs/inode.c | |||
@@ -29,7 +29,7 @@ struct afs_iget_data { | |||
29 | /* | 29 | /* |
30 | * map the AFS file status to the inode member variables | 30 | * map the AFS file status to the inode member variables |
31 | */ | 31 | */ |
32 | static int afs_inode_map_status(struct afs_vnode *vnode) | 32 | static int afs_inode_map_status(struct afs_vnode *vnode, struct key *key) |
33 | { | 33 | { |
34 | struct inode *inode = AFS_VNODE_TO_I(vnode); | 34 | struct inode *inode = AFS_VNODE_TO_I(vnode); |
35 | 35 | ||
@@ -44,7 +44,7 @@ static int afs_inode_map_status(struct afs_vnode *vnode) | |||
44 | case AFS_FTYPE_FILE: | 44 | case AFS_FTYPE_FILE: |
45 | inode->i_mode = S_IFREG | vnode->status.mode; | 45 | inode->i_mode = S_IFREG | vnode->status.mode; |
46 | inode->i_op = &afs_file_inode_operations; | 46 | inode->i_op = &afs_file_inode_operations; |
47 | inode->i_fop = &generic_ro_fops; | 47 | inode->i_fop = &afs_file_operations; |
48 | break; | 48 | break; |
49 | case AFS_FTYPE_DIR: | 49 | case AFS_FTYPE_DIR: |
50 | inode->i_mode = S_IFDIR | vnode->status.mode; | 50 | inode->i_mode = S_IFDIR | vnode->status.mode; |
@@ -73,7 +73,7 @@ static int afs_inode_map_status(struct afs_vnode *vnode) | |||
73 | 73 | ||
74 | /* check to see whether a symbolic link is really a mountpoint */ | 74 | /* check to see whether a symbolic link is really a mountpoint */ |
75 | if (vnode->status.type == AFS_FTYPE_SYMLINK) { | 75 | if (vnode->status.type == AFS_FTYPE_SYMLINK) { |
76 | afs_mntpt_check_symlink(vnode); | 76 | afs_mntpt_check_symlink(vnode, key); |
77 | 77 | ||
78 | if (test_bit(AFS_VNODE_MOUNTPOINT, &vnode->flags)) { | 78 | if (test_bit(AFS_VNODE_MOUNTPOINT, &vnode->flags)) { |
79 | inode->i_mode = S_IFDIR | vnode->status.mode; | 79 | inode->i_mode = S_IFDIR | vnode->status.mode; |
@@ -115,7 +115,8 @@ static int afs_iget5_set(struct inode *inode, void *opaque) | |||
115 | /* | 115 | /* |
116 | * inode retrieval | 116 | * inode retrieval |
117 | */ | 117 | */ |
118 | inline struct inode *afs_iget(struct super_block *sb, struct afs_fid *fid) | 118 | inline struct inode *afs_iget(struct super_block *sb, struct key *key, |
119 | struct afs_fid *fid) | ||
119 | { | 120 | { |
120 | struct afs_iget_data data = { .fid = *fid }; | 121 | struct afs_iget_data data = { .fid = *fid }; |
121 | struct afs_super_info *as; | 122 | struct afs_super_info *as; |
@@ -157,10 +158,10 @@ inline struct inode *afs_iget(struct super_block *sb, struct afs_fid *fid) | |||
157 | 158 | ||
158 | /* okay... it's a new inode */ | 159 | /* okay... it's a new inode */ |
159 | set_bit(AFS_VNODE_CB_BROKEN, &vnode->flags); | 160 | set_bit(AFS_VNODE_CB_BROKEN, &vnode->flags); |
160 | ret = afs_vnode_fetch_status(vnode); | 161 | ret = afs_vnode_fetch_status(vnode, NULL, key); |
161 | if (ret < 0) | 162 | if (ret < 0) |
162 | goto bad_inode; | 163 | goto bad_inode; |
163 | ret = afs_inode_map_status(vnode); | 164 | ret = afs_inode_map_status(vnode, key); |
164 | if (ret < 0) | 165 | if (ret < 0) |
165 | goto bad_inode; | 166 | goto bad_inode; |
166 | 167 | ||
@@ -201,6 +202,7 @@ int afs_inode_getattr(struct vfsmount *mnt, struct dentry *dentry, | |||
201 | */ | 202 | */ |
202 | void afs_clear_inode(struct inode *inode) | 203 | void afs_clear_inode(struct inode *inode) |
203 | { | 204 | { |
205 | struct afs_permits *permits; | ||
204 | struct afs_vnode *vnode; | 206 | struct afs_vnode *vnode; |
205 | 207 | ||
206 | vnode = AFS_FS_I(inode); | 208 | vnode = AFS_FS_I(inode); |
@@ -233,5 +235,12 @@ void afs_clear_inode(struct inode *inode) | |||
233 | vnode->cache = NULL; | 235 | vnode->cache = NULL; |
234 | #endif | 236 | #endif |
235 | 237 | ||
238 | mutex_lock(&vnode->permits_lock); | ||
239 | permits = vnode->permits; | ||
240 | rcu_assign_pointer(vnode->permits, NULL); | ||
241 | mutex_unlock(&vnode->permits_lock); | ||
242 | if (permits) | ||
243 | call_rcu(&permits->rcu, afs_zap_permits); | ||
244 | |||
236 | _leave(""); | 245 | _leave(""); |
237 | } | 246 | } |