Changeset View
Changeset View
Standalone View
Standalone View
files/0001-Zfs-provision-1.patch
Property | Old Value | New Value |
---|---|---|
svn:eol-style | null | native \ No newline at end of property |
svn:mime-type | null | text/plain \ No newline at end of property |
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 | |||||
@@ -1695,19 +1695,26 @@ | |||||
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, 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()) | |||||
@@ -1984,6 +1991,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: | |||||
@@ -2340,6 +2350,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 | |||||
@@ -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 | |||||
@@ -393,6 +393,20 @@ static SMB_ACL_T make_simple_acl(TALLOC_ | |||||
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 | |||||
*/ | |||||
@@ -438,6 +452,57 @@ static PyObject *py_smbd_set_simple_acl( | |||||
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 | |||||
*/ | |||||
@@ -537,7 +602,7 @@ static PyObject *py_smbd_unlink(PyObject | |||||
} | |||||
/* | |||||
- 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)) | |||||
@@ -549,6 +614,86 @@ static PyObject *py_smbd_have_posix_acls | |||||
#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 | |||||
*/ | |||||
@@ -883,10 +1028,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.14.2 | |||||