Home | History | Annotate | Download | only in nfs
      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
     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
     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 		/*
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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