[PATCH] Add "zfsacl:force inheritance special id ace" parameter

SATOH Fumiyasu fumiyas at osstech.co.jp
Thu Feb 16 05:54:06 MST 2012


Hi,

At Mon, 13 Feb 2012 12:06:34 -0500,
Ira Cooper wrote:
> This is a workaround for an explicit kernel behavior in ZFS.  What you are
> seeing is actually the mode bits from a chmod, being done by the kernel,
> you can see how it happens:

I think this behavior cannot help non-ZFS-ACL-compatible users and
applications, but then this behavior annoys ZFS-ACL-compatible one.

I want an "aclinherit=passthrough-no-chmod" ZFS property. :)

> http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/common/fs/zfs/zfs_acl.c#1602;
> I won't quote the code here, for IP reasons.
> 
> I'm not sure about some of your checks after reading that code, but I'd
> have to track through things a bit more to be sure.
> 
> An edge condition to think about:
> 
> $ ls -lV
> total 3
> drwxr-xr-x+  2 ira  users          2 Feb 13 11:44 dir
>             owner@:--------------:------:deny
>             owner@:rwxp---A-W-Co-:------:allow
>             group@:-w-p----------:------:deny
>             group@:r-x-----------:------:allow
>          everyone@:-w-p---A-W-Co-:------:deny
>          everyone@:r-x---a-R-c--s:------:allow

You should adjust ACL for Windows explorer to avoid
"DENY ACEs must appear before ALLOW ACEs." error.

Windows explorer does not send such ACL.

>          everyone@:--------------:fd----:allow

> $ touch dir/foo
> $ ls -dV dir/foo
> ----------+  1 ira  users          0 Feb 13 11:45 dir/foo
>          everyone@:--------------:------:allow

OK. I've revised my patch to not add the ACE 'everyone@::fd:allow'
if the ACL sent from client has no inherit no-special id ACE.

> If an NFSV3 user made a file in that directory, he'd never know the ACE was
> there, and he'd be pretty confused about what just happened!  This is a
> general issue with ACEs but this really amplifies the issues.  I'd expect
> the windows user who made the directory would be surprised by the results
> also.
> 
> That said, at least on my NexentaOS_134f box, and I assume on Illumos, I
> don't get any of the negative entries, so the issue with explorer shouldn't
> happen, this is using your original reproduction steps:
> 
> -rw-r--r--+  1 ira     users           0 Feb 13 08:34
> dir/file-inherit-bad-ace
>             group:staff:rwxpd-aARWcCos:------I:allow
>                  owner@:rw-p--aARWcCos:-------:allow
>                  group@:r-----a-R-c--s:-------:allow
>               everyone@:r-----a-R-c--s:-------:allow

Yes. The "Unexpected DENY ACE appears after ALLOW ACE in the
inherited ACL" problem does not occur on Solaris 11 too. But
"Unexpected ALLOW ACE appears" problem still occurs:

  $ uname -a
  SunOS exp-sol11 5.11 11.0 i86pc i386 i86pc
  $ zfs get aclinherit rpool/share
  NAME         PROPERTY    VALUE          SOURCE
  rpool/share  aclinherit  passthrough    local

  $ chmod A=group:staff:rwxp-DaARWcCos:fd:allow dir
  $ mkdir dir/d-with-unexpected-ace
  $ touch dir/f-with-unexpected-ace
  $ ls -Vd dir dir/
  d---------+  3 fumiyas  other          4 Feb 17 05:36 dir
              group:staff:rwxp-DaARWcCos:fd-----:allow
  -rw-r--r--+  1 fumiyas  other          0 Feb 17 05:36 dir/f-with-unexpected-ace
              group:staff:rwxp-DaARWcCos:------I:allow
                   owner@:rw-p--aARWcCos:-------:allow
                   group@:r-----a-R-c--s:-------:allow
                everyone@:r-----a-R-c--s:-------:allow
  drwxr-xr-x+  2 fumiyas  other          2 Feb 17 05:36 dir/d-with-unexpected-ace
              group:staff:rwxp-DaARWcCos:fd----I:allow
                   owner@:rwxp-DaARWcCos:-------:allow
                   group@:r-x---a-R-c--s:-------:allow
                everyone@:r-x---a-R-c--s:-------:allow

