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