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 }