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