787829268c
Sponsored by: iXsystems Inc.
319 lines
9.7 KiB
Diff
319 lines
9.7 KiB
Diff
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 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@iXsystems.com>
|
|
---
|
|
python/samba/provision/__init__.py | 25 ++++--
|
|
source3/lib/sysacls.c | 10 +++
|
|
source3/param/loadparm.c | 7 ++
|
|
source3/smbd/pysmbd.c | 156 ++++++++++++++++++++++++++++++++++++-
|
|
4 files changed, 191 insertions(+), 7 deletions(-)
|
|
|
|
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
|
|
@@ -1556,19 +1556,24 @@ 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, 0755, gid)
|
|
+ set_simple_acl(file.name, 0755, 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)
|
|
@@ -1821,6 +1828,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:
|
|
@@ -2184,6 +2194,9 @@ def provision(logger, session_info, smbconf=None,
|
|
if not os.path.isdir(paths.netlogon):
|
|
os.makedirs(paths.netlogon, 0755)
|
|
|
|
+ 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 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
|
|
@@ -2740,6 +2740,13 @@ static void init_locals(void)
|
|
} 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
|
|
@@ -335,6 +335,18 @@ static SMB_ACL_T make_simple_acl(gid_t gid, mode_t chmod_mode)
|
|
return acl;
|
|
}
|
|
|
|
+static SMB_ACL_T make_simple_nfsv4_acl(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
|
|
*/
|
|
@@ -363,6 +375,53 @@ static PyObject *py_smbd_set_simple_acl(PyObject *self, PyObject *args, PyObject
|
|
}
|
|
|
|
ret = set_sys_acl_conn(fname, SMB_ACL_TYPE_ACCESS, acl, conn);
|
|
+
|
|
+ TALLOC_FREE(acl);
|
|
+
|
|
+ if (ret != 0) {
|
|
+ TALLOC_FREE(frame);
|
|
+ errno = ret;
|
|
+ return PyErr_SetFromErrno(PyExc_OSError);
|
|
+ }
|
|
+
|
|
+ TALLOC_FREE(frame);
|
|
+
|
|
+ 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;
|
|
+
|
|
+ acl = make_simple_nfsv4_acl(gid, mode);
|
|
+
|
|
+ frame = talloc_stackframe();
|
|
+
|
|
+ conn = get_conn(frame, service);
|
|
+ if (!conn) {
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * SMB_ACL_TYPE_ACCESS -> ACL_TYPE_ACCESS -> Not valid for NFSv4 ACL
|
|
+ */
|
|
+ //ret = set_sys_acl_conn(fname, SMB_ACL_TYPE_ACCESS, acl, conn);
|
|
+ ret = 0;
|
|
+
|
|
TALLOC_FREE(acl);
|
|
|
|
if (ret != 0) {
|
|
@@ -483,7 +542,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)
|
|
{
|
|
@@ -494,6 +553,86 @@ 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)
|
|
+{
|
|
+ /*
|
|
+ * 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
|
|
*/
|
|
@@ -681,9 +820,24 @@ static PyMethodDef py_smbd_methods[] = {
|
|
{ "have_posix_acls",
|
|
(PyCFunction)py_smbd_have_posix_acls, METH_NOARGS,
|
|
NULL },
|
|
+ { "has_posix_acls",
|
|
+ (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",
|
|
+ (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",
|
|
(PyCFunction)py_smbd_set_simple_acl, METH_VARARGS|METH_KEYWORDS,
|
|
NULL },
|
|
+ { "set_simple_nfsv4_acl",
|
|
+ (PyCFunction)py_smbd_set_simple_nfsv4_acl, METH_VARARGS|METH_KEYWORDS,
|
|
+ NULL },
|
|
{ "set_nt_acl",
|
|
(PyCFunction)py_smbd_set_nt_acl, METH_VARARGS|METH_KEYWORDS,
|
|
NULL },
|
|
--
|
|
2.14.2
|
|
|