diff options
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.patch | 367 |
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 + |