If the "everyone@::fd:allow" ACE is appended to the ACL on the
parent directory, no unexpected ACE does not appear.

  $ chmod A1+everyone@::fd:allow dir
  $ mkdir dir/d-with-expected-ace
  $ touch dir/f-with-expected-ace
  $ ls -Vd dir dir/
  d---------+  3 fumiyas  other          4 Feb 17 05:42 dir
              group:staff:rwxp-DaARWcCos:fd-----:allow
  -rw-r--r--+  1 fumiyas  other          0 Feb 17 05:42 dir/f-with-expected-ace
              group:staff:rwxp-DaARWcCos:------I:allow
                everyone@:--------------:------I:allow
  drwxr-xr-x+  2 fumiyas   other          2 Feb 17 05:42 dir/d-with-expected-ace
              group:staff:rwxp-DaARWcCos:fd----I:allow
                everyone@:--------------:fd----I:allow

> ------
> 
> I suspect there's a better answer.  But we need to understand more of the
> situation, and what the correct set of permissions at the end should be.

-- 
-- Name: SATOH Fumiyasu (fumiyas @ osstech co jp)
-- Business Home: http://www.OSSTech.co.jp/
-- Personal Home: https://github.com/fumiyas/
-------------- next part --------------
>From 4a24092b28b03cc42988239d8907f249a7842b97 Mon Sep 17 00:00:00 2001
From: SATOH Fumiyasu <fumiyas at osstech.co.jp>
Date: Sat, 11 Feb 2012 18:04:14 +0900
Subject: [PATCH] Add "zfsacl:force inheritance special id ace" parameter

Append the non-effective ACE 'everyone@::fd:allow' if the
specified ACL has no inheritance special id ACE.

When a directory has no inheritance special id ACE (i.e.,
'owner@', 'group@' and 'everyone@' with inheritance flags),
a new file under the directory inherits the ACL with unexpected
DENY special id ACEs. It is NOT compatible with Windows explorer
ACL editor.

  $ zfs get aclinherit rpool/share
  NAME         PROPERTY    VALUE          SOURCE
  rpool/share  aclinherit  passthrough    local
  $ mkdir dir

  $ chmod A=group:staff:rwxpd-aARWcCos:fd----:allow dir
  $ touch dir/file-inherit-bad-ace
  $ ls -dV dir dir/file-inherit-bad-ace
  d---------+  2 root     root           3 Feb 11 19:01 dir
	group:staff:rwxpd-aARWcCos:fd----:allow
  -rw-r--r--+  1 root     root           0 Feb 11 19:01 dir/file-inherit-bad-ace
	group:staff:-wxp----------:------:deny
	group:staff:rwxpd-aARWcCos:------:allow
	      owner@:--x-----------:------:deny
	      owner@:rw-p---A-W-Co-:------:allow
	      group@:-wxp----------:------:deny
	      group@:r-------------:------:allow
	  everyone@:-wxp---A-W-Co-:------:deny
	  everyone@:r-----a-R-c--s:------:allow

  $ chmod A1+everyone@::fd:allow dir
  $ touch dir/file-inherit-good-ace
  $ ls -dV dir dir/file-inherit-good-ace
  d---------+  2 root     root           4 Feb 11 19:02 dir
	group:staff:rwxpd-aARWcCos:fd----:allow
	  everyone@:--------------:fd----:allow
  ----------+  1 root     root           0 Feb 11 19:02 dir/file-inherit-good-ace
	group:staff:rwxpd-aARWcCos:------:allow
	  everyone@:--------------:------:allow
---
 source3/modules/vfs_zfsacl.c |   51 +++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 50 insertions(+), 1 deletions(-)

diff --git a/source3/modules/vfs_zfsacl.c b/source3/modules/vfs_zfsacl.c
index 286720a..b39e030 100644
--- a/source3/modules/vfs_zfsacl.c
+++ b/source3/modules/vfs_zfsacl.c
@@ -113,10 +113,14 @@ static bool zfs_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl)
 	SMB4ACE_T *smbace;
 	TALLOC_CTX	*mem_ctx;
 	bool have_special_id = false;
+	bool have_file_inherit_special_id = false;
+	bool have_file_inherit_no_special_id = false;
+	bool have_dir_inherit_special_id = false;
+	bool have_dir_inherit_no_special_id = false;
 
 	/* allocate the field of ZFS aces */
 	mem_ctx = talloc_tos();
-	acebuf = (ace_t *) talloc_size(mem_ctx, sizeof(ace_t)*naces);
+	acebuf = (ace_t *) talloc_size(mem_ctx, sizeof(ace_t)*(naces+1));
 	if(acebuf == NULL) {
 		errno = ENOMEM;
 		return False;
@@ -151,6 +155,22 @@ static bool zfs_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl)
 				continue; /* don't add it !!! */
 			}
 			have_special_id = true;
+
+			if (acebuf[i].a_flags & ACE_FILE_INHERIT_ACE) {
+				have_file_inherit_special_id = true;
+			}
+			if (acebuf[i].a_flags & ACE_DIRECTORY_INHERIT_ACE &&
+			    !(acebuf[i].a_flags & ACE_NO_PROPAGATE_INHERIT_ACE)) {
+				have_dir_inherit_special_id = true;
+			}
+		} else {
+			if (acebuf[i].a_flags & ACE_FILE_INHERIT_ACE) {
+				have_file_inherit_no_special_id = true;
+			}
+			if (acebuf[i].a_flags & ACE_DIRECTORY_INHERIT_ACE &&
+			    !(acebuf[i].a_flags & ACE_NO_PROPAGATE_INHERIT_ACE)) {
+				have_dir_inherit_no_special_id = true;
+			}
 		}
 	}
 
@@ -163,6 +183,35 @@ static bool zfs_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl)
 
 	SMB_ASSERT(i == naces);
 
+	/* Solaris 10 hack: Append the non-effective ACE
+	 * 'everyone@::fd:allow' if the specified ACL has no
+	 * inheritance special id ACE.
+	 *
+	 * When a directory has no inheritance special id ACE
+	 * (i.e., 'owner@', 'group@' and 'everyone@' with
+	 * inheritance flags), a new file under the directory
+	 * inherits the ACL with unexpected DENY special id
+	 * ACEs. It is NOT compatible with Windows explorer
+	 * ACL editor.
+	 */
+	acebuf[naces].a_flags = 0;
+	if (!have_file_inherit_special_id && have_file_inherit_no_special_id) {
+		acebuf[naces].a_flags |= ACE_FILE_INHERIT_ACE;
+	}
+	if (!have_dir_inherit_special_id && have_dir_inherit_no_special_id) {
+		acebuf[naces].a_flags |= ACE_DIRECTORY_INHERIT_ACE;
+	}
+	if (acebuf[naces].a_flags &&
+	    lp_parm_bool(fsp->conn->params->service, "zfsacl",
+			"force inheritance special id ace",
+			false)) {
+		acebuf[naces].a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
+		acebuf[naces].a_flags |= ACE_EVERYONE;
+		acebuf[naces].a_access_mask = 0;
+		acebuf[naces].a_who = 0;
+		naces++;
+	}
+
 	/* store acl */
 	if(acl(fsp->fsp_name->base_name, ACE_SETACL, naces, acebuf)) {
 		if(errno == ENOSYS) {
-- 
1.7.9



More information about the samba-technical mailing list