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