The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/fs/nfs/nfs_commonacl.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2009 Rick Macklem, University of Guelph
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  *
   26  */
   27 
   28 #include <sys/cdefs.h>
   29 __FBSDID("$FreeBSD$");
   30 
   31 #include <fs/nfs/nfsport.h>
   32 
   33 extern int nfsrv_useacl;
   34 
   35 static int nfsrv_acemasktoperm(u_int32_t acetype, u_int32_t mask, int owner,
   36     enum vtype type, acl_perm_t *permp);
   37 
   38 /*
   39  * Handle xdr for an ace.
   40  */
   41 int
   42 nfsrv_dissectace(struct nfsrv_descript *nd, struct acl_entry *acep,
   43     int *aceerrp, int *acesizep, NFSPROC_T *p)
   44 {
   45         u_int32_t *tl;
   46         int len, gotid = 0, owner = 0, error = 0, aceerr = 0;
   47         u_char *name, namestr[NFSV4_SMALLSTR + 1];
   48         u_int32_t flag, mask, acetype;
   49         gid_t gid;
   50         uid_t uid;
   51 
   52         *aceerrp = 0;
   53         acep->ae_flags = 0;
   54         NFSM_DISSECT(tl, u_int32_t *, 4 * NFSX_UNSIGNED);
   55         acetype = fxdr_unsigned(u_int32_t, *tl++);
   56         flag = fxdr_unsigned(u_int32_t, *tl++);
   57         mask = fxdr_unsigned(u_int32_t, *tl++);
   58         len = fxdr_unsigned(int, *tl);
   59         if (len < 0) {
   60                 error = NFSERR_BADXDR;
   61                 goto nfsmout;
   62         } else if (len == 0) {
   63                 /* Netapp filers return a 0 length who for nil users */
   64                 acep->ae_tag = ACL_UNDEFINED_TAG;
   65                 acep->ae_id = ACL_UNDEFINED_ID;
   66                 acep->ae_perm = (acl_perm_t)0;
   67                 acep->ae_entry_type = ACL_ENTRY_TYPE_DENY;
   68                 if (acesizep)
   69                         *acesizep = 4 * NFSX_UNSIGNED;
   70                 error = 0;
   71                 goto nfsmout;
   72         }
   73         if (len > NFSV4_SMALLSTR)
   74                 name = malloc(len + 1, M_NFSSTRING, M_WAITOK);
   75         else
   76                 name = namestr;
   77         error = nfsrv_mtostr(nd, name, len);
   78         if (error) {
   79                 if (len > NFSV4_SMALLSTR)
   80                         free(name, M_NFSSTRING);
   81                 goto nfsmout;
   82         }
   83         if (len == 6) {
   84                 if (!NFSBCMP(name, "OWNER@", 6)) {
   85                         acep->ae_tag = ACL_USER_OBJ;
   86                         acep->ae_id = ACL_UNDEFINED_ID;
   87                         owner = 1;
   88                         gotid = 1;
   89                 } else if (!NFSBCMP(name, "GROUP@", 6)) {
   90                         acep->ae_tag = ACL_GROUP_OBJ;
   91                         acep->ae_id = ACL_UNDEFINED_ID;
   92                         gotid = 1;
   93                 }
   94         } else if (len == 9 && !NFSBCMP(name, "EVERYONE@", 9)) {
   95                 acep->ae_tag = ACL_EVERYONE;
   96                 acep->ae_id = ACL_UNDEFINED_ID;
   97                 gotid = 1;
   98         }
   99         if (gotid == 0) {
  100                 if (flag & NFSV4ACE_IDENTIFIERGROUP) {
  101                         acep->ae_tag = ACL_GROUP;
  102                         aceerr = nfsv4_strtogid(nd, name, len, &gid, p);
  103                         if (aceerr == 0)
  104                                 acep->ae_id = (uid_t)gid;
  105                 } else {
  106                         acep->ae_tag = ACL_USER;
  107                         aceerr = nfsv4_strtouid(nd, name, len, &uid, p);
  108                         if (aceerr == 0)
  109                                 acep->ae_id = uid;
  110                 }
  111         }
  112         if (len > NFSV4_SMALLSTR)
  113                 free(name, M_NFSSTRING);
  114 
  115         if (aceerr == 0) {
  116                 /*
  117                  * Handle the flags.
  118                  */
  119                 flag &= ~NFSV4ACE_IDENTIFIERGROUP;
  120                 if (flag & NFSV4ACE_FILEINHERIT) {
  121                         flag &= ~NFSV4ACE_FILEINHERIT;
  122                         acep->ae_flags |= ACL_ENTRY_FILE_INHERIT;
  123                 }
  124                 if (flag & NFSV4ACE_DIRECTORYINHERIT) {
  125                         flag &= ~NFSV4ACE_DIRECTORYINHERIT;
  126                         acep->ae_flags |= ACL_ENTRY_DIRECTORY_INHERIT;
  127                 }
  128                 if (flag & NFSV4ACE_NOPROPAGATEINHERIT) {
  129                         flag &= ~NFSV4ACE_NOPROPAGATEINHERIT;
  130                         acep->ae_flags |= ACL_ENTRY_NO_PROPAGATE_INHERIT;
  131                 }
  132                 if (flag & NFSV4ACE_INHERITONLY) {
  133                         flag &= ~NFSV4ACE_INHERITONLY;
  134                         acep->ae_flags |= ACL_ENTRY_INHERIT_ONLY;
  135                 }
  136                 if (flag & NFSV4ACE_SUCCESSFULACCESS) {
  137                         flag &= ~NFSV4ACE_SUCCESSFULACCESS;
  138                         acep->ae_flags |= ACL_ENTRY_SUCCESSFUL_ACCESS;
  139                 }
  140                 if (flag & NFSV4ACE_FAILEDACCESS) {
  141                         flag &= ~NFSV4ACE_FAILEDACCESS;
  142                         acep->ae_flags |= ACL_ENTRY_FAILED_ACCESS;
  143                 }
  144                 /*
  145                  * Set ae_entry_type.
  146                  */
  147                 if (acetype == NFSV4ACE_ALLOWEDTYPE)
  148                         acep->ae_entry_type = ACL_ENTRY_TYPE_ALLOW;
  149                 else if (acetype == NFSV4ACE_DENIEDTYPE)
  150                         acep->ae_entry_type = ACL_ENTRY_TYPE_DENY;
  151                 else if (acetype == NFSV4ACE_AUDITTYPE)
  152                         acep->ae_entry_type = ACL_ENTRY_TYPE_AUDIT;
  153                 else if (acetype == NFSV4ACE_ALARMTYPE)
  154                         acep->ae_entry_type = ACL_ENTRY_TYPE_ALARM;
  155                 else
  156                         aceerr = NFSERR_ATTRNOTSUPP;
  157         }
  158 
  159         /*
  160          * Now, check for unsupported flag bits.
  161          */
  162         if (aceerr == 0 && flag != 0)
  163                 aceerr = NFSERR_ATTRNOTSUPP;
  164 
  165         /*
  166          * And turn the mask into perm bits.
  167          */
  168         if (aceerr == 0)
  169                 aceerr = nfsrv_acemasktoperm(acetype, mask, owner, VREG,
  170                     &acep->ae_perm);
  171         *aceerrp = aceerr;
  172         if (acesizep)
  173                 *acesizep = NFSM_RNDUP(len) + (4 * NFSX_UNSIGNED);
  174         error = 0;
  175 nfsmout:
  176         NFSEXITCODE(error);
  177         return (error);
  178 }
  179 
  180 /*
  181  * Turn an NFSv4 ace mask into R/W/X flag bits.
  182  */
  183 static int
  184 nfsrv_acemasktoperm(u_int32_t acetype, u_int32_t mask, int owner,
  185     enum vtype type, acl_perm_t *permp)
  186 {
  187         acl_perm_t perm = 0x0;
  188         int error = 0;
  189 
  190         if (mask & NFSV4ACE_READDATA) {
  191                 mask &= ~NFSV4ACE_READDATA;
  192                 perm |= ACL_READ_DATA;
  193         }
  194         if (mask & NFSV4ACE_LISTDIRECTORY) {
  195                 mask &= ~NFSV4ACE_LISTDIRECTORY;
  196                 perm |= ACL_LIST_DIRECTORY;
  197         }
  198         if (mask & NFSV4ACE_WRITEDATA) {
  199                 mask &= ~NFSV4ACE_WRITEDATA;
  200                 perm |= ACL_WRITE_DATA;
  201         }
  202         if (mask & NFSV4ACE_ADDFILE) {
  203                 mask &= ~NFSV4ACE_ADDFILE;
  204                 perm |= ACL_ADD_FILE;
  205         }
  206         if (mask & NFSV4ACE_APPENDDATA) {
  207                 mask &= ~NFSV4ACE_APPENDDATA;
  208                 perm |= ACL_APPEND_DATA;
  209         }
  210         if (mask & NFSV4ACE_ADDSUBDIRECTORY) {
  211                 mask &= ~NFSV4ACE_ADDSUBDIRECTORY;
  212                 perm |= ACL_ADD_SUBDIRECTORY;
  213         }
  214         if (mask & NFSV4ACE_READNAMEDATTR) {
  215                 mask &= ~NFSV4ACE_READNAMEDATTR;
  216                 perm |= ACL_READ_NAMED_ATTRS;
  217         }
  218         if (mask & NFSV4ACE_WRITENAMEDATTR) {
  219                 mask &= ~NFSV4ACE_WRITENAMEDATTR;
  220                 perm |= ACL_WRITE_NAMED_ATTRS;
  221         }
  222         if (mask & NFSV4ACE_EXECUTE) {
  223                 mask &= ~NFSV4ACE_EXECUTE;
  224                 perm |= ACL_EXECUTE;
  225         }
  226         if (mask & NFSV4ACE_SEARCH) {
  227                 mask &= ~NFSV4ACE_SEARCH;
  228                 perm |= ACL_EXECUTE;
  229         }
  230         if (mask & NFSV4ACE_DELETECHILD) {
  231                 mask &= ~NFSV4ACE_DELETECHILD;
  232                 perm |= ACL_DELETE_CHILD;
  233         }
  234         if (mask & NFSV4ACE_READATTRIBUTES) {
  235                 mask &= ~NFSV4ACE_READATTRIBUTES;
  236                 perm |= ACL_READ_ATTRIBUTES;
  237         }
  238         if (mask & NFSV4ACE_WRITEATTRIBUTES) {
  239                 mask &= ~NFSV4ACE_WRITEATTRIBUTES;
  240                 perm |= ACL_WRITE_ATTRIBUTES;
  241         }
  242         if (mask & NFSV4ACE_DELETE) {
  243                 mask &= ~NFSV4ACE_DELETE;
  244                 perm |= ACL_DELETE;
  245         }
  246         if (mask & NFSV4ACE_READACL) {
  247                 mask &= ~NFSV4ACE_READACL;
  248                 perm |= ACL_READ_ACL;
  249         }
  250         if (mask & NFSV4ACE_WRITEACL) {
  251                 mask &= ~NFSV4ACE_WRITEACL;
  252                 perm |= ACL_WRITE_ACL;
  253         }
  254         if (mask & NFSV4ACE_WRITEOWNER) {
  255                 mask &= ~NFSV4ACE_WRITEOWNER;
  256                 perm |= ACL_WRITE_OWNER;
  257         }
  258         if (mask & NFSV4ACE_SYNCHRONIZE) {
  259                 mask &= ~NFSV4ACE_SYNCHRONIZE;
  260                 perm |= ACL_SYNCHRONIZE;
  261         }
  262         if (mask != 0) {
  263                 error = NFSERR_ATTRNOTSUPP;
  264                 goto out;
  265         }
  266         *permp = perm;
  267 
  268 out:
  269         NFSEXITCODE(error);
  270         return (error);
  271 }
  272 
  273 /* local functions */
  274 static int nfsrv_buildace(struct nfsrv_descript *, u_char *, int,
  275     enum vtype, int, int, struct acl_entry *);
  276 
  277 /*
  278  * This function builds an NFS ace.
  279  */
  280 static int
  281 nfsrv_buildace(struct nfsrv_descript *nd, u_char *name, int namelen,
  282     enum vtype type, int group, int owner, struct acl_entry *ace)
  283 {
  284         u_int32_t *tl, aceflag = 0x0, acemask = 0x0, acetype;
  285         int full_len;
  286 
  287         full_len = NFSM_RNDUP(namelen);
  288         NFSM_BUILD(tl, u_int32_t *, 4 * NFSX_UNSIGNED + full_len);
  289 
  290         /*
  291          * Fill in the ace type.
  292          */
  293         if (ace->ae_entry_type & ACL_ENTRY_TYPE_ALLOW)
  294                 acetype = NFSV4ACE_ALLOWEDTYPE;
  295         else if (ace->ae_entry_type & ACL_ENTRY_TYPE_DENY)
  296                 acetype = NFSV4ACE_DENIEDTYPE;
  297         else if (ace->ae_entry_type & ACL_ENTRY_TYPE_AUDIT)
  298                 acetype = NFSV4ACE_AUDITTYPE;
  299         else
  300                 acetype = NFSV4ACE_ALARMTYPE;
  301         *tl++ = txdr_unsigned(acetype);
  302 
  303         /*
  304          * Set the flag bits from the ACL.
  305          */
  306         if (ace->ae_flags & ACL_ENTRY_FILE_INHERIT)
  307                 aceflag |= NFSV4ACE_FILEINHERIT;
  308         if (ace->ae_flags & ACL_ENTRY_DIRECTORY_INHERIT)
  309                 aceflag |= NFSV4ACE_DIRECTORYINHERIT;
  310         if (ace->ae_flags & ACL_ENTRY_NO_PROPAGATE_INHERIT)
  311                 aceflag |= NFSV4ACE_NOPROPAGATEINHERIT;
  312         if (ace->ae_flags & ACL_ENTRY_INHERIT_ONLY)
  313                 aceflag |= NFSV4ACE_INHERITONLY;
  314         if (ace->ae_flags & ACL_ENTRY_SUCCESSFUL_ACCESS)
  315                 aceflag |= NFSV4ACE_SUCCESSFULACCESS;
  316         if (ace->ae_flags & ACL_ENTRY_FAILED_ACCESS)
  317                 aceflag |= NFSV4ACE_FAILEDACCESS;
  318         if (group)
  319                 aceflag |= NFSV4ACE_IDENTIFIERGROUP;
  320         *tl++ = txdr_unsigned(aceflag);
  321         if (type == VDIR) {
  322                 if (ace->ae_perm & ACL_LIST_DIRECTORY)
  323                         acemask |= NFSV4ACE_LISTDIRECTORY;
  324                 if (ace->ae_perm & ACL_ADD_FILE)
  325                         acemask |= NFSV4ACE_ADDFILE;
  326                 if (ace->ae_perm & ACL_ADD_SUBDIRECTORY)
  327                         acemask |= NFSV4ACE_ADDSUBDIRECTORY;
  328                 if (ace->ae_perm & ACL_READ_NAMED_ATTRS)
  329                         acemask |= NFSV4ACE_READNAMEDATTR;
  330                 if (ace->ae_perm & ACL_WRITE_NAMED_ATTRS)
  331                         acemask |= NFSV4ACE_WRITENAMEDATTR;
  332                 if (ace->ae_perm & ACL_EXECUTE)
  333                         acemask |= NFSV4ACE_SEARCH;
  334                 if (ace->ae_perm & ACL_DELETE_CHILD)
  335                         acemask |= NFSV4ACE_DELETECHILD;
  336                 if (ace->ae_perm & ACL_READ_ATTRIBUTES)
  337                         acemask |= NFSV4ACE_READATTRIBUTES;
  338                 if (ace->ae_perm & ACL_WRITE_ATTRIBUTES)
  339                         acemask |= NFSV4ACE_WRITEATTRIBUTES;
  340                 if (ace->ae_perm & ACL_DELETE)
  341                         acemask |= NFSV4ACE_DELETE;
  342                 if (ace->ae_perm & ACL_READ_ACL)
  343                         acemask |= NFSV4ACE_READACL;
  344                 if (ace->ae_perm & ACL_WRITE_ACL)
  345                         acemask |= NFSV4ACE_WRITEACL;
  346                 if (ace->ae_perm & ACL_WRITE_OWNER)
  347                         acemask |= NFSV4ACE_WRITEOWNER;
  348                 if (ace->ae_perm & ACL_SYNCHRONIZE)
  349                         acemask |= NFSV4ACE_SYNCHRONIZE;
  350         } else {
  351                 if (ace->ae_perm & ACL_READ_DATA)
  352                         acemask |= NFSV4ACE_READDATA;
  353                 if (ace->ae_perm & ACL_WRITE_DATA)
  354                         acemask |= NFSV4ACE_WRITEDATA;
  355                 if (ace->ae_perm & ACL_APPEND_DATA)
  356                         acemask |= NFSV4ACE_APPENDDATA;
  357                 if (ace->ae_perm & ACL_READ_NAMED_ATTRS)
  358                         acemask |= NFSV4ACE_READNAMEDATTR;
  359                 if (ace->ae_perm & ACL_WRITE_NAMED_ATTRS)
  360                         acemask |= NFSV4ACE_WRITENAMEDATTR;
  361                 if (ace->ae_perm & ACL_EXECUTE)
  362                         acemask |= NFSV4ACE_EXECUTE;
  363                 if (ace->ae_perm & ACL_READ_ATTRIBUTES)
  364                         acemask |= NFSV4ACE_READATTRIBUTES;
  365                 if (ace->ae_perm & ACL_WRITE_ATTRIBUTES)
  366                         acemask |= NFSV4ACE_WRITEATTRIBUTES;
  367                 if (ace->ae_perm & ACL_DELETE)
  368                         acemask |= NFSV4ACE_DELETE;
  369                 if (ace->ae_perm & ACL_READ_ACL)
  370                         acemask |= NFSV4ACE_READACL;
  371                 if (ace->ae_perm & ACL_WRITE_ACL)
  372                         acemask |= NFSV4ACE_WRITEACL;
  373                 if (ace->ae_perm & ACL_WRITE_OWNER)
  374                         acemask |= NFSV4ACE_WRITEOWNER;
  375                 if (ace->ae_perm & ACL_SYNCHRONIZE)
  376                         acemask |= NFSV4ACE_SYNCHRONIZE;
  377         }
  378         *tl++ = txdr_unsigned(acemask);
  379         *tl++ = txdr_unsigned(namelen);
  380         if (full_len - namelen)
  381                 *(tl + (namelen / NFSX_UNSIGNED)) = 0x0;
  382         NFSBCOPY(name, (caddr_t)tl, namelen);
  383         return (full_len + 4 * NFSX_UNSIGNED);
  384 }
  385 
  386 /*
  387  * Build an NFSv4 ACL.
  388  */
  389 int
  390 nfsrv_buildacl(struct nfsrv_descript *nd, NFSACL_T *aclp, enum vtype type,
  391     NFSPROC_T *p)
  392 {
  393         int i, entrycnt = 0, retlen;
  394         u_int32_t *entrycntp;
  395         int isowner, isgroup, namelen, malloced;
  396         u_char *name, namestr[NFSV4_SMALLSTR];
  397 
  398         NFSM_BUILD(entrycntp, u_int32_t *, NFSX_UNSIGNED);
  399         retlen = NFSX_UNSIGNED;
  400         /*
  401          * Loop through the acl entries, building each one.
  402          */
  403         for (i = 0; i < aclp->acl_cnt; i++) {
  404                 isowner = isgroup = malloced = 0;
  405                 switch (aclp->acl_entry[i].ae_tag) {
  406                 case ACL_USER_OBJ:
  407                         isowner = 1;
  408                         name = "OWNER@";
  409                         namelen = 6;
  410                         break;
  411                 case ACL_GROUP_OBJ:
  412                         isgroup = 1;
  413                         name = "GROUP@";
  414                         namelen = 6;
  415                         break;
  416                 case ACL_EVERYONE:
  417                         name = "EVERYONE@";
  418                         namelen = 9;
  419                         break;
  420                 case ACL_USER:
  421                         name = namestr;
  422                         nfsv4_uidtostr(aclp->acl_entry[i].ae_id, &name,
  423                             &namelen, p);
  424                         if (name != namestr)
  425                                 malloced = 1;
  426                         break;
  427                 case ACL_GROUP:
  428                         isgroup = 1;
  429                         name = namestr;
  430                         nfsv4_gidtostr((gid_t)aclp->acl_entry[i].ae_id, &name,
  431                             &namelen, p);
  432                         if (name != namestr)
  433                                 malloced = 1;
  434                         break;
  435                 default:
  436                         continue;
  437                 }
  438                 retlen += nfsrv_buildace(nd, name, namelen, type, isgroup,
  439                     isowner, &aclp->acl_entry[i]);
  440                 entrycnt++;
  441                 if (malloced)
  442                         free(name, M_NFSSTRING);
  443         }
  444         *entrycntp = txdr_unsigned(entrycnt);
  445         return (retlen);
  446 }
  447 
  448 /*
  449  * Set an NFSv4 acl.
  450  */
  451 int
  452 nfsrv_setacl(vnode_t vp, NFSACL_T *aclp, struct ucred *cred,
  453     NFSPROC_T *p)
  454 {
  455         int error;
  456 
  457         if (nfsrv_useacl == 0 || nfs_supportsnfsv4acls(vp) == 0) {
  458                 error = NFSERR_ATTRNOTSUPP;
  459                 goto out;
  460         }
  461         /*
  462          * With NFSv4 ACLs, chmod(2) may need to add additional entries.
  463          * Make sure it has enough room for that - splitting every entry
  464          * into two and appending "canonical six" entries at the end.
  465          * Cribbed out of kern/vfs_acl.c - Rick M.
  466          */
  467         if (aclp->acl_cnt > (ACL_MAX_ENTRIES - 6) / 2) {
  468                 error = NFSERR_ATTRNOTSUPP;
  469                 goto out;
  470         }
  471         error = VOP_SETACL(vp, ACL_TYPE_NFS4, aclp, cred, p);
  472 
  473 out:
  474         NFSEXITCODE(error);
  475         return (error);
  476 }
  477 
  478 /*
  479  * Compare two NFSv4 acls.
  480  * Return 0 if they are the same, 1 if not the same.
  481  */
  482 int
  483 nfsrv_compareacl(NFSACL_T *aclp1, NFSACL_T *aclp2)
  484 {
  485         int i;
  486         struct acl_entry *acep1, *acep2;
  487 
  488         if (aclp1->acl_cnt != aclp2->acl_cnt)
  489                 return (1);
  490         acep1 = aclp1->acl_entry;
  491         acep2 = aclp2->acl_entry;
  492         for (i = 0; i < aclp1->acl_cnt; i++) {
  493                 if (acep1->ae_tag != acep2->ae_tag)
  494                         return (1);
  495                 switch (acep1->ae_tag) {
  496                 case ACL_GROUP:
  497                 case ACL_USER:
  498                         if (acep1->ae_id != acep2->ae_id)
  499                                 return (1);
  500                         /* fall through */
  501                 case ACL_USER_OBJ:
  502                 case ACL_GROUP_OBJ:
  503                 case ACL_OTHER:
  504                         if (acep1->ae_perm != acep2->ae_perm)
  505                                 return (1);
  506                 }
  507                 acep1++;
  508                 acep2++;
  509         }
  510         return (0);
  511 }

Cache object: bd56ebbe5c3b0e3f9245c761ba3c2a43


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.