xref: /openbmc/linux/fs/nfsd/nfs2acl.c (revision a257cdd0e2179630d3201c32ba14d7fcb3c3a055)
1*a257cdd0SAndreas Gruenbacher /*
2*a257cdd0SAndreas Gruenbacher  * linux/fs/nfsd/nfsacl.c
3*a257cdd0SAndreas Gruenbacher  *
4*a257cdd0SAndreas Gruenbacher  * Process version 2 NFSACL requests.
5*a257cdd0SAndreas Gruenbacher  *
6*a257cdd0SAndreas Gruenbacher  * Copyright (C) 2002-2003 Andreas Gruenbacher <agruen@suse.de>
7*a257cdd0SAndreas Gruenbacher  */
8*a257cdd0SAndreas Gruenbacher 
9*a257cdd0SAndreas Gruenbacher #include <linux/sunrpc/svc.h>
10*a257cdd0SAndreas Gruenbacher #include <linux/nfs.h>
11*a257cdd0SAndreas Gruenbacher #include <linux/nfsd/nfsd.h>
12*a257cdd0SAndreas Gruenbacher #include <linux/nfsd/cache.h>
13*a257cdd0SAndreas Gruenbacher #include <linux/nfsd/xdr.h>
14*a257cdd0SAndreas Gruenbacher #include <linux/nfsd/xdr3.h>
15*a257cdd0SAndreas Gruenbacher #include <linux/posix_acl.h>
16*a257cdd0SAndreas Gruenbacher #include <linux/nfsacl.h>
17*a257cdd0SAndreas Gruenbacher 
18*a257cdd0SAndreas Gruenbacher #define NFSDDBG_FACILITY		NFSDDBG_PROC
19*a257cdd0SAndreas Gruenbacher #define RETURN_STATUS(st)	{ resp->status = (st); return (st); }
20*a257cdd0SAndreas Gruenbacher 
21*a257cdd0SAndreas Gruenbacher /*
22*a257cdd0SAndreas Gruenbacher  * NULL call.
23*a257cdd0SAndreas Gruenbacher  */
24*a257cdd0SAndreas Gruenbacher static int
25*a257cdd0SAndreas Gruenbacher nfsacld_proc_null(struct svc_rqst *rqstp, void *argp, void *resp)
26*a257cdd0SAndreas Gruenbacher {
27*a257cdd0SAndreas Gruenbacher 	return nfs_ok;
28*a257cdd0SAndreas Gruenbacher }
29*a257cdd0SAndreas Gruenbacher 
30*a257cdd0SAndreas Gruenbacher /*
31*a257cdd0SAndreas Gruenbacher  * Get the Access and/or Default ACL of a file.
32*a257cdd0SAndreas Gruenbacher  */
33*a257cdd0SAndreas Gruenbacher static int nfsacld_proc_getacl(struct svc_rqst * rqstp,
34*a257cdd0SAndreas Gruenbacher 		struct nfsd3_getaclargs *argp, struct nfsd3_getaclres *resp)
35*a257cdd0SAndreas Gruenbacher {
36*a257cdd0SAndreas Gruenbacher 	svc_fh *fh;
37*a257cdd0SAndreas Gruenbacher 	struct posix_acl *acl;
38*a257cdd0SAndreas Gruenbacher 	int nfserr = 0;
39*a257cdd0SAndreas Gruenbacher 
40*a257cdd0SAndreas Gruenbacher 	dprintk("nfsd: GETACL(2acl)   %s\n", SVCFH_fmt(&argp->fh));
41*a257cdd0SAndreas Gruenbacher 
42*a257cdd0SAndreas Gruenbacher 	fh = fh_copy(&resp->fh, &argp->fh);
43*a257cdd0SAndreas Gruenbacher 	if ((nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_NOP)))
44*a257cdd0SAndreas Gruenbacher 		RETURN_STATUS(nfserr_inval);
45*a257cdd0SAndreas Gruenbacher 
46*a257cdd0SAndreas Gruenbacher 	if (argp->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT))
47*a257cdd0SAndreas Gruenbacher 		RETURN_STATUS(nfserr_inval);
48*a257cdd0SAndreas Gruenbacher 	resp->mask = argp->mask;
49*a257cdd0SAndreas Gruenbacher 
50*a257cdd0SAndreas Gruenbacher 	if (resp->mask & (NFS_ACL|NFS_ACLCNT)) {
51*a257cdd0SAndreas Gruenbacher 		acl = nfsd_get_posix_acl(fh, ACL_TYPE_ACCESS);
52*a257cdd0SAndreas Gruenbacher 		if (IS_ERR(acl)) {
53*a257cdd0SAndreas Gruenbacher 			int err = PTR_ERR(acl);
54*a257cdd0SAndreas Gruenbacher 
55*a257cdd0SAndreas Gruenbacher 			if (err == -ENODATA || err == -EOPNOTSUPP)
56*a257cdd0SAndreas Gruenbacher 				acl = NULL;
57*a257cdd0SAndreas Gruenbacher 			else {
58*a257cdd0SAndreas Gruenbacher 				nfserr = nfserrno(err);
59*a257cdd0SAndreas Gruenbacher 				goto fail;
60*a257cdd0SAndreas Gruenbacher 			}
61*a257cdd0SAndreas Gruenbacher 		}
62*a257cdd0SAndreas Gruenbacher 		if (acl == NULL) {
63*a257cdd0SAndreas Gruenbacher 			/* Solaris returns the inode's minimum ACL. */
64*a257cdd0SAndreas Gruenbacher 
65*a257cdd0SAndreas Gruenbacher 			struct inode *inode = fh->fh_dentry->d_inode;
66*a257cdd0SAndreas Gruenbacher 			acl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL);
67*a257cdd0SAndreas Gruenbacher 		}
68*a257cdd0SAndreas Gruenbacher 		resp->acl_access = acl;
69*a257cdd0SAndreas Gruenbacher 	}
70*a257cdd0SAndreas Gruenbacher 	if (resp->mask & (NFS_DFACL|NFS_DFACLCNT)) {
71*a257cdd0SAndreas Gruenbacher 		/* Check how Solaris handles requests for the Default ACL
72*a257cdd0SAndreas Gruenbacher 		   of a non-directory! */
73*a257cdd0SAndreas Gruenbacher 
74*a257cdd0SAndreas Gruenbacher 		acl = nfsd_get_posix_acl(fh, ACL_TYPE_DEFAULT);
75*a257cdd0SAndreas Gruenbacher 		if (IS_ERR(acl)) {
76*a257cdd0SAndreas Gruenbacher 			int err = PTR_ERR(acl);
77*a257cdd0SAndreas Gruenbacher 
78*a257cdd0SAndreas Gruenbacher 			if (err == -ENODATA || err == -EOPNOTSUPP)
79*a257cdd0SAndreas Gruenbacher 				acl = NULL;
80*a257cdd0SAndreas Gruenbacher 			else {
81*a257cdd0SAndreas Gruenbacher 				nfserr = nfserrno(err);
82*a257cdd0SAndreas Gruenbacher 				goto fail;
83*a257cdd0SAndreas Gruenbacher 			}
84*a257cdd0SAndreas Gruenbacher 		}
85*a257cdd0SAndreas Gruenbacher 		resp->acl_default = acl;
86*a257cdd0SAndreas Gruenbacher 	}
87*a257cdd0SAndreas Gruenbacher 
88*a257cdd0SAndreas Gruenbacher 	/* resp->acl_{access,default} are released in nfssvc_release_getacl. */
89*a257cdd0SAndreas Gruenbacher 	RETURN_STATUS(0);
90*a257cdd0SAndreas Gruenbacher 
91*a257cdd0SAndreas Gruenbacher fail:
92*a257cdd0SAndreas Gruenbacher 	posix_acl_release(resp->acl_access);
93*a257cdd0SAndreas Gruenbacher 	posix_acl_release(resp->acl_default);
94*a257cdd0SAndreas Gruenbacher 	RETURN_STATUS(nfserr);
95*a257cdd0SAndreas Gruenbacher }
96*a257cdd0SAndreas Gruenbacher 
97*a257cdd0SAndreas Gruenbacher /*
98*a257cdd0SAndreas Gruenbacher  * Set the Access and/or Default ACL of a file.
99*a257cdd0SAndreas Gruenbacher  */
100*a257cdd0SAndreas Gruenbacher static int nfsacld_proc_setacl(struct svc_rqst * rqstp,
101*a257cdd0SAndreas Gruenbacher 		struct nfsd3_setaclargs *argp,
102*a257cdd0SAndreas Gruenbacher 		struct nfsd_attrstat *resp)
103*a257cdd0SAndreas Gruenbacher {
104*a257cdd0SAndreas Gruenbacher 	svc_fh *fh;
105*a257cdd0SAndreas Gruenbacher 	int nfserr = 0;
106*a257cdd0SAndreas Gruenbacher 
107*a257cdd0SAndreas Gruenbacher 	dprintk("nfsd: SETACL(2acl)   %s\n", SVCFH_fmt(&argp->fh));
108*a257cdd0SAndreas Gruenbacher 
109*a257cdd0SAndreas Gruenbacher 	fh = fh_copy(&resp->fh, &argp->fh);
110*a257cdd0SAndreas Gruenbacher 	nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_NOP);
111*a257cdd0SAndreas Gruenbacher 
112*a257cdd0SAndreas Gruenbacher 	if (!nfserr) {
113*a257cdd0SAndreas Gruenbacher 		nfserr = nfserrno( nfsd_set_posix_acl(
114*a257cdd0SAndreas Gruenbacher 			fh, ACL_TYPE_ACCESS, argp->acl_access) );
115*a257cdd0SAndreas Gruenbacher 	}
116*a257cdd0SAndreas Gruenbacher 	if (!nfserr) {
117*a257cdd0SAndreas Gruenbacher 		nfserr = nfserrno( nfsd_set_posix_acl(
118*a257cdd0SAndreas Gruenbacher 			fh, ACL_TYPE_DEFAULT, argp->acl_default) );
119*a257cdd0SAndreas Gruenbacher 	}
120*a257cdd0SAndreas Gruenbacher 
121*a257cdd0SAndreas Gruenbacher 	/* argp->acl_{access,default} may have been allocated in
122*a257cdd0SAndreas Gruenbacher 	   nfssvc_decode_setaclargs. */
123*a257cdd0SAndreas Gruenbacher 	posix_acl_release(argp->acl_access);
124*a257cdd0SAndreas Gruenbacher 	posix_acl_release(argp->acl_default);
125*a257cdd0SAndreas Gruenbacher 	return nfserr;
126*a257cdd0SAndreas Gruenbacher }
127*a257cdd0SAndreas Gruenbacher 
128*a257cdd0SAndreas Gruenbacher /*
129*a257cdd0SAndreas Gruenbacher  * Check file attributes
130*a257cdd0SAndreas Gruenbacher  */
131*a257cdd0SAndreas Gruenbacher static int nfsacld_proc_getattr(struct svc_rqst * rqstp,
132*a257cdd0SAndreas Gruenbacher 		struct nfsd_fhandle *argp, struct nfsd_attrstat *resp)
133*a257cdd0SAndreas Gruenbacher {
134*a257cdd0SAndreas Gruenbacher 	dprintk("nfsd: GETATTR  %s\n", SVCFH_fmt(&argp->fh));
135*a257cdd0SAndreas Gruenbacher 
136*a257cdd0SAndreas Gruenbacher 	fh_copy(&resp->fh, &argp->fh);
137*a257cdd0SAndreas Gruenbacher 	return fh_verify(rqstp, &resp->fh, 0, MAY_NOP);
138*a257cdd0SAndreas Gruenbacher }
139*a257cdd0SAndreas Gruenbacher 
140*a257cdd0SAndreas Gruenbacher /*
141*a257cdd0SAndreas Gruenbacher  * Check file access
142*a257cdd0SAndreas Gruenbacher  */
143*a257cdd0SAndreas Gruenbacher static int nfsacld_proc_access(struct svc_rqst *rqstp, struct nfsd3_accessargs *argp,
144*a257cdd0SAndreas Gruenbacher 		struct nfsd3_accessres *resp)
145*a257cdd0SAndreas Gruenbacher {
146*a257cdd0SAndreas Gruenbacher 	int nfserr;
147*a257cdd0SAndreas Gruenbacher 
148*a257cdd0SAndreas Gruenbacher 	dprintk("nfsd: ACCESS(2acl)   %s 0x%x\n",
149*a257cdd0SAndreas Gruenbacher 			SVCFH_fmt(&argp->fh),
150*a257cdd0SAndreas Gruenbacher 			argp->access);
151*a257cdd0SAndreas Gruenbacher 
152*a257cdd0SAndreas Gruenbacher 	fh_copy(&resp->fh, &argp->fh);
153*a257cdd0SAndreas Gruenbacher 	resp->access = argp->access;
154*a257cdd0SAndreas Gruenbacher 	nfserr = nfsd_access(rqstp, &resp->fh, &resp->access, NULL);
155*a257cdd0SAndreas Gruenbacher 	return nfserr;
156*a257cdd0SAndreas Gruenbacher }
157*a257cdd0SAndreas Gruenbacher 
158*a257cdd0SAndreas Gruenbacher /*
159*a257cdd0SAndreas Gruenbacher  * XDR decode functions
160*a257cdd0SAndreas Gruenbacher  */
161*a257cdd0SAndreas Gruenbacher static int nfsaclsvc_decode_getaclargs(struct svc_rqst *rqstp, u32 *p,
162*a257cdd0SAndreas Gruenbacher 		struct nfsd3_getaclargs *argp)
163*a257cdd0SAndreas Gruenbacher {
164*a257cdd0SAndreas Gruenbacher 	if (!(p = nfs2svc_decode_fh(p, &argp->fh)))
165*a257cdd0SAndreas Gruenbacher 		return 0;
166*a257cdd0SAndreas Gruenbacher 	argp->mask = ntohl(*p); p++;
167*a257cdd0SAndreas Gruenbacher 
168*a257cdd0SAndreas Gruenbacher 	return xdr_argsize_check(rqstp, p);
169*a257cdd0SAndreas Gruenbacher }
170*a257cdd0SAndreas Gruenbacher 
171*a257cdd0SAndreas Gruenbacher 
172*a257cdd0SAndreas Gruenbacher static int nfsaclsvc_decode_setaclargs(struct svc_rqst *rqstp, u32 *p,
173*a257cdd0SAndreas Gruenbacher 		struct nfsd3_setaclargs *argp)
174*a257cdd0SAndreas Gruenbacher {
175*a257cdd0SAndreas Gruenbacher 	struct kvec *head = rqstp->rq_arg.head;
176*a257cdd0SAndreas Gruenbacher 	unsigned int base;
177*a257cdd0SAndreas Gruenbacher 	int n;
178*a257cdd0SAndreas Gruenbacher 
179*a257cdd0SAndreas Gruenbacher 	if (!(p = nfs2svc_decode_fh(p, &argp->fh)))
180*a257cdd0SAndreas Gruenbacher 		return 0;
181*a257cdd0SAndreas Gruenbacher 	argp->mask = ntohl(*p++);
182*a257cdd0SAndreas Gruenbacher 	if (argp->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT) ||
183*a257cdd0SAndreas Gruenbacher 	    !xdr_argsize_check(rqstp, p))
184*a257cdd0SAndreas Gruenbacher 		return 0;
185*a257cdd0SAndreas Gruenbacher 
186*a257cdd0SAndreas Gruenbacher 	base = (char *)p - (char *)head->iov_base;
187*a257cdd0SAndreas Gruenbacher 	n = nfsacl_decode(&rqstp->rq_arg, base, NULL,
188*a257cdd0SAndreas Gruenbacher 			  (argp->mask & NFS_ACL) ?
189*a257cdd0SAndreas Gruenbacher 			  &argp->acl_access : NULL);
190*a257cdd0SAndreas Gruenbacher 	if (n > 0)
191*a257cdd0SAndreas Gruenbacher 		n = nfsacl_decode(&rqstp->rq_arg, base + n, NULL,
192*a257cdd0SAndreas Gruenbacher 				  (argp->mask & NFS_DFACL) ?
193*a257cdd0SAndreas Gruenbacher 				  &argp->acl_default : NULL);
194*a257cdd0SAndreas Gruenbacher 	return (n > 0);
195*a257cdd0SAndreas Gruenbacher }
196*a257cdd0SAndreas Gruenbacher 
197*a257cdd0SAndreas Gruenbacher static int nfsaclsvc_decode_fhandleargs(struct svc_rqst *rqstp, u32 *p,
198*a257cdd0SAndreas Gruenbacher 		struct nfsd_fhandle *argp)
199*a257cdd0SAndreas Gruenbacher {
200*a257cdd0SAndreas Gruenbacher 	if (!(p = nfs2svc_decode_fh(p, &argp->fh)))
201*a257cdd0SAndreas Gruenbacher 		return 0;
202*a257cdd0SAndreas Gruenbacher 	return xdr_argsize_check(rqstp, p);
203*a257cdd0SAndreas Gruenbacher }
204*a257cdd0SAndreas Gruenbacher 
205*a257cdd0SAndreas Gruenbacher static int nfsaclsvc_decode_accessargs(struct svc_rqst *rqstp, u32 *p,
206*a257cdd0SAndreas Gruenbacher 		struct nfsd3_accessargs *argp)
207*a257cdd0SAndreas Gruenbacher {
208*a257cdd0SAndreas Gruenbacher 	if (!(p = nfs2svc_decode_fh(p, &argp->fh)))
209*a257cdd0SAndreas Gruenbacher 		return 0;
210*a257cdd0SAndreas Gruenbacher 	argp->access = ntohl(*p++);
211*a257cdd0SAndreas Gruenbacher 
212*a257cdd0SAndreas Gruenbacher 	return xdr_argsize_check(rqstp, p);
213*a257cdd0SAndreas Gruenbacher }
214*a257cdd0SAndreas Gruenbacher 
215*a257cdd0SAndreas Gruenbacher /*
216*a257cdd0SAndreas Gruenbacher  * XDR encode functions
217*a257cdd0SAndreas Gruenbacher  */
218*a257cdd0SAndreas Gruenbacher 
219*a257cdd0SAndreas Gruenbacher /* GETACL */
220*a257cdd0SAndreas Gruenbacher static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, u32 *p,
221*a257cdd0SAndreas Gruenbacher 		struct nfsd3_getaclres *resp)
222*a257cdd0SAndreas Gruenbacher {
223*a257cdd0SAndreas Gruenbacher 	struct dentry *dentry = resp->fh.fh_dentry;
224*a257cdd0SAndreas Gruenbacher 	struct inode *inode = dentry->d_inode;
225*a257cdd0SAndreas Gruenbacher 	int w = nfsacl_size(
226*a257cdd0SAndreas Gruenbacher 		(resp->mask & NFS_ACL)   ? resp->acl_access  : NULL,
227*a257cdd0SAndreas Gruenbacher 		(resp->mask & NFS_DFACL) ? resp->acl_default : NULL);
228*a257cdd0SAndreas Gruenbacher 	struct kvec *head = rqstp->rq_res.head;
229*a257cdd0SAndreas Gruenbacher 	unsigned int base;
230*a257cdd0SAndreas Gruenbacher 	int n;
231*a257cdd0SAndreas Gruenbacher 
232*a257cdd0SAndreas Gruenbacher 	if (dentry == NULL || dentry->d_inode == NULL)
233*a257cdd0SAndreas Gruenbacher 		return 0;
234*a257cdd0SAndreas Gruenbacher 	inode = dentry->d_inode;
235*a257cdd0SAndreas Gruenbacher 
236*a257cdd0SAndreas Gruenbacher 	p = nfs2svc_encode_fattr(rqstp, p, &resp->fh);
237*a257cdd0SAndreas Gruenbacher 	*p++ = htonl(resp->mask);
238*a257cdd0SAndreas Gruenbacher 	if (!xdr_ressize_check(rqstp, p))
239*a257cdd0SAndreas Gruenbacher 		return 0;
240*a257cdd0SAndreas Gruenbacher 	base = (char *)p - (char *)head->iov_base;
241*a257cdd0SAndreas Gruenbacher 
242*a257cdd0SAndreas Gruenbacher 	rqstp->rq_res.page_len = w;
243*a257cdd0SAndreas Gruenbacher 	while (w > 0) {
244*a257cdd0SAndreas Gruenbacher 		if (!svc_take_res_page(rqstp))
245*a257cdd0SAndreas Gruenbacher 			return 0;
246*a257cdd0SAndreas Gruenbacher 		w -= PAGE_SIZE;
247*a257cdd0SAndreas Gruenbacher 	}
248*a257cdd0SAndreas Gruenbacher 
249*a257cdd0SAndreas Gruenbacher 	n = nfsacl_encode(&rqstp->rq_res, base, inode,
250*a257cdd0SAndreas Gruenbacher 			  resp->acl_access,
251*a257cdd0SAndreas Gruenbacher 			  resp->mask & NFS_ACL, 0);
252*a257cdd0SAndreas Gruenbacher 	if (n > 0)
253*a257cdd0SAndreas Gruenbacher 		n = nfsacl_encode(&rqstp->rq_res, base + n, inode,
254*a257cdd0SAndreas Gruenbacher 				  resp->acl_default,
255*a257cdd0SAndreas Gruenbacher 				  resp->mask & NFS_DFACL,
256*a257cdd0SAndreas Gruenbacher 				  NFS_ACL_DEFAULT);
257*a257cdd0SAndreas Gruenbacher 	if (n <= 0)
258*a257cdd0SAndreas Gruenbacher 		return 0;
259*a257cdd0SAndreas Gruenbacher 	return 1;
260*a257cdd0SAndreas Gruenbacher }
261*a257cdd0SAndreas Gruenbacher 
262*a257cdd0SAndreas Gruenbacher static int nfsaclsvc_encode_attrstatres(struct svc_rqst *rqstp, u32 *p,
263*a257cdd0SAndreas Gruenbacher 		struct nfsd_attrstat *resp)
264*a257cdd0SAndreas Gruenbacher {
265*a257cdd0SAndreas Gruenbacher 	p = nfs2svc_encode_fattr(rqstp, p, &resp->fh);
266*a257cdd0SAndreas Gruenbacher 	return xdr_ressize_check(rqstp, p);
267*a257cdd0SAndreas Gruenbacher }
268*a257cdd0SAndreas Gruenbacher 
269*a257cdd0SAndreas Gruenbacher /* ACCESS */
270*a257cdd0SAndreas Gruenbacher static int nfsaclsvc_encode_accessres(struct svc_rqst *rqstp, u32 *p,
271*a257cdd0SAndreas Gruenbacher 		struct nfsd3_accessres *resp)
272*a257cdd0SAndreas Gruenbacher {
273*a257cdd0SAndreas Gruenbacher 	p = nfs2svc_encode_fattr(rqstp, p, &resp->fh);
274*a257cdd0SAndreas Gruenbacher 	*p++ = htonl(resp->access);
275*a257cdd0SAndreas Gruenbacher 	return xdr_ressize_check(rqstp, p);
276*a257cdd0SAndreas Gruenbacher }
277*a257cdd0SAndreas Gruenbacher 
278*a257cdd0SAndreas Gruenbacher /*
279*a257cdd0SAndreas Gruenbacher  * XDR release functions
280*a257cdd0SAndreas Gruenbacher  */
281*a257cdd0SAndreas Gruenbacher static int nfsaclsvc_release_getacl(struct svc_rqst *rqstp, u32 *p,
282*a257cdd0SAndreas Gruenbacher 		struct nfsd3_getaclres *resp)
283*a257cdd0SAndreas Gruenbacher {
284*a257cdd0SAndreas Gruenbacher 	fh_put(&resp->fh);
285*a257cdd0SAndreas Gruenbacher 	posix_acl_release(resp->acl_access);
286*a257cdd0SAndreas Gruenbacher 	posix_acl_release(resp->acl_default);
287*a257cdd0SAndreas Gruenbacher 	return 1;
288*a257cdd0SAndreas Gruenbacher }
289*a257cdd0SAndreas Gruenbacher 
290*a257cdd0SAndreas Gruenbacher static int nfsaclsvc_release_fhandle(struct svc_rqst *rqstp, u32 *p,
291*a257cdd0SAndreas Gruenbacher 		struct nfsd_fhandle *resp)
292*a257cdd0SAndreas Gruenbacher {
293*a257cdd0SAndreas Gruenbacher 	fh_put(&resp->fh);
294*a257cdd0SAndreas Gruenbacher 	return 1;
295*a257cdd0SAndreas Gruenbacher }
296*a257cdd0SAndreas Gruenbacher 
297*a257cdd0SAndreas Gruenbacher #define nfsaclsvc_decode_voidargs	NULL
298*a257cdd0SAndreas Gruenbacher #define nfsaclsvc_encode_voidres	NULL
299*a257cdd0SAndreas Gruenbacher #define nfsaclsvc_release_void		NULL
300*a257cdd0SAndreas Gruenbacher #define nfsd3_fhandleargs	nfsd_fhandle
301*a257cdd0SAndreas Gruenbacher #define nfsd3_attrstatres	nfsd_attrstat
302*a257cdd0SAndreas Gruenbacher #define nfsd3_voidres		nfsd3_voidargs
303*a257cdd0SAndreas Gruenbacher struct nfsd3_voidargs { int dummy; };
304*a257cdd0SAndreas Gruenbacher 
305*a257cdd0SAndreas Gruenbacher #define PROC(name, argt, rest, relt, cache, respsize)	\
306*a257cdd0SAndreas Gruenbacher  { (svc_procfunc) nfsacld_proc_##name,		\
307*a257cdd0SAndreas Gruenbacher    (kxdrproc_t) nfsaclsvc_decode_##argt##args,	\
308*a257cdd0SAndreas Gruenbacher    (kxdrproc_t) nfsaclsvc_encode_##rest##res,	\
309*a257cdd0SAndreas Gruenbacher    (kxdrproc_t) nfsaclsvc_release_##relt,		\
310*a257cdd0SAndreas Gruenbacher    sizeof(struct nfsd3_##argt##args),		\
311*a257cdd0SAndreas Gruenbacher    sizeof(struct nfsd3_##rest##res),		\
312*a257cdd0SAndreas Gruenbacher    0,						\
313*a257cdd0SAndreas Gruenbacher    cache,					\
314*a257cdd0SAndreas Gruenbacher    respsize,					\
315*a257cdd0SAndreas Gruenbacher  }
316*a257cdd0SAndreas Gruenbacher 
317*a257cdd0SAndreas Gruenbacher #define ST 1		/* status*/
318*a257cdd0SAndreas Gruenbacher #define AT 21		/* attributes */
319*a257cdd0SAndreas Gruenbacher #define pAT (1+AT)	/* post attributes - conditional */
320*a257cdd0SAndreas Gruenbacher #define ACL (1+NFS_ACL_MAX_ENTRIES*3)  /* Access Control List */
321*a257cdd0SAndreas Gruenbacher 
322*a257cdd0SAndreas Gruenbacher static struct svc_procedure		nfsd_acl_procedures2[] = {
323*a257cdd0SAndreas Gruenbacher   PROC(null,	void,		void,		void,	  RC_NOCACHE, ST),
324*a257cdd0SAndreas Gruenbacher   PROC(getacl,	getacl,		getacl,		getacl,	  RC_NOCACHE, ST+1+2*(1+ACL)),
325*a257cdd0SAndreas Gruenbacher   PROC(setacl,	setacl,		attrstat,	fhandle,  RC_NOCACHE, ST+AT),
326*a257cdd0SAndreas Gruenbacher   PROC(getattr, fhandle,	attrstat,	fhandle,  RC_NOCACHE, ST+AT),
327*a257cdd0SAndreas Gruenbacher   PROC(access,	access,		access,		fhandle,  RC_NOCACHE, ST+AT+1),
328*a257cdd0SAndreas Gruenbacher };
329*a257cdd0SAndreas Gruenbacher 
330*a257cdd0SAndreas Gruenbacher struct svc_version	nfsd_acl_version2 = {
331*a257cdd0SAndreas Gruenbacher 		.vs_vers	= 2,
332*a257cdd0SAndreas Gruenbacher 		.vs_nproc	= 5,
333*a257cdd0SAndreas Gruenbacher 		.vs_proc	= nfsd_acl_procedures2,
334*a257cdd0SAndreas Gruenbacher 		.vs_dispatch	= nfsd_dispatch,
335*a257cdd0SAndreas Gruenbacher 		.vs_xdrsize	= NFS3_SVC_XDRSIZE,
336*a257cdd0SAndreas Gruenbacher };
337