]> git.proxmox.com Git - mirror_zfs-debian.git/blame - module/zfs/zfs_acl.c
Imported Upstream version 0.6.4.2
[mirror_zfs-debian.git] / module / zfs / zfs_acl.c
CommitLineData
34dc7c2f
BB
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
428870ff 22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
a08ee875 23 * Copyright (c) 2013 by Delphix. All rights reserved.
34dc7c2f
BB
24 */
25
60101509 26
34dc7c2f
BB
27#include <sys/types.h>
28#include <sys/param.h>
29#include <sys/time.h>
30#include <sys/systm.h>
31#include <sys/sysmacros.h>
32#include <sys/resource.h>
33#include <sys/vfs.h>
34#include <sys/vnode.h>
35#include <sys/sid.h>
36#include <sys/file.h>
37#include <sys/stat.h>
38#include <sys/kmem.h>
39#include <sys/cmn_err.h>
40#include <sys/errno.h>
41#include <sys/unistd.h>
42#include <sys/sdt.h>
43#include <sys/fs/zfs.h>
44#include <sys/mode.h>
45#include <sys/policy.h>
46#include <sys/zfs_znode.h>
47#include <sys/zfs_fuid.h>
48#include <sys/zfs_acl.h>
49#include <sys/zfs_dir.h>
50#include <sys/zfs_vfsops.h>
51#include <sys/dmu.h>
52#include <sys/dnode.h>
53#include <sys/zap.h>
428870ff 54#include <sys/sa.h>
ea04106b 55#include <sys/trace_acl.h>
34dc7c2f 56#include "fs/fs_subr.h"
34dc7c2f
BB
57
58#define ALLOW ACE_ACCESS_ALLOWED_ACE_TYPE
59#define DENY ACE_ACCESS_DENIED_ACE_TYPE
60#define MAX_ACE_TYPE ACE_SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE
b128c09f 61#define MIN_ACE_TYPE ALLOW
34dc7c2f
BB
62
63#define OWNING_GROUP (ACE_GROUP|ACE_IDENTIFIER_GROUP)
64#define EVERYONE_ALLOW_MASK (ACE_READ_ACL|ACE_READ_ATTRIBUTES | \
65 ACE_READ_NAMED_ATTRS|ACE_SYNCHRONIZE)
66#define EVERYONE_DENY_MASK (ACE_WRITE_ACL|ACE_WRITE_OWNER | \
67 ACE_WRITE_ATTRIBUTES|ACE_WRITE_NAMED_ATTRS)
68#define OWNER_ALLOW_MASK (ACE_WRITE_ACL | ACE_WRITE_OWNER | \
69 ACE_WRITE_ATTRIBUTES|ACE_WRITE_NAMED_ATTRS)
34dc7c2f
BB
70
71#define ZFS_CHECKED_MASKS (ACE_READ_ACL|ACE_READ_ATTRIBUTES|ACE_READ_DATA| \
72 ACE_READ_NAMED_ATTRS|ACE_WRITE_DATA|ACE_WRITE_ATTRIBUTES| \
73 ACE_WRITE_NAMED_ATTRS|ACE_APPEND_DATA|ACE_EXECUTE|ACE_WRITE_OWNER| \
74 ACE_WRITE_ACL|ACE_DELETE|ACE_DELETE_CHILD|ACE_SYNCHRONIZE)
75
9babb374
BB
76#define WRITE_MASK_DATA (ACE_WRITE_DATA|ACE_APPEND_DATA|ACE_WRITE_NAMED_ATTRS)
77#define WRITE_MASK_ATTRS (ACE_WRITE_ACL|ACE_WRITE_OWNER|ACE_WRITE_ATTRIBUTES| \
78 ACE_DELETE|ACE_DELETE_CHILD)
79#define WRITE_MASK (WRITE_MASK_DATA|WRITE_MASK_ATTRS)
34dc7c2f
BB
80
81#define OGE_CLEAR (ACE_READ_DATA|ACE_LIST_DIRECTORY|ACE_WRITE_DATA| \
82 ACE_ADD_FILE|ACE_APPEND_DATA|ACE_ADD_SUBDIRECTORY|ACE_EXECUTE)
83
84#define OKAY_MASK_BITS (ACE_READ_DATA|ACE_LIST_DIRECTORY|ACE_WRITE_DATA| \
85 ACE_ADD_FILE|ACE_APPEND_DATA|ACE_ADD_SUBDIRECTORY|ACE_EXECUTE)
86
87#define ALL_INHERIT (ACE_FILE_INHERIT_ACE|ACE_DIRECTORY_INHERIT_ACE | \
88 ACE_NO_PROPAGATE_INHERIT_ACE|ACE_INHERIT_ONLY_ACE|ACE_INHERITED_ACE)
89
90#define RESTRICTED_CLEAR (ACE_WRITE_ACL|ACE_WRITE_OWNER)
91
92#define V4_ACL_WIDE_FLAGS (ZFS_ACL_AUTO_INHERIT|ZFS_ACL_DEFAULTED|\
93 ZFS_ACL_PROTECTED)
94
95#define ZFS_ACL_WIDE_FLAGS (V4_ACL_WIDE_FLAGS|ZFS_ACL_TRIVIAL|ZFS_INHERIT_ACE|\
96 ZFS_ACL_OBJ_ACE)
97
45d1cae3
BB
98#define ALL_MODE_EXECS (S_IXUSR | S_IXGRP | S_IXOTH)
99
34dc7c2f
BB
100static uint16_t
101zfs_ace_v0_get_type(void *acep)
102{
103 return (((zfs_oldace_t *)acep)->z_type);
104}
105
106static uint16_t
107zfs_ace_v0_get_flags(void *acep)
108{
109 return (((zfs_oldace_t *)acep)->z_flags);
110}
111
112static uint32_t
113zfs_ace_v0_get_mask(void *acep)
114{
115 return (((zfs_oldace_t *)acep)->z_access_mask);
116}
117
118static uint64_t
119zfs_ace_v0_get_who(void *acep)
120{
121 return (((zfs_oldace_t *)acep)->z_fuid);
122}
123
124static void
125zfs_ace_v0_set_type(void *acep, uint16_t type)
126{
127 ((zfs_oldace_t *)acep)->z_type = type;
128}
129
130static void
131zfs_ace_v0_set_flags(void *acep, uint16_t flags)
132{
133 ((zfs_oldace_t *)acep)->z_flags = flags;
134}
135
136static void
137zfs_ace_v0_set_mask(void *acep, uint32_t mask)
138{
139 ((zfs_oldace_t *)acep)->z_access_mask = mask;
140}
141
142static void
143zfs_ace_v0_set_who(void *acep, uint64_t who)
144{
145 ((zfs_oldace_t *)acep)->z_fuid = who;
146}
147
148/*ARGSUSED*/
149static size_t
150zfs_ace_v0_size(void *acep)
151{
152 return (sizeof (zfs_oldace_t));
153}
154
155static size_t
156zfs_ace_v0_abstract_size(void)
157{
158 return (sizeof (zfs_oldace_t));
159}
160
161static int
162zfs_ace_v0_mask_off(void)
163{
164 return (offsetof(zfs_oldace_t, z_access_mask));
165}
166
167/*ARGSUSED*/
168static int
169zfs_ace_v0_data(void *acep, void **datap)
170{
171 *datap = NULL;
172 return (0);
173}
174
175static acl_ops_t zfs_acl_v0_ops = {
176 zfs_ace_v0_get_mask,
177 zfs_ace_v0_set_mask,
178 zfs_ace_v0_get_flags,
179 zfs_ace_v0_set_flags,
180 zfs_ace_v0_get_type,
181 zfs_ace_v0_set_type,
182 zfs_ace_v0_get_who,
183 zfs_ace_v0_set_who,
184 zfs_ace_v0_size,
185 zfs_ace_v0_abstract_size,
186 zfs_ace_v0_mask_off,
187 zfs_ace_v0_data
188};
189
190static uint16_t
191zfs_ace_fuid_get_type(void *acep)
192{
193 return (((zfs_ace_hdr_t *)acep)->z_type);
194}
195
196static uint16_t
197zfs_ace_fuid_get_flags(void *acep)
198{
199 return (((zfs_ace_hdr_t *)acep)->z_flags);
200}
201
202static uint32_t
203zfs_ace_fuid_get_mask(void *acep)
204{
205 return (((zfs_ace_hdr_t *)acep)->z_access_mask);
206}
207
208static uint64_t
209zfs_ace_fuid_get_who(void *args)
210{
211 uint16_t entry_type;
212 zfs_ace_t *acep = args;
213
214 entry_type = acep->z_hdr.z_flags & ACE_TYPE_FLAGS;
215
216 if (entry_type == ACE_OWNER || entry_type == OWNING_GROUP ||
217 entry_type == ACE_EVERYONE)
218 return (-1);
219 return (((zfs_ace_t *)acep)->z_fuid);
220}
221
222static void
223zfs_ace_fuid_set_type(void *acep, uint16_t type)
224{
225 ((zfs_ace_hdr_t *)acep)->z_type = type;
226}
227
228static void
229zfs_ace_fuid_set_flags(void *acep, uint16_t flags)
230{
231 ((zfs_ace_hdr_t *)acep)->z_flags = flags;
232}
233
234static void
235zfs_ace_fuid_set_mask(void *acep, uint32_t mask)
236{
237 ((zfs_ace_hdr_t *)acep)->z_access_mask = mask;
238}
239
240static void
241zfs_ace_fuid_set_who(void *arg, uint64_t who)
242{
243 zfs_ace_t *acep = arg;
244
245 uint16_t entry_type = acep->z_hdr.z_flags & ACE_TYPE_FLAGS;
246
247 if (entry_type == ACE_OWNER || entry_type == OWNING_GROUP ||
248 entry_type == ACE_EVERYONE)
249 return;
250 acep->z_fuid = who;
251}
252
253static size_t
254zfs_ace_fuid_size(void *acep)
255{
256 zfs_ace_hdr_t *zacep = acep;
257 uint16_t entry_type;
258
259 switch (zacep->z_type) {
260 case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE:
261 case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE:
262 case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE:
263 case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE:
264 return (sizeof (zfs_object_ace_t));
265 case ALLOW:
266 case DENY:
267 entry_type =
268 (((zfs_ace_hdr_t *)acep)->z_flags & ACE_TYPE_FLAGS);
269 if (entry_type == ACE_OWNER ||
b128c09f 270 entry_type == OWNING_GROUP ||
34dc7c2f
BB
271 entry_type == ACE_EVERYONE)
272 return (sizeof (zfs_ace_hdr_t));
273 /*FALLTHROUGH*/
274 default:
275 return (sizeof (zfs_ace_t));
276 }
277}
278
279static size_t
280zfs_ace_fuid_abstract_size(void)
281{
282 return (sizeof (zfs_ace_hdr_t));
283}
284
285static int
286zfs_ace_fuid_mask_off(void)
287{
288 return (offsetof(zfs_ace_hdr_t, z_access_mask));
289}
290
291static int
292zfs_ace_fuid_data(void *acep, void **datap)
293{
294 zfs_ace_t *zacep = acep;
295 zfs_object_ace_t *zobjp;
296
297 switch (zacep->z_hdr.z_type) {
298 case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE:
299 case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE:
300 case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE:
301 case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE:
302 zobjp = acep;
303 *datap = (caddr_t)zobjp + sizeof (zfs_ace_t);
304 return (sizeof (zfs_object_ace_t) - sizeof (zfs_ace_t));
305 default:
306 *datap = NULL;
307 return (0);
308 }
309}
310
311static acl_ops_t zfs_acl_fuid_ops = {
312 zfs_ace_fuid_get_mask,
313 zfs_ace_fuid_set_mask,
314 zfs_ace_fuid_get_flags,
315 zfs_ace_fuid_set_flags,
316 zfs_ace_fuid_get_type,
317 zfs_ace_fuid_set_type,
318 zfs_ace_fuid_get_who,
319 zfs_ace_fuid_set_who,
320 zfs_ace_fuid_size,
321 zfs_ace_fuid_abstract_size,
322 zfs_ace_fuid_mask_off,
323 zfs_ace_fuid_data
324};
325
428870ff
BB
326/*
327 * The following three functions are provided for compatibility with
328 * older ZPL version in order to determine if the file use to have
329 * an external ACL and what version of ACL previously existed on the
330 * file. Would really be nice to not need this, sigh.
331 */
428870ff
BB
332uint64_t
333zfs_external_acl(znode_t *zp)
334{
335 zfs_acl_phys_t acl_phys;
572e2857 336 int error;
428870ff
BB
337
338 if (zp->z_is_sa)
339 return (0);
340
572e2857
BB
341 /*
342 * Need to deal with a potential
343 * race where zfs_sa_upgrade could cause
344 * z_isa_sa to change.
345 *
346 * If the lookup fails then the state of z_is_sa should have
347 * changed.
348 */
428870ff 349
3558fd73 350 if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_ZNODE_ACL(ZTOZSB(zp)),
572e2857
BB
351 &acl_phys, sizeof (acl_phys))) == 0)
352 return (acl_phys.z_acl_extern_obj);
353 else {
354 /*
355 * after upgrade the SA_ZPL_ZNODE_ACL should have been
356 * removed
357 */
358 VERIFY(zp->z_is_sa && error == ENOENT);
359 return (0);
360 }
428870ff
BB
361}
362
363/*
364 * Determine size of ACL in bytes
365 *
366 * This is more complicated than it should be since we have to deal
367 * with old external ACLs.
368 */
369static int
370zfs_acl_znode_info(znode_t *zp, int *aclsize, int *aclcount,
371 zfs_acl_phys_t *aclphys)
372{
3558fd73 373 zfs_sb_t *zsb = ZTOZSB(zp);
428870ff
BB
374 uint64_t acl_count;
375 int size;
376 int error;
377
572e2857 378 ASSERT(MUTEX_HELD(&zp->z_acl_lock));
428870ff 379 if (zp->z_is_sa) {
3558fd73 380 if ((error = sa_size(zp->z_sa_hdl, SA_ZPL_DACL_ACES(zsb),
428870ff
BB
381 &size)) != 0)
382 return (error);
383 *aclsize = size;
3558fd73 384 if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_DACL_COUNT(zsb),
428870ff
BB
385 &acl_count, sizeof (acl_count))) != 0)
386 return (error);
387 *aclcount = acl_count;
388 } else {
3558fd73 389 if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_ZNODE_ACL(zsb),
428870ff
BB
390 aclphys, sizeof (*aclphys))) != 0)
391 return (error);
392
393 if (aclphys->z_acl_version == ZFS_ACL_VERSION_INITIAL) {
394 *aclsize = ZFS_ACL_SIZE(aclphys->z_acl_size);
395 *aclcount = aclphys->z_acl_size;
396 } else {
397 *aclsize = aclphys->z_acl_size;
398 *aclcount = aclphys->z_acl_count;
399 }
400 }
401 return (0);
402}
403
404int
405zfs_znode_acl_version(znode_t *zp)
406{
407 zfs_acl_phys_t acl_phys;
408
572e2857 409 if (zp->z_is_sa)
428870ff 410 return (ZFS_ACL_VERSION_FUID);
572e2857
BB
411 else {
412 int error;
413
414 /*
415 * Need to deal with a potential
416 * race where zfs_sa_upgrade could cause
417 * z_isa_sa to change.
418 *
419 * If the lookup fails then the state of z_is_sa should have
420 * changed.
421 */
422 if ((error = sa_lookup(zp->z_sa_hdl,
3558fd73 423 SA_ZPL_ZNODE_ACL(ZTOZSB(zp)),
572e2857
BB
424 &acl_phys, sizeof (acl_phys))) == 0)
425 return (acl_phys.z_acl_version);
426 else {
427 /*
428 * After upgrade SA_ZPL_ZNODE_ACL should have
429 * been removed.
430 */
431 VERIFY(zp->z_is_sa && error == ENOENT);
432 return (ZFS_ACL_VERSION_FUID);
433 }
428870ff
BB
434 }
435}
436
34dc7c2f
BB
437static int
438zfs_acl_version(int version)
439{
440 if (version < ZPL_VERSION_FUID)
441 return (ZFS_ACL_VERSION_INITIAL);
442 else
443 return (ZFS_ACL_VERSION_FUID);
444}
445
446static int
447zfs_acl_version_zp(znode_t *zp)
448{
3558fd73 449 return (zfs_acl_version(ZTOZSB(zp)->z_version));
34dc7c2f
BB
450}
451
428870ff 452zfs_acl_t *
34dc7c2f
BB
453zfs_acl_alloc(int vers)
454{
455 zfs_acl_t *aclp;
456
ea04106b 457 aclp = kmem_zalloc(sizeof (zfs_acl_t), KM_SLEEP);
34dc7c2f
BB
458 list_create(&aclp->z_acl, sizeof (zfs_acl_node_t),
459 offsetof(zfs_acl_node_t, z_next));
460 aclp->z_version = vers;
461 if (vers == ZFS_ACL_VERSION_FUID)
0a6b03d3 462 aclp->z_ops = &zfs_acl_fuid_ops;
34dc7c2f 463 else
0a6b03d3 464 aclp->z_ops = &zfs_acl_v0_ops;
34dc7c2f
BB
465 return (aclp);
466}
467
428870ff 468zfs_acl_node_t *
34dc7c2f
BB
469zfs_acl_node_alloc(size_t bytes)
470{
471 zfs_acl_node_t *aclnode;
472
ea04106b 473 aclnode = kmem_zalloc(sizeof (zfs_acl_node_t), KM_SLEEP);
34dc7c2f 474 if (bytes) {
ea04106b 475 aclnode->z_acldata = kmem_alloc(bytes, KM_SLEEP);
34dc7c2f
BB
476 aclnode->z_allocdata = aclnode->z_acldata;
477 aclnode->z_allocsize = bytes;
478 aclnode->z_size = bytes;
479 }
480
481 return (aclnode);
482}
483
484static void
485zfs_acl_node_free(zfs_acl_node_t *aclnode)
486{
487 if (aclnode->z_allocsize)
488 kmem_free(aclnode->z_allocdata, aclnode->z_allocsize);
489 kmem_free(aclnode, sizeof (zfs_acl_node_t));
490}
491
492static void
493zfs_acl_release_nodes(zfs_acl_t *aclp)
494{
495 zfs_acl_node_t *aclnode;
496
149e873a 497 while ((aclnode = list_head(&aclp->z_acl))) {
34dc7c2f
BB
498 list_remove(&aclp->z_acl, aclnode);
499 zfs_acl_node_free(aclnode);
500 }
501 aclp->z_acl_count = 0;
502 aclp->z_acl_bytes = 0;
503}
504
505void
506zfs_acl_free(zfs_acl_t *aclp)
507{
508 zfs_acl_release_nodes(aclp);
509 list_destroy(&aclp->z_acl);
510 kmem_free(aclp, sizeof (zfs_acl_t));
511}
512
513static boolean_t
b128c09f 514zfs_acl_valid_ace_type(uint_t type, uint_t flags)
34dc7c2f 515{
b128c09f 516 uint16_t entry_type;
34dc7c2f 517
b128c09f
BB
518 switch (type) {
519 case ALLOW:
520 case DENY:
521 case ACE_SYSTEM_AUDIT_ACE_TYPE:
522 case ACE_SYSTEM_ALARM_ACE_TYPE:
523 entry_type = flags & ACE_TYPE_FLAGS;
524 return (entry_type == ACE_OWNER ||
525 entry_type == OWNING_GROUP ||
526 entry_type == ACE_EVERYONE || entry_type == 0 ||
527 entry_type == ACE_IDENTIFIER_GROUP);
34dc7c2f 528 default:
b128c09f
BB
529 if (type >= MIN_ACE_TYPE && type <= MAX_ACE_TYPE)
530 return (B_TRUE);
34dc7c2f 531 }
b128c09f
BB
532 return (B_FALSE);
533}
34dc7c2f 534
b128c09f 535static boolean_t
3558fd73 536zfs_ace_valid(umode_t obj_mode, zfs_acl_t *aclp, uint16_t type, uint16_t iflags)
b128c09f 537{
34dc7c2f 538 /*
b128c09f 539 * first check type of entry
34dc7c2f
BB
540 */
541
b128c09f 542 if (!zfs_acl_valid_ace_type(type, iflags))
34dc7c2f 543 return (B_FALSE);
34dc7c2f
BB
544
545 switch (type) {
546 case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE:
547 case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE:
548 case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE:
549 case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE:
550 if (aclp->z_version < ZFS_ACL_VERSION_FUID)
551 return (B_FALSE);
552 aclp->z_hints |= ZFS_ACL_OBJ_ACE;
553 }
554
555 /*
b128c09f 556 * next check inheritance level flags
34dc7c2f 557 */
34dc7c2f 558
3558fd73 559 if (S_ISDIR(obj_mode) &&
b128c09f 560 (iflags & (ACE_FILE_INHERIT_ACE|ACE_DIRECTORY_INHERIT_ACE)))
34dc7c2f
BB
561 aclp->z_hints |= ZFS_INHERIT_ACE;
562
563 if (iflags & (ACE_INHERIT_ONLY_ACE|ACE_NO_PROPAGATE_INHERIT_ACE)) {
564 if ((iflags & (ACE_FILE_INHERIT_ACE|
565 ACE_DIRECTORY_INHERIT_ACE)) == 0) {
566 return (B_FALSE);
567 }
568 }
569
570 return (B_TRUE);
571}
572
573static void *
574zfs_acl_next_ace(zfs_acl_t *aclp, void *start, uint64_t *who,
575 uint32_t *access_mask, uint16_t *iflags, uint16_t *type)
576{
577 zfs_acl_node_t *aclnode;
578
428870ff
BB
579 ASSERT(aclp);
580
34dc7c2f
BB
581 if (start == NULL) {
582 aclnode = list_head(&aclp->z_acl);
583 if (aclnode == NULL)
584 return (NULL);
585
586 aclp->z_next_ace = aclnode->z_acldata;
587 aclp->z_curr_node = aclnode;
588 aclnode->z_ace_idx = 0;
589 }
590
591 aclnode = aclp->z_curr_node;
592
593 if (aclnode == NULL)
594 return (NULL);
595
596 if (aclnode->z_ace_idx >= aclnode->z_ace_count) {
597 aclnode = list_next(&aclp->z_acl, aclnode);
598 if (aclnode == NULL)
599 return (NULL);
600 else {
601 aclp->z_curr_node = aclnode;
602 aclnode->z_ace_idx = 0;
603 aclp->z_next_ace = aclnode->z_acldata;
604 }
605 }
606
607 if (aclnode->z_ace_idx < aclnode->z_ace_count) {
608 void *acep = aclp->z_next_ace;
b128c09f
BB
609 size_t ace_size;
610
611 /*
612 * Make sure we don't overstep our bounds
613 */
0a6b03d3 614 ace_size = aclp->z_ops->ace_size(acep);
b128c09f
BB
615
616 if (((caddr_t)acep + ace_size) >
617 ((caddr_t)aclnode->z_acldata + aclnode->z_size)) {
618 return (NULL);
619 }
620
0a6b03d3
RY
621 *iflags = aclp->z_ops->ace_flags_get(acep);
622 *type = aclp->z_ops->ace_type_get(acep);
623 *access_mask = aclp->z_ops->ace_mask_get(acep);
624 *who = aclp->z_ops->ace_who_get(acep);
b128c09f 625 aclp->z_next_ace = (caddr_t)aclp->z_next_ace + ace_size;
34dc7c2f 626 aclnode->z_ace_idx++;
428870ff 627
34dc7c2f
BB
628 return ((void *)acep);
629 }
630 return (NULL);
631}
632
633/*ARGSUSED*/
634static uint64_t
635zfs_ace_walk(void *datap, uint64_t cookie, int aclcnt,
636 uint16_t *flags, uint16_t *type, uint32_t *mask)
637{
638 zfs_acl_t *aclp = datap;
639 zfs_ace_hdr_t *acep = (zfs_ace_hdr_t *)(uintptr_t)cookie;
640 uint64_t who;
641
642 acep = zfs_acl_next_ace(aclp, acep, &who, mask,
643 flags, type);
644 return ((uint64_t)(uintptr_t)acep);
645}
646
34dc7c2f
BB
647/*
648 * Copy ACE to internal ZFS format.
649 * While processing the ACL each ACE will be validated for correctness.
650 * ACE FUIDs will be created later.
651 */
652int
3558fd73 653zfs_copy_ace_2_fuid(zfs_sb_t *zsb, umode_t obj_mode, zfs_acl_t *aclp,
428870ff 654 void *datap, zfs_ace_t *z_acl, uint64_t aclcnt, size_t *size,
9babb374 655 zfs_fuid_info_t **fuidp, cred_t *cr)
34dc7c2f
BB
656{
657 int i;
658 uint16_t entry_type;
659 zfs_ace_t *aceptr = z_acl;
660 ace_t *acep = datap;
661 zfs_object_ace_t *zobjacep;
662 ace_object_t *aceobjp;
663
664 for (i = 0; i != aclcnt; i++) {
665 aceptr->z_hdr.z_access_mask = acep->a_access_mask;
666 aceptr->z_hdr.z_flags = acep->a_flags;
667 aceptr->z_hdr.z_type = acep->a_type;
668 entry_type = aceptr->z_hdr.z_flags & ACE_TYPE_FLAGS;
669 if (entry_type != ACE_OWNER && entry_type != OWNING_GROUP &&
670 entry_type != ACE_EVERYONE) {
3558fd73 671 aceptr->z_fuid = zfs_fuid_create(zsb, acep->a_who,
9babb374
BB
672 cr, (entry_type == 0) ?
673 ZFS_ACE_USER : ZFS_ACE_GROUP, fuidp);
34dc7c2f
BB
674 }
675
676 /*
677 * Make sure ACE is valid
678 */
3558fd73 679 if (zfs_ace_valid(obj_mode, aclp, aceptr->z_hdr.z_type,
34dc7c2f 680 aceptr->z_hdr.z_flags) != B_TRUE)
a08ee875 681 return (SET_ERROR(EINVAL));
34dc7c2f
BB
682
683 switch (acep->a_type) {
684 case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE:
685 case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE:
686 case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE:
687 case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE:
688 zobjacep = (zfs_object_ace_t *)aceptr;
689 aceobjp = (ace_object_t *)acep;
690
691 bcopy(aceobjp->a_obj_type, zobjacep->z_object_type,
692 sizeof (aceobjp->a_obj_type));
693 bcopy(aceobjp->a_inherit_obj_type,
694 zobjacep->z_inherit_type,
695 sizeof (aceobjp->a_inherit_obj_type));
696 acep = (ace_t *)((caddr_t)acep + sizeof (ace_object_t));
697 break;
698 default:
699 acep = (ace_t *)((caddr_t)acep + sizeof (ace_t));
700 }
701
702 aceptr = (zfs_ace_t *)((caddr_t)aceptr +
0a6b03d3 703 aclp->z_ops->ace_size(aceptr));
34dc7c2f
BB
704 }
705
706 *size = (caddr_t)aceptr - (caddr_t)z_acl;
707
708 return (0);
709}
710
711/*
712 * Copy ZFS ACEs to fixed size ace_t layout
713 */
714static void
3558fd73 715zfs_copy_fuid_2_ace(zfs_sb_t *zsb, zfs_acl_t *aclp, cred_t *cr,
34dc7c2f
BB
716 void *datap, int filter)
717{
718 uint64_t who;
719 uint32_t access_mask;
720 uint16_t iflags, type;
721 zfs_ace_hdr_t *zacep = NULL;
722 ace_t *acep = datap;
723 ace_object_t *objacep;
724 zfs_object_ace_t *zobjacep;
725 size_t ace_size;
726 uint16_t entry_type;
727
149e873a
BB
728 while ((zacep = zfs_acl_next_ace(aclp, zacep,
729 &who, &access_mask, &iflags, &type))) {
34dc7c2f
BB
730
731 switch (type) {
732 case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE:
733 case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE:
734 case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE:
735 case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE:
736 if (filter) {
737 continue;
738 }
739 zobjacep = (zfs_object_ace_t *)zacep;
740 objacep = (ace_object_t *)acep;
741 bcopy(zobjacep->z_object_type,
742 objacep->a_obj_type,
743 sizeof (zobjacep->z_object_type));
744 bcopy(zobjacep->z_inherit_type,
745 objacep->a_inherit_obj_type,
746 sizeof (zobjacep->z_inherit_type));
747 ace_size = sizeof (ace_object_t);
748 break;
749 default:
750 ace_size = sizeof (ace_t);
751 break;
752 }
753
754 entry_type = (iflags & ACE_TYPE_FLAGS);
755 if ((entry_type != ACE_OWNER &&
b128c09f 756 entry_type != OWNING_GROUP &&
34dc7c2f 757 entry_type != ACE_EVERYONE)) {
3558fd73 758 acep->a_who = zfs_fuid_map_id(zsb, who,
34dc7c2f
BB
759 cr, (entry_type & ACE_IDENTIFIER_GROUP) ?
760 ZFS_ACE_GROUP : ZFS_ACE_USER);
761 } else {
762 acep->a_who = (uid_t)(int64_t)who;
763 }
764 acep->a_access_mask = access_mask;
765 acep->a_flags = iflags;
766 acep->a_type = type;
767 acep = (ace_t *)((caddr_t)acep + ace_size);
768 }
769}
770
771static int
3558fd73 772zfs_copy_ace_2_oldace(umode_t obj_mode, zfs_acl_t *aclp, ace_t *acep,
34dc7c2f
BB
773 zfs_oldace_t *z_acl, int aclcnt, size_t *size)
774{
775 int i;
776 zfs_oldace_t *aceptr = z_acl;
777
778 for (i = 0; i != aclcnt; i++, aceptr++) {
779 aceptr->z_access_mask = acep[i].a_access_mask;
780 aceptr->z_type = acep[i].a_type;
781 aceptr->z_flags = acep[i].a_flags;
782 aceptr->z_fuid = acep[i].a_who;
783 /*
784 * Make sure ACE is valid
785 */
3558fd73 786 if (zfs_ace_valid(obj_mode, aclp, aceptr->z_type,
34dc7c2f 787 aceptr->z_flags) != B_TRUE)
a08ee875 788 return (SET_ERROR(EINVAL));
34dc7c2f
BB
789 }
790 *size = (caddr_t)aceptr - (caddr_t)z_acl;
791 return (0);
792}
793
794/*
795 * convert old ACL format to new
796 */
797void
9babb374 798zfs_acl_xform(znode_t *zp, zfs_acl_t *aclp, cred_t *cr)
34dc7c2f
BB
799{
800 zfs_oldace_t *oldaclp;
801 int i;
802 uint16_t type, iflags;
803 uint32_t access_mask;
804 uint64_t who;
805 void *cookie = NULL;
806 zfs_acl_node_t *newaclnode;
807
808 ASSERT(aclp->z_version == ZFS_ACL_VERSION_INITIAL);
809 /*
810 * First create the ACE in a contiguous piece of memory
811 * for zfs_copy_ace_2_fuid().
812 *
813 * We only convert an ACL once, so this won't happen
814 * everytime.
815 */
816 oldaclp = kmem_alloc(sizeof (zfs_oldace_t) * aclp->z_acl_count,
817 KM_SLEEP);
818 i = 0;
149e873a
BB
819 while ((cookie = zfs_acl_next_ace(aclp, cookie, &who,
820 &access_mask, &iflags, &type))) {
34dc7c2f
BB
821 oldaclp[i].z_flags = iflags;
822 oldaclp[i].z_type = type;
823 oldaclp[i].z_fuid = who;
824 oldaclp[i++].z_access_mask = access_mask;
825 }
826
827 newaclnode = zfs_acl_node_alloc(aclp->z_acl_count *
828 sizeof (zfs_object_ace_t));
0a6b03d3 829 aclp->z_ops = &zfs_acl_fuid_ops;
3558fd73
BB
830 VERIFY(zfs_copy_ace_2_fuid(ZTOZSB(zp), ZTOI(zp)->i_mode,
831 aclp, oldaclp, newaclnode->z_acldata, aclp->z_acl_count,
9babb374 832 &newaclnode->z_size, NULL, cr) == 0);
34dc7c2f
BB
833 newaclnode->z_ace_count = aclp->z_acl_count;
834 aclp->z_version = ZFS_ACL_VERSION;
835 kmem_free(oldaclp, aclp->z_acl_count * sizeof (zfs_oldace_t));
836
837 /*
838 * Release all previous ACL nodes
839 */
840
841 zfs_acl_release_nodes(aclp);
842
843 list_insert_head(&aclp->z_acl, newaclnode);
844
845 aclp->z_acl_bytes = newaclnode->z_size;
846 aclp->z_acl_count = newaclnode->z_ace_count;
847
848}
849
850/*
851 * Convert unix access mask to v4 access mask
852 */
853static uint32_t
854zfs_unix_to_v4(uint32_t access_mask)
855{
856 uint32_t new_mask = 0;
857
858 if (access_mask & S_IXOTH)
859 new_mask |= ACE_EXECUTE;
860 if (access_mask & S_IWOTH)
861 new_mask |= ACE_WRITE_DATA;
862 if (access_mask & S_IROTH)
863 new_mask |= ACE_READ_DATA;
864 return (new_mask);
865}
866
867static void
868zfs_set_ace(zfs_acl_t *aclp, void *acep, uint32_t access_mask,
869 uint16_t access_type, uint64_t fuid, uint16_t entry_type)
870{
871 uint16_t type = entry_type & ACE_TYPE_FLAGS;
872
0a6b03d3
RY
873 aclp->z_ops->ace_mask_set(acep, access_mask);
874 aclp->z_ops->ace_type_set(acep, access_type);
875 aclp->z_ops->ace_flags_set(acep, entry_type);
b128c09f 876 if ((type != ACE_OWNER && type != OWNING_GROUP &&
34dc7c2f 877 type != ACE_EVERYONE))
0a6b03d3 878 aclp->z_ops->ace_who_set(acep, fuid);
34dc7c2f
BB
879}
880
881/*
882 * Determine mode of file based on ACL.
883 * Also, create FUIDs for any User/Group ACEs
884 */
428870ff
BB
885uint64_t
886zfs_mode_compute(uint64_t fmode, zfs_acl_t *aclp,
887 uint64_t *pflags, uint64_t fuid, uint64_t fgid)
34dc7c2f
BB
888{
889 int entry_type;
890 mode_t mode;
891 mode_t seen = 0;
892 zfs_ace_hdr_t *acep = NULL;
893 uint64_t who;
894 uint16_t iflags, type;
895 uint32_t access_mask;
45d1cae3 896 boolean_t an_exec_denied = B_FALSE;
34dc7c2f 897
428870ff 898 mode = (fmode & (S_IFMT | S_ISUID | S_ISGID | S_ISVTX));
34dc7c2f 899
149e873a
BB
900 while ((acep = zfs_acl_next_ace(aclp, acep, &who,
901 &access_mask, &iflags, &type))) {
34dc7c2f 902
b128c09f 903 if (!zfs_acl_valid_ace_type(type, iflags))
34dc7c2f
BB
904 continue;
905
906 entry_type = (iflags & ACE_TYPE_FLAGS);
907
b128c09f
BB
908 /*
909 * Skip over owner@, group@ or everyone@ inherit only ACEs
910 */
911 if ((iflags & ACE_INHERIT_ONLY_ACE) &&
912 (entry_type == ACE_OWNER || entry_type == ACE_EVERYONE ||
913 entry_type == OWNING_GROUP))
914 continue;
915
428870ff
BB
916 if (entry_type == ACE_OWNER || (entry_type == 0 &&
917 who == fuid)) {
34dc7c2f
BB
918 if ((access_mask & ACE_READ_DATA) &&
919 (!(seen & S_IRUSR))) {
920 seen |= S_IRUSR;
921 if (type == ALLOW) {
922 mode |= S_IRUSR;
923 }
924 }
925 if ((access_mask & ACE_WRITE_DATA) &&
926 (!(seen & S_IWUSR))) {
927 seen |= S_IWUSR;
928 if (type == ALLOW) {
929 mode |= S_IWUSR;
930 }
931 }
932 if ((access_mask & ACE_EXECUTE) &&
933 (!(seen & S_IXUSR))) {
934 seen |= S_IXUSR;
935 if (type == ALLOW) {
936 mode |= S_IXUSR;
937 }
938 }
428870ff
BB
939 } else if (entry_type == OWNING_GROUP ||
940 (entry_type == ACE_IDENTIFIER_GROUP && who == fgid)) {
34dc7c2f
BB
941 if ((access_mask & ACE_READ_DATA) &&
942 (!(seen & S_IRGRP))) {
943 seen |= S_IRGRP;
944 if (type == ALLOW) {
945 mode |= S_IRGRP;
946 }
947 }
948 if ((access_mask & ACE_WRITE_DATA) &&
949 (!(seen & S_IWGRP))) {
950 seen |= S_IWGRP;
951 if (type == ALLOW) {
952 mode |= S_IWGRP;
953 }
954 }
955 if ((access_mask & ACE_EXECUTE) &&
956 (!(seen & S_IXGRP))) {
957 seen |= S_IXGRP;
958 if (type == ALLOW) {
959 mode |= S_IXGRP;
960 }
961 }
962 } else if (entry_type == ACE_EVERYONE) {
963 if ((access_mask & ACE_READ_DATA)) {
964 if (!(seen & S_IRUSR)) {
965 seen |= S_IRUSR;
966 if (type == ALLOW) {
967 mode |= S_IRUSR;
968 }
969 }
970 if (!(seen & S_IRGRP)) {
971 seen |= S_IRGRP;
972 if (type == ALLOW) {
973 mode |= S_IRGRP;
974 }
975 }
976 if (!(seen & S_IROTH)) {
977 seen |= S_IROTH;
978 if (type == ALLOW) {
979 mode |= S_IROTH;
980 }
981 }
982 }
983 if ((access_mask & ACE_WRITE_DATA)) {
984 if (!(seen & S_IWUSR)) {
985 seen |= S_IWUSR;
986 if (type == ALLOW) {
987 mode |= S_IWUSR;
988 }
989 }
990 if (!(seen & S_IWGRP)) {
991 seen |= S_IWGRP;
992 if (type == ALLOW) {
993 mode |= S_IWGRP;
994 }
995 }
996 if (!(seen & S_IWOTH)) {
997 seen |= S_IWOTH;
998 if (type == ALLOW) {
999 mode |= S_IWOTH;
1000 }
1001 }
1002 }
1003 if ((access_mask & ACE_EXECUTE)) {
1004 if (!(seen & S_IXUSR)) {
1005 seen |= S_IXUSR;
1006 if (type == ALLOW) {
1007 mode |= S_IXUSR;
1008 }
1009 }
1010 if (!(seen & S_IXGRP)) {
1011 seen |= S_IXGRP;
1012 if (type == ALLOW) {
1013 mode |= S_IXGRP;
1014 }
1015 }
1016 if (!(seen & S_IXOTH)) {
1017 seen |= S_IXOTH;
1018 if (type == ALLOW) {
1019 mode |= S_IXOTH;
1020 }
1021 }
1022 }
45d1cae3
BB
1023 } else {
1024 /*
1025 * Only care if this IDENTIFIER_GROUP or
1026 * USER ACE denies execute access to someone,
1027 * mode is not affected
1028 */
1029 if ((access_mask & ACE_EXECUTE) && type == DENY)
1030 an_exec_denied = B_TRUE;
34dc7c2f 1031 }
34dc7c2f 1032 }
45d1cae3
BB
1033
1034 /*
1035 * Failure to allow is effectively a deny, so execute permission
1036 * is denied if it was never mentioned or if we explicitly
1037 * weren't allowed it.
1038 */
1039 if (!an_exec_denied &&
1040 ((seen & ALL_MODE_EXECS) != ALL_MODE_EXECS ||
1041 (mode & ALL_MODE_EXECS) != ALL_MODE_EXECS))
1042 an_exec_denied = B_TRUE;
1043
1044 if (an_exec_denied)
428870ff 1045 *pflags &= ~ZFS_NO_EXECS_DENIED;
45d1cae3 1046 else
428870ff 1047 *pflags |= ZFS_NO_EXECS_DENIED;
45d1cae3 1048
34dc7c2f
BB
1049 return (mode);
1050}
1051
34dc7c2f 1052/*
45d1cae3
BB
1053 * Read an external acl object. If the intent is to modify, always
1054 * create a new acl and leave any cached acl in place.
34dc7c2f
BB
1055 */
1056static int
572e2857
BB
1057zfs_acl_node_read(znode_t *zp, boolean_t have_lock, zfs_acl_t **aclpp,
1058 boolean_t will_modify)
34dc7c2f 1059{
34dc7c2f 1060 zfs_acl_t *aclp;
ddc07fa5
CW
1061 int aclsize = 0;
1062 int acl_count = 0;
34dc7c2f 1063 zfs_acl_node_t *aclnode;
428870ff
BB
1064 zfs_acl_phys_t znode_acl;
1065 int version;
1066 int error;
572e2857 1067 boolean_t drop_lock = B_FALSE;
34dc7c2f
BB
1068
1069 ASSERT(MUTEX_HELD(&zp->z_acl_lock));
1070
45d1cae3
BB
1071 if (zp->z_acl_cached && !will_modify) {
1072 *aclpp = zp->z_acl_cached;
1073 return (0);
1074 }
1075
572e2857
BB
1076 /*
1077 * close race where znode could be upgrade while trying to
1078 * read the znode attributes.
1079 *
1080 * But this could only happen if the file isn't already an SA
1081 * znode
1082 */
1083 if (!zp->z_is_sa && !have_lock) {
1084 mutex_enter(&zp->z_lock);
1085 drop_lock = B_TRUE;
1086 }
1087 version = zfs_znode_acl_version(zp);
34dc7c2f 1088
428870ff 1089 if ((error = zfs_acl_znode_info(zp, &aclsize,
572e2857
BB
1090 &acl_count, &znode_acl)) != 0) {
1091 goto done;
1092 }
428870ff
BB
1093
1094 aclp = zfs_acl_alloc(version);
34dc7c2f 1095
34dc7c2f
BB
1096 aclp->z_acl_count = acl_count;
1097 aclp->z_acl_bytes = aclsize;
1098
428870ff
BB
1099 aclnode = zfs_acl_node_alloc(aclsize);
1100 aclnode->z_ace_count = aclp->z_acl_count;
1101 aclnode->z_size = aclsize;
1102
1103 if (!zp->z_is_sa) {
1104 if (znode_acl.z_acl_extern_obj) {
3558fd73 1105 error = dmu_read(ZTOZSB(zp)->z_os,
428870ff
BB
1106 znode_acl.z_acl_extern_obj, 0, aclnode->z_size,
1107 aclnode->z_acldata, DMU_READ_PREFETCH);
1108 } else {
1109 bcopy(znode_acl.z_ace_data, aclnode->z_acldata,
1110 aclnode->z_size);
1111 }
1112 } else {
3558fd73 1113 error = sa_lookup(zp->z_sa_hdl, SA_ZPL_DACL_ACES(ZTOZSB(zp)),
428870ff
BB
1114 aclnode->z_acldata, aclnode->z_size);
1115 }
1116
34dc7c2f
BB
1117 if (error != 0) {
1118 zfs_acl_free(aclp);
428870ff 1119 zfs_acl_node_free(aclnode);
b128c09f
BB
1120 /* convert checksum errors into IO errors */
1121 if (error == ECKSUM)
a08ee875 1122 error = SET_ERROR(EIO);
572e2857 1123 goto done;
34dc7c2f
BB
1124 }
1125
428870ff
BB
1126 list_insert_head(&aclp->z_acl, aclnode);
1127
34dc7c2f 1128 *aclpp = aclp;
45d1cae3
BB
1129 if (!will_modify)
1130 zp->z_acl_cached = aclp;
572e2857
BB
1131done:
1132 if (drop_lock)
1133 mutex_exit(&zp->z_lock);
1134 return (error);
34dc7c2f
BB
1135}
1136
428870ff
BB
1137/*ARGSUSED*/
1138void
1139zfs_acl_data_locator(void **dataptr, uint32_t *length, uint32_t buflen,
1140 boolean_t start, void *userdata)
1141{
1142 zfs_acl_locator_cb_t *cb = (zfs_acl_locator_cb_t *)userdata;
1143
1144 if (start) {
1145 cb->cb_acl_node = list_head(&cb->cb_aclp->z_acl);
1146 } else {
1147 cb->cb_acl_node = list_next(&cb->cb_aclp->z_acl,
1148 cb->cb_acl_node);
1149 }
1150 *dataptr = cb->cb_acl_node->z_acldata;
1151 *length = cb->cb_acl_node->z_size;
1152}
1153
428870ff
BB
1154int
1155zfs_acl_chown_setattr(znode_t *zp)
1156{
1157 int error;
1158 zfs_acl_t *aclp;
428870ff 1159
a08ee875
LG
1160 if (ZTOZSB(zp)->z_acl_type == ZFS_ACLTYPE_POSIXACL)
1161 return (0);
1162
572e2857
BB
1163 ASSERT(MUTEX_HELD(&zp->z_lock));
1164 ASSERT(MUTEX_HELD(&zp->z_acl_lock));
428870ff 1165
ea04106b
AX
1166 error = zfs_acl_node_read(zp, B_TRUE, &aclp, B_FALSE);
1167 if (error == 0 && aclp->z_acl_count > 0)
428870ff 1168 zp->z_mode = zfs_mode_compute(zp->z_mode, aclp,
572e2857 1169 &zp->z_pflags, zp->z_uid, zp->z_gid);
a08ee875
LG
1170
1171 /*
1172 * Some ZFS implementations (ZEVO) create neither a ZNODE_ACL
1173 * nor a DACL_ACES SA in which case ENOENT is returned from
1174 * zfs_acl_node_read() when the SA can't be located.
1175 * Allow chown/chgrp to succeed in these cases rather than
1176 * returning an error that makes no sense in the context of
1177 * the caller.
1178 */
1179 if (error == ENOENT)
1180 return (0);
1181
428870ff
BB
1182 return (error);
1183}
1184
538f669f
BB
1185static void
1186acl_trivial_access_masks(mode_t mode, uint32_t *allow0, uint32_t *deny1,
1187 uint32_t *deny2, uint32_t *owner, uint32_t *group, uint32_t *everyone)
1188{
1189 *deny1 = *deny2 = *allow0 = *group = 0;
1190
1191 if (!(mode & S_IRUSR) && (mode & (S_IRGRP|S_IROTH)))
1192 *deny1 |= ACE_READ_DATA;
1193 if (!(mode & S_IWUSR) && (mode & (S_IWGRP|S_IWOTH)))
1194 *deny1 |= ACE_WRITE_DATA;
1195 if (!(mode & S_IXUSR) && (mode & (S_IXGRP|S_IXOTH)))
1196 *deny1 |= ACE_EXECUTE;
1197
1198 if (!(mode & S_IRGRP) && (mode & S_IROTH))
1199 *deny2 = ACE_READ_DATA;
1200 if (!(mode & S_IWGRP) && (mode & S_IWOTH))
1201 *deny2 |= ACE_WRITE_DATA;
1202 if (!(mode & S_IXGRP) && (mode & S_IXOTH))
1203 *deny2 |= ACE_EXECUTE;
1204
1205 if ((mode & S_IRUSR) && (!(mode & S_IRGRP) && (mode & S_IROTH)))
1206 *allow0 |= ACE_READ_DATA;
1207 if ((mode & S_IWUSR) && (!(mode & S_IWGRP) && (mode & S_IWOTH)))
1208 *allow0 |= ACE_WRITE_DATA;
1209 if ((mode & S_IXUSR) && (!(mode & S_IXGRP) && (mode & S_IXOTH)))
1210 *allow0 |= ACE_EXECUTE;
1211
1212 *owner = ACE_WRITE_ATTRIBUTES|ACE_WRITE_OWNER|ACE_WRITE_ACL|
1213 ACE_WRITE_NAMED_ATTRS|ACE_READ_ACL|ACE_READ_ATTRIBUTES|
1214 ACE_READ_NAMED_ATTRS|ACE_SYNCHRONIZE;
1215 if (mode & S_IRUSR)
1216 *owner |= ACE_READ_DATA;
1217 if (mode & S_IWUSR)
1218 *owner |= ACE_WRITE_DATA|ACE_APPEND_DATA;
1219 if (mode & S_IXUSR)
1220 *owner |= ACE_EXECUTE;
1221
1222 *group = ACE_READ_ACL|ACE_READ_ATTRIBUTES| ACE_READ_NAMED_ATTRS|
1223 ACE_SYNCHRONIZE;
1224 if (mode & S_IRGRP)
1225 *group |= ACE_READ_DATA;
1226 if (mode & S_IWGRP)
1227 *group |= ACE_WRITE_DATA|ACE_APPEND_DATA;
1228 if (mode & S_IXGRP)
1229 *group |= ACE_EXECUTE;
1230
1231 *everyone = ACE_READ_ACL|ACE_READ_ATTRIBUTES| ACE_READ_NAMED_ATTRS|
1232 ACE_SYNCHRONIZE;
1233 if (mode & S_IROTH)
1234 *everyone |= ACE_READ_DATA;
1235 if (mode & S_IWOTH)
1236 *everyone |= ACE_WRITE_DATA|ACE_APPEND_DATA;
1237 if (mode & S_IXOTH)
1238 *everyone |= ACE_EXECUTE;
1239}
1240
1241/*
1242 * ace_trivial:
1243 * determine whether an ace_t acl is trivial
1244 *
1245 * Trivialness implies that the acl is composed of only
1246 * owner, group, everyone entries. ACL can't
1247 * have read_acl denied, and write_owner/write_acl/write_attributes
1248 * can only be owner@ entry.
1249 */
1250static int
1251ace_trivial_common(void *acep, int aclcnt,
1252 uint64_t (*walk)(void *, uint64_t, int aclcnt,
1253 uint16_t *, uint16_t *, uint32_t *))
1254{
1255 uint16_t flags;
1256 uint32_t mask;
1257 uint16_t type;
1258 uint64_t cookie = 0;
1259
1260 while ((cookie = walk(acep, cookie, aclcnt, &flags, &type, &mask))) {
1261 switch (flags & ACE_TYPE_FLAGS) {
1262 case ACE_OWNER:
1263 case ACE_GROUP|ACE_IDENTIFIER_GROUP:
1264 case ACE_EVERYONE:
1265 break;
1266 default:
1267 return (1);
1268 }
1269
1270 if (flags & (ACE_FILE_INHERIT_ACE|
1271 ACE_DIRECTORY_INHERIT_ACE|ACE_NO_PROPAGATE_INHERIT_ACE|
1272 ACE_INHERIT_ONLY_ACE))
1273 return (1);
1274
1275 /*
1276 * Special check for some special bits
1277 *
1278 * Don't allow anybody to deny reading basic
1279 * attributes or a files ACL.
1280 */
1281 if ((mask & (ACE_READ_ACL|ACE_READ_ATTRIBUTES)) &&
1282 (type == ACE_ACCESS_DENIED_ACE_TYPE))
1283 return (1);
1284
1285 /*
1286 * Delete permissions are never set by default
1287 */
1288 if (mask & (ACE_DELETE|ACE_DELETE_CHILD))
1289 return (1);
1290 /*
1291 * only allow owner@ to have
1292 * write_acl/write_owner/write_attributes/write_xattr/
1293 */
1294 if (type == ACE_ACCESS_ALLOWED_ACE_TYPE &&
1295 (!(flags & ACE_OWNER) && (mask &
1296 (ACE_WRITE_OWNER|ACE_WRITE_ACL| ACE_WRITE_ATTRIBUTES|
1297 ACE_WRITE_NAMED_ATTRS))))
1298 return (1);
1299
1300 }
1301
1302 return (0);
1303}
1304
34dc7c2f
BB
1305/*
1306 * common code for setting ACLs.
1307 *
1308 * This function is called from zfs_mode_update, zfs_perm_init, and zfs_setacl.
1309 * zfs_setacl passes a non-NULL inherit pointer (ihp) to indicate that it's
1310 * already checked the acl and knows whether to inherit.
1311 */
1312int
9babb374 1313zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx)
34dc7c2f 1314{
428870ff 1315 int error;
3558fd73 1316 zfs_sb_t *zsb = ZTOZSB(zp);
428870ff
BB
1317 dmu_object_type_t otype;
1318 zfs_acl_locator_cb_t locate = { 0 };
1319 uint64_t mode;
1320 sa_bulk_attr_t bulk[5];
1321 uint64_t ctime[2];
1322 int count = 0;
428870ff
BB
1323
1324 mode = zp->z_mode;
1325
572e2857
BB
1326 mode = zfs_mode_compute(mode, aclp, &zp->z_pflags,
1327 zp->z_uid, zp->z_gid);
34dc7c2f 1328
428870ff 1329 zp->z_mode = mode;
3558fd73 1330 SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zsb), NULL,
428870ff 1331 &mode, sizeof (mode));
3558fd73 1332 SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zsb), NULL,
428870ff 1333 &zp->z_pflags, sizeof (zp->z_pflags));
3558fd73 1334 SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb), NULL,
428870ff 1335 &ctime, sizeof (ctime));
34dc7c2f 1336
45d1cae3
BB
1337 if (zp->z_acl_cached) {
1338 zfs_acl_free(zp->z_acl_cached);
1339 zp->z_acl_cached = NULL;
1340 }
1341
34dc7c2f 1342 /*
428870ff 1343 * Upgrade needed?
34dc7c2f 1344 */
3558fd73 1345 if (!zsb->z_use_fuids) {
34dc7c2f
BB
1346 otype = DMU_OT_OLDACL;
1347 } else {
1348 if ((aclp->z_version == ZFS_ACL_VERSION_INITIAL) &&
3558fd73 1349 (zsb->z_version >= ZPL_VERSION_FUID))
9babb374 1350 zfs_acl_xform(zp, aclp, cr);
34dc7c2f
BB
1351 ASSERT(aclp->z_version >= ZFS_ACL_VERSION_FUID);
1352 otype = DMU_OT_ACL;
1353 }
1354
428870ff
BB
1355 /*
1356 * Arrgh, we have to handle old on disk format
1357 * as well as newer (preferred) SA format.
1358 */
1359
1360 if (zp->z_is_sa) { /* the easy case, just update the ACL attribute */
1361 locate.cb_aclp = aclp;
3558fd73 1362 SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_DACL_ACES(zsb),
428870ff 1363 zfs_acl_data_locator, &locate, aclp->z_acl_bytes);
3558fd73 1364 SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_DACL_COUNT(zsb),
428870ff
BB
1365 NULL, &aclp->z_acl_count, sizeof (uint64_t));
1366 } else { /* Painful legacy way */
1367 zfs_acl_node_t *aclnode;
1368 uint64_t off = 0;
1369 zfs_acl_phys_t acl_phys;
1370 uint64_t aoid;
1371
3558fd73 1372 if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_ZNODE_ACL(zsb),
428870ff
BB
1373 &acl_phys, sizeof (acl_phys))) != 0)
1374 return (error);
1375
1376 aoid = acl_phys.z_acl_extern_obj;
1377
1378 if (aclp->z_acl_bytes > ZFS_ACE_SPACE) {
1379 /*
1380 * If ACL was previously external and we are now
1381 * converting to new ACL format then release old
1382 * ACL object and create a new one.
1383 */
1384 if (aoid &&
1385 aclp->z_version != acl_phys.z_acl_version) {
3558fd73 1386 error = dmu_object_free(zsb->z_os, aoid, tx);
428870ff
BB
1387 if (error)
1388 return (error);
1389 aoid = 0;
1390 }
1391 if (aoid == 0) {
3558fd73 1392 aoid = dmu_object_alloc(zsb->z_os,
428870ff
BB
1393 otype, aclp->z_acl_bytes,
1394 otype == DMU_OT_ACL ?
1395 DMU_OT_SYSACL : DMU_OT_NONE,
1396 otype == DMU_OT_ACL ?
1397 DN_MAX_BONUSLEN : 0, tx);
1398 } else {
3558fd73 1399 (void) dmu_object_set_blocksize(zsb->z_os,
428870ff
BB
1400 aoid, aclp->z_acl_bytes, 0, tx);
1401 }
1402 acl_phys.z_acl_extern_obj = aoid;
1403 for (aclnode = list_head(&aclp->z_acl); aclnode;
1404 aclnode = list_next(&aclp->z_acl, aclnode)) {
1405 if (aclnode->z_ace_count == 0)
1406 continue;
3558fd73 1407 dmu_write(zsb->z_os, aoid, off,
428870ff
BB
1408 aclnode->z_size, aclnode->z_acldata, tx);
1409 off += aclnode->z_size;
1410 }
34dc7c2f 1411 } else {
428870ff
BB
1412 void *start = acl_phys.z_ace_data;
1413 /*
1414 * Migrating back embedded?
1415 */
1416 if (acl_phys.z_acl_extern_obj) {
3558fd73 1417 error = dmu_object_free(zsb->z_os,
428870ff
BB
1418 acl_phys.z_acl_extern_obj, tx);
1419 if (error)
1420 return (error);
1421 acl_phys.z_acl_extern_obj = 0;
1422 }
1423
1424 for (aclnode = list_head(&aclp->z_acl); aclnode;
1425 aclnode = list_next(&aclp->z_acl, aclnode)) {
1426 if (aclnode->z_ace_count == 0)
1427 continue;
1428 bcopy(aclnode->z_acldata, start,
1429 aclnode->z_size);
1430 start = (caddr_t)start + aclnode->z_size;
1431 }
34dc7c2f 1432 }
34dc7c2f 1433 /*
428870ff
BB
1434 * If Old version then swap count/bytes to match old
1435 * layout of znode_acl_phys_t.
34dc7c2f 1436 */
428870ff
BB
1437 if (aclp->z_version == ZFS_ACL_VERSION_INITIAL) {
1438 acl_phys.z_acl_size = aclp->z_acl_count;
1439 acl_phys.z_acl_count = aclp->z_acl_bytes;
1440 } else {
1441 acl_phys.z_acl_size = aclp->z_acl_bytes;
1442 acl_phys.z_acl_count = aclp->z_acl_count;
34dc7c2f 1443 }
428870ff 1444 acl_phys.z_acl_version = aclp->z_version;
34dc7c2f 1445
3558fd73 1446 SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ZNODE_ACL(zsb), NULL,
428870ff 1447 &acl_phys, sizeof (acl_phys));
34dc7c2f
BB
1448 }
1449
34dc7c2f
BB
1450 /*
1451 * Replace ACL wide bits, but first clear them.
1452 */
428870ff 1453 zp->z_pflags &= ~ZFS_ACL_WIDE_FLAGS;
34dc7c2f 1454
428870ff 1455 zp->z_pflags |= aclp->z_hints;
34dc7c2f
BB
1456
1457 if (ace_trivial_common(aclp, 0, zfs_ace_walk) == 0)
428870ff 1458 zp->z_pflags |= ZFS_ACL_TRIVIAL;
34dc7c2f 1459
428870ff
BB
1460 zfs_tstamp_update_setup(zp, STATE_CHANGED, NULL, ctime, B_TRUE);
1461 return (sa_bulk_update(zp->z_sa_hdl, bulk, count, tx));
34dc7c2f
BB
1462}
1463
34dc7c2f 1464static void
3558fd73 1465zfs_acl_chmod(zfs_sb_t *zsb, uint64_t mode, zfs_acl_t *aclp)
34dc7c2f 1466{
428870ff 1467 void *acep = NULL;
34dc7c2f 1468 uint64_t who;
428870ff
BB
1469 int new_count, new_bytes;
1470 int ace_size;
3558fd73 1471 int entry_type;
34dc7c2f
BB
1472 uint16_t iflags, type;
1473 uint32_t access_mask;
428870ff 1474 zfs_acl_node_t *newnode;
0a6b03d3 1475 size_t abstract_size = aclp->z_ops->ace_abstract_size();
3558fd73
BB
1476 void *zacep;
1477 uint32_t owner, group, everyone;
428870ff
BB
1478 uint32_t deny1, deny2, allow0;
1479
1480 new_count = new_bytes = 0;
1481
1482 acl_trivial_access_masks((mode_t)mode, &allow0, &deny1, &deny2,
1483 &owner, &group, &everyone);
1484
1485 newnode = zfs_acl_node_alloc((abstract_size * 6) + aclp->z_acl_bytes);
1486
1487 zacep = newnode->z_acldata;
1488 if (allow0) {
1489 zfs_set_ace(aclp, zacep, allow0, ALLOW, -1, ACE_OWNER);
1490 zacep = (void *)((uintptr_t)zacep + abstract_size);
1491 new_count++;
1492 new_bytes += abstract_size;
a08ee875
LG
1493 }
1494 if (deny1) {
428870ff
BB
1495 zfs_set_ace(aclp, zacep, deny1, DENY, -1, ACE_OWNER);
1496 zacep = (void *)((uintptr_t)zacep + abstract_size);
1497 new_count++;
1498 new_bytes += abstract_size;
1499 }
1500 if (deny2) {
1501 zfs_set_ace(aclp, zacep, deny2, DENY, -1, OWNING_GROUP);
1502 zacep = (void *)((uintptr_t)zacep + abstract_size);
1503 new_count++;
1504 new_bytes += abstract_size;
1505 }
34dc7c2f 1506
149e873a
BB
1507 while ((acep = zfs_acl_next_ace(aclp, acep, &who, &access_mask,
1508 &iflags, &type))) {
428870ff 1509 uint16_t inherit_flags;
34dc7c2f
BB
1510
1511 entry_type = (iflags & ACE_TYPE_FLAGS);
428870ff
BB
1512 inherit_flags = (iflags & ALL_INHERIT);
1513
1514 if ((entry_type == ACE_OWNER || entry_type == ACE_EVERYONE ||
1515 (entry_type == OWNING_GROUP)) &&
1516 ((inherit_flags & ACE_INHERIT_ONLY_ACE) == 0)) {
1517 continue;
1518 }
34dc7c2f
BB
1519
1520 if ((type != ALLOW && type != DENY) ||
428870ff
BB
1521 (inherit_flags & ACE_INHERIT_ONLY_ACE)) {
1522 if (inherit_flags)
34dc7c2f
BB
1523 aclp->z_hints |= ZFS_INHERIT_ACE;
1524 switch (type) {
1525 case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE:
1526 case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE:
1527 case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE:
1528 case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE:
1529 aclp->z_hints |= ZFS_ACL_OBJ_ACE;
1530 break;
1531 }
34dc7c2f 1532 } else {
34dc7c2f 1533
428870ff
BB
1534 /*
1535 * Limit permissions to be no greater than
1536 * group permissions
1537 */
3558fd73 1538 if (zsb->z_acl_inherit == ZFS_ACL_RESTRICTED) {
428870ff
BB
1539 if (!(mode & S_IRGRP))
1540 access_mask &= ~ACE_READ_DATA;
1541 if (!(mode & S_IWGRP))
1542 access_mask &=
1543 ~(ACE_WRITE_DATA|ACE_APPEND_DATA);
1544 if (!(mode & S_IXGRP))
1545 access_mask &= ~ACE_EXECUTE;
1546 access_mask &=
1547 ~(ACE_WRITE_OWNER|ACE_WRITE_ACL|
1548 ACE_WRITE_ATTRIBUTES|ACE_WRITE_NAMED_ATTRS);
1549 }
34dc7c2f 1550 }
428870ff 1551 zfs_set_ace(aclp, zacep, access_mask, type, who, iflags);
0a6b03d3 1552 ace_size = aclp->z_ops->ace_size(acep);
428870ff
BB
1553 zacep = (void *)((uintptr_t)zacep + ace_size);
1554 new_count++;
1555 new_bytes += ace_size;
1556 }
1557 zfs_set_ace(aclp, zacep, owner, 0, -1, ACE_OWNER);
1558 zacep = (void *)((uintptr_t)zacep + abstract_size);
1559 zfs_set_ace(aclp, zacep, group, 0, -1, OWNING_GROUP);
1560 zacep = (void *)((uintptr_t)zacep + abstract_size);
1561 zfs_set_ace(aclp, zacep, everyone, 0, -1, ACE_EVERYONE);
1562
1563 new_count += 3;
1564 new_bytes += abstract_size * 3;
1565 zfs_acl_release_nodes(aclp);
1566 aclp->z_acl_count = new_count;
1567 aclp->z_acl_bytes = new_bytes;
1568 newnode->z_ace_count = new_count;
1569 newnode->z_size = new_bytes;
1570 list_insert_tail(&aclp->z_acl, newnode);
34dc7c2f
BB
1571}
1572
572e2857 1573void
34dc7c2f
BB
1574zfs_acl_chmod_setattr(znode_t *zp, zfs_acl_t **aclp, uint64_t mode)
1575{
34dc7c2f 1576 mutex_enter(&zp->z_acl_lock);
572e2857 1577 mutex_enter(&zp->z_lock);
428870ff
BB
1578 *aclp = zfs_acl_alloc(zfs_acl_version_zp(zp));
1579 (*aclp)->z_hints = zp->z_pflags & V4_ACL_WIDE_FLAGS;
3558fd73 1580 zfs_acl_chmod(ZTOZSB(zp), mode, *aclp);
34dc7c2f 1581 mutex_exit(&zp->z_lock);
572e2857 1582 mutex_exit(&zp->z_acl_lock);
428870ff 1583 ASSERT(*aclp);
34dc7c2f
BB
1584}
1585
1586/*
1587 * strip off write_owner and write_acl
1588 */
1589static void
3558fd73 1590zfs_restricted_update(zfs_sb_t *zsb, zfs_acl_t *aclp, void *acep)
34dc7c2f 1591{
0a6b03d3 1592 uint32_t mask = aclp->z_ops->ace_mask_get(acep);
34dc7c2f 1593
3558fd73 1594 if ((zsb->z_acl_inherit == ZFS_ACL_RESTRICTED) &&
0a6b03d3 1595 (aclp->z_ops->ace_type_get(acep) == ALLOW)) {
34dc7c2f 1596 mask &= ~RESTRICTED_CLEAR;
0a6b03d3 1597 aclp->z_ops->ace_mask_set(acep, mask);
34dc7c2f
BB
1598 }
1599}
1600
1601/*
1602 * Should ACE be inherited?
1603 */
1604static int
3558fd73 1605zfs_ace_can_use(umode_t obj_mode, uint16_t acep_flags)
34dc7c2f 1606{
34dc7c2f
BB
1607 int iflags = (acep_flags & 0xf);
1608
3558fd73 1609 if (S_ISDIR(obj_mode) && (iflags & ACE_DIRECTORY_INHERIT_ACE))
34dc7c2f
BB
1610 return (1);
1611 else if (iflags & ACE_FILE_INHERIT_ACE)
3558fd73 1612 return (!(S_ISDIR(obj_mode) &&
34dc7c2f
BB
1613 (iflags & ACE_NO_PROPAGATE_INHERIT_ACE)));
1614 return (0);
1615}
1616
1617/*
1618 * inherit inheritable ACEs from parent
1619 */
1620static zfs_acl_t *
3558fd73 1621zfs_acl_inherit(zfs_sb_t *zsb, umode_t obj_mode, zfs_acl_t *paclp,
9babb374 1622 uint64_t mode, boolean_t *need_chmod)
34dc7c2f 1623{
34dc7c2f 1624 void *pacep;
428870ff
BB
1625 void *acep;
1626 zfs_acl_node_t *aclnode;
34dc7c2f
BB
1627 zfs_acl_t *aclp = NULL;
1628 uint64_t who;
1629 uint32_t access_mask;
1630 uint16_t iflags, newflags, type;
1631 size_t ace_size;
1632 void *data1, *data2;
1633 size_t data1sz, data2sz;
3558fd73
BB
1634 boolean_t vdir = S_ISDIR(obj_mode);
1635 boolean_t vreg = S_ISREG(obj_mode);
b128c09f
BB
1636 boolean_t passthrough, passthrough_x, noallow;
1637
1638 passthrough_x =
3558fd73 1639 zsb->z_acl_inherit == ZFS_ACL_PASSTHROUGH_X;
b128c09f 1640 passthrough = passthrough_x ||
3558fd73 1641 zsb->z_acl_inherit == ZFS_ACL_PASSTHROUGH;
b128c09f 1642 noallow =
3558fd73 1643 zsb->z_acl_inherit == ZFS_ACL_NOALLOW;
34dc7c2f
BB
1644
1645 *need_chmod = B_TRUE;
1646 pacep = NULL;
b128c09f 1647 aclp = zfs_acl_alloc(paclp->z_version);
3558fd73 1648 if (zsb->z_acl_inherit == ZFS_ACL_DISCARD || S_ISLNK(obj_mode))
b128c09f 1649 return (aclp);
149e873a
BB
1650 while ((pacep = zfs_acl_next_ace(paclp, pacep, &who,
1651 &access_mask, &iflags, &type))) {
34dc7c2f 1652
b128c09f
BB
1653 /*
1654 * don't inherit bogus ACEs
1655 */
1656 if (!zfs_acl_valid_ace_type(type, iflags))
1657 continue;
34dc7c2f 1658
b128c09f
BB
1659 if (noallow && type == ALLOW)
1660 continue;
34dc7c2f 1661
0a6b03d3 1662 ace_size = aclp->z_ops->ace_size(pacep);
34dc7c2f 1663
3558fd73 1664 if (!zfs_ace_can_use(obj_mode, iflags))
b128c09f
BB
1665 continue;
1666
1667 /*
1668 * If owner@, group@, or everyone@ inheritable
1669 * then zfs_acl_chmod() isn't needed.
1670 */
1671 if (passthrough &&
1672 ((iflags & (ACE_OWNER|ACE_EVERYONE)) ||
1673 ((iflags & OWNING_GROUP) ==
1674 OWNING_GROUP)) && (vreg || (vdir && (iflags &
1675 ACE_DIRECTORY_INHERIT_ACE)))) {
1676 *need_chmod = B_FALSE;
428870ff 1677 }
b128c09f 1678
428870ff
BB
1679 if (!vdir && passthrough_x &&
1680 ((mode & (S_IXUSR | S_IXGRP | S_IXOTH)) == 0)) {
1681 access_mask &= ~ACE_EXECUTE;
b128c09f
BB
1682 }
1683
1684 aclnode = zfs_acl_node_alloc(ace_size);
1685 list_insert_tail(&aclp->z_acl, aclnode);
1686 acep = aclnode->z_acldata;
1687
1688 zfs_set_ace(aclp, acep, access_mask, type,
1689 who, iflags|ACE_INHERITED_ACE);
1690
1691 /*
1692 * Copy special opaque data if any
1693 */
0a6b03d3
RY
1694 if ((data1sz = paclp->z_ops->ace_data(pacep, &data1)) != 0) {
1695 VERIFY((data2sz = aclp->z_ops->ace_data(acep,
b128c09f
BB
1696 &data2)) == data1sz);
1697 bcopy(data1, data2, data2sz);
1698 }
428870ff 1699
b128c09f
BB
1700 aclp->z_acl_count++;
1701 aclnode->z_ace_count++;
1702 aclp->z_acl_bytes += aclnode->z_size;
0a6b03d3 1703 newflags = aclp->z_ops->ace_flags_get(acep);
b128c09f
BB
1704
1705 if (vdir)
1706 aclp->z_hints |= ZFS_INHERIT_ACE;
1707
1708 if ((iflags & ACE_NO_PROPAGATE_INHERIT_ACE) || !vdir) {
1709 newflags &= ~ALL_INHERIT;
0a6b03d3 1710 aclp->z_ops->ace_flags_set(acep,
b128c09f 1711 newflags|ACE_INHERITED_ACE);
3558fd73 1712 zfs_restricted_update(zsb, aclp, acep);
b128c09f
BB
1713 continue;
1714 }
1715
1716 ASSERT(vdir);
1717
428870ff
BB
1718 /*
1719 * If only FILE_INHERIT is set then turn on
1720 * inherit_only
1721 */
b128c09f 1722 if ((iflags & (ACE_FILE_INHERIT_ACE |
428870ff 1723 ACE_DIRECTORY_INHERIT_ACE)) == ACE_FILE_INHERIT_ACE) {
b128c09f 1724 newflags |= ACE_INHERIT_ONLY_ACE;
0a6b03d3 1725 aclp->z_ops->ace_flags_set(acep,
b128c09f 1726 newflags|ACE_INHERITED_ACE);
b128c09f 1727 } else {
428870ff 1728 newflags &= ~ACE_INHERIT_ONLY_ACE;
0a6b03d3 1729 aclp->z_ops->ace_flags_set(acep,
b128c09f 1730 newflags|ACE_INHERITED_ACE);
34dc7c2f
BB
1731 }
1732 }
1733 return (aclp);
1734}
1735
1736/*
1737 * Create file system object initial permissions
1738 * including inheritable ACEs.
1739 */
9babb374
BB
1740int
1741zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr,
1742 vsecattr_t *vsecp, zfs_acl_ids_t *acl_ids)
34dc7c2f 1743{
34dc7c2f 1744 int error;
3558fd73 1745 zfs_sb_t *zsb = ZTOZSB(dzp);
34dc7c2f 1746 zfs_acl_t *paclp;
a405c8a6 1747#ifdef HAVE_KSID
34dc7c2f 1748 gid_t gid;
a405c8a6 1749#endif /* HAVE_KSID */
34dc7c2f 1750 boolean_t need_chmod = B_TRUE;
428870ff 1751 boolean_t inherited = B_FALSE;
34dc7c2f 1752
9babb374 1753 bzero(acl_ids, sizeof (zfs_acl_ids_t));
3558fd73 1754 acl_ids->z_mode = vap->va_mode;
34dc7c2f 1755
9babb374 1756 if (vsecp)
3558fd73
BB
1757 if ((error = zfs_vsec_2_aclp(zsb, vap->va_mode, vsecp,
1758 cr, &acl_ids->z_fuidp, &acl_ids->z_aclp)) != 0)
9babb374 1759 return (error);
a405c8a6
BB
1760
1761 acl_ids->z_fuid = vap->va_uid;
1762 acl_ids->z_fgid = vap->va_gid;
1763#ifdef HAVE_KSID
34dc7c2f
BB
1764 /*
1765 * Determine uid and gid.
1766 */
3558fd73
BB
1767 if ((flag & IS_ROOT_NODE) || zsb->z_replay ||
1768 ((flag & IS_XATTR) && (S_ISDIR(vap->va_mode)))) {
1769 acl_ids->z_fuid = zfs_fuid_create(zsb, (uint64_t)vap->va_uid,
1770 cr, ZFS_OWNER, &acl_ids->z_fuidp);
1771 acl_ids->z_fgid = zfs_fuid_create(zsb, (uint64_t)vap->va_gid,
1772 cr, ZFS_GROUP, &acl_ids->z_fuidp);
34dc7c2f
BB
1773 gid = vap->va_gid;
1774 } else {
3558fd73 1775 acl_ids->z_fuid = zfs_fuid_create_cred(zsb, ZFS_OWNER,
9babb374
BB
1776 cr, &acl_ids->z_fuidp);
1777 acl_ids->z_fgid = 0;
34dc7c2f 1778 if (vap->va_mask & AT_GID) {
3558fd73 1779 acl_ids->z_fgid = zfs_fuid_create(zsb,
9babb374
BB
1780 (uint64_t)vap->va_gid,
1781 cr, ZFS_GROUP, &acl_ids->z_fuidp);
34dc7c2f 1782 gid = vap->va_gid;
572e2857 1783 if (acl_ids->z_fgid != dzp->z_gid &&
34dc7c2f
BB
1784 !groupmember(vap->va_gid, cr) &&
1785 secpolicy_vnode_create_gid(cr) != 0)
9babb374 1786 acl_ids->z_fgid = 0;
34dc7c2f 1787 }
9babb374 1788 if (acl_ids->z_fgid == 0) {
428870ff
BB
1789 if (dzp->z_mode & S_ISGID) {
1790 char *domain;
1791 uint32_t rid;
1792
572e2857 1793 acl_ids->z_fgid = dzp->z_gid;
3558fd73 1794 gid = zfs_fuid_map_id(zsb, acl_ids->z_fgid,
34dc7c2f 1795 cr, ZFS_GROUP);
428870ff 1796
3558fd73 1797 if (zsb->z_use_fuids &&
428870ff
BB
1798 IS_EPHEMERAL(acl_ids->z_fgid)) {
1799 domain = zfs_fuid_idx_domain(
3558fd73 1800 &zsb->z_fuid_idx,
428870ff
BB
1801 FUID_INDEX(acl_ids->z_fgid));
1802 rid = FUID_RID(acl_ids->z_fgid);
1803 zfs_fuid_node_add(&acl_ids->z_fuidp,
1804 domain, rid,
1805 FUID_INDEX(acl_ids->z_fgid),
1806 acl_ids->z_fgid, ZFS_GROUP);
1807 }
34dc7c2f 1808 } else {
3558fd73 1809 acl_ids->z_fgid = zfs_fuid_create_cred(zsb,
9babb374 1810 ZFS_GROUP, cr, &acl_ids->z_fuidp);
34dc7c2f
BB
1811 gid = crgetgid(cr);
1812 }
1813 }
1814 }
a405c8a6 1815#endif /* HAVE_KSID */
34dc7c2f
BB
1816
1817 /*
1818 * If we're creating a directory, and the parent directory has the
1819 * set-GID bit set, set in on the new directory.
1820 * Otherwise, if the user is neither privileged nor a member of the
1821 * file's new group, clear the file's set-GID bit.
1822 */
1823
428870ff 1824 if (!(flag & IS_ROOT_NODE) && (dzp->z_mode & S_ISGID) &&
3558fd73 1825 (S_ISDIR(vap->va_mode))) {
9babb374 1826 acl_ids->z_mode |= S_ISGID;
34dc7c2f 1827 } else {
9babb374 1828 if ((acl_ids->z_mode & S_ISGID) &&
34dc7c2f 1829 secpolicy_vnode_setids_setgids(cr, gid) != 0)
9babb374 1830 acl_ids->z_mode &= ~S_ISGID;
34dc7c2f
BB
1831 }
1832
9babb374 1833 if (acl_ids->z_aclp == NULL) {
572e2857 1834 mutex_enter(&dzp->z_acl_lock);
9babb374 1835 mutex_enter(&dzp->z_lock);
3558fd73 1836 if (!(flag & IS_ROOT_NODE) && (S_ISDIR(ZTOI(dzp)->i_mode) &&
428870ff
BB
1837 (dzp->z_pflags & ZFS_INHERIT_ACE)) &&
1838 !(dzp->z_pflags & ZFS_XATTR)) {
572e2857
BB
1839 VERIFY(0 == zfs_acl_node_read(dzp, B_TRUE,
1840 &paclp, B_FALSE));
3558fd73
BB
1841 acl_ids->z_aclp = zfs_acl_inherit(zsb,
1842 vap->va_mode, paclp, acl_ids->z_mode, &need_chmod);
428870ff 1843 inherited = B_TRUE;
34dc7c2f 1844 } else {
9babb374
BB
1845 acl_ids->z_aclp =
1846 zfs_acl_alloc(zfs_acl_version_zp(dzp));
428870ff 1847 acl_ids->z_aclp->z_hints |= ZFS_ACL_TRIVIAL;
9babb374
BB
1848 }
1849 mutex_exit(&dzp->z_lock);
572e2857 1850 mutex_exit(&dzp->z_acl_lock);
9babb374 1851 if (need_chmod) {
3558fd73 1852 acl_ids->z_aclp->z_hints |= S_ISDIR(vap->va_mode) ?
9babb374 1853 ZFS_ACL_AUTO_INHERIT : 0;
3558fd73 1854 zfs_acl_chmod(zsb, acl_ids->z_mode, acl_ids->z_aclp);
34dc7c2f 1855 }
34dc7c2f
BB
1856 }
1857
428870ff
BB
1858 if (inherited || vsecp) {
1859 acl_ids->z_mode = zfs_mode_compute(acl_ids->z_mode,
1860 acl_ids->z_aclp, &acl_ids->z_aclp->z_hints,
1861 acl_ids->z_fuid, acl_ids->z_fgid);
1862 if (ace_trivial_common(acl_ids->z_aclp, 0, zfs_ace_walk) == 0)
1863 acl_ids->z_aclp->z_hints |= ZFS_ACL_TRIVIAL;
1864 }
1865
9babb374
BB
1866 return (0);
1867}
34dc7c2f 1868
9babb374
BB
1869/*
1870 * Free ACL and fuid_infop, but not the acl_ids structure
1871 */
1872void
1873zfs_acl_ids_free(zfs_acl_ids_t *acl_ids)
1874{
1875 if (acl_ids->z_aclp)
1876 zfs_acl_free(acl_ids->z_aclp);
1877 if (acl_ids->z_fuidp)
1878 zfs_fuid_info_free(acl_ids->z_fuidp);
1879 acl_ids->z_aclp = NULL;
1880 acl_ids->z_fuidp = NULL;
1881}
34dc7c2f 1882
9babb374 1883boolean_t
3558fd73 1884zfs_acl_ids_overquota(zfs_sb_t *zsb, zfs_acl_ids_t *acl_ids)
9babb374 1885{
3558fd73
BB
1886 return (zfs_fuid_overquota(zsb, B_FALSE, acl_ids->z_fuid) ||
1887 zfs_fuid_overquota(zsb, B_TRUE, acl_ids->z_fgid));
34dc7c2f
BB
1888}
1889
1890/*
a08ee875 1891 * Retrieve a file's ACL
34dc7c2f
BB
1892 */
1893int
1894zfs_getacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr)
1895{
1896 zfs_acl_t *aclp;
1897 ulong_t mask;
1898 int error;
1899 int count = 0;
1900 int largeace = 0;
1901
1902 mask = vsecp->vsa_mask & (VSA_ACE | VSA_ACECNT |
1903 VSA_ACE_ACLFLAGS | VSA_ACE_ALLTYPES);
1904
34dc7c2f 1905 if (mask == 0)
a08ee875 1906 return (SET_ERROR(ENOSYS));
34dc7c2f 1907
149e873a 1908 if ((error = zfs_zaccess(zp, ACE_READ_ACL, 0, skipaclchk, cr)))
428870ff
BB
1909 return (error);
1910
34dc7c2f
BB
1911 mutex_enter(&zp->z_acl_lock);
1912
572e2857 1913 error = zfs_acl_node_read(zp, B_FALSE, &aclp, B_FALSE);
34dc7c2f
BB
1914 if (error != 0) {
1915 mutex_exit(&zp->z_acl_lock);
1916 return (error);
1917 }
1918
1919 /*
1920 * Scan ACL to determine number of ACEs
1921 */
428870ff 1922 if ((zp->z_pflags & ZFS_ACL_OBJ_ACE) && !(mask & VSA_ACE_ALLTYPES)) {
34dc7c2f
BB
1923 void *zacep = NULL;
1924 uint64_t who;
1925 uint32_t access_mask;
1926 uint16_t type, iflags;
1927
149e873a
BB
1928 while ((zacep = zfs_acl_next_ace(aclp, zacep,
1929 &who, &access_mask, &iflags, &type))) {
34dc7c2f
BB
1930 switch (type) {
1931 case ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE:
1932 case ACE_ACCESS_DENIED_OBJECT_ACE_TYPE:
1933 case ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE:
1934 case ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE:
1935 largeace++;
1936 continue;
1937 default:
1938 count++;
1939 }
1940 }
1941 vsecp->vsa_aclcnt = count;
1942 } else
428870ff 1943 count = (int)aclp->z_acl_count;
34dc7c2f
BB
1944
1945 if (mask & VSA_ACECNT) {
1946 vsecp->vsa_aclcnt = count;
1947 }
1948
1949 if (mask & VSA_ACE) {
1950 size_t aclsz;
1951
34dc7c2f
BB
1952 aclsz = count * sizeof (ace_t) +
1953 sizeof (ace_object_t) * largeace;
1954
1955 vsecp->vsa_aclentp = kmem_alloc(aclsz, KM_SLEEP);
1956 vsecp->vsa_aclentsz = aclsz;
1957
1958 if (aclp->z_version == ZFS_ACL_VERSION_FUID)
3558fd73 1959 zfs_copy_fuid_2_ace(ZTOZSB(zp), aclp, cr,
34dc7c2f
BB
1960 vsecp->vsa_aclentp, !(mask & VSA_ACE_ALLTYPES));
1961 else {
428870ff
BB
1962 zfs_acl_node_t *aclnode;
1963 void *start = vsecp->vsa_aclentp;
1964
1965 for (aclnode = list_head(&aclp->z_acl); aclnode;
1966 aclnode = list_next(&aclp->z_acl, aclnode)) {
1967 bcopy(aclnode->z_acldata, start,
1968 aclnode->z_size);
1969 start = (caddr_t)start + aclnode->z_size;
1970 }
1971 ASSERT((caddr_t)start - (caddr_t)vsecp->vsa_aclentp ==
1972 aclp->z_acl_bytes);
34dc7c2f
BB
1973 }
1974 }
1975 if (mask & VSA_ACE_ACLFLAGS) {
1976 vsecp->vsa_aclflags = 0;
428870ff 1977 if (zp->z_pflags & ZFS_ACL_DEFAULTED)
34dc7c2f 1978 vsecp->vsa_aclflags |= ACL_DEFAULTED;
428870ff 1979 if (zp->z_pflags & ZFS_ACL_PROTECTED)
34dc7c2f 1980 vsecp->vsa_aclflags |= ACL_PROTECTED;
428870ff 1981 if (zp->z_pflags & ZFS_ACL_AUTO_INHERIT)
34dc7c2f
BB
1982 vsecp->vsa_aclflags |= ACL_AUTO_INHERIT;
1983 }
1984
1985 mutex_exit(&zp->z_acl_lock);
1986
34dc7c2f
BB
1987 return (0);
1988}
1989
1990int
3558fd73 1991zfs_vsec_2_aclp(zfs_sb_t *zsb, umode_t obj_mode,
9babb374 1992 vsecattr_t *vsecp, cred_t *cr, zfs_fuid_info_t **fuidp, zfs_acl_t **zaclp)
34dc7c2f
BB
1993{
1994 zfs_acl_t *aclp;
1995 zfs_acl_node_t *aclnode;
1996 int aclcnt = vsecp->vsa_aclcnt;
1997 int error;
1998
1999 if (vsecp->vsa_aclcnt > MAX_ACL_ENTRIES || vsecp->vsa_aclcnt <= 0)
a08ee875 2000 return (SET_ERROR(EINVAL));
34dc7c2f 2001
3558fd73 2002 aclp = zfs_acl_alloc(zfs_acl_version(zsb->z_version));
34dc7c2f
BB
2003
2004 aclp->z_hints = 0;
2005 aclnode = zfs_acl_node_alloc(aclcnt * sizeof (zfs_object_ace_t));
2006 if (aclp->z_version == ZFS_ACL_VERSION_INITIAL) {
3558fd73 2007 if ((error = zfs_copy_ace_2_oldace(obj_mode, aclp,
34dc7c2f
BB
2008 (ace_t *)vsecp->vsa_aclentp, aclnode->z_acldata,
2009 aclcnt, &aclnode->z_size)) != 0) {
2010 zfs_acl_free(aclp);
2011 zfs_acl_node_free(aclnode);
2012 return (error);
2013 }
2014 } else {
3558fd73 2015 if ((error = zfs_copy_ace_2_fuid(zsb, obj_mode, aclp,
34dc7c2f 2016 vsecp->vsa_aclentp, aclnode->z_acldata, aclcnt,
9babb374 2017 &aclnode->z_size, fuidp, cr)) != 0) {
34dc7c2f
BB
2018 zfs_acl_free(aclp);
2019 zfs_acl_node_free(aclnode);
2020 return (error);
2021 }
2022 }
2023 aclp->z_acl_bytes = aclnode->z_size;
2024 aclnode->z_ace_count = aclcnt;
2025 aclp->z_acl_count = aclcnt;
2026 list_insert_head(&aclp->z_acl, aclnode);
2027
2028 /*
2029 * If flags are being set then add them to z_hints
2030 */
2031 if (vsecp->vsa_mask & VSA_ACE_ACLFLAGS) {
2032 if (vsecp->vsa_aclflags & ACL_PROTECTED)
2033 aclp->z_hints |= ZFS_ACL_PROTECTED;
2034 if (vsecp->vsa_aclflags & ACL_DEFAULTED)
2035 aclp->z_hints |= ZFS_ACL_DEFAULTED;
2036 if (vsecp->vsa_aclflags & ACL_AUTO_INHERIT)
2037 aclp->z_hints |= ZFS_ACL_AUTO_INHERIT;
2038 }
2039
2040 *zaclp = aclp;
2041
2042 return (0);
2043}
2044
2045/*
a08ee875 2046 * Set a file's ACL
34dc7c2f
BB
2047 */
2048int
2049zfs_setacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr)
2050{
3558fd73
BB
2051 zfs_sb_t *zsb = ZTOZSB(zp);
2052 zilog_t *zilog = zsb->z_log;
34dc7c2f
BB
2053 ulong_t mask = vsecp->vsa_mask & (VSA_ACE | VSA_ACECNT);
2054 dmu_tx_t *tx;
2055 int error;
2056 zfs_acl_t *aclp;
2057 zfs_fuid_info_t *fuidp = NULL;
9babb374 2058 boolean_t fuid_dirtied;
572e2857 2059 uint64_t acl_obj;
34dc7c2f
BB
2060
2061 if (mask == 0)
a08ee875 2062 return (SET_ERROR(ENOSYS));
34dc7c2f 2063
428870ff 2064 if (zp->z_pflags & ZFS_IMMUTABLE)
a08ee875 2065 return (SET_ERROR(EPERM));
34dc7c2f 2066
149e873a 2067 if ((error = zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr)))
34dc7c2f
BB
2068 return (error);
2069
3558fd73 2070 error = zfs_vsec_2_aclp(zsb, ZTOI(zp)->i_mode, vsecp, cr, &fuidp,
9babb374 2071 &aclp);
34dc7c2f
BB
2072 if (error)
2073 return (error);
2074
2075 /*
2076 * If ACL wide flags aren't being set then preserve any
2077 * existing flags.
2078 */
2079 if (!(vsecp->vsa_mask & VSA_ACE_ACLFLAGS)) {
428870ff
BB
2080 aclp->z_hints |=
2081 (zp->z_pflags & V4_ACL_WIDE_FLAGS);
34dc7c2f
BB
2082 }
2083top:
34dc7c2f 2084 mutex_enter(&zp->z_acl_lock);
572e2857 2085 mutex_enter(&zp->z_lock);
34dc7c2f 2086
3558fd73 2087 tx = dmu_tx_create(zsb->z_os);
428870ff
BB
2088
2089 dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_TRUE);
2090
3558fd73 2091 fuid_dirtied = zsb->z_fuid_dirty;
428870ff 2092 if (fuid_dirtied)
3558fd73 2093 zfs_fuid_txhold(zsb, tx);
428870ff
BB
2094
2095 /*
2096 * If old version and ACL won't fit in bonus and we aren't
2097 * upgrading then take out necessary DMU holds
2098 */
2099
572e2857 2100 if ((acl_obj = zfs_external_acl(zp)) != 0) {
3558fd73 2101 if (zsb->z_version >= ZPL_VERSION_FUID &&
572e2857
BB
2102 zfs_znode_acl_version(zp) <= ZFS_ACL_VERSION_INITIAL) {
2103 dmu_tx_hold_free(tx, acl_obj, 0,
428870ff 2104 DMU_OBJECT_END);
572e2857
BB
2105 dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0,
2106 aclp->z_acl_bytes);
34dc7c2f 2107 } else {
572e2857 2108 dmu_tx_hold_write(tx, acl_obj, 0, aclp->z_acl_bytes);
34dc7c2f 2109 }
428870ff 2110 } else if (!zp->z_is_sa && aclp->z_acl_bytes > ZFS_ACE_SPACE) {
34dc7c2f
BB
2111 dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, aclp->z_acl_bytes);
2112 }
34dc7c2f 2113
428870ff 2114 zfs_sa_upgrade_txholds(tx, zp);
fb5f0bc8 2115 error = dmu_tx_assign(tx, TXG_NOWAIT);
34dc7c2f
BB
2116 if (error) {
2117 mutex_exit(&zp->z_acl_lock);
2118 mutex_exit(&zp->z_lock);
2119
fb5f0bc8 2120 if (error == ERESTART) {
34dc7c2f
BB
2121 dmu_tx_wait(tx);
2122 dmu_tx_abort(tx);
2123 goto top;
2124 }
2125 dmu_tx_abort(tx);
2126 zfs_acl_free(aclp);
2127 return (error);
2128 }
2129
9babb374 2130 error = zfs_aclset_common(zp, aclp, cr, tx);
34dc7c2f 2131 ASSERT(error == 0);
572e2857 2132 ASSERT(zp->z_acl_cached == NULL);
45d1cae3 2133 zp->z_acl_cached = aclp;
34dc7c2f 2134
9babb374 2135 if (fuid_dirtied)
3558fd73 2136 zfs_fuid_sync(zsb, tx);
9babb374 2137
34dc7c2f
BB
2138 zfs_log_acl(zilog, tx, zp, vsecp, fuidp);
2139
2140 if (fuidp)
2141 zfs_fuid_info_free(fuidp);
34dc7c2f 2142 dmu_tx_commit(tx);
c60bc1fb 2143
34dc7c2f 2144 mutex_exit(&zp->z_lock);
572e2857 2145 mutex_exit(&zp->z_acl_lock);
34dc7c2f
BB
2146
2147 return (error);
2148}
2149
2150/*
9babb374
BB
2151 * Check accesses of interest (AoI) against attributes of the dataset
2152 * such as read-only. Returns zero if no AoI conflict with dataset
2153 * attributes, otherwise an appropriate errno is returned.
34dc7c2f
BB
2154 */
2155static int
9babb374 2156zfs_zaccess_dataset_check(znode_t *zp, uint32_t v4_mode)
34dc7c2f 2157{
2cf7f52b 2158 if ((v4_mode & WRITE_MASK) && (zfs_is_readonly(ZTOZSB(zp))) &&
3558fd73
BB
2159 (!S_ISDEV(ZTOI(zp)->i_mode) ||
2160 (S_ISDEV(ZTOI(zp)->i_mode) && (v4_mode & WRITE_MASK_ATTRS)))) {
a08ee875 2161 return (SET_ERROR(EROFS));
34dc7c2f
BB
2162 }
2163
2164 /*
2165 * Only check for READONLY on non-directories.
2166 */
2167 if ((v4_mode & WRITE_MASK_DATA) &&
3558fd73 2168 ((!S_ISDIR(ZTOI(zp)->i_mode) &&
428870ff 2169 (zp->z_pflags & (ZFS_READONLY | ZFS_IMMUTABLE))) ||
3558fd73 2170 (S_ISDIR(ZTOI(zp)->i_mode) &&
428870ff 2171 (zp->z_pflags & ZFS_IMMUTABLE)))) {
a08ee875 2172 return (SET_ERROR(EPERM));
34dc7c2f
BB
2173 }
2174
2175 if ((v4_mode & (ACE_DELETE | ACE_DELETE_CHILD)) &&
428870ff 2176 (zp->z_pflags & ZFS_NOUNLINK)) {
a08ee875 2177 return (SET_ERROR(EPERM));
34dc7c2f
BB
2178 }
2179
2180 if (((v4_mode & (ACE_READ_DATA|ACE_EXECUTE)) &&
428870ff 2181 (zp->z_pflags & ZFS_AV_QUARANTINED))) {
a08ee875 2182 return (SET_ERROR(EACCES));
34dc7c2f
BB
2183 }
2184
9babb374
BB
2185 return (0);
2186}
2187
2188/*
2189 * The primary usage of this function is to loop through all of the
2190 * ACEs in the znode, determining what accesses of interest (AoI) to
2191 * the caller are allowed or denied. The AoI are expressed as bits in
2192 * the working_mode parameter. As each ACE is processed, bits covered
2193 * by that ACE are removed from the working_mode. This removal
2194 * facilitates two things. The first is that when the working mode is
2195 * empty (= 0), we know we've looked at all the AoI. The second is
2196 * that the ACE interpretation rules don't allow a later ACE to undo
2197 * something granted or denied by an earlier ACE. Removing the
2198 * discovered access or denial enforces this rule. At the end of
2199 * processing the ACEs, all AoI that were found to be denied are
2200 * placed into the working_mode, giving the caller a mask of denied
2201 * accesses. Returns:
2202 * 0 if all AoI granted
2203 * EACCESS if the denied mask is non-zero
2204 * other error if abnormal failure (e.g., IO error)
2205 *
2206 * A secondary usage of the function is to determine if any of the
2207 * AoI are granted. If an ACE grants any access in
2208 * the working_mode, we immediately short circuit out of the function.
2209 * This mode is chosen by setting anyaccess to B_TRUE. The
2210 * working_mode is not a denied access mask upon exit if the function
2211 * is used in this manner.
2212 */
2213static int
2214zfs_zaccess_aces_check(znode_t *zp, uint32_t *working_mode,
2215 boolean_t anyaccess, cred_t *cr)
2216{
3558fd73 2217 zfs_sb_t *zsb = ZTOZSB(zp);
9babb374
BB
2218 zfs_acl_t *aclp;
2219 int error;
2220 uid_t uid = crgetuid(cr);
3558fd73 2221 uint64_t who;
9babb374
BB
2222 uint16_t type, iflags;
2223 uint16_t entry_type;
2224 uint32_t access_mask;
2225 uint32_t deny_mask = 0;
2226 zfs_ace_hdr_t *acep = NULL;
2227 boolean_t checkit;
572e2857
BB
2228 uid_t gowner;
2229 uid_t fowner;
2230
2231 zfs_fuid_map_ids(zp, cr, &fowner, &gowner);
34dc7c2f
BB
2232
2233 mutex_enter(&zp->z_acl_lock);
2234
572e2857 2235 error = zfs_acl_node_read(zp, B_FALSE, &aclp, B_FALSE);
34dc7c2f
BB
2236 if (error != 0) {
2237 mutex_exit(&zp->z_acl_lock);
2238 return (error);
2239 }
2240
428870ff
BB
2241 ASSERT(zp->z_acl_cached);
2242
149e873a
BB
2243 while ((acep = zfs_acl_next_ace(aclp, acep, &who, &access_mask,
2244 &iflags, &type))) {
9babb374 2245 uint32_t mask_matched;
34dc7c2f 2246
b128c09f
BB
2247 if (!zfs_acl_valid_ace_type(type, iflags))
2248 continue;
2249
3558fd73
BB
2250 if (S_ISDIR(ZTOI(zp)->i_mode) &&
2251 (iflags & ACE_INHERIT_ONLY_ACE))
34dc7c2f
BB
2252 continue;
2253
9babb374
BB
2254 /* Skip ACE if it does not affect any AoI */
2255 mask_matched = (access_mask & *working_mode);
2256 if (!mask_matched)
2257 continue;
2258
34dc7c2f
BB
2259 entry_type = (iflags & ACE_TYPE_FLAGS);
2260
2261 checkit = B_FALSE;
2262
2263 switch (entry_type) {
2264 case ACE_OWNER:
572e2857 2265 if (uid == fowner)
34dc7c2f
BB
2266 checkit = B_TRUE;
2267 break;
2268 case OWNING_GROUP:
2269 who = gowner;
2270 /*FALLTHROUGH*/
2271 case ACE_IDENTIFIER_GROUP:
3558fd73 2272 checkit = zfs_groupmember(zsb, who, cr);
34dc7c2f
BB
2273 break;
2274 case ACE_EVERYONE:
2275 checkit = B_TRUE;
2276 break;
2277
2278 /* USER Entry */
2279 default:
2280 if (entry_type == 0) {
2281 uid_t newid;
2282
3558fd73 2283 newid = zfs_fuid_map_id(zsb, who, cr,
34dc7c2f
BB
2284 ZFS_ACE_USER);
2285 if (newid != IDMAP_WK_CREATOR_OWNER_UID &&
2286 uid == newid)
2287 checkit = B_TRUE;
2288 break;
2289 } else {
34dc7c2f 2290 mutex_exit(&zp->z_acl_lock);
a08ee875 2291 return (SET_ERROR(EIO));
34dc7c2f
BB
2292 }
2293 }
2294
2295 if (checkit) {
9babb374
BB
2296 if (type == DENY) {
2297 DTRACE_PROBE3(zfs__ace__denies,
2298 znode_t *, zp,
2299 zfs_ace_hdr_t *, acep,
2300 uint32_t, mask_matched);
2301 deny_mask |= mask_matched;
2302 } else {
2303 DTRACE_PROBE3(zfs__ace__allows,
2304 znode_t *, zp,
2305 zfs_ace_hdr_t *, acep,
2306 uint32_t, mask_matched);
2307 if (anyaccess) {
2308 mutex_exit(&zp->z_acl_lock);
9babb374
BB
2309 return (0);
2310 }
34dc7c2f 2311 }
9babb374 2312 *working_mode &= ~mask_matched;
34dc7c2f
BB
2313 }
2314
2315 /* Are we done? */
2316 if (*working_mode == 0)
2317 break;
2318 }
2319
2320 mutex_exit(&zp->z_acl_lock);
34dc7c2f
BB
2321
2322 /* Put the found 'denies' back on the working mode */
b128c09f
BB
2323 if (deny_mask) {
2324 *working_mode |= deny_mask;
a08ee875 2325 return (SET_ERROR(EACCES));
b128c09f
BB
2326 } else if (*working_mode) {
2327 return (-1);
2328 }
34dc7c2f
BB
2329
2330 return (0);
2331}
2332
9babb374
BB
2333/*
2334 * Return true if any access whatsoever granted, we don't actually
2335 * care what access is granted.
2336 */
2337boolean_t
2338zfs_has_access(znode_t *zp, cred_t *cr)
2339{
2340 uint32_t have = ACE_ALL_PERMS;
2341
2342 if (zfs_zaccess_aces_check(zp, &have, B_TRUE, cr) != 0) {
572e2857
BB
2343 uid_t owner;
2344
3558fd73
BB
2345 owner = zfs_fuid_map_id(ZTOZSB(zp), zp->z_uid, cr, ZFS_OWNER);
2346 return (secpolicy_vnode_any_access(cr, ZTOI(zp), owner) == 0);
9babb374
BB
2347 }
2348 return (B_TRUE);
2349}
2350
2351static int
2352zfs_zaccess_common(znode_t *zp, uint32_t v4_mode, uint32_t *working_mode,
2353 boolean_t *check_privs, boolean_t skipaclchk, cred_t *cr)
2354{
3558fd73 2355 zfs_sb_t *zsb = ZTOZSB(zp);
9babb374
BB
2356 int err;
2357
2358 *working_mode = v4_mode;
2359 *check_privs = B_TRUE;
2360
2361 /*
2362 * Short circuit empty requests
2363 */
3558fd73 2364 if (v4_mode == 0 || zsb->z_replay) {
9babb374
BB
2365 *working_mode = 0;
2366 return (0);
2367 }
2368
2369 if ((err = zfs_zaccess_dataset_check(zp, v4_mode)) != 0) {
2370 *check_privs = B_FALSE;
2371 return (err);
2372 }
2373
2374 /*
2375 * The caller requested that the ACL check be skipped. This
2376 * would only happen if the caller checked VOP_ACCESS() with a
2377 * 32 bit ACE mask and already had the appropriate permissions.
2378 */
2379 if (skipaclchk) {
2380 *working_mode = 0;
2381 return (0);
2382 }
2383
2384 return (zfs_zaccess_aces_check(zp, working_mode, B_FALSE, cr));
2385}
2386
34dc7c2f
BB
2387static int
2388zfs_zaccess_append(znode_t *zp, uint32_t *working_mode, boolean_t *check_privs,
2389 cred_t *cr)
2390{
2391 if (*working_mode != ACE_WRITE_DATA)
a08ee875 2392 return (SET_ERROR(EACCES));
34dc7c2f
BB
2393
2394 return (zfs_zaccess_common(zp, ACE_APPEND_DATA, working_mode,
2395 check_privs, B_FALSE, cr));
2396}
2397
45d1cae3
BB
2398int
2399zfs_fastaccesschk_execute(znode_t *zdp, cred_t *cr)
2400{
2401 boolean_t owner = B_FALSE;
2402 boolean_t groupmbr = B_FALSE;
2403 boolean_t is_attr;
45d1cae3
BB
2404 uid_t uid = crgetuid(cr);
2405 int error;
2406
428870ff 2407 if (zdp->z_pflags & ZFS_AV_QUARANTINED)
a08ee875 2408 return (SET_ERROR(EACCES));
45d1cae3 2409
428870ff 2410 is_attr = ((zdp->z_pflags & ZFS_XATTR) &&
3558fd73 2411 (S_ISDIR(ZTOI(zdp)->i_mode)));
45d1cae3
BB
2412 if (is_attr)
2413 goto slow;
2414
428870ff 2415
45d1cae3
BB
2416 mutex_enter(&zdp->z_acl_lock);
2417
428870ff 2418 if (zdp->z_pflags & ZFS_NO_EXECS_DENIED) {
45d1cae3
BB
2419 mutex_exit(&zdp->z_acl_lock);
2420 return (0);
2421 }
2422
572e2857 2423 if (FUID_INDEX(zdp->z_uid) != 0 || FUID_INDEX(zdp->z_gid) != 0) {
45d1cae3
BB
2424 mutex_exit(&zdp->z_acl_lock);
2425 goto slow;
2426 }
2427
428870ff 2428 if (uid == zdp->z_uid) {
45d1cae3 2429 owner = B_TRUE;
428870ff 2430 if (zdp->z_mode & S_IXUSR) {
45d1cae3
BB
2431 mutex_exit(&zdp->z_acl_lock);
2432 return (0);
2433 } else {
2434 mutex_exit(&zdp->z_acl_lock);
2435 goto slow;
2436 }
2437 }
428870ff 2438 if (groupmember(zdp->z_gid, cr)) {
45d1cae3 2439 groupmbr = B_TRUE;
428870ff 2440 if (zdp->z_mode & S_IXGRP) {
45d1cae3
BB
2441 mutex_exit(&zdp->z_acl_lock);
2442 return (0);
2443 } else {
2444 mutex_exit(&zdp->z_acl_lock);
2445 goto slow;
2446 }
2447 }
2448 if (!owner && !groupmbr) {
428870ff 2449 if (zdp->z_mode & S_IXOTH) {
45d1cae3
BB
2450 mutex_exit(&zdp->z_acl_lock);
2451 return (0);
2452 }
2453 }
2454
2455 mutex_exit(&zdp->z_acl_lock);
2456
2457slow:
2458 DTRACE_PROBE(zfs__fastpath__execute__access__miss);
3558fd73 2459 ZFS_ENTER(ZTOZSB(zdp));
45d1cae3 2460 error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr);
3558fd73 2461 ZFS_EXIT(ZTOZSB(zdp));
45d1cae3
BB
2462 return (error);
2463}
2464
34dc7c2f 2465/*
428870ff 2466 * Determine whether Access should be granted/denied.
a08ee875 2467 *
428870ff
BB
2468 * The least priv subsytem is always consulted as a basic privilege
2469 * can define any form of access.
34dc7c2f
BB
2470 */
2471int
2472zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
2473{
2474 uint32_t working_mode;
2475 int error;
3558fd73 2476 boolean_t check_privs;
3558fd73 2477 znode_t *check_zp = zp;
428870ff 2478 mode_t needed_bits;
572e2857 2479 uid_t owner;
34dc7c2f 2480
34dc7c2f
BB
2481 /*
2482 * If attribute then validate against base file
2483 */
e89260a1 2484 if ((zp->z_pflags & ZFS_XATTR) && S_ISDIR(ZTOI(zp)->i_mode)) {
428870ff
BB
2485 uint64_t parent;
2486
e89260a1
BB
2487 rw_enter(&zp->z_xattr_lock, RW_READER);
2488 if (zp->z_xattr_parent) {
2489 check_zp = zp->z_xattr_parent;
2490 rw_exit(&zp->z_xattr_lock);
428870ff 2491
e89260a1
BB
2492 /*
2493 * Verify a lookup yields the same znode.
2494 */
2495 ASSERT3S(sa_lookup(zp->z_sa_hdl, SA_ZPL_PARENT(
2496 ZTOZSB(zp)), &parent, sizeof (parent)), ==, 0);
2497 ASSERT3U(check_zp->z_id, ==, parent);
2498 } else {
2499 rw_exit(&zp->z_xattr_lock);
34dc7c2f 2500
e89260a1
BB
2501 error = sa_lookup(zp->z_sa_hdl, SA_ZPL_PARENT(
2502 ZTOZSB(zp)), &parent, sizeof (parent));
2503 if (error)
2504 return (error);
2505
2506 /*
2507 * Cache the lookup on the parent file znode as
2508 * zp->z_xattr_parent and hold a reference. This
2509 * effectively pins the parent in memory until all
2510 * child xattr znodes have been destroyed and
2511 * release their references in zfs_inode_destroy().
2512 */
2513 error = zfs_zget(ZTOZSB(zp), parent, &check_zp);
2514 if (error)
a08ee875 2515 return (error);
e89260a1
BB
2516
2517 rw_enter(&zp->z_xattr_lock, RW_WRITER);
2518 if (zp->z_xattr_parent == NULL)
2519 zp->z_xattr_parent = check_zp;
2520 rw_exit(&zp->z_xattr_lock);
2521 }
34dc7c2f
BB
2522
2523 /*
2524 * fixup mode to map to xattr perms
2525 */
2526
2527 if (mode & (ACE_WRITE_DATA|ACE_APPEND_DATA)) {
2528 mode &= ~(ACE_WRITE_DATA|ACE_APPEND_DATA);
2529 mode |= ACE_WRITE_NAMED_ATTRS;
2530 }
2531
2532 if (mode & (ACE_READ_DATA|ACE_EXECUTE)) {
2533 mode &= ~(ACE_READ_DATA|ACE_EXECUTE);
2534 mode |= ACE_READ_NAMED_ATTRS;
2535 }
2536 }
2537
3558fd73 2538 owner = zfs_fuid_map_id(ZTOZSB(zp), zp->z_uid, cr, ZFS_OWNER);
428870ff 2539 /*
3558fd73
BB
2540 * Map the bits required to the standard inode flags
2541 * S_IRUSR|S_IWUSR|S_IXUSR in the needed_bits. Map the bits
2542 * mapped by working_mode (currently missing) in missing_bits.
428870ff
BB
2543 * Call secpolicy_vnode_access2() with (needed_bits & ~checkmode),
2544 * needed_bits.
2545 */
2546 needed_bits = 0;
2547
2548 working_mode = mode;
2549 if ((working_mode & (ACE_READ_ACL|ACE_READ_ATTRIBUTES)) &&
572e2857 2550 owner == crgetuid(cr))
428870ff
BB
2551 working_mode &= ~(ACE_READ_ACL|ACE_READ_ATTRIBUTES);
2552
2553 if (working_mode & (ACE_READ_DATA|ACE_READ_NAMED_ATTRS|
2554 ACE_READ_ACL|ACE_READ_ATTRIBUTES|ACE_SYNCHRONIZE))
3558fd73 2555 needed_bits |= S_IRUSR;
428870ff
BB
2556 if (working_mode & (ACE_WRITE_DATA|ACE_WRITE_NAMED_ATTRS|
2557 ACE_APPEND_DATA|ACE_WRITE_ATTRIBUTES|ACE_SYNCHRONIZE))
3558fd73 2558 needed_bits |= S_IWUSR;
428870ff 2559 if (working_mode & ACE_EXECUTE)
3558fd73 2560 needed_bits |= S_IXUSR;
428870ff 2561
34dc7c2f
BB
2562 if ((error = zfs_zaccess_common(check_zp, mode, &working_mode,
2563 &check_privs, skipaclchk, cr)) == 0) {
3558fd73 2564 return (secpolicy_vnode_access2(cr, ZTOI(zp), owner,
428870ff 2565 needed_bits, needed_bits));
34dc7c2f
BB
2566 }
2567
2568 if (error && !check_privs) {
34dc7c2f
BB
2569 return (error);
2570 }
2571
2572 if (error && (flags & V_APPEND)) {
2573 error = zfs_zaccess_append(zp, &working_mode, &check_privs, cr);
2574 }
2575
2576 if (error && check_privs) {
34dc7c2f
BB
2577 mode_t checkmode = 0;
2578
34dc7c2f
BB
2579 /*
2580 * First check for implicit owner permission on
2581 * read_acl/read_attributes
2582 */
2583
2584 error = 0;
2585 ASSERT(working_mode != 0);
2586
2587 if ((working_mode & (ACE_READ_ACL|ACE_READ_ATTRIBUTES) &&
572e2857 2588 owner == crgetuid(cr)))
34dc7c2f
BB
2589 working_mode &= ~(ACE_READ_ACL|ACE_READ_ATTRIBUTES);
2590
2591 if (working_mode & (ACE_READ_DATA|ACE_READ_NAMED_ATTRS|
b128c09f 2592 ACE_READ_ACL|ACE_READ_ATTRIBUTES|ACE_SYNCHRONIZE))
3558fd73 2593 checkmode |= S_IRUSR;
34dc7c2f 2594 if (working_mode & (ACE_WRITE_DATA|ACE_WRITE_NAMED_ATTRS|
b128c09f 2595 ACE_APPEND_DATA|ACE_WRITE_ATTRIBUTES|ACE_SYNCHRONIZE))
3558fd73 2596 checkmode |= S_IWUSR;
34dc7c2f 2597 if (working_mode & ACE_EXECUTE)
3558fd73 2598 checkmode |= S_IXUSR;
34dc7c2f 2599
3558fd73 2600 error = secpolicy_vnode_access2(cr, ZTOI(check_zp), owner,
428870ff 2601 needed_bits & ~checkmode, needed_bits);
34dc7c2f
BB
2602
2603 if (error == 0 && (working_mode & ACE_WRITE_OWNER))
572e2857 2604 error = secpolicy_vnode_chown(cr, owner);
34dc7c2f 2605 if (error == 0 && (working_mode & ACE_WRITE_ACL))
572e2857 2606 error = secpolicy_vnode_setdac(cr, owner);
34dc7c2f
BB
2607
2608 if (error == 0 && (working_mode &
2609 (ACE_DELETE|ACE_DELETE_CHILD)))
2610 error = secpolicy_vnode_remove(cr);
2611
b128c09f 2612 if (error == 0 && (working_mode & ACE_SYNCHRONIZE)) {
572e2857 2613 error = secpolicy_vnode_chown(cr, owner);
b128c09f 2614 }
34dc7c2f
BB
2615 if (error == 0) {
2616 /*
2617 * See if any bits other than those already checked
2618 * for are still present. If so then return EACCES
2619 */
2620 if (working_mode & ~(ZFS_CHECKED_MASKS)) {
a08ee875 2621 error = SET_ERROR(EACCES);
34dc7c2f
BB
2622 }
2623 }
428870ff 2624 } else if (error == 0) {
3558fd73 2625 error = secpolicy_vnode_access2(cr, ZTOI(zp), owner,
428870ff 2626 needed_bits, needed_bits);
34dc7c2f
BB
2627 }
2628
34dc7c2f
BB
2629 return (error);
2630}
2631
2632/*
3558fd73 2633 * Translate traditional unix S_IRUSR/S_IWUSR/S_IXUSR mode into
34dc7c2f
BB
2634 * native ACL format and call zfs_zaccess()
2635 */
2636int
2637zfs_zaccess_rwx(znode_t *zp, mode_t mode, int flags, cred_t *cr)
2638{
2639 return (zfs_zaccess(zp, zfs_unix_to_v4(mode >> 6), flags, B_FALSE, cr));
2640}
2641
2642/*
2643 * Access function for secpolicy_vnode_setattr
2644 */
2645int
2646zfs_zaccess_unix(znode_t *zp, mode_t mode, cred_t *cr)
2647{
2648 int v4_mode = zfs_unix_to_v4(mode >> 6);
2649
2650 return (zfs_zaccess(zp, v4_mode, 0, B_FALSE, cr));
2651}
2652
2653static int
2654zfs_delete_final_check(znode_t *zp, znode_t *dzp,
428870ff 2655 mode_t available_perms, cred_t *cr)
34dc7c2f
BB
2656{
2657 int error;
572e2857
BB
2658 uid_t downer;
2659
3558fd73 2660 downer = zfs_fuid_map_id(ZTOZSB(dzp), dzp->z_uid, cr, ZFS_OWNER);
34dc7c2f 2661
3558fd73
BB
2662 error = secpolicy_vnode_access2(cr, ZTOI(dzp),
2663 downer, available_perms, S_IWUSR|S_IXUSR);
34dc7c2f
BB
2664
2665 if (error == 0)
2666 error = zfs_sticky_remove_access(dzp, zp, cr);
2667
2668 return (error);
2669}
2670
2671/*
2672 * Determine whether Access should be granted/deny, without
2673 * consulting least priv subsystem.
2674 *
34dc7c2f
BB
2675 * The following chart is the recommended NFSv4 enforcement for
2676 * ability to delete an object.
2677 *
2678 * -------------------------------------------------------
2679 * | Parent Dir | Target Object Permissions |
2680 * | permissions | |
2681 * -------------------------------------------------------
2682 * | | ACL Allows | ACL Denies| Delete |
2683 * | | Delete | Delete | unspecified|
2684 * -------------------------------------------------------
2685 * | ACL Allows | Permit | Permit | Permit |
2686 * | DELETE_CHILD | |
2687 * -------------------------------------------------------
2688 * | ACL Denies | Permit | Deny | Deny |
2689 * | DELETE_CHILD | | | |
2690 * -------------------------------------------------------
2691 * | ACL specifies | | | |
2692 * | only allow | Permit | Permit | Permit |
2693 * | write and | | | |
2694 * | execute | | | |
2695 * -------------------------------------------------------
2696 * | ACL denies | | | |
2697 * | write and | Permit | Deny | Deny |
2698 * | execute | | | |
2699 * -------------------------------------------------------
2700 * ^
2701 * |
2702 * No search privilege, can't even look up file?
2703 *
2704 */
2705int
2706zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr)
2707{
2708 uint32_t dzp_working_mode = 0;
2709 uint32_t zp_working_mode = 0;
2710 int dzp_error, zp_error;
428870ff 2711 mode_t available_perms;
34dc7c2f
BB
2712 boolean_t dzpcheck_privs = B_TRUE;
2713 boolean_t zpcheck_privs = B_TRUE;
2714
2715 /*
2716 * We want specific DELETE permissions to
2717 * take precedence over WRITE/EXECUTE. We don't
2718 * want an ACL such as this to mess us up.
2719 * user:joe:write_data:deny,user:joe:delete:allow
2720 *
2721 * However, deny permissions may ultimately be overridden
2722 * by secpolicy_vnode_access().
2723 *
2724 * We will ask for all of the necessary permissions and then
2725 * look at the working modes from the directory and target object
2726 * to determine what was found.
2727 */
2728
428870ff 2729 if (zp->z_pflags & (ZFS_IMMUTABLE | ZFS_NOUNLINK))
a08ee875 2730 return (SET_ERROR(EPERM));
34dc7c2f
BB
2731
2732 /*
b128c09f 2733 * First row
34dc7c2f
BB
2734 * If the directory permissions allow the delete, we are done.
2735 */
b128c09f 2736 if ((dzp_error = zfs_zaccess_common(dzp, ACE_DELETE_CHILD,
34dc7c2f
BB
2737 &dzp_working_mode, &dzpcheck_privs, B_FALSE, cr)) == 0)
2738 return (0);
2739
2740 /*
2741 * If target object has delete permission then we are done
2742 */
2743 if ((zp_error = zfs_zaccess_common(zp, ACE_DELETE, &zp_working_mode,
2744 &zpcheck_privs, B_FALSE, cr)) == 0)
2745 return (0);
2746
b128c09f
BB
2747 ASSERT(dzp_error && zp_error);
2748
34dc7c2f
BB
2749 if (!dzpcheck_privs)
2750 return (dzp_error);
b128c09f 2751 if (!zpcheck_privs)
34dc7c2f
BB
2752 return (zp_error);
2753
34dc7c2f
BB
2754 /*
2755 * Second row
b128c09f
BB
2756 *
2757 * If directory returns EACCES then delete_child was denied
2758 * due to deny delete_child. In this case send the request through
2759 * secpolicy_vnode_remove(). We don't use zfs_delete_final_check()
2760 * since that *could* allow the delete based on write/execute permission
2761 * and we want delete permissions to override write/execute.
34dc7c2f
BB
2762 */
2763
34dc7c2f 2764 if (dzp_error == EACCES)
b128c09f 2765 return (secpolicy_vnode_remove(cr));
34dc7c2f
BB
2766
2767 /*
2768 * Third Row
2769 * only need to see if we have write/execute on directory.
2770 */
2771
428870ff
BB
2772 dzp_error = zfs_zaccess_common(dzp, ACE_EXECUTE|ACE_WRITE_DATA,
2773 &dzp_working_mode, &dzpcheck_privs, B_FALSE, cr);
34dc7c2f 2774
428870ff 2775 if (dzp_error != 0 && !dzpcheck_privs)
b128c09f
BB
2776 return (dzp_error);
2777
34dc7c2f 2778 /*
b128c09f 2779 * Fourth row
34dc7c2f
BB
2780 */
2781
3558fd73
BB
2782 available_perms = (dzp_working_mode & ACE_WRITE_DATA) ? 0 : S_IWUSR;
2783 available_perms |= (dzp_working_mode & ACE_EXECUTE) ? 0 : S_IXUSR;
34dc7c2f 2784
428870ff 2785 return (zfs_delete_final_check(zp, dzp, available_perms, cr));
b128c09f 2786
34dc7c2f
BB
2787}
2788
2789int
2790zfs_zaccess_rename(znode_t *sdzp, znode_t *szp, znode_t *tdzp,
2791 znode_t *tzp, cred_t *cr)
2792{
2793 int add_perm;
2794 int error;
2795
428870ff 2796 if (szp->z_pflags & ZFS_AV_QUARANTINED)
a08ee875 2797 return (SET_ERROR(EACCES));
34dc7c2f 2798
3558fd73 2799 add_perm = S_ISDIR(ZTOI(szp)->i_mode) ?
34dc7c2f
BB
2800 ACE_ADD_SUBDIRECTORY : ACE_ADD_FILE;
2801
2802 /*
2803 * Rename permissions are combination of delete permission +
2804 * add file/subdir permission.
2805 */
2806
2807 /*
2808 * first make sure we do the delete portion.
2809 *
2810 * If that succeeds then check for add_file/add_subdir permissions
2811 */
2812
149e873a 2813 if ((error = zfs_zaccess_delete(sdzp, szp, cr)))
34dc7c2f
BB
2814 return (error);
2815
2816 /*
2817 * If we have a tzp, see if we can delete it?
2818 */
2819 if (tzp) {
149e873a 2820 if ((error = zfs_zaccess_delete(tdzp, tzp, cr)))
34dc7c2f
BB
2821 return (error);
2822 }
2823
2824 /*
2825 * Now check for add permissions
2826 */
2827 error = zfs_zaccess(tdzp, add_perm, 0, B_FALSE, cr);
2828
2829 return (error);
2830}