Blame view
fs/nfsd/nfs3acl.c
6.29 KB
a257cdd0e [PATCH] NFSD: Add... |
1 |
/* |
a257cdd0e [PATCH] NFSD: Add... |
2 3 4 5 |
* Process version 3 NFSACL requests. * * Copyright (C) 2002-2003 Andreas Gruenbacher <agruen@suse.de> */ |
9a74af213 nfsd: Move privat... |
6 7 |
#include "nfsd.h" /* FIXME: nfsacl.h is a broken header */ |
a257cdd0e [PATCH] NFSD: Add... |
8 |
#include <linux/nfsacl.h> |
5a0e3ad6a include cleanup: ... |
9 |
#include <linux/gfp.h> |
9a74af213 nfsd: Move privat... |
10 11 |
#include "cache.h" #include "xdr3.h" |
0a3adadee nfsd: make fs/nfs... |
12 |
#include "vfs.h" |
a257cdd0e [PATCH] NFSD: Add... |
13 14 15 16 17 18 |
#define RETURN_STATUS(st) { resp->status = (st); return (st); } /* * NULL call. */ |
7111c66e4 [PATCH] fix svc_p... |
19 |
static __be32 |
a257cdd0e [PATCH] NFSD: Add... |
20 21 22 23 24 25 26 27 |
nfsd3_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) { return nfs_ok; } /* * Get the Access and/or Default ACL of a file. */ |
7111c66e4 [PATCH] fix svc_p... |
28 |
static __be32 nfsd3_proc_getacl(struct svc_rqst * rqstp, |
a257cdd0e [PATCH] NFSD: Add... |
29 30 |
struct nfsd3_getaclargs *argp, struct nfsd3_getaclres *resp) { |
a257cdd0e [PATCH] NFSD: Add... |
31 |
struct posix_acl *acl; |
4ac7249ea nfsd: use get_acl... |
32 33 |
struct inode *inode; svc_fh *fh; |
c4d987ba8 [PATCH] nfsd: NFS... |
34 |
__be32 nfserr = 0; |
a257cdd0e [PATCH] NFSD: Add... |
35 36 |
fh = fh_copy(&resp->fh, &argp->fh); |
8837abcab nfsd: rename MAY_... |
37 38 |
nfserr = fh_verify(rqstp, &resp->fh, 0, NFSD_MAY_NOP); if (nfserr) |
ac8587dcb knfsd: fix spurio... |
39 |
RETURN_STATUS(nfserr); |
a257cdd0e [PATCH] NFSD: Add... |
40 |
|
2b0143b5c VFS: normal files... |
41 |
inode = d_inode(fh->fh_dentry); |
4ac7249ea nfsd: use get_acl... |
42 |
|
7b8f45865 nfsd: Add macro N... |
43 |
if (argp->mask & ~NFS_ACL_MASK) |
a257cdd0e [PATCH] NFSD: Add... |
44 45 46 47 |
RETURN_STATUS(nfserr_inval); resp->mask = argp->mask; if (resp->mask & (NFS_ACL|NFS_ACLCNT)) { |
4ac7249ea nfsd: use get_acl... |
48 |
acl = get_acl(inode, ACL_TYPE_ACCESS); |
a257cdd0e [PATCH] NFSD: Add... |
49 50 |
if (acl == NULL) { /* Solaris returns the inode's minimum ACL. */ |
a257cdd0e [PATCH] NFSD: Add... |
51 52 |
acl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL); } |
35e634b83 NFSD: Check acl r... |
53 54 55 56 |
if (IS_ERR(acl)) { nfserr = nfserrno(PTR_ERR(acl)); goto fail; } |
a257cdd0e [PATCH] NFSD: Add... |
57 58 59 60 61 |
resp->acl_access = acl; } if (resp->mask & (NFS_DFACL|NFS_DFACLCNT)) { /* Check how Solaris handles requests for the Default ACL of a non-directory! */ |
4ac7249ea nfsd: use get_acl... |
62 |
acl = get_acl(inode, ACL_TYPE_DEFAULT); |
a257cdd0e [PATCH] NFSD: Add... |
63 |
if (IS_ERR(acl)) { |
4ac7249ea nfsd: use get_acl... |
64 65 |
nfserr = nfserrno(PTR_ERR(acl)); goto fail; |
a257cdd0e [PATCH] NFSD: Add... |
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
} resp->acl_default = acl; } /* resp->acl_{access,default} are released in nfs3svc_release_getacl. */ RETURN_STATUS(0); fail: posix_acl_release(resp->acl_access); posix_acl_release(resp->acl_default); RETURN_STATUS(nfserr); } /* * Set the Access and/or Default ACL of a file. */ |
7111c66e4 [PATCH] fix svc_p... |
82 |
static __be32 nfsd3_proc_setacl(struct svc_rqst * rqstp, |
a257cdd0e [PATCH] NFSD: Add... |
83 84 85 |
struct nfsd3_setaclargs *argp, struct nfsd3_attrstat *resp) { |
4ac7249ea nfsd: use get_acl... |
86 |
struct inode *inode; |
a257cdd0e [PATCH] NFSD: Add... |
87 |
svc_fh *fh; |
c4d987ba8 [PATCH] nfsd: NFS... |
88 |
__be32 nfserr = 0; |
4ac7249ea nfsd: use get_acl... |
89 |
int error; |
a257cdd0e [PATCH] NFSD: Add... |
90 91 |
fh = fh_copy(&resp->fh, &argp->fh); |
8837abcab nfsd: rename MAY_... |
92 |
nfserr = fh_verify(rqstp, &resp->fh, 0, NFSD_MAY_SATTR); |
4ac7249ea nfsd: use get_acl... |
93 94 |
if (nfserr) goto out; |
a257cdd0e [PATCH] NFSD: Add... |
95 |
|
2b0143b5c VFS: normal files... |
96 |
inode = d_inode(fh->fh_dentry); |
a257cdd0e [PATCH] NFSD: Add... |
97 |
|
4ac7249ea nfsd: use get_acl... |
98 99 100 |
error = fh_want_write(fh); if (error) goto out_errno; |
999653786 nfsd: check permi... |
101 102 103 |
fh_lock(fh); error = set_posix_acl(inode, ACL_TYPE_ACCESS, argp->acl_access); |
4ac7249ea nfsd: use get_acl... |
104 |
if (error) |
999653786 nfsd: check permi... |
105 106 |
goto out_drop_lock; error = set_posix_acl(inode, ACL_TYPE_DEFAULT, argp->acl_default); |
4ac7249ea nfsd: use get_acl... |
107 |
|
999653786 nfsd: check permi... |
108 109 |
out_drop_lock: fh_unlock(fh); |
4ac7249ea nfsd: use get_acl... |
110 111 112 113 |
fh_drop_write(fh); out_errno: nfserr = nfserrno(error); out: |
a257cdd0e [PATCH] NFSD: Add... |
114 115 116 117 118 119 120 121 122 123 |
/* argp->acl_{access,default} may have been allocated in nfs3svc_decode_setaclargs. */ posix_acl_release(argp->acl_access); posix_acl_release(argp->acl_default); RETURN_STATUS(nfserr); } /* * XDR decode functions */ |
91f07168c [PATCH] xdr annot... |
124 |
static int nfs3svc_decode_getaclargs(struct svc_rqst *rqstp, __be32 *p, |
a257cdd0e [PATCH] NFSD: Add... |
125 126 |
struct nfsd3_getaclargs *args) { |
d40aa3372 nfsd: Remove assi... |
127 128 |
p = nfs3svc_decode_fh(p, &args->fh); if (!p) |
a257cdd0e [PATCH] NFSD: Add... |
129 130 131 132 133 |
return 0; args->mask = ntohl(*p); p++; return xdr_argsize_check(rqstp, p); } |
91f07168c [PATCH] xdr annot... |
134 |
static int nfs3svc_decode_setaclargs(struct svc_rqst *rqstp, __be32 *p, |
a257cdd0e [PATCH] NFSD: Add... |
135 136 137 138 139 |
struct nfsd3_setaclargs *args) { struct kvec *head = rqstp->rq_arg.head; unsigned int base; int n; |
d40aa3372 nfsd: Remove assi... |
140 141 |
p = nfs3svc_decode_fh(p, &args->fh); if (!p) |
a257cdd0e [PATCH] NFSD: Add... |
142 143 |
return 0; args->mask = ntohl(*p++); |
7b8f45865 nfsd: Add macro N... |
144 |
if (args->mask & ~NFS_ACL_MASK || |
a257cdd0e [PATCH] NFSD: Add... |
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
!xdr_argsize_check(rqstp, p)) return 0; base = (char *)p - (char *)head->iov_base; n = nfsacl_decode(&rqstp->rq_arg, base, NULL, (args->mask & NFS_ACL) ? &args->acl_access : NULL); if (n > 0) n = nfsacl_decode(&rqstp->rq_arg, base + n, NULL, (args->mask & NFS_DFACL) ? &args->acl_default : NULL); return (n > 0); } /* * XDR encode functions */ /* GETACL */ |
91f07168c [PATCH] xdr annot... |
164 |
static int nfs3svc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p, |
a257cdd0e [PATCH] NFSD: Add... |
165 166 167 168 169 |
struct nfsd3_getaclres *resp) { struct dentry *dentry = resp->fh.fh_dentry; p = nfs3svc_encode_post_op_attr(rqstp, p, &resp->fh); |
2b0143b5c VFS: normal files... |
170 171 |
if (resp->status == 0 && dentry && d_really_is_positive(dentry)) { struct inode *inode = d_inode(dentry); |
a257cdd0e [PATCH] NFSD: Add... |
172 173 174 |
struct kvec *head = rqstp->rq_res.head; unsigned int base; int n; |
14d2b59e8 [PATCH] NFS3: Cal... |
175 |
int w; |
a257cdd0e [PATCH] NFSD: Add... |
176 177 178 179 180 |
*p++ = htonl(resp->mask); if (!xdr_ressize_check(rqstp, p)) return 0; base = (char *)p - (char *)head->iov_base; |
14d2b59e8 [PATCH] NFS3: Cal... |
181 182 183 |
rqstp->rq_res.page_len = w = nfsacl_size( (resp->mask & NFS_ACL) ? resp->acl_access : NULL, (resp->mask & NFS_DFACL) ? resp->acl_default : NULL); |
a257cdd0e [PATCH] NFSD: Add... |
184 |
while (w > 0) { |
afc59400d nfsd4: cleanup: r... |
185 |
if (!*(rqstp->rq_next_page++)) |
a257cdd0e [PATCH] NFSD: Add... |
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
return 0; w -= PAGE_SIZE; } n = nfsacl_encode(&rqstp->rq_res, base, inode, resp->acl_access, resp->mask & NFS_ACL, 0); if (n > 0) n = nfsacl_encode(&rqstp->rq_res, base + n, inode, resp->acl_default, resp->mask & NFS_DFACL, NFS_ACL_DEFAULT); if (n <= 0) return 0; } else if (!xdr_ressize_check(rqstp, p)) return 0; return 1; } /* SETACL */ |
91f07168c [PATCH] xdr annot... |
208 |
static int nfs3svc_encode_setaclres(struct svc_rqst *rqstp, __be32 *p, |
a257cdd0e [PATCH] NFSD: Add... |
209 210 211 212 213 214 215 216 217 218 |
struct nfsd3_attrstat *resp) { p = nfs3svc_encode_post_op_attr(rqstp, p, &resp->fh); return xdr_ressize_check(rqstp, p); } /* * XDR release functions */ |
91f07168c [PATCH] xdr annot... |
219 |
static int nfs3svc_release_getacl(struct svc_rqst *rqstp, __be32 *p, |
a257cdd0e [PATCH] NFSD: Add... |
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 |
struct nfsd3_getaclres *resp) { fh_put(&resp->fh); posix_acl_release(resp->acl_access); posix_acl_release(resp->acl_default); return 1; } #define nfs3svc_decode_voidargs NULL #define nfs3svc_release_void NULL #define nfsd3_setaclres nfsd3_attrstat #define nfsd3_voidres nfsd3_voidargs struct nfsd3_voidargs { int dummy; }; #define PROC(name, argt, rest, relt, cache, respsize) \ { (svc_procfunc) nfsd3_proc_##name, \ (kxdrproc_t) nfs3svc_decode_##argt##args, \ (kxdrproc_t) nfs3svc_encode_##rest##res, \ (kxdrproc_t) nfs3svc_release_##relt, \ sizeof(struct nfsd3_##argt##args), \ sizeof(struct nfsd3_##rest##res), \ 0, \ cache, \ respsize, \ } #define ST 1 /* status*/ #define AT 21 /* attributes */ #define pAT (1+AT) /* post attributes - conditional */ #define ACL (1+NFS_ACL_MAX_ENTRIES*3) /* Access Control List */ static struct svc_procedure nfsd_acl_procedures3[] = { PROC(null, void, void, void, RC_NOCACHE, ST), PROC(getacl, getacl, getacl, getacl, RC_NOCACHE, ST+1+2*(1+ACL)), PROC(setacl, setacl, setacl, fhandle, RC_NOCACHE, ST+pAT), }; struct svc_version nfsd_acl_version3 = { .vs_vers = 3, .vs_nproc = 3, .vs_proc = nfsd_acl_procedures3, .vs_dispatch = nfsd_dispatch, .vs_xdrsize = NFS3_SVC_XDRSIZE, |
1b7e0403c nfsd: register NF... |
263 |
.vs_hidden = 0, |
a257cdd0e [PATCH] NFSD: Add... |
264 |
}; |