summaryrefslogtreecommitdiff
path: root/net/samba419/files/0024-Cherry-pick-ZFS-provisioning-code-by-iXsystems-Inc.patch
diff options
context:
space:
mode:
Diffstat (limited to 'net/samba419/files/0024-Cherry-pick-ZFS-provisioning-code-by-iXsystems-Inc.patch')
-rw-r--r--net/samba419/files/0024-Cherry-pick-ZFS-provisioning-code-by-iXsystems-Inc.patch367
1 files changed, 367 insertions, 0 deletions
diff --git a/net/samba419/files/0024-Cherry-pick-ZFS-provisioning-code-by-iXsystems-Inc.patch b/net/samba419/files/0024-Cherry-pick-ZFS-provisioning-code-by-iXsystems-Inc.patch
new file mode 100644
index 000000000000..3746f0e479f6
--- /dev/null
+++ b/net/samba419/files/0024-Cherry-pick-ZFS-provisioning-code-by-iXsystems-Inc.patch
@@ -0,0 +1,367 @@
+From d3024a4a2ff8015932a26a9df08e8ea5ff12a959 Mon Sep 17 00:00:00 2001
+From: "Timur I. Bakeyev" <timur@FreeBSD.org>
+Date: Thu, 4 Aug 2022 05:15:33 +0200
+Subject: [PATCH 24/28] Cherry-pick ZFS provisioning code by iXsystems Inc.
+
+* Check if sysvol is on filesystem with NFSv4 ACL's
+(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 ACL's
+(cherry picked from commit 1c7542ff4904b729e311e17464ee76582760c219)
+
+Signed-off-by: Timur I. Bakeyev <timur@FreeBSD.org>
+---
+ python/samba/provision/__init__.py | 22 +++-
+ source3/lib/sysacls.c | 10 ++
+ source3/param/loadparm.c | 20 +++
+ source3/smbd/pysmbd.c | 189 ++++++++++++++++++++++++++++-
+ 4 files changed, 235 insertions(+), 6 deletions(-)
+
+diff --git a/python/samba/provision/__init__.py b/python/samba/provision/__init__.py
+index ff9b8fac916..20e41a9ad3e 100644
+--- a/python/samba/provision/__init__.py
++++ b/python/samba/provision/__init__.py
+@@ -1662,19 +1662,25 @@ def setsysvolacl(samdb, netlogon, sysvol, uid, gid, domainsid, dnsdomain,
+ s3conf = s3param.get_context()
+ s3conf.load(lp.configfile)
+
+- file = tempfile.NamedTemporaryFile(dir=os.path.abspath(sysvol))
++ sysvol_dir = os.path.abspath(sysvol)
++
++ set_simple_acl = smbd.set_simple_acl
++ if smbd.has_nfsv4_acls(sysvol_dir):
++ set_simple_acl = smbd.set_simple_nfsv4_acl
++
++ file = tempfile.NamedTemporaryFile(dir=sysvol_dir)
+ try:
+ try:
+- smbd.set_simple_acl(file.name, 0o755, system_session_unix(), gid)
++ 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.
+- raise ProvisioningError("Samba was compiled without the posix ACL support that s3fs requires. "
++ raise ProvisioningError("Samba was compiled without the ACL support that s3fs requires. "
+ "Try installing libacl1-dev or libacl-devel, then re-run configure and make.")
+
+- raise ProvisioningError("Your filesystem or build does not support posix ACLs, which s3fs requires. "
++ raise ProvisioningError("Your filesystem or build does not support ACLs, which s3fs requires. "
+ "Try the mounting the filesystem with the 'acl' option.")
+ try:
+ smbd.chown(file.name, uid, gid, system_session_unix())
+@@ -1959,6 +1965,9 @@ def provision_fill(samdb, secrets_ldb, logger, names, paths,
+ 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:
+@@ -2313,6 +2322,9 @@ def provision(logger, session_info, smbconf=None,
+ 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)
+ adminpass_generated = True
+diff --git a/source3/lib/sysacls.c b/source3/lib/sysacls.c
+index 891fabea21e..d1357a47bd0 100644
+--- a/source3/lib/sysacls.c
++++ b/source3/lib/sysacls.c
+@@ -38,6 +38,16 @@
+ #include "modules/vfs_aixacl.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 21e061939e3..4e23fdaaf6d 100644
+--- a/source3/param/loadparm.c
++++ b/source3/param/loadparm.c
+@@ -2830,9 +2830,29 @@ static void init_locals(void)
+ } else {
+ if (lp_parm_const_string(-1, "xattr_tdb", "file", NULL)) {
+ lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr xattr_tdb");
++ /*
++ * By default, the samba sysvol is located in the statedir. Provisioning will fail in setntacl
++ * unless we have zfacl enabled. Unfortunately, at this point the smb.conf has not been generated.
++ * This workaround is freebsd-specific.
++ */
++#if defined(_PC_ACL_EXTENDED)
++ } else if (pathconf(lp_state_directory(), _PC_ACL_EXTENDED) == 1) {
++ lp_do_parameter(-1, "vfs objects", "dfs_samba4 freebsd");
++#endif
++#if defined(_PC_ACL_NFS4)
++ } else if (pathconf(lp_state_directory(), _PC_ACL_NFS4) == 1) {
++ lp_do_parameter(-1, "vfs objects", "dfs_samba4 zfsacl");
++#endif
+ } 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 88cbf62a680..867010ea6cd 100644
+--- a/source3/smbd/pysmbd.c
++++ b/source3/smbd/pysmbd.c
+@@ -485,6 +485,20 @@ static SMB_ACL_T make_simple_acl(TALLOC_CTX *mem_ctx,
+ 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
+ */
+@@ -557,6 +571,84 @@ static PyObject *py_smbd_set_simple_acl(PyObject *self, PyObject *args, PyObject
+ 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",
++ "session_info",
++ "gid",
++ "service",
++ NULL
++ };
++ char *fname, *service = NULL;
++ PyObject *py_session = Py_None;
++ struct auth_session_info *session_info = NULL;
++ int ret;
++ int mode, gid = -1;
++ SMB_ACL_T acl;
++ TALLOC_CTX *frame;
++ connection_struct *conn;
++
++ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "siO|iz",
++ discard_const_p(char *, kwnames),
++ &fname,
++ &mode,
++ &py_session,
++ &gid,
++ &service))
++ return NULL;
++
++ if (!py_check_dcerpc_type(py_session,
++ "samba.dcerpc.auth",
++ "session_info")) {
++ return NULL;
++ }
++ session_info = pytalloc_get_type(py_session,
++ struct auth_session_info);
++ if (session_info == NULL) {
++ PyErr_Format(PyExc_TypeError,
++ "Expected auth_session_info for session_info argument got %s",
++ pytalloc_get_name(py_session));
++ 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, session_info);
++ 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
+ */
+@@ -744,7 +836,7 @@ static PyObject *py_smbd_unlink(PyObject *self, PyObject *args, PyObject *kwargs
+ }
+
+ /*
+- 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))
+@@ -756,6 +848,83 @@ static PyObject *py_smbd_have_posix_acls(PyObject *self,
+ #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)
++{
++ /*
++ * It is really be done in source3/param/loadparm.c
++ */
++ Py_RETURN_NONE;
++}
++
+ /*
+ set the NT ACL on a file
+ */
+@@ -1242,10 +1411,28 @@ static PyMethodDef py_smbd_methods[] = {
+ { "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",
+ PY_DISCARD_FUNC_SIG(PyCFunction, py_smbd_set_nt_acl),
+ METH_VARARGS|METH_KEYWORDS,
+--
+2.37.1
+