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: releng/8.4/sys/fs/nfs/nfs_commonacl.c 241306 2012-10-06 22:14:19Z rmacklem $");
   30 
   31 #ifndef APPLEKEXT
   32 #include <fs/nfs/nfsport.h>
   33 
   34 extern int nfsrv_useacl;
   35 #endif
   36 
   37 static int nfsrv_acemasktoperm(u_int32_t acetype, u_int32_t mask, int owner,
   38     enum vtype type, acl_perm_t *permp);
   39 
   40 /*
   41  * Handle xdr for an ace.
   42  */
   43 APPLESTATIC int
   44 nfsrv_dissectace(struct nfsrv_descript *nd, struct acl_entry *acep,
   45     int *aceerrp, int *acesizep, NFSPROC_T *p)
   46 {
   47         u_int32_t *tl;
   48         int len, gotid = 0, owner = 0, error = 0, aceerr = 0;
   49         u_char *name, namestr[NFSV4_SMALLSTR + 1];
   50         u_int32_t flag, mask, acetype;
   51         gid_t gid;
   52         uid_t uid;
   53 
   54         *aceerrp = 0;
   55         acep->ae_flags = 0;
   56         NFSM_DISSECT(tl, u_int32_t *, 4 * NFSX_UNSIGNED);
   57         acetype = fxdr_unsigned(u_int32_t, *tl++);
   58         flag = fxdr_unsigned(u_int32_t, *tl++);
   59         mask = fxdr_unsigned(u_int32_t, *tl++);
   60         len = fxdr_unsigned(int, *tl);
   61         if (len < 0) {
   62                 error = NFSERR_BADXDR;
   63                 goto nfsmout;
   64         } else if (len == 0) {
   65                 /* Netapp filers return a 0 length who for nil users */
   66                 acep->ae_tag = ACL_UNDEFINED_TAG;
   67                 acep->ae_id = ACL_UNDEFINED_ID;
   68                 acep->ae_perm = (acl_perm_t)0;
   69                 acep->ae_entry_type = ACL_ENTRY_TYPE_DENY;
   70                 if (acesizep)
   71                         *acesizep = 4 * NFSX_UNSIGNED;
   72                 error = 0;
   73                 goto nfsmout;
   74         }
   75         if (len > NFSV4_SMALLSTR)
   76                 name = malloc(len + 1, M_NFSSTRING, M_WAITOK);
   77         else
   78                 name = namestr;
   79         error = nfsrv_mtostr(nd, name, len);
   80         if (error) {
   81                 if (len > NFSV4_SMALLSTR)
   82                         free(name, M_NFSSTRING);
   83                 goto nfsmout;
   84         }
   85         if (len == 6) {
   86                 if (!NFSBCMP(name, "OWNER@", 6)) {
   87                         acep->ae_tag = ACL_USER_OBJ;
   88                         acep->ae_id = ACL_UNDEFINED_ID;
   89                         owner = 1;
   90                         gotid = 1;
   91                 } else if (!NFSBCMP(name, "GROUP@", 6)) {
   92                         acep->ae_tag = ACL_GROUP_OBJ;
   93                         acep->ae_id = ACL_UNDEFINED_ID;
   94                         gotid = 1;
   95                 }
   96         } else if (len == 9 && !NFSBCMP(name, "EVERYONE@", 9)) {
   97                 acep->ae_tag = ACL_EVERYONE;
   98                 acep->ae_id = ACL_UNDEFINED_ID;
   99                 gotid = 1;
  100         }
  101         if (gotid == 0) {
  102                 if (flag & NFSV4ACE_IDENTIFIERGROUP) {
  103                         acep->ae_tag = ACL_GROUP;
  104                         aceerr = nfsv4_strtogid(nd, name, len, &gid, p);
  105                         if (aceerr == 0)
  106                                 acep->ae_id = (uid_t)gid;
  107                 } else {
  108                         acep->ae_tag = ACL_USER;
  109                         aceerr = nfsv4_strtouid(nd, name, len, &uid, p);
  110                         if (aceerr == 0)
  111                                 acep->ae_id = uid;
  112                 }
  113         }
  114         if (len > NFSV4_SMALLSTR)
  115                 free(name, M_NFSSTRING);
  116 
  117         if (aceerr == 0) {
  118                 /*
  119                  * Handle the flags.
  120                  */
  121                 flag &= ~NFSV4ACE_IDENTIFIERGROUP;
  122                 if (flag & NFSV4ACE_FILEINHERIT) {
  123                         flag &= ~NFSV4ACE_FILEINHERIT;
  124                         acep->ae_flags |= ACL_ENTRY_FILE_INHERIT;
  125                 }
  126                 if (flag & NFSV4ACE_DIRECTORYINHERIT) {
  127                         flag &= ~NFSV4ACE_DIRECTORYINHERIT;
  128                         acep->ae_flags |= ACL_ENTRY_DIRECTORY_INHERIT;
  129                 }
  130                 if (flag & NFSV4ACE_NOPROPAGATEINHERIT) {
  131                         flag &= ~NFSV4ACE_NOPROPAGATEINHERIT;
  132                         acep->ae_flags |= ACL_ENTRY_NO_PROPAGATE_INHERIT;
  133                 }
  134                 if (flag & NFSV4ACE_INHERITONLY) {
  135                         flag &= ~NFSV4ACE_INHERITONLY;
  136                         acep->ae_flags |= ACL_ENTRY_INHERIT_ONLY;
  137                 }
  138                 if (flag & NFSV4ACE_SUCCESSFULACCESS) {
  139                         flag &= ~NFSV4ACE_SUCCESSFULACCESS;
  140                         acep->ae_flags |= ACL_ENTRY_SUCCESSFUL_ACCESS;
  141                 }
  142                 if (flag & NFSV4ACE_FAILEDACCESS) {
  143                         flag &= ~NFSV4ACE_FAILEDACCESS;
  144                         acep->ae_flags |= ACL_ENTRY_FAILED_ACCESS;
  145                 }
  146                 /*
  147                  * Set ae_entry_type.
  148                  */
  149                 if (acetype == NFSV4ACE_ALLOWEDTYPE)
  150                         acep->ae_entry_type = ACL_ENTRY_TYPE_ALLOW;
  151                 else if (acetype == NFSV4ACE_DENIEDTYPE)
  152                         acep->ae_entry_type = ACL_ENTRY_TYPE_DENY;
  153                 else if (acetype == NFSV4ACE_AUDITTYPE)
  154                         acep->ae_entry_type = ACL_ENTRY_TYPE_AUDIT;
  155                 else if (acetype == NFSV4ACE_ALARMTYPE)
  156                         acep->ae_entry_type = ACL_ENTRY_TYPE_ALARM;
  157                 else
  158                         aceerr = NFSERR_ATTRNOTSUPP;
  159         }
  160 
  161         /*
  162          * Now, check for unsupported flag bits.
  163          */
  164         if (aceerr == 0 && flag != 0)
  165                 aceerr = NFSERR_ATTRNOTSUPP;
  166 
  167         /*
  168          * And turn the mask into perm bits.
  169          */
  170         if (aceerr == 0)
  171                 aceerr = nfsrv_acemasktoperm(acetype, mask, owner, VREG,
  172                     &acep->ae_perm);
  173         *aceerrp = aceerr;
  174         if (acesizep)
  175                 *acesizep = NFSM_RNDUP(len) + (4 * NFSX_UNSIGNED);
  176         error = 0;
  177 nfsmout:
  178         NFSEXITCODE(error);
  179         return (error);
  180 }
  181 
  182 /*
  183  * Turn an NFSv4 ace mask into R/W/X flag bits.
  184  */
  185 static int
  186 nfsrv_acemasktoperm(u_int32_t acetype, u_int32_t mask, int owner,
  187     enum vtype type, acl_perm_t *permp)
  188 {
  189         acl_perm_t perm = 0x0;
  190         int error = 0;
  191 
  192         if (mask & NFSV4ACE_READDATA) {
  193                 mask &= ~NFSV4ACE_READDATA;
  194                 perm |= ACL_READ_DATA;
  195         }
  196         if (mask & NFSV4ACE_LISTDIRECTORY) {
  197                 mask &= ~NFSV4ACE_LISTDIRECTORY;
  198                 perm |= ACL_LIST_DIRECTORY;
  199         }
  200         if (mask & NFSV4ACE_WRITEDATA) {
  201                 mask &= ~NFSV4ACE_WRITEDATA;
  202                 perm |= ACL_WRITE_DATA;
  203         }
  204         if (mask & NFSV4ACE_ADDFILE) {
  205                 mask &= ~NFSV4ACE_ADDFILE;
  206                 perm |= ACL_ADD_FILE;
  207         }
  208         if (mask & NFSV4ACE_APPENDDATA) {
  209                 mask &= ~NFSV4ACE_APPENDDATA;
  210                 perm |= ACL_APPEND_DATA;
  211         }
  212         if (mask & NFSV4ACE_ADDSUBDIRECTORY) {
  213                 mask &= ~NFSV4ACE_ADDSUBDIRECTORY;
  214                 perm |= ACL_ADD_SUBDIRECTORY;
  215         }
  216         if (mask & NFSV4ACE_READNAMEDATTR) {
  217                 mask &= ~NFSV4ACE_READNAMEDATTR;
  218                 perm |= ACL_READ_NAMED_ATTRS;
  219         }
  220         if (mask & NFSV4ACE_WRITENAMEDATTR) {
  221                 mask &= ~NFSV4ACE_WRITENAMEDATTR;
  222                 perm |= ACL_WRITE_NAMED_ATTRS;
  223         }
  224         if (mask & NFSV4ACE_EXECUTE) {
  225                 mask &= ~NFSV4ACE_EXECUTE;
  226                 perm |= ACL_EXECUTE;
  227         }
  228         if (mask & NFSV4ACE_SEARCH) {
  229                 mask &= ~NFSV4ACE_SEARCH;
  230                 perm |= ACL_EXECUTE;
  231         }
  232         if (mask & NFSV4ACE_DELETECHILD) {
  233                 mask &= ~NFSV4ACE_DELETECHILD;
  234                 perm |= ACL_DELETE_CHILD;
  235         }
  236         if (mask & NFSV4ACE_READATTRIBUTES) {
  237                 mask &= ~NFSV4ACE_READATTRIBUTES;
  238                 perm |= ACL_READ_ATTRIBUTES;
  239         }
  240         if (mask & NFSV4ACE_WRITEATTRIBUTES) {
  241                 mask &= ~NFSV4ACE_WRITEATTRIBUTES;
  242                 perm |= ACL_WRITE_ATTRIBUTES;
  243         }
  244         if (mask & NFSV4ACE_DELETE) {
  245                 mask &= ~NFSV4ACE_DELETE;
  246                 perm |= ACL_DELETE;
  247         }
  248         if (mask & NFSV4ACE_READACL) {
  249                 mask &= ~NFSV4ACE_READACL;
  250                 perm |= ACL_READ_ACL;
  251         }
  252         if (mask & NFSV4ACE_WRITEACL) {
  253                 mask &= ~NFSV4ACE_WRITEACL;
  254                 perm |= ACL_WRITE_ACL;
  255         }
  256         if (mask & NFSV4ACE_WRITEOWNER) {
  257                 mask &= ~NFSV4ACE_WRITEOWNER;
  258                 perm |= ACL_WRITE_OWNER;
  259         }
  260         if (mask & NFSV4ACE_SYNCHRONIZE) {
  261                 mask &= ~NFSV4ACE_SYNCHRONIZE;
  262                 perm |= ACL_SYNCHRONIZE;
  263         }
  264         if (mask != 0) {
  265                 error = NFSERR_ATTRNOTSUPP;
  266                 goto out;
  267         }
  268         *permp = perm;
  269 
  270 out:
  271         NFSEXITCODE(error);
  272         return (error);
  273 }
  274 
  275 /* local functions */
  276 static int nfsrv_buildace(struct nfsrv_descript *, u_char *, int,
  277     enum vtype, int, int, struct acl_entry *);
  278 
  279 /*
  280  * This function builds an NFS ace.
  281  */
  282 static int
  283 nfsrv_buildace(struct nfsrv_descript *nd, u_char *name, int namelen,
  284     enum vtype type, int group, int owner, struct acl_entry *ace)
  285 {
  286         u_int32_t *tl, aceflag = 0x0, acemask = 0x0, acetype;
  287         int full_len;
  288 
  289         full_len = NFSM_RNDUP(namelen);
  290         NFSM_BUILD(tl, u_int32_t *, 4 * NFSX_UNSIGNED + full_len);
  291 
  292         /*
  293          * Fill in the ace type.
  294          */
  295         if (ace->ae_entry_type & ACL_ENTRY_TYPE_ALLOW)
  296                 acetype = NFSV4ACE_ALLOWEDTYPE;
  297         else if (ace->ae_entry_type & ACL_ENTRY_TYPE_DENY)
  298                 acetype = NFSV4ACE_DENIEDTYPE;
  299         else if (ace->ae_entry_type & ACL_ENTRY_TYPE_AUDIT)
  300                 acetype = NFSV4ACE_AUDITTYPE;
  301         else
  302                 acetype = NFSV4ACE_ALARMTYPE;
  303         *tl++ = txdr_unsigned(acetype);
  304 
  305         /*
  306          * Set the flag bits from the ACL.
  307          */
  308         if (ace->ae_flags & ACL_ENTRY_FILE_INHERIT)
  309                 aceflag |= NFSV4ACE_FILEINHERIT;
  310         if (ace->ae_flags & ACL_ENTRY_DIRECTORY_INHERIT)
  311                 aceflag |= NFSV4ACE_DIRECTORYINHERIT;
  312         if (ace->ae_flags & ACL_ENTRY_NO_PROPAGATE_INHERIT)
  313                 aceflag |= NFSV4ACE_NOPROPAGATEINHERIT;
  314         if (ace->ae_flags & ACL_ENTRY_INHERIT_ONLY)
  315                 aceflag |= NFSV4ACE_INHERITONLY;
  316         if (ace->ae_flags & ACL_ENTRY_SUCCESSFUL_ACCESS)
  317                 aceflag |= NFSV4ACE_SUCCESSFULACCESS;
  318         if (ace->ae_flags & ACL_ENTRY_FAILED_ACCESS)
  319                 aceflag |= NFSV4ACE_FAILEDACCESS;
  320         if (group)
  321                 aceflag |= NFSV4ACE_IDENTIFIERGROUP;
  322         *tl++ = txdr_unsigned(aceflag);
  323         if (type == VDIR) {
  324                 if (ace->ae_perm & ACL_LIST_DIRECTORY)
  325                         acemask |= NFSV4ACE_LISTDIRECTORY;
  326                 if (ace->ae_perm & ACL_ADD_FILE)
  327                         acemask |= NFSV4ACE_ADDFILE;
  328                 if (ace->ae_perm & ACL_ADD_SUBDIRECTORY)
  329                         acemask |= NFSV4ACE_ADDSUBDIRECTORY;
  330                 if (ace->ae_perm & ACL_READ_NAMED_ATTRS)
  331                         acemask |= NFSV4ACE_READNAMEDATTR;
  332                 if (ace->ae_perm & ACL_WRITE_NAMED_ATTRS)
  333                         acemask |= NFSV4ACE_WRITENAMEDATTR;
  334                 if (ace->ae_perm & ACL_EXECUTE)
  335                         acemask |= NFSV4ACE_SEARCH;
  336                 if (ace->ae_perm & ACL_DELETE_CHILD)
  337                         acemask |= NFSV4ACE_DELETECHILD;
  338                 if (ace->ae_perm & ACL_READ_ATTRIBUTES)
  339                         acemask |= NFSV4ACE_READATTRIBUTES;
  340                 if (ace->ae_perm & ACL_WRITE_ATTRIBUTES)
  341                         acemask |= NFSV4ACE_WRITEATTRIBUTES;
  342                 if (ace->ae_perm & ACL_DELETE)
  343                         acemask |= NFSV4ACE_DELETE;
  344                 if (ace->ae_perm & ACL_READ_ACL)
  345                         acemask |= NFSV4ACE_READACL;
  346                 if (ace->ae_perm & ACL_WRITE_ACL)
  347                         acemask |= NFSV4ACE_WRITEACL;
  348                 if (ace->ae_perm & ACL_WRITE_OWNER)
  349                         acemask |= NFSV4ACE_WRITEOWNER;
  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 APPLESTATIC 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 APPLESTATIC 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 APPLESTATIC 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: 39bf2073f4cef898e633b6bd1fae80b3


[ 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.