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