1 1.2 pgoyette /* $NetBSD: nfs_commonacl.c,v 1.2 2016/12/13 22:31:51 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.2 pgoyette /* __FBSDID("FreeBSD: head/sys/fs/nfs/nfs_commonacl.c 297793 2016-04-10 23:07:00Z pfg "); */ 31 1.2 pgoyette __RCSID("$NetBSD: nfs_commonacl.c,v 1.2 2016/12/13 22:31:51 pgoyette Exp $"); 32 1.1 dholland 33 1.1 dholland #ifndef APPLEKEXT 34 1.2 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.2 pgoyette if (ace->ae_perm & ACL_SYNCHRONIZE) 353 1.2 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.2 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.2 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