1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #include <sys/param.h>
27 #include <sys/types.h>
28 #include <sys/systm.h>
29 #include <sys/user.h>
30 #include <sys/vnode.h>
31 #include <sys/file.h>
32 #include <sys/dirent.h>
33 #include <sys/vfs.h>
34 #include <sys/stream.h>
35 #include <sys/strsubr.h>
36 #include <sys/debug.h>
37 #include <sys/t_lock.h>
38 #include <sys/acl.h>
39 
40 #include <rpc/types.h>
41 #include <rpc/xdr.h>
42 
43 #include <nfs/nfs.h>
44 #include <nfs/nfs_clnt.h>
45 #include <nfs/nfs_acl.h>
46 
47 /*
48  * These are the XDR routines used to serialize and deserialize
49  * the various structures passed as parameters accross the network
50  * between ACL clients and servers.
51  */
52 
53 bool_t
xdr_uid(XDR * xdrs,uid32_t * objp)54 xdr_uid(XDR *xdrs, uid32_t *objp)
55 {
56 	if (!xdr_u_int(xdrs, objp))
57 		return (FALSE);
58 	return (TRUE);
59 }
60 
61 bool_t
xdr_o_mode(XDR * xdrs,o_mode * objp)62 xdr_o_mode(XDR *xdrs, o_mode *objp)
63 {
64 
65 	if (!xdr_u_short(xdrs, (ushort_t *)objp))
66 		return (FALSE);
67 	return (TRUE);
68 }
69 
70 bool_t
xdr_aclent(XDR * xdrs,aclent_t * objp)71 xdr_aclent(XDR *xdrs, aclent_t *objp)
72 {
73 
74 	if (!xdr_int(xdrs, &objp->a_type))
75 		return (FALSE);
76 	if (!xdr_uid(xdrs, &objp->a_id))
77 		return (FALSE);
78 	if (!xdr_o_mode(xdrs, &objp->a_perm))
79 		return (FALSE);
80 	return (TRUE);
81 }
82 
83 bool_t
xdr_secattr(XDR * xdrs,vsecattr_t * objp)84 xdr_secattr(XDR *xdrs, vsecattr_t *objp)
85 {
86 	uint_t count;
87 
88 	if (!xdr_u_int(xdrs, &objp->vsa_mask))
89 		return (FALSE);
90 	if (!xdr_int(xdrs, &objp->vsa_aclcnt))
91 		return (FALSE);
92 	if (objp->vsa_aclentp != NULL)
93 		count = (uint_t)objp->vsa_aclcnt;
94 	else
95 		count = 0;
96 	if (!xdr_array(xdrs, (char **)&objp->vsa_aclentp, &count,
97 	    NFS_ACL_MAX_ENTRIES, sizeof (aclent_t), (xdrproc_t)xdr_aclent))
98 		return (FALSE);
99 	if (count != 0 && count != (uint_t)objp->vsa_aclcnt) {
100 		/*
101 		 * Assign the actual array size to vsa_aclcnt before
102 		 * aborting on error
103 		 */
104 		objp->vsa_aclcnt = (int)count;
105 		return (FALSE);
106 	}
107 	if (!xdr_int(xdrs, &objp->vsa_dfaclcnt))
108 		return (FALSE);
109 	if (objp->vsa_dfaclentp != NULL)
110 		count = (uint_t)objp->vsa_dfaclcnt;
111 	else
112 		count = 0;
113 	if (!xdr_array(xdrs, (char **)&objp->vsa_dfaclentp, &count,
114 	    NFS_ACL_MAX_ENTRIES, sizeof (aclent_t), (xdrproc_t)xdr_aclent))
115 		return (FALSE);
116 	if (count != 0 && count != (uint_t)objp->vsa_dfaclcnt) {
117 		/*
118 		 * Assign the actual array size to vsa_dfaclcnt before
119 		 * aborting on error
120 		 */
121 		objp->vsa_dfaclcnt = (int)count;
122 		return (FALSE);
123 	}
124 	return (TRUE);
125 }
126 
127 bool_t
xdr_GETACL2args(XDR * xdrs,GETACL2args * objp)128 xdr_GETACL2args(XDR *xdrs, GETACL2args *objp)
129 {
130 
131 	if (!xdr_fhandle(xdrs, &objp->fh))
132 		return (FALSE);
133 	if (!xdr_u_int(xdrs, &objp->mask))
134 		return (FALSE);
135 	return (TRUE);
136 }
137 bool_t
xdr_fastGETACL2args(XDR * xdrs,GETACL2args ** objpp)138 xdr_fastGETACL2args(XDR *xdrs, GETACL2args **objpp)
139 {
140 	int32_t *ptr;
141 #ifdef _LITTLE_ENDIAN
142 	GETACL2args *objp;
143 #endif
144 
145 	if (xdrs->x_op != XDR_DECODE)
146 		return (FALSE);
147 
148 	ptr = XDR_INLINE(xdrs, RNDUP(sizeof (GETACL2args)));
149 	if (ptr != NULL) {
150 		*objpp = (GETACL2args *)ptr;
151 #ifdef _LITTLE_ENDIAN
152 		objp = (GETACL2args *)ptr;
153 		objp->mask = ntohl(objp->mask);
154 #endif
155 		return (TRUE);
156 	}
157 
158 	return (FALSE);
159 }
160 
161 bool_t
xdr_GETACL2resok(XDR * xdrs,GETACL2resok * objp)162 xdr_GETACL2resok(XDR *xdrs, GETACL2resok *objp)
163 {
164 
165 	if (!xdr_fattr(xdrs, &objp->attr))
166 		return (FALSE);
167 	if (!xdr_secattr(xdrs, &objp->acl))
168 		return (FALSE);
169 	return (TRUE);
170 }
171 
172 bool_t
xdr_GETACL2res(XDR * xdrs,GETACL2res * objp)173 xdr_GETACL2res(XDR *xdrs, GETACL2res *objp)
174 {
175 
176 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
177 		return (FALSE);
178 	switch (objp->status) {
179 	case NFS_OK:
180 		if (!xdr_GETACL2resok(xdrs, &objp->resok))
181 			return (FALSE);
182 		break;
183 	}
184 	return (TRUE);
185 }
186 
187 bool_t
xdr_SETACL2args(XDR * xdrs,SETACL2args * objp)188 xdr_SETACL2args(XDR *xdrs, SETACL2args *objp)
189 {
190 
191 	if (!xdr_fhandle(xdrs, &objp->fh))
192 		return (FALSE);
193 	if (!xdr_secattr(xdrs, &objp->acl))
194 		return (FALSE);
195 	return (TRUE);
196 }
197 
198 bool_t
xdr_SETACL2resok(XDR * xdrs,SETACL2resok * objp)199 xdr_SETACL2resok(XDR *xdrs, SETACL2resok *objp)
200 {
201 
202 	if (!xdr_fattr(xdrs, &objp->attr))
203 		return (FALSE);
204 	return (TRUE);
205 }
206 #ifdef _LITTLE_ENDIAN
207 bool_t
xdr_fastSETACL2resok(XDR * xdrs,SETACL2resok * objp)208 xdr_fastSETACL2resok(XDR *xdrs, SETACL2resok *objp)
209 {
210 
211 	if (!xdr_fastfattr(xdrs, &objp->attr))
212 		return (FALSE);
213 	return (TRUE);
214 }
215 #endif
216 
217 bool_t
xdr_SETACL2res(XDR * xdrs,SETACL2res * objp)218 xdr_SETACL2res(XDR *xdrs, SETACL2res *objp)
219 {
220 
221 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
222 		return (FALSE);
223 	switch (objp->status) {
224 	case NFS_OK:
225 		if (!xdr_SETACL2resok(xdrs, &objp->resok))
226 			return (FALSE);
227 		break;
228 	}
229 	return (TRUE);
230 }
231 #ifdef _LITTLE_ENDIAN
232 bool_t
xdr_fastSETACL2res(XDR * xdrs,SETACL2res * objp)233 xdr_fastSETACL2res(XDR *xdrs, SETACL2res *objp)
234 {
235 
236 	if (!xdr_fastenum(xdrs, (enum_t *)&objp->status))
237 		return (FALSE);
238 	switch (objp->status) {
239 	case NFS_OK:
240 		if (!xdr_fastSETACL2resok(xdrs, &objp->resok))
241 			return (FALSE);
242 		break;
243 	}
244 	return (TRUE);
245 }
246 #endif
247 
248 bool_t
xdr_GETATTR2args(XDR * xdrs,GETATTR2args * objp)249 xdr_GETATTR2args(XDR *xdrs, GETATTR2args *objp)
250 {
251 
252 	if (!xdr_fhandle(xdrs, &objp->fh))
253 		return (FALSE);
254 	return (TRUE);
255 }
256 bool_t
xdr_fastGETATTR2args(XDR * xdrs,GETATTR2args ** objpp)257 xdr_fastGETATTR2args(XDR *xdrs, GETATTR2args **objpp)
258 {
259 	int32_t *ptr;
260 
261 	if (xdrs->x_op != XDR_DECODE)
262 		return (FALSE);
263 
264 	ptr = XDR_INLINE(xdrs, RNDUP(sizeof (GETATTR2args)));
265 	if (ptr != NULL) {
266 		*objpp = (GETATTR2args *)ptr;
267 		return (TRUE);
268 	}
269 
270 	return (FALSE);
271 }
272 
273 bool_t
xdr_GETATTR2resok(XDR * xdrs,GETATTR2resok * objp)274 xdr_GETATTR2resok(XDR *xdrs, GETATTR2resok *objp)
275 {
276 
277 	if (!xdr_fattr(xdrs, &objp->attr))
278 		return (FALSE);
279 	return (TRUE);
280 }
281 #ifdef _LITTLE_ENDIAN
282 bool_t
xdr_fastGETATTR2resok(XDR * xdrs,GETATTR2resok * objp)283 xdr_fastGETATTR2resok(XDR *xdrs, GETATTR2resok *objp)
284 {
285 
286 	if (!xdr_fastfattr(xdrs, &objp->attr))
287 		return (FALSE);
288 	return (TRUE);
289 }
290 #endif
291 
292 bool_t
xdr_GETATTR2res(XDR * xdrs,GETATTR2res * objp)293 xdr_GETATTR2res(XDR *xdrs, GETATTR2res *objp)
294 {
295 
296 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
297 		return (FALSE);
298 	switch (objp->status) {
299 	case NFS_OK:
300 		if (!xdr_GETATTR2resok(xdrs, &objp->resok))
301 			return (FALSE);
302 		break;
303 	}
304 	return (TRUE);
305 }
306 #ifdef _LITTLE_ENDIAN
307 bool_t
xdr_fastGETATTR2res(XDR * xdrs,GETATTR2res * objp)308 xdr_fastGETATTR2res(XDR *xdrs, GETATTR2res *objp)
309 {
310 
311 	if (!xdr_fastenum(xdrs, (enum_t *)&objp->status))
312 		return (FALSE);
313 	switch (objp->status) {
314 	case NFS_OK:
315 		if (!xdr_fastGETATTR2resok(xdrs, &objp->resok))
316 			return (FALSE);
317 		break;
318 	}
319 	return (TRUE);
320 }
321 #endif
322 
323 bool_t
xdr_ACCESS2args(XDR * xdrs,ACCESS2args * objp)324 xdr_ACCESS2args(XDR *xdrs, ACCESS2args *objp)
325 {
326 
327 	if (!xdr_fhandle(xdrs, &objp->fh))
328 		return (FALSE);
329 	if (!xdr_uint32(xdrs, &objp->access))
330 		return (FALSE);
331 	return (TRUE);
332 }
333 bool_t
xdr_fastACCESS2args(XDR * xdrs,ACCESS2args ** objpp)334 xdr_fastACCESS2args(XDR *xdrs, ACCESS2args **objpp)
335 {
336 	int32_t *ptr;
337 #ifdef _LITTLE_ENDIAN
338 	ACCESS2args *objp;
339 #endif
340 
341 	if (xdrs->x_op != XDR_DECODE)
342 		return (FALSE);
343 
344 	ptr = XDR_INLINE(xdrs, RNDUP(sizeof (ACCESS2args)));
345 	if (ptr != NULL) {
346 		*objpp = (ACCESS2args *)ptr;
347 #ifdef _LITTLE_ENDIAN
348 		objp = (ACCESS2args *)ptr;
349 		objp->access = ntohl(objp->access);
350 #endif
351 		return (TRUE);
352 	}
353 
354 	return (FALSE);
355 }
356 
357 bool_t
xdr_ACCESS2resok(XDR * xdrs,ACCESS2resok * objp)358 xdr_ACCESS2resok(XDR *xdrs, ACCESS2resok *objp)
359 {
360 
361 	if (!xdr_fattr(xdrs, &objp->attr))
362 		return (FALSE);
363 	if (!xdr_uint32(xdrs, &objp->access))
364 		return (FALSE);
365 	return (TRUE);
366 }
367 #ifdef _LITTLE_ENDIAN
368 bool_t
xdr_fastACCESS2resok(XDR * xdrs,ACCESS2resok * objp)369 xdr_fastACCESS2resok(XDR *xdrs, ACCESS2resok *objp)
370 {
371 
372 	if (!xdr_fastfattr(xdrs, &objp->attr))
373 		return (FALSE);
374 	objp->access = ntohl(objp->access);
375 	return (TRUE);
376 }
377 #endif
378 
379 bool_t
xdr_ACCESS2res(XDR * xdrs,ACCESS2res * objp)380 xdr_ACCESS2res(XDR *xdrs, ACCESS2res *objp)
381 {
382 
383 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
384 		return (FALSE);
385 	switch (objp->status) {
386 	case NFS_OK:
387 		if (!xdr_ACCESS2resok(xdrs, &objp->resok))
388 			return (FALSE);
389 		break;
390 	}
391 	return (TRUE);
392 }
393 #ifdef _LITTLE_ENDIAN
394 bool_t
xdr_fastACCESS2res(XDR * xdrs,ACCESS2res * objp)395 xdr_fastACCESS2res(XDR *xdrs, ACCESS2res *objp)
396 {
397 
398 	if (!xdr_fastenum(xdrs, (enum_t *)&objp->status))
399 		return (FALSE);
400 	switch (objp->status) {
401 	case NFS_OK:
402 		if (!xdr_fastACCESS2resok(xdrs, &objp->resok))
403 			return (FALSE);
404 		break;
405 	}
406 	return (TRUE);
407 }
408 #endif
409 
410 bool_t
xdr_GETXATTRDIR2args(XDR * xdrs,GETXATTRDIR2args * objp)411 xdr_GETXATTRDIR2args(XDR *xdrs, GETXATTRDIR2args *objp)
412 {
413 	if (!xdr_fhandle(xdrs, &objp->fh))
414 		return (FALSE);
415 	if (!xdr_bool(xdrs, &objp->create))
416 		return (FALSE);
417 	return (TRUE);
418 }
419 
420 bool_t
xdr_GETXATTRDIR2resok(XDR * xdrs,GETXATTRDIR2resok * objp)421 xdr_GETXATTRDIR2resok(XDR *xdrs, GETXATTRDIR2resok *objp)
422 {
423 	if (!xdr_fhandle(xdrs, &objp->fh))
424 		return (FALSE);
425 	if (!xdr_fattr(xdrs, &objp->attr))
426 		return (FALSE);
427 	return (TRUE);
428 }
429 
430 bool_t
xdr_GETXATTRDIR2res(XDR * xdrs,GETXATTRDIR2res * objp)431 xdr_GETXATTRDIR2res(XDR *xdrs, GETXATTRDIR2res *objp)
432 {
433 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
434 		return (FALSE);
435 	switch (objp->status) {
436 	case NFS_OK:
437 		if (!xdr_GETXATTRDIR2resok(xdrs, &objp->resok))
438 			return (FALSE);
439 		break;
440 	}
441 	return (TRUE);
442 }
443 
444 bool_t
xdr_GETACL3args(XDR * xdrs,GETACL3args * objp)445 xdr_GETACL3args(XDR *xdrs, GETACL3args *objp)
446 {
447 
448 	switch (xdrs->x_op) {
449 	case XDR_FREE:
450 	case XDR_ENCODE:
451 		if (!xdr_nfs_fh3(xdrs, &objp->fh))
452 			return (FALSE);
453 		break;
454 	case XDR_DECODE:
455 		if (!xdr_nfs_fh3_server(xdrs, &objp->fh))
456 			return (FALSE);
457 		break;
458 	}
459 	if (!xdr_u_int(xdrs, &objp->mask))
460 		return (FALSE);
461 	return (TRUE);
462 }
463 
464 bool_t
xdr_GETACL3resok(XDR * xdrs,GETACL3resok * objp)465 xdr_GETACL3resok(XDR *xdrs, GETACL3resok *objp)
466 {
467 
468 	if (!xdr_post_op_attr(xdrs, &objp->attr))
469 		return (FALSE);
470 	if (!xdr_secattr(xdrs, &objp->acl))
471 		return (FALSE);
472 	return (TRUE);
473 }
474 
475 bool_t
xdr_GETACL3resfail(XDR * xdrs,GETACL3resfail * objp)476 xdr_GETACL3resfail(XDR *xdrs, GETACL3resfail *objp)
477 {
478 
479 	if (!xdr_post_op_attr(xdrs, &objp->attr))
480 		return (FALSE);
481 	return (TRUE);
482 }
483 
484 bool_t
xdr_GETACL3res(XDR * xdrs,GETACL3res * objp)485 xdr_GETACL3res(XDR *xdrs, GETACL3res *objp)
486 {
487 
488 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
489 		return (FALSE);
490 	switch (objp->status) {
491 	case NFS3_OK:
492 		if (!xdr_GETACL3resok(xdrs, &objp->resok))
493 			return (FALSE);
494 		break;
495 	default:
496 		if (!xdr_GETACL3resfail(xdrs, &objp->resfail))
497 			return (FALSE);
498 		break;
499 	}
500 	return (TRUE);
501 }
502 
503 bool_t
xdr_SETACL3args(XDR * xdrs,SETACL3args * objp)504 xdr_SETACL3args(XDR *xdrs, SETACL3args *objp)
505 {
506 
507 	switch (xdrs->x_op) {
508 	case XDR_FREE:
509 	case XDR_ENCODE:
510 		if (!xdr_nfs_fh3(xdrs, &objp->fh))
511 			return (FALSE);
512 		break;
513 	case XDR_DECODE:
514 		if (!xdr_nfs_fh3_server(xdrs, &objp->fh))
515 			return (FALSE);
516 		break;
517 	}
518 	if (!xdr_secattr(xdrs, &objp->acl))
519 		return (FALSE);
520 	return (TRUE);
521 }
522 
523 bool_t
xdr_SETACL3resok(XDR * xdrs,SETACL3resok * objp)524 xdr_SETACL3resok(XDR *xdrs, SETACL3resok *objp)
525 {
526 
527 	if (!xdr_post_op_attr(xdrs, &objp->attr))
528 		return (FALSE);
529 	return (TRUE);
530 }
531 
532 bool_t
xdr_SETACL3resfail(XDR * xdrs,SETACL3resfail * objp)533 xdr_SETACL3resfail(XDR *xdrs, SETACL3resfail *objp)
534 {
535 
536 	if (!xdr_post_op_attr(xdrs, &objp->attr))
537 		return (FALSE);
538 	return (TRUE);
539 }
540 
541 bool_t
xdr_SETACL3res(XDR * xdrs,SETACL3res * objp)542 xdr_SETACL3res(XDR *xdrs, SETACL3res *objp)
543 {
544 
545 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
546 		return (FALSE);
547 	switch (objp->status) {
548 	case NFS3_OK:
549 		if (!xdr_SETACL3resok(xdrs, &objp->resok))
550 			return (FALSE);
551 		break;
552 	default:
553 		if (!xdr_SETACL3resfail(xdrs, &objp->resfail))
554 			return (FALSE);
555 		break;
556 	}
557 	return (TRUE);
558 }
559 
560 bool_t
xdr_GETXATTRDIR3args(XDR * xdrs,GETXATTRDIR3args * objp)561 xdr_GETXATTRDIR3args(XDR *xdrs, GETXATTRDIR3args *objp)
562 {
563 	switch (xdrs->x_op) {
564 	case XDR_FREE:
565 	case XDR_ENCODE:
566 		if (!xdr_nfs_fh3(xdrs, &objp->fh))
567 			return (FALSE);
568 		break;
569 	case XDR_DECODE:
570 		if (!xdr_nfs_fh3_server(xdrs, &objp->fh))
571 			return (FALSE);
572 		break;
573 	}
574 	if (!xdr_bool(xdrs, &objp->create))
575 		return (FALSE);
576 	return (TRUE);
577 }
578 
579 bool_t
xdr_GETXATTRDIR3resok(XDR * xdrs,GETXATTRDIR3resok * objp)580 xdr_GETXATTRDIR3resok(XDR *xdrs, GETXATTRDIR3resok *objp)
581 {
582 	switch (xdrs->x_op) {
583 	case XDR_ENCODE:
584 		if (!xdr_nfs_fh3_server(xdrs, &objp->fh))
585 			return (FALSE);
586 		break;
587 	case XDR_FREE:
588 	case XDR_DECODE:
589 		if (!xdr_nfs_fh3(xdrs, &objp->fh))
590 			return (FALSE);
591 		break;
592 	}
593 	if (!xdr_post_op_attr(xdrs, &objp->attr))
594 		return (FALSE);
595 	return (TRUE);
596 }
597 
598 bool_t
xdr_GETXATTRDIR3res(XDR * xdrs,GETXATTRDIR3res * objp)599 xdr_GETXATTRDIR3res(XDR *xdrs, GETXATTRDIR3res *objp)
600 {
601 	if (!xdr_enum(xdrs, (enum_t *)&objp->status))
602 		return (FALSE);
603 	switch (objp->status) {
604 	case NFS_OK:
605 		if (!xdr_GETXATTRDIR3resok(xdrs, &objp->resok))
606 			return (FALSE);
607 		break;
608 	}
609 	return (TRUE);
610 }
611