diff options
-rw-r--r-- | fs/nfsd/nfsfh.c | 2 | ||||
-rw-r--r-- | fs/nfsd/nfsproc.c | 3 | ||||
-rw-r--r-- | fs/nfsd/vfs.c | 13 | ||||
-rw-r--r-- | include/linux/nfsd/export.h | 13 | ||||
-rw-r--r-- | include/linux/nfsd/nfsd.h | 3 |
5 files changed, 24 insertions, 10 deletions
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index d5fe392b14fb..8d2b49914843 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c | |||
@@ -255,7 +255,7 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) | |||
255 | goto out; | 255 | goto out; |
256 | 256 | ||
257 | /* Finally, check access permissions. */ | 257 | /* Finally, check access permissions. */ |
258 | error = nfsd_permission(exp, dentry, access); | 258 | error = nfsd_permission(rqstp, exp, dentry, access); |
259 | 259 | ||
260 | if (error) { | 260 | if (error) { |
261 | dprintk("fh_verify: %s/%s permission failure, " | 261 | dprintk("fh_verify: %s/%s permission failure, " |
diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c index b2c7147aa921..977a71f64e19 100644 --- a/fs/nfsd/nfsproc.c +++ b/fs/nfsd/nfsproc.c | |||
@@ -278,7 +278,8 @@ nfsd_proc_create(struct svc_rqst *rqstp, struct nfsd_createargs *argp, | |||
278 | * echo thing > device-special-file-or-pipe | 278 | * echo thing > device-special-file-or-pipe |
279 | * by doing a CREATE with type==0 | 279 | * by doing a CREATE with type==0 |
280 | */ | 280 | */ |
281 | nfserr = nfsd_permission(newfhp->fh_export, | 281 | nfserr = nfsd_permission(rqstp, |
282 | newfhp->fh_export, | ||
282 | newfhp->fh_dentry, | 283 | newfhp->fh_dentry, |
283 | MAY_WRITE|MAY_LOCAL_ACCESS); | 284 | MAY_WRITE|MAY_LOCAL_ACCESS); |
284 | if (nfserr && nfserr != nfserr_rofs) | 285 | if (nfserr && nfserr != nfserr_rofs) |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 8e109e586a74..e90f4a8a1d01 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -328,7 +328,7 @@ nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap, | |||
328 | /* The size case is special. It changes the file as well as the attributes. */ | 328 | /* The size case is special. It changes the file as well as the attributes. */ |
329 | if (iap->ia_valid & ATTR_SIZE) { | 329 | if (iap->ia_valid & ATTR_SIZE) { |
330 | if (iap->ia_size < inode->i_size) { | 330 | if (iap->ia_size < inode->i_size) { |
331 | err = nfsd_permission(fhp->fh_export, dentry, MAY_TRUNC|MAY_OWNER_OVERRIDE); | 331 | err = nfsd_permission(rqstp, fhp->fh_export, dentry, MAY_TRUNC|MAY_OWNER_OVERRIDE); |
332 | if (err) | 332 | if (err) |
333 | goto out; | 333 | goto out; |
334 | } | 334 | } |
@@ -616,7 +616,7 @@ nfsd_access(struct svc_rqst *rqstp, struct svc_fh *fhp, u32 *access, u32 *suppor | |||
616 | 616 | ||
617 | sresult |= map->access; | 617 | sresult |= map->access; |
618 | 618 | ||
619 | err2 = nfsd_permission(export, dentry, map->how); | 619 | err2 = nfsd_permission(rqstp, export, dentry, map->how); |
620 | switch (err2) { | 620 | switch (err2) { |
621 | case nfs_ok: | 621 | case nfs_ok: |
622 | result |= map->access; | 622 | result |= map->access; |
@@ -1043,7 +1043,7 @@ nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, | |||
1043 | __be32 err; | 1043 | __be32 err; |
1044 | 1044 | ||
1045 | if (file) { | 1045 | if (file) { |
1046 | err = nfsd_permission(fhp->fh_export, fhp->fh_dentry, | 1046 | err = nfsd_permission(rqstp, fhp->fh_export, fhp->fh_dentry, |
1047 | MAY_READ|MAY_OWNER_OVERRIDE); | 1047 | MAY_READ|MAY_OWNER_OVERRIDE); |
1048 | if (err) | 1048 | if (err) |
1049 | goto out; | 1049 | goto out; |
@@ -1072,7 +1072,7 @@ nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, | |||
1072 | __be32 err = 0; | 1072 | __be32 err = 0; |
1073 | 1073 | ||
1074 | if (file) { | 1074 | if (file) { |
1075 | err = nfsd_permission(fhp->fh_export, fhp->fh_dentry, | 1075 | err = nfsd_permission(rqstp, fhp->fh_export, fhp->fh_dentry, |
1076 | MAY_WRITE|MAY_OWNER_OVERRIDE); | 1076 | MAY_WRITE|MAY_OWNER_OVERRIDE); |
1077 | if (err) | 1077 | if (err) |
1078 | goto out; | 1078 | goto out; |
@@ -1801,7 +1801,8 @@ nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat) | |||
1801 | * Check for a user's access permissions to this inode. | 1801 | * Check for a user's access permissions to this inode. |
1802 | */ | 1802 | */ |
1803 | __be32 | 1803 | __be32 |
1804 | nfsd_permission(struct svc_export *exp, struct dentry *dentry, int acc) | 1804 | nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp, |
1805 | struct dentry *dentry, int acc) | ||
1805 | { | 1806 | { |
1806 | struct inode *inode = dentry->d_inode; | 1807 | struct inode *inode = dentry->d_inode; |
1807 | int err; | 1808 | int err; |
@@ -1832,7 +1833,7 @@ nfsd_permission(struct svc_export *exp, struct dentry *dentry, int acc) | |||
1832 | */ | 1833 | */ |
1833 | if (!(acc & MAY_LOCAL_ACCESS)) | 1834 | if (!(acc & MAY_LOCAL_ACCESS)) |
1834 | if (acc & (MAY_WRITE | MAY_SATTR | MAY_TRUNC)) { | 1835 | if (acc & (MAY_WRITE | MAY_SATTR | MAY_TRUNC)) { |
1835 | if (EX_RDONLY(exp) || IS_RDONLY(inode)) | 1836 | if (EX_RDONLY(exp, rqstp) || IS_RDONLY(inode)) |
1836 | return nfserr_rofs; | 1837 | return nfserr_rofs; |
1837 | if (/* (acc & MAY_WRITE) && */ IS_IMMUTABLE(inode)) | 1838 | if (/* (acc & MAY_WRITE) && */ IS_IMMUTABLE(inode)) |
1838 | return nfserr_perm; | 1839 | return nfserr_perm; |
diff --git a/include/linux/nfsd/export.h b/include/linux/nfsd/export.h index 424be41130ba..a01f775cb944 100644 --- a/include/linux/nfsd/export.h +++ b/include/linux/nfsd/export.h | |||
@@ -112,10 +112,21 @@ struct svc_expkey { | |||
112 | 112 | ||
113 | #define EX_SECURE(exp) (!((exp)->ex_flags & NFSEXP_INSECURE_PORT)) | 113 | #define EX_SECURE(exp) (!((exp)->ex_flags & NFSEXP_INSECURE_PORT)) |
114 | #define EX_ISSYNC(exp) (!((exp)->ex_flags & NFSEXP_ASYNC)) | 114 | #define EX_ISSYNC(exp) (!((exp)->ex_flags & NFSEXP_ASYNC)) |
115 | #define EX_RDONLY(exp) ((exp)->ex_flags & NFSEXP_READONLY) | ||
116 | #define EX_NOHIDE(exp) ((exp)->ex_flags & NFSEXP_NOHIDE) | 115 | #define EX_NOHIDE(exp) ((exp)->ex_flags & NFSEXP_NOHIDE) |
117 | #define EX_WGATHER(exp) ((exp)->ex_flags & NFSEXP_GATHERED_WRITES) | 116 | #define EX_WGATHER(exp) ((exp)->ex_flags & NFSEXP_GATHERED_WRITES) |
118 | 117 | ||
118 | static inline int EX_RDONLY(struct svc_export *exp, struct svc_rqst *rqstp) | ||
119 | { | ||
120 | struct exp_flavor_info *f; | ||
121 | struct exp_flavor_info *end = exp->ex_flavors + exp->ex_nflavors; | ||
122 | |||
123 | for (f = exp->ex_flavors; f < end; f++) { | ||
124 | if (f->pseudoflavor == rqstp->rq_flavor) | ||
125 | return f->flags & NFSEXP_READONLY; | ||
126 | } | ||
127 | return exp->ex_flags & NFSEXP_READONLY; | ||
128 | } | ||
129 | |||
119 | __be32 check_nfsd_access(struct svc_export *exp, struct svc_rqst *rqstp); | 130 | __be32 check_nfsd_access(struct svc_export *exp, struct svc_rqst *rqstp); |
120 | 131 | ||
121 | /* | 132 | /* |
diff --git a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h index 62499c2f0918..54ef1a18a56c 100644 --- a/include/linux/nfsd/nfsd.h +++ b/include/linux/nfsd/nfsd.h | |||
@@ -119,7 +119,8 @@ __be32 nfsd_statfs(struct svc_rqst *, struct svc_fh *, | |||
119 | struct kstatfs *); | 119 | struct kstatfs *); |
120 | 120 | ||
121 | int nfsd_notify_change(struct inode *, struct iattr *); | 121 | int nfsd_notify_change(struct inode *, struct iattr *); |
122 | __be32 nfsd_permission(struct svc_export *, struct dentry *, int); | 122 | __be32 nfsd_permission(struct svc_rqst *, struct svc_export *, |
123 | struct dentry *, int); | ||
123 | int nfsd_sync_dir(struct dentry *dp); | 124 | int nfsd_sync_dir(struct dentry *dp); |
124 | 125 | ||
125 | #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) | 126 | #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) |