aboutsummaryrefslogtreecommitdiff
path: root/net/samba410/files/0001-Zfs-provision-1.patch
blob: bfa5b4d071352e2f193a610fcc63c51adfdc74de (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
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, 0o755, 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)
@@ -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, 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 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
@@ -392,6 +392,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
  */
@@ -437,6 +451,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
  */
@@ -536,7 +601,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)
 {
@@ -547,6 +612,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
  */
@@ -881,9 +1026,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