mirror of
https://git.freebsd.org/ports.git
synced 2025-06-10 15:20:32 -04:00
This is an initial attempt to add Samba to the FreeBSD after major rewrite of the VFS code in the upstream. Most of the port development is now carried in: https://gitlab.com/samba-freebsd Due to the way how new Samba VFS code is written there is a constrain that Samba 4.14+ can run only on FreeBSD 13.1+, as it requires support of the `nodup` option for the `fdesc` file system, as well as it's presence in the system in general. https://gitlab.com/samba-freebsd/-/wikis/The-New-VFS I'd like to thank CyberSecure Pty Ltd. company for their supoort of the port development and Andrew Walker from iXsystems Inc. for the patches he created and made available for the Samba4 on TrueNAS. PR: 263874
367 lines
11 KiB
Diff
367 lines
11 KiB
Diff
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
|
|
|