Created
July 26, 2020 19:49
-
-
Save yds/2e1b2ca7a0f5f1eaed6b5f360bb48e50 to your computer and use it in GitHub Desktop.
Check if sysvol is on filesystem with ZFS ACLs cherry picked from <https://Bugs.FreeBSD.org/bugzilla/show_bug.cgi?id=239105#c47>
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 2664c997587416a2c8c911a75158485a5c98b70b Mon Sep 17 00:00:00 2001 | |
From: John Hixon <john@ixsystems.com> | |
Date: Sat, 20 May 2017 04:39:37 +0200 | |
Subject: [PATCH] Zfs provision (#1) | |
Cherry-pick ZFS provisioning code by iXsystems Inc. | |
* Check if sysvol is on filesystem with ZFS ACLs | |
(cherry picked from <https://Bugs.FreeBSD.org/bugzilla/show_bug.cgi?id=239105#c47>) | |
* Check if sysvol is on filesystem with NFSv4 ACLs | |
(cherry picked from commit ca86f52b78a7b6e7537454a69cf93e7b96210cba) | |
* Only check targetdir if it is defined (I had assumed it was) | |
(cherry picked from commit a29050cb2978ce23e3c04a859340dc2664c77a8a) | |
* Kick samba a little bit into understanding NFSv4 ACLs | |
(cherry picked from commit 1c7542ff4904b729e311e17464ee76582760c219) | |
Signed-off-by: Timur I. Bakeyev <timur@iXsystems.com> | |
diff --git a/python/samba/provision/__init__.py b/python/samba/provision/__init__.py | |
index 5de986463a5..cd3b91f41b9 100644 | |
--- a/python/samba/provision/__init__.py | |
+++ b/python/samba/provision/__init__.py | |
@@ -1679,12 +1679,17 @@ | |
s3conf = s3param.get_context() | |
s3conf.load(lp.configfile) | |
- file = tempfile.NamedTemporaryFile(dir=os.path.abspath(sysvol)) | |
+ sysvol_dir = os.path.abspath(sysvol) | |
+ | |
+ file = tempfile.NamedTemporaryFile(dir=sysvol_dir) | |
try: | |
try: | |
- smbd.set_simple_acl(file.name, 0o755, system_session_unix(), gid) | |
+ if smbd.has_nfsv4_acls(sysvol_dir): | |
+ smbd.set_simple_nfsv4_acl(file.name, 0o755, gid) | |
+ else: | |
+ smbd.set_simple_acl(file.name, 0o755, system_session_unix(), gid) | |
except OSError: | |
- if not smbd.have_posix_acls(): | |
+ if not smbd.have_posix_acls() and not smbd.have_nfsv4_acls(): | |
# This clue is only strictly correct for RPM and | |
# Debian-like Linux systems, but hopefully other users | |
# will get enough clue from it. | |
@@ -1973,6 +1978,9 @@ | |
samdb.transaction_commit() | |
if serverrole == "active directory domain controller": | |
+ if targetdir and smbd.have_nfsv4_acls() and smbd.has_nfsv4_acls(targetdir): | |
+ smbd.set_nfsv4_defaults() | |
+ | |
# Continue setting up sysvol for GPO. This appears to require being | |
# outside a transaction. | |
if not skip_sysvolacl: | |
@@ -2328,6 +2336,9 @@ | |
if not os.path.isdir(paths.netlogon): | |
os.makedirs(paths.netlogon, 0o755) | |
+ | |
+ if smbd.have_nfsv4_acls() and smbd.has_nfsv4_acls(paths.sysvol): | |
+ smbd.set_nfsv4_defaults() | |
if adminpass is None: | |
adminpass = samba.generate_random_password(12, 32) | |
diff --git a/source3/lib/sysacls.c b/source3/lib/sysacls.c | |
index 0bf3c37edfa..786cd39b5bc 100644 | |
--- a/source3/lib/sysacls.c | |
+++ b/source3/lib/sysacls.c | |
@@ -38,6 +38,16 @@ | |
#include "modules/vfs_hpuxacl.h" | |
#endif | |
+/* | |
+ * NFSv4 ACL's should be understood and a first class citizen. Work | |
+ * needs to be done in librpc/idl/smb_acl.idl for this to occur. | |
+ */ | |
+#if defined(HAVE_LIBSUNACL) && defined(FREEBSD) | |
+#if 0 | |
+#include "modules/nfs4_acls.h" | |
+#endif | |
+#endif | |
+ | |
#undef DBGC_CLASS | |
#define DBGC_CLASS DBGC_ACLS | |
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c | |
index a2fcc4246c9..4b676897fc1 100644 | |
--- a/source3/param/loadparm.c | |
+++ b/source3/param/loadparm.c | |
@@ -2803,9 +2803,24 @@ | |
} else { | |
if (lp_parm_const_string(-1, "xattr_tdb", "file", NULL)) { | |
lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr xattr_tdb"); | |
+ } else if (pathconf(get_dyn_STATEDIR(), _PC_ACL_NFS4) == 1){ | |
+ /* | |
+ * By default, the samba sysvol is located in the statedir. | |
+ * Provisioning will fail in setntacl unless we have zfsacl enabled. | |
+ * Unfortunately, at this point the smb.conf has not been generated. | |
+ * This workaround is freebsd-specific. | |
+ */ | |
+ lp_do_parameter(-1, "vfs objects", "dfs_samba4 zfsacl"); | |
} else if (lp_parm_const_string(-1, "posix", "eadb", NULL)) { | |
lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr posix_eadb"); | |
} else { | |
+ /* | |
+ * This should only set dfs_samba4 and leave acl_xattr | |
+ * to be set later (or zfsacl). The only reason the | |
+ * decision can't be made here to load acl_xattr or | |
+ * zfsacl is that we don't have access to what the | |
+ * target directory is. | |
+ */ | |
lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr"); | |
} | |
} | |
diff --git a/source3/smbd/pysmbd.c b/source3/smbd/pysmbd.c | |
index 63fc5d68c33..f5a536ee186 100644 | |
--- a/source3/smbd/pysmbd.c | |
+++ b/source3/smbd/pysmbd.c | |
@@ -419,6 +419,20 @@ | |
return acl; | |
} | |
+static SMB_ACL_T make_simple_nfsv4_acl(TALLOC_CTX *mem_ctx, | |
+ gid_t gid, | |
+ mode_t chmod_mode) | |
+{ | |
+ /* | |
+ * This function needs to create an NFSv4 ACL. Currently, the only way | |
+ * to do so is to use the operating system interface, or to use the | |
+ * functions in source3/modules/nfs4_acls.c. These seems ugly and | |
+ * hacky. NFSv4 ACL's should be a first class citizen and | |
+ * librpc/idl/smb_acl.idl should be modified accordingly. | |
+ */ | |
+ return NULL; | |
+} | |
+ | |
/* | |
set a simple ACL on a file, as a test | |
*/ | |
@@ -491,7 +505,58 @@ | |
Py_RETURN_NONE; | |
} | |
+ | |
/* | |
+ set a simple NFSv4 ACL on a file, as a test | |
+ */ | |
+static PyObject *py_smbd_set_simple_nfsv4_acl(PyObject *self, PyObject *args, PyObject *kwargs) | |
+{ | |
+ const char * const kwnames[] = { "fname", "mode", "gid", "service", NULL }; | |
+ char *fname, *service = NULL; | |
+ int ret; | |
+ int mode, gid = -1; | |
+ SMB_ACL_T acl; | |
+ TALLOC_CTX *frame; | |
+ connection_struct *conn; | |
+ | |
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "si|iz", | |
+ discard_const_p(char *, kwnames), | |
+ &fname, &mode, &gid, &service)) | |
+ return NULL; | |
+ | |
+ frame = talloc_stackframe(); | |
+ | |
+ acl = make_simple_nfsv4_acl(frame, gid, mode); | |
+ if (acl == NULL) { | |
+ TALLOC_FREE(frame); | |
+ Py_RETURN_NONE; | |
+ } | |
+ | |
+ conn = get_conn_tos(service, NULL); | |
+ if (!conn) { | |
+ TALLOC_FREE(frame); | |
+ Py_RETURN_NONE; | |
+ } | |
+ | |
+ /* | |
+ * SMB_ACL_TYPE_ACCESS -> ACL_TYPE_ACCESS -> Not valid for NFSv4 ACL | |
+ */ | |
+ ret = 0; | |
+ | |
+ /* ret = set_sys_acl_conn(fname, SMB_ACL_TYPE_ACCESS, acl, conn); */ | |
+ | |
+ if (ret != 0) { | |
+ TALLOC_FREE(frame); | |
+ errno = ret; | |
+ return PyErr_SetFromErrno(PyExc_OSError); | |
+ } | |
+ | |
+ TALLOC_FREE(frame); | |
+ | |
+ Py_RETURN_NONE; | |
+} | |
+ | |
+/* | |
chown a file | |
*/ | |
static PyObject *py_smbd_chown(PyObject *self, PyObject *args, PyObject *kwargs) | |
@@ -665,7 +730,7 @@ | |
} | |
/* | |
- check if we have ACL support | |
+ check if we have POSIX.1e ACL support | |
*/ | |
static PyObject *py_smbd_have_posix_acls(PyObject *self, | |
PyObject *Py_UNUSED(ignored)) | |
@@ -677,7 +742,87 @@ | |
#endif | |
} | |
+static PyObject *py_smbd_has_posix_acls(PyObject *self, PyObject *args, PyObject *kwargs) | |
+{ | |
+ const char * const kwnames[] = { "path", NULL }; | |
+ char *path = NULL; | |
+ TALLOC_CTX *frame; | |
+ struct statfs fs; | |
+ int ret = false; | |
+ | |
+ frame = talloc_stackframe(); | |
+ | |
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|z", | |
+ discard_const_p(char *, kwnames), &path)) { | |
+ TALLOC_FREE(frame); | |
+ return NULL; | |
+ } | |
+ | |
+ if (statfs(path, &fs) != 0) { | |
+ TALLOC_FREE(frame); | |
+ return NULL; | |
+ } | |
+ | |
+ if (fs.f_flags & MNT_ACLS) | |
+ ret = true; | |
+ | |
+ TALLOC_FREE(frame); | |
+ return PyBool_FromLong(ret); | |
+} | |
+ | |
/* | |
+ check if we have NFSv4 ACL support | |
+ */ | |
+static PyObject *py_smbd_have_nfsv4_acls(PyObject *self) | |
+{ | |
+#ifdef HAVE_LIBSUNACL | |
+ return PyBool_FromLong(true); | |
+#else | |
+ return PyBool_FromLong(false); | |
+#endif | |
+} | |
+ | |
+static PyObject *py_smbd_has_nfsv4_acls(PyObject *self, PyObject *args, PyObject *kwargs) | |
+{ | |
+ const char * const kwnames[] = { "path", NULL }; | |
+ char *path = NULL; | |
+ TALLOC_CTX *frame; | |
+ struct statfs fs; | |
+ int ret = false; | |
+ | |
+ frame = talloc_stackframe(); | |
+ | |
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|z", | |
+ discard_const_p(char *, kwnames), &path)) { | |
+ TALLOC_FREE(frame); | |
+ return NULL; | |
+ } | |
+ | |
+ if (statfs(path, &fs) != 0) { | |
+ TALLOC_FREE(frame); | |
+ return NULL; | |
+ } | |
+ | |
+ if (fs.f_flags & MNT_NFS4ACLS) | |
+ ret = true; | |
+ | |
+ TALLOC_FREE(frame); | |
+ return PyBool_FromLong(ret); | |
+} | |
+ | |
+ | |
+static PyObject *py_smbd_set_nfsv4_defaults(PyObject *self) | |
+{ | |
+ /* | |
+ * This should really be done in source3/param/loadparm.c | |
+ */ | |
+#if defined(HAVE_LIBSUNACL) && defined(FREEBSD) | |
+ lp_do_parameter(-1, "vfs objects", "dfs_samba4 zfsacl"); | |
+#endif | |
+ Py_RETURN_NONE; | |
+} | |
+ | |
+/* | |
set the NT ACL on a file | |
*/ | |
static PyObject *py_smbd_set_nt_acl(PyObject *self, PyObject *args, PyObject *kwargs) | |
@@ -1124,8 +1269,26 @@ | |
{ "have_posix_acls", | |
(PyCFunction)py_smbd_have_posix_acls, METH_NOARGS, | |
NULL }, | |
+ { "has_posix_acls", | |
+ PY_DISCARD_FUNC_SIG(PyCFunction, py_smbd_has_posix_acls), | |
+ METH_VARARGS|METH_KEYWORDS, | |
+ NULL }, | |
+ { "have_nfsv4_acls", | |
+ (PyCFunction)py_smbd_have_nfsv4_acls, METH_NOARGS, | |
+ NULL }, | |
+ { "has_nfsv4_acls", | |
+ PY_DISCARD_FUNC_SIG(PyCFunction, py_smbd_has_nfsv4_acls), | |
+ METH_VARARGS|METH_KEYWORDS, | |
+ NULL }, | |
+ { "set_nfsv4_defaults", | |
+ (PyCFunction)py_smbd_set_nfsv4_defaults, METH_NOARGS, | |
+ NULL }, | |
{ "set_simple_acl", | |
PY_DISCARD_FUNC_SIG(PyCFunction, py_smbd_set_simple_acl), | |
+ METH_VARARGS|METH_KEYWORDS, | |
+ NULL }, | |
+ { "set_simple_nfsv4_acl", | |
+ PY_DISCARD_FUNC_SIG(PyCFunction, py_smbd_set_simple_nfsv4_acl), | |
METH_VARARGS|METH_KEYWORDS, | |
NULL }, | |
{ "set_nt_acl", | |
-- | |
2.14.2 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